pax_global_header00006660000000000000000000000064150133256240014513gustar00rootroot0000000000000052 comment=e4d2788f0869808bccea67a041a347c4c6bc237b icinga2-2.14.6/000077500000000000000000000000001501332562400131215ustar00rootroot00000000000000icinga2-2.14.6/.github/000077500000000000000000000000001501332562400144615ustar00rootroot00000000000000icinga2-2.14.6/.github/ISSUE_TEMPLATE/000077500000000000000000000000001501332562400166445ustar00rootroot00000000000000icinga2-2.14.6/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000024021501332562400213340ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- ## Describe the bug A clear and concise description of what the bug is. Please ensure to read https://github.com/Icinga/icinga2/blob/master/doc/15-troubleshooting.md first. Formatting tips: GitHub supports Markdown: https://guides.github.com/features/mastering-markdown/ ## To Reproduce Provide a link to a live example, or an unambiguous set of steps to reproduce this bug. Include configuration, logs, etc. to reproduce, if relevant. 1. 2. 3. 4. ## Expected behavior A clear and concise description of what you expected to happen. ## Screenshots If applicable, add screenshots to help explain your problem. ## Your Environment Include as many relevant details about the environment you experienced the problem in * Version used (`icinga2 --version`): * Operating System and version: * Enabled features (`icinga2 feature list`): * Icinga Web 2 version and modules (System - About): * Config validation (`icinga2 daemon -C`): * If you run multiple Icinga 2 instances, the `zones.conf` file (or `icinga2 object list --type Endpoint` and `icinga2 object list --type Zone`) from all affected nodes. ## Additional context Add any other context about the problem here. icinga2-2.14.6/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000002471501332562400206370ustar00rootroot00000000000000blank_issues_enabled: true contact_links: - name: Ask a question url: https://community.icinga.com/c/icinga-2/6 about: Ask a question in our community forum icinga2-2.14.6/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000011451501332562400223720ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- ## Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always using this feature but am missing [...] ## Describe the solution you'd like A clear and concise description of what you want to happen. ## Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered. ## Additional context Add any other context or screenshots about the feature request here. icinga2-2.14.6/.github/workflows/000077500000000000000000000000001501332562400165165ustar00rootroot00000000000000icinga2-2.14.6/.github/workflows/authors-file.yml000066400000000000000000000020641501332562400216450ustar00rootroot00000000000000name: AUTHORS file on: pull_request: { } jobs: authors-file: name: AUTHORS file runs-on: ubuntu-latest steps: - name: Checkout HEAD uses: actions/checkout@v3 with: fetch-depth: 0 - name: Check whether ./AUTHORS is up-to-date run: | set -exo pipefail sort -uo AUTHORS AUTHORS git add AUTHORS git log --format='format:%aN <%aE>' "$( git merge-base HEAD^1 HEAD^2 )..HEAD^2" >> AUTHORS sort -uo AUTHORS AUTHORS git diff AUTHORS >> AUTHORS.diff - name: Complain if ./AUTHORS isn't up-to-date run: | if [ -s AUTHORS.diff ]; then cat <<'EOF' >&2 There are the following new authors. If the commit author data is correct, either add them to the AUTHORS file or update .mailmap. See gitmailmap(5) or: https://git-scm.com/docs/gitmailmap Don't hesitate to ask us for help if necessary. EOF cat AUTHORS.diff exit 1 fi icinga2-2.14.6/.github/workflows/docker.yml000066400000000000000000000014041501332562400205070ustar00rootroot00000000000000name: Docker image on: pull_request: {} push: branches: - master release: types: - published concurrency: group: docker-${{ github.event_name == 'push' && github.sha || github.ref }} cancel-in-progress: true jobs: docker-release: if: github.event_name == 'release' concurrency: docker-release runs-on: ubuntu-latest steps: - name: Docker image uses: Icinga/docker-icinga2@master with: dockerhub-token: '${{ secrets.DOCKER_HUB_PERSONAL_TOKEN }}' docker: if: github.event_name != 'release' runs-on: ubuntu-latest steps: - name: Docker image uses: Icinga/docker-icinga2@master with: dockerhub-token: '${{ secrets.DOCKER_HUB_PERSONAL_TOKEN }}' icinga2-2.14.6/.github/workflows/linux.bash000077500000000000000000000045571501332562400205320ustar00rootroot00000000000000#!/bin/bash set -exo pipefail export PATH="/usr/lib/ccache:/usr/lib64/ccache:$PATH" export CCACHE_DIR=/icinga2/ccache export CTEST_OUTPUT_ON_FAILURE=1 CMAKE_OPTS='' case "$DISTRO" in amazonlinux:2) amazon-linux-extras install -y epel yum install -y bison ccache cmake3 gcc-c++ flex ninja-build \ {libedit,mariadb,ncurses,openssl,postgresql,systemd}-devel yum install -y bzip2 tar wget wget https://archives.boost.io/release/1.69.0/source/boost_1_69_0.tar.bz2 tar -xjf boost_1_69_0.tar.bz2 ( cd boost_1_69_0 ./bootstrap.sh --with-libraries=context,coroutine,date_time,filesystem,iostreams,program_options,regex,system,test,thread ./b2 ) ln -vs /usr/bin/cmake3 /usr/local/bin/cmake ln -vs /usr/bin/ninja-build /usr/local/bin/ninja CMAKE_OPTS='-DBOOST_INCLUDEDIR=/boost_1_69_0 -DBOOST_LIBRARYDIR=/boost_1_69_0/stage/lib' export LD_LIBRARY_PATH=/boost_1_69_0/stage/lib ;; amazonlinux:20*) dnf install -y bison cmake flex gcc-c++ ninja-build \ {boost,libedit,mariadb-connector-c,ncurses,openssl,postgresql,systemd}-devel ;; debian:*|ubuntu:*) apt-get update DEBIAN_FRONTEND=noninteractive apt-get install --no-install-{recommends,suggests} -y bison \ ccache cmake flex g++ lib{boost-all,edit,mariadb,ncurses,pq,ssl,systemd}-dev ninja-build tzdata ;; fedora:*) dnf install -y bison ccache cmake flex gcc-c++ ninja-build \ {boost,libedit,mariadb,ncurses,openssl,postgresql,systemd}-devel ;; *suse*) zypper in -y bison ccache cmake flex gcc-c++ ninja {lib{edit,mariadb,openssl},ncurses,postgresql,systemd}-devel \ libboost_{context,coroutine,filesystem,iostreams,program_options,regex,system,test,thread}-devel ;; rockylinux:*) dnf install -y 'dnf-command(config-manager)' epel-release case "$DISTRO" in *:8) dnf config-manager --enable powertools ;; *) dnf config-manager --enable crb ;; esac dnf install -y bison ccache cmake gcc-c++ flex ninja-build \ {boost,libedit,mariadb,ncurses,openssl,postgresql,systemd}-devel ;; esac mkdir /icinga2/build cd /icinga2/build cmake \ -GNinja \ -DCMAKE_BUILD_TYPE=Release \ -DICINGA2_UNITY_BUILD=ON \ -DUSE_SYSTEMD=ON \ -DICINGA2_USER=$(id -un) \ -DICINGA2_GROUP=$(id -gn) \ $CMAKE_OPTS .. ninja ninja test ninja install icinga2 daemon -C icinga2-2.14.6/.github/workflows/linux.yml000066400000000000000000000030041501332562400203750ustar00rootroot00000000000000name: Linux on: push: branches: - master - 'support/*' pull_request: {} concurrency: group: linux-${{ github.event_name == 'push' && github.sha || github.ref }} cancel-in-progress: true jobs: linux: name: ${{ matrix.distro }} runs-on: ubuntu-latest strategy: fail-fast: false max-parallel: 2 matrix: distro: - amazonlinux:2 - amazonlinux:2023 # Raspberry Pi OS is close enough to Debian to test just one of them. # Its architecture is different, though, and covered by the Docker job. - debian:11 - debian:12 - fedora:39 - fedora:40 - fedora:41 - opensuse/leap:15.5 - opensuse/leap:15.6 # We don't actually support Rocky Linux as such! # We just use that RHEL clone to test the original. - rockylinux:8 - rockylinux:9 - registry.suse.com/suse/sle15:15.5 - registry.suse.com/suse/sle15:15.6 - ubuntu:20.04 - ubuntu:22.04 - ubuntu:24.04 - ubuntu:24.10 steps: - name: Checkout HEAD uses: actions/checkout@v3 - name: Restore/backup ccache uses: actions/cache@v3 with: path: ccache key: ccache/${{ matrix.distro }} - name: Build run: >- docker run --rm -v "$(pwd):/icinga2" -e DISTRO=${{ matrix.distro }} ${{ matrix.distro }} /icinga2/.github/workflows/linux.bash icinga2-2.14.6/.github/workflows/windows.yml000066400000000000000000000021151501332562400207320ustar00rootroot00000000000000name: Windows on: push: branches: - master - 'support/*' pull_request: {} concurrency: group: windows-${{ github.event_name == 'push' && github.sha || github.ref }} cancel-in-progress: true jobs: windows: name: Windows strategy: fail-fast: false max-parallel: 1 matrix: bits: [32, 64] runs-on: windows-2019 env: BITS: '${{ matrix.bits }}' CMAKE_BUILD_TYPE: RelWithDebInfo steps: - name: Checkout HEAD uses: actions/checkout@v1 - name: Build tools run: | Set-PSDebug -Trace 1 & .\doc\win-dev.ps1 - name: Binary run: | Set-PSDebug -Trace 1 & .\tools\win32\load-vsenv.ps1 & powershell.exe .\tools\win32\configure.ps1 if ($LastExitCode -ne 0) { throw "Error during configure" } & powershell.exe .\tools\win32\build.ps1 if ($LastExitCode -ne 0) { throw "Error during build" } & powershell.exe .\tools\win32\test.ps1 if ($LastExitCode -ne 0) { throw "Error during test" } icinga2-2.14.6/.gitignore000066400000000000000000000004631501332562400151140ustar00rootroot00000000000000# Exclude all hidden files .* # Except those related to git and vagrant !.git* !.puppet* !.travis.yml !.mailmap ## Tools *~ tickets.pickle ## Build artifacts build*/ debug/ release/ cmake-build-debug /Testing/ /install/ /vendor/ tools/selinux/icinga2.pp tools/selinux/icinga2_selinux.8 tools/selinux/tmp icinga2-2.14.6/.mailmap000066400000000000000000000073161501332562400145510ustar00rootroot00000000000000 Alexander A. Klimov <7324088+MarcusCaepio@users.noreply.github.com> Alex Baptiste Beauplat Carsten Köbke Carsten Koebke Claudio Kuenzler Diana Flach Diana Flach Diana Flach Diana Flach Jean Flach Dolf Schimmel Gunnar Beutner Henrik Triem Henrik Triem Henrik Triem <43344334+htriem@users.noreply.github.com> Jens Schanz Jens Schanz Schanz, Jens Kálmán „KAMI” Szalai Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Marianne Spiller Markus Waldmüller Mattia Codato mcodato <64135571+mcodato@users.noreply.github.com> Michael Insel Michael Insel Michael Insel nemtrif nemtrif Robin O'Brien Roman Gerhardt Sebastian Chrostek Thomas Gelf icinga2-2.14.6/AUTHORS000066400000000000000000000271751501332562400142050ustar00rootroot00000000000000Aaron Bishop Adam Bolte Adam James akrus Alan Jenkins Alan Litster Alex Alex Merry Alexander A. Klimov Alexander Fuhr Alexander Schomburg Alexander Stoll Alexander Wirt Alvar Penning Andrea Avancini Andrea Kao Andreas Maus Andreas Scherbaum Andreas Unterkircher Andres Ivanov Andrew Jaffie Andrew Meyer Andy Grunwald Angel Roman Ant1x <37016240+Ant1x@users.noreply.github.com> Arnd Hannemann Assaf Flatto azthec Baptiste Beauplat BarbUk Bård Dahlmo-Lerbæk Bas Couwenberg bascarsija Bastian Guse Bauerheim, Marcus BausPhi Benedikt Heine Benjamin Groeber Bernd Arnold Bernd Erk Berthold Cogel Blerim Sheqa Brendan Jurd Brian De Wolf Brian Dockter Bruno Lingner C C Magnus Gustavsson Carlos Cesario Carsten Köbke Chris Boot Christian Birk Christian Gut Christian Harke Christian Jonak Christian Lehmann Christian Lauf Christian Loos Christian Schmidt Christopher Peterson <3893680+cspeterson@users.noreply.github.com> Christopher Schirner Claudio Bilotta Claudio Kuenzler Conrad Clement cstegm ctrlaltca Damiano Chini Daniel Bodky Daniel Helgenberger Daniel Kesselberg Daniil Yaroslavtsev David Beck David Lublink Denis Dennis Lichtenthäler dh.harald Diana Flach Dinesh Majrekar Dirk Goetz Dirk Melchers Dolf Schimmel Dominik Riva dominik-r-s <43005480+dominik-r-s@users.noreply.github.com> Edgar Fuß Eduard Güldner Edvin Seferovic Elias Ohm Élie Bouttier Eric Lippmann Evgeni Golov Ewoud Kohl van Wijngaarden Fabian Röhl Fabian Werner <47595490+fabieins@users.noreply.github.com> fbachmann Federico Cuello Federico Pires Ferdi Gueran Feu Mourek Francesco Colista Gaël Beaudoin Georg Faerber Georg Haas Gerd von Egidy gitmopp Glauco Vinicius Greg Hewgill Grischa Zengel Gunnar Beutner Hannes Happle Hannes Van de Vel Harald Laabs Heike Jurzik Hendrik Röder Henrik Triem Ian Kelling Ildar Hizbulin Irina Kaprizkina Iustin Pop Jaap Marcus <9754650+jaapmarcus@users.noreply.github.com> Jack James Pharaoh Jan Andres Jan Beich Jan Wagner Janne Heß Jason Young Jean Flach Jean-Louis Dupond Jens Link Jens Schanz Jeon Sang Wan Jeremy Armstrong Jérôme Drouet Jesse Morgan Jo Goossens Jochen Friedrich Johannes Meyer Jonas Meurer Jordi van Scheijen Josef Friedrich Joseph L. Casale jre3brg Julian Brost K0nne <34264690+K0nne@users.noreply.github.com> Kai Goller Kálmán „KAMI” Szalai kiba Konstantin Kelemen krishna Lara Lars Engels Lars Krüger Lars Vogdt Leah Oswald Lee Clemens Lee Garrett Lennart Betz Leon Stringer lihan log1-c <24474580+log1-c@users.noreply.github.com> Lord Hepipud Lorenz Kästle Louis Sautier Luca Lesinigo Lucas Bremgartner Lucas Fairchild-Madar Luiz Amaral Maciej Dems Magnus Bäck Maik Stuebner Malte Rabenseifner Manuel Reiter Marc Rupprecht Marcus van Dam MarcusCaepio Marianne Spiller Marius Bergmann Marius Sturm Mark Leary Markus Frosch Markus Waldmüller Markus Weber Martijn van Duren Martin Neubert Martin Stiborsky marxin Mathias Aerts Mathieu Arnold Mathieu Lutfy Matthaus Owens Matthias Baur Matthias Schales Mattia Codato Maurice Meyer Max Deparade Max Rosin Max Zhang Maximilian Eschenbacher Maximilian Falkenstein Mhd Sulhan Micha Ahrweiler Michael Friedrich Michael Insel Michael Kraus Michael Newton Michal Moravec Michal Petko Mikesch-mp Mirco Bauer Mirko Nardin mocruz Muhammad Mominul Huque nemtrif Nicolai Nicolas Berens Nicolas Limage Nicole Lang Niflou Noah Hilverling noobahoi <20069422+noobahoi@users.noreply.github.com> Obihörnchen Oleg Artenii Pall Sigurdsson Paolo Schiro Patrick Patrick Dolinic Patrick Huy Paul Denning Paul Richards Pavel Motyrev Pawel Szafer Per von Zweigbergk Peter Eckel <6815386+peteeckel@users.noreply.github.com> Peter Eckel Peter Eckel Petr Ruzicka Phil Hutchinson Philipp Dallig Philipp Dorschner pv2b Ralph Breier Reto Zeder Ricardo Bartels RincewindsHat <12514511+RincewindsHat@users.noreply.github.com> Rinck H. Sonnenberg Robert Lindgren Robert Scheck Robin O'Brien Roland Hopferwieser Roman Gerhardt Rostislav Opocensky Rudy Gevaert Rune Darrud ryanohnemus sah Sam Kottler Sascha Westermann Sebastian Brückner Sebastian Chrostek Sebastian Eikenberg Sebastian Marsching Silas <67681686+Tqnsls@users.noreply.github.com> Simon Murray Simon Ruderich Siyalrach Anton Thomas Stefan Bethke Stefan Triep Stefar77 Stephan Platz Stephan Tesch Steve McMaster stevie-sy <38723488+stevie-sy@users.noreply.github.com> Strajan Sebastian Ioan Strix <660956+MrStrix@users.noreply.github.com> Stuart Henderson Sven Nierlein Sven Wegener sysadt T. Mulyana teclogi <27726999+teclogi@users.noreply.github.com> Thomas Forrer Thomas Gelf Thomas Niedermeier Thomas Widhalm Tim Hardeck Tim Weippert Timo Buhrmester Tobias Birnbaum Tobias Deiminger Tobias von der Krone Tom Geissler Uwe Ebel Valentin Hoebel vigiroux Vytenis Darulis Wenger Florian Will Frey Winfried Angele Wolfgang Nieder XnS Yannick Charton Yannick Martin Yohan Jarosz Yonas Habteab Zachary McGibbon Zoltan Nagy icinga2-2.14.6/CHANGELOG.md000066400000000000000000015537441501332562400147550ustar00rootroot00000000000000# Icinga 2 CHANGELOG **The latest release announcements are available on [https://icinga.com/blog/](https://icinga.com/blog/).** Please read the [upgrading](https://icinga.com/docs/icinga2/latest/doc/16-upgrading-icinga-2/) documentation before upgrading to a new release. Released closed milestones can be found on [GitHub](https://github.com/Icinga/icinga2/milestones?state=closed). ## 2.14.6 (2025-05-27) This security release fixes a critical issue in the certificate renewal logic in Icinga 2, which might incorrectly renew an invalid certificate. However, only nodes with access to the Icinga CA private key running with OpenSSL older than version 1.1.0 (released in 2016) are vulnerable. So this typically affects Icinga 2 masters running on operating systems like RHEL 7 and Amazon Linux 2. * CVE-2025-48057: Prevent invalid certificates from being renewed with OpenSSL older than v1.1.0. * Fix use-after-free in VerifyCertificate(): Additionally, a use-after-free was found in the same function which is fixed as well, but in case it is triggered, typically only a wrong error code may be shown in a log message. * Windows: Update OpenSSL shipped on Windows to v3.0.16. ## 2.14.5 (2025-02-06) This release fixes a regression introduced in 2.14.4 that caused the `icinga2 node setup`, `icinga2 node wizard`, and `icinga2 pki request` commands to fail if a certificate was requested from a node that has to forward the request to another node for signing. Additionally, it fixes a small bug in the performance data normalization and includes various documentation improvements. ### Bug Fixes * Don't close anonymous connections before sending the response for a certificate request #10337 * Performance data: Don't discard min/max values even if crit/warn thresholds aren’t given #10339 * Fix a failing test case on systems `time_t` is only 32 bits #10343 ### Documentation * Document the -X option for the mail-host-notification and mail-service-notification commands #10335 * Include Nagios in the migration docs #10324 * Remove RHEL 7 from installation instructions #10334 * Add instructions for installing build dependencies on Windows Server #10336 ## 2.14.4 (2025-01-23) This bugfix release is focused on improving HA cluster stability and easing troubleshooting of issues in this area. It also addresses several crashes, in the core itself and both in Icinga DB and IDO (numbers out of range). In addition, it fixes several other issues such as lost notifications or TimePeriod/ScheduledDowntime exceeding specified date ranges. ### Crash Fixes * Invalid `DateTime#format()` arguments in config and console on Windows Server 2016 and older. #10112 * Downtime scheduling at runtime with non-existent trigger. #10049 * Object creation at runtime during Icinga DB initialization. #10151 * Comment on a service of a non-existent host. #9861 ### Miscellaneous Bugfixes * Lost notifications after recovery outside the notification time period. #10187 * TimePeriod/ScheduledDowntime exceeding specified date range. #9983 #10107 * Clean up failure for obsolete Downtimes. #10062 * ifw-api check command: use correct process-finished handler. #10140 * Email notification scripts: strip 0x0D (CR) for a proper Content-Type. #10061 * Several fixes and improvements of the code quality. #10066 #10214 #10254 #10263 #10264 ### Cluster and API * Sync runtime objects in topological order to honor their dependencies. #10000 * Make parallel config syncs more robust. #10013 * After object creation via API fails, clean up properly for the next try. #10111 * Close HTTPS connections properly to prevent leaks. #10005 #10006 * Reduce the number of cluster messages in memory at the same time. #9991 #9999 #10210 * Once a cluster connection shall be closed, stop communicating. #10213 #10221 * Remove unnecessary blocking of semaphores. #9992 #9994 * Reduce unnecessary cluster messages setting the next check time. #10011 ### Icinga DB and IDO * IDO: fix object relations after aborted synchronization. #10065 * Icinga DB, IDO: limit all timestamps to four year digits. #10058 #10059 * Icinga DB: limit execution\_time and latency (milliseconds) to database schema. #10060 ### Troubleshooting * Add `/v1/debug/malloc_info` which calls `malloc_info(3)` if available. #10015 * Add log messages about own network I/O. #9993 #10141 #10207 * Several fixes and improvements of log messages. #9997 #10021 #10209 ### Windows * Update OpenSSL shipped on Windows to v3.0.15. #10170 * Update Boost shipped on Windows to v1.86. #10114 * Support CMake v3.29. #10037 * Don't require to build .msi as admin. #10137 * Build configuration scripts: allow custom `$CMAKE_ARGS`. #10312 ### Documentation * Distributed Monitoring: add section "External CA/PKI". #9825 * Explain how to enable/disable debug logging on the fly. #9981 * Update supported OS versions and repository configuration. #10064 #10090 #10120 #10135 #10136 #10205 * Several fixes and improvements. #9960 #10050 #10071 #10156 #10194 * Replace broken links. #10115 #10118 #10282 * Fix typographical and similarly trivial errors. #9953 #9967 #10056 #10116 #10152 #10153 #10204 ## 2.14.3 (2024-11-12) This security release fixes a TLS certificate validation bypass. Given the severity of that issue, users are advised to upgrade all nodes immediately. * Security: fix TLS certificate validation bypass. CVE-2024-49369 * Security: update OpenSSL shipped on Windows to v3.0.15. * Windows: sign MSI packages with a certificate the OS trusts by default. ## 2.14.2 (2024-01-18) Version 2.14.2 is a hotfix release for master nodes that mainly fixes excessive disk usage caused by the InfluxDB writers. * InfluxDB: truncate timestamps to whole seconds to save disk space. #9969 * HttpServerConnection: log request processing time as well. #9970 * Update Boost shipped on Windows to v1.84. #9970 ## 2.14.1 (2023-12-21) Version 2.14.1 is a hotfix release for masters and satellites that mainly prevents permanent disintegration of a whole cluster due to root CA expiry. ### Security * Automatically renew own root CA and distribute it to all nodes. #9933 * Update OpenSSL shipped on Windows to v3.0.12. #9946 * Disable TLS renegotiation (handshake on existing connection). #9946 ### Bugfixes * Icinga DB feature: fix crash due to missing NULL pointer check. #9946 * Icinga DB feature: fix data written into Redis crashing the Go daemon. #9946 * GelfWriter: fix deadlock on stop/reload caused by busy queue. #9947 * Don't lose notifications due to too long output, truncate it. #9947 ### Enhancements * Discard duplicate problem notifications due to state filtering. #9932 * Speed up API filters targeting specific hosts/services to O(1). #9944 * POST /v1/console/\*: return HTTP 503 while Icinga is reloading. #9947 * Update Boost shipped on Windows to v1.83. #9946 * Documentation: several fixes and improvements. #9921 ## 2.14.0 (2023-07-12) [Issues and PRs](https://github.com/Icinga/icinga2/issues?q=is%3Aclosed+milestone%3A2.14.0) ### Notes Upgrading docs: https://icinga.com/docs/icinga2/snapshot/doc/16-upgrading-icinga-2/#upgrading-to-2-14 Thanks to all contributors: [atj](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Aatj), [atwebm](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Aatwebm), [cspeterson](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Acspeterson), [cycloon](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Acycloon), [DamianoChini](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3ADamianoChini), [efuss](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Aefuss), [fabieins](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Afabieins), [haxtibal](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Ahaxtibal), [jaapmarcus](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Ajaapmarcus), [log1-c](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Alog1-c), [lrupp](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Alrupp), [maggu](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Amaggu), [mcodato](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Amcodato), [Napsty](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3ANapsty), [orbison](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Aorbison), [peteeckel](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Apeteeckel), [slalomsk8er](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Aslalomsk8er), [stevie-sy](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3Astevie-sy), [Tqnsls](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+is%3Aclosed+milestone%3A2.14.0+author%3ATqnsls) ### Breaking Changes * Remove CheckResultReader (which has been deprecated since v2.9). #9714 * Remove StatusDataWriter (which has been deprecated since v2.9). #9715 * ElasticsearchWriter: drop support for Elasticsearch < v7. #9812 * Consider a checkable unreachable once one Dependency fails. Previously all of them had to fail. (Consult the upgrading docs.) #8218 * API: reject config modifications during reload with HTTP status 503. #9445 * `icinga2 daemon`: to reduce config load time, write file needed by `icinga2 object list` only if `--dump-objects` is given. #9586 #9591 * Default email notification scripts: link to Icinga DB Web, not the monitoring module. (Consult the upgrading docs.) #9742 #9757 * API: for security reasons hide TicketSalt in /v1/variables. #7863 #### Icinga 2 Config DSL * Disallow global variable modification after config commit start (i.e. inside `object/apply T "x" { ... }`) to reduce config load time. #9740 * Forbid Dependency cycles at config load time. #8389 * Allow only strings in the arrays Host#groups, Service#groups and User#groups. Needed for consistency, especially by the IDO. #9057 * Disallow empty object names. (They worked only partially anyway.) #9409 #### Windows Agent only The official MSIs don't include the following features anymore. They weren't intended, tested or needed on Windows and only waste build time, bandwidth and disk space. Both new installations and upgrades are affected. * ElasticsearchWriter #9704 * GelfWriter #9704 * GraphiteWriter #9704 * InfluxdbWriter and Influxdb2Writer #9704 * OpenTsdbWriter #9704 * PerfdataWriter #9704 We also don't ship the following files anymore. (You can still obtain them manually.) * `NSCP.msi` (NSClient++ installer) #9703 * [doc/](doc) (Icinga 2 markdown documentation) #9705 On the other hand MSIs are now 75% smaller than before. ### Enhancements * Significantly reduce config load time of large setups. #8118 #9555 #9557 #9572 #9577 #9603 #9608 #9627 #9648 #9657 #9662 * Allow to connect dependencies via redundancy groups. Only parents within one group are assumed to provide redundancy for each other. #8218 * Built-in check command ifw-api, communicates directly with the Icinga for Windows REST API. (Doesn't spawn a PowerShell process for that.) #9062 * JournaldLogger which logs to systemd journal. #9000 * API: POST /v1/objects: allow to discard some previously modified attributes, i.e. to restore the config files' values. #9783 * ElasticsearchWriter: support Elasticsearch v8. #9812 * Support `$env.ENV_VAR_NAME$` macros. #8302 * Speed up Icinga DB config dump. #9524 * Default mail notification scripts: also print `$host.notes$` and `$service.notes$`. #9713 * Enable built-in OpenSSL DH parameters to allow DHE TLS ciphers. #9811 * Clean up global default TLS cipher list to improve security. #9809 * Influxdb(2)Writer: write more precise timestamps (nanoseconds). #9599 ### Bugfixes * Icinga DB feature: normalize several Redis data not to crash the Go daemon. #9772 #9775 #9792 #9793 #9794 #9805 * Fix parsing of perfdata across multiple lines in plugin output. #8969 * icinga check: fix last reload failure time. #8429 #9827 * Resolve macros inside custom vars of IcingaApplication. #9779 * SELinux: allow Icinga and its plugins to write to syslog. #9688 * ElasticsearchWriter: fix data buffer flush race condition during stop. #9810 * Trigger flexible downtimes not in the past if checkable is already down. #9726 * Send downtime expiration notifications immediately, not after up to a minute. #9726 #### Cluster * Don't hang in timed out connection attempt. #9711 #9725 * Fix lost acknowledgements after re-connect. #9718 * cluster-zone check: don't complain about not connected other local zone members if there aren't any. #8595 * Allow agent to update executions delegated to it via /v1/actions/execute-command. #8627 #### API * Disallow breaking inter-object relationships by changing relationship attributes at runtime, e.g. `Service#host_name`. #9407 * Correct several HTTP response status codes. #7958 #9354 * Correct Boolean field types previously reported by /v1/types as Number. #9514 #### CLI * `icinga2 daemon`: fix -DConfiguration.Concurrency= flag which now allows to override the number of threads. #9643 * `icinga2 node wizard`: avoid unnecessary chown(2) which may fail and abort the wizard. #8744 * Correct several log messages. #8895 #8965 #9663 ### ITL Add `linux_netdev` check command. #9045 #### Command Argument Changes * `disk`: don't pass -m (`disk_megabytes`) by default. #9642 * `disk`: pass -X fuse.portal (`disk_exclude_type`) by default. #9459 * `http`: support multiple -k (`http_header`) as array. #8574 * `icmp`: double defaults for -w (`icmp_wpl`) and -c (`icmp_cpl`). #9041 * `logfiles`: pass --winwarncrit (`logfiles_winwarncrit`) without argument. #9056 * `nwc_health`: pass SNMPv3-only args only when using SNMPv3. #9095 * `vmware-esx-dc-runtime-tools` and `vmware-esx-soap-vm-runtime-tools`: rename `--open-vm-tools` to `--open_vm_tools_ok` (`vmware_openvmtools`). #9611 #### New Command Arguments | Command | Argument | Custom Variable | PR | |------------------------------------|------------------------------|------------------------------------------|-------| | `disk` | `-P` | `disk_inode_perfdata` | #9494 | | `esxi_hardware` | `--format` | `esxi_hardware_format` | #9435 | | `esxi_hardware` | `--pretty` | `esxi_hardware_pretty` | #9435 | | `http` | `--verify-host` | `http_verify_host` | #8005 | | `icingacli-businessprocess` | `--ack-is-ok` | `icingacli_businessprocess_ackisok` | #9103 | | `icingacli-businessprocess` | `--blame` | `icingacli_businessprocess_blame` | #9103 | | `icingacli-businessprocess` | `--colors` | `icingacli_businessprocess_colors` | #9103 | | `icingacli-businessprocess` | `--downtime-is-ok` | `icingacli_businessprocess_downtimeisok` | #9103 | | `icingacli-businessprocess` | `--root-cause` | `icingacli_businessprocess_rootcause` | #9103 | | `mem` | `-a` | `mem_available` | #9385 | | `mongodb` | `--disable_retry_writes` | `mongodb_disableretrywrites` | #9539 | | `mongodb` | `--ssl-ca-cert-file` | `mongodb_ssl_ca_cert_file` | #9610 | | `mysql` | `--extra-opts` | `mysql_extra_opts` | #9197 | | `nrpe` | `-3` | `nrpe_version_3` | #9296 | | `nrpe` | `-D` | `nrpe_no_logging` | #9016 | | `nrpe` | `-P` | `nrpe_payload_size` | #9032 | | `pgsql` | `--extra-opts` | `pgsql_extra_opts` | #9197 | | `postgres` | `$PGCONTROLDATA` (env. var.) | `postgres_pgcontroldata` | #8929 | | `postgres` | `--datadir` | `postgres_datadir` | #8924 | | `postgres` | `--language` | `postgres_language` | #8924 | | `postgres` | `--perflimit` | `postgres_perflimit` | #8924 | | `ssl_cert` | `--ignore-host-cn` | `ssl_cert_ignore_host_cn` | #9512 | | `ssl_cert` | `--ignore-ocsp-errors` | `ssl_cert_ignore_ocsp_errors` | #9512 | | `ssl_cert` | `--ignore-ocsp-timeout` | `ssl_cert_ignore_ocsp_timeout` | #9512 | | `ssl_cert` | `--ignore-tls-renegotiation` | `ssl_cert_ignore_tls_renegotiation` | #9042 | | `ssl_cert` | `--proxy` | `ssl_cert_proxy` | #8927 | | `tcp` | `--sni` | `tcp_sni` | #9347 | | `vmware-esx-dc-runtime-tools` | `--no_vm_tools_ok` | `vmware_novmtools` | #9611 | | `vmware-esx-soap-vm-runtime-tools` | `--no_vm_tools_ok` | `vmware_novmtools` | #9611 | ### Miscellaneous * Require GCC 7+ for building to enable C++17. #9133 #9485 #9489 * Require CMake v2.8.12+ for building. (Compatibility with older ones will be removed from a future CMake version.) #9706 * Repair config reload on OpenBSD by using waitpid(2), not a SIGCHLD handler. #9518 * Ignore SIGHUP in main process to allow `/etc/rc.d/icinga2 reload` sending it to all Icinga 2 processes on OpenBSD. #9622 * Fix crash in debug build on macOS when API and debug log are enabled. #9497 * Update Boost shipped on Windows to v1.82. #9761 * Update OpenSSL shipped on Windows to v3.0.9. #9787 * Update vendored https://github.com/nlohmann/json to v3.9.1. #9675 * Update vendored https://github.com/nemtrif/utfcpp to v3.2.3. #9683 * Documentation: several fixes and improvements. #8954 #9741 #9763 #9767 #9769 #9777 * Several code quality improvements. #8815 #9106 #9250 #9508 #9517 #9537 #9594 #9605 #9606 #9641 #9658 #9702 #9717 #9738 ## 2.13.10 (2024-11-12) This security release fixes a TLS certificate validation bypass. Given the severity of that issue, users are advised to upgrade all nodes immediately. * Security: fix TLS certificate validation bypass. CVE-2024-49369 * Security: update OpenSSL shipped on Windows to v3.0.15. * Windows: sign MSI packages with a certificate the OS trusts by default. ## 2.13.9 (2023-12-21) Version 2.13.9 is a hotfix release for masters and satellites that mainly prevents permanent disintegration of a whole cluster due to root CA expiry. ### Security * Automatically renew own root CA and distribute it to all nodes. #9934 * Update OpenSSL shipped on Windows to v3.0.12. #9945 * Disable TLS renegotiation (handshake on existing connection). #9945 ### Bugfixes * Icinga DB feature: fix crash due to missing NULL pointer check. #9945 * Icinga DB feature: fix data written into Redis crashing the Go daemon. #9945 ### Updates * Update Boost shipped on Windows to v1.83. #9945 ## 2.13.8 (2023-07-12) Version 2.13.8 is a maintenance release that fixes some bugs, especially Icinga DB crashes, and updates several bundled libraries. ### Bugfixes * Icinga DB feature: normalize several Redis data not to crash the Go daemon. #9814 * Don't hang in timed out connection attempt. #9815 * Trigger flexible downtimes not in the past if checkable is already down. #9817 * ElasticsearchWriter: fix data buffer flush race condition during stop. #9818 * SELinux: allow Icinga and its plugins to write to syslog. #9819 * Fix lost acknowledgements after re-connect. #9820 * Fix parsing of perfdata across multiple lines in plugin output. #9821 * cluster-zone check: don't complain about not connected other local zone members if there aren't any. #9822 ### Updates * Update Boost shipped on Windows to v1.82. #9816 * Update OpenSSL shipped on Windows to v3.0.9. #9816 * Update vendored https://github.com/nlohmann/json to v3.9.1. #9816 * Update vendored https://github.com/nemtrif/utfcpp to v3.2.3. #9816 ## 2.13.7 (2023-02-16) This security release updates Boost and OpenSSL libraries bundled on Windows and repairs broken SELinux policies. By the way it fixes several other bugs. ### Security * Windows: update bundled OpenSSL to v1.1.1t. #9672 ### Bugfixes * SELinux: fix user and domain creation by explicitly setting the role. #9690 * Signal handlers: don't interrupt and break plugins spawning. #9682 * Icinga DB: take check\_period into account during overdue calculation. #9679 * Avoid corrupted files: use fsync(2)/FlushFileBuffers() everywhere. #9681 * Solaris: fix compile error. #9680 ### Enhancements * Windows: update bundled Boost to v1.81. #9678 * Documentation: several fixes and improvements. #9671 ## 2.13.6 (2022-11-08) The main focus of version 2.13.6 is improved performance of Icinga DB and apply rules. Additionally, it includes bug fixes related to config loading and API permissions. ### Bugfixes * Improve the throughput of the Icinga DB feature. #9550 * Multiple changes to speed up evaluation of apply rules. #9559 #9565 #9558 * Fix a possible crash on config loading related to `ignore_on_error`. #9560 * Check API user permission on objects returned by joins. #9561 * Windows: update bundled Boost and OpenSSL versions. #9562 #9567 ## 2.13.5 (2022-08-11) Version 2.13.5 is a maintenance release that fixes some bugs, improves logging and updates the documentation as well as a bundled library. ### Bugfixes * Ensure not to write an incomplete (i.e. corrupt) state file. #9467 * ITL: Render vars.apt\_upgrade=true as --upgrade, not --upgrade=true. #9458 * Icinga DB: Don't surprise (and crash) the Go daemon with config types it doesn't know. #9480 * Icinga DB: Add missing Redis SELinux policy. #9473 * Windows: Don't spam the event log with non-error startup messages. #9457 * Windows: Update bundled version of OpenSSL. #9460 * Docs: Update RHEL 8 installation instructions. #9482 * Docs: Add RHEL 9 installation instructions. #9482 ## 2.13.4 (2022-06-30) This release brings the final changes needed for the Icinga DB 1.0 release. Addtionally, it includes some fixes and a performance improvement resulting in faster config validation and reload times. ### Bugfixes * Fix a race-condition involving object attribute updates that could result in a crash. #9395 * After a host recovered, only send problem notifications for services after they have been rechecked afterwards to avoid false notifications. #9348 * Speed up config validation by avoiding redundant serialization of objects. #9400 * Add a `separator` attribute to allow using arguments like `--key=value` as required by some check plugins. This fixes the `--upgrade` and `--dist-upgrade` arguments of `check_apt`. #9397 * Windows: Update bundled versions of Boost and OpenSSL. #9360 #9415 ### Icinga DB * Add an `icingadb` CheckCommand to allow checking if Icinga DB is healthy. #9417 * Update documentation related to Icinga DB. #9423 * Fix a bug where history events could miss the environment ID. #9396 * Properly serialize attributes of command arguments when explicitly set to `null`. #9398 * Rename some attributes to make the database schema more consistent. #9399 #9419 #9421 * Make the error message more helpful if the API isn't set up #9418 ## 2.13.3 (2022-04-14) This version includes bugfixes for many features of Icinga 2, including fixes for multiple crashes. It also includes a number of fixes and improvements for Icinga DB. ### API * The /v1/config/stages endpoint now immediately rejects parallel config updates instead of accepting and then later failing to verify and activate them. #9328 ### Certificates * The lifetime of newly issued node certificates is reduced from 15 years to 397 days. #9337 * Compare cluster certificate tickets in constant time. #9333 ### Notifications * Fix a crash that could happen while sending notifications shortly after Icinga 2 started. #9124 * Fix missing or redundant notifications after certain combinations of state changes happened while notifications were suppressed, for example during a downtime. #9285 ### Checks and Commands * Fix a deadlock when processing check results for checkables with dependencies. #9228 * Fix a message routing loop that can happen for event commands that are executed within a zone using `command_endpoint` that resulted in excessive execution of the command. #9260 ### Downtimes * Fix scheduling of downtimes for all services on child hosts. #9159 * Creating fixed downtimes starting immediately now send a corresponding notification. #9158 * Fix some issues involving daylight saving time changes that could result in an hour missing from scheduled downtimes. This fix applies to time periods as well. #9238 ### Configuration * Fix the evaluation order of default templates when used in combination with apply rules. Now default templates are imported first as stated in the documentation and as it already happens for objects defined without using apply. #9290 ### IDO * Fix an issue where contacts were not written correctly to the notification history if multiple IDO instances are active on the same node. #9242 * Explicitly set the encoding for MySQL connections as a workaround for changed defaults in Debian bullseye. #9312 * Ship a MySQL schema upgrade that fixes inconsistent version information in the full schema file and upgrade files which could have resulted in inaccurate reports of an outdated schema version. #9139 ### Performance Data Writers * Fix a race condition in the InfluxDB Writers that could result in a crash. #9237 * Fix a log message where Influxdb2Writer logged as InfluxdbWriter. #9315 * All writers no longer send metrics multiple times after HA failovers. #9322 ### Build * Fix the order of linker flags to fix builds on some ARM platforms. #9164 * Fix a regression introduced in 2.13.2 preventing non-unity builds. #9094 * Fix an issue when building within an unrelated Git repository, version information from that repository could incorrectly be used for Icinga 2. #9155 * Windows: Update bundled Boost version to 1.78.0 and OpenSSL to 1.1.1n #9325 ### Internals * Fix some race conditions due to missing synchronization. These race conditions should not have caused any practical problems besides incorrect numbers in debug log message. #9306 * Move the startup.log and status files created when validating incoming cluster config updates to /var/lib/icinga2/api and always keep the last failed startup.log to ease debugging. #9335 ### Icinga DB * The `severity` attribute was updated to match the sort order Icinga Web 2 uses for the IDO. The documentation for this attribute was already incorrect before and was updated to reflect the current functionality. #9239 #9240 * Fix the `is_sticky` attribute for comments. #9303 * Fix missing updates of `is_reachable` and `severity` in the state tables. #9241 * Removing an acknowledgement no longer incorrectly writes comment history. #9302 * Fix multiple issues so that in an HA zone, both nodes now write consistent history. #9157 #9182 #9190 * Fix that history events are no longer written when state information should be updated. #9252 * Fix an issue where incomplete comment history events were generated. #9301 **Note:** when removing comments using the API, the dedicated remove-comment action should be used instead of the objects API, otherwise no history event will be generated. * Fix handling of non-integer values for the order attribute of command arguments. #9181 **Note:** You should only specify integer values for order, other values are converted to integer before use so using fractional numbers there has no effect. * Add a dependency on icingadb-redis.service to the systemd service file so that Redis is stopped after Icinga 2. #9304 * Buffer history events in memory when the Redis connection is lost. #9271 * Add the previous soft state to the state tables. #9214 * Add missing locking on object runtime updates. #9300 ## 2.13.2 (2021-11-12) This version only includes changes needed for the release of Icinga DB 1.0.0 RC2 and doesn't include any other bugfixes or features. ### Icinga DB * Prefix command_id with command type #9085 * Decouple environment from Icinga 2 Environment constant #9082 * Make icinga:history:stream:*#event_id deterministic #9076 * Add downtime.duration & service_state.host_id to Redis #9084 * Sync checkables along with their states first #9081 * Flush both buffered states and state checksums on initial dump #9079 * Introduce icinga:history:stream:downtime#scheduled_by #9080 * Actually write parent to parent_id of zones #9078 * Set value in milliseconds for program_start in stats/heartbeat #9077 * Clean up vanished objects from icinga:checksum:*:state #9074 * Remove usernotification history stream #9073 * Write IDs of notified users into notification history stream #9071 * Make CheckResult#scheduling_source available to Icinga DB #9072 * Stream runtime state updates only to icinga:runtime:state #9068 * Publish Redis schema version via XADD icinga:schema #9069 * Don't include checkable types in history IDs #9070 * Remove unused Redis key 'icinga:zone:parent' #9075 * Make sure object relationships are handled correctly during runtime updates #9089 * Only log queries at debug level #9088 ## 2.13.1 (2021-08-19) The main focus of this version is a security vulnerability in the TLS certificate verification of our metrics writers ElasticsearchWriter, GelfWriter, InfluxdbWriter and Influxdb2Writer. Version 2.13.1 also fixes two issues indroduced with the 2.13.0 release. ### Security * Add TLS server certificate validation to ElasticsearchWriter, GelfWriter, InfluxdbWriter and Influxdb2Writer ([GHSA-cxfm-8j5v-5qr2](https://github.com/Icinga/icinga2/security/advisories/GHSA-cxfm-8j5v-5qr2)) Depending on your setup, manual intervention beyond installing the new versions may be required, so please read the more detailed information in the [release blog post](https://icinga.com/blog/2021/08/19/icinga-2-13-1-security-release//) carefully ### Bugfixes * IDO PgSQL: Fix a string quoting regression introduced in 2.13.0 #8958 * ApiListener: Automatically fall back to IPv4 in default configuration on systems without IPv6 support #8961 ## 2.13.0 (2021-08-03) [Issues and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.13.0) ### Notes Upgrading docs: https://icinga.com/docs/icinga2/snapshot/doc/16-upgrading-icinga-2/#upgrading-to-v213 Thanks to all contributors: [andygrunwald](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aandygrunwald+milestone%3A2.13.0), [BausPhi](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ABausPhi+milestone%3A2.13.0), [bebehei](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Abebehei+milestone%3A2.13.0), [Bobobo-bo-Bo-bobo](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ABobobo-bo-Bo-bobo+milestone%3A2.13.0), [efuss](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aefuss+milestone%3A2.13.0), [froehl](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Afroehl+milestone%3A2.13.0), [iustin](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aiustin+milestone%3A2.13.0), [JochenFriedrich](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AJochenFriedrich+milestone%3A2.13.0), [leeclemens](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aleeclemens+milestone%3A2.13.0), [log1-c](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Alog1-c+milestone%3A2.13.0), [lyknode](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Alyknode+milestone%3A2.13.0), [m41kc0d3](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Am41kc0d3+milestone%3A2.13.0), [MarcusCaepio](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AMarcusCaepio+milestone%3A2.13.0), [mathiasaerts](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amathiasaerts+milestone%3A2.13.0), [mcktr](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amcktr+milestone%3A2.13.0), [MEschenbacher](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AMEschenbacher+milestone%3A2.13.0), [Napsty](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ANapsty+milestone%3A2.13.0), [netson](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Anetson+milestone%3A2.13.0), [pdolinic](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Apdolinic+milestone%3A2.13.0), [Ragnra](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ARagnra+milestone%3A2.13.0), [RincewindsHat](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ARincewindsHat+milestone%3A2.13.0), [sbraz](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Asbraz+milestone%3A2.13.0), [sni](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Asni+milestone%3A2.13.0), [sysadt](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Asysadt+milestone%3A2.13.0), [XnS](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AXnS+milestone%3A2.13.0), [yayayayaka](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Ayayayayaka+milestone%3A2.13.0) ### Enhancements * Core * PerfdataValue: Add units of measurement #7871 * Flapping: Allow to ignore states in flapping detection #8600 * Cluster * Display log message if two nodes run on incompatible versions #8088 * API * /v1/actions/remove-downtime: Also remove child downtimes #8913 * Add API endpoint: /v1/actions/execute-command #8040 * /v1/actions/add-comment: Add param expiry #8035 * API-Event StateChange & CheckResult: Add acknowledgement and downtime_depth #7736 * Implement new API events ObjectCreated, ObjectDeleted and ObjectModified #8083 * Implement scheduling_endpoint attribute to checkable #6326 * Windows * Add support for Windows Event Log and write early log messages to it #8710 * IDO * MySQL: support larger host and service names #8425 * ITL * Add -S parameter for esxi_hardware ITL #8814 * Add CheckCommands for Thola #8683 * Add option ignore-sct for ssl_cert to ITL #8625 * Improve check_dns command when used with monitoring-plugins 2.3 #8589 * Add parameter -f to snmp-process #8569 * Add systemd CheckCommand #8568 * Add new options for ipmi-sensor #8498 * check_snmp_int: support -a #8003 * check_fail2ban: Add parameter fail2ban_jail to monitor a specific jail only #7960 * check_nrpe: Add parameters needed for PKI usage #7907 * Metrics * Support InfluxDB 2.0 #8719 * Add support for InfluxDB basic auth #8314 * Docs * Add info about ongoing support for IDO #8446 * Improve instructions on how to setup a Windows dev env #8400 * Improve instructions for installing wixtoolset on Windows #8397 * Add section about usage of satellites #8458 * Document command for verifying the parent node's certificate #8221 * Clarify TimePeriod/ScheduledDowntime time zone handling #8001 * Misc * Support TLS 1.3 #8718 * Livestatus: append app name to program_version #7931 * sd_notify() systemd about what we're doing right now #7874 ### Bugfixes * Core * Fix state not being UNKNOWN after process timeout #8937 * Set a default severity for loggers #8846 * Fix integer overflow when converting large unsigned integers to string #8742 * StartUnixWorker(): don't exit() on fork() failure #8427 * Fix perf data parser not recognizing scientific notation #8492 * Close FDs based on /proc/self/fd #8442 * Fix check source getting overwritten on passive check result #8158 * Clean up temp files #8157 * Improve perf data parser to allow for special output (e.g. ASCII tables) #8008 * On check timeout first send SIGTERM #7918 * Cluster * Drop passive check results for unreachable hosts/services #8267 * Fix state timestamps set by the same check result differing across nodes #8101 * API * Do not override status codes that are not 200 #8532 * Update the SSL context after accepting incoming connections #8515 * Allow to create API User with password #8321 * Send Content-Type as API response header too #8108 * Display a correct status when removing a downtime #8104 * Display log message if a permission error occurs #8087 * Replace broken package name validation regex #8825 #8946 * Windows * Fix Windows command escape for \" #7092 * Notifications/Downtimes * Fix no re-notification for non OK state changes with time delay #8562 * TimePeriod/ScheduledDowntime: Improve DST handling #8921 * Don't send notifications while suppressed by checkable #8513 * Fix a crash while removing a downtime from a disappeared checkable #8229 * IDO * Update program status on stop #8730 * Also mark objects inactive in memory on object deactivation #8626 * IdoCheckTask: Don't override checkable critical with warn state #8613 * PostgreSQL: Do not set standard_conforming_strings to off #8123 * ITL * check_http: Fix assignment of check_adress blocking check by hostname #8109 * check_mysql: Don't set -H if -s is given #8020 * Metrics * OpenTSDB-Writer: Remove incorrect space causing missing tag error #8245 ## 2.12.5 (2021-07-15) Version 2.12.5 fixes two security vulnerabilities that may lead to privilege escalation for authenticated API users. Other improvements include several bugfixes related to downtimes, downtime notifications, and more reliable connection handling. ### Security * Don't expose the PKI ticket salt via the API. This may lead to privilege escalation for authenticated API users by them being able to request certificates for other identities (CVE-2021-32739) * Don't expose IdoMysqlConnection, IdoPgsqlConnection, IcingaDB, and ElasticsearchWriter passwords via the API (CVE-2021-32743) * Windows: Update bundled OpenSSL to version 1.1.1k #8885 Depending on your setup, manual intervention beyond installing the new versions may be required, so please read the more detailed information in the [release blog post](https://icinga.com/blog/2021/07/15/releasing-icinga-2-12-5-and-2-11-10/) carefully. ### Bugfixes * Don't send downtime end notification if downtime hasn't started #8877 * Don't let a failed downtime creation block the others #8863 * Support downtimes and comments for checkables with long names #8864 * Trigger fixed downtimes immediately if the current time matches (instead of waiting for the timer) #8889 * Add configurable timeout for full connection handshake #8866 ### Enhancements * Replace existing downtimes on ScheduledDowntime change #8879 * Improve crashlog #8865 ## 2.12.4 (2021-05-27) Version 2.12.4 is a maintenance release that fixes some crashes, improves error handling and adds compatibility for systems coming with newer Boost versions. ### Bugfixes * Fix a crash when notification objects are deleted using the API #8782 * Fix crashes that might occur during downtime scheduling if host or downtime objects are deleted using the API #8785 * Fix an issue where notifications may incorrectly be skipped after a downtime ends #8775 * Don't send reminder notification if the notification is still suppressed by a time period #8808 * Fix an issue where attempting to create a duplicate object using the API might result in the original object being deleted #8787 * IDO: prioritize program status updates #8809 * Improve exceptions handling, including a fix for an uncaught exception on Windows #8777 * Retry file rename operations on Windows to avoid intermittent locking issues #8771 ### Enhancements * Support Boost 1.74 (Ubuntu 21.04, Fedora 34) #8792 ## 2.12.3 (2020-12-15) Version 2.12.3 resolves a security vulnerability with revoked certificates being renewed automatically ignoring the CRL. This version also resolves issues with high load on Windows regarding the config sync and not being able to disable/enable Icinga 2 features over the API. ### Security * Fix that revoked certificates due for renewal will automatically be renewed ignoring the CRL (CVE-2020-29663) When a CRL is specified in the ApiListener configuration, Icinga 2 only used it when connections were established so far, but not when a certificate is requested. This allows a node to automatically renew a revoked certificate if it meets the other conditions for auto renewal (issued before 2017 or expires in less than 30 days). Because Icinga 2 currently (v2.12.3 and earlier) uses a validity duration of 15 years, this only affects setups with external certificate signing and revoked certificates that expire in less then 30 days. ### Bugfixes * Improve config sync locking - resolves high load issues on Windows #8511 * Fix runtime config updates being ignored for objects without zone #8549 * Use proper buffer size for OpenSSL error messages #8542 ### Enhancements * On checkable recovery: re-check children that have a problem #8506 ## 2.12.2 (2020-12-01) Version 2.12.2 fixes several issues to improve the reliability of the cluster functionality. ### Bugfixes * Fix a connection leak with misconfigured agents #8483 * Properly sync changes of config objects in global zones done via the API #8474 #8470 * Prevent other clients from being disconnected when replaying the cluster log takes very long #8496 * Avoid duplicate connections between endpoints #8465 * Ignore incoming config object updates for unknown zones #8461 * Check timestamps before removing files in config sync #8495 ### Enhancements * Include HTTP status codes in log #8467 ## 2.12.1 (2020-10-15) Version 2.12.1 fixes several crashes, deadlocks and excessive check latencies. It also addresses several bugs regarding IDO, API, notifications and checks. ### Bugfixes * Core * Fix crashes during config update #8348 #8345 * Fix crash while removing a downtime #8228 * Ensure the daemon doesn't get killed by logrotate #8170 * Fix hangup during shutdown #8211 * Fix a deadlock in Icinga DB #8168 * Clean up zombie processes during reload #8376 * Reduce check latency #8276 * IDO * Prevent unnecessary IDO updates #8327 #8320 * Commit IDO MySQL transactions earlier #8349 * Make sure to insert IDO program status #8330 * Improve IDO queue stats logging #8271 #8328 #8379 * Misc * Ensure API connections are closed properly #8293 * Prevent unnecessary notifications #8299 * Don't skip null values of command arguments #8174 * Fix Windows .exe version #8234 * Reset Icinga check warning after successful config update #8189 ## 2.12.0 (2020-08-05) [Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.12.0) ### Notes Upgrading docs: https://icinga.com/docs/icinga2/snapshot/doc/16-upgrading-icinga-2/#upgrading-to-v212 Thanks to all contributors: [Ant1x](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AAnt1x+milestone%3A2.12.0), [azthec](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aazthec+milestone%3A2.12.0), [baurmatt](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Abaurmatt+milestone%3A2.12.0), [bootc](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Abootc+milestone%3A2.12.0), [Foxeronie](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AFoxeronie+milestone%3A2.12.0), [ggzengel](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aggzengel+milestone%3A2.12.0), [islander](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aislander+milestone%3A2.12.0), [joni1993](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Ajoni1993+milestone%3A2.12.0), [KAMI911](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AKAMI911+milestone%3A2.12.0), [mcktr](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amcktr+milestone%3A2.12.0), [MichalMMac](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AMichalMMac+milestone%3A2.12.0), [sebastic](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Asebastic+milestone%3A2.12.0), [sthen](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Asthen+milestone%3A2.12.0), [unki](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aunki+milestone%3A2.12.0), [vigiroux](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Avigiroux+milestone%3A2.12.0), [wopfel](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Awopfel+milestone%3A2.12.0) ### Breaking changes * Deprecate Windows plugins in favor of our [PowerShell plugins](https://github.com/Icinga/icinga-powershell-plugins) #8071 * Deprecate Livestatus #8051 * Refuse acknowledging an already acknowledged checkable #7695 * Config lexer: complain on EOF in heredocs, i.e. `{{{abc` #7541 ### Enhancements * Core * Implement new database backend: Icinga DB #7571 * Re-send notifications previously suppressed by their time periods #7816 * API * Host/Service: Add `acknowledgement_last_change` and `next_update` attributes #7881 #7534 * Improve error message for POST queries #7681 * /v1/actions/remove-comment: let users specify themselves #7646 * /v1/actions/remove-downtime: let users specify themselves #7645 * /v1/config/stages: Add 'activate' parameter #7535 * CLI * Add `pki verify` command for better TLS certificate troubleshooting #7843 * Add OpenSSL version to 'Build' section in --version #7833 * Improve experience with 'Node Setup for Agents/Satellite' #7835 * DSL * Add `get_template()` and `get_templates()` #7632 * `MacroProcessor::ResolveArguments()`: skip null argument values #7567 * Fix crash due to dependency apply rule with `ignore_on_error` and non-existing parent #7538 * Introduce ternary operator (`x ? y : z`) #7442 * LegacyTimePeriod: support specifying seconds #7439 * Add support for Lambda Closures (`() use(x) => x and () use(x) => { return x }`) #7417 * ITL * Add notemp parameter to oracle health #7748 * Add extended checks options to snmp-interface command template #7602 * Add file age check for Windows command definition #7540 * Docs * Development: Update debugging instructions #7867 * Add new API clients #7859 * Clarify CRITICAL vs. UNKNOWN #7665 * Explicitly explain how to disable freshness checks #7664 * Update installation for RHEL/CentOS 8 and SLES 15 #7640 * Add Powershell example to validate the certificate #7603 * Misc * Don't send `event::Heartbeat` to unauthenticated peers #7747 * OpenTsdbWriter: Add custom tag support #7357 ### Bugfixes * Core * Fix JSON-RPC crashes #7532 #7737 * Fix zone definitions in zones #7546 * Fix deadlock during start on OpenBSD #7739 * Consider PENDING not a problem #7685 * Fix zombie processes after reload #7606 * Don't wait for checks to finish during reload #7894 * Cluster * Fix segfault during heartbeat timeout with clients not yet signed #7970 * Make the config update process mutually exclusive (Prevents file system race conditions) #7936 * Fix `check_timeout` not being forwarded to agent command endpoints #7861 * Config sync: Use a more friendly message when configs are equal and don't need a reload #7811 * Fix open connections when agent waits for CA approval #7686 * Consider a JsonRpcConnection alive on a single byte of TLS payload, not only on a whole message #7836 * Send JsonRpcConnection heartbeat every 20s instead of 10s #8102 * Use JsonRpcConnection heartbeat only to update connection liveness (m\_Seen) #8142 * Fix TLS context not being updated on signed certificate messages on agents #7654 * API * Close connections w/o successful TLS handshakes after 10s #7809 * Handle permission exceptions soon enough, returning 404 #7528 * SELinux * Fix safe-reload #7858 * Allow direct SMTP notifications #7749 * Windows * Terminate check processes with UNKNOWN state on timeout #7788 * Ensure that log replay files are properly renamed #7767 * Metrics * Graphite/OpenTSDB: Ensure that reconnect failure is detected #7765 * Always send 0 as value for thresholds #7696 * Scripts * Fix notification scripts to stay compatible with Dash #7706 * Fix bash line continuation in mail-host-notification.sh #7701 * Fix notification scripts string comparison #7647 * Service and host mail-notifications: Add line-breaks to very long output #6822 * Set correct UTF-8 email subject header (RFC1342) #6369 * Misc * DSL: Fix segfault due to passing null as custom function to `Array#{sort,map,reduce,filter,any,all}()` #8053 * CLI: `pki save-cert`: allow to specify --key and --cert for backwards compatibility #7995 * Catch exception when trusted cert is not readable during node setup on agent/satellite #7838 * CheckCommand ssl: Fix wrong parameter `-N` #7741 * Code quality fixes * Small documentation fixes ## 2.12.0 RC1 (2020-03-13) [Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.12.0) ### Notes Upgrading docs: https://icinga.com/docs/icinga2/snapshot/doc/16-upgrading-icinga-2/#upgrading-to-v212 Thanks to all contributors: [Ant1x](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AAnt1x+milestone%3A2.12.0), [azthec](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aazthec+milestone%3A2.12.0), [baurmatt](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Abaurmatt+milestone%3A2.12.0), [bootc](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Abootc+milestone%3A2.12.0), [Foxeronie](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AFoxeronie+milestone%3A2.12.0), [ggzengel](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aggzengel+milestone%3A2.12.0), [islander](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aislander+milestone%3A2.12.0), [joni1993](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Ajoni1993+milestone%3A2.12.0), [KAMI911](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AKAMI911+milestone%3A2.12.0), [mcktr](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amcktr+milestone%3A2.12.0), [MichalMMac](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AMichalMMac+milestone%3A2.12.0), [sebastic](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Asebastic+milestone%3A2.12.0), [sthen](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Asthen+milestone%3A2.12.0), [unki](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aunki+milestone%3A2.12.0), [vigiroux](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Avigiroux+milestone%3A2.12.0), [wopfel](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Awopfel+milestone%3A2.12.0), ### Breaking changes * Refuse acknowledging an already acknowledged checkable #7695 * Config lexer: complain on EOF in heredocs, i.e. `{{{abc` #7541 ### Enhancements * Core * Implement new database backend: Icinga DB #7571 * API * Host/Service: Add `acknowledgement_last_change` and `next_update` attributes #7881 #7534 * Improve error message for POST queries #7681 * /v1/actions/remove-comment: let users specify themselves #7646 * /v1/actions/remove-downtime: let users specify themselves #7645 * /v1/config/stages: Add 'activate' parameter #7535 * CLI * Add `pki verify` command for better TLS certificate troubleshooting #7843 * Add OpenSSL version to 'Build' section in --version #7833 * Improve experience with 'Node Setup for Agents/Satellite' #7835 * DSL * Add `get_template()` and `get_templates()` #7632 * `MacroProcessor::ResolveArguments()`: skip null argument values #7567 * Fix crash due to dependency apply rule with `ignore_on_error` and non-existing parent #7538 * Introduce ternary operator (`x ? y : z`) #7442 * LegacyTimePeriod: support specifying seconds #7439 * Add support for Lambda Closures (`() use(x) => x and () use(x) => { return x }`) #7417 * ITL * Add notemp parameter to oracle health #7748 * Add extended checks options to snmp-interface command template #7602 * Add file age check for Windows command definition #7540 * Docs * Development: Update debugging instructions #7867 * Add new API clients #7859 * Clarify CRITICAL vs. UNKNOWN #7665 * Explicitly explain how to disable freshness checks #7664 * Update installation for RHEL/CentOS 8 and SLES 15 #7640 * Add Powershell example to validate the certificate #7603 * Misc * Don't send `event::Heartbeat` to unauthenticated peers #7747 * OpenTsdbWriter: Add custom tag support #7357 ### Bugfixes * Core * Fix JSON-RPC crashes #7532 #7737 * Fix zone definitions in zones #7546 * Fix deadlock during start on OpenBSD #7739 * Consider PENDING not a problem #7685 * Fix zombie processes after reload #7606 * Cluster * Fix `check_timeout` not being forwarded to agent command endpoints #7861 * Config sync: Use a more friendly message when configs are equal and don't need a reload #7811 * Fix open connections when agent waits for CA approval #7686 * Fix TLS context not being updated on signed certificate messages on agents #7654 * API * Close connections w/o successful TLS handshakes after 10s #7809 * Handle permission exceptions soon enough, returning 404 #7528 * SELinux * Fix safe-reload #7858 * Allow direct SMTP notifications #7749 * Windows * Terminate check processes with UNKNOWN state on timeout #7788 * Ensure that log replay files are properly renamed #7767 * Metrics * Graphite/OpenTSDB: Ensure that reconnect failure is detected #7765 * Always send 0 as value for thresholds #7696 * Scripts * Fix notification scripts to stay compatible with Dash #7706 * Fix bash line continuation in mail-host-notification.sh #7701 * Fix notification scripts string comparison #7647 * Service and host mail-notifications: Add line-breaks to very long output #6822 * Set correct UTF-8 email subject header (RFC1342) #6369 * Misc * Catch exception when trusted cert is not readable during node setup on agent/satellite #7838 * CheckCommand ssl: Fix wrong parameter `-N` #7741 * Code quality fixes * Small documentation fixes ## 2.11.12 (2024-11-12) This security release fixes a TLS certificate validation bypass. Given the severity of that issue, users are advised to upgrade all nodes immediately. * Security: fix TLS certificate validation bypass. CVE-2024-49369 * Security: update OpenSSL shipped on Windows to v3.0.15. * Windows: sign MSI packages with a certificate the OS trusts by default. ## 2.11.11 (2021-08-19) The main focus of these versions is a security vulnerability in the TLS certificate verification of our metrics writers ElasticsearchWriter, GelfWriter and InfluxdbWriter. ### Security * Add TLS server certificate validation to ElasticsearchWriter, GelfWriter and InfluxdbWriter Depending on your setup, manual intervention beyond installing the new versions may be required, so please read the more detailed information in the [release blog post](https://icinga.com/blog/2021/08/19/icinga-2-13-1-security-release//) carefully ## 2.11.10 (2021-07-15) Version 2.11.10 fixes two security vulnerabilities that may lead to privilege escalation for authenticated API users. Other improvements include several bugfixes related to downtimes, downtime notifications, and more reliable connection handling. ### Security * Don't expose the PKI ticket salt via the API. This may lead to privilege escalation for authenticated API users by them being able to request certificates for other identities (CVE-2021-32739) * Don't expose IdoMysqlConnection, IdoPgsqlConnection, and ElasticsearchWriter passwords via the API (CVE-2021-32743) * Windows: Update bundled OpenSSL to version 1.1.1k #8888 Depending on your setup, manual intervention beyond installing the new versions may be required, so please read the more detailed information in the [release blog post](https://icinga.com/blog/2021/07/15/releasing-icinga-2-12-5-and-2-11-10/) carefully. ### Bugfixes * Don't send downtime end notification if downtime hasn't started #8878 * Don't let a failed downtime creation block the others #8871 * Support downtimes and comments for checkables with long names #8870 * Trigger fixed downtimes immediately if the current time matches (instead of waiting for the timer) #8891 * Add configurable timeout for full connection handshake #8872 ### Enhancements * Replace existing downtimes on ScheduledDowntime change #8880 * Improve crashlog #8869 ## 2.11.9 (2021-05-27) Version 2.11.9 is a maintenance release that fixes some crashes, improves error handling and adds compatibility for systems coming with newer Boost versions. ### Bugfixes * Fix a crash when notification objects are deleted using the API #8780 * Fix crashes that might occur during downtime scheduling if host or downtime objects are deleted using the API #8784 * Fix an issue where notifications may incorrectly be skipped after a downtime ends #8772 * Fix an issue where attempting to create a duplicate object using the API might result in the original object being deleted #8788 * IDO: prioritize program status updates #8810 * Improve exceptions handling, including a fix for an uncaught exception on Windows #8776 * Retry file rename operations on Windows to avoid intermittent locking issues #8770 ### Enhancements * Support Boost 1.74 (Ubuntu 21.04, Fedora 34) #8793 #8802 ## 2.11.8 (2020-12-15) Version 2.11.8 resolves a security vulnerability with revoked certificates being renewed automatically ignoring the CRL. This version also resolves issues with high load on Windows regarding the config sync and not being able to disable/enable Icinga 2 features over the API. ### Security * Fix that revoked certificates due for renewal will automatically be renewed ignoring the CRL (CVE-2020-29663) When a CRL is specified in the ApiListener configuration, Icinga 2 only used it when connections were established so far, but not when a certificate is requested. This allows a node to automatically renew a revoked certificate if it meets the other conditions for auto renewal (issued before 2017 or expires in less than 30 days). Because Icinga 2 currently (v2.12.3 and earlier) uses a validity duration of 15 years, this only affects setups with external certificate signing and revoked certificates that expire in less then 30 days. ### Bugfixes * Improve config sync locking - resolves high load issues on Windows #8510 * Fix runtime config updates being ignored for objects without zone #8550 * Use proper buffer size for OpenSSL error messages #8543 ### Enhancements * On checkable recovery: re-check children that have a problem #8560 ## 2.11.7 (2020-12-01) Version 2.11.7 fixes several issues to improve the reliability of the cluster functionality. ### Bugfixes * Fix a connection leak with misconfigured agents #8482 * Properly sync changes of config objects in global zones done via the API #8473 #8457 * Prevent other clients from being disconnected when replaying the cluster log takes very long #8475 * Avoid duplicate connections between endpoints #8399 * Ignore incoming config object updates for unknown zones #8459 * Check timestamps before removing files in config sync #8486 ### Enhancements * Include HTTP status codes in log #8454 ## 2.11.6 (2020-10-15) Version 2.11.6 fixes several crashes, prevents unnecessary notifications and addresses several bugs in IDO and API. ### Bugfixes * Crashes * Fix crashes during config update #8337 #8308 * Fix crash while removing a downtime #8226 * Ensure the daemon doesn't get killed by logrotate #8227 * IDO * Prevent unnecessary IDO updates #8316 #8305 * Commit IDO MySQL transactions earlier #8298 * Make sure to insert IDO program status #8291 * Improve IDO queue stats logging #8270 #8325 #8378 * API * Ensure API connections are closed properly #8292 * Fix open connections when agent waits for CA approval #8230 * Close connections without successful TLS handshakes within 10s #8224 * Misc * Prevent unnecessary notifications #8300 * Fix Windows .exe version #8235 * Reset Icinga check warning after successful config update #8225 ## 2.11.5 (2020-08-05) Version 2.11.5 fixes file system race conditions in the config update process occurring in large HA environments and improves the cluster connection liveness mechanisms. ### Bugfixes * Make the config update process mutually exclusive (Prevents file system race conditions) #8093 * Consider a JsonRpcConnection alive on a single byte of TLS payload, not only on a whole message #8094 * Send JsonRpcConnection heartbeat every 20s instead of 10s #8103 * Use JsonRpcConnection heartbeat only to update connection liveness (m\_Seen) #8097 ## 2.11.4 (2020-06-18) Version 2.11.4 fixes a crash during a heartbeat timeout with clients not yet signed. It also resolves an issue with endpoints not reconnecting after a reload/deploy, which caused a lot of UNKNOWN states. ### Bugfixes * Cluster * Fix segfault during heartbeat timeout with clients not yet signed #7997 * Fix endpoints not reconnecting after reload (UNKNOWN hosts/services after reload) #8043 * Setup * Fix exception on trusted cert not readable during node setup #8044 * prepare-dirs: Only set permissions during directory creation #8046 * DSL * Fix segfault on missing compare function in Array functions (sort, map, reduce, filter, any, all) #8054 ## 2.11.3 (2020-03-02) The 2.11.3 release fixes a critical crash in our JSON-RPC connections. This mainly affects large HA enabled environments. ### Bugfixes * Cluster * JSON-RPC Crashes with 2.11 #7532 ## 2.11.2 (2019-10-24) 2.11.2 fixes a problem where the newly introduced config sync "check-change-then-reload" functionality could cause endless reload loops with agents. The most visible parts are failing command endpoint checks with "not connected" UNKNOWN state. **Only applies to HA enabled zones with 2 masters and/or 2 satellites.** ### Bugfixes * Cluster Config Sync * Config sync checksum change detection may not work within high load HA clusters #7565 ## 2.11.1 (2019-10-17) This release fixes a hidden long lasting bug unveiled with 2.11 and distributed setups. If you are affected by agents/satellites not accepting configuration anymore, or not reloading, please upgrade. ### Bugfixes * Cluster Config Sync * Never accept authoritative config markers from other instances #7552 * This affects setups where agent/satellites are newer than the config master, e.g. satellite/agent=2.11.0, master=2.10. * Configuration * Error message for `command_endpoint` should hint that zone is not set #7514 * Global variable 'ActiveStageOverride' has been set implicitly via 'ActiveStageOverride ... #7521 ### Documentation * Docs: Add upgrading/troubleshooting details for repos, config sync, agents #7526 * Explain repository requirements for 2.11: https://icinga.com/docs/icinga2/latest/doc/16-upgrading-icinga-2/#added-boost-166 * `command_endpoint` objects require a zone: https://icinga.com/docs/icinga2/latest/doc/16-upgrading-icinga-2/#agent-hosts-with-command-endpoint-require-a-zone * Zones declared in zones.d are not loaded anymore: https://icinga.com/docs/icinga2/latest/doc/16-upgrading-icinga-2/#config-sync-zones-in-zones ## 2.11.0 (2019-09-19) [Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.11.0) ### Notes Upgrading docs: https://icinga.com/docs/icinga2/snapshot/doc/16-upgrading-icinga-2/ Thanks to all contributors: [Obihoernchen](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AObihoernchen), [dasJ](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AdasJ), [sebastic](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Asebastic), [waja](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Awaja), [BarbUk](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ABarbUk), [alanlitster](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aalanlitster), [mcktr](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amcktr), [KAMI911](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AKAMI911), [peteeckel](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Apeteeckel), [breml](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Abreml), [episodeiv](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aepisodeiv), [Crited](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ACrited), [robert-scheck](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Arobert-scheck), [west0rmann](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Awest0rmann), [Napsty](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ANapsty), [Elias481](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AElias481), [uubk](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Auubk), [miso231](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amiso231), [neubi4](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aneubi4), [atj](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aatj), [mvanduren-itisit](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amvanduren-itisit), [jschanz](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Ajschanz), [MaBauMeBad](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AMaBauMeBad), [markleary](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amarkleary), [leeclemens](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aleeclemens), [m4k5ym](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Am4k5ym) ### Enhancements * Core * Rewrite Network Stack (cluster, REST API) based on Boost Asio, Beast, Coroutines * Technical concept: #7041 * Requires package updates: Boost >1.66 (either from packages.icinga.com, EPEL or backports). SLES11 & Ubuntu 14 are EOL. * Require TLS 1.2 and harden default cipher list * Improved Reload Handling (umbrella process, now 3 processes at runtime) * Support running Icinga 2 in (Docker) containers natively in foreground * Quality: Use Modern JSON for C++ library instead of YAJL (dead project) * Quality: Improve handling of invalid UTF8 strings * API * Fix crashes on Linux, Unix and Windows from Nessus scans #7431 * Locks and stalled waits are fixed with the core rewrite in #7071 * schedule-downtime action supports `all_services` for host downtimes * Improve storage handling for runtime created objects in the `_api` package * Cluster * HA aware features & improvements for failover handling #2941 #7062 * Improve cluster config sync with staging #6716 * Fixed that same downtime/comment objects would be synced again in a cluster loop #7198 * Checks & Notifications * Ensure that notifications during a restart are sent * Immediately notify about a problem after leaving a downtime and still NOT-OK * Improve reload handling and wait for features/metrics * Store notification command results and sync them in HA enabled zones #6722 * DSL/Configuration * Add getenv() function * Fix TimePeriod range support over midnight * `concurrent_checks` in the Checker feature has no effect, use the global MaxConcurrentChecks constant instead * CLI * Permissions: node wizard/setup, feature, api setup now run in the Icinga user context, not root * `ca list` shows pending CSRs by default, `ca remove/restore` allow to delete signing requests * ITL * Add new commands and missing attributes * Windows * Update bundled NSClient++ to 0.5.2.39 * Refine agent setup wizard & update requirements to .NET 4.6 * Documentation * Service Monitoring: How to create plugins by example, check commands and a modern version of the supported plugin API with best practices * Features: Better structure on metrics, and supported features * Technical Concepts: TLS Network IO, Cluster Feature HA, Cluster Config Sync * Development: Rewritten for better debugging and development experience for contributors including a style guide. Add nightly build setup instructions. * Packaging: INSTALL.md was integrated into the Development chapter, being available at https://icinga.com/docs too. ## 2.11.0 RC1 (2019-07-25) [Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.11.0) ### Notes **This is the first release candidate for 2.11.** Upgrading docs: https://icinga.com/docs/icinga2/snapshot/doc/16-upgrading-icinga-2/ Thanks to all contributors: [BarbUk](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ABarbUk), [alanlitster](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aalanlitster), [mcktr](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amcktr), [KAMI911](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AKAMI911), [peteeckel](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Apeteeckel), [breml](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Abreml), [episodeiv](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aepisodeiv), [Crited](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ACrited), [robert-scheck](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Arobert-scheck), [west0rmann](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Awest0rmann), [Napsty](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3ANapsty), [Elias481](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AElias481), [uubk](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Auubk), [miso231](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amiso231), [neubi4](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aneubi4), [atj](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aatj), [mvanduren-itisit](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amvanduren-itisit), [jschanz](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Ajschanz), [MaBauMeBad](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3AMaBauMeBad), [markleary](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Amarkleary), [leeclemens](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Aleeclemens), [m4k5ym](https://github.com/Icinga/icinga2/pulls?q=is%3Apr+author%3Am4k5ym) ### Enhancements * Core * Rewrite Network Stack (cluster, REST API) based on Boost Asio, Beast, Coroutines * Technical concept: #7041 * Requires package updates: Boost >1.66 (either from packages.icinga.com, EPEL or backports). SLES11 & Ubuntu 14 are EOL. * Require TLS 1.2 and harden default cipher list * Improved Reload Handling (umbrella process, now 3 processes at runtime) * Support running Icinga 2 in (Docker) containers natively in foreground * Quality: Use Modern JSON for C++ library instead of YAJL (dead project) * Quality: Improve handling of invalid UTF8 strings * API * Fix crashes and problems with permission filters from recent Namespace introduction #6785 (thanks Elias Ohm) #6874 (backported to 2.10.5) * Locks and stalled waits are fixed with the core rewrite in #7071 * schedule-downtime action supports `all_services` for host downtimes * Improve storage handling for runtime created objects in the `_api` package * Cluster * HA aware features & improvements for failover handling #2941 #7062 * Improve cluster config sync with staging #6716 * Checks & Notifications * Ensure that notifications during a restart are sent * Immediately notify about a problem after leaving a downtime and still NOT-OK * Improve reload handling and wait for features/metrics * Store notification command results and sync them in HA enabled zones #6722 * DSL/Configuration * Add getenv() function * Fix TimePeriod range support over midnight * `concurrent_checks` in the Checker feature has no effect, use the global MaxConcurrentChecks constant instead * CLI * Permissions: node wizard/setup, feature, api setup now run in the Icinga user context, not root * `ca list` shows pending CSRs by default, `ca remove/restore` allow to delete signing requests * ITL * Add new commands and missing attributes - thanks to all contributors! * Windows * Update bundled NSClient++ to 0.5.2.39 * Update agent installer and OpenSSL * Documentation * Service Monitoring: How to create plugins by example, check commands and a modern version of the supported plugin API with best practices. * Features: Better structure on metrics, and supported features. * Basics: Rename `Custom Attributes` to `Custom Variables`. * Basics: Refine explanation of command arguments. * Distributed: Reword `Icinga client` into `Icinga agent` and add new images for scenarios and modes. * Security: Add TLS v1.2+ requirement, hardened cipher lists * Technical Concepts: TLS Network IO, Cluster Feature HA, Cluster Config Sync, Core Reload Handling. * Development: Rewritten for better debugging and development experience for contributors including a style guide. Add nightly build setup instructions. * Packaging: INSTALL.md was integrated into the Development chapter available at https://icinga.com/docs too. ## 2.10.7 (2019-10-17) [Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.10.7) ### Bugfixes * Cluster config master must not load/sync its marker to other instances #7544 * This affects scenarios where the satellite/agent is newer than the master, e.g. master=2.10.x satellite=2.11.0 ## 2.10.6 (2019-07-30) [Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.10.6) ### Bugfixes * Fix el7 not loading ECDHE cipher suites #7247 ## 2.10.5 (2019-05-23) [Issues and PRs](https://github.com/Icinga/icinga2/milestone/81?closed=1) ### Bugfixes * Core * Fix crashes with logrotate signals #6737 (thanks Elias Ohm) * API * Fix crashes and problems with permission filters from recent Namespace introduction #6785 (thanks Elias Ohm) #6874 (backported from 2.11) * Reduce log spam with locked connections (real fix is the network stack rewrite in 2.11) #6877 * Cluster * Fix problems with replay log rotation and storage #6932 (thanks Peter Eckel) * IDO DB * Fix that reload shutdown deactivates hosts and hostgroups (introduced in 2.9) #7157 * Documentation * Improve the [REST API](https://icinga.com/docs/icinga2/latest/doc/12-icinga2-api/) chapter: Unix timestamp handling, filters, unify POST requests with filters in the body * Better layout for the [features](https://icinga.com/docs/icinga2/latest/doc/14-features/) chapter, specifically metrics and events * Split [object types](https://icinga.com/docs/icinga2/latest/doc/09-object-types/) into monitoring, runtime, features * Add technical concepts for [cluster messages](https://icinga.com/docs/icinga2/latest/doc/19-technical-concepts/#json-rpc-message-api) ## 2.10.4 (2019-03-19) ### Notes * Fix TLS connections in Influxdb/Elasticsearch features leaking file descriptors (#6989 #7018 ref/IP/12219) * Fixes for delayed and one-time notifications (#5561 #6757) * Improve performance for downtimes/comments added in HA clusters (#6885 ref/IP/9235) * check_perfmon supports non-localized performance counter names (#5546 #6418) ### Enhancement * [#6732](https://github.com/icinga/icinga2/issues/6732) (Windows, PR): Update Windows Agent with new design * [#6729](https://github.com/icinga/icinga2/issues/6729) (Windows): Polish the Windows Agent design * [#6418](https://github.com/icinga/icinga2/issues/6418) (Windows): check\_perfmon.exe: Add fallback support for localized performance counters ### Bug * [#7020](https://github.com/icinga/icinga2/issues/7020) (Elasticsearch, PR): ElasticsearchWriter: don't leak sockets * [#7018](https://github.com/icinga/icinga2/issues/7018) (Elasticsearch): ElasticsearchWriter not closing SSL connections on Icinga2 2.10.3.1 * [#6991](https://github.com/icinga/icinga2/issues/6991) (CLI, PR): PkiUtility::NewCa\(\): just warn if the CA files already exist * [#6990](https://github.com/icinga/icinga2/issues/6990) (InfluxDB, PR): InfluxdbWriter: don't leak sockets * [#6989](https://github.com/icinga/icinga2/issues/6989) (InfluxDB): InfluxdbWriter not closing connections Icinga2 2.10.3 CentOS 7 * [#6976](https://github.com/icinga/icinga2/issues/6976) (Cluster, PR): Don't require OS headers to provide SO\_REUSEPORT * [#6896](https://github.com/icinga/icinga2/issues/6896) (Notifications, PR): Notification\#BeginExecuteNotification\(\): SetNextNotification\(\) correctly * [#6885](https://github.com/icinga/icinga2/issues/6885) (API, Configuration, PR): Don't run UpdateObjectAuthority for Comments and Downtimes * [#6800](https://github.com/icinga/icinga2/issues/6800) (Plugins, Windows, PR): Fix check\_perfmon to support non-localized names * [#6757](https://github.com/icinga/icinga2/issues/6757) (Notifications, PR): Fix that no\_more\_notifications gets reset when Recovery notifications are filtered away * [#5561](https://github.com/icinga/icinga2/issues/5561) (Notifications): Set the notification mode times.begin is not 0, the first notification has a delay * [#5546](https://github.com/icinga/icinga2/issues/5546) (Plugins, Windows): check\_perfmon.exe doesn't support cyrillic names of perf counters ### Documentation * [#7033](https://github.com/icinga/icinga2/issues/7033) (Documentation, PR): Docs: Update supported package repos in Getting Started chapter * [#7028](https://github.com/icinga/icinga2/issues/7028) (Documentation, PR): Fix heading level in development chapter * [#7001](https://github.com/icinga/icinga2/issues/7001) (Documentation, PR): Assignment operators doc: tell what the { } are for * [#6995](https://github.com/icinga/icinga2/issues/6995) (Documentation, PR): Typo and link fix * [#6979](https://github.com/icinga/icinga2/issues/6979) (Documentation, PR): Doc: write systemd lower-case * [#6975](https://github.com/icinga/icinga2/issues/6975) (Documentation, PR): Fix nested hostgroup example * [#6949](https://github.com/icinga/icinga2/issues/6949) (Documentation, PR): Doc fix: update check\_rbl parameter * [#6708](https://github.com/icinga/icinga2/issues/6708) (Documentation, PR): Docs: Alpine needs 'edge/main' repository too * [#5430](https://github.com/icinga/icinga2/issues/5430) (Documentation): Documentation about dictionaries and assignements ### Support * [#7032](https://github.com/icinga/icinga2/issues/7032) (code-quality, PR): Backport Defer class for 2.10 * [#7030](https://github.com/icinga/icinga2/issues/7030) (Packages, PR): SELinux: add unreserved\_port\_type attribute to icinga2\_port\_t * [#7029](https://github.com/icinga/icinga2/issues/7029) (Packages): Add unreserved\_port\_type attribute to icinga2\_port\_t * [#7002](https://github.com/icinga/icinga2/issues/7002) (Plugins, Windows, PR): check\_network -h: drop non-existent feature * [#6987](https://github.com/icinga/icinga2/issues/6987) (Tests): base-base\_utility/comparepasswords\_issafe test fails on i386 * [#6977](https://github.com/icinga/icinga2/issues/6977) (Tests, PR): Ignore failure of unit test base\_utility/comparepasswords\_issafe ## 2.10.3 (2019-02-26) ### Notes Bugfixes: - Stalled TLS connections on reload/Director deployments (#6816 #6898 ref/NC/588119) - 'Connection: close' header leading to unstable instance, affects Ruby clients (#6799) - Server time in the future breaks check result processing (#6797 ref/NC/595861) - ScheduledDowntimes: Generate downtime objects only on one HA endpoint (#2844 ref/IC/9673 ref/NC/590167 ref/NC/591721) - Improve activation & syncing for downtime objects generated from ScheduledDowntimes (#6826 ref/IC/9673 ref/NC/585559) - Generate a runtime downtime object from already running ScheduledDowntime objects (#6704) - DB IDO: Don't enqueue queries when the feature is paused in HA zones (#5876) - Crashes with localtime_r errors (#6887) Documentation updates: - Ephemeral port range blocking on Windows agents (ref/NC/597307) - Technical concepts for the check scheduler (#6775) - DB IDO cleanup (#6791) - Unified development docs (#6819) ### Bug * [#6971](https://github.com/icinga/icinga2/issues/6971) (Notifications, PR): Activate downtimes before any checkable object * [#6968](https://github.com/icinga/icinga2/issues/6968) (API, PR): Secure ApiUser::GetByAuthHeader\(\) against timing attacks * [#6940](https://github.com/icinga/icinga2/issues/6940) (Plugins, Windows, PR): Fix check\_swap percentage calculation * [#6925](https://github.com/icinga/icinga2/issues/6925) (Plugins, Windows, PR): Fix check\_swap formatting * [#6924](https://github.com/icinga/icinga2/issues/6924) (PR): Fix double to long conversions * [#6922](https://github.com/icinga/icinga2/issues/6922) (API, DB IDO): IDO MySQL fails on start if check\_interval is a float \(Icinga 2.9.2\) * [#6920](https://github.com/icinga/icinga2/issues/6920) (PR): Downtime::AddDowntime\(\): place Downtimes in the same zone as the origin ScheduledDowntimes * [#6917](https://github.com/icinga/icinga2/issues/6917) (Cluster, Log, PR): Cluster: Delete object message should log that * [#6916](https://github.com/icinga/icinga2/issues/6916) (PR): Don't allow retry\_interval \<= 0 * [#6914](https://github.com/icinga/icinga2/issues/6914) (Cluster, PR): ClusterEvents::AcknowledgementSet event should forward 'persistent' attribute * [#6913](https://github.com/icinga/icinga2/issues/6913) (Plugins, Windows): check\_swap return value wrong when no swap file configured * [#6901](https://github.com/icinga/icinga2/issues/6901) (API, PR): TcpSocket\#Bind\(\): also set SO\_REUSEPORT * [#6899](https://github.com/icinga/icinga2/issues/6899) (PR): Log: Ensure not to pass negative values to localtime\(\) * [#6898](https://github.com/icinga/icinga2/issues/6898) (API): API action restart-process fails on FreeBSD * [#6894](https://github.com/icinga/icinga2/issues/6894) (Check Execution, PR): Fix checkresults from the future breaking checks * [#6887](https://github.com/icinga/icinga2/issues/6887) (Check Execution, Windows): Icinga2 Windows Service does not start critical/checker: Exception occurred while checking 'hostname.tld' * [#6883](https://github.com/icinga/icinga2/issues/6883) (Check Execution, PR): Allow Checkable\#retry\_interval to be 0 * [#6871](https://github.com/icinga/icinga2/issues/6871): Icinga2 crashes after localtime\_r call * [#6857](https://github.com/icinga/icinga2/issues/6857) (Plugins, Windows, PR): Url\#m\_Query: preserve order * [#6826](https://github.com/icinga/icinga2/issues/6826) (Configuration, PR): Downtime\#HasValidConfigOwner\(\): wait for ScheduledDowntimes * [#6821](https://github.com/icinga/icinga2/issues/6821) (Cluster, Configuration, PR): Don't delete downtimes in satellite zones * [#6820](https://github.com/icinga/icinga2/issues/6820) (Cluster, PR): Only create downtimes from non-paused ScheduledDowntime objects in HA enabled cluster zones * [#6817](https://github.com/icinga/icinga2/issues/6817) (API, PR): HttpServerConnection\#DataAvailableHandler\(\): be aware of being called multiple times concurrently * [#6816](https://github.com/icinga/icinga2/issues/6816) (API, Cluster): Stalled TLS connections and lock waits in SocketEventEngine * [#6814](https://github.com/icinga/icinga2/issues/6814) (API, PR): Restore 'Connection: close' behaviour in HTTP responses * [#6811](https://github.com/icinga/icinga2/issues/6811) (Plugins, Windows, PR): Fix state conditions in check\_memory and check\_swap * [#6810](https://github.com/icinga/icinga2/issues/6810) (Plugins, Windows): Windows check\_memory never gets critical * [#6808](https://github.com/icinga/icinga2/issues/6808) (API, PR): Remove redundand check for object existence on creation via API * [#6807](https://github.com/icinga/icinga2/issues/6807) (API): \[2.10.2\] Director deploy crashes the Icinga service \[FreeBSD\] * [#6799](https://github.com/icinga/icinga2/issues/6799) (API): "Connection: close" header leads to unstable instance * [#6797](https://github.com/icinga/icinga2/issues/6797) (Check Execution): Servertime in the future breaks check results processing * [#6750](https://github.com/icinga/icinga2/issues/6750) (Configuration, PR): \#6749 Wrong operator on stride variable causing incorrect behaviour * [#6749](https://github.com/icinga/icinga2/issues/6749) (Configuration): Stride is misinterpreted in multi-date legacydatetime * [#6748](https://github.com/icinga/icinga2/issues/6748) (CLI, PR): Fix api setup to automatically create the conf.d directory * [#6718](https://github.com/icinga/icinga2/issues/6718) (API, Cluster, PR): Call SSL\_shutdown\(\) at least twice * [#6704](https://github.com/icinga/icinga2/issues/6704) (Notifications, PR): Put newly configured already running ScheduledDowntime immediately in effect * [#6542](https://github.com/icinga/icinga2/issues/6542) (Configuration, Log): /var/log/icinga2/icinga2.log is growing very fast on satellites * [#6536](https://github.com/icinga/icinga2/issues/6536) (Windows, help wanted): check\_nscp\_api: Query arguments are sorted on Url::Format\(\) * [#4790](https://github.com/icinga/icinga2/issues/4790) (Notifications): Newly configured already running ScheduledDowntime not put into effect * [#3937](https://github.com/icinga/icinga2/issues/3937) (API): Icinga2 API: PUT request fails at 0-byte file * [#2844](https://github.com/icinga/icinga2/issues/2844) (Cluster): Duplicated scheduled downtimes created in cluster HA zone ### Documentation * [#6956](https://github.com/icinga/icinga2/issues/6956) (Documentation, PR): Escape pipe symbol in api documentation * [#6944](https://github.com/icinga/icinga2/issues/6944) (Documentation, PR): Troubleshooting: Add notes on ephemeral port range blocking on Windows agents * [#6928](https://github.com/icinga/icinga2/issues/6928) (Documentation, PR): Doc: Add .NET 3.5 to the windows build stack * [#6825](https://github.com/icinga/icinga2/issues/6825) (Documentation, PR): Document that retry\_interval is only used after an active check result * [#6819](https://github.com/icinga/icinga2/issues/6819) (Documentation, PR): Enhance and unify development docs for debug, develop, package * [#6791](https://github.com/icinga/icinga2/issues/6791) (Documentation, PR): Docs: Add a section for DB IDO Cleanup * [#6776](https://github.com/icinga/icinga2/issues/6776) (Documentation, PR): Doc fix: update apache section * [#6775](https://github.com/icinga/icinga2/issues/6775) (Documentation, PR): Add technical docs for the check scheduler \(general, initial check, offsets\) * [#6751](https://github.com/icinga/icinga2/issues/6751) (Documentation, PR): Doc fix: documentation link for apt * [#6743](https://github.com/icinga/icinga2/issues/6743) (Documentation, PR): Doc fix: error in example path. * [#5341](https://github.com/icinga/icinga2/issues/5341) (Documentation): Enhance development documentation ### Support * [#6972](https://github.com/icinga/icinga2/issues/6972) (PR): Fix formatting in development docs * [#6958](https://github.com/icinga/icinga2/issues/6958) (code-quality, PR): Debug: Log calls to ConfigObject::Deactivate\(\) * [#6897](https://github.com/icinga/icinga2/issues/6897) (PR): Validate Zone::GetLocalZone\(\) before using * [#6872](https://github.com/icinga/icinga2/issues/6872) (Windows): 2.10 is unstable \(Windows Agent\) * [#6843](https://github.com/icinga/icinga2/issues/6843) (Tests, Windows, PR): Improve AppVeyor builds * [#6479](https://github.com/icinga/icinga2/issues/6479) (code-quality, PR): SocketEvents: inherit from Stream * [#6477](https://github.com/icinga/icinga2/issues/6477) (code-quality): SocketEvents: inherit from Object ## 2.10.2 (2018-11-14) ### Bug * [#6770](https://github.com/icinga/icinga2/issues/6770) (PR): Fix deadlock in GraphiteWriter * [#6769](https://github.com/icinga/icinga2/issues/6769) (Cluster): Hanging TLS connections * [#6759](https://github.com/icinga/icinga2/issues/6759) (Log, PR): Fix possible double free in StreamLogger::BindStream\(\) * [#6753](https://github.com/icinga/icinga2/issues/6753): Icinga2.service state is reloading in systemd after safe-reload until systemd time-out * [#6740](https://github.com/icinga/icinga2/issues/6740) (DB IDO, PR): DB IDO: Don't enqueue queries when the feature is paused \(HA\) * [#6738](https://github.com/icinga/icinga2/issues/6738) (API, Cluster, PR): Ensure that API/JSON-RPC messages in the same session are processed and not stalled * [#6736](https://github.com/icinga/icinga2/issues/6736) (Crash): Stability issues with Icinga 2.10.x * [#6717](https://github.com/icinga/icinga2/issues/6717) (API, PR): Improve error handling for invalid child\_options for API downtime actions * [#6712](https://github.com/icinga/icinga2/issues/6712) (API): Downtime name not returned when error occurs * [#6711](https://github.com/icinga/icinga2/issues/6711) (API, Cluster): Slow API \(TLS-Handshake\) * [#6709](https://github.com/icinga/icinga2/issues/6709) (PR): Fix the Icinga2 version check for versions with more than 5 characters * [#6707](https://github.com/icinga/icinga2/issues/6707) (Compat, PR): Fix regression for wrong objects.cache path overwriting icinga2.debug file * [#6705](https://github.com/icinga/icinga2/issues/6705) (CLI, Compat, Configuration): Crash "icinga2 object list" command with 2.10.1-1 on CentOS 7 * [#6703](https://github.com/icinga/icinga2/issues/6703): Check command 'icinga' breaks when vars.icinga\_min\_version is defined \(2.10.x\) * [#6635](https://github.com/icinga/icinga2/issues/6635) (API): API TLS session connection closed after 2 requests * [#5876](https://github.com/icinga/icinga2/issues/5876) (DB IDO): IDO Work queue on the inactive node growing when switching connection between redundant master servers ### Documentation * [#6714](https://github.com/icinga/icinga2/issues/6714) (Documentation, PR): Docs: Add package related changes to the upgrading docs ### Support * [#6773](https://github.com/icinga/icinga2/issues/6773) (Installation, Packages, PR): Initialize ICINGA2\_ERROR\_LOG inside the systemd environment * [#6771](https://github.com/icinga/icinga2/issues/6771) (Tests, PR): Implement unit tests for Dictionary initializers * [#6760](https://github.com/icinga/icinga2/issues/6760) (Packages, Tests, PR): armhf: Apply workaround for timer tests with std::bind callbacks * [#6710](https://github.com/icinga/icinga2/issues/6710) (Packages): Crash when upgrading from 2.10.0 to 2.10.1 \(SELinux related\) ## 2.10.1 (2018-10-18) ### Bug * [#6696](https://github.com/icinga/icinga2/issues/6696) (PR): Remove default environment, regression from e678fa1aa5 * [#6694](https://github.com/icinga/icinga2/issues/6694): v2.10.0 sets a default environment "production" in SNI * [#6691](https://github.com/icinga/icinga2/issues/6691) (PR): Add missing shutdown/program state dumps for SIGUSR2 reload handler * [#6689](https://github.com/icinga/icinga2/issues/6689): State file not updated on reload * [#6685](https://github.com/icinga/icinga2/issues/6685) (API, PR): Fix regression with API permission filters and namespaces in v2.10 * [#6682](https://github.com/icinga/icinga2/issues/6682) (API): API process-check-result fails in 2.10.0 * [#6679](https://github.com/icinga/icinga2/issues/6679) (Windows, PR): Initialize Configuration::InitRunDir for Windows and writing the PID file * [#6624](https://github.com/icinga/icinga2/issues/6624) (Check Execution): Master Reload Causes Passive Check State Change * [#6592](https://github.com/icinga/icinga2/issues/6592): Reloads seem to reset the check atempt count. Also notifications go missing shortly after a reload. ### Documentation * [#6701](https://github.com/icinga/icinga2/issues/6701) (Documentation, PR): Add GitHub release tag to README * [#6700](https://github.com/icinga/icinga2/issues/6700) (Documentation, PR): Enhance the addon chapter in the docs * [#6699](https://github.com/icinga/icinga2/issues/6699) (Documentation, PR): Update to https://icinga.com/ * [#6692](https://github.com/icinga/icinga2/issues/6692) (Documentation, PR): Update release docs for Chocolatey * [#6690](https://github.com/icinga/icinga2/issues/6690) (Documentation, PR): Extend 09-object-types.md with argument array * [#6674](https://github.com/icinga/icinga2/issues/6674) (Documentation, PR): Add a note to the docs on \>2 endpoints in a zone * [#6673](https://github.com/icinga/icinga2/issues/6673) (Documentation, PR): Update RELEASE docs * [#6672](https://github.com/icinga/icinga2/issues/6672) (Documentation, PR): Extend upgrade docs * [#6671](https://github.com/icinga/icinga2/issues/6671) (Documentation): Zone requirements changed in 2.10 - Undocumented Change ### Support * [#6681](https://github.com/icinga/icinga2/issues/6681) (code-quality, PR): Fix spelling errors. * [#6677](https://github.com/icinga/icinga2/issues/6677) (Packages, Windows): icinga does not start after Update to 2.10 ## 2.10.0 (2018-10-11) ### Notes * Support for namespaces, details in [this blogpost](https://icinga.com/2018/09/17/icinga-2-dsl-feature-namespaces-coming-in-v2-10/) * Only send acknowledgement notification to users notified about a problem before, thanks for sponsoring to the [Max-Planck-Institut for Marine Mikrobiologie](https://www.mpi-bremen.de) * More child options for scheduled downtimes * Performance improvements and fixes for the TLS connections inside cluster/REST API * Better logging for HTTP requests and less verbose object creation (e.g. downtimes via Icinga Web 2 & REST API) * New configuration path constants, e.g. ConfigDir * Fixed problem with dependencies rescheduling parent checks too fast * Fixed problem with logging in systemd and syslog * Improved vim syntax highlighting * [Technical concepts docs](https://icinga.com/docs/icinga2/latest/doc/19-technical-concepts/) update with config compiler and TLS network IO ### Enhancement * [#6663](https://github.com/icinga/icinga2/issues/6663) (API, Log, PR): Silence config compiler logging for runtime created objects * [#6657](https://github.com/icinga/icinga2/issues/6657) (API, Log, PR): Enable the HTTP request body debug log entry for release builds * [#6655](https://github.com/icinga/icinga2/issues/6655) (API, Log, PR): Improve logging for disconnected HTTP clients * [#6651](https://github.com/icinga/icinga2/issues/6651) (Plugins, PR): Add 'used' feature to check\_swap * [#6633](https://github.com/icinga/icinga2/issues/6633) (API, Cluster, PR): Use a dynamic thread pool for API connections * [#6632](https://github.com/icinga/icinga2/issues/6632) (Cluster, PR): Increase the cluster reconnect frequency to 10s * [#6616](https://github.com/icinga/icinga2/issues/6616) (API, Cluster, PR): Add ApiListener\#tls\_handshake\_timeout option * [#6611](https://github.com/icinga/icinga2/issues/6611) (Notifications): Allow types = \[ Recovery \] to always send recovery notifications * [#6595](https://github.com/icinga/icinga2/issues/6595) (API, Cluster, PR): Allow to configure anonymous clients limit inside the ApiListener object * [#6532](https://github.com/icinga/icinga2/issues/6532) (Configuration, PR): Add child\_options to ScheduledDowntime * [#6531](https://github.com/icinga/icinga2/issues/6531) (API, PR): Expose Zone\#all\_parents via API * [#6527](https://github.com/icinga/icinga2/issues/6527) (Notifications, PR): Acknowledgment notifications should only be send if problem notification has been send * [#6521](https://github.com/icinga/icinga2/issues/6521) (Configuration, PR): Implement references * [#6512](https://github.com/icinga/icinga2/issues/6512) (Cluster, PR): Refactor environment for API connections * [#6511](https://github.com/icinga/icinga2/issues/6511) (Cluster, PR): ApiListener: Add support for dynamic port handling * [#6509](https://github.com/icinga/icinga2/issues/6509) (Configuration, PR): Implement support for namespaces * [#6508](https://github.com/icinga/icinga2/issues/6508) (Configuration, PR): Implement the Dictionary\#clear script function * [#6506](https://github.com/icinga/icinga2/issues/6506) (PR): Improve path handling in cmake and daemon * [#6460](https://github.com/icinga/icinga2/issues/6460) (Log, help wanted): Feature suggestion: Do not log warnings when env elements are undefined in CheckCommand objects * [#6455](https://github.com/icinga/icinga2/issues/6455) (Log, PR): Log something when the Filelogger has been started * [#6379](https://github.com/icinga/icinga2/issues/6379) (Configuration, PR): Throw config error when using global zones as parent * [#6356](https://github.com/icinga/icinga2/issues/6356) (Log, PR): Fix logging under systemd * [#6339](https://github.com/icinga/icinga2/issues/6339) (Log, help wanted): On systemd, icinga2 floods the system log, and this cannot simply be opted out of * [#6110](https://github.com/icinga/icinga2/issues/6110) (Configuration, PR): Implement support for optionally specifying the 'var' keyword in 'for' loops * [#6047](https://github.com/icinga/icinga2/issues/6047) (Notifications): Acknowledgment notifications should only be sent if the user already received a problem notification * [#4282](https://github.com/icinga/icinga2/issues/4282) (API, Log): Icinga should log HTTP bodies for API requests ### Bug * [#6658](https://github.com/icinga/icinga2/issues/6658) (API, PR): Ensure that HTTP/1.0 or 'Connection: close' headers are properly disconnecting the client * [#6652](https://github.com/icinga/icinga2/issues/6652) (Plugins, PR): Fix check\_memory thresholds in 'used' mode * [#6647](https://github.com/icinga/icinga2/issues/6647) (CLI, PR): node setup: always respect --accept-config and --accept-commands * [#6643](https://github.com/icinga/icinga2/issues/6643) (Check Execution, Notifications, PR): Fix that check\_timeout was used for Event/Notification commands too * [#6639](https://github.com/icinga/icinga2/issues/6639) (Windows, PR): Ensure to \_unlink before renaming replay log on Windows * [#6622](https://github.com/icinga/icinga2/issues/6622) (DB IDO, PR): Ensure to use UTC timestamps for IDO PgSQL cleanup queries * [#6603](https://github.com/icinga/icinga2/issues/6603) (Check Execution, Cluster): CheckCommand 'icinga' seems to ignore retry interval via command\_endpoint * [#6575](https://github.com/icinga/icinga2/issues/6575): LTO builds fail on Linux * [#6566](https://github.com/icinga/icinga2/issues/6566) (Cluster): Master disconnects during signing process * [#6546](https://github.com/icinga/icinga2/issues/6546) (API, CLI, PR): Overridden path constants not passed to config validation in /v1/config/stages API call * [#6530](https://github.com/icinga/icinga2/issues/6530) (DB IDO, PR): IDO/MySQL: avoid empty queries * [#6519](https://github.com/icinga/icinga2/issues/6519) (CLI, PR): Reset terminal on erroneous console exit * [#6517](https://github.com/icinga/icinga2/issues/6517) (Cluster): Not all Endpoints can't reconnect due to "Client TLS handshake failed" error after "reload or restart" * [#6514](https://github.com/icinga/icinga2/issues/6514) (API): API using "Connection: close" header results in infinite threads * [#6507](https://github.com/icinga/icinga2/issues/6507) (Cluster): Variable name conflict in constants.conf / Problem with TLS verification, CN and Environment variable * [#6503](https://github.com/icinga/icinga2/issues/6503) (Log, PR): Reduce the log level for missing env macros to debug * [#6485](https://github.com/icinga/icinga2/issues/6485) (Log): Icinga logs discarding messages still as warning and not as notice * [#6475](https://github.com/icinga/icinga2/issues/6475) (Compat, PR): lib-\>compat-\>statusdatawriter: fix notifications\_enabled * [#6430](https://github.com/icinga/icinga2/issues/6430) (Log, PR): Fix negative 'empty in' value in WorkQueue log message * [#6427](https://github.com/icinga/icinga2/issues/6427) (Configuration, Crash, PR): Improve error message for serializing objects with recursive references * [#6409](https://github.com/icinga/icinga2/issues/6409) (Configuration, Crash): Assigning vars.x = vars causes Icinga 2 segfaults * [#6408](https://github.com/icinga/icinga2/issues/6408) (PR): ObjectLock\#Unlock\(\): don't reset m\_Object-\>m\_LockOwner too early * [#6386](https://github.com/icinga/icinga2/issues/6386) (Configuration, PR): Fix that TimePeriod segments are not cleared on restart * [#6382](https://github.com/icinga/icinga2/issues/6382) (CLI, help wanted): icinga2 console breaks the terminal on errors * [#6313](https://github.com/icinga/icinga2/issues/6313) (Plugins, Windows, PR): Fix wrong calculation of check\_swap windows plugin * [#6304](https://github.com/icinga/icinga2/issues/6304) (Configuration, Notifications): Timeout defined in NotificationCommand is ignored and uses check\_timeout * [#5815](https://github.com/icinga/icinga2/issues/5815) (Plugins, Windows): swap-windows check delivers wrong result * [#5375](https://github.com/icinga/icinga2/issues/5375) (Check Execution, PR): Parents who are non-active should not be rescheduled * [#5052](https://github.com/icinga/icinga2/issues/5052) (Cluster, Windows): Replay log not working with Windows client * [#5022](https://github.com/icinga/icinga2/issues/5022) (Check Execution): Dependencies may reschedule passive checks, triggering freshness checks ### ITL * [#6646](https://github.com/icinga/icinga2/issues/6646) (ITL, PR): Update ITL and Docs for memory-windows - show used * [#6640](https://github.com/icinga/icinga2/issues/6640) (ITL): Update ITL and Docs for memory-windows - show used * [#6563](https://github.com/icinga/icinga2/issues/6563) (ITL, PR): \[Feature\] Cloudera service health CheckCommand * [#6561](https://github.com/icinga/icinga2/issues/6561) (ITL, PR): \[Feature\] Ceph health CheckCommand * [#6504](https://github.com/icinga/icinga2/issues/6504) (ITL, PR): squashfs ignored * [#6491](https://github.com/icinga/icinga2/issues/6491) (ITL, PR): Feature/itl vmware health * [#6481](https://github.com/icinga/icinga2/issues/6481) (ITL): command-plugins.conf check\_disk exclude squashfs ### Documentation * [#6670](https://github.com/icinga/icinga2/issues/6670) (Documentation, PR): Add technical concepts for the config compiler and daemon CLI command * [#6665](https://github.com/icinga/icinga2/issues/6665) (Documentation, PR): Make the two modes of check\_http more obvious. * [#6615](https://github.com/icinga/icinga2/issues/6615) (Documentation, PR): Update distributed monitoring docs for 2.10 * [#6610](https://github.com/icinga/icinga2/issues/6610) (Documentation, PR): Add "TLS Network IO" into technical concepts docs * [#6607](https://github.com/icinga/icinga2/issues/6607) (Documentation, PR): Enhance development docs with GDB backtrace and thread list * [#6606](https://github.com/icinga/icinga2/issues/6606) (Documentation, PR): Enhance contributing docs * [#6598](https://github.com/icinga/icinga2/issues/6598) (Documentation, PR): doc/09-object-types: states filter ignored for Acknowledgements * [#6597](https://github.com/icinga/icinga2/issues/6597) (Documentation, PR): Add Fedora to development docs for debuginfo packages * [#6593](https://github.com/icinga/icinga2/issues/6593) (Documentation, help wanted): Include CA Proxy in 3rd scenario in Distributed Monitoring docs * [#6573](https://github.com/icinga/icinga2/issues/6573) (Documentation, PR): Fix operator precedence table * [#6528](https://github.com/icinga/icinga2/issues/6528) (Documentation, PR): Document default of User\#enable\_notifications * [#6502](https://github.com/icinga/icinga2/issues/6502) (Documentation, PR): Update 17-language-reference.md * [#6501](https://github.com/icinga/icinga2/issues/6501) (Documentation, PR): Update 03-monitoring-basics.md * [#6488](https://github.com/icinga/icinga2/issues/6488) (Documentation, ITL, PR): Fix typo with the CheckCommand cert ### Support * [#6669](https://github.com/icinga/icinga2/issues/6669) (PR): Don't throw an error when namespace indexers don't find a valid key * [#6668](https://github.com/icinga/icinga2/issues/6668) (Installation, PR): Enhance vim syntax highlighting for 2.10 * [#6661](https://github.com/icinga/icinga2/issues/6661) (API, Log, code-quality, PR): Cache the peer address in the HTTP server * [#6642](https://github.com/icinga/icinga2/issues/6642) (PR): Allow to override MaxConcurrentChecks constant * [#6621](https://github.com/icinga/icinga2/issues/6621) (code-quality, PR): Remove unused timestamp function in DB IDO * [#6618](https://github.com/icinga/icinga2/issues/6618) (PR): Silence compiler warning for nice\(\) * [#6591](https://github.com/icinga/icinga2/issues/6591) (PR): Fix static initializer priority for namespaces in LTO builds * [#6588](https://github.com/icinga/icinga2/issues/6588) (PR): Fix using full path in prepare-dirs/safe-reload scripts * [#6586](https://github.com/icinga/icinga2/issues/6586) (PR): Fix non-unity builds on CentOS 7 with std::shared\_ptr * [#6583](https://github.com/icinga/icinga2/issues/6583) (Documentation, Installation, PR): Update PostgreSQL library path variable in INSTALL.md * [#6574](https://github.com/icinga/icinga2/issues/6574) (PR): Move new downtime constants into the Icinga namespace * [#6570](https://github.com/icinga/icinga2/issues/6570) (Cluster, PR): Increase limit for simultaneously connected anonymous TLS clients * [#6567](https://github.com/icinga/icinga2/issues/6567) (PR): ApiListener: Dump the state file port detail as number * [#6556](https://github.com/icinga/icinga2/issues/6556) (Installation, Windows, PR): windows: Allow suppression of extra actions in the MSI package * [#6544](https://github.com/icinga/icinga2/issues/6544) (code-quality, PR): Remove \#include for deprecated header file * [#6539](https://github.com/icinga/icinga2/issues/6539) (PR): Build fix for CentOS 7 and non-unity builds * [#6526](https://github.com/icinga/icinga2/issues/6526) (code-quality, PR): icinga::PackObject\(\): shorten conversion to string * [#6510](https://github.com/icinga/icinga2/issues/6510) (Tests, Windows, PR): Update windows build scripts * [#6494](https://github.com/icinga/icinga2/issues/6494) (Tests, PR): Test PackObject * [#6489](https://github.com/icinga/icinga2/issues/6489) (code-quality, PR): Implement object packer for consistent hashing * [#6484](https://github.com/icinga/icinga2/issues/6484) (Packages): Packages from https://packages.icinga.com are not Systemd Type=notify enabled? * [#6469](https://github.com/icinga/icinga2/issues/6469) (Installation, Windows, PR): Fix Windows Agent resize behavior * [#6458](https://github.com/icinga/icinga2/issues/6458) (code-quality, PR): Fix debug build log entry for ConfigItem activation priority * [#6456](https://github.com/icinga/icinga2/issues/6456) (code-quality, PR): Keep notes for immediately log flushing * [#6440](https://github.com/icinga/icinga2/issues/6440) (code-quality, PR): Fix typo * [#6410](https://github.com/icinga/icinga2/issues/6410) (code-quality, PR): Remove unused code * [#4959](https://github.com/icinga/icinga2/issues/4959) (Installation, Windows): Windows Agent Wizard Window resizes with screen, hiding buttons ## 2.9.3 (2019-07-30) [Issue and PRs](https://github.com/Icinga/icinga2/issues?utf8=%E2%9C%93&q=milestone%3A2.9.3) ### Bugfixes * Fix el7 not loading ECDHE cipher suites #7247 * Fix checkresults from the future breaking checks #6797 ref/NC/595861 * DB IDO: Don't enqueue queries when the feature is paused (HA) #5876 ## 2.9.2 (2018-09-26) ### Enhancement * [#6602](https://github.com/icinga/icinga2/issues/6602) (API, Cluster, PR): Improve TLS handshake exception logging * [#6568](https://github.com/icinga/icinga2/issues/6568) (Configuration, PR): Ensure that config object types are committed in dependent load order * [#6497](https://github.com/icinga/icinga2/issues/6497) (Configuration, PR): Improve error logging for match/regex/cidr\_match functions and unsupported dictionary usage ### Bug * [#6596](https://github.com/icinga/icinga2/issues/6596) (Crash, PR): Fix crash on API queries with Fedora 28 hardening and GCC 8 * [#6581](https://github.com/icinga/icinga2/issues/6581) (Configuration, PR): Shuffle items before config validation * [#6569](https://github.com/icinga/icinga2/issues/6569) (DB IDO): Custom Vars not updated after upgrade * [#6533](https://github.com/icinga/icinga2/issues/6533) (Crash): Icinga2 crashes after using some api-commands on Fedora 28 * [#6505](https://github.com/icinga/icinga2/issues/6505) (Cluster, PR): Fix clusterzonecheck if not connected * [#6498](https://github.com/icinga/icinga2/issues/6498) (Configuration, PR): Fix regression with MatchAny false conditions on match/regex/cidr\_match * [#6496](https://github.com/icinga/icinga2/issues/6496) (Configuration): error with match and type matchany ### Documentation * [#6590](https://github.com/icinga/icinga2/issues/6590) (DB IDO, Documentation, PR): Update workaround for custom vars * [#6572](https://github.com/icinga/icinga2/issues/6572) (Documentation, PR): Add note about workaround for broken custom vars ### Support * [#6540](https://github.com/icinga/icinga2/issues/6540) (Configuration): Evaluate a fixed config compiler commit order * [#6486](https://github.com/icinga/icinga2/issues/6486) (Configuration): Configuration validation w/ ScheduledDowntimes performance decreased in 2.9 * [#6442](https://github.com/icinga/icinga2/issues/6442) (Configuration): Error while evaluating "assign where match" expression: std::bad\_cast ## 2.9.1 (2018-07-24) ### Bug * [#6457](https://github.com/icinga/icinga2/issues/6457) (PR): Ensure that timer thread is initialized after Daemonize\(\) * [#6449](https://github.com/icinga/icinga2/issues/6449): icinga r2.9.0-1 init.d script overrides PATH variable * [#6445](https://github.com/icinga/icinga2/issues/6445): Problem with daemonize \(init scripts, -d\) on Debian 8 / CentOS 6 / Ubuntu 14 / SLES 11 in 2.9 * [#6444](https://github.com/icinga/icinga2/issues/6444) (PR): SELinux: allow systemd notify * [#6443](https://github.com/icinga/icinga2/issues/6443): selinux and 2.9 ### Support * [#6470](https://github.com/icinga/icinga2/issues/6470) (code-quality, PR): Fix spelling errors. * [#6467](https://github.com/icinga/icinga2/issues/6467) (Tests, PR): Start and stop the timer thread lazily * [#6461](https://github.com/icinga/icinga2/issues/6461) (Tests): Broken tests with fix from \#6457 * [#6451](https://github.com/icinga/icinga2/issues/6451) (Packages, PR): Fix initscripts * [#6450](https://github.com/icinga/icinga2/issues/6450) (Packages): init script helpers - source: not found ## 2.9.0 (2018-07-17) ### Notes - Elasticsearch 6 Support - icinga health check supports minimum version parameter, ido thresholds for query rate, dummy check is executed in-memory, avoids plugin call - `ApplicationVersion` constant in the configuration - Setup wizards: global zone, disable conf.d inclusion, unified parameter handling - TTL support for check results, pretty formatting for REST API queries - TLS support for IDO PostgreSQL - Improvements for check scheduling, concurrent checks with command endpoints, downtime notification handling, scheduled downtimes and memory handling with many API requests ### Enhancement * [#6400](https://github.com/icinga/icinga2/issues/6400) (Plugins, Windows, PR): Enhance debug logging for check\_nscp\_api * [#6321](https://github.com/icinga/icinga2/issues/6321) (Log, PR): Update log message for skipped certificate renewal * [#6305](https://github.com/icinga/icinga2/issues/6305) (PR): Introduce the 'Environment' variable * [#6299](https://github.com/icinga/icinga2/issues/6299) (Check Execution, Log, PR): Change log level for failed event command execution * [#6285](https://github.com/icinga/icinga2/issues/6285) (CLI, Log, PR): Add support for config validation log timestamps * [#6270](https://github.com/icinga/icinga2/issues/6270) (Configuration, PR): Add activation priority for config object types * [#6236](https://github.com/icinga/icinga2/issues/6236) (DB IDO, PR): Add TLS support for DB IDO PostgreSQL feature * [#6219](https://github.com/icinga/icinga2/issues/6219) (Elasticsearch, PR): Add support for Elasticsearch 6 * [#6211](https://github.com/icinga/icinga2/issues/6211) (DB IDO): IDO pgsql with TLS support * [#6209](https://github.com/icinga/icinga2/issues/6209) (CLI, PR): Unify zone name settings in node setup/wizard; add connection-less mode for node setup * [#6208](https://github.com/icinga/icinga2/issues/6208) (CLI): Add connection-less support for node setup CLI command * [#6206](https://github.com/icinga/icinga2/issues/6206) (Configuration, PR): Add ApplicationVersion built-in constant * [#6205](https://github.com/icinga/icinga2/issues/6205) (API, PR): API: Unify verbose error messages * [#6194](https://github.com/icinga/icinga2/issues/6194) (Elasticsearch, Graylog, PR): Elasticsearch/GELF: Add metric unit to performance data fields * [#6170](https://github.com/icinga/icinga2/issues/6170) (Configuration, Windows, PR): Add option to windows installer to add global zones * [#6158](https://github.com/icinga/icinga2/issues/6158) (API, Log): Review API debugging: verboseErrors and diagnostic information * [#6136](https://github.com/icinga/icinga2/issues/6136) (Check Execution, PR): Add counter for current concurrent checks to Icinga check * [#6131](https://github.com/icinga/icinga2/issues/6131) (Log, PR): Log which ticket was invalid on the master * [#6109](https://github.com/icinga/icinga2/issues/6109) (Plugins, PR): Add 'used' feature to check\_memory * [#6090](https://github.com/icinga/icinga2/issues/6090) (Notifications, PR): Fixed URL encoding for HOSTNAME and SERVICENAME in mail notification * [#6078](https://github.com/icinga/icinga2/issues/6078) (Check Execution, PR): Add more metrics and details to built-in 'random' check * [#6039](https://github.com/icinga/icinga2/issues/6039) (Configuration, PR): Improve location info for some error messages * [#6033](https://github.com/icinga/icinga2/issues/6033) (Compat): Deprecate StatusDataWriter * [#6032](https://github.com/icinga/icinga2/issues/6032) (Compat): Deprecate CompatLogger * [#6010](https://github.com/icinga/icinga2/issues/6010) (Cluster, PR): Move the endpoint list into a new line for the 'cluster' check * [#5996](https://github.com/icinga/icinga2/issues/5996) (PR): Add systemd watchdog and adjust reload behaviour * [#5985](https://github.com/icinga/icinga2/issues/5985) (DB IDO, PR): Add query thresholds for the 'ido' check: Rate and pending queries * [#5979](https://github.com/icinga/icinga2/issues/5979) (CLI, PR): Add quit, exit and help * [#5973](https://github.com/icinga/icinga2/issues/5973) (API, Check Execution, PR): Add 'ttl' support for check result freshness via REST API * [#5959](https://github.com/icinga/icinga2/issues/5959) (API, PR): API: Add 'pretty' parameter for beautified JSON response bodies * [#5905](https://github.com/icinga/icinga2/issues/5905) (Elasticsearch): Add support for Elasticsearch 6 * [#5888](https://github.com/icinga/icinga2/issues/5888) (DB IDO, PR): FindMySQL: Support mariadbclient implementation * [#5877](https://github.com/icinga/icinga2/issues/5877) (API): Add pretty format to REST API parameters \(for debugging\) * [#5811](https://github.com/icinga/icinga2/issues/5811) (CLI, PR): Update NodeName/ZoneName constants with 'api setup' * [#5767](https://github.com/icinga/icinga2/issues/5767) (CLI, PR): Implement ability to make global zones configurable during node wizard/setup * [#5733](https://github.com/icinga/icinga2/issues/5733) (Plugins, Windows, PR): Make --perf-syntax also change short message * [#5729](https://github.com/icinga/icinga2/issues/5729) (CLI, Cluster, PR): Correct node wizard output formatting * [#5675](https://github.com/icinga/icinga2/issues/5675) (InfluxDB, PR): Add pdv unit to influxdbwriter if not empty + doc * [#5627](https://github.com/icinga/icinga2/issues/5627) (InfluxDB, Metrics): InfluxDBWriter: Send metric unit \(perfdata\) * [#5605](https://github.com/icinga/icinga2/issues/5605) (CLI, Cluster, Configuration): Disable conf.d inclusion in node setup wizards * [#5509](https://github.com/icinga/icinga2/issues/5509) (Cluster, wishlist): Add metrics about communication between endpoints * [#5444](https://github.com/icinga/icinga2/issues/5444) (Cluster): Display endpoints in the second line of the ClusterCheckTask output * [#5426](https://github.com/icinga/icinga2/issues/5426) (CLI, Configuration, PR): Add the ability to disable the conf.d inclusion through the node wizard * [#5418](https://github.com/icinga/icinga2/issues/5418) (Plugins, Windows): Feature request: check\_perfmon.exe - Change name of counter in output * [#4966](https://github.com/icinga/icinga2/issues/4966) (CLI, Cluster): Unify setting of master zones name * [#4508](https://github.com/icinga/icinga2/issues/4508) (CLI): node wizard/setup: allow to disable conf.d inclusion * [#3455](https://github.com/icinga/icinga2/issues/3455) (API, Log): startup.log in stage dir has no timestamps * [#3245](https://github.com/icinga/icinga2/issues/3245) (CLI, help wanted, wishlist): Add option to Windows installer to add global zone during setup * [#2287](https://github.com/icinga/icinga2/issues/2287) (help wanted, wishlist): Please support systemd startup notification ### Bug * [#6429](https://github.com/icinga/icinga2/issues/6429) (PR): Make HttpServerConnection\#m\_DataHandlerMutex a boost::recursive\_mutex * [#6428](https://github.com/icinga/icinga2/issues/6428) (API): Director kickstart wizard querying the API results in TLS stream disconnected infinite loop * [#6411](https://github.com/icinga/icinga2/issues/6411) (Plugins, Windows, PR): Windows: Conform to the Plugin API spec for performance label quoting * [#6407](https://github.com/icinga/icinga2/issues/6407) (Windows, PR): Fix wrong UOM in check\_uptime windows plugin * [#6405](https://github.com/icinga/icinga2/issues/6405) (Windows, PR): TcpSocket\#Bind\(\): reuse socket addresses on Windows, too * [#6403](https://github.com/icinga/icinga2/issues/6403) (API, PR): Conform to RFC for CRLF in HTTP requests * [#6401](https://github.com/icinga/icinga2/issues/6401) (Elasticsearch, InfluxDB, PR): Fix connection error handling in Elasticsearch and InfluxDB features * [#6397](https://github.com/icinga/icinga2/issues/6397) (Plugins, Windows, PR): TlsStream\#IsEof\(\): fix false positive EOF indicator * [#6394](https://github.com/icinga/icinga2/issues/6394) (Crash, Elasticsearch): Icinga will throw an exception, if ElasticSearch is not reachable * [#6393](https://github.com/icinga/icinga2/issues/6393) (API, Elasticsearch, PR): Stream\#ReadLine\(\): fix false positive buffer underflow indicator * [#6387](https://github.com/icinga/icinga2/issues/6387) (Configuration, Crash, Windows, PR): Remove ApiUser password\_hash functionality * [#6383](https://github.com/icinga/icinga2/issues/6383) (API, CLI, PR): HttpRequest\#ParseBody\(\): indicate success on complete body * [#6378](https://github.com/icinga/icinga2/issues/6378) (Windows): Analyze Windows reload behaviour * [#6371](https://github.com/icinga/icinga2/issues/6371) (API, Cluster, PR): ApiListener\#NewClientHandlerInternal\(\): Explicitly close the TLS stream on any failure * [#6368](https://github.com/icinga/icinga2/issues/6368) (CLI, PR): Fix program option parsing * [#6365](https://github.com/icinga/icinga2/issues/6365) (CLI): Different behavior between `icinga2 -V` and `icinga2 --version` * [#6355](https://github.com/icinga/icinga2/issues/6355) (API): HTTP header size too low: Long URLs and session cookies cause bad requests * [#6354](https://github.com/icinga/icinga2/issues/6354) (Elasticsearch): ElasticsearchWriter not writing to ES * [#6336](https://github.com/icinga/icinga2/issues/6336) (Log, PR): Fix unnecessary blank in log message * [#6324](https://github.com/icinga/icinga2/issues/6324) (Crash, PR): Ensure that password hash generation from OpenSSL is atomic * [#6319](https://github.com/icinga/icinga2/issues/6319) (Windows): Windows service restart fails and config validate runs forever * [#6297](https://github.com/icinga/icinga2/issues/6297) (Cluster, PR): Execute event commands only on actively checked host/service objects in an HA zone * [#6294](https://github.com/icinga/icinga2/issues/6294) (API, Configuration, PR): Ensure that group memberships on API object creation are unique * [#6292](https://github.com/icinga/icinga2/issues/6292) (Notifications, PR): Fix problem with reminder notifications if the checkable is flapping * [#6290](https://github.com/icinga/icinga2/issues/6290) (OpenTSDB, PR): Fixed opentsdb metric name with colon chars * [#6282](https://github.com/icinga/icinga2/issues/6282) (Configuration): Issue when using excludes in TimePeriod Objects * [#6279](https://github.com/icinga/icinga2/issues/6279) (Crash): segfault with sha1\_block\_data\_order\_avx of libcrypto * [#6255](https://github.com/icinga/icinga2/issues/6255) (Configuration): On debian based systems /etc/default/icinga2 is not read/used * [#6242](https://github.com/icinga/icinga2/issues/6242) (Plugins, Windows): Sporadic check\_nscp\_api timeouts * [#6239](https://github.com/icinga/icinga2/issues/6239) (Plugins, Windows, PR): Fix Windows check\_memory rounding * [#6231](https://github.com/icinga/icinga2/issues/6231) (Notifications): icinga2.8 - Notifications are sent even in downtime * [#6218](https://github.com/icinga/icinga2/issues/6218) (PR): attempt to fix issue \#5277 * [#6217](https://github.com/icinga/icinga2/issues/6217) (Check Execution, PR): Fix check behavior on restart * [#6204](https://github.com/icinga/icinga2/issues/6204) (API, PR): API: Check if objects exists and return proper error message * [#6195](https://github.com/icinga/icinga2/issues/6195) (API, Crash, PR): Fix crash in remote api console * [#6193](https://github.com/icinga/icinga2/issues/6193) (Crash, Graylog, PR): GelfWriter: Fix crash on invalid performance data metrics * [#6184](https://github.com/icinga/icinga2/issues/6184) (API): debug console with API connection sometimes hangs since 2.8.2 * [#6125](https://github.com/icinga/icinga2/issues/6125) (Configuration, PR): Fix description of the NotificationComponent in notification.conf * [#6077](https://github.com/icinga/icinga2/issues/6077) (API, PR): Allow to pass raw performance data in 'process-check-result' API action * [#6057](https://github.com/icinga/icinga2/issues/6057) (Notifications): Icinga2 sends notifications without logging about it and despite having a downtime * [#6020](https://github.com/icinga/icinga2/issues/6020) (CLI, PR): Fix crash when running 'icinga2 console' without HOME environment variable * [#6019](https://github.com/icinga/icinga2/issues/6019): icinga2 console -r crashes when run without a HOME environment variable * [#6016](https://github.com/icinga/icinga2/issues/6016) (Notifications, PR): Check notification state filters for problems only, not for Custom, etc. * [#5988](https://github.com/icinga/icinga2/issues/5988) (Check Execution, Cluster, PR): Fix concurrent checks limit while using command\_endpoint * [#5964](https://github.com/icinga/icinga2/issues/5964) (Metrics, OpenTSDB, PR): OpenTSDB writer - Fix function for escaping host tag chars. * [#5963](https://github.com/icinga/icinga2/issues/5963) (Metrics, OpenTSDB): OpenTSDB writer is escaping wrong chars for host names. * [#5952](https://github.com/icinga/icinga2/issues/5952) (Notifications): Custom notifications are filtered by object state * [#5940](https://github.com/icinga/icinga2/issues/5940) (PR): Remove deprecated Chocolatey functions * [#5928](https://github.com/icinga/icinga2/issues/5928) (PR): Fix build problem with MSVC * [#5908](https://github.com/icinga/icinga2/issues/5908) (Windows): Icinga2 fails to build on Windows * [#5901](https://github.com/icinga/icinga2/issues/5901) (PR): Do not replace colons in plugin output * [#5885](https://github.com/icinga/icinga2/issues/5885) (PR): Workaround for GCC bug 61321 * [#5884](https://github.com/icinga/icinga2/issues/5884): Icinga2 fails to build * [#5872](https://github.com/icinga/icinga2/issues/5872) (PR): Replace incorrect fclose\(\) call with pclose\(\) * [#5863](https://github.com/icinga/icinga2/issues/5863) (PR): Fix glob error handling * [#5861](https://github.com/icinga/icinga2/issues/5861) (PR): Fix incorrect memory access * [#5860](https://github.com/icinga/icinga2/issues/5860) (PR): Fix memory leaks in the unit tests * [#5853](https://github.com/icinga/icinga2/issues/5853) (Plugins, Windows, PR): Fix missing space in check\_service output * [#5840](https://github.com/icinga/icinga2/issues/5840) (Elasticsearch, PR): Fix newline terminator for bulk requests in ElasticsearchWriter * [#5796](https://github.com/icinga/icinga2/issues/5796) (CLI, PR): Fix error reporting for 'icinga2 console -r' * [#5795](https://github.com/icinga/icinga2/issues/5795) (Elasticsearch): ElasticsearchWriter gives "Unexpected response code 400" with Elasticsearch 6.x * [#5763](https://github.com/icinga/icinga2/issues/5763) (API): "icinga2 api setup" should explicitly set the NodeName constant in constants.conf * [#5753](https://github.com/icinga/icinga2/issues/5753) (API, Cluster, Metrics, PR): Fix that RingBuffer does not get updated and add metrics about communication between endpoints * [#5718](https://github.com/icinga/icinga2/issues/5718) (API, PR): API: Fix http status codes * [#5550](https://github.com/icinga/icinga2/issues/5550) (API): Verify error codes and returned log messages in API actions * [#5277](https://github.com/icinga/icinga2/issues/5277) (Notifications): Flexible downtime is expired at end\_time, not trigger\_time+duration * [#5095](https://github.com/icinga/icinga2/issues/5095) (API): Wrong HTTP status code when API request fails * [#5083](https://github.com/icinga/icinga2/issues/5083) (Check Execution): Initial checks are not executed immediately * [#4786](https://github.com/icinga/icinga2/issues/4786) (API): API: Command process-check-result fails if it contains performance data * [#4785](https://github.com/icinga/icinga2/issues/4785) (Compat): Semicolons in plugin output are converted to colon * [#4732](https://github.com/icinga/icinga2/issues/4732) (API, Configuration): Duplicate groups allowed when creating host * [#4436](https://github.com/icinga/icinga2/issues/4436) (Check Execution): New objects not scheduled to check immediately * [#4272](https://github.com/icinga/icinga2/issues/4272) (Cluster, Configuration): Duplicating downtime from ScheduledDowntime object on each restart * [#3431](https://github.com/icinga/icinga2/issues/3431) (Cluster): Eventhandler trigger on all endpoints in high available zone ### ITL * [#6389](https://github.com/icinga/icinga2/issues/6389) (ITL, PR): New ITL command nscp-local-tasksched * [#6348](https://github.com/icinga/icinga2/issues/6348) (ITL, PR): Fix for catalogued locally databases. Fixes \#6338 * [#6338](https://github.com/icinga/icinga2/issues/6338) (ITL): db2\_health not working with catalogued databases, as --hostname is always used * [#6308](https://github.com/icinga/icinga2/issues/6308) (ITL, PR): Update lsi-raid ITL command * [#6263](https://github.com/icinga/icinga2/issues/6263) (ITL, PR): ITL: Add default thresholds to windows check commands * [#6139](https://github.com/icinga/icinga2/issues/6139) (ITL, PR): itl/disk: Ignore overlay and netfs filesystems * [#6045](https://github.com/icinga/icinga2/issues/6045) (ITL, PR): Move the "passive" check command to command-icinga.conf * [#6043](https://github.com/icinga/icinga2/issues/6043) (ITL): ITL "plugins" has an implicit dependency on "itl" * [#6034](https://github.com/icinga/icinga2/issues/6034) (ITL, PR): ITL by\_ssh add -E parameter * [#5958](https://github.com/icinga/icinga2/issues/5958) (ITL, PR): Add minimum version check to the built-in icinga command * [#5954](https://github.com/icinga/icinga2/issues/5954) (ITL, PR): ITL: Add mongodb --authdb parameter support * [#5951](https://github.com/icinga/icinga2/issues/5951) (ITL, PR): itl: Add command parameters for snmp-memory * [#5921](https://github.com/icinga/icinga2/issues/5921) (ITL, PR): Add icingacli-director check to ITL * [#5920](https://github.com/icinga/icinga2/issues/5920) (ITL): Add Check for Director Jobs to ITL * [#5914](https://github.com/icinga/icinga2/issues/5914) (ITL, PR): Fix for wrong attribute in ITL mongodb CheckCommand * [#5906](https://github.com/icinga/icinga2/issues/5906) (ITL, PR): Add check\_openmanage command to ITL. * [#5902](https://github.com/icinga/icinga2/issues/5902) (ITL, PR): Add parameter --octetlength to snmp-storage command. * [#5817](https://github.com/icinga/icinga2/issues/5817) (ITL): mongodb\_address vs mongodb\_host * [#5812](https://github.com/icinga/icinga2/issues/5812) (ITL): Better way to check required parameters in notification scripts * [#5805](https://github.com/icinga/icinga2/issues/5805) (ITL, PR): Add support for LD\_LIBRARY\_PATH env variable in oracle\_health ITL CheckCommand * [#5792](https://github.com/icinga/icinga2/issues/5792) (ITL, PR): ITL: Add check\_rpc * [#5787](https://github.com/icinga/icinga2/issues/5787) (Check Execution, ITL): random check should provide performance data metrics * [#5744](https://github.com/icinga/icinga2/issues/5744) (Check Execution, ITL, PR): Implement DummyCheckTask and move dummy into embedded in-memory checks * [#5717](https://github.com/icinga/icinga2/issues/5717) (ITL, PR): add order tags to disk check * [#5714](https://github.com/icinga/icinga2/issues/5714) (ITL): disk check in icinga2/itl/command-plugins.conf lacks order tags * [#5260](https://github.com/icinga/icinga2/issues/5260) (ITL): CheckCommand mongodb does not expose authdb option ### Documentation * [#6436](https://github.com/icinga/icinga2/issues/6436) (Documentation, PR): Update tested Elasticsearch version * [#6435](https://github.com/icinga/icinga2/issues/6435) (Documentation, PR): Add note on sysconfig shell variables for Systemd to the Upgrading docs * [#6433](https://github.com/icinga/icinga2/issues/6433) (Documentation, PR): Docs: Fix typos in 03-monitoring-basics.md * [#6426](https://github.com/icinga/icinga2/issues/6426) (Documentation, PR): Update 'Upgrading to 2.9' docs * [#6413](https://github.com/icinga/icinga2/issues/6413) (Documentation, PR): Fix table in Livestatus Filters * [#6391](https://github.com/icinga/icinga2/issues/6391) (Documentation, PR): Docs: Fix icinga.com link * [#6390](https://github.com/icinga/icinga2/issues/6390) (Documentation, Windows, PR): Docs: Update Windows wizard images * [#6375](https://github.com/icinga/icinga2/issues/6375) (Documentation, PR): some minor fixes in the flapping documentation * [#6374](https://github.com/icinga/icinga2/issues/6374) (Documentation, PR): Docs: Add an additional note for VMWare timeouts on Ubuntu 16.04 LTS * [#6373](https://github.com/icinga/icinga2/issues/6373) (Documentation, PR): Drop command template imports for versions \< 2.6 in the docs * [#6372](https://github.com/icinga/icinga2/issues/6372) (Documentation, PR): Remove the import of 'legacy-timeperiod' in the docs * [#6350](https://github.com/icinga/icinga2/issues/6350) (Documentation, PR): clarify the permision system of the api in the docs * [#6344](https://github.com/icinga/icinga2/issues/6344) (Documentation, PR): README: Fix broken community link * [#6330](https://github.com/icinga/icinga2/issues/6330) (Documentation, PR): Fix $ipaddress6$ attribute name typo in the docs * [#6317](https://github.com/icinga/icinga2/issues/6317) (Documentation, PR): Add a note on Windows NSClient++ CPU checks to the docs * [#6289](https://github.com/icinga/icinga2/issues/6289) (Documentation, PR): Update release documentation with git tag signing key configuration * [#6286](https://github.com/icinga/icinga2/issues/6286) (Documentation): Update Windows wizard screenshots in the docs * [#6283](https://github.com/icinga/icinga2/issues/6283) (Documentation, PR): edit Icinga license info so that GitHub recognizes it * [#6271](https://github.com/icinga/icinga2/issues/6271) (Documentation, PR): Enhance advanced topics with \(scheduled\) downtimes * [#6267](https://github.com/icinga/icinga2/issues/6267) (Documentation, PR): Update docs to reflect required user\* attributes for notification objects * [#6265](https://github.com/icinga/icinga2/issues/6265) (Documentation): Notifications user/user\_groups required * [#6264](https://github.com/icinga/icinga2/issues/6264) (Documentation, PR): Enhance "Getting Started" chapter * [#6262](https://github.com/icinga/icinga2/issues/6262) (Documentation, PR): Enhance the environment variables chapter * [#6254](https://github.com/icinga/icinga2/issues/6254) (Documentation, PR): Enhance release documentation * [#6253](https://github.com/icinga/icinga2/issues/6253) (Documentation, PR): Doc: Add note for not fully supported Plugin collections * [#6243](https://github.com/icinga/icinga2/issues/6243) (Documentation, PR): Update PostgreSQL documentation * [#6226](https://github.com/icinga/icinga2/issues/6226) (Documentation, PR): Fix broken SELinux anchor in the documentation * [#6224](https://github.com/icinga/icinga2/issues/6224) (Documentation, PR): Update volatile docs * [#6216](https://github.com/icinga/icinga2/issues/6216) (Documentation): Volatile service explanation * [#6180](https://github.com/icinga/icinga2/issues/6180) (Documentation, PR): Doc: fixed wrong information about defaulting * [#6128](https://github.com/icinga/icinga2/issues/6128) (Documentation, PR): Adding documentation for configurable global zones during setup * [#6067](https://github.com/icinga/icinga2/issues/6067) (Documentation, Windows, PR): Improve Windows builds and testing * [#6022](https://github.com/icinga/icinga2/issues/6022) (Configuration, Documentation, PR): Update default config and documentation for the "library" keyword * [#6018](https://github.com/icinga/icinga2/issues/6018) (Documentation): Move init configuration from getting-started * [#6000](https://github.com/icinga/icinga2/issues/6000) (Documentation, PR): Add newline to COPYING to fix Github license detection * [#5948](https://github.com/icinga/icinga2/issues/5948) (Documentation, PR): doc: Improve INSTALL documentation * [#4958](https://github.com/icinga/icinga2/issues/4958) (Check Execution, Documentation): How to set the HOME environment variable ### Support * [#6439](https://github.com/icinga/icinga2/issues/6439) (PR): Revert "Fix obsolete parameter in Systemd script" * [#6423](https://github.com/icinga/icinga2/issues/6423) (PR): Fix missing next check update causing the scheduler to execute checks too often * [#6421](https://github.com/icinga/icinga2/issues/6421) (Check Execution): High CPU load due to seemingly ignored check\_interval * [#6412](https://github.com/icinga/icinga2/issues/6412) (Plugins, Windows, PR): Fix output formatting in windows plugins * [#6402](https://github.com/icinga/icinga2/issues/6402) (Cluster, code-quality, PR): Use SSL\_pending\(\) for remaining TLS stream data * [#6384](https://github.com/icinga/icinga2/issues/6384) (PR): Remove leftover for sysconfig file parsing * [#6381](https://github.com/icinga/icinga2/issues/6381) (Packages, PR): Fix sysconfig not being handled correctly by sysvinit * [#6377](https://github.com/icinga/icinga2/issues/6377) (code-quality, PR): Fix missing name for workqueue while creating runtime objects via API * [#6364](https://github.com/icinga/icinga2/issues/6364) (code-quality): lib/base/workqueue.cpp:212: assertion failed: !m\_Name.IsEmpty\(\) * [#6361](https://github.com/icinga/icinga2/issues/6361) (API, Cluster): Analyse socket IO handling with HTTP/JSON-RPC * [#6359](https://github.com/icinga/icinga2/issues/6359) (Configuration, PR): Fix ScheduledDowntimes replicating on restart * [#6357](https://github.com/icinga/icinga2/issues/6357) (API, PR): Increase header size to 8KB for HTTP requests * [#6347](https://github.com/icinga/icinga2/issues/6347) (Packages, PR): SELinux: Allow notification plugins to read local users * [#6343](https://github.com/icinga/icinga2/issues/6343) (Check Execution, Cluster, PR): Fix that checks with command\_endpoint don't return any check results * [#6337](https://github.com/icinga/icinga2/issues/6337): Checks via command\_endpoint are not executed \(snapshot packages only\) * [#6328](https://github.com/icinga/icinga2/issues/6328) (Installation, Packages, PR): Rework sysconfig file/startup environment * [#6320](https://github.com/icinga/icinga2/issues/6320) (PR): Ensure that icinga\_min\_version parameter is optional * [#6309](https://github.com/icinga/icinga2/issues/6309) (PR): Fix compiler warning in checkercomponent.ti * [#6306](https://github.com/icinga/icinga2/issues/6306) (code-quality, PR): Adjust message for CheckResultReader deprecation * [#6301](https://github.com/icinga/icinga2/issues/6301) (Documentation, code-quality, PR): Adjust deprecation removal for compat features * [#6295](https://github.com/icinga/icinga2/issues/6295) (Compat, PR): Deprecate compatlog feature * [#6238](https://github.com/icinga/icinga2/issues/6238) (Notifications, PR): Implement better way to check parameters in notification scripts * [#6233](https://github.com/icinga/icinga2/issues/6233) (Check Execution): Verify next check execution on daemon reload * [#6229](https://github.com/icinga/icinga2/issues/6229) (Packages, PR): Don't use shell variables in sysconfig * [#6214](https://github.com/icinga/icinga2/issues/6214) (Packages): Reload-internal with unresolved shell variable * [#6201](https://github.com/icinga/icinga2/issues/6201) (Windows, PR): Handle exceptions from X509Certificate2 * [#6199](https://github.com/icinga/icinga2/issues/6199) (API, PR): Return 500 when no api action is successful * [#6198](https://github.com/icinga/icinga2/issues/6198) (Compat, PR): Deprecate Statusdatawriter * [#6187](https://github.com/icinga/icinga2/issues/6187) (code-quality, PR): Remove Icinga Studio Screenshots * [#6181](https://github.com/icinga/icinga2/issues/6181) (Tests, PR): tests: Ensure IcingaApplication is initialized before adding config * [#6174](https://github.com/icinga/icinga2/issues/6174) (API, PR): Fix crash without CORS setting * [#6173](https://github.com/icinga/icinga2/issues/6173) (API, Crash): Using the API crashes Icinga2 in v2.8.1-537-g064fc80 * [#6171](https://github.com/icinga/icinga2/issues/6171) (code-quality, PR): Update copyright of the Windows Agent to 2018 * [#6163](https://github.com/icinga/icinga2/issues/6163) (PR): Fix reload handling by updating the PID file before process overtake * [#6160](https://github.com/icinga/icinga2/issues/6160) (code-quality, PR): Replace std::vector:push\_back calls with initializer list * [#6126](https://github.com/icinga/icinga2/issues/6126) (PR): Require systemd headers * [#6113](https://github.com/icinga/icinga2/issues/6113) (Tests, PR): appveyor: Disable artifacts until we use them * [#6107](https://github.com/icinga/icinga2/issues/6107) (code-quality, PR): Allow MYSQL\_LIB to be specified by ENV variable * [#6105](https://github.com/icinga/icinga2/issues/6105) (Tests): Snapshot builds fail on livestatus tests * [#6098](https://github.com/icinga/icinga2/issues/6098) (API, code-quality, PR): Clean up CORS implementation * [#6085](https://github.com/icinga/icinga2/issues/6085) (Cluster, Crash, PR): Fix crash with anonymous clients on certificate signing request and storing sent bytes * [#6083](https://github.com/icinga/icinga2/issues/6083) (Log, code-quality, PR): Fix wrong type logging in ConfigItem::Commit * [#6082](https://github.com/icinga/icinga2/issues/6082) (Installation, Packages): PID file removed after reload * [#6063](https://github.com/icinga/icinga2/issues/6063) (Compat, PR): Deprecate CheckResultReader * [#6062](https://github.com/icinga/icinga2/issues/6062) (code-quality, PR): Remove the obsolete 'make-agent-config.py' script * [#6061](https://github.com/icinga/icinga2/issues/6061) (code-quality, PR): Remove jenkins test scripts * [#6060](https://github.com/icinga/icinga2/issues/6060) (code-quality, PR): Remove Icinga development docker scripts * [#6059](https://github.com/icinga/icinga2/issues/6059) (code-quality, PR): Remove Icinga Studio * [#6058](https://github.com/icinga/icinga2/issues/6058) (code-quality, PR): Clean up the Icinga plugins a bit * [#6055](https://github.com/icinga/icinga2/issues/6055) (Check Execution, Windows, code-quality, PR): methods: Remove unused clrchecktask feature * [#6054](https://github.com/icinga/icinga2/issues/6054) (Check Execution, Windows, code-quality): Remove unused clrchecktask * [#6051](https://github.com/icinga/icinga2/issues/6051) (code-quality, PR): Set FOLDER cmake property for the icingaloader target * [#6050](https://github.com/icinga/icinga2/issues/6050) (code-quality, PR): Replace boost::algorithm::split calls with String::Split * [#6044](https://github.com/icinga/icinga2/issues/6044) (code-quality, PR): Implement support for frozen arrays and dictionaries * [#6038](https://github.com/icinga/icinga2/issues/6038) (PR): Fix missing include for boost::split * [#6037](https://github.com/icinga/icinga2/issues/6037) (PR): Fix build error on Windows * [#6029](https://github.com/icinga/icinga2/issues/6029) (code-quality, PR): Remove duplicate semicolons * [#6028](https://github.com/icinga/icinga2/issues/6028) (Packages): python notification not running when icinga ran as a service * [#6026](https://github.com/icinga/icinga2/issues/6026) (Check Execution, Windows, PR): Fix flapping support for Windows * [#6025](https://github.com/icinga/icinga2/issues/6025) (Windows): Implement Flapping on Windows * [#6023](https://github.com/icinga/icinga2/issues/6023): Icinga should check whether the libsystemd library is available * [#6017](https://github.com/icinga/icinga2/issues/6017) (PR): Remove build breaking include * [#6015](https://github.com/icinga/icinga2/issues/6015) (code-quality, PR): Fix whitespaces in CMakeLists files * [#6009](https://github.com/icinga/icinga2/issues/6009) (PR): Build fix for ancient versions of GCC * [#6008](https://github.com/icinga/icinga2/issues/6008) (PR): Fix compatibility with CMake \< 3.1 * [#6007](https://github.com/icinga/icinga2/issues/6007) (PR): Fix missing include * [#6005](https://github.com/icinga/icinga2/issues/6005) (PR): Fix incorrect dependencies for mkunity targets * [#5999](https://github.com/icinga/icinga2/issues/5999) (PR): Build fix * [#5998](https://github.com/icinga/icinga2/issues/5998) (code-quality, PR): Build all remaining libraries as object libraries * [#5997](https://github.com/icinga/icinga2/issues/5997) (PR): Use gcc-ar and gcc-ranlib when building with -flto * [#5994](https://github.com/icinga/icinga2/issues/5994) (InfluxDB, PR): InfluxDBWriter: Fix macro in template * [#5993](https://github.com/icinga/icinga2/issues/5993) (code-quality, PR): Use CMake object libraries for our libs * [#5992](https://github.com/icinga/icinga2/issues/5992) (code-quality, PR): Remove unused includes * [#5984](https://github.com/icinga/icinga2/issues/5984) (DB IDO, PR): Fix missing static libraries for DB IDO * [#5983](https://github.com/icinga/icinga2/issues/5983) (code-quality, PR): Use initializer lists for arrays and dictionaries * [#5980](https://github.com/icinga/icinga2/issues/5980) (code-quality, PR): Explicitly pass 1 or 0 for notification filters in DB IDO * [#5974](https://github.com/icinga/icinga2/issues/5974) (PR): Fix non-unity builds with the icinga check * [#5971](https://github.com/icinga/icinga2/issues/5971) (code-quality, PR): Remove libdemo and libhello * [#5970](https://github.com/icinga/icinga2/issues/5970) (code-quality, PR): Allocate ConfigItemBuilder objects on the stack * [#5969](https://github.com/icinga/icinga2/issues/5969) (code-quality, PR): Remove the WorkQueue::m\_StatsMutex instance variable * [#5968](https://github.com/icinga/icinga2/issues/5968) (code-quality, PR): Update the RingBuffer class to use a regular mutex instead of ObjectLock * [#5967](https://github.com/icinga/icinga2/issues/5967) (code-quality, PR): Avoid accessing attributes for validators where not necessary * [#5965](https://github.com/icinga/icinga2/issues/5965) (code-quality, PR): Avoid unnecessary casts in the JSON encoder * [#5961](https://github.com/icinga/icinga2/issues/5961) (PR): Fix macro warning from the icinga check * [#5960](https://github.com/icinga/icinga2/issues/5960): Macro warning from the icinga check * [#5957](https://github.com/icinga/icinga2/issues/5957) (code-quality, PR): Change a bunch more copyright headers for 2018 * [#5955](https://github.com/icinga/icinga2/issues/5955) (Configuration, code-quality, PR): Avoid mutex contention in the config parser * [#5946](https://github.com/icinga/icinga2/issues/5946) (code-quality, PR): Use clang-tidy to add some more C++11 features * [#5945](https://github.com/icinga/icinga2/issues/5945) (code-quality, PR): Fix incorrect indentation for code generated by mkclass * [#5944](https://github.com/icinga/icinga2/issues/5944) (code-quality, PR): Add the final keyword to classes * [#5939](https://github.com/icinga/icinga2/issues/5939) (PR): Build fix for Debian wheezy * [#5937](https://github.com/icinga/icinga2/issues/5937) (code-quality, PR): Remove inline methods and use explicit template instantiation to minimize the number of weak symbols * [#5936](https://github.com/icinga/icinga2/issues/5936) (code-quality, PR): Clean up source lists in the CMakeLists.txt files * [#5935](https://github.com/icinga/icinga2/issues/5935) (code-quality, PR): Implement support for precompiled headers * [#5934](https://github.com/icinga/icinga2/issues/5934) (code-quality, PR): Add more include/library paths for MySQL and PostgreSQL * [#5933](https://github.com/icinga/icinga2/issues/5933) (code-quality, PR): Change copyright headers for 2018 * [#5932](https://github.com/icinga/icinga2/issues/5932) (code-quality, PR): Fix copyright header in cli/troubleshootcommand.hpp * [#5931](https://github.com/icinga/icinga2/issues/5931) (code-quality, PR): Improve detection for linker flags * [#5930](https://github.com/icinga/icinga2/issues/5930) (code-quality, PR): Replace boost::function with std::function * [#5929](https://github.com/icinga/icinga2/issues/5929) (code-quality, PR): Get rid of boost::assign::list\_of in mkclass * [#5927](https://github.com/icinga/icinga2/issues/5927) (code-quality, PR): Build libraries as static libraries * [#5909](https://github.com/icinga/icinga2/issues/5909) (code-quality, PR): WIP: Improve build times * [#5903](https://github.com/icinga/icinga2/issues/5903) (code-quality, PR): Cleanup CompatUtility class and features * [#5897](https://github.com/icinga/icinga2/issues/5897) (code-quality, PR): Remove unnecessary inline statements * [#5894](https://github.com/icinga/icinga2/issues/5894) (code-quality, PR): Remove string\_iless * [#5891](https://github.com/icinga/icinga2/issues/5891) (code-quality, PR): Update .gitignore * [#5889](https://github.com/icinga/icinga2/issues/5889) (code-quality, PR): execvpe: Fixup indention for readability * [#5887](https://github.com/icinga/icinga2/issues/5887) (PR): Windows build fix * [#5886](https://github.com/icinga/icinga2/issues/5886) (code-quality): Remove unnecessary 'inline' keyword * [#5882](https://github.com/icinga/icinga2/issues/5882) (code-quality, PR): Avoid unnecessary allocations * [#5871](https://github.com/icinga/icinga2/issues/5871) (code-quality, PR): Unit tests for the LegacyTimePeriod class * [#5868](https://github.com/icinga/icinga2/issues/5868) (Configuration, code-quality, PR): Use std::unique\_ptr for Expression objects * [#5865](https://github.com/icinga/icinga2/issues/5865) (code-quality, PR): Add missing initializer in Utility::NewUniqueID\(\) * [#5862](https://github.com/icinga/icinga2/issues/5862) (code-quality, PR): Replace a few more NULLs with nullptr * [#5858](https://github.com/icinga/icinga2/issues/5858) (Tests, code-quality, PR): Travis: Add support for Coverity * [#5857](https://github.com/icinga/icinga2/issues/5857) (code-quality, PR): Fix compiler warnings * [#5855](https://github.com/icinga/icinga2/issues/5855) (PR): Fix build problems with Visual Studio 2017 * [#5848](https://github.com/icinga/icinga2/issues/5848) (code-quality, PR): Fix COPYING format * [#5846](https://github.com/icinga/icinga2/issues/5846) (code-quality, PR): Fix compiler warnings * [#5831](https://github.com/icinga/icinga2/issues/5831) (Check Execution, Configuration): No checks were launched on snapshot version 2.8.0.71 \(RHEL6\) * [#5827](https://github.com/icinga/icinga2/issues/5827) (code-quality, PR): Replace StatsFunction with Function * [#5825](https://github.com/icinga/icinga2/issues/5825) (code-quality, PR): Replace boost::assign::list\_of with initializer lists * [#5824](https://github.com/icinga/icinga2/issues/5824) (code-quality, PR): Replace a few Boost features with equivalent C++11 features * [#5821](https://github.com/icinga/icinga2/issues/5821) (Packages, Windows): check\_disk build error * [#5819](https://github.com/icinga/icinga2/issues/5819) (code-quality, PR): Avoid unnecessary allocations in the FunctionCallExpression class * [#5816](https://github.com/icinga/icinga2/issues/5816) (code-quality, PR): Re-implement WrapFunction\(\) using C++11 features * [#5809](https://github.com/icinga/icinga2/issues/5809) (Documentation, Installation, PR): Raise required OpenSSL version to 1.0.1 * [#5758](https://github.com/icinga/icinga2/issues/5758) (Documentation, Packages): Completely remove the spec file from the icinga2 repository * [#5743](https://github.com/icinga/icinga2/issues/5743) (CLI, Configuration, Installation): node setup: Deprecate --master\_host and use --parent\_host instead * [#5725](https://github.com/icinga/icinga2/issues/5725) (code-quality, PR): Use real UUIDs for Utility::NewUniqueID * [#5388](https://github.com/icinga/icinga2/issues/5388) (Packages, PR): Handle mis-detection with clang on RHEL/CentOS 7 * [#3246](https://github.com/icinga/icinga2/issues/3246) (Installation): Add option to windows installer to disable inclusion of conf.d directory ## 2.8.4 (2018-04-25) ### Bug * [#6257](https://github.com/icinga/icinga2/issues/6257) (Check Execution): Plugins crash when run from icinga2-2.8.3 ### Support * [#6260](https://github.com/icinga/icinga2/issues/6260) (Check Execution, PR): Revert "fixup set rlimit stack failed condition" ## 2.8.3 (2018-04-24) ### Notes - Fix InfluxDB backslash escaping - Fix Elasticsearch crash on invalid performance data - Sysconfig file settings are taken into account - Support multiple parameters for check_nscp_api - Documentation enhancements and fixes ### Bug * [#6207](https://github.com/icinga/icinga2/issues/6207) (Plugins, Windows, PR): Fix multiple parameter problems for check\_nscp\_api * [#6196](https://github.com/icinga/icinga2/issues/6196) (InfluxDB, Metrics, PR): Fix InfluxDB backslash escaping * [#6192](https://github.com/icinga/icinga2/issues/6192) (Crash, Elasticsearch, PR): Elasticsearch: Fix crash with invalid performance data metrics * [#6191](https://github.com/icinga/icinga2/issues/6191) (Crash, Elasticsearch): Invalid Perfdata causing Segmentation fault with ElasticsearchWriter * [#6182](https://github.com/icinga/icinga2/issues/6182) (InfluxDB): Windows Disk performance data broken in InfluxDB * [#6179](https://github.com/icinga/icinga2/issues/6179) (CLI, Crash, PR): Fix crash in api user command * [#6178](https://github.com/icinga/icinga2/issues/6178) (API, Crash): Error: boost::bad\_any\_cast: failed conversion using boost::any\_cast * [#6140](https://github.com/icinga/icinga2/issues/6140): Force check has no effect * [#6119](https://github.com/icinga/icinga2/issues/6119) (PR): fixup set rlimit stack failed condition * [#5925](https://github.com/icinga/icinga2/issues/5925) (Crash, PR): Fix missing variable name in ApiListener::Start * [#5924](https://github.com/icinga/icinga2/issues/5924) (Crash): The lock variable in ApiListener::Start is missing its name * [#5881](https://github.com/icinga/icinga2/issues/5881) (API, PR): Fix package error message * [#5706](https://github.com/icinga/icinga2/issues/5706) (Plugins, Windows): nscp\_api - cannot use check\_cpu with "time" argument used multiple times ### Documentation * [#6227](https://github.com/icinga/icinga2/issues/6227) (Documentation, PR): Fix missing anchors in CLI commands chapter * [#6203](https://github.com/icinga/icinga2/issues/6203) (Documentation, PR): Add docs for script debugger and API filters * [#6177](https://github.com/icinga/icinga2/issues/6177) (Documentation, PR): Doc: Fix typo in API user creation example * [#6176](https://github.com/icinga/icinga2/issues/6176) (Documentation, PR): hashed\_password -\> password\_hash. Fixes \#6175 * [#6175](https://github.com/icinga/icinga2/issues/6175) (Documentation): ApiUser does not know hashed\_password Attribute * [#6166](https://github.com/icinga/icinga2/issues/6166) (Documentation, PR): Fix broken link in README * [#6145](https://github.com/icinga/icinga2/issues/6145) (Documentation, PR): Fix incorrect parameter name in the API documentation * [#6102](https://github.com/icinga/icinga2/issues/6102) (Documentation, PR): Fix typo in Apply for Rules documentation * [#6080](https://github.com/icinga/icinga2/issues/6080) (Documentation, PR): Document the 'ignore\_on\_error' attribute for object creation * [#6068](https://github.com/icinga/icinga2/issues/6068) (Documentation, PR): Fix the explanation of `types` and `states` for user objects * [#5913](https://github.com/icinga/icinga2/issues/5913) (Documentation, ITL, PR): Enhance http\_certificate parameter documentation * [#5838](https://github.com/icinga/icinga2/issues/5838) (Documentation, PR): services.conf has also be moved to zones.d/global-templates/ * [#5797](https://github.com/icinga/icinga2/issues/5797) (Documentation): Document the ignore\_on\_error parameter for CreateObjectHandler::HandleRequest * [#5610](https://github.com/icinga/icinga2/issues/5610) (Documentation, ITL): http check doesn't map the critical ssl certificate age option ### Support * [#6250](https://github.com/icinga/icinga2/issues/6250) (PR): Fix typo * [#6241](https://github.com/icinga/icinga2/issues/6241) (Packages, PR): Fix Sysconfig file detection for Icinga 2 settings * [#6230](https://github.com/icinga/icinga2/issues/6230) (PR): Unbreak build against Boost 1.67 * [#6215](https://github.com/icinga/icinga2/issues/6215) (Configuration, Packages): Sysconfig limits and settings are not respected * [#6202](https://github.com/icinga/icinga2/issues/6202) (Packages, code-quality, PR): Use VERSION instead of icinga2.spec ## 2.8.2 (2018-03-22) ### Notes A bugfix release with a focus on security. Most of these have been brought to our attention by the community and we are very thankful for that. Special thanks to Michael H., Julian and Michael O., who helped by reporting and assisting us in fixing security bugs. CVEs have also been requested for these issues, they are as follows: CVE-2017-16933, CVE-2018-6532, CVE-2018-6533, CVE-2018-6534, CVE-2018-6535, CVE-2018-6536. ### Enhancement * [#5715](https://github.com/icinga/icinga2/issues/5715) (API, PR): Hash API password and comparison ### Bug * [#6153](https://github.com/icinga/icinga2/issues/6153) (API, PR): Improve error handling for empty packages in /v1/config/packages * [#6147](https://github.com/icinga/icinga2/issues/6147) (PR): Fix incorrect argument type for JsonRpc::SendMessage * [#6146](https://github.com/icinga/icinga2/issues/6146) (PR): Ensure that SetCorked\(\) works properly * [#6134](https://github.com/icinga/icinga2/issues/6134) (PR): Fix incorrect HTTP content length limits * [#6133](https://github.com/icinga/icinga2/issues/6133) (PR): Limit the number of HTTP/JSON-RPC requests we read in parallel * [#6132](https://github.com/icinga/icinga2/issues/6132) (PR): Fix HTTP parser crash/hang * [#6129](https://github.com/icinga/icinga2/issues/6129): api/packages not created by prepare-dir/daemon * [#5995](https://github.com/icinga/icinga2/issues/5995) (InfluxDB, PR): Fix InfluxDB requests * [#5991](https://github.com/icinga/icinga2/issues/5991): Partial privilege escalation via PID file manipulation * [#5987](https://github.com/icinga/icinga2/issues/5987) (Elasticsearch, InfluxDB, Metrics): InfluxDBWriter and ElasticsearchWriter stop writing to HTTP API * [#5943](https://github.com/icinga/icinga2/issues/5943) (PR): Fix incorrect ::Start call * [#5793](https://github.com/icinga/icinga2/issues/5793): CVE-2017-16933: root privilege escalation via prepare-dirs \(init script and systemd service file\) * [#5760](https://github.com/icinga/icinga2/issues/5760) (Crash, PR): Fix incorrect socket handling for the HTTP client ### Documentation * [#6172](https://github.com/icinga/icinga2/issues/6172) (Documentation, PR): Docs: Add a note to only query the NSClient++ API from the local Icinga 2 client * [#6111](https://github.com/icinga/icinga2/issues/6111) (Documentation, PR): Add Upgrading to Icinga 2.8.2 chapter * [#6089](https://github.com/icinga/icinga2/issues/6089) (Documentation, PR): Docs: Fix bracket in notification example * [#6086](https://github.com/icinga/icinga2/issues/6086) (Documentation, PR): Upgrading: Make it more clear that the Director script is just an example * [#6075](https://github.com/icinga/icinga2/issues/6075) (Documentation, PR): Explain how to register functions in the global scope * [#6014](https://github.com/icinga/icinga2/issues/6014) (Documentation, PR): Docs: Add IDO DB tuning tips * [#6006](https://github.com/icinga/icinga2/issues/6006) (Documentation, PR): Fix wrong nscp-local include in the docs ### Support * [#6148](https://github.com/icinga/icinga2/issues/6148) (PR): Fix ApiUser unit test * [#6135](https://github.com/icinga/icinga2/issues/6135) (API, Cluster, PR): Limit JSON RPC message size * [#6115](https://github.com/icinga/icinga2/issues/6115) (PR): Fix incorrect size of request limits * [#6114](https://github.com/icinga/icinga2/issues/6114) (PR): Fix typo in prepare-dirs * [#6104](https://github.com/icinga/icinga2/issues/6104) (PR): Fix nullptr dereferences * [#6103](https://github.com/icinga/icinga2/issues/6103) (PR): HTTP Security fixes * [#5982](https://github.com/icinga/icinga2/issues/5982) (Packages, PR): SELinux: Allows icinga2\_t to send sigkill to all domains it transitions to * [#5916](https://github.com/icinga/icinga2/issues/5916) (Packages): Unable to kill process group after check timeout if SElinux is enabled * [#5850](https://github.com/icinga/icinga2/issues/5850) (Installation, PR): init script security fixes * [#5764](https://github.com/icinga/icinga2/issues/5764) (InfluxDB, code-quality, PR): Improve InfluxdbWriter performance * [#5759](https://github.com/icinga/icinga2/issues/5759) (code-quality, PR): Make default getters and setters non-virtual ## 2.8.1 (2018-01-17) ### Enhancement * [#5856](https://github.com/icinga/icinga2/issues/5856) (PR): Implement AppLocal deployment support for UCRT ### Bug * [#5986](https://github.com/icinga/icinga2/issues/5986) (DB IDO, PR): Fix wrong schema constraint for fresh 2.8.0 installations * [#5947](https://github.com/icinga/icinga2/issues/5947) (DB IDO): Duplicate entry constraint violations in 2.8 * [#5907](https://github.com/icinga/icinga2/issues/5907) (PR): Windows plugin check\_swap build fix * [#5808](https://github.com/icinga/icinga2/issues/5808) (Crash, PR): Fix missing variable name which can lead to segfaults * [#5807](https://github.com/icinga/icinga2/issues/5807) (Crash): icinga v2.8.0 crashes frequently with "segmentation fault" on Debian 8.9 * [#5804](https://github.com/icinga/icinga2/issues/5804) (Log, PR): Silence UpdateRepository message errors * [#5776](https://github.com/icinga/icinga2/issues/5776) (Cluster, Log): 2.8.0: warning/JsonRpcConnection: Call to non-existent function 'event::UpdateRepository' * [#5746](https://github.com/icinga/icinga2/issues/5746) (Livestatus, PR): livestatus: custom variables return empty arrays instead of strings * [#5716](https://github.com/icinga/icinga2/issues/5716) (Livestatus, PR): add bogus zero reply in livestatus when aggregate and non matching filter * [#5626](https://github.com/icinga/icinga2/issues/5626) (Livestatus, help wanted): Empty result set with non-matching filters in Livestatus stats query ### ITL * [#5785](https://github.com/icinga/icinga2/issues/5785) (ITL, PR): ITL: Drop ssl\_sni default setting * [#5775](https://github.com/icinga/icinga2/issues/5775) (ITL): Default usage of ssl\_sni in check\_tcp ### Documentation * [#5972](https://github.com/icinga/icinga2/issues/5972) (Documentation, PR): Update 08-advanced-topics.md * [#5942](https://github.com/icinga/icinga2/issues/5942) (Documentation, PR): Add some technical insights into the cluster-zone health check and log lag * [#5922](https://github.com/icinga/icinga2/issues/5922) (Documentation, PR): Fix link format in documentation * [#5918](https://github.com/icinga/icinga2/issues/5918) (Documentation, PR): Fix typo in SELinux documentation * [#5911](https://github.com/icinga/icinga2/issues/5911) (Documentation, PR): Update ElasticsearchWriter docs for 5.x support only * [#5866](https://github.com/icinga/icinga2/issues/5866) (Documentation, PR): Remove redundant FreeBSD from restart instructions and add openSUSE * [#5864](https://github.com/icinga/icinga2/issues/5864) (Documentation, PR): Add missing initdb to PostgreSQL documentation * [#5835](https://github.com/icinga/icinga2/issues/5835) (Documentation, PR): Fixes postgres schema upgrade path * [#5833](https://github.com/icinga/icinga2/issues/5833) (Documentation, PR): fix formatting error * [#5790](https://github.com/icinga/icinga2/issues/5790) (Documentation, PR): Documentation fixes * [#5783](https://github.com/icinga/icinga2/issues/5783) (Documentation, PR): Fix formatting in value types docs * [#5773](https://github.com/icinga/icinga2/issues/5773) (Documentation, Windows, PR): Update Windows Client requirements for 2.8 * [#5757](https://github.com/icinga/icinga2/issues/5757) (Documentation, PR): Add documentation about automatic service restarts with systemd ### Support * [#5989](https://github.com/icinga/icinga2/issues/5989) (PR): changelog.py: Adjust categories and labels: Enhancement, Bug, ITL, Documentation, Support * [#5938](https://github.com/icinga/icinga2/issues/5938) (Packages, Windows): chocolatey outdated version * [#5893](https://github.com/icinga/icinga2/issues/5893) (code-quality, PR): Whitespace fix * [#5892](https://github.com/icinga/icinga2/issues/5892) (Installation, PR): Enable installing the init scripts on Solaris * [#5851](https://github.com/icinga/icinga2/issues/5851) (Plugins, Windows, PR): Fix check\_service returning Warning instead of Critical * [#5780](https://github.com/icinga/icinga2/issues/5780) (Packages, Windows): Icinga Agent Windows 2.8.0 msvcr120.dll is missing ## 2.8.0 (2017-11-16) ### Notes * Certificate path changed to /var/lib/icinga2/certs - check the upgrading docs! * DB IDO 2.8.0 schema upgrade * Cluster/Clients: Forward certificate signing requests over multiple levels * Cluster/Clients: Support on-demand signing next to ticket based certificate request signing * New flapping detection algorithm * Add ElasticsearchWriter feature with HTTP proxy support * Add CORS support for the REST API * Deprecate `flapping_threshold` config option * Remove client configuration mode "bottom up" * Remove classicui meta configuration package * Remove deprecated `enable_legacy_mode` in Graphite feature * Spec file was moved to https://github.com/icinga/icinga-packaging * ITL CheckCommand definition updates * Documentation updates ### Enhancement * [#5682](https://github.com/icinga/icinga2/issues/5682) (Cluster, Configuration, PR): Implement support for migrating certificates to /var/lib/icinga2/certs * [#5681](https://github.com/icinga/icinga2/issues/5681) (CLI, Cluster, Windows): Update Windows wizard from enhanced CSR signing \(optional ticket\) * [#5679](https://github.com/icinga/icinga2/issues/5679) (CLI, Cluster): Migration path for improved certificate signing in the cluster * [#5606](https://github.com/icinga/icinga2/issues/5606) (Cluster, PR): Remove bottom-up client mode * [#5602](https://github.com/icinga/icinga2/issues/5602) (Windows, PR): Add windows process elevation and log message if user does not have privileges to read/write files * [#5587](https://github.com/icinga/icinga2/issues/5587) (Log, PR): SyslogLogger: Implement option to set syslog facility * [#5580](https://github.com/icinga/icinga2/issues/5580) (Configuration, PR): Implement new script functions: path\_exists, glob and glob\_recursive * [#5571](https://github.com/icinga/icinga2/issues/5571) (CLI, Cluster, PR): Implement support for forwarding certificate signing requests in the cluster * [#5569](https://github.com/icinga/icinga2/issues/5569) (Metrics, PR): ElasticWriter: Add basic auth and TLS support for Elasticsearch behind an HTTP proxy * [#5554](https://github.com/icinga/icinga2/issues/5554) (API, Cluster, PR): Add subjectAltName extension for all non-CA certificates * [#5547](https://github.com/icinga/icinga2/issues/5547) (API, PR): Add optional reload parameter to config stage upload * [#5538](https://github.com/icinga/icinga2/issues/5538) (Metrics): Add ElasticsearchWriter feature * [#5534](https://github.com/icinga/icinga2/issues/5534) (Configuration, PR): Implement get\_services\(host {name,object}\) and add host object support for get\_service\(\) * [#5527](https://github.com/icinga/icinga2/issues/5527) (API, PR): API: Add execution\_{start,end} attribute to 'process-check-result' action * [#5450](https://github.com/icinga/icinga2/issues/5450) (CLI, Cluster): Enhance CSR Autosigning \(CA proxy, etc.\) * [#5443](https://github.com/icinga/icinga2/issues/5443) (API, PR): Add CORS support and set response header 'Access-Control-Allow-Origin' * [#5435](https://github.com/icinga/icinga2/issues/5435) (Plugins, Windows, PR): Add -d option to check\_service * [#5002](https://github.com/icinga/icinga2/issues/5002) (API, wishlist): API process-check-result allow setting timestamp * [#4912](https://github.com/icinga/icinga2/issues/4912) (Configuration): new function get\_services\(host\_name\) * [#4799](https://github.com/icinga/icinga2/issues/4799) (Cluster): Remove cluster/client mode "bottom up" w/ repository.d and node update-config * [#4769](https://github.com/icinga/icinga2/issues/4769) (API): Validate and activate config package stages without triggering a reload * [#4326](https://github.com/icinga/icinga2/issues/4326) (API): API should provide CORS Header * [#3891](https://github.com/icinga/icinga2/issues/3891) (Plugins): Add option to specify ServiceDescription instead of ServiceName with check\_service.exe ### Bug * [#5728](https://github.com/icinga/icinga2/issues/5728) (Plugins, Windows, PR): Fix check\_service not working with names * [#5720](https://github.com/icinga/icinga2/issues/5720) (Check Execution): Flapping tests and bugs * [#5710](https://github.com/icinga/icinga2/issues/5710) (CLI, Configuration, PR): Include default global zones during node wizard/setup * [#5707](https://github.com/icinga/icinga2/issues/5707) (CLI): node wizard/setup override zones.conf but do not include default global zones \(director-global, global-templates\) * [#5696](https://github.com/icinga/icinga2/issues/5696) (PR): Fix fork error handling * [#5641](https://github.com/icinga/icinga2/issues/5641) (PR): Fix compiler warnings on macOS 10.13 * [#5635](https://github.com/icinga/icinga2/issues/5635) (Configuration, PR): Fix match\(\), regex\(\), cidr\_match\(\) behaviour with MatchAll and empty arrays * [#5634](https://github.com/icinga/icinga2/issues/5634) (Configuration): match\(\) for arrays returns boolean true if array is empty * [#5620](https://github.com/icinga/icinga2/issues/5620) (API, PR): Ensure that the REST API config package/stage creation is atomic * [#5617](https://github.com/icinga/icinga2/issues/5617): Crash with premature EOF on resource limited OS * [#5614](https://github.com/icinga/icinga2/issues/5614) (PR): Fixed missing include statement in unit tests * [#5584](https://github.com/icinga/icinga2/issues/5584) (Windows): Build error on Windows * [#5581](https://github.com/icinga/icinga2/issues/5581) (API, Cluster, Crash, PR): Fix possible race condition in ApiListener locking * [#5558](https://github.com/icinga/icinga2/issues/5558) (API, PR): Don't sent scheme and hostname in request * [#5515](https://github.com/icinga/icinga2/issues/5515) (Windows): Config validation fails on Windows with unprivileged account * [#5500](https://github.com/icinga/icinga2/issues/5500) (Crash, PR): Process: Fix JSON parsing error on process helper crash * [#5497](https://github.com/icinga/icinga2/issues/5497) (API, PR): API: Fix requested attrs/joins/meta type errors in object query response * [#5485](https://github.com/icinga/icinga2/issues/5485) (DB IDO, PR): Ensure that expired/removed downtimes/comments are correctly updated in DB IDO * [#5377](https://github.com/icinga/icinga2/issues/5377) (API, Log): Sending wrong value for key causes ugly stacktrace * [#5231](https://github.com/icinga/icinga2/issues/5231) (Check Execution, PR): Report failure to kill check command after exceeding timeout * [#4981](https://github.com/icinga/icinga2/issues/4981) (Check Execution): Failure to kill check command after exceeding timeout is not reported ### ITL * [#5678](https://github.com/icinga/icinga2/issues/5678) (ITL, PR): Added missing "-q" parameter to check\_ntp\_peer * [#5672](https://github.com/icinga/icinga2/issues/5672) (ITL, PR): add itl snmp-service for manubulon plugin check\_snmp\_win.pl * [#5647](https://github.com/icinga/icinga2/issues/5647) (ITL, PR): Allow to disable thresholds for ipmi CheckCommand * [#5640](https://github.com/icinga/icinga2/issues/5640) (ITL, PR): ITL: Support weathermap data in snmp\_interface CheckCommand * [#5638](https://github.com/icinga/icinga2/issues/5638) (ITL, PR): Add support for check\_address as default in database CheckCommand objects * [#5578](https://github.com/icinga/icinga2/issues/5578) (ITL, PR): ITL: Re-Add ssl\_sni attribute for check\_tcp * [#5577](https://github.com/icinga/icinga2/issues/5577) (ITL): ssl CheckCommand does not support SNI * [#5570](https://github.com/icinga/icinga2/issues/5570) (ITL, PR): check\_esxi\_hardware.py with new --no-lcd parameter * [#5559](https://github.com/icinga/icinga2/issues/5559) (ITL, PR): Exclude configfs from disk checks * [#5427](https://github.com/icinga/icinga2/issues/5427) (ITL): Update negate CheckCommand definition * [#5401](https://github.com/icinga/icinga2/issues/5401) (ITL, PR): itl: Add manubulon/check\_snmp\_env.pl as CheckCommand snmp-env * [#5394](https://github.com/icinga/icinga2/issues/5394) (ITL, PR): itl: add additional mssql\_health arguments * [#5387](https://github.com/icinga/icinga2/issues/5387) (ITL, PR): Add missing options to snmp CheckCommand definition ### Documentation * [#5768](https://github.com/icinga/icinga2/issues/5768) (Documentation, PR): Update .mailmap and AUTHORS * [#5761](https://github.com/icinga/icinga2/issues/5761) (Documentation, PR): Fix wrong anchors in the documentation * [#5755](https://github.com/icinga/icinga2/issues/5755) (Documentation, PR): Fix missing Accept header in troubleshooting docs * [#5754](https://github.com/icinga/icinga2/issues/5754) (Documentation, PR): Improve documentation of cipher\_list * [#5752](https://github.com/icinga/icinga2/issues/5752) (Documentation, PR): Add Noah Hilverling to .mailmap * [#5748](https://github.com/icinga/icinga2/issues/5748) (Documentation, PR): Fix missing word in pin checks in a zone doc chapter * [#5741](https://github.com/icinga/icinga2/issues/5741) (Documentation, PR): Fix manual certificate creation chapter in the docs * [#5738](https://github.com/icinga/icinga2/issues/5738) (Documentation, PR): Update release docs * [#5734](https://github.com/icinga/icinga2/issues/5734) (Documentation, PR): Fix broken links inside the documentation * [#5727](https://github.com/icinga/icinga2/issues/5727) (Documentation, PR): Update upgrading documentation for 2.8 * [#5708](https://github.com/icinga/icinga2/issues/5708) (Documentation, PR): Fixed grammar and spelling mistakes * [#5703](https://github.com/icinga/icinga2/issues/5703) (Documentation): Minor documentation typos in flapping detection description * [#5695](https://github.com/icinga/icinga2/issues/5695) (Documentation, PR): Enhance Security chapter for Distributed Monitoring documentation * [#5691](https://github.com/icinga/icinga2/issues/5691) (Documentation, PR): Fixed doc formatting * [#5690](https://github.com/icinga/icinga2/issues/5690) (Documentation): Improve documentation of cipher\_list * [#5688](https://github.com/icinga/icinga2/issues/5688) (Documentation, PR): Fixed typos and punctuation * [#5680](https://github.com/icinga/icinga2/issues/5680) (Documentation): Review documentation for enhanced CSR signing and update migration chapter for 2.8 * [#5677](https://github.com/icinga/icinga2/issues/5677) (Documentation, PR): Fix typo in threshold syntax documentation * [#5668](https://github.com/icinga/icinga2/issues/5668) (Documentation, PR): Enhance Monitoring Basics in the documentation * [#5667](https://github.com/icinga/icinga2/issues/5667) (Documentation): Explain which values can be used for set\_if in command arguments * [#5666](https://github.com/icinga/icinga2/issues/5666) (Documentation): Explain the notification with users defined on host/service in a dedicated docs chapter * [#5665](https://github.com/icinga/icinga2/issues/5665) (Documentation): Better explanations and iteration details for "apply for" documentation * [#5664](https://github.com/icinga/icinga2/issues/5664) (Documentation): Add usage examples to the "apply" chapter based on custom attribute values * [#5663](https://github.com/icinga/icinga2/issues/5663) (Documentation): Explain custom attribute value types and nested dictionaries * [#5662](https://github.com/icinga/icinga2/issues/5662) (Documentation): Explain how to use a different host check command * [#5655](https://github.com/icinga/icinga2/issues/5655) (Documentation, PR): Enhance documentation with more details on value types for object attributes * [#5576](https://github.com/icinga/icinga2/issues/5576) (Documentation, PR): Fixed downtime example in documentation * [#5568](https://github.com/icinga/icinga2/issues/5568) (Documentation, PR): Add documentation for multi-line plugin output for API actions * [#5511](https://github.com/icinga/icinga2/issues/5511) (Cluster, Documentation, Windows): SSL errors with leading zeros in certificate serials \(created \< v2.4\) with OpenSSL 1.1.0 * [#5379](https://github.com/icinga/icinga2/issues/5379) (Documentation, PR): Set shell prompt for commands to be \# * [#5186](https://github.com/icinga/icinga2/issues/5186) (Documentation): Document boolean values understood by set\_if * [#5060](https://github.com/icinga/icinga2/issues/5060) (Documentation): Missing documentation for macro\(\) * [#4015](https://github.com/icinga/icinga2/issues/4015) (Documentation): Add documentation for host state calculation from plugin exit codes ### Support * [#5765](https://github.com/icinga/icinga2/issues/5765) (Configuration, PR): Fix default configuration example for ElasticsearchWriter * [#5739](https://github.com/icinga/icinga2/issues/5739) (Metrics, PR): Rename ElasticWriter to ElasticsearchWriter * [#5732](https://github.com/icinga/icinga2/issues/5732) (Check Execution, DB IDO, PR): Fix flapping calculation and events * [#5730](https://github.com/icinga/icinga2/issues/5730) (PR): Add missing trims to GetMasterHostPort and remove Convert.ToString from variables that are strings already * [#5719](https://github.com/icinga/icinga2/issues/5719) (Cluster, Installation, Windows, PR): Update Windows Wizard for 2.8 and new signing methods * [#5687](https://github.com/icinga/icinga2/issues/5687) (Cluster, Log, PR): Improve error message for unknown cluster message functions * [#5686](https://github.com/icinga/icinga2/issues/5686) (Log): Ugly stacktrace with mismatching versions in cluster * [#5643](https://github.com/icinga/icinga2/issues/5643) (PR): Fix debug builds on Apple Clang 9.0.0 \(macOS High Sierra\) * [#5637](https://github.com/icinga/icinga2/issues/5637) (InfluxDB, PR): Fix unnecessary String\(\) casts in InfluxdbWriter * [#5629](https://github.com/icinga/icinga2/issues/5629) (InfluxDB, Metrics, code-quality): Remove the unnecessary String\(\) casts in influxdbwriter.cpp * [#5624](https://github.com/icinga/icinga2/issues/5624) (PR): Fixed missing include statement in unit test * [#5619](https://github.com/icinga/icinga2/issues/5619) (Packages, PR): Exit early in changelog.py if GitHub API fetch fails * [#5616](https://github.com/icinga/icinga2/issues/5616) (PR): Fix a build warning * [#5608](https://github.com/icinga/icinga2/issues/5608) (CLI, Cluster, PR): Fix certificate paths for installers * [#5604](https://github.com/icinga/icinga2/issues/5604) (Packages, PR): Remove the icinga2-classicui-package and update documentation * [#5601](https://github.com/icinga/icinga2/issues/5601) (Installation, Packages, PR): Ensure that the cache directory always is set and add a note to upgrading docs * [#5563](https://github.com/icinga/icinga2/issues/5563) (Cluster, PR): Implement additional logging for the JsonRpc class * [#5545](https://github.com/icinga/icinga2/issues/5545) (Installation, Windows, PR): Add Edit button to Windows Setup Wizard * [#5488](https://github.com/icinga/icinga2/issues/5488) (code-quality, PR): Implement additional functions for printing values with LLDB/GDB * [#5486](https://github.com/icinga/icinga2/issues/5486) (Graphite, PR): Graphite: Remove deprecated legacy schema mode * [#5301](https://github.com/icinga/icinga2/issues/5301) (Installation, Packages): Remove the icinga2-classicui-config package * [#5258](https://github.com/icinga/icinga2/issues/5258) (Installation, PR): Fix clang compiler detection on Fedora and macOS * [#4992](https://github.com/icinga/icinga2/issues/4992) (Graphite): Remove deprecated GraphiteWriter feature enable\_legacy\_mode * [#4982](https://github.com/icinga/icinga2/issues/4982) (Notifications, Tests): Verify and fix flapping detection ## 2.7.2 (2017-11-09) ### Notes * Fixed invalid attribute names in the systemd unit file * Fixed incorrect unique constraint for IDO DB * Moved spec file to the icinga-packaging Git repository * Documentation updates ### Bug * [#5636](https://github.com/icinga/icinga2/issues/5636) (DB IDO, PR): Fix unique constraint matching for UPDATE downtime/comment runtime tables in DB IDO * [#5623](https://github.com/icinga/icinga2/issues/5623) (DB IDO): Duplicate Key on MySQL after upgrading to v2.7.1 * [#5603](https://github.com/icinga/icinga2/issues/5603) (DB IDO): Icinga 2.7.1 IDO Unique Key Constraint Violation with PostgreSQL ### Documentation * [#5653](https://github.com/icinga/icinga2/issues/5653) (Documentation, PR): Docs: Fix default value for `snmp\_nocrypt` for Manubulon CheckCommand definitions * [#5652](https://github.com/icinga/icinga2/issues/5652) (Documentation, PR): Docs: Fix missing default value for cluster-zone checks * [#5632](https://github.com/icinga/icinga2/issues/5632) (Documentation, PR): Docs: Mention SELinux in Getting Started chapter ### Support * [#5736](https://github.com/icinga/icinga2/issues/5736) (Packages, PR): Remove spec file * [#5612](https://github.com/icinga/icinga2/issues/5612) (Documentation, Packages, PR): Improve documentation and systemd config on TaskMax ## 2.7.1 (2017-09-21) ### Notes * Fixes and upgrade documentation for notificatication scripts introduced in 2.7.0 * InfluxdbWriter attribute `socket_timeout` introduced in 2.7.0 was deprecated (will be removed in 2.8.0). Details in #5469 and #5460 * Livestatus bygroup table stats fixes for NagVis * DB IDO: Fixes for downtime/comment history queries not correctly updating the end time * check_nscp_api allows white spaces in arguments * Bugfixes * Documentation updates ### Enhancement * [#5523](https://github.com/icinga/icinga2/issues/5523) (Cluster, Log, PR): Enhance client connect/sync logging and include bytes/zone in logs * [#5474](https://github.com/icinga/icinga2/issues/5474) (Notifications, PR): Notification scripts - make HOSTADDRESS optional * [#5468](https://github.com/icinga/icinga2/issues/5468) (Notifications, PR): Make notification mails more readable. Remove redundancy and cruft. ### Bug * [#5585](https://github.com/icinga/icinga2/issues/5585) (DB IDO, PR): Fix where clause for non-matching {downtime,comment}history IDO database updates * [#5566](https://github.com/icinga/icinga2/issues/5566) (Cluster, Log, PR): Logs: Change config sync update to highlight an information, not an error * [#5539](https://github.com/icinga/icinga2/issues/5539) (Plugins, Windows, PR): check\_nscp\_api: Allow arguments containing spaces * [#5537](https://github.com/icinga/icinga2/issues/5537) (Plugins): check\_nscp\_api: support spaces in query arguments * [#5524](https://github.com/icinga/icinga2/issues/5524) (Cluster, PR): Change FIFO::Optimize\(\) frequency for large messages * [#5513](https://github.com/icinga/icinga2/issues/5513) (Cluster): Node in Cluster loses connection * [#5504](https://github.com/icinga/icinga2/issues/5504) (InfluxDB, PR): Fix TLS Race Connecting to InfluxDB * [#5503](https://github.com/icinga/icinga2/issues/5503) (Livestatus, PR): Fix grouping for Livestatus queries with 'Stats' * [#5502](https://github.com/icinga/icinga2/issues/5502) (Notifications, PR): Fix duplicate variable in notification scripts * [#5495](https://github.com/icinga/icinga2/issues/5495) (Notifications, PR): Fix parameter order for AcknowledgeSvcProblem / AcknowledgeHostProblem / apiactions:AcknowledgeProblem * [#5492](https://github.com/icinga/icinga2/issues/5492) (DB IDO): Comments may not be removed correctly * [#5484](https://github.com/icinga/icinga2/issues/5484) (Log): Timestamp comparison of config files logs a wrong message * [#5483](https://github.com/icinga/icinga2/issues/5483) (DB IDO, PR): Fix config validation for DB IDO categories 'DbCatEverything' * [#5469](https://github.com/icinga/icinga2/issues/5469) (InfluxDB): Failure to connect to InfluxDB increases CPU utilisation by 100% for every failure * [#5466](https://github.com/icinga/icinga2/issues/5466) (DB IDO, PR): DB IDO: Fix host's unreachable state in history tables * [#5460](https://github.com/icinga/icinga2/issues/5460) (InfluxDB): Icinga 2.7 InfluxdbWriter fails to write metrics to InfluxDB over HTTPS * [#5458](https://github.com/icinga/icinga2/issues/5458) (DB IDO): IDO donwtimehistory records orphaned from scheduleddowntime records following restart * [#5405](https://github.com/icinga/icinga2/issues/5405) (DB IDO): IDO statehistory table does not show hosts going to "UNREACHABLE" state. * [#5078](https://github.com/icinga/icinga2/issues/5078) (Compat, Livestatus): Livestatus hostsbygroup and servicesbyhostgroup do not work ### ITL * [#5543](https://github.com/icinga/icinga2/issues/5543) (ITL, PR): ITL: Correct arguments for ipmi-sensor CheckCommand ### Documentation * [#5594](https://github.com/icinga/icinga2/issues/5594) (Documentation, PR): Docs: Enhance certificate and configuration troubleshooting chapter * [#5593](https://github.com/icinga/icinga2/issues/5593) (Documentation, PR): Docs: Add a note for upgrading to 2.7 * [#5583](https://github.com/icinga/icinga2/issues/5583) (Documentation, PR): Docs: Add example for Windows service monitoring with check\_nscp\_api * [#5582](https://github.com/icinga/icinga2/issues/5582) (Documentation, PR): Docs: Add firewall details for check\_nscp\_api * [#5549](https://github.com/icinga/icinga2/issues/5549) (Documentation, PR): Fix cli command used to enable debuglog feature on windows * [#5536](https://github.com/icinga/icinga2/issues/5536) (Documentation, PR): Fixed nscp-disk service example * [#5522](https://github.com/icinga/icinga2/issues/5522) (Documentation, PR): Docs: Update freshness checks; add chapter for external check results * [#5516](https://github.com/icinga/icinga2/issues/5516) (Documentation, PR): Updates the install dependencies for Debian 9 'stretch' * [#5506](https://github.com/icinga/icinga2/issues/5506) (Documentation, PR): Docs: Fix wrong parameter for ITL CheckCommand nscp\_api * [#5496](https://github.com/icinga/icinga2/issues/5496) (Documentation, PR): Docs: Update examples for match/regex/cidr\_match and mode for arrays \(Match{All,Any}\) * [#5494](https://github.com/icinga/icinga2/issues/5494) (Documentation, PR): Docs: Add section for multiple template imports * [#5491](https://github.com/icinga/icinga2/issues/5491) (Documentation, PR): Update "Getting Started" documentation with Alpine Linux * [#5487](https://github.com/icinga/icinga2/issues/5487) (Documentation, PR): Docs: Enhance Troubleshooting with nscp-local, check\_source, wrong thresholds * [#5476](https://github.com/icinga/icinga2/issues/5476) (Documentation, PR): Docs: Fix ITL chapter TOC; add introduction with mini TOC * [#5475](https://github.com/icinga/icinga2/issues/5475) (Documentation, PR): Docs: Add a note on required configuration updates for new notification scripts in v2.7.0 * [#5461](https://github.com/icinga/icinga2/issues/5461) (Documentation, PR): Update Icinga repository release rpm location * [#5457](https://github.com/icinga/icinga2/issues/5457) (Documentation, PR): Add Changelog generation script for GitHub API * [#5428](https://github.com/icinga/icinga2/issues/5428) (Documentation): "Plugin Check Commands" section inside ITL docs needs adjustments ### Support * [#5599](https://github.com/icinga/icinga2/issues/5599) (PR): changelog.py: Add "backported" to the list of ignored labels * [#5590](https://github.com/icinga/icinga2/issues/5590) (Cluster, Log, PR): Silence log level for configuration file updates * [#5529](https://github.com/icinga/icinga2/issues/5529) (Log, PR): Change two more loglines for checkables so checkable is quoted * [#5528](https://github.com/icinga/icinga2/issues/5528) (Log, PR): Change loglines for checkables so checkable is quoted * [#5501](https://github.com/icinga/icinga2/issues/5501) (Installation, Packages, PR): SELinux: fixes for 2.7.0 * [#5479](https://github.com/icinga/icinga2/issues/5479) (Packages): Icinga2 2.7.0 requires SELinux boolean icinga2\_can\_connect\_all on CentOS 7 even for default port * [#5477](https://github.com/icinga/icinga2/issues/5477) (Installation, Packages, PR): Systemd: Add DefaultTasksMax=infinity to service file * [#5392](https://github.com/icinga/icinga2/issues/5392) (Packages, PR): Ensure the cache directory exists * [#4918](https://github.com/icinga/icinga2/issues/4918) (Packages): cgroup: fork rejected by pids controller in /system.slice/icinga2.service * [#4414](https://github.com/icinga/icinga2/issues/4414) (Packages): /usr/lib/icinga2/prepare-dirs does not create /var/cache/icinga2 ## 2.7.0 (2017-08-02) ### Notes * New mail notification scripts. Please note that this requires a configuration update to NotificationCommand objects, Notification apply rules for specific settings and of course the notification scripts. More can be found [here](https://github.com/Icinga/icinga2/pull/5475). * check_nscp_api plugin for NSClient++ REST API checks * Work queues for features including logs & metrics * More metrics for the "icinga" check * Many bugfixes ### Enhancement * [#5421](https://github.com/icinga/icinga2/issues/5421) (Plugins, Windows, PR): Windows Plugins: Add new parameter to check\_disk to show used space * [#5348](https://github.com/icinga/icinga2/issues/5348) (Configuration, PR): Implement support for handling exceptions in user scripts * [#5331](https://github.com/icinga/icinga2/issues/5331) (Graylog, PR): GelfWriter: Add 'check\_command' to CHECK RESULT/\* NOTIFICATION/STATE CHANGE messages * [#5330](https://github.com/icinga/icinga2/issues/5330) (Graphite, PR): GraphiteWriter: Add 'connected' to stats; fix reconnect exceptions * [#5329](https://github.com/icinga/icinga2/issues/5329) (Graylog, PR): GelfWriter: Use async work queue and add feature metric stats * [#5320](https://github.com/icinga/icinga2/issues/5320) (Configuration, PR): zones.conf: Add global-templates & director-global by default * [#5287](https://github.com/icinga/icinga2/issues/5287) (Graphite, InfluxDB, Metrics, PR): Use workqueues in Graphite and InfluxDB features * [#5284](https://github.com/icinga/icinga2/issues/5284) (Check Execution, PR): Add feature stats to 'icinga' check as performance data metrics * [#5280](https://github.com/icinga/icinga2/issues/5280) (API, Cluster, Log, PR): Implement WorkQueue metric stats and periodic logging * [#5266](https://github.com/icinga/icinga2/issues/5266) (API, Cluster, PR): Add API & Cluster metric stats to /v1/status & icinga check incl. performance data * [#5264](https://github.com/icinga/icinga2/issues/5264) (Configuration, PR): Implement new array match functionality * [#5247](https://github.com/icinga/icinga2/issues/5247) (Log, PR): Add target object in cluster error messages to debug log * [#5246](https://github.com/icinga/icinga2/issues/5246) (API, Cluster, PR): Add subjectAltName X509 ext for certificate requests * [#5242](https://github.com/icinga/icinga2/issues/5242) (Configuration, PR): Allow expressions for the type in object/template declarations * [#5241](https://github.com/icinga/icinga2/issues/5241) (InfluxDB, PR): Verbose InfluxDB Error Logging * [#5239](https://github.com/icinga/icinga2/issues/5239) (Plugins, Windows, PR): Add NSCP API check plugin for NSClient++ HTTP API * [#5212](https://github.com/icinga/icinga2/issues/5212) (Cluster, Log): Add additional logging for config sync * [#5145](https://github.com/icinga/icinga2/issues/5145): Add a GitHub issue template * [#5133](https://github.com/icinga/icinga2/issues/5133) (API, wishlist): ApiListener: Metrics for cluster data * [#5106](https://github.com/icinga/icinga2/issues/5106) (Configuration): Add director-global as global zone to the default zones.conf configuration * [#4945](https://github.com/icinga/icinga2/issues/4945) (API, Log): No hint for missing permissions in Icinga2 log for API user * [#4925](https://github.com/icinga/icinga2/issues/4925): Update changelog generation scripts for GitHub * [#4411](https://github.com/icinga/icinga2/issues/4411) (InfluxDB, Log, Metrics): Better Debugging for InfluxdbWriter * [#4288](https://github.com/icinga/icinga2/issues/4288) (Cluster, Log): Add check information to the debuglog when check result is discarded * [#4242](https://github.com/icinga/icinga2/issues/4242) (Configuration): Default mail notification from header * [#3557](https://github.com/icinga/icinga2/issues/3557) (Log): Log started and stopped features ### Bug * [#5433](https://github.com/icinga/icinga2/issues/5433) (CLI, PR): Fix: update feature list help text * [#5367](https://github.com/icinga/icinga2/issues/5367) (CLI, Crash): Unable to start icinga2 with kernel-3.10.0-514.21.2 RHEL7 * [#5350](https://github.com/icinga/icinga2/issues/5350) (Plugins): check\_nscp\_api not building on Debian wheezy * [#5316](https://github.com/icinga/icinga2/issues/5316) (Livestatus, PR): Fix for stats min operator * [#5308](https://github.com/icinga/icinga2/issues/5308) (Configuration, PR): Improve validation for attributes which must not be 'null' * [#5297](https://github.com/icinga/icinga2/issues/5297) (PR): Fix compiler warnings * [#5295](https://github.com/icinga/icinga2/issues/5295) (Notifications, PR): Fix missing apostrophe in notification log * [#5292](https://github.com/icinga/icinga2/issues/5292) (PR): Build fix for OpenSSL 0.9.8 and stack\_st\_X509\_EXTENSION * [#5288](https://github.com/icinga/icinga2/issues/5288) (Configuration): Hostgroup using assign for Host with groups = null segfault * [#5278](https://github.com/icinga/icinga2/issues/5278) (PR): Build fix for I2\_LEAK\_DEBUG * [#5262](https://github.com/icinga/icinga2/issues/5262) (Graylog, PR): Fix performance data processing in GelfWriter feature * [#5259](https://github.com/icinga/icinga2/issues/5259) (API, PR): Don't allow acknowledgement expire timestamps in the past * [#5256](https://github.com/icinga/icinga2/issues/5256) (Configuration): Config type changes break object serialization \(JsonEncode\) * [#5250](https://github.com/icinga/icinga2/issues/5250) (API, Compat): Acknowledgement expire time in the past * [#5245](https://github.com/icinga/icinga2/issues/5245) (Notifications, PR): Fix that host downtimes might be triggered even if their state is Up * [#5224](https://github.com/icinga/icinga2/issues/5224) (Configuration, Notifications): Icinga sends notifications even though a Downtime object exists * [#5223](https://github.com/icinga/icinga2/issues/5223) (Plugins, Windows): Wrong return Code for Windows ICMP * [#5219](https://github.com/icinga/icinga2/issues/5219) (InfluxDB): InfluxDBWriter feature might block and leak memory * [#5211](https://github.com/icinga/icinga2/issues/5211) (API, Cluster): Config received is always accepted by client even if own config is newer * [#5194](https://github.com/icinga/icinga2/issues/5194) (API, CLI): No subjectAltName in Icinga CA created CSRs * [#5168](https://github.com/icinga/icinga2/issues/5168) (Windows): include files from other volume/partition * [#5146](https://github.com/icinga/icinga2/issues/5146) (Configuration): parsing of scheduled downtime object allow typing range instead of ranges * [#5132](https://github.com/icinga/icinga2/issues/5132) (Graphite): GraphiteWriter can slow down Icinga's check result processing * [#5062](https://github.com/icinga/icinga2/issues/5062) (Compat): icinga2 checkresults error * [#5043](https://github.com/icinga/icinga2/issues/5043) (API): API POST request with 'attrs' as array returns bad\_cast error * [#5040](https://github.com/icinga/icinga2/issues/5040) (Cluster): CRL loading fails due to incorrect return code check * [#5033](https://github.com/icinga/icinga2/issues/5033) (DB IDO): Flexible downtimes which are not triggered must not update DB IDO's actual\_end\_time in downtimehistory table * [#4984](https://github.com/icinga/icinga2/issues/4984) (API): Wrong response type when unauthorized * [#4983](https://github.com/icinga/icinga2/issues/4983) (Livestatus): Typo in livestatus key worst\_services\_state for hostgroups table * [#4956](https://github.com/icinga/icinga2/issues/4956) (DB IDO, PR): Fix persistent comments for Acknowledgements * [#4941](https://github.com/icinga/icinga2/issues/4941) (Metrics, PR): PerfData: Server Timeouts for InfluxDB Writer * [#4927](https://github.com/icinga/icinga2/issues/4927) (InfluxDB, Metrics): InfluxDbWriter error 500 hanging Icinga daemon * [#4913](https://github.com/icinga/icinga2/issues/4913) (API): acknowledge-problem api sending notifications when notify is false * [#4909](https://github.com/icinga/icinga2/issues/4909) (CLI): icinga2 feature disable fails on already disabled feature * [#4896](https://github.com/icinga/icinga2/issues/4896) (Plugins): Windows Agent: performance data of check\_perfmon * [#4832](https://github.com/icinga/icinga2/issues/4832) (API, Configuration): API max\_check\_attempts validation * [#4818](https://github.com/icinga/icinga2/issues/4818): Acknowledgements marked with Persistent Comment are not honored * [#4779](https://github.com/icinga/icinga2/issues/4779): Superflous error messages for non-exisiting lsb\_release/sw\_vers commands \(on NetBSD\) * [#4778](https://github.com/icinga/icinga2/issues/4778): Fix for traditional glob\(3\) behaviour * [#4777](https://github.com/icinga/icinga2/issues/4777): NetBSD execvpe.c fix * [#4709](https://github.com/icinga/icinga2/issues/4709) (API): Posting config stage fails on FreeBSD * [#4696](https://github.com/icinga/icinga2/issues/4696) (Notifications): Notifications are sent when reloading Icinga 2 even though they're deactivated via modified attributes * [#4666](https://github.com/icinga/icinga2/issues/4666) (Graylog, Metrics): GelfWriter with enable\_send\_perfdata breaks checks * [#4532](https://github.com/icinga/icinga2/issues/4532) (Graylog, Metrics): Icinga 2 "hangs" if the GelfWriter cannot send messages * [#4440](https://github.com/icinga/icinga2/issues/4440) (DB IDO, Log): Exceptions might be better than exit in IDO * [#3664](https://github.com/icinga/icinga2/issues/3664) (DB IDO): mysql\_error cannot be used for mysql\_init * [#3483](https://github.com/icinga/icinga2/issues/3483) (Compat): Stacktrace on Command Pipe Error * [#3410](https://github.com/icinga/icinga2/issues/3410) (Livestatus): Livestatus: Problem with stats min operator * [#121](https://github.com/icinga/icinga2/issues/121) (CLI, PR): give only warnings if feature is already disabled ### ITL * [#5384](https://github.com/icinga/icinga2/issues/5384) (ITL, PR): Remove default value for 'dns\_query\_type' * [#5383](https://github.com/icinga/icinga2/issues/5383) (ITL): Monitoring-Plugins check\_dns command does not support the `-q` flag * [#5372](https://github.com/icinga/icinga2/issues/5372) (ITL, PR): Update ITL CheckCommand description attribute, part 2 * [#5363](https://github.com/icinga/icinga2/issues/5363) (ITL, PR): Update missing description attributes for ITL CheckCommand definitions * [#5347](https://github.com/icinga/icinga2/issues/5347) (ITL, PR): Improve ITL CheckCommand description attribute * [#5344](https://github.com/icinga/icinga2/issues/5344) (ITL, PR): Add ip4-or-ipv6 import to logstash ITL command * [#5343](https://github.com/icinga/icinga2/issues/5343) (ITL): logstash ITL command misses import * [#5236](https://github.com/icinga/icinga2/issues/5236) (ITL, PR): ITL: Add some missing arguments to ssl\_cert * [#5210](https://github.com/icinga/icinga2/issues/5210) (ITL, PR): Add report mode to db2\_health * [#5170](https://github.com/icinga/icinga2/issues/5170) (ITL, PR): Enhance mail notifications scripts and add support for command line parameters * [#5139](https://github.com/icinga/icinga2/issues/5139) (ITL, PR): Add more options to ldap CheckCommand * [#5129](https://github.com/icinga/icinga2/issues/5129) (ITL): Additional parameters for perfout manubulon scripts * [#5126](https://github.com/icinga/icinga2/issues/5126) (ITL, PR): Added support to NRPE v2 in NRPE CheckCommand * [#5075](https://github.com/icinga/icinga2/issues/5075) (ITL, PR): fix mitigation for nwc\_health * [#5063](https://github.com/icinga/icinga2/issues/5063) (ITL, PR): Add additional arguments to mssql\_health * [#5046](https://github.com/icinga/icinga2/issues/5046) (ITL): Add querytype to dns check * [#5019](https://github.com/icinga/icinga2/issues/5019) (ITL, PR): Added CheckCommand definitions for SMART, RAID controller and IPMI ping check * [#5015](https://github.com/icinga/icinga2/issues/5015) (ITL, PR): nwc\_health\_report attribute requires a value * [#4987](https://github.com/icinga/icinga2/issues/4987) (ITL): Review `dummy` entry in ITL * [#4985](https://github.com/icinga/icinga2/issues/4985) (ITL): Allow hpasm command from ITL to run in local mode * [#4964](https://github.com/icinga/icinga2/issues/4964) (ITL, PR): ITL: check\_icmp: add missing TTL attribute * [#4839](https://github.com/icinga/icinga2/issues/4839) (ITL): Remove deprecated dns\_expected\_answer attribute * [#4826](https://github.com/icinga/icinga2/issues/4826) (ITL): Prepare icingacli-businessprocess for next release * [#4661](https://github.com/icinga/icinga2/issues/4661) (ITL): ITL - check\_oracle\_health - report option to shorten output * [#124](https://github.com/icinga/icinga2/issues/124) (ITL, PR): FreeBSD's /dev/fd can either be inside devfs, or be of type fdescfs. * [#123](https://github.com/icinga/icinga2/issues/123) (ITL, PR): ITL: Update ipmi CheckCommand attributes * [#120](https://github.com/icinga/icinga2/issues/120) (ITL, PR): Add new parameter for check\_http: -L: Wrap output in HTML link * [#117](https://github.com/icinga/icinga2/issues/117) (ITL, PR): Support --only-critical for check\_apt * [#115](https://github.com/icinga/icinga2/issues/115) (ITL, PR): Inverse Interface Switch for snmp-interface * [#114](https://github.com/icinga/icinga2/issues/114) (ITL, PR): Adding -A to snmp interfaces check ### Documentation * [#5448](https://github.com/icinga/icinga2/issues/5448) (Documentation, PR): Update documentation for 2.7.0 * [#5440](https://github.com/icinga/icinga2/issues/5440) (Documentation, PR): Add missing notification state filter to documentation * [#5425](https://github.com/icinga/icinga2/issues/5425) (Documentation, PR): Fix formatting in API docs * [#5410](https://github.com/icinga/icinga2/issues/5410) (Documentation): Update docs for better compatibility with mkdocs * [#5393](https://github.com/icinga/icinga2/issues/5393) (Documentation, PR): Fix typo in the documentation * [#5378](https://github.com/icinga/icinga2/issues/5378) (Documentation, PR): Fixed warnings when using mkdocs * [#5370](https://github.com/icinga/icinga2/issues/5370) (Documentation, PR): Rename ChangeLog to CHANGELOG.md * [#5366](https://github.com/icinga/icinga2/issues/5366) (Documentation, PR): Fixed wrong node in documentation chapter Client/Satellite Linux Setup * [#5365](https://github.com/icinga/icinga2/issues/5365) (Documentation, PR): Update package documentation for Debian Stretch * [#5358](https://github.com/icinga/icinga2/issues/5358) (Documentation, PR): Add documentation for securing mysql on Debian/Ubuntu. * [#5357](https://github.com/icinga/icinga2/issues/5357) (Documentation, Notifications, PR): Notification Scripts: Ensure that mail from address works on Debian/RHEL/SUSE \(mailutils vs mailx\) * [#5354](https://github.com/icinga/icinga2/issues/5354) (Documentation, PR): Docs: Fix built-in template description and URLs * [#5349](https://github.com/icinga/icinga2/issues/5349) (Documentation, PR): Docs: Fix broken format for notes/tips in CLI command chapter * [#5339](https://github.com/icinga/icinga2/issues/5339) (Documentation, ITL, PR): Add accept\_cname to dns CheckCommand * [#5336](https://github.com/icinga/icinga2/issues/5336) (Documentation, PR): Docs: Fix formatting issues and broken URLs * [#5333](https://github.com/icinga/icinga2/issues/5333) (Documentation, PR): Update documentation for enhanced notification scripts * [#5324](https://github.com/icinga/icinga2/issues/5324) (Documentation, PR): Fix phrasing in Getting Started chapter * [#5317](https://github.com/icinga/icinga2/issues/5317) (Documentation, PR): Fix typo in INSTALL.md * [#5315](https://github.com/icinga/icinga2/issues/5315) (Documentation, PR): Docs: Replace nagios-plugins by monitoring-plugins for Debian/Ubuntu * [#5314](https://github.com/icinga/icinga2/issues/5314) (Documentation, PR): Document Common name \(CN\) in client setup * [#5309](https://github.com/icinga/icinga2/issues/5309) (Documentation, PR): Docs: Replace the command pipe w/ the REST API as Icinga Web 2 requirement in 'Getting Started' chapter * [#5291](https://github.com/icinga/icinga2/issues/5291) (Documentation): Update docs for RHEL/CentOS 5 EOL * [#5285](https://github.com/icinga/icinga2/issues/5285) (Documentation, PR): Fix sysstat installation in troubleshooting docs * [#5279](https://github.com/icinga/icinga2/issues/5279) (Documentation, PR): Docs: Add API query example for acknowledgements w/o expire time * [#5275](https://github.com/icinga/icinga2/issues/5275) (Documentation, PR): Add troubleshooting hints for cgroup fork errors * [#5244](https://github.com/icinga/icinga2/issues/5244) (Documentation, PR): Add a PR review section to CONTRIBUTING.md * [#5237](https://github.com/icinga/icinga2/issues/5237) (Documentation, PR): Docs: Add a note for Windows debuglog to the troubleshooting chapter * [#5227](https://github.com/icinga/icinga2/issues/5227) (Documentation, ITL, PR): feature/itl-vmware-esx-storage-path-standbyok * [#5216](https://github.com/icinga/icinga2/issues/5216) (Documentation, PR): Remove "... is is ..." in CONTRIBUTING.md * [#5206](https://github.com/icinga/icinga2/issues/5206) (Documentation): Typo in Getting Started Guide * [#5203](https://github.com/icinga/icinga2/issues/5203) (Documentation, PR): Fix typo in Getting Started chapter * [#5184](https://github.com/icinga/icinga2/issues/5184) (Documentation, PR): Doc/appendix: fix malformed markdown links * [#5181](https://github.com/icinga/icinga2/issues/5181) (Documentation, PR): List SELinux packages required for building RPMs * [#5178](https://github.com/icinga/icinga2/issues/5178) (Documentation, Windows): Documentation vague on "update-windows" check plugin * [#5175](https://github.com/icinga/icinga2/issues/5175) (Documentation): Add a note about flapping problems to the docs * [#5174](https://github.com/icinga/icinga2/issues/5174) (Documentation, PR): Add missing object type to Apply Rules doc example * [#5173](https://github.com/icinga/icinga2/issues/5173) (Documentation): Object type missing from ping Service example in docs * [#5167](https://github.com/icinga/icinga2/issues/5167) (Documentation): Add more assign where expression examples * [#5166](https://github.com/icinga/icinga2/issues/5166) (API, Documentation): Set zone attribute to no\_user\_modify for API POST requests * [#5165](https://github.com/icinga/icinga2/issues/5165) (Documentation, PR): Syntax error In Dependencies chapter * [#5164](https://github.com/icinga/icinga2/issues/5164) (Documentation, ITL, PR): ITL: Add CheckCommand ssl\_cert, fix ssl attributes * [#5161](https://github.com/icinga/icinga2/issues/5161) (Documentation, PR): ITL documentation - disk-windows usage note with % thresholds * [#5157](https://github.com/icinga/icinga2/issues/5157) (Documentation): "Three Levels with master, Satellites, and Clients" chapter is not clear about client config * [#5156](https://github.com/icinga/icinga2/issues/5156) (Documentation): Add CONTRIBUTING.md * [#5155](https://github.com/icinga/icinga2/issues/5155) (Documentation): 3.5. Apply Rules topic in the docs needs work. * [#5151](https://github.com/icinga/icinga2/issues/5151) (Documentation, PR): Replace http:// links with https:// links where a secure website exists * [#5150](https://github.com/icinga/icinga2/issues/5150) (Documentation): Invalid links in documentation * [#5149](https://github.com/icinga/icinga2/issues/5149) (Documentation, PR): Update documentation, change http:// links to https:// links where a website exists * [#5144](https://github.com/icinga/icinga2/issues/5144) (Documentation): Extend troubleshooting docs w/ environment analysis and common tools * [#5143](https://github.com/icinga/icinga2/issues/5143) (Documentation): Docs: Explain how to include your own config tree instead of conf.d * [#5142](https://github.com/icinga/icinga2/issues/5142) (Documentation): Add an Elastic Stack Integrations chapter to feature documentation * [#5140](https://github.com/icinga/icinga2/issues/5140) (Documentation): Documentation should explain that runtime modifications are not immediately updated for "object list" * [#5137](https://github.com/icinga/icinga2/issues/5137) (Documentation): Doc updates: Getting Started w/ own config, Troubleshooting w/ debug console * [#5111](https://github.com/icinga/icinga2/issues/5111) (Documentation): Fix duration attribute requirement for schedule-downtime API action * [#5104](https://github.com/icinga/icinga2/issues/5104) (Documentation, PR): Correct link to nscp documentation * [#5097](https://github.com/icinga/icinga2/issues/5097) (Documentation): The last example for typeof\(\) is missing the result * [#5090](https://github.com/icinga/icinga2/issues/5090) (Cluster, Documentation): EventHandler to be executed at the endpoint * [#5077](https://github.com/icinga/icinga2/issues/5077) (Documentation): Replace the 'command' feature w/ the REST API for Icinga Web 2 * [#5016](https://github.com/icinga/icinga2/issues/5016) (Documentation, ITL, PR): Add fuse.gvfs-fuse-daemon to disk\_exclude\_type * [#5010](https://github.com/icinga/icinga2/issues/5010) (Documentation): \[Documentation\] Missing parameter for SNMPv3 auth * [#3560](https://github.com/icinga/icinga2/issues/3560) (Documentation): Explain check\_memorys and check\_disks thresholds * [#1880](https://github.com/icinga/icinga2/issues/1880) (Documentation): add a section for 'monitoring the icinga2 node' ### Support * [#5359](https://github.com/icinga/icinga2/issues/5359) (CLI, PR): Fixed missing closing bracket in CLI command pki new-cert. * [#5332](https://github.com/icinga/icinga2/issues/5332) (Configuration, Notifications, PR): Notification Scripts: notification\_type is always required * [#5326](https://github.com/icinga/icinga2/issues/5326) (Documentation, Installation, PR): Install the images directory containing the needed PNGs for the markd * [#5310](https://github.com/icinga/icinga2/issues/5310) (Packages, PR): RPM: Disable SELinux policy hardlink * [#5306](https://github.com/icinga/icinga2/issues/5306) (Documentation, Packages, PR): Remove CentOS 5 from 'Getting started' docs * [#5304](https://github.com/icinga/icinga2/issues/5304) (Documentation, Packages, PR): Update INSTALL.md for RPM builds * [#5303](https://github.com/icinga/icinga2/issues/5303) (Packages, PR): RPM: Fix builds on Amazon Linux * [#5299](https://github.com/icinga/icinga2/issues/5299) (Notifications): Ensure that "mail from" works on RHEL/CentOS * [#5286](https://github.com/icinga/icinga2/issues/5286) (Configuration, PR): Fix verbose mode in notifications scripts * [#5265](https://github.com/icinga/icinga2/issues/5265) (PR): Move PerfdataValue\(\) class into base library * [#5252](https://github.com/icinga/icinga2/issues/5252) (Tests, PR): travis: Update to trusty as CI environment * [#5251](https://github.com/icinga/icinga2/issues/5251) (Tests): Update Travis CI environment to trusty * [#5248](https://github.com/icinga/icinga2/issues/5248) (Tests, PR): Travis: Run config validation at the end * [#5238](https://github.com/icinga/icinga2/issues/5238) (DB IDO, PR): Remove deprecated "DbCat1 | DbCat2" notation for DB IDO categories * [#5229](https://github.com/icinga/icinga2/issues/5229) (Installation, PR): CMake: require a GCC version according to INSTALL.md * [#5226](https://github.com/icinga/icinga2/issues/5226) (Packages, PR): RPM spec: don't enable features after an upgrade * [#5225](https://github.com/icinga/icinga2/issues/5225) (DB IDO, PR): Don't call mysql\_error\(\) after a failure of mysql\_init\(\) * [#5218](https://github.com/icinga/icinga2/issues/5218) (Packages): icinga2.spec: Allow selecting g++ compiler on older SUSE release builds * [#5189](https://github.com/icinga/icinga2/issues/5189) (Documentation, Packages, PR): RPM packaging updates * [#5188](https://github.com/icinga/icinga2/issues/5188) (Documentation, Packages): Boost \>= 1.48 required * [#5177](https://github.com/icinga/icinga2/issues/5177) (Packages): Issues Packing icinga 2.6.3 tar.gz to RPM * [#5153](https://github.com/icinga/icinga2/issues/5153) (Packages, PR): Changed dependency of selinux subpackage * [#5127](https://github.com/icinga/icinga2/issues/5127) (Installation, PR): Improve systemd service file * [#5102](https://github.com/icinga/icinga2/issues/5102) (Compat, Configuration, Packages): Deprecate the icinga2-classicui-config package * [#5101](https://github.com/icinga/icinga2/issues/5101) (Packages, Windows): Fix incorrect metadata for the Chocolatey package * [#5100](https://github.com/icinga/icinga2/issues/5100) (Packages, Windows): Update Chocolatey package to match current guidelines * [#5094](https://github.com/icinga/icinga2/issues/5094) (Cluster, Configuration): Log message "Object cannot be deleted because it was not created using the API" * [#5087](https://github.com/icinga/icinga2/issues/5087) (Configuration): Function metadata should show available arguments * [#5042](https://github.com/icinga/icinga2/issues/5042) (DB IDO, PR): Add link to upgrade documentation to log message * [#4977](https://github.com/icinga/icinga2/issues/4977) (Cluster, Installation): icinga2/api/log directory is not created * [#4921](https://github.com/icinga/icinga2/issues/4921) (Installation, Packages): No network dependency for /etc/init.d/icinga2 * [#4781](https://github.com/icinga/icinga2/issues/4781) (Packages): Improve SELinux Policy * [#4776](https://github.com/icinga/icinga2/issues/4776) (Installation): NetBSD install path fixes * [#4621](https://github.com/icinga/icinga2/issues/4621) (Configuration, Notifications, Packages): notifications always enabled after update ## 2.6.3 (2017-03-29) ### Bug * [#5080](https://github.com/icinga/icinga2/issues/5080) (DB IDO): Missing index use can cause icinga\_downtimehistory queries to hang indefinitely * [#4989](https://github.com/icinga/icinga2/issues/4989) (Check Execution): Icinga daemon runs with nice 5 after reload * [#4930](https://github.com/icinga/icinga2/issues/4930) (Cluster): Change "Discarding 'config update object'" log messages to notice log level * [#4603](https://github.com/icinga/icinga2/issues/4603) (DB IDO): With too many comments, Icinga reload process won't finish reconnecting to Database ### Documentation * [#5057](https://github.com/icinga/icinga2/issues/5057) (Documentation): Update Security section in the Distributed Monitoring chapter * [#5055](https://github.com/icinga/icinga2/issues/5055) (Documentation, ITL): mysql\_socket attribute missing in the documentation for the mysql CheckCommand * [#5035](https://github.com/icinga/icinga2/issues/5035) (Documentation): Docs: Typo in Distributed Monitoring chapter * [#5030](https://github.com/icinga/icinga2/issues/5030) (Documentation): Advanced topics: Mention the API and explain stick acks, fixed/flexible downtimes * [#5029](https://github.com/icinga/icinga2/issues/5029) (Documentation): Advanced topics: Wrong acknowledgement notification filter * [#4996](https://github.com/icinga/icinga2/issues/4996) (Documentation): documentation: mixed up host names in 6-distributed-monitoring.md * [#4980](https://github.com/icinga/icinga2/issues/4980) (Documentation): Add OpenBSD and AlpineLinux package repositories to the documentation * [#4955](https://github.com/icinga/icinga2/issues/4955) (Documentation, ITL): Review CheckCommand documentation including external URLs * [#4954](https://github.com/icinga/icinga2/issues/4954) (Documentation): Add an example for /v1/actions/process-check-result which uses filter/type * [#3133](https://github.com/icinga/icinga2/issues/3133) (Documentation): Add practical examples for apply expressions ## 2.6.2 (2017-02-13) ### Bug * [#4952](https://github.com/icinga/icinga2/issues/4952) (API, CLI): Icinga crashes while trying to remove configuration files for objects which no longer exist ## 2.6.1 (2017-01-31) ### Notes This release addresses a number of bugs we have identified in version 2.6.0. The documentation changes reflect our recent move to GitHub. ### Enhancement * [#4923](https://github.com/icinga/icinga2/issues/4923): Migration to Github * [#4813](https://github.com/icinga/icinga2/issues/4813): Include argument name for log message about incorrect set\_if values ### Bug * [#4950](https://github.com/icinga/icinga2/issues/4950): IDO schema update is not compatible to MySQL 5.7 * [#4882](https://github.com/icinga/icinga2/issues/4882): Crash - Error: parse error: premature EOF * [#4877](https://github.com/icinga/icinga2/issues/4877) (DB IDO): IDO MySQL schema not working on MySQL 5.7 * [#4874](https://github.com/icinga/icinga2/issues/4874) (DB IDO): IDO: Timestamps in PostgreSQL may still have a time zone offset * [#4867](https://github.com/icinga/icinga2/issues/4867): SIGPIPE shutdown on config reload ### Documentation * [#4944](https://github.com/icinga/icinga2/issues/4944) (Documentation, PR): doc/6-distributed-monitoring.md: Fix typo * [#4934](https://github.com/icinga/icinga2/issues/4934) (Documentation): Update contribution section for GitHub * [#4917](https://github.com/icinga/icinga2/issues/4917) (Documentation): Incorrect license file mentioned in README.md * [#4916](https://github.com/icinga/icinga2/issues/4916) (Documentation): Add travis-ci build status logo to README.md * [#4908](https://github.com/icinga/icinga2/issues/4908) (Documentation): Move domain to icinga.com * [#4885](https://github.com/icinga/icinga2/issues/4885) (Documentation): SLES 12 SP2 libboost\_thread package requires libboost\_chrono * [#4869](https://github.com/icinga/icinga2/issues/4869) (Documentation): Update RELEASE.md * [#4868](https://github.com/icinga/icinga2/issues/4868) (Documentation): Add more build details to INSTALL.md * [#4803](https://github.com/icinga/icinga2/issues/4803) (Documentation): Update Repositories in Docs ### Support * [#4870](https://github.com/icinga/icinga2/issues/4870) (Packages): SLES11 SP4 dependency on Postgresql \>= 8.4 ## 2.6.0 (2016-12-13) ### Notes * Client/Satellite setup * The "bottom up" client configuration mode has been deprecated. Check [#13255](https://dev.icinga.com/issues/13255) for additional details and migration. * Linux/Unix daemon * Ensure that Icinga 2 does not leak file descriptors to executed commands. * There are 2 processes started instead of previously just one process. * Windows client * Package bundles NSClient++ 0.5.0. ITL CheckCommands have been updated too. * Allow to configure the user account for the Icinga 2 service. This is useful if several checks require administrator permissions (e.g. check_update.exe) * Bugfixes for check plugins * Cluster and API * Provide location information for objects and templates in the API * Improve log message for ignored config updates * Fix cluster resync problem with API created objects (hosts, downtimes, etc.) * Fix that API-created objects in a global zone are not synced to child endpoints * Notifications * Several bugfixes for downtime, custom and flapping notifications * New ITL CheckCommands: logstash, glusterfs, iostats * Package builds require a compiler which supports C++11 features (gcc-c++ >= 4.7, clang++) * DB IDO * Schema upgrade required (2.6.0.sql) * This update fixes timestamp columns required by Icinga Web 2 and might take a while. Please ensure to schedule a maintenance task for your database upgrade. ### Enhancement * [#4798](https://github.com/icinga/icinga2/issues/4798) (Cluster): Deprecate cluster/client mode "bottom up" w/ repository.d and node update-config * [#4770](https://github.com/icinga/icinga2/issues/4770) (API): Allow to evaluate macros through the API * [#4713](https://github.com/icinga/icinga2/issues/4713) (Cluster): Check whether nodes are synchronizing the API log before putting them into UNKNOWN * [#4651](https://github.com/icinga/icinga2/issues/4651) (Plugins): Review windows plugins performance output * [#4631](https://github.com/icinga/icinga2/issues/4631) (Configuration): Suppress compiler warnings for auto-generated code * [#4622](https://github.com/icinga/icinga2/issues/4622) (Cluster): Improve log message for ignored config updates * [#4590](https://github.com/icinga/icinga2/issues/4590): Make sure that libmethods is automatically loaded even when not using the ITL * [#4587](https://github.com/icinga/icinga2/issues/4587) (Configuration): Implement support for default templates * [#4580](https://github.com/icinga/icinga2/issues/4580) (API): Provide location information for objects and templates in the API * [#4576](https://github.com/icinga/icinga2/issues/4576): Use lambda functions for INITIALIZE\_ONCE * [#4575](https://github.com/icinga/icinga2/issues/4575): Use 'auto' for iterator declarations * [#4571](https://github.com/icinga/icinga2/issues/4571): Implement an rvalue constructor for the String and Value classes * [#4570](https://github.com/icinga/icinga2/issues/4570) (Configuration): Implement a command-line argument for "icinga2 console" to allow specifying a script file * [#4563](https://github.com/icinga/icinga2/issues/4563) (Configuration): Remove unused method: ApplyRule::DiscardRules * [#4559](https://github.com/icinga/icinga2/issues/4559): Replace BOOST\_FOREACH with range-based for loops * [#4557](https://github.com/icinga/icinga2/issues/4557): Add -fvisibility=hidden to the default compiler flags * [#4537](https://github.com/icinga/icinga2/issues/4537): Implement an environment variable to keep Icinga from closing FDs on startup * [#4536](https://github.com/icinga/icinga2/issues/4536): Avoid unnecessary string copies * [#4535](https://github.com/icinga/icinga2/issues/4535): Remove deprecated functions * [#3684](https://github.com/icinga/icinga2/issues/3684) (Configuration): Command line option for config syntax validation * [#2968](https://github.com/icinga/icinga2/issues/2968): Better message for apply errors ### Bug * [#4831](https://github.com/icinga/icinga2/issues/4831) (CLI): Wrong help string for node setup cli command argument --master\_host * [#4828](https://github.com/icinga/icinga2/issues/4828) (API): Crash in CreateObjectHandler \(regression from \#11684 * [#4802](https://github.com/icinga/icinga2/issues/4802): Icinga tries to delete Downtime objects that were statically configured * [#4801](https://github.com/icinga/icinga2/issues/4801): Sending a HUP signal to the child process for execution actually kills it * [#4791](https://github.com/icinga/icinga2/issues/4791) (DB IDO): PostgreSQL: Don't use timestamp with timezone for UNIX timestamp columns * [#4789](https://github.com/icinga/icinga2/issues/4789) (Notifications): Recovery notifications sent for Not-Problem notification type if notified before * [#4775](https://github.com/icinga/icinga2/issues/4775) (Cluster): Crash w/ SendNotifications cluster handler and check result with empty perfdata * [#4771](https://github.com/icinga/icinga2/issues/4771): Config validation crashes when using command\_endpoint without also having an ApiListener object * [#4752](https://github.com/icinga/icinga2/issues/4752) (Graphite): Performance data writer for Graphite : Values without fraction limited to 2147483647 \(7FFFFFFF\) * [#4740](https://github.com/icinga/icinga2/issues/4740): SIGALRM handling may be affected by recent commit * [#4726](https://github.com/icinga/icinga2/issues/4726) (Notifications): Flapping notifications sent for soft state changes * [#4717](https://github.com/icinga/icinga2/issues/4717) (API): Icinga crashes while deleting a config file which doesn't exist anymore * [#4678](https://github.com/icinga/icinga2/issues/4678) (Configuration): Configuration validation fails when setting tls\_protocolmin to TLSv1.2 * [#4674](https://github.com/icinga/icinga2/issues/4674) (CLI): Parse error: "premature EOF" when running "icinga2 node update-config" * [#4665](https://github.com/icinga/icinga2/issues/4665): Crash in ClusterEvents::SendNotificationsAPIHandler * [#4646](https://github.com/icinga/icinga2/issues/4646) (Notifications): Forced custom notification is setting "force\_next\_notification": true permanently * [#4644](https://github.com/icinga/icinga2/issues/4644) (API): Crash in HttpRequest::Parse while processing HTTP request * [#4630](https://github.com/icinga/icinga2/issues/4630) (Configuration): Validation does not highlight the correct attribute * [#4629](https://github.com/icinga/icinga2/issues/4629) (CLI): broken: icinga2 --version * [#4620](https://github.com/icinga/icinga2/issues/4620) (API): Invalid API filter error messages * [#4619](https://github.com/icinga/icinga2/issues/4619) (CLI): Cli: boost::bad\_get on icinga::String::String\(icinga::Value&&\) * [#4616](https://github.com/icinga/icinga2/issues/4616): Build fails with Visual Studio 2015 * [#4606](https://github.com/icinga/icinga2/issues/4606): Remove unused last\_in\_downtime field * [#4602](https://github.com/icinga/icinga2/issues/4602) (CLI): Last option highlighted as the wrong one, even when it is not the culprit * [#4599](https://github.com/icinga/icinga2/issues/4599): Unexpected state changes with max\_check\_attempts = 2 * [#4583](https://github.com/icinga/icinga2/issues/4583) (Configuration): Debug hints for dictionary expressions are nested incorrectly * [#4574](https://github.com/icinga/icinga2/issues/4574) (Notifications): Don't send Flapping\* notifications when downtime is active * [#4573](https://github.com/icinga/icinga2/issues/4573) (DB IDO): Getting error during schema update * [#4572](https://github.com/icinga/icinga2/issues/4572) (Configuration): Config validation shouldnt allow 'endpoints = \[ "" \]' * [#4566](https://github.com/icinga/icinga2/issues/4566) (Notifications): Fixed downtimes scheduled for a future date trigger DOWNTIMESTART notifications * [#4564](https://github.com/icinga/icinga2/issues/4564): Add missing initializer for WorkQueue::m\_NextTaskID * [#4555](https://github.com/icinga/icinga2/issues/4555): Fix compiler warnings * [#4541](https://github.com/icinga/icinga2/issues/4541) (DB IDO): Don't link against libmysqlclient\_r * [#4538](https://github.com/icinga/icinga2/issues/4538): Don't update TimePeriod ranges for inactive objects * [#4423](https://github.com/icinga/icinga2/issues/4423) (Metrics): InfluxdbWriter does not write state other than 0 * [#4369](https://github.com/icinga/icinga2/issues/4369) (Plugins): check\_network performance data in invalid format - ingraph * [#4169](https://github.com/icinga/icinga2/issues/4169) (Cluster): Cluster resync problem with API created objects * [#4098](https://github.com/icinga/icinga2/issues/4098) (API): Objects created in a global zone are not synced to child endpoints * [#4010](https://github.com/icinga/icinga2/issues/4010) (API): API requests from execute-script action are too verbose * [#3802](https://github.com/icinga/icinga2/issues/3802) (Compat): SCHEDULE\_AND\_PROPAGATE\_HOST\_DOWNTIME command missing * [#3801](https://github.com/icinga/icinga2/issues/3801) (Compat): SCHEDULE\_AND\_PROPAGATE\_TRIGGERED\_HOST\_DOWNTIME command missing * [#3575](https://github.com/icinga/icinga2/issues/3575) (DB IDO): MySQL 5.7.9, Incorrect datetime value Error * [#3565](https://github.com/icinga/icinga2/issues/3565) (Plugins): Windows Agent: performance data of check\_perfmon * [#3564](https://github.com/icinga/icinga2/issues/3564) (Plugins): Windows Agent: Performance data values for check\_perfmon.exe are invalid sometimes * [#3220](https://github.com/icinga/icinga2/issues/3220) (Plugins): Implement support for resolving DNS hostnames in check\_ping.exe * [#2847](https://github.com/icinga/icinga2/issues/2847): File descriptors are leaked to child processes which makes SELinux unhappy ### ITL * [#4842](https://github.com/icinga/icinga2/issues/4842) (ITL): Add tempdir attribute to postgres CheckCommand * [#4837](https://github.com/icinga/icinga2/issues/4837) (ITL): Add sudo option to mailq CheckCommand * [#4836](https://github.com/icinga/icinga2/issues/4836) (ITL): Add verbose parameter to http CheckCommand * [#4835](https://github.com/icinga/icinga2/issues/4835) (ITL): Add timeout option to mysql\_health CheckCommand * [#4714](https://github.com/icinga/icinga2/issues/4714) (ITL): Default values for check\_swap are incorrect * [#4710](https://github.com/icinga/icinga2/issues/4710) (ITL): snmp\_miblist variable to feed the -m option of check\_snmp is missing in the snmpv3 CheckCommand object * [#4684](https://github.com/icinga/icinga2/issues/4684) (ITL): Add a radius CheckCommand for the radius check provide by nagios-plugins * [#4681](https://github.com/icinga/icinga2/issues/4681) (ITL): Add CheckCommand definition for check\_logstash * [#4677](https://github.com/icinga/icinga2/issues/4677) (ITL): Problem passing arguments to nscp-local CheckCommand objects * [#4672](https://github.com/icinga/icinga2/issues/4672) (ITL): Add timeout option to oracle\_health CheckCommand * [#4618](https://github.com/icinga/icinga2/issues/4618) (ITL): Hangman easter egg is broken * [#4608](https://github.com/icinga/icinga2/issues/4608) (ITL): Add CheckCommand definition for check\_iostats * [#4597](https://github.com/icinga/icinga2/issues/4597) (ITL): Default disk plugin check should not check inodes * [#4595](https://github.com/icinga/icinga2/issues/4595) (ITL): Manubulon: Add missing procurve memory flag * [#4585](https://github.com/icinga/icinga2/issues/4585) (ITL): Fix code style violations in the ITL * [#4582](https://github.com/icinga/icinga2/issues/4582) (ITL): Incorrect help text for check\_swap * [#4543](https://github.com/icinga/icinga2/issues/4543) (ITL): ITL - check\_vmware\_esx - specify a datacenter/vsphere server for esx/host checks * [#4324](https://github.com/icinga/icinga2/issues/4324) (ITL): Add CheckCommand definition for check\_glusterfs ### Documentation * [#4862](https://github.com/icinga/icinga2/issues/4862) (Documentation): "2.1.4. Installation Paths" should contain systemd paths * [#4861](https://github.com/icinga/icinga2/issues/4861) (Documentation): Update "2.1.3. Enabled Features during Installation" - outdated "feature list" * [#4859](https://github.com/icinga/icinga2/issues/4859) (Documentation): Update package instructions for Fedora * [#4851](https://github.com/icinga/icinga2/issues/4851) (Documentation): Update README.md and correct project URLs * [#4846](https://github.com/icinga/icinga2/issues/4846) (Documentation): Add a note for boolean values in the disk CheckCommand section * [#4845](https://github.com/icinga/icinga2/issues/4845) (Documentation): Troubleshooting: Add examples for fetching the executed command line * [#4840](https://github.com/icinga/icinga2/issues/4840) (Documentation): Update Windows screenshots in the client documentation * [#4838](https://github.com/icinga/icinga2/issues/4838) (Documentation): Add example for concurrent\_checks in CheckerComponent object type * [#4829](https://github.com/icinga/icinga2/issues/4829) (Documentation): Missing API headers for X-HTTP-Method-Override * [#4827](https://github.com/icinga/icinga2/issues/4827) (Documentation): Fix example in PNP template docs * [#4821](https://github.com/icinga/icinga2/issues/4821) (Documentation): Add a note about removing "conf.d" on the client for "top down command endpoint" setups * [#4809](https://github.com/icinga/icinga2/issues/4809) (Documentation): Update API and Library Reference chapters * [#4804](https://github.com/icinga/icinga2/issues/4804) (Documentation): Add a note about default template import to the CheckCommand object * [#4800](https://github.com/icinga/icinga2/issues/4800) (Documentation): Docs: Typo in "CLI commands" chapter * [#4793](https://github.com/icinga/icinga2/issues/4793) (Documentation): Docs: ITL plugins contrib order * [#4787](https://github.com/icinga/icinga2/issues/4787) (Documentation): Doc: Swap packages.icinga.org w/ DebMon * [#4780](https://github.com/icinga/icinga2/issues/4780) (Documentation): Add a note about pinning checks w/ command\_endpoint * [#4736](https://github.com/icinga/icinga2/issues/4736) (Documentation): Docs: wrong heading level for commands.conf and groups.conf * [#4708](https://github.com/icinga/icinga2/issues/4708) (Documentation): Add more Timeperiod examples in the documentation * [#4706](https://github.com/icinga/icinga2/issues/4706) (Documentation): Add an example of multi-parents configuration for the Migration chapter * [#4705](https://github.com/icinga/icinga2/issues/4705) (Documentation): Typo in the documentation * [#4699](https://github.com/icinga/icinga2/issues/4699) (Documentation): Fix some spelling mistakes * [#4667](https://github.com/icinga/icinga2/issues/4667) (Documentation): Add documentation for logrotation for the mainlog feature * [#4653](https://github.com/icinga/icinga2/issues/4653) (Documentation): Corrections for distributed monitoring chapter * [#4641](https://github.com/icinga/icinga2/issues/4641) (Documentation): Docs: Migrating Notification example tells about filters instead of types * [#4639](https://github.com/icinga/icinga2/issues/4639) (Documentation): GDB example in the documentation isn't working * [#4636](https://github.com/icinga/icinga2/issues/4636) (Documentation): Add development docs for writing a core dump file * [#4601](https://github.com/icinga/icinga2/issues/4601) (Documentation): Typo in distributed monitoring docs * [#4596](https://github.com/icinga/icinga2/issues/4596) (Documentation): Update service monitoring and distributed docs * [#4589](https://github.com/icinga/icinga2/issues/4589) (Documentation): Fix help output for update-links.py * [#4584](https://github.com/icinga/icinga2/issues/4584) (Documentation): Add missing reference to libmethods for the default ITL command templates * [#4492](https://github.com/icinga/icinga2/issues/4492) (Documentation): Add information about function 'range' ### Support * [#4796](https://github.com/icinga/icinga2/issues/4796) (Installation): Sort Changelog by category * [#4792](https://github.com/icinga/icinga2/issues/4792) (Tests): Add unit test for notification state/type filter checks * [#4724](https://github.com/icinga/icinga2/issues/4724) (Packages): Update .mailmap for icinga.com * [#4671](https://github.com/icinga/icinga2/issues/4671) (Packages): Windows Installer should include NSClient++ 0.5.0 * [#4612](https://github.com/icinga/icinga2/issues/4612) (Tests): Unit tests randomly crash after the tests have completed * [#4607](https://github.com/icinga/icinga2/issues/4607) (Packages): Improve support for building the chocolatey package * [#4588](https://github.com/icinga/icinga2/issues/4588) (Installation): Use raw string literals in mkembedconfig * [#4578](https://github.com/icinga/icinga2/issues/4578) (Installation): Improve detection for the -flto compiler flag * [#4569](https://github.com/icinga/icinga2/issues/4569) (Installation): Set versions for all internal libraries * [#4558](https://github.com/icinga/icinga2/issues/4558) (Installation): Update cmake config to require a compiler that supports C++11 * [#4556](https://github.com/icinga/icinga2/issues/4556) (Installation): logrotate file is not properly generated when the logrotate binary resides in /usr/bin * [#4551](https://github.com/icinga/icinga2/issues/4551) (Tests): Implement unit tests for state changes * [#2943](https://github.com/icinga/icinga2/issues/2943) (Installation): Make the user account configurable for the Windows service * [#2792](https://github.com/icinga/icinga2/issues/2792) (Tests): Livestatus tests don't work on OS X ## 2.5.4 (2016-08-30) ### Notes * Bugfixes ### Bug * [#4277](https://github.com/icinga/icinga2/issues/4277): many check commands executed at same time when master reload ## 2.5.3 (2016-08-25) ### Notes This release addresses an issue with PostgreSQL support for the IDO database module. ### Bug * [#4554](https://github.com/icinga/icinga2/issues/4554) (DB IDO): ido pgsql migration from 2.4.0 to 2.5.0 : wrong size for config\_hash ## 2.5.2 (2016-08-24) ### Notes * Bugfixes ### Bug * [#4550](https://github.com/icinga/icinga2/issues/4550): Icinga 2 sends SOFT recovery notifications * [#4549](https://github.com/icinga/icinga2/issues/4549) (DB IDO): Newly added group member tables in the IDO database are not updated ### Documentation * [#4548](https://github.com/icinga/icinga2/issues/4548) (Documentation): Wrong formatting in client docs ## 2.5.1 (2016-08-23) ### Notes * Bugfixes ### Bug * [#4544](https://github.com/icinga/icinga2/issues/4544) (Notifications): Icinga 2 sends recovery notifications for SOFT NOT-OK states ## 2.5.0 (2016-08-23) ### Notes * InfluxdbWriter feature * API * New endpoints: /v1/variables and /v1/templates (GET requests), /v1/action/generate-ticket (POST request) * State/type filters for notifications/users are now string values (PUT, POST, GET requests) * Configuration * TimePeriod excludes/includes attributes * DateTime object for formatting time strings * New prototype methods: Array#filter, Array#unique, Array#map, Array#reduce * icinga2.conf now includes plugins-contrib, manubulon, windows-plugins, nscp by default (ITL CheckCommand definitions) * Performance improvements (config compiler and validation) * CLI * 'icinga2 object list' formats state/type filters as string values * Compiled config files are now visible with "notice" debug level (hidden by default) * CA serial file now uses a hash value (HA cluster w/ 2 CA directories) * Cluster * There is a known issue with >2 endpoints inside a zone. Icinga 2 will now log a warning. * Support for accepted ciphers and minimum TLS version * Connection and error logging has been improved. * DB IDO * Schema upgrade required (2.5.0.sql) * Incremental config dump (performance boost) * `categories` attribute is now an array. Previous method is deprecated and to be removed. * DbCatLog is not enabled by default anymore. * SSL support for MySQL * New packages * vim-icinga2 for syntax highlighting * libicinga2 (Debian), icinga2-libs (RPM) for Icinga Studio packages ### Enhancement * [#4516](https://github.com/icinga/icinga2/issues/4516): Remove some unused \#includes * [#4498](https://github.com/icinga/icinga2/issues/4498): Remove unnecessary Dictionary::Contains calls * [#4493](https://github.com/icinga/icinga2/issues/4493) (Cluster): Improve performance for Endpoint config validation * [#4491](https://github.com/icinga/icinga2/issues/4491): Improve performance for type lookups * [#4487](https://github.com/icinga/icinga2/issues/4487) (DB IDO): Incremental updates for the IDO database * [#4486](https://github.com/icinga/icinga2/issues/4486) (DB IDO): Remove unused code from the IDO classes * [#4485](https://github.com/icinga/icinga2/issues/4485) (API): Add API action for generating a PKI ticket * [#4479](https://github.com/icinga/icinga2/issues/4479) (Configuration): Implement comparison operators for the Array class * [#4467](https://github.com/icinga/icinga2/issues/4467): Implement the System\#sleep function * [#4465](https://github.com/icinga/icinga2/issues/4465) (Configuration): Implement support for namespaces * [#4464](https://github.com/icinga/icinga2/issues/4464) (CLI): Implement support for inspecting variables with LLDB/GDB * [#4457](https://github.com/icinga/icinga2/issues/4457): Implement support for marking functions as deprecated * [#4454](https://github.com/icinga/icinga2/issues/4454): Include compiler name/version and build host name in --version * [#4451](https://github.com/icinga/icinga2/issues/4451) (Configuration): Move internal script functions into the 'Internal' namespace * [#4449](https://github.com/icinga/icinga2/issues/4449): Improve logging for the WorkQueue class * [#4445](https://github.com/icinga/icinga2/issues/4445): Rename/Remove experimental script functions * [#4443](https://github.com/icinga/icinga2/issues/4443): Implement process\_check\_result script method for the Checkable class * [#4442](https://github.com/icinga/icinga2/issues/4442) (API): Support for determining the Icinga 2 version via the API * [#4431](https://github.com/icinga/icinga2/issues/4431) (Notifications): Add the notification type into the log message * [#4424](https://github.com/icinga/icinga2/issues/4424) (Cluster): Enhance TLS handshake error messages with connection information * [#4415](https://github.com/icinga/icinga2/issues/4415) (API): Remove obsolete debug log message * [#4410](https://github.com/icinga/icinga2/issues/4410) (Configuration): Add map/reduce and filter functionality for the Array class * [#4403](https://github.com/icinga/icinga2/issues/4403) (CLI): Add history for icinga2 console * [#4398](https://github.com/icinga/icinga2/issues/4398) (Cluster): Log a warning if there are more than 2 zone endpoint members * [#4393](https://github.com/icinga/icinga2/issues/4393) (Cluster): Include IP address and port in the "New connection" log message * [#4388](https://github.com/icinga/icinga2/issues/4388) (Configuration): Implement the \_\_ptr script function * [#4386](https://github.com/icinga/icinga2/issues/4386) (Cluster): Improve error messages for failed certificate validation * [#4381](https://github.com/icinga/icinga2/issues/4381) (Cluster): Improve log message for connecting nodes without configured Endpoint object * [#4352](https://github.com/icinga/icinga2/issues/4352) (Cluster): Enhance client disconnect message for "No data received on new API connection." * [#4348](https://github.com/icinga/icinga2/issues/4348) (DB IDO): Do not populate logentries table by default * [#4325](https://github.com/icinga/icinga2/issues/4325) (API): API: Add missing downtime\_depth attribute * [#4314](https://github.com/icinga/icinga2/issues/4314) (DB IDO): Change Ido\*Connection 'categories' attribute to an array * [#4295](https://github.com/icinga/icinga2/issues/4295) (DB IDO): Enhance IDO check with schema version info * [#4294](https://github.com/icinga/icinga2/issues/4294) (DB IDO): Update DB IDO schema version to 1.14.1 * [#4290](https://github.com/icinga/icinga2/issues/4290) (API): Implement support for getting a list of global variables from the API * [#4281](https://github.com/icinga/icinga2/issues/4281) (API): Support for enumerating available templates via the API * [#4268](https://github.com/icinga/icinga2/issues/4268) (Metrics): InfluxDB Metadata * [#4206](https://github.com/icinga/icinga2/issues/4206) (Cluster): Add lag threshold for cluster-zone check * [#4178](https://github.com/icinga/icinga2/issues/4178) (API): Improve logging for HTTP API requests * [#4154](https://github.com/icinga/icinga2/issues/4154) (Configuration): Remove the \(unused\) 'inherits' keyword * [#4129](https://github.com/icinga/icinga2/issues/4129) (Configuration): Improve performance for field accesses * [#4061](https://github.com/icinga/icinga2/issues/4061) (Configuration): Allow strings in state/type filters * [#4048](https://github.com/icinga/icinga2/issues/4048): Cleanup downtimes created by ScheduleDowntime * [#4046](https://github.com/icinga/icinga2/issues/4046) (Configuration): Config parser should not log names of included files by default * [#3999](https://github.com/icinga/icinga2/issues/3999) (API): ApiListener: Make minimum TLS version configurable * [#3997](https://github.com/icinga/icinga2/issues/3997) (API): ApiListener: Force server's preferred cipher * [#3911](https://github.com/icinga/icinga2/issues/3911) (Graphite): Add acknowledgement type to Graphite, InfluxDB, OpenTSDB metadata * [#3888](https://github.com/icinga/icinga2/issues/3888) (API): Implement SSL cipher configuration support for the API feature * [#3763](https://github.com/icinga/icinga2/issues/3763): Add name attribute for WorkQueue class * [#3562](https://github.com/icinga/icinga2/issues/3562) (Metrics): Add InfluxDbWriter feature * [#3400](https://github.com/icinga/icinga2/issues/3400): Remove the deprecated IcingaStatusWriter feature * [#3237](https://github.com/icinga/icinga2/issues/3237) (Metrics): Gelf module: expose 'perfdata' fields for 'CHECK\_RESULT' events * [#3224](https://github.com/icinga/icinga2/issues/3224) (Configuration): Implement support for formatting date/time * [#3178](https://github.com/icinga/icinga2/issues/3178) (DB IDO): Add SSL support for the IdoMysqlConnection feature * [#2970](https://github.com/icinga/icinga2/issues/2970) (Metrics): Add timestamp support for GelfWriter * [#2040](https://github.com/icinga/icinga2/issues/2040): Exclude option for TimePeriod definitions ### Bug * [#4534](https://github.com/icinga/icinga2/issues/4534) (CLI): Icinga2 segault on startup * [#4524](https://github.com/icinga/icinga2/issues/4524) (API): API Remote crash via Google Chrome * [#4520](https://github.com/icinga/icinga2/issues/4520) (Configuration): Memory leak when using closures * [#4512](https://github.com/icinga/icinga2/issues/4512) (Cluster): Incorrect certificate validation error message * [#4511](https://github.com/icinga/icinga2/issues/4511): ClrCheck is null on \*nix * [#4505](https://github.com/icinga/icinga2/issues/4505) (CLI): Cannot set ownership for user 'icinga' group 'icinga' on file '/var/lib/icinga2/ca/serial.txt'. * [#4504](https://github.com/icinga/icinga2/issues/4504) (API): API: events for DowntimeTriggered does not provide needed information * [#4502](https://github.com/icinga/icinga2/issues/4502) (DB IDO): IDO query fails due to key contraint violation for the icinga\_customvariablestatus table * [#4501](https://github.com/icinga/icinga2/issues/4501) (Cluster): DB IDO started before daemonizing \(no systemd\) * [#4500](https://github.com/icinga/icinga2/issues/4500) (DB IDO): Query for customvariablestatus incorrectly updates the host's/service's insert ID * [#4499](https://github.com/icinga/icinga2/issues/4499) (DB IDO): Insert fails for the icinga\_scheduleddowntime table due to duplicate key * [#4497](https://github.com/icinga/icinga2/issues/4497): Fix incorrect detection of the 'Concurrency' variable * [#4496](https://github.com/icinga/icinga2/issues/4496) (API): API: action schedule-downtime requires a duration also when fixed is true * [#4495](https://github.com/icinga/icinga2/issues/4495): Use hash-based serial numbers for new certificates * [#4490](https://github.com/icinga/icinga2/issues/4490) (Cluster): ClusterEvents::NotificationSentAllUsersAPIHandler\(\) does not set notified\_users * [#4488](https://github.com/icinga/icinga2/issues/4488): Replace GetType\(\)-\>GetName\(\) calls with GetReflectionType\(\)-\>GetName\(\) * [#4484](https://github.com/icinga/icinga2/issues/4484) (Cluster): Only allow sending command\_endpoint checks to directly connected child zones * [#4483](https://github.com/icinga/icinga2/issues/4483) (DB IDO): ido CheckCommand returns returns "Could not connect to database server" when HA enabled * [#4481](https://github.com/icinga/icinga2/issues/4481) (DB IDO): Fix the "ido" check command for use with command\_endpoint * [#4478](https://github.com/icinga/icinga2/issues/4478): CompatUtility::GetCheckableNotificationStateFilter is returning an incorrect value * [#4476](https://github.com/icinga/icinga2/issues/4476) (DB IDO): Importing mysql schema fails * [#4475](https://github.com/icinga/icinga2/issues/4475) (CLI): pki sign-csr does not log where it is writing the certificate file * [#4472](https://github.com/icinga/icinga2/issues/4472) (DB IDO): IDO marks objects as inactive on shutdown * [#4471](https://github.com/icinga/icinga2/issues/4471) (DB IDO): IDO does duplicate config updates * [#4466](https://github.com/icinga/icinga2/issues/4466) (Configuration): 'use' keyword cannot be used with templates * [#4462](https://github.com/icinga/icinga2/issues/4462) (Notifications): Add log message if notifications are forced \(i.e. filters are not checked\) * [#4461](https://github.com/icinga/icinga2/issues/4461) (Notifications): Notification resent, even if interval = 0 * [#4460](https://github.com/icinga/icinga2/issues/4460) (DB IDO): Fixed downtime start does not update actual\_start\_time * [#4458](https://github.com/icinga/icinga2/issues/4458): Flexible downtimes should be removed after trigger\_time+duration * [#4455](https://github.com/icinga/icinga2/issues/4455): Disallow casting "" to an Object * [#4447](https://github.com/icinga/icinga2/issues/4447): Handle I/O errors while writing the Icinga state file more gracefully * [#4446](https://github.com/icinga/icinga2/issues/4446) (Notifications): Incorrect downtime notification events * [#4444](https://github.com/icinga/icinga2/issues/4444): Fix building Icinga with -fvisibility=hidden * [#4439](https://github.com/icinga/icinga2/issues/4439) (Configuration): Icinga doesn't delete temporary icinga2.debug file when config validation fails * [#4434](https://github.com/icinga/icinga2/issues/4434) (Notifications): Notification sent too fast when one master fails * [#4430](https://github.com/icinga/icinga2/issues/4430) (Cluster): Remove obsolete README files in tools/syntax * [#4427](https://github.com/icinga/icinga2/issues/4427) (Notifications): Missing notification for recovery during downtime * [#4425](https://github.com/icinga/icinga2/issues/4425) (DB IDO): Change the way outdated comments/downtimes are deleted on restart * [#4420](https://github.com/icinga/icinga2/issues/4420) (Notifications): Multiple notifications when master fails * [#4418](https://github.com/icinga/icinga2/issues/4418) (DB IDO): icinga2 IDO reload performance significant slower with latest snapshot release * [#4417](https://github.com/icinga/icinga2/issues/4417) (Notifications): Notification interval mistimed * [#4413](https://github.com/icinga/icinga2/issues/4413) (DB IDO): icinga2 empties custom variables, host-, servcie- and contactgroup members at the end of IDO database reconnection * [#4412](https://github.com/icinga/icinga2/issues/4412) (Notifications): Reminder notifications ignore HA mode * [#4405](https://github.com/icinga/icinga2/issues/4405) (DB IDO): Deprecation warning should include object type and name * [#4401](https://github.com/icinga/icinga2/issues/4401) (Metrics): Incorrect escaping / formatting of perfdata to InfluxDB * [#4399](https://github.com/icinga/icinga2/issues/4399): Icinga stats min\_execution\_time and max\_execution\_time are invalid * [#4394](https://github.com/icinga/icinga2/issues/4394): icinga check reports "-1" for minimum latency and execution time and only uptime has a number but 0 * [#4391](https://github.com/icinga/icinga2/issues/4391) (DB IDO): Do not clear {host,service,contact}group\_members tables on restart * [#4384](https://github.com/icinga/icinga2/issues/4384) (API): Fix URL encoding for '&' * [#4380](https://github.com/icinga/icinga2/issues/4380) (Cluster): Increase cluster reconnect interval * [#4378](https://github.com/icinga/icinga2/issues/4378) (Notifications): Optimize two ObjectLocks into one in Notification::BeginExecuteNotification method * [#4376](https://github.com/icinga/icinga2/issues/4376) (Cluster): CheckerComponent sometimes fails to schedule checks in time * [#4375](https://github.com/icinga/icinga2/issues/4375) (Cluster): Duplicate messages for command\_endpoint w/ master and satellite * [#4372](https://github.com/icinga/icinga2/issues/4372) (API): state\_filters\_real shouldn't be visible in the API * [#4371](https://github.com/icinga/icinga2/issues/4371) (Notifications): notification.notification\_number runtime attribute returning 0 \(instead of 1\) in first notification e-mail * [#4370](https://github.com/icinga/icinga2/issues/4370): Test the change with HARD OK transitions * [#4363](https://github.com/icinga/icinga2/issues/4363) (DB IDO): IDO module starts threads before daemonize * [#4356](https://github.com/icinga/icinga2/issues/4356) (DB IDO): DB IDO query queue does not clean up with v2.4.10-520-g124c80b * [#4349](https://github.com/icinga/icinga2/issues/4349) (DB IDO): Add missing index on state history for DB IDO cleanup * [#4345](https://github.com/icinga/icinga2/issues/4345): Ensure to clear the SSL error queue before calling SSL\_{read,write,do\_handshake} * [#4343](https://github.com/icinga/icinga2/issues/4343) (Configuration): include\_recursive should gracefully handle inaccessible files * [#4341](https://github.com/icinga/icinga2/issues/4341) (API): Icinga incorrectly disconnects all endpoints if one has a wrong certificate * [#4340](https://github.com/icinga/icinga2/issues/4340) (DB IDO): deadlock in ido reconnect * [#4329](https://github.com/icinga/icinga2/issues/4329) (Metrics): Key Escapes in InfluxDB Writer Don't Work * [#4313](https://github.com/icinga/icinga2/issues/4313) (Configuration): Icinga crashes when using include\_recursive in an object definition * [#4309](https://github.com/icinga/icinga2/issues/4309) (Configuration): ConfigWriter::EmitScope incorrectly quotes dictionary keys * [#4300](https://github.com/icinga/icinga2/issues/4300) (DB IDO): Comment/Downtime delete queries are slow * [#4293](https://github.com/icinga/icinga2/issues/4293) (DB IDO): Overflow in current\_notification\_number column in DB IDO MySQL * [#4287](https://github.com/icinga/icinga2/issues/4287) (DB IDO): Program status table is not updated in IDO after starting icinga * [#4283](https://github.com/icinga/icinga2/issues/4283) (Cluster): Icinga 2 satellite crashes * [#4278](https://github.com/icinga/icinga2/issues/4278) (DB IDO): SOFT state changes with the same state are not logged * [#4275](https://github.com/icinga/icinga2/issues/4275) (API): Trying to delete an object protected by a permissions filter, ends up deleting all objects that match the filter instead * [#4274](https://github.com/icinga/icinga2/issues/4274) (Notifications): Duplicate notifications * [#4264](https://github.com/icinga/icinga2/issues/4264) (Metrics): InfluxWriter doesnt sanitize the data before sending * [#4259](https://github.com/icinga/icinga2/issues/4259): Flapping Notifications dependent on state change * [#4258](https://github.com/icinga/icinga2/issues/4258): last SOFT state should be hard \(max\_check\_attempts\) * [#4257](https://github.com/icinga/icinga2/issues/4257) (Configuration): Incorrect custom variable name in the hosts.conf example config * [#4255](https://github.com/icinga/icinga2/issues/4255) (Configuration): Config validation should not delete comments/downtimes w/o reference * [#4244](https://github.com/icinga/icinga2/issues/4244): SOFT OK-state after returning from a soft state * [#4239](https://github.com/icinga/icinga2/issues/4239) (Notifications): Downtime notifications do not pass author and comment * [#4232](https://github.com/icinga/icinga2/issues/4232): Problems with check scheduling for HARD state changes \(standalone/command\_endpoint\) * [#4231](https://github.com/icinga/icinga2/issues/4231) (DB IDO): Volatile check results for OK-\>OK transitions are logged into DB IDO statehistory * [#4187](https://github.com/icinga/icinga2/issues/4187): Icinga 2 client gets killed during network scans * [#4171](https://github.com/icinga/icinga2/issues/4171) (DB IDO): Outdated downtime/comments not removed from IDO database \(restart\) * [#4134](https://github.com/icinga/icinga2/issues/4134) (Configuration): Don't allow flow control keywords outside of other flow control constructs * [#4121](https://github.com/icinga/icinga2/issues/4121) (Notifications): notification interval = 0 not honoured in HA clusters * [#4106](https://github.com/icinga/icinga2/issues/4106) (Notifications): last\_problem\_notification should be synced in HA cluster * [#4077](https://github.com/icinga/icinga2/issues/4077): Numbers are not properly formatted in runtime macro strings * [#4002](https://github.com/icinga/icinga2/issues/4002): Don't violate POSIX by ensuring that the argument to usleep\(3\) is less than 1000000 * [#3954](https://github.com/icinga/icinga2/issues/3954) (Cluster): High load when pinning command endpoint on HA cluster * [#3949](https://github.com/icinga/icinga2/issues/3949) (DB IDO): IDO: entry\_time of all comments is set to the date and time when Icinga 2 was restarted * [#3902](https://github.com/icinga/icinga2/issues/3902): Hang in TlsStream::Handshake * [#3820](https://github.com/icinga/icinga2/issues/3820) (Configuration): High CPU usage with self-referenced parent zone config * [#3805](https://github.com/icinga/icinga2/issues/3805) (Metrics): GELF multi-line output * [#3627](https://github.com/icinga/icinga2/issues/3627) (API): /v1 returns HTML even if JSON is requested * [#3486](https://github.com/icinga/icinga2/issues/3486) (Notifications): Notification times w/ empty begin/end specifications prevent sending notifications * [#3370](https://github.com/icinga/icinga2/issues/3370): Race condition in CreatePipeOverlapped * [#3365](https://github.com/icinga/icinga2/issues/3365) (DB IDO): IDO: there is no usable object index on icinga\_{scheduleddowntime,comments} * [#3364](https://github.com/icinga/icinga2/issues/3364) (DB IDO): IDO: check\_source should not be a TEXT field * [#3361](https://github.com/icinga/icinga2/issues/3361) (DB IDO): Missing indexes for icinga\_endpoints\* and icinga\_zones\* tables in DB IDO schema * [#3355](https://github.com/icinga/icinga2/issues/3355) (DB IDO): IDO: icinga\_host/service\_groups alias columns are TEXT columns * [#3229](https://github.com/icinga/icinga2/issues/3229): Function::Invoke should optionally register ScriptFrame * [#2996](https://github.com/icinga/icinga2/issues/2996) (Cluster): Custom notification external commands do not work in a master-master setup * [#2039](https://github.com/icinga/icinga2/issues/2039): Disable immediate hard state after first checkresult ### ITL * [#4518](https://github.com/icinga/icinga2/issues/4518) (ITL): ITL uses unsupported arguments for check\_swap on Debian wheezy/Ubuntu trusty * [#4506](https://github.com/icinga/icinga2/issues/4506) (ITL): Add interfacetable CheckCommand options --trafficwithpkt and --snmp-maxmsgsize * [#4477](https://github.com/icinga/icinga2/issues/4477) (ITL): Add perfsyntax parameter to nscp-local-counter CheckCommand * [#4456](https://github.com/icinga/icinga2/issues/4456) (ITL): Add custom variables for all check\_swap arguments * [#4437](https://github.com/icinga/icinga2/issues/4437) (ITL): Add command definition for check\_mysql\_query * [#4421](https://github.com/icinga/icinga2/issues/4421) (ITL): -q option for check\_ntp\_time is wrong * [#4416](https://github.com/icinga/icinga2/issues/4416) (ITL): Add check command definition for check\_graphite * [#4397](https://github.com/icinga/icinga2/issues/4397) (ITL): A lot of missing parameters for \(latest\) mysql\_health * [#4379](https://github.com/icinga/icinga2/issues/4379) (ITL): Add support for "-A" command line switch to CheckCommand "snmp-process" * [#4359](https://github.com/icinga/icinga2/issues/4359) (ITL): ITL: check\_iftraffic64.pl default values, wrong postfix value in CheckCommand * [#4332](https://github.com/icinga/icinga2/issues/4332) (ITL): Add check command definition for db2\_health * [#4305](https://github.com/icinga/icinga2/issues/4305) (ITL): Add check command definitions for kdc and rbl * [#4297](https://github.com/icinga/icinga2/issues/4297) (ITL): add check command for plugin check\_apache\_status * [#4276](https://github.com/icinga/icinga2/issues/4276) (ITL): Adding option to access ifName for manubulon snmp-interface check command * [#4254](https://github.com/icinga/icinga2/issues/4254) (ITL): Add "fuse.gvfsd-fuse" to the list of excluded file systems for check\_disk * [#4250](https://github.com/icinga/icinga2/issues/4250) (ITL): Add CIM port parameter for esxi\_hardware CheckCommand * [#4023](https://github.com/icinga/icinga2/issues/4023) (ITL): Add "retries" option to check\_snmp command * [#3711](https://github.com/icinga/icinga2/issues/3711) (ITL): icinga2.conf: Include plugins-contrib, manubulon, windows-plugins, nscp by default * [#3683](https://github.com/icinga/icinga2/issues/3683) (ITL): Add IPv4/IPv6 support to the rest of the monitoring-plugins * [#3012](https://github.com/icinga/icinga2/issues/3012) (ITL): Extend CheckCommand definitions for nscp-local ### Documentation * [#4521](https://github.com/icinga/icinga2/issues/4521) (Documentation): Typo in Notification object documentation * [#4517](https://github.com/icinga/icinga2/issues/4517) (Documentation): Documentation is missing for the API permissions that are new in 2.5.0 * [#4513](https://github.com/icinga/icinga2/issues/4513) (Documentation): Development docs: Add own section for gdb backtrace from a running process * [#4510](https://github.com/icinga/icinga2/issues/4510) (Documentation): Docs: API example uses wrong attribute name * [#4489](https://github.com/icinga/icinga2/issues/4489) (Documentation): Missing documentation for "legacy-timeperiod" template * [#4470](https://github.com/icinga/icinga2/issues/4470) (Documentation): The description for the http\_certificate attribute doesn't have the right default value * [#4468](https://github.com/icinga/icinga2/issues/4468) (Documentation): Add URL and short description for Monitoring Plugins inside the ITL documentation * [#4453](https://github.com/icinga/icinga2/issues/4453) (Documentation): Rewrite Client and Cluster chapter and; add service monitoring chapter * [#4419](https://github.com/icinga/icinga2/issues/4419) (Documentation): Incorrect API permission name for /v1/status in the documentation * [#4396](https://github.com/icinga/icinga2/issues/4396) (Documentation): Missing explanation for three level clusters with CSR auto-signing * [#4395](https://github.com/icinga/icinga2/issues/4395) (Documentation): Incorrect documentation about apply rules in zones.d directories * [#4387](https://github.com/icinga/icinga2/issues/4387) (Documentation): Improve author information about check\_yum * [#4361](https://github.com/icinga/icinga2/issues/4361) (Documentation): pkg-config is not listed as a build requirement in INSTALL.md * [#4337](https://github.com/icinga/icinga2/issues/4337) (Documentation): Add a note to the docs that API POST updates to custom attributes/groups won't trigger re-evaluation * [#4333](https://github.com/icinga/icinga2/issues/4333) (Documentation): Documentation: Setting up Plugins section is broken * [#4328](https://github.com/icinga/icinga2/issues/4328) (Documentation): Typo in Manubulon CheckCommand documentation * [#4318](https://github.com/icinga/icinga2/issues/4318) (Documentation): Migration docs still show unsupported CHANGE\_\*MODATTR external commands * [#4306](https://github.com/icinga/icinga2/issues/4306) (Documentation): Add a note about creating Zone/Endpoint objects with the API * [#4299](https://github.com/icinga/icinga2/issues/4299) (Documentation): Incorrect URL for API examples in the documentation * [#4265](https://github.com/icinga/icinga2/issues/4265) (Documentation): Improve "Endpoint" documentation * [#4263](https://github.com/icinga/icinga2/issues/4263) (Documentation): Fix systemd client command formatting * [#4238](https://github.com/icinga/icinga2/issues/4238) (Documentation): Missing quotes for API action URL * [#4236](https://github.com/icinga/icinga2/issues/4236) (Documentation): Use HTTPS for debmon.org links in the documentation * [#4217](https://github.com/icinga/icinga2/issues/4217) (Documentation): node setup: Add a note for --endpoint syntax for client-master connection * [#4124](https://github.com/icinga/icinga2/issues/4124) (Documentation): Documentation review * [#3612](https://github.com/icinga/icinga2/issues/3612) (Documentation): Update SELinux documentation ### Support * [#4526](https://github.com/icinga/icinga2/issues/4526) (Packages): Revert dependency on firewalld on RHEL * [#4494](https://github.com/icinga/icinga2/issues/4494) (Installation): Remove unused functions from icinga-installer * [#4452](https://github.com/icinga/icinga2/issues/4452) (Packages): Error compiling on windows due to changes in apilistener around minimum tls version * [#4432](https://github.com/icinga/icinga2/issues/4432) (Packages): Windows build broken since ref 11292 * [#4404](https://github.com/icinga/icinga2/issues/4404) (Installation): Increase default systemd timeout * [#4344](https://github.com/icinga/icinga2/issues/4344) (Packages): Build fails with Visual Studio 2013 * [#4327](https://github.com/icinga/icinga2/issues/4327) (Packages): Icinga fails to build with OpenSSL 1.1.0 * [#4251](https://github.com/icinga/icinga2/issues/4251) (Tests): Add debugging mode for Utility::GetTime * [#4234](https://github.com/icinga/icinga2/issues/4234) (Tests): Boost tests are missing a dependency on libmethods * [#4230](https://github.com/icinga/icinga2/issues/4230) (Installation): Windows: Error with repository handler \(missing /var/lib/icinga2/api/repository path\) * [#4211](https://github.com/icinga/icinga2/issues/4211) (Packages): Incorrect filter in pick.py * [#4190](https://github.com/icinga/icinga2/issues/4190) (Packages): Windows Installer: Remove dependency on KB2999226 package * [#4148](https://github.com/icinga/icinga2/issues/4148) (Packages): RPM update starts disabled icinga2 service * [#4147](https://github.com/icinga/icinga2/issues/4147) (Packages): Reload permission error with SELinux * [#4135](https://github.com/icinga/icinga2/issues/4135) (Installation): Add script for automatically cherry-picking commits for minor versions * [#3829](https://github.com/icinga/icinga2/issues/3829) (Packages): Provide packages for icinga-studio on Fedora * [#3708](https://github.com/icinga/icinga2/issues/3708) (Packages): Firewalld Service definition for Icinga * [#2606](https://github.com/icinga/icinga2/issues/2606) (Packages): Package for syntax highlighting ## 2.4.9 (2016-05-19) ### Notes This release fixes a number of issues introduced in 2.4.8. ### Bug * [#4225](https://github.com/icinga/icinga2/issues/4225) (Compat): Command Pipe thread 100% CPU Usage * [#4224](https://github.com/icinga/icinga2/issues/4224): Checks are not executed anymore on command * [#4222](https://github.com/icinga/icinga2/issues/4222) (Configuration): Segfault when trying to start 2.4.8 * [#4221](https://github.com/icinga/icinga2/issues/4221) (Metrics): Error: Function call 'rename' for file '/var/spool/icinga2/tmp/service-perfdata' failed with error code 2, 'No such file or directory' ## 2.4.10 (2016-05-19) ### Notes * Bugfixes ### Bug * [#4227](https://github.com/icinga/icinga2/issues/4227): Checker component doesn't execute any checks for command\_endpoint ## 2.4.8 (2016-05-17) ### Notes * Bugfixes * Support for limiting the maximum number of concurrent checks (new configuration option) * HA-aware features now wait for connected cluster nodes in the same zone (e.g. DB IDO) * The 'icinga' check now alerts on failed reloads ### Enhancement * [#4203](https://github.com/icinga/icinga2/issues/4203) (Cluster): Only activate HARunOnce objects once there's a cluster connection * [#4198](https://github.com/icinga/icinga2/issues/4198): Move CalculateExecutionTime and CalculateLatency into the CheckResult class * [#4196](https://github.com/icinga/icinga2/issues/4196) (Cluster): Remove unused cluster commands * [#4149](https://github.com/icinga/icinga2/issues/4149) (CLI): Implement SNI support for the CLI commands * [#4103](https://github.com/icinga/icinga2/issues/4103): Add support for subjectAltName in SSL certificates * [#3919](https://github.com/icinga/icinga2/issues/3919) (Configuration): Internal check for config problems * [#3321](https://github.com/icinga/icinga2/issues/3321): "icinga" check should have state WARNING when the last reload failed * [#2993](https://github.com/icinga/icinga2/issues/2993) (Metrics): PerfdataWriter: Better failure handling for file renames across file systems * [#2896](https://github.com/icinga/icinga2/issues/2896) (Cluster): Alert config reload failures with the icinga check * [#2468](https://github.com/icinga/icinga2/issues/2468): Maximum concurrent service checks ### Bug * [#4219](https://github.com/icinga/icinga2/issues/4219) (DB IDO): Postgresql warnings on startup * [#4212](https://github.com/icinga/icinga2/issues/4212): assertion failed: GetResumeCalled\(\) * [#4210](https://github.com/icinga/icinga2/issues/4210) (API): Incorrect variable names for joined fields in filters * [#4204](https://github.com/icinga/icinga2/issues/4204) (DB IDO): Ensure that program status updates are immediately updated in DB IDO * [#4202](https://github.com/icinga/icinga2/issues/4202) (API): API: Missing error handling for invalid JSON request body * [#4182](https://github.com/icinga/icinga2/issues/4182): Crash in UnameHelper * [#4180](https://github.com/icinga/icinga2/issues/4180): Expired downtimes are not removed * [#4170](https://github.com/icinga/icinga2/issues/4170) (API): Icinga Crash with the workflow Create\_Host-\> Downtime for the Host -\> Delete Downtime -\> Remove Host * [#4145](https://github.com/icinga/icinga2/issues/4145) (Configuration): Wrong log severity causes segfault * [#4120](https://github.com/icinga/icinga2/issues/4120): notification sent out during flexible downtime * [#4038](https://github.com/icinga/icinga2/issues/4038) (API): inconsistent API /v1/objects/\* response for PUT requests * [#4037](https://github.com/icinga/icinga2/issues/4037) (Compat): Command pipe overloaded: Can't send external Icinga command to the local command file * [#4029](https://github.com/icinga/icinga2/issues/4029) (API): Icinga2 API: deleting service with cascade=1 does not delete dependant notification * [#3938](https://github.com/icinga/icinga2/issues/3938): Crash with empty ScheduledDowntime 'ranges' attribute * [#3932](https://github.com/icinga/icinga2/issues/3932): "day -X" time specifications are parsed incorrectly * [#3912](https://github.com/icinga/icinga2/issues/3912) (Compat): Empty author/text attribute for comment/downtimes external commands causing crash * [#3881](https://github.com/icinga/icinga2/issues/3881) (Cluster): Icinga2 agent gets stuck after disconnect and won't relay messages * [#3707](https://github.com/icinga/icinga2/issues/3707) (Configuration): Comments and downtimes of deleted checkable objects are not deleted * [#3526](https://github.com/icinga/icinga2/issues/3526): Icinga crashes with a segfault on receiving a lot of check results for nonexisting hosts/services * [#3316](https://github.com/icinga/icinga2/issues/3316) (Configuration): Service apply without name possible ### ITL * [#4184](https://github.com/icinga/icinga2/issues/4184) (ITL): 'disk' CheckCommand: Exclude 'cgroup' and 'tracefs' by default * [#3634](https://github.com/icinga/icinga2/issues/3634) (ITL): Provide icingacli in the ITL ### Documentation * [#4205](https://github.com/icinga/icinga2/issues/4205) (Documentation): Add the category to the generated changelog * [#4193](https://github.com/icinga/icinga2/issues/4193) (Documentation): Missing documentation for event commands w/ execution bridge * [#4144](https://github.com/icinga/icinga2/issues/4144) (Documentation): Incorrect chapter headings for Object\#to\_string and Object\#type ### Support * [#4146](https://github.com/icinga/icinga2/issues/4146) (Packages): Update chocolatey packages and RELEASE.md ## 2.4.7 (2016-04-21) ### Notes * Bugfixes ### Bug * [#4142](https://github.com/icinga/icinga2/issues/4142) (DB IDO): Crash in IdoMysqlConnection::ExecuteMultipleQueries ## 2.4.6 (2016-04-20) ### Notes * Bugfixes ### Bug * [#4140](https://github.com/icinga/icinga2/issues/4140) (DB IDO): Failed assertion in IdoPgsqlConnection::FieldToEscapedString ### Documentation * [#4141](https://github.com/icinga/icinga2/issues/4141) (Documentation): Update RELEASE.md * [#4136](https://github.com/icinga/icinga2/issues/4136) (Documentation): Docs: Zone attribute 'endpoints' is an array ### Support * [#4139](https://github.com/icinga/icinga2/issues/4139) (Packages): Icinga 2 fails to build on Ubuntu Xenial ## 2.4.5 (2016-04-20) ### Notes * Windows Installer changed from NSIS to MSI * New configuration attribute for hosts and services: check_timeout (overrides the CheckCommand's timeout when set) * ITL updates * Lots of bugfixes ### Enhancement * [#3023](https://github.com/icinga/icinga2/issues/3023) (Configuration): Implement support for overriding check command timeout ### Bug * [#4131](https://github.com/icinga/icinga2/issues/4131) (Configuration): Vim Syntax Highlighting does not work with assign where * [#4116](https://github.com/icinga/icinga2/issues/4116) (API): icinga2 crashes when a command\_endpoint is set, but the api feature is not active * [#4114](https://github.com/icinga/icinga2/issues/4114): Compiler warning in NotifyActive * [#4109](https://github.com/icinga/icinga2/issues/4109) (API): Navigation attributes are missing in /v1/objects/\ * [#4104](https://github.com/icinga/icinga2/issues/4104) (Configuration): Segfault during config validation if host exists, service does not exist any longer and downtime expires * [#4095](https://github.com/icinga/icinga2/issues/4095): DowntimesExpireTimerHandler crashes Icinga2 with \ * [#4089](https://github.com/icinga/icinga2/issues/4089): Make the socket event engine configurable * [#4078](https://github.com/icinga/icinga2/issues/4078) (Configuration): Overwriting global type variables causes crash in ConfigItem::Commit\(\) * [#4076](https://github.com/icinga/icinga2/issues/4076) (API): API User gets wrongly authenticated \(client\_cn and no password\) * [#4066](https://github.com/icinga/icinga2/issues/4066): ConfigSync broken from 2.4.3. to 2.4.4 under Windows * [#4056](https://github.com/icinga/icinga2/issues/4056) (CLI): Remove semi-colons in the auto-generated configs * [#4052](https://github.com/icinga/icinga2/issues/4052) (API): Config validation for Notification objects should check whether the state filters are valid * [#4035](https://github.com/icinga/icinga2/issues/4035) (DB IDO): IDO: historical contact notifications table column notification\_id is off-by-one * [#4031](https://github.com/icinga/icinga2/issues/4031): Downtimes are not always activated/expired on restart * [#4016](https://github.com/icinga/icinga2/issues/4016): Symlink subfolders not followed/considered for config files * [#4014](https://github.com/icinga/icinga2/issues/4014): Use retry\_interval instead of check\_interval for first OK -\> NOT-OK state change * [#3973](https://github.com/icinga/icinga2/issues/3973) (Cluster): Downtimes and Comments are not synced to child zones * [#3970](https://github.com/icinga/icinga2/issues/3970) (API): Socket Exceptions \(Operation not permitted\) while reading from API * [#3907](https://github.com/icinga/icinga2/issues/3907) (Configuration): Too many assign where filters cause stack overflow * [#3780](https://github.com/icinga/icinga2/issues/3780) (DB IDO): DB IDO: downtime is not in effect after restart ### ITL * [#3953](https://github.com/icinga/icinga2/issues/3953) (ITL): Add --units, --rate and --rate-multiplier support for the snmpv3 check command * [#3903](https://github.com/icinga/icinga2/issues/3903) (ITL): Add --method parameter for check\_{oracle,mysql,mssql}\_health CheckCommands ### Documentation * [#4122](https://github.com/icinga/icinga2/issues/4122) (Documentation): Remove instance\_name from Ido\*Connection example * [#4108](https://github.com/icinga/icinga2/issues/4108) (Documentation): Incorrect link in the documentation * [#4080](https://github.com/icinga/icinga2/issues/4080) (Documentation): Update documentation URL for Icinga Web 2 * [#4058](https://github.com/icinga/icinga2/issues/4058) (Documentation): Docs: Cluster manual SSL generation formatting is broken * [#4057](https://github.com/icinga/icinga2/issues/4057) (Documentation): Update the CentOS installation documentation * [#4055](https://github.com/icinga/icinga2/issues/4055) (Documentation): Add silent install / reference to NSClient++ to documentation * [#4043](https://github.com/icinga/icinga2/issues/4043) (Documentation): Docs: Remove the migration script chapter * [#4041](https://github.com/icinga/icinga2/issues/4041) (Documentation): Explain how to use functions for wildcard matches for arrays and/or dictionaries in assign where expressions * [#4039](https://github.com/icinga/icinga2/issues/4039) (Documentation): Update .mailmap for Markus Frosch * [#3145](https://github.com/icinga/icinga2/issues/3145) (Documentation): Add Windows setup wizard screenshots ### Support * [#4127](https://github.com/icinga/icinga2/issues/4127) (Installation): Windows installer does not copy "features-enabled" on upgrade * [#4119](https://github.com/icinga/icinga2/issues/4119) (Installation): Update chocolatey uninstall script for the MSI package * [#4118](https://github.com/icinga/icinga2/issues/4118) (Installation): icinga2-installer.exe doesn't wait until NSIS uninstall.exe exits * [#4117](https://github.com/icinga/icinga2/issues/4117) (Installation): Make sure to update the agent wizard banner * [#4113](https://github.com/icinga/icinga2/issues/4113) (Installation): Package fails to build on \*NIX * [#4099](https://github.com/icinga/icinga2/issues/4099) (Installation): make install overwrites configuration files * [#4074](https://github.com/icinga/icinga2/issues/4074) (Installation): FatalError\(\) returns when called before Application.Run * [#4073](https://github.com/icinga/icinga2/issues/4073) (Installation): Install 64-bit version of NSClient++ on 64-bit versions of Windows * [#4072](https://github.com/icinga/icinga2/issues/4072) (Installation): Update NSClient++ to version 0.4.4.19 * [#4069](https://github.com/icinga/icinga2/issues/4069) (Installation): Error compiling icinga2 targeted for x64 on Windows * [#4064](https://github.com/icinga/icinga2/issues/4064) (Packages): Build 64-bit packages for Windows * [#4053](https://github.com/icinga/icinga2/issues/4053) (Installation): Icinga 2 Windows Agent does not honor install path during upgrade * [#4032](https://github.com/icinga/icinga2/issues/4032) (Packages): Remove dependency for .NET 3.5 from the chocolatey package * [#3988](https://github.com/icinga/icinga2/issues/3988) (Packages): Incorrect base URL in the icinga-rpm-release packages for Fedora * [#3658](https://github.com/icinga/icinga2/issues/3658) (Packages): Add application manifest for the Windows agent wizard * [#2998](https://github.com/icinga/icinga2/issues/2998) (Installation): logrotate fails since the "su" directive was removed ## 2.4.4 (2016-03-16) ### Notes * Bugfixes ### Bug * [#4036](https://github.com/icinga/icinga2/issues/4036) (CLI): Add the executed cli command to the Windows wizard error messages * [#4019](https://github.com/icinga/icinga2/issues/4019) (Configuration): Segmentation fault during 'icinga2 daemon -C' * [#4017](https://github.com/icinga/icinga2/issues/4017) (CLI): 'icinga2 feature list' fails when all features are disabled * [#4008](https://github.com/icinga/icinga2/issues/4008) (Configuration): Windows wizard error "too many arguments" * [#4006](https://github.com/icinga/icinga2/issues/4006): Volatile transitions from HARD NOT-OK-\>NOT-OK do not trigger notifications * [#3996](https://github.com/icinga/icinga2/issues/3996): epoll\_ctl might cause oops on Ubuntu trusty * [#3990](https://github.com/icinga/icinga2/issues/3990): Services status updated multiple times within check\_interval even though no retry was triggered * [#3987](https://github.com/icinga/icinga2/issues/3987): Incorrect check interval when passive check results are used * [#3985](https://github.com/icinga/icinga2/issues/3985): Active checks are executed even though passive results are submitted * [#3981](https://github.com/icinga/icinga2/issues/3981): DEL\_DOWNTIME\_BY\_HOST\_NAME does not accept optional arguments * [#3961](https://github.com/icinga/icinga2/issues/3961) (CLI): Wrong log message for trusted cert in node setup command * [#3939](https://github.com/icinga/icinga2/issues/3939) (CLI): Common name in node wizard isn't case sensitive * [#3745](https://github.com/icinga/icinga2/issues/3745) (API): Status code 200 even if an object could not be deleted. * [#3742](https://github.com/icinga/icinga2/issues/3742) (DB IDO): DB IDO: User notification type filters are incorrect * [#3442](https://github.com/icinga/icinga2/issues/3442) (API): MkDirP not working on Windows * [#3439](https://github.com/icinga/icinga2/issues/3439) (Notifications): Host notification type is PROBLEM but should be RECOVERY * [#3303](https://github.com/icinga/icinga2/issues/3303) (Notifications): Problem notifications while Flapping is active * [#3153](https://github.com/icinga/icinga2/issues/3153) (Notifications): Flapping notifications are sent for hosts/services which are in a downtime ### ITL * [#3958](https://github.com/icinga/icinga2/issues/3958) (ITL): Add "query" option to check\_postgres command. * [#3908](https://github.com/icinga/icinga2/issues/3908) (ITL): ITL: Missing documentation for nwc\_health "mode" parameter * [#3484](https://github.com/icinga/icinga2/issues/3484) (ITL): ITL: Allow to enforce specific SSL versions using the http check command ### Documentation * [#4033](https://github.com/icinga/icinga2/issues/4033) (Documentation): Update development docs to use 'thread apply all bt full' * [#4018](https://github.com/icinga/icinga2/issues/4018) (Documentation): Docs: Add API examples for creating services and check commands * [#4009](https://github.com/icinga/icinga2/issues/4009) (Documentation): Typo in API docs * [#3845](https://github.com/icinga/icinga2/issues/3845) (Documentation): Explain how to join hosts/services for /v1/objects/comments * [#3755](https://github.com/icinga/icinga2/issues/3755) (Documentation): http check's URI is really just Path ### Support * [#4027](https://github.com/icinga/icinga2/issues/4027) (Packages): Chocolatey package is missing uninstall function * [#4011](https://github.com/icinga/icinga2/issues/4011) (Packages): Update build requirements for SLES 11 SP4 * [#3960](https://github.com/icinga/icinga2/issues/3960) (Installation): CMake does not find MySQL libraries on Windows ## 2.4.3 (2016-02-24) ### Notes * Bugfixes ### Bug * [#3963](https://github.com/icinga/icinga2/issues/3963): Wrong permissions for files in /var/cache/icinga2/\* * [#3962](https://github.com/icinga/icinga2/issues/3962) (Configuration): Permission problem after running icinga2 node wizard ## 2.4.2 (2016-02-23) ### Notes * ITL Additional arguments for check_disk Fix incorrect path for the check_hpasm plugin New command: check_iostat Fix incorrect variable names for the check_impi plugin * Cluster Improve cluster performance Fix connection handling problems (multiple connections for the same endpoint) * Performance improvements for the DB IDO modules * Lots and lots of various other bugfixes * Documentation updates ### Enhancement * [#3878](https://github.com/icinga/icinga2/issues/3878) (Configuration): Add String\#trim * [#3857](https://github.com/icinga/icinga2/issues/3857) (Cluster): Support TLSv1.1 and TLSv1.2 for the cluster transport encryption * [#3810](https://github.com/icinga/icinga2/issues/3810) (Plugins): Add Timeout parameter to snmpv3 check * [#3785](https://github.com/icinga/icinga2/issues/3785) (DB IDO): Log DB IDO query queue stats * [#3784](https://github.com/icinga/icinga2/issues/3784) (DB IDO): DB IDO: Add a log message when the connection handling is completed * [#3760](https://github.com/icinga/icinga2/issues/3760) (Configuration): Raise a config error for "Checkable" objects in global zones * [#3754](https://github.com/icinga/icinga2/issues/3754) (Plugins): Add "-x" parameter in command definition for disk-windows CheckCommand ### Bug * [#3957](https://github.com/icinga/icinga2/issues/3957) (CLI): "node setup" tries to chown\(\) files before they're created * [#3947](https://github.com/icinga/icinga2/issues/3947): CentOS 5 doesn't support epoll\_create1 * [#3922](https://github.com/icinga/icinga2/issues/3922) (Configuration): YYYY-MM-DD time specs are parsed incorrectly * [#3915](https://github.com/icinga/icinga2/issues/3915) (API): Connections are not cleaned up properly * [#3913](https://github.com/icinga/icinga2/issues/3913) (Cluster): Cluster WQ thread dies after fork\(\) * [#3910](https://github.com/icinga/icinga2/issues/3910): Clean up unused variables a bit * [#3905](https://github.com/icinga/icinga2/issues/3905) (DB IDO): Problem with hostgroup\_members table cleanup * [#3898](https://github.com/icinga/icinga2/issues/3898) (API): API queries on non-existant objects cause exception * [#3897](https://github.com/icinga/icinga2/issues/3897) (Configuration): Crash in ConfigItem::RunWithActivationContext * [#3896](https://github.com/icinga/icinga2/issues/3896) (Cluster): Ensure that config sync updates are always sent on reconnect * [#3889](https://github.com/icinga/icinga2/issues/3889) (DB IDO): Deleting an object via API does not disable it in DB IDO * [#3871](https://github.com/icinga/icinga2/issues/3871) (Cluster): Master reloads with agents generate false alarms * [#3870](https://github.com/icinga/icinga2/issues/3870) (DB IDO): next\_check noise in the IDO * [#3866](https://github.com/icinga/icinga2/issues/3866) (Cluster): Check event duplication with parallel connections involved * [#3863](https://github.com/icinga/icinga2/issues/3863) (Cluster): Segfault in ApiListener::ConfigUpdateObjectAPIHandler * [#3859](https://github.com/icinga/icinga2/issues/3859): Stream buffer size is 512 bytes, could be raised * [#3858](https://github.com/icinga/icinga2/issues/3858) (CLI): Escaped sequences not properly generated with 'node update-config' * [#3848](https://github.com/icinga/icinga2/issues/3848) (Configuration): Mistake in mongodb command definition \(mongodb\_replicaset\) * [#3843](https://github.com/icinga/icinga2/issues/3843): Modified attributes do not work for the IcingaApplication object w/ external commands * [#3835](https://github.com/icinga/icinga2/issues/3835) (Cluster): high load and memory consumption on icinga2 agent v2.4.1 * [#3827](https://github.com/icinga/icinga2/issues/3827) (Configuration): Icinga state file corruption with temporary file creation * [#3817](https://github.com/icinga/icinga2/issues/3817) (Cluster): Cluster config sync: Ensure that /var/lib/icinga2/api/zones/\* exists * [#3816](https://github.com/icinga/icinga2/issues/3816) (Cluster): Exception stack trace on icinga2 client when the master reloads the configuration * [#3812](https://github.com/icinga/icinga2/issues/3812) (API): API actions: Decide whether fixed: false is the right default * [#3798](https://github.com/icinga/icinga2/issues/3798) (DB IDO): is\_active in IDO is only re-enabled on "every second" restart * [#3797](https://github.com/icinga/icinga2/issues/3797): Remove superfluous \#ifdef * [#3794](https://github.com/icinga/icinga2/issues/3794) (DB IDO): Icinga2 crashes in IDO when removing a comment * [#3787](https://github.com/icinga/icinga2/issues/3787) (CLI): "repository add" cli command writes invalid "type" attribute * [#3786](https://github.com/icinga/icinga2/issues/3786) (DB IDO): Evaluate if CanExecuteQuery/FieldToEscapedString lead to exceptions on !m\_Connected * [#3783](https://github.com/icinga/icinga2/issues/3783) (DB IDO): Implement support for re-ordering groups of IDO queries * [#3775](https://github.com/icinga/icinga2/issues/3775) (Configuration): Config validation doesn't fail when templates are used as object names * [#3774](https://github.com/icinga/icinga2/issues/3774) (DB IDO): IDO breaks when writing to icinga\_programstatus with latest snapshots * [#3773](https://github.com/icinga/icinga2/issues/3773) (Configuration): Relative path in include\_zones does not work * [#3766](https://github.com/icinga/icinga2/issues/3766) (API): Cluster config sync ignores zones.d from API packages * [#3765](https://github.com/icinga/icinga2/issues/3765): Use NodeName in null and random checks * [#3764](https://github.com/icinga/icinga2/issues/3764) (DB IDO): Failed IDO query for icinga\_downtimehistory * [#3752](https://github.com/icinga/icinga2/issues/3752): Incorrect information in --version on Linux * [#3741](https://github.com/icinga/icinga2/issues/3741) (DB IDO): Avoid duplicate config and status updates on startup * [#3735](https://github.com/icinga/icinga2/issues/3735) (Configuration): Disallow lambda expressions where side-effect-free expressions are not allowed * [#3730](https://github.com/icinga/icinga2/issues/3730): Missing path in mkdir\(\) exceptions * [#3728](https://github.com/icinga/icinga2/issues/3728) (DB IDO): build of icinga2 with gcc 4.4.7 segfaulting with ido * [#3722](https://github.com/icinga/icinga2/issues/3722) (API): Missing num\_hosts\_pending in /v1/status/CIB * [#3715](https://github.com/icinga/icinga2/issues/3715) (CLI): node wizard does not remember user defined port * [#3712](https://github.com/icinga/icinga2/issues/3712) (CLI): Remove the local zone name question in node wizard * [#3705](https://github.com/icinga/icinga2/issues/3705) (API): API is not working on wheezy * [#3704](https://github.com/icinga/icinga2/issues/3704) (Cluster): ApiListener::ReplayLog can block with a lot of clients * [#3702](https://github.com/icinga/icinga2/issues/3702) (Cluster): Zone::CanAccessObject is very expensive * [#3697](https://github.com/icinga/icinga2/issues/3697) (Compat): Crash in ExternalCommandListener * [#3677](https://github.com/icinga/icinga2/issues/3677) (API): API queries cause memory leaks * [#3613](https://github.com/icinga/icinga2/issues/3613) (DB IDO): Non-UTF8 characters from plugins causes IDO to fail * [#3606](https://github.com/icinga/icinga2/issues/3606) (Plugins): check\_network performance data in invalid format * [#3571](https://github.com/icinga/icinga2/issues/3571) (Plugins): check\_memory and check\_swap plugins do unit conversion and rounding before percentage calculations resulting in imprecise percentages * [#3540](https://github.com/icinga/icinga2/issues/3540) (Livestatus): Livestatus log query - filter "class" yields empty results * [#3440](https://github.com/icinga/icinga2/issues/3440): Icinga2 reload timeout results in killing old and new process because of systemd * [#2866](https://github.com/icinga/icinga2/issues/2866) (DB IDO): DB IDO: notification\_id for contact notifications is out of range * [#2746](https://github.com/icinga/icinga2/issues/2746) (DB IDO): Add priority queue for disconnect/programstatus update events * [#2009](https://github.com/icinga/icinga2/issues/2009): Re-checks scheduling w/ retry\_interval ### ITL * [#3927](https://github.com/icinga/icinga2/issues/3927) (ITL): Checkcommand Disk : Option Freespace-ignore-reserved * [#3749](https://github.com/icinga/icinga2/issues/3749) (ITL): The hpasm check command is using the PluginDir constant * [#3747](https://github.com/icinga/icinga2/issues/3747) (ITL): Add check\_iostat to ITL * [#3729](https://github.com/icinga/icinga2/issues/3729) (ITL): ITL check command possibly mistyped variable names ### Documentation * [#3946](https://github.com/icinga/icinga2/issues/3946) (Documentation): Documentation: Unescaped pipe character in tables * [#3893](https://github.com/icinga/icinga2/issues/3893) (Documentation): Outdated link to icingaweb2-module-nagvis * [#3892](https://github.com/icinga/icinga2/issues/3892) (Documentation): Partially missing escaping in doc/7-icinga-template-library.md * [#3861](https://github.com/icinga/icinga2/issues/3861) (Documentation): Incorrect IdoPgSqlConnection Example in Documentation * [#3850](https://github.com/icinga/icinga2/issues/3850) (Documentation): Incorrect name in AUTHORS * [#3836](https://github.com/icinga/icinga2/issues/3836) (Documentation): Troubleshooting: Explain how to fetch the executed command * [#3833](https://github.com/icinga/icinga2/issues/3833) (Documentation): Better explaination for array values in "disk" CheckCommand docs * [#3826](https://github.com/icinga/icinga2/issues/3826) (Documentation): Add example how to use custom functions in attributes * [#3808](https://github.com/icinga/icinga2/issues/3808) (Documentation): Typos in the "troubleshooting" section of the documentation * [#3793](https://github.com/icinga/icinga2/issues/3793) (Documentation): "setting up check plugins" section should be enhanced with package manager examples * [#3781](https://github.com/icinga/icinga2/issues/3781) (Documentation): Formatting problem in "Advanced Filter" chapter * [#3770](https://github.com/icinga/icinga2/issues/3770) (Documentation): Missing documentation for API packages zones.d config sync * [#3759](https://github.com/icinga/icinga2/issues/3759) (Documentation): Missing SUSE repository for monitoring plugins documentation * [#3748](https://github.com/icinga/icinga2/issues/3748) (Documentation): Wrong postgresql-setup initdb command for RHEL7 * [#3550](https://github.com/icinga/icinga2/issues/3550) (Documentation): A PgSQL DB for the IDO can't be created w/ UTF8 * [#3549](https://github.com/icinga/icinga2/issues/3549) (Documentation): Incorrect SQL command for creating the user of the PostgreSQL DB for the IDO ### Support * [#3900](https://github.com/icinga/icinga2/issues/3900) (Packages): Windows build fails on InterlockedIncrement type * [#3838](https://github.com/icinga/icinga2/issues/3838) (Installation): Race condition when using systemd unit file * [#3832](https://github.com/icinga/icinga2/issues/3832) (Installation): Compiler warnings in lib/remote/base64.cpp * [#3818](https://github.com/icinga/icinga2/issues/3818) (Installation): Logrotate on systemd distros should use systemctl not service * [#3771](https://github.com/icinga/icinga2/issues/3771) (Installation): Build error with older CMake versions on VERSION\_LESS compare * [#3769](https://github.com/icinga/icinga2/issues/3769) (Packages): Windows build fails with latest git master * [#3746](https://github.com/icinga/icinga2/issues/3746) (Packages): chcon partial context error in safe-reload prevents reload * [#3723](https://github.com/icinga/icinga2/issues/3723) (Installation): Crash on startup with incorrect directory permissions * [#3679](https://github.com/icinga/icinga2/issues/3679) (Installation): Add CMake flag for disabling the unit tests ## 2.4.1 (2015-11-26) ### Notes * ITL * Add running_kernel_use_sudo option for the running_kernel check * Configuration * Add global constants: `PlatformName`. `PlatformVersion`, `PlatformKernel` and `PlatformKernelVersion` * CLI * Use NodeName and ZoneName constants for 'node setup' and 'node wizard' ### Enhancement * [#3706](https://github.com/icinga/icinga2/issues/3706) (CLI): Use NodeName and ZoneName constants for 'node setup' and 'node wizard' ### Bug * [#3710](https://github.com/icinga/icinga2/issues/3710) (CLI): Remove --master\_zone from --help because it is currently not implemented * [#3689](https://github.com/icinga/icinga2/issues/3689) (CLI): CLI command 'repository add' doesn't work * [#3685](https://github.com/icinga/icinga2/issues/3685) (CLI): node wizard checks for /var/lib/icinga2/ca directory but not the files * [#3674](https://github.com/icinga/icinga2/issues/3674): lib/base/process.cpp SIGSEGV on Debian squeeze / RHEL 6 * [#3671](https://github.com/icinga/icinga2/issues/3671) (API): Icinga 2 crashes when ScheduledDowntime objects are used * [#3670](https://github.com/icinga/icinga2/issues/3670) (CLI): API setup command incorrectly overwrites existing certificates * [#3665](https://github.com/icinga/icinga2/issues/3665) (CLI): "node wizard" does not ask user to verify SSL certificate ### ITL * [#3691](https://github.com/icinga/icinga2/issues/3691) (ITL): Add running\_kernel\_use\_sudo option for the running\_kernel check * [#3682](https://github.com/icinga/icinga2/issues/3682) (ITL): Indentation in command-plugins.conf * [#3657](https://github.com/icinga/icinga2/issues/3657) (ITL): Add by\_ssh\_options argument for the check\_by\_ssh plugin ### Documentation * [#3701](https://github.com/icinga/icinga2/issues/3701) (Documentation): Incorrect path for icinga2 binary in development documentation * [#3690](https://github.com/icinga/icinga2/issues/3690) (Documentation): Fix typos in the documentation * [#3673](https://github.com/icinga/icinga2/issues/3673) (Documentation): Documentation for schedule-downtime is missing required paremeters * [#3594](https://github.com/icinga/icinga2/issues/3594) (Documentation): Documentation example in "Access Object Attributes at Runtime" doesn't work correctly * [#3391](https://github.com/icinga/icinga2/issues/3391) (Documentation): Incorrect web inject URL in documentation ### Support * [#3699](https://github.com/icinga/icinga2/issues/3699) (Installation): Windows setup wizard crashes when InstallDir registry key is not set * [#3680](https://github.com/icinga/icinga2/issues/3680) (Installation): Incorrect redirect for stderr in /usr/lib/icinga2/prepare-dirs * [#3656](https://github.com/icinga/icinga2/issues/3656) (Packages): Build fails on SLES 11 SP3 with GCC 4.8 ## 2.4.0 (2015-11-16) ### Notes * API * RESTful API with basic auth or client certificates * Filters, types, permissions * configuration package management * query/create/modify/delete config objects at runtime * status queries for global stats * actions (e.g. acknowledge all service problems) * event streams * ITL and Plugin Check Command definitions * The 'running_kernel' check command was moved to the plugins-contrib section. You have to update your config to include 'plugins-contrib' * Configuration * The global constants Enable* and Vars have been removed. Use the IcingaApplication object attributes instead. * Features * New Graphite tree. Please check the documentation how enable the legacy schema. * IcingaStatusWriter feature has been deprecated and will be removed in future versions. * Modified attributes are not exposed as bit mask to external interfaces anymore (api related changes). External commands like CHANGE_*_MODATTR have been removed. ### Enhancement * [#3642](https://github.com/icinga/icinga2/issues/3642): Release 2.4.0 * [#3624](https://github.com/icinga/icinga2/issues/3624) (API): Enhance programmatic examples for the API docs * [#3611](https://github.com/icinga/icinga2/issues/3611) (API): Change object query result set * [#3609](https://github.com/icinga/icinga2/issues/3609) (API): Change 'api setup' into a manual step while configuring the API * [#3608](https://github.com/icinga/icinga2/issues/3608) (CLI): Icinga 2 script debugger * [#3591](https://github.com/icinga/icinga2/issues/3591) (CLI): Change output format for 'icinga2 console' * [#3580](https://github.com/icinga/icinga2/issues/3580): Change GetLastStateUp/Down to host attributes * [#3576](https://github.com/icinga/icinga2/issues/3576) (Plugins): Missing parameters for check jmx4perl * [#3561](https://github.com/icinga/icinga2/issues/3561) (CLI): Use ZoneName variable for parent\_zone in node update-config * [#3537](https://github.com/icinga/icinga2/issues/3537) (CLI): Rewrite man page * [#3531](https://github.com/icinga/icinga2/issues/3531) (DB IDO): Add the name for comments/downtimes next to legacy\_id to DB IDO * [#3515](https://github.com/icinga/icinga2/issues/3515): Remove api.cpp, api.hpp * [#3508](https://github.com/icinga/icinga2/issues/3508) (Cluster): Add getter for endpoint 'connected' attribute * [#3507](https://github.com/icinga/icinga2/issues/3507) (API): Hide internal attributes * [#3506](https://github.com/icinga/icinga2/issues/3506) (API): Original attributes list in IDO * [#3503](https://github.com/icinga/icinga2/issues/3503) (API): Log a warning message on unauthorized http request * [#3502](https://github.com/icinga/icinga2/issues/3502) (API): Use the API for "icinga2 console" * [#3498](https://github.com/icinga/icinga2/issues/3498) (DB IDO): DB IDO should provide its connected state via /v1/status * [#3488](https://github.com/icinga/icinga2/issues/3488) (API): Document that modified attributes require accept\_config for cluster/clients * [#3469](https://github.com/icinga/icinga2/issues/3469) (Configuration): Pretty-print arrays and dictionaries when converting them to strings * [#3463](https://github.com/icinga/icinga2/issues/3463) (API): Change object version to timestamps for diff updates on config sync * [#3452](https://github.com/icinga/icinga2/issues/3452) (Configuration): Provide keywords to retrieve the current file name at parse time * [#3435](https://github.com/icinga/icinga2/issues/3435) (API): Move /v1/\ to /v1/objects/\ * [#3432](https://github.com/icinga/icinga2/issues/3432) (API): Rename statusqueryhandler to objectqueryhandler * [#3419](https://github.com/icinga/icinga2/issues/3419) (API): Sanitize error status codes and messages * [#3414](https://github.com/icinga/icinga2/issues/3414): Make ConfigObject::{G,S}etField\(\) method public * [#3386](https://github.com/icinga/icinga2/issues/3386) (API): Add global status handler for the API * [#3357](https://github.com/icinga/icinga2/issues/3357) (API): Implement CSRF protection for the API * [#3354](https://github.com/icinga/icinga2/issues/3354) (API): Implement joins for status queries * [#3343](https://github.com/icinga/icinga2/issues/3343) (API): Implement a demo API client: Icinga Studio * [#3341](https://github.com/icinga/icinga2/issues/3341) (API): URL class improvements * [#3340](https://github.com/icinga/icinga2/issues/3340) (API): Add plural\_name field to /v1/types * [#3332](https://github.com/icinga/icinga2/issues/3332) (Configuration): Use an AST node for the 'library' keyword * [#3297](https://github.com/icinga/icinga2/issues/3297) (Configuration): Implement ignore\_on\_error keyword * [#3296](https://github.com/icinga/icinga2/issues/3296) (API): Rename config/modules to config/packages * [#3291](https://github.com/icinga/icinga2/issues/3291) (API): Remove debug messages in HttpRequest class * [#3290](https://github.com/icinga/icinga2/issues/3290): Add String::ToLower/ToUpper * [#3287](https://github.com/icinga/icinga2/issues/3287) (API): Add package attribute for ConfigObject and set its origin * [#3285](https://github.com/icinga/icinga2/issues/3285) (API): Implement support for restoring modified attributes * [#3283](https://github.com/icinga/icinga2/issues/3283) (API): Implement support for indexers in ConfigObject::RestoreAttribute * [#3282](https://github.com/icinga/icinga2/issues/3282): Implement Object\#clone and rename Array/Dictionary\#clone to shallow\_clone * [#3280](https://github.com/icinga/icinga2/issues/3280): Add override keyword for all relevant methods * [#3278](https://github.com/icinga/icinga2/issues/3278) (API): Figure out how to sync dynamically created objects inside the cluster * [#3277](https://github.com/icinga/icinga2/issues/3277) (API): Ensure that runtime config objects are persisted on disk * [#3272](https://github.com/icinga/icinga2/issues/3272): Implement the 'base' field for the Type class * [#3267](https://github.com/icinga/icinga2/issues/3267): Rename DynamicObject/DynamicType to ConfigObject/ConfigType * [#3240](https://github.com/icinga/icinga2/issues/3240): Implement support for attaching GDB to the Icinga process on crash * [#3238](https://github.com/icinga/icinga2/issues/3238) (API): Implement global modified attributes * [#3233](https://github.com/icinga/icinga2/issues/3233) (API): Implement support for . in modify\_attribute * [#3232](https://github.com/icinga/icinga2/issues/3232) (API): Remove GetModifiedAttributes/SetModifiedAttributes * [#3231](https://github.com/icinga/icinga2/issues/3231) (API): Re-implement events for attribute changes * [#3230](https://github.com/icinga/icinga2/issues/3230) (API): Validation for modified attributes * [#3203](https://github.com/icinga/icinga2/issues/3203) (Configuration): Setting global variables with i2tcl doesn't work * [#3197](https://github.com/icinga/icinga2/issues/3197) (API): Make Comments and Downtime types available as ConfigObject type in the API * [#3193](https://github.com/icinga/icinga2/issues/3193) (API): Update the url parsers behaviour * [#3177](https://github.com/icinga/icinga2/issues/3177) (API): Documentation for config management API * [#3173](https://github.com/icinga/icinga2/issues/3173) (API): Add real path sanity checks to provided file paths * [#3172](https://github.com/icinga/icinga2/issues/3172): String::Trim\(\) should return a new string rather than modifying the current string * [#3169](https://github.com/icinga/icinga2/issues/3169) (API): Implement support for X-HTTP-Method-Override * [#3168](https://github.com/icinga/icinga2/issues/3168): Add Array::FromVector\(\) method * [#3167](https://github.com/icinga/icinga2/issues/3167): Add exceptions for Utility::MkDir{,P} * [#3154](https://github.com/icinga/icinga2/issues/3154): Move url to /lib/remote from /lib/base * [#3144](https://github.com/icinga/icinga2/issues/3144): Register ServiceOK, ServiceWarning, HostUp, etc. as constants * [#3140](https://github.com/icinga/icinga2/issues/3140) (API): Implement base64 de- and encoder * [#3094](https://github.com/icinga/icinga2/issues/3094) (API): Implement ApiUser type * [#3093](https://github.com/icinga/icinga2/issues/3093) (API): Implement URL parser * [#3090](https://github.com/icinga/icinga2/issues/3090) (Graphite): New Graphite schema * [#3089](https://github.com/icinga/icinga2/issues/3089) (API): Implement support for filter\_vars * [#3083](https://github.com/icinga/icinga2/issues/3083) (API): Define RESTful url schema * [#3082](https://github.com/icinga/icinga2/issues/3082) (API): Implement support for HTTP * [#3065](https://github.com/icinga/icinga2/issues/3065): Allow comments when parsing JSON * [#3025](https://github.com/icinga/icinga2/issues/3025) (DB IDO): DB IDO/Livestatus: Add zone object table w/ endpoint members * [#2934](https://github.com/icinga/icinga2/issues/2934) (API): API Documentation * [#2933](https://github.com/icinga/icinga2/issues/2933) (API): Implement config file management commands * [#2932](https://github.com/icinga/icinga2/issues/2932) (API): Staging for configuration validation * [#2931](https://github.com/icinga/icinga2/issues/2931) (API): Support validating configuration changes * [#2930](https://github.com/icinga/icinga2/issues/2930) (API): Commands for adding and removing objects * [#2929](https://github.com/icinga/icinga2/issues/2929) (API): Multiple sources for zone configuration tree * [#2928](https://github.com/icinga/icinga2/issues/2928) (API): Implement support for writing configuration files * [#2927](https://github.com/icinga/icinga2/issues/2927) (API): Update modules to support adding and removing objects at runtime * [#2926](https://github.com/icinga/icinga2/issues/2926) (API): Dependency tracking for objects * [#2925](https://github.com/icinga/icinga2/issues/2925) (API): Disallow changes for certain config attributes at runtime * [#2923](https://github.com/icinga/icinga2/issues/2923) (API): Changelog for modified attributes * [#2921](https://github.com/icinga/icinga2/issues/2921) (API): API status queries * [#2918](https://github.com/icinga/icinga2/issues/2918) (API): API permissions * [#2917](https://github.com/icinga/icinga2/issues/2917) (API): Create default administrative user * [#2916](https://github.com/icinga/icinga2/issues/2916) (API): Password-based authentication for the API * [#2915](https://github.com/icinga/icinga2/issues/2915) (API): Certificate-based authentication for the API * [#2914](https://github.com/icinga/icinga2/issues/2914) (API): Enable the ApiListener by default * [#2913](https://github.com/icinga/icinga2/issues/2913) (API): Configuration file management for the API * [#2912](https://github.com/icinga/icinga2/issues/2912) (API): Runtime configuration for the API * [#2911](https://github.com/icinga/icinga2/issues/2911) (API): Add modified attribute support for the API * [#2910](https://github.com/icinga/icinga2/issues/2910) (API): Add commands \(actions\) for the API * [#2909](https://github.com/icinga/icinga2/issues/2909) (API): Implement status queries for the API * [#2908](https://github.com/icinga/icinga2/issues/2908) (API): Event stream support for the API * [#2907](https://github.com/icinga/icinga2/issues/2907) (API): Implement filters for the API * [#2906](https://github.com/icinga/icinga2/issues/2906) (API): Reflection support for the API * [#2904](https://github.com/icinga/icinga2/issues/2904) (API): Basic API framework * [#2901](https://github.com/icinga/icinga2/issues/2901) (Configuration): Implement sandbox mode for the config parser * [#2887](https://github.com/icinga/icinga2/issues/2887) (Configuration): Remove the ScopeCurrent constant * [#2857](https://github.com/icinga/icinga2/issues/2857): Avoid unnecessary dictionary lookups * [#2838](https://github.com/icinga/icinga2/issues/2838): Move implementation code from thpp files into separate files * [#2826](https://github.com/icinga/icinga2/issues/2826) (Configuration): Use DebugHint information when reporting validation errors * [#2814](https://github.com/icinga/icinga2/issues/2814): Add support for the C++11 keyword 'override' * [#2809](https://github.com/icinga/icinga2/issues/2809) (Configuration): Implement constructor-style casts * [#2788](https://github.com/icinga/icinga2/issues/2788) (Configuration): Refactor the startup process * [#2785](https://github.com/icinga/icinga2/issues/2785) (CLI): Implement support for libedit * [#2757](https://github.com/icinga/icinga2/issues/2757): Deprecate IcingaStatusWriter feature * [#2755](https://github.com/icinga/icinga2/issues/2755) (DB IDO): Implement support for CLIENT\_MULTI\_STATEMENTS * [#2741](https://github.com/icinga/icinga2/issues/2741) (DB IDO): Add support for current and current-1 db ido schema version * [#2740](https://github.com/icinga/icinga2/issues/2740) (DB IDO): Add embedded DB IDO version health check * [#2722](https://github.com/icinga/icinga2/issues/2722): Allow some of the Array and Dictionary methods to be inlined by the compiler * [#2514](https://github.com/icinga/icinga2/issues/2514): 'icinga2 console' should serialize temporary attributes \(rather than just config + state\) * [#2474](https://github.com/icinga/icinga2/issues/2474) (Graphite): graphite writer should pass "-" in host names and "." in perf data * [#2438](https://github.com/icinga/icinga2/issues/2438) (API): Add icinga, cluster, cluster-zone check information to the ApiListener status handler * [#2268](https://github.com/icinga/icinga2/issues/2268) (Configuration): Validators should be implemented in \(auto-generated\) native code ### Bug * [#3669](https://github.com/icinga/icinga2/issues/3669): Use notify\_one in WorkQueue::Enqueue * [#3667](https://github.com/icinga/icinga2/issues/3667): Utility::FormatErrorNumber fails when error message uses arguments * [#3649](https://github.com/icinga/icinga2/issues/3649) (DB IDO): Group memberships are not updated for runtime created objects * [#3648](https://github.com/icinga/icinga2/issues/3648) (API): API overwrites \(and then deletes\) config file when trying to create an object that already exists * [#3647](https://github.com/icinga/icinga2/issues/3647) (API): Don't allow users to set state attributes via PUT * [#3645](https://github.com/icinga/icinga2/issues/3645): Deadlock in MacroProcessor::EvaluateFunction * [#3635](https://github.com/icinga/icinga2/issues/3635): modify\_attribute: object cannot be cloned * [#3633](https://github.com/icinga/icinga2/issues/3633) (API): Detailed error message is missing when object creation via API fails * [#3632](https://github.com/icinga/icinga2/issues/3632) (API): API call doesn't fail when trying to use a template that doesn't exist * [#3625](https://github.com/icinga/icinga2/issues/3625): Improve location information for errors in API filters * [#3622](https://github.com/icinga/icinga2/issues/3622) (API): /v1/console should only use a single permission * [#3620](https://github.com/icinga/icinga2/issues/3620) (API): 'remove-comment' action does not support filters * [#3619](https://github.com/icinga/icinga2/issues/3619) (CLI): 'api setup' should create a user even when api feature is already enabled * [#3618](https://github.com/icinga/icinga2/issues/3618) (CLI): Autocompletion doesn't work in the debugger * [#3617](https://github.com/icinga/icinga2/issues/3617) (API): There's a variable called 'string' in filter expressions * [#3607](https://github.com/icinga/icinga2/issues/3607) (CLI): Broken build - unresolved external symbol "public: void \_\_thiscall icinga::ApiClient::ExecuteScript... * [#3602](https://github.com/icinga/icinga2/issues/3602) (DB IDO): Async mysql queries aren't logged in the debug log * [#3601](https://github.com/icinga/icinga2/issues/3601): Don't validate custom attributes that aren't strings * [#3600](https://github.com/icinga/icinga2/issues/3600): Crash in ConfigWriter::EmitIdentifier * [#3598](https://github.com/icinga/icinga2/issues/3598) (CLI): Spaces do not work in command arguments * [#3595](https://github.com/icinga/icinga2/issues/3595) (DB IDO): Change session\_token to integer timestamp * [#3593](https://github.com/icinga/icinga2/issues/3593): Fix indentation for Dictionary::ToString * [#3587](https://github.com/icinga/icinga2/issues/3587): Crash in ConfigWriter::GetKeywords * [#3586](https://github.com/icinga/icinga2/issues/3586) (Cluster): Circular reference between \*Connection and TlsStream objects * [#3583](https://github.com/icinga/icinga2/issues/3583) (API): Mismatch on {comment,downtime}\_id vs internal name in the API * [#3581](https://github.com/icinga/icinga2/issues/3581): CreatePipeOverlapped is not thread-safe * [#3579](https://github.com/icinga/icinga2/issues/3579): Figure out whether we need the Checkable attributes state\_raw, last\_state\_raw, hard\_state\_raw * [#3577](https://github.com/icinga/icinga2/issues/3577) (Plugins): Increase the default timeout for OS checks * [#3574](https://github.com/icinga/icinga2/issues/3574) (API): Plural name rule not treating edge case correcly * [#3572](https://github.com/icinga/icinga2/issues/3572) (API): IcingaStudio: Accessing non-ConfigObjects causes ugly exception * [#3569](https://github.com/icinga/icinga2/issues/3569) (API): Incorrect JSON-RPC message causes Icinga 2 to crash * [#3566](https://github.com/icinga/icinga2/issues/3566) (DB IDO): Unique constraint violation with multiple comment inserts in DB IDO * [#3558](https://github.com/icinga/icinga2/issues/3558) (DB IDO): IDO tries to execute empty UPDATE queries * [#3554](https://github.com/icinga/icinga2/issues/3554) (Configuration): Crash in IndexerExpression::GetReference when attempting to set an attribute on an object other than the current one * [#3551](https://github.com/icinga/icinga2/issues/3551) (Configuration): Line continuation is broken in 'icinga2 console' * [#3548](https://github.com/icinga/icinga2/issues/3548) (Configuration): Don't allow scripts to access FANoUserView attributes in sandbox mode * [#3546](https://github.com/icinga/icinga2/issues/3546) (Cluster): Improve error handling during log replay * [#3536](https://github.com/icinga/icinga2/issues/3536) (CLI): Improve --help output for the --log-level option * [#3535](https://github.com/icinga/icinga2/issues/3535) (CLI): "Command options" is empty when executing icinga2 without any argument. * [#3534](https://github.com/icinga/icinga2/issues/3534) (DB IDO): Custom variables aren't removed from the IDO database * [#3524](https://github.com/icinga/icinga2/issues/3524) (DB IDO): Changing a group's attributes causes duplicate rows in the icinga\_\*group\_members table * [#3517](https://github.com/icinga/icinga2/issues/3517): OpenBSD: hang during ConfigItem::ActivateItems\(\) in daemon startup * [#3514](https://github.com/icinga/icinga2/issues/3514) (CLI): Misleading wording in generated zones.conf * [#3501](https://github.com/icinga/icinga2/issues/3501) (API): restore\_attribute does not work in clusters * [#3489](https://github.com/icinga/icinga2/issues/3489) (API): Ensure that modified attributes work with clients with local config and no zone attribute * [#3485](https://github.com/icinga/icinga2/issues/3485) (API): Icinga2 API performance regression * [#3482](https://github.com/icinga/icinga2/issues/3482) (API): Version updates are not working properly * [#3468](https://github.com/icinga/icinga2/issues/3468) (CLI): icinga2 repository host add does not work * [#3462](https://github.com/icinga/icinga2/issues/3462): ConfigWriter::EmitValue should format floating point values properly * [#3461](https://github.com/icinga/icinga2/issues/3461) (API): Config sync does not set endpoint syncing and plays disconnect-sync ping-pong * [#3459](https://github.com/icinga/icinga2/issues/3459) (API): /v1/objects/\ returns an HTTP error when there are no objects of that type * [#3457](https://github.com/icinga/icinga2/issues/3457) (API): Config Sync shouldn't send updates for objects the client doesn't have access to * [#3451](https://github.com/icinga/icinga2/issues/3451) (API): Properly encode URLs in Icinga Studio * [#3448](https://github.com/icinga/icinga2/issues/3448) (API): Use a temporary file for modified-attributes.conf updates * [#3445](https://github.com/icinga/icinga2/issues/3445) (Configuration): ASCII NULs don't work in string values * [#3438](https://github.com/icinga/icinga2/issues/3438) (API): URL parser is cutting off last character * [#3434](https://github.com/icinga/icinga2/issues/3434) (API): PerfdataValue is not properly serialised in status queries * [#3433](https://github.com/icinga/icinga2/issues/3433) (API): Move the Collection status handler to /v1/status * [#3422](https://github.com/icinga/icinga2/issues/3422) (Configuration): Detect infinite recursion in user scripts * [#3411](https://github.com/icinga/icinga2/issues/3411) (API): API actions do not follow REST guidelines * [#3383](https://github.com/icinga/icinga2/issues/3383) (DB IDO): Add object\_id where clause for icinga\_downtimehistory * [#3345](https://github.com/icinga/icinga2/issues/3345) (API): Error handling in HttpClient/icinga-studio * [#3338](https://github.com/icinga/icinga2/issues/3338) (CLI): Unused variable console\_type in consolecommand.cpp * [#3336](https://github.com/icinga/icinga2/issues/3336) (API): Filtering by name doesn't work * [#3335](https://github.com/icinga/icinga2/issues/3335) (API): HTTP keep-alive does not work with .NET WebClient * [#3330](https://github.com/icinga/icinga2/issues/3330): Unused variable 'dobj' in configobject.tcpp * [#3328](https://github.com/icinga/icinga2/issues/3328) (Configuration): Don't parse config files for branches not taken * [#3315](https://github.com/icinga/icinga2/issues/3315) (Configuration): Crash in ConfigCompiler::RegisterZoneDir * [#3302](https://github.com/icinga/icinga2/issues/3302) (API): Implement support for '.' when persisting modified attributes * [#3301](https://github.com/icinga/icinga2/issues/3301): Fix formatting in mkclass * [#3264](https://github.com/icinga/icinga2/issues/3264) (API): Do not let API users create objects with invalid names * [#3250](https://github.com/icinga/icinga2/issues/3250) (API): Missing conf.d or zones.d cause parse failure * [#3248](https://github.com/icinga/icinga2/issues/3248): Crash during cluster log replay * [#3244](https://github.com/icinga/icinga2/issues/3244) (CLI): Color codes in console prompt break line editing * [#3242](https://github.com/icinga/icinga2/issues/3242) (CLI): Crash in ScriptFrame::~ScriptFrame * [#3227](https://github.com/icinga/icinga2/issues/3227) (CLI): console autocompletion should take into account parent classes' prototypes * [#3215](https://github.com/icinga/icinga2/issues/3215) (API): win32 build: S\_ISDIR is undefined * [#3205](https://github.com/icinga/icinga2/issues/3205) (Configuration): ScriptFrame's 'Self' attribute gets corrupted when an expression throws an exception * [#3202](https://github.com/icinga/icinga2/issues/3202) (Configuration): Operator - should not work with "" and numbers * [#3198](https://github.com/icinga/icinga2/issues/3198): Accessing field ID 0 \("prototype"\) fails * [#3182](https://github.com/icinga/icinga2/issues/3182) (API): Broken cluster config sync w/o include\_zones * [#3171](https://github.com/icinga/icinga2/issues/3171) (API): Problem with child nodes in http url registry * [#3138](https://github.com/icinga/icinga2/issues/3138) (CLI): 'node wizard/setup' should always generate new CN certificates * [#3131](https://github.com/icinga/icinga2/issues/3131) (DB IDO): Overflow in freshness\_threshold column \(smallint\) w/ DB IDO MySQL * [#3109](https://github.com/icinga/icinga2/issues/3109) (API): build failure: demo module * [#3087](https://github.com/icinga/icinga2/issues/3087) (DB IDO): Fix incorrect datatype for the check\_source column in icinga\_statehistory table * [#2974](https://github.com/icinga/icinga2/issues/2974) (Configuration): Remove incorrect 'ignore where' expression from 'ssh' apply example * [#2939](https://github.com/icinga/icinga2/issues/2939) (Cluster): Wrong vars changed handler in api events * [#2884](https://github.com/icinga/icinga2/issues/2884) (DB IDO): PostgreSQL schema sets default timestamps w/o time zone * [#2879](https://github.com/icinga/icinga2/issues/2879): Compiler warnings with latest HEAD 5ac5f98 * [#2870](https://github.com/icinga/icinga2/issues/2870) (DB IDO): pgsql driver does not have latest mysql changes synced * [#2863](https://github.com/icinga/icinga2/issues/2863) (Configuration): Crash in VMOps::FunctionCall * [#2850](https://github.com/icinga/icinga2/issues/2850) (Configuration): Validation fails even though field is not required * [#2824](https://github.com/icinga/icinga2/issues/2824) (DB IDO): Failed assertion in IdoMysqlConnection::FieldToEscapedString * [#2808](https://github.com/icinga/icinga2/issues/2808) (Configuration): Make default notifications include users from host.vars.notification.mail.users * [#2803](https://github.com/icinga/icinga2/issues/2803): Don't allow users to instantiate the StreamLogger class ### ITL * [#3584](https://github.com/icinga/icinga2/issues/3584) (ITL): Add ipv4/ipv6 only to tcp and http CheckCommand * [#3582](https://github.com/icinga/icinga2/issues/3582) (ITL): Add check command mysql * [#3578](https://github.com/icinga/icinga2/issues/3578) (ITL): Add check command negate * [#3532](https://github.com/icinga/icinga2/issues/3532) (ITL): 'dig\_lookup' custom attribute for the 'dig' check command isn't optional * [#3525](https://github.com/icinga/icinga2/issues/3525) (ITL): Ability to set port on SNMP Checks * [#3490](https://github.com/icinga/icinga2/issues/3490) (ITL): Add check command nginx\_status * [#2964](https://github.com/icinga/icinga2/issues/2964) (ITL): Move 'running\_kernel' check command to plugins-contrib 'operating system' section * [#2784](https://github.com/icinga/icinga2/issues/2784) (ITL): Move the base command templates into libmethods ### Documentation * [#3663](https://github.com/icinga/icinga2/issues/3663) (Documentation): Update wxWidgets documentation for Icinga Studio * [#3640](https://github.com/icinga/icinga2/issues/3640) (Documentation): Explain DELETE for config stages/packages * [#3638](https://github.com/icinga/icinga2/issues/3638) (Documentation): Documentation for /v1/types * [#3631](https://github.com/icinga/icinga2/issues/3631) (Documentation): Documentation for the script debugger * [#3630](https://github.com/icinga/icinga2/issues/3630) (Documentation): Explain variable names for joined objects in filter expressions * [#3629](https://github.com/icinga/icinga2/issues/3629) (Documentation): Documentation for /v1/console * [#3628](https://github.com/icinga/icinga2/issues/3628) (Documentation): Mention wxWidget \(optional\) requirement in INSTALL.md * [#3626](https://github.com/icinga/icinga2/issues/3626) (Documentation): Icinga 2 API Docs * [#3621](https://github.com/icinga/icinga2/issues/3621) (Documentation): Documentation should not reference real host names * [#3563](https://github.com/icinga/icinga2/issues/3563) (Documentation): Documentation: Reorganize Livestatus and alternative frontends * [#3547](https://github.com/icinga/icinga2/issues/3547) (Documentation): Incorrect attribute name in the documentation * [#3516](https://github.com/icinga/icinga2/issues/3516) (Documentation): Add documentation for apply+for in the language reference chapter * [#3511](https://github.com/icinga/icinga2/issues/3511) (Documentation): Escaping $ not documented * [#3500](https://github.com/icinga/icinga2/issues/3500) (Documentation): Add 'support' tracker to changelog.py * [#3477](https://github.com/icinga/icinga2/issues/3477) (Documentation): Remove duplicated text in section "Apply Notifications to Hosts and Services" * [#3426](https://github.com/icinga/icinga2/issues/3426) (Documentation): Add documentation for api-users.conf and app.conf * [#3281](https://github.com/icinga/icinga2/issues/3281) (Documentation): Document Object\#clone ### Support * [#3662](https://github.com/icinga/icinga2/issues/3662) (Packages): Download URL for NSClient++ is incorrect * [#3615](https://github.com/icinga/icinga2/issues/3615) (Packages): Update OpenSSL for the Windows builds * [#3614](https://github.com/icinga/icinga2/issues/3614) (Installation): Don't try to use --gc-sections on Solaris * [#3522](https://github.com/icinga/icinga2/issues/3522) (Packages): 'which' isn't available in a minimal CentOS container * [#3063](https://github.com/icinga/icinga2/issues/3063) (Installation): "-Wno-deprecated-register" compiler option breaks builds on SLES 11 * [#2893](https://github.com/icinga/icinga2/issues/2893) (Installation): icinga demo module can not be built * [#2858](https://github.com/icinga/icinga2/issues/2858) (Packages): Specify pidfile for status\_of\_proc in the init script * [#2802](https://github.com/icinga/icinga2/issues/2802) (Packages): Update OpenSSL for the Windows builds ## 2.3.11 (2015-10-20) ### Notes * Function for performing CIDR matches: cidr_match() * New methods: String#reverse and Array#reverse * New ITL command definitions: nwc_health, hpasm, squid, pgsql * Additional arguments for ITL command definitions: by_ssh, dig, pop, spop, imap, simap * Documentation updates * Various bugfixes ### Enhancement * [#3494](https://github.com/icinga/icinga2/issues/3494) (DB IDO): Add a debug log message for updating the program status table in DB IDO * [#3481](https://github.com/icinga/icinga2/issues/3481): New method: cidr\_match\(\) * [#3421](https://github.com/icinga/icinga2/issues/3421): Implement the Array\#reverse and String\#reverse methods * [#3327](https://github.com/icinga/icinga2/issues/3327): Implement a way for users to resolve commands+arguments in the same way Icinga does * [#3326](https://github.com/icinga/icinga2/issues/3326): escape\_shell\_arg\(\) method * [#2969](https://github.com/icinga/icinga2/issues/2969) (Metrics): Add timestamp support for OpenTsdbWriter ### Bug * [#3492](https://github.com/icinga/icinga2/issues/3492) (Cluster): Wrong connection log message for global zones * [#3491](https://github.com/icinga/icinga2/issues/3491): cidr\_match\(\) doesn't properly validate IP addresses * [#3487](https://github.com/icinga/icinga2/issues/3487) (Cluster): ApiListener::SyncRelayMessage doesn't send message to all zone members * [#3476](https://github.com/icinga/icinga2/issues/3476) (Compat): Missing Start call for base class in CheckResultReader * [#3475](https://github.com/icinga/icinga2/issues/3475) (Compat): Checkresultreader is unable to process host checks * [#3466](https://github.com/icinga/icinga2/issues/3466): "Not after" value overflows in X509 certificates on RHEL5 * [#3464](https://github.com/icinga/icinga2/issues/3464) (Cluster): Don't log messages we've already relayed to all relevant zones * [#3460](https://github.com/icinga/icinga2/issues/3460) (Metrics): Performance Data Labels including '=' will not be displayed correct * [#3454](https://github.com/icinga/icinga2/issues/3454): Percent character whitespace on Windows * [#3449](https://github.com/icinga/icinga2/issues/3449) (Cluster): Don't throw an exception when replaying the current replay log file * [#3446](https://github.com/icinga/icinga2/issues/3446): Deadlock in TlsStream::Close * [#3428](https://github.com/icinga/icinga2/issues/3428) (Configuration): config checker reports wrong error on apply for rules * [#3427](https://github.com/icinga/icinga2/issues/3427) (Configuration): Config parser problem with parenthesis and newlines * [#3423](https://github.com/icinga/icinga2/issues/3423) (Configuration): Remove unnecessary MakeLiteral calls in SetExpression::DoEvaluate * [#3417](https://github.com/icinga/icinga2/issues/3417) (Configuration): null + null should not be "" * [#3416](https://github.com/icinga/icinga2/issues/3416) (API): Problem with customvariable table update/insert queries * [#3373](https://github.com/icinga/icinga2/issues/3373) (Livestatus): Improve error message for socket errors in Livestatus * [#3324](https://github.com/icinga/icinga2/issues/3324) (Cluster): Deadlock in WorkQueue::Enqueue * [#3204](https://github.com/icinga/icinga2/issues/3204) (Configuration): String methods cannot be invoked on an empty string * [#3038](https://github.com/icinga/icinga2/issues/3038) (Livestatus): sending multiple Livestatus commands rejects all except the first * [#2568](https://github.com/icinga/icinga2/issues/2568) (Cluster): check cluster-zone returns wrong log lag ### ITL * [#3437](https://github.com/icinga/icinga2/issues/3437) (ITL): Add timeout argument for pop, spop, imap, simap commands * [#3407](https://github.com/icinga/icinga2/issues/3407) (ITL): Make check\_disk.exe CheckCommand Config more verbose * [#3399](https://github.com/icinga/icinga2/issues/3399) (ITL): expand check command dig * [#3394](https://github.com/icinga/icinga2/issues/3394) (ITL): Add ipv4/ipv6 only to nrpe CheckCommand * [#3385](https://github.com/icinga/icinga2/issues/3385) (ITL): Add check command pgsql * [#3382](https://github.com/icinga/icinga2/issues/3382) (ITL): Add check command squid * [#3235](https://github.com/icinga/icinga2/issues/3235) (ITL): check\_command for plugin check\_hpasm * [#3214](https://github.com/icinga/icinga2/issues/3214) (ITL): add check command for check\_nwc\_health ### Documentation * [#3479](https://github.com/icinga/icinga2/issues/3479) (Documentation): Improve timeperiod documentation * [#3478](https://github.com/icinga/icinga2/issues/3478) (Documentation): Broken table layout in chapter 20 * [#3436](https://github.com/icinga/icinga2/issues/3436) (Documentation): Clarify on cluster/client naming convention and add troubleshooting section * [#3430](https://github.com/icinga/icinga2/issues/3430) (Documentation): Find a better description for cluster communication requirements * [#3409](https://github.com/icinga/icinga2/issues/3409) (Documentation): Windows Check Update -\> Access denied * [#3408](https://github.com/icinga/icinga2/issues/3408) (Documentation): Improve documentation for check\_memory * [#3406](https://github.com/icinga/icinga2/issues/3406) (Documentation): Update graphing section in the docs * [#3402](https://github.com/icinga/icinga2/issues/3402) (Documentation): Update debug docs for core dumps and full backtraces * [#3351](https://github.com/icinga/icinga2/issues/3351) (Documentation): Command Execution Bridge: Use of same endpoint names in examples for a better understanding * [#3092](https://github.com/icinga/icinga2/issues/3092) (Documentation): Add FreeBSD setup to getting started ### Support * [#3379](https://github.com/icinga/icinga2/issues/3379) (Installation): Rather use unique SID when granting rights for folders in NSIS on Windows Client * [#3045](https://github.com/icinga/icinga2/issues/3045) (Packages): icinga2 ido mysql misspelled database username ## 2.3.10 (2015-09-05) ### Notes * Feature 9218: Use the command_endpoint name as check_source value if defined ### Enhancement * [#2985](https://github.com/icinga/icinga2/issues/2985): Use the command\_endpoint name as check\_source value if defined ### Bug * [#3369](https://github.com/icinga/icinga2/issues/3369): Missing zero padding for generated CA serial.txt * [#3352](https://github.com/icinga/icinga2/issues/3352): Wrong calculation for host compat state "UNREACHABLE" in DB IDO * [#3348](https://github.com/icinga/icinga2/issues/3348) (Cluster): Missing fix for reload on Windows in 2.3.9 * [#3325](https://github.com/icinga/icinga2/issues/3325): Nested "outer" macro calls fails on \(handled\) missing "inner" values * [#2811](https://github.com/icinga/icinga2/issues/2811) (DB IDO): String escape problem with PostgreSQL \>= 9.1 and standard\_conforming\_strings=on ## 2.3.9 (2015-08-26) ### Notes * Fix that the first SOFT state is recognized as second SOFT state * Implemented reload functionality for Windows * New ITL check commands * Documentation updates * Various other bugfixes ### Enhancement * [#3254](https://github.com/icinga/icinga2/issues/3254) (Livestatus): Use an empty dictionary for the 'this' scope when executing commands with Livestatus * [#3253](https://github.com/icinga/icinga2/issues/3253): Implement the Dictionary\#keys method * [#3206](https://github.com/icinga/icinga2/issues/3206): Implement Dictionary\#get and Array\#get * [#3170](https://github.com/icinga/icinga2/issues/3170) (Configuration): Adding "-r" parameter to the check\_load command for dividing the load averages by the number of CPUs. ### Bug * [#3305](https://github.com/icinga/icinga2/issues/3305) (Configuration): Icinga2 - too many open files - Exception * [#3299](https://github.com/icinga/icinga2/issues/3299): Utility::Glob on Windows doesn't support wildcards in all but the last path component * [#3292](https://github.com/icinga/icinga2/issues/3292): Serial number field is not properly initialized for CA certificates * [#3279](https://github.com/icinga/icinga2/issues/3279) (DB IDO): Add missing category for IDO query * [#3266](https://github.com/icinga/icinga2/issues/3266) (Plugins): Default disk checks on Windows fail because check\_disk doesn't support -K * [#3260](https://github.com/icinga/icinga2/issues/3260): First SOFT state is recognized as second SOFT state * [#3255](https://github.com/icinga/icinga2/issues/3255) (Cluster): Warning about invalid API function icinga::Hello * [#3241](https://github.com/icinga/icinga2/issues/3241): Agent freezes when the check returns massive output * [#3222](https://github.com/icinga/icinga2/issues/3222) (Configuration): Dict initializer incorrectly re-initializes field that is set to an empty string * [#3211](https://github.com/icinga/icinga2/issues/3211) (Configuration): Operator + is inconsistent when used with empty and non-empty strings * [#3200](https://github.com/icinga/icinga2/issues/3200) (CLI): icinga2 node wizard don't take zone\_name input * [#3199](https://github.com/icinga/icinga2/issues/3199): Trying to set a field for a non-object instance fails * [#3196](https://github.com/icinga/icinga2/issues/3196) (Cluster): Add log for missing EventCommand for command\_endpoints * [#3194](https://github.com/icinga/icinga2/issues/3194): Set correct X509 version for certificates * [#3149](https://github.com/icinga/icinga2/issues/3149) (CLI): missing config warning on empty port in endpoints * [#3010](https://github.com/icinga/icinga2/issues/3010) (Cluster): cluster check w/ immediate parent and child zone endpoints * [#2867](https://github.com/icinga/icinga2/issues/2867): Missing DEL\_DOWNTIME\_BY\_HOST\_NAME command required by Classic UI 1.x * [#2352](https://github.com/icinga/icinga2/issues/2352) (Cluster): Reload does not work on Windows ### ITL * [#3320](https://github.com/icinga/icinga2/issues/3320) (ITL): Add new arguments openvmtools for Open VM Tools * [#3313](https://github.com/icinga/icinga2/issues/3313) (ITL): add check command nscp-local-counter * [#3312](https://github.com/icinga/icinga2/issues/3312) (ITL): fix check command nscp-local * [#3265](https://github.com/icinga/icinga2/issues/3265) (ITL): check\_command interfaces option match\_aliases has to be boolean * [#3219](https://github.com/icinga/icinga2/issues/3219) (ITL): snmpv3 CheckCommand section improved * [#3213](https://github.com/icinga/icinga2/issues/3213) (ITL): add check command for check\_mailq * [#3208](https://github.com/icinga/icinga2/issues/3208) (ITL): Add check\_jmx4perl to ITL * [#3186](https://github.com/icinga/icinga2/issues/3186) (ITL): check\_command for plugin check\_clamd * [#3164](https://github.com/icinga/icinga2/issues/3164) (ITL): Add check\_redis to ITL * [#3162](https://github.com/icinga/icinga2/issues/3162) (ITL): Add check\_yum to ITL * [#3111](https://github.com/icinga/icinga2/issues/3111) (ITL): CheckCommand for check\_interfaces ### Documentation * [#3319](https://github.com/icinga/icinga2/issues/3319) (Documentation): Duplicate severity type in the documentation for SyslogLogger * [#3308](https://github.com/icinga/icinga2/issues/3308) (Documentation): Fix global Zone example to "Global Configuration Zone for Templates" * [#3262](https://github.com/icinga/icinga2/issues/3262) (Documentation): typo in docs * [#3166](https://github.com/icinga/icinga2/issues/3166) (Documentation): Update gdb pretty printer docs w/ Python 3 ### Support * [#3298](https://github.com/icinga/icinga2/issues/3298) (Packages): Don't re-download NSCP for every build * [#3239](https://github.com/icinga/icinga2/issues/3239) (Packages): missing check\_perfmon.exe * [#3216](https://github.com/icinga/icinga2/issues/3216) (Tests): Build fix for Boost 1.59 ## 2.3.8 (2015-07-21) ### Notes * Bugfixes ### Bug * [#3160](https://github.com/icinga/icinga2/issues/3160) (Metrics): Escaping does not work for OpenTSDB perfdata plugin * [#3151](https://github.com/icinga/icinga2/issues/3151) (DB IDO): DB IDO: Do not update endpointstatus table on config updates * [#3120](https://github.com/icinga/icinga2/issues/3120) (Configuration): Don't allow "ignore where" for groups when there's no "assign where" ### ITL * [#3161](https://github.com/icinga/icinga2/issues/3161) (ITL): checkcommand disk does not check free inode - check\_disk * [#3152](https://github.com/icinga/icinga2/issues/3152) (ITL): Wrong parameter for CheckCommand "ping-common-windows" ## 2.3.7 (2015-07-15) ### Notes * Bugfixes ### Bug * [#3148](https://github.com/icinga/icinga2/issues/3148): Missing lock in ScriptUtils::Union * [#3147](https://github.com/icinga/icinga2/issues/3147): Assertion failed in icinga::ScriptUtils::Intersection * [#3136](https://github.com/icinga/icinga2/issues/3136) (DB IDO): DB IDO: endpoint\* tables are cleared on reload causing constraint violations * [#3134](https://github.com/icinga/icinga2/issues/3134): Incorrect return value for the macro\(\) function * [#3114](https://github.com/icinga/icinga2/issues/3114) (Configuration): Config parser ignores "ignore" in template definition * [#3061](https://github.com/icinga/icinga2/issues/3061) (Cluster): Selective cluster reconnecting breaks client communication ### Documentation * [#3142](https://github.com/icinga/icinga2/issues/3142) (Documentation): Enhance troubleshooting ssl errors & cluster replay log * [#3135](https://github.com/icinga/icinga2/issues/3135) (Documentation): Wrong formatting in DB IDO extensions docs ## 2.3.6 (2015-07-08) ### Notes * Require openssl1 on sles11sp3 from Security Module repository * Bug in SLES 11's OpenSSL version 0.9.8j preventing verification of generated certificates. * Re-create these certificates with 2.3.6 linking against openssl1 (cli command or CSR auto-signing). * ITL: Add ldap, ntp_peer, mongodb and elasticsearch CheckCommand definitions * Bugfixes ### Bug * [#3118](https://github.com/icinga/icinga2/issues/3118) (Cluster): Generated certificates cannot be verified w/ openssl 0.9.8j on SLES 11 * [#3098](https://github.com/icinga/icinga2/issues/3098) (Cluster): Add log message for discarded cluster events \(e.g. from unauthenticated clients\) * [#3097](https://github.com/icinga/icinga2/issues/3097): Fix stability issues in the TlsStream/Stream classes * [#3088](https://github.com/icinga/icinga2/issues/3088) (Cluster): Windows client w/ command\_endpoint broken with $nscp\_path$ and NscpPath detection * [#3084](https://github.com/icinga/icinga2/issues/3084) (CLI): node setup: indent accept\_config and accept\_commands * [#3074](https://github.com/icinga/icinga2/issues/3074) (Notifications): Functions can't be specified as command arguments * [#2979](https://github.com/icinga/icinga2/issues/2979) (CLI): port empty when using icinga2 node wizard ### ITL * [#3132](https://github.com/icinga/icinga2/issues/3132) (ITL): new options for smtp CheckCommand * [#3125](https://github.com/icinga/icinga2/issues/3125) (ITL): Add new options for ntp\_time CheckCommand * [#3110](https://github.com/icinga/icinga2/issues/3110) (ITL): Add ntp\_peer CheckCommand * [#3103](https://github.com/icinga/icinga2/issues/3103) (ITL): itl/plugins-contrib.d/\*.conf should point to PluginContribDir * [#3091](https://github.com/icinga/icinga2/issues/3091) (ITL): Incorrect check\_ping.exe parameter in the ITL * [#3066](https://github.com/icinga/icinga2/issues/3066) (ITL): snmpv3 CheckCommand: Add possibility to set securityLevel * [#3064](https://github.com/icinga/icinga2/issues/3064) (ITL): Add elasticsearch checkcommand to itl * [#3031](https://github.com/icinga/icinga2/issues/3031) (ITL): Missing 'snmp\_is\_cisco' in Manubulon snmp-memory command definition * [#3002](https://github.com/icinga/icinga2/issues/3002) (ITL): Incorrect variable name in the ITL * [#2975](https://github.com/icinga/icinga2/issues/2975) (ITL): Add "mongodb" CheckCommand definition * [#2963](https://github.com/icinga/icinga2/issues/2963) (ITL): Add "ldap" CheckCommand for "check\_ldap" plugin ### Documentation * [#3126](https://github.com/icinga/icinga2/issues/3126) (Documentation): Update getting started for Debian Jessie * [#3108](https://github.com/icinga/icinga2/issues/3108) (Documentation): wrong default port documentated for nrpe * [#3099](https://github.com/icinga/icinga2/issues/3099) (Documentation): Missing openssl verify in cluster troubleshooting docs * [#3096](https://github.com/icinga/icinga2/issues/3096) (Documentation): Documentation for checks in an HA zone is wrong * [#3086](https://github.com/icinga/icinga2/issues/3086) (Documentation): Wrong file reference in README.md * [#3085](https://github.com/icinga/icinga2/issues/3085) (Documentation): Merge documentation fixes from GitHub * [#1793](https://github.com/icinga/icinga2/issues/1793) (Documentation): add pagerduty notification documentation ### Support * [#3123](https://github.com/icinga/icinga2/issues/3123) (Packages): Require gcc47-c++ on sles11 from SLES software development kit repository * [#3122](https://github.com/icinga/icinga2/issues/3122) (Packages): mysql-devel is not available in sles11sp3 * [#3081](https://github.com/icinga/icinga2/issues/3081) (Installation): changelog.py: Allow to define project, make custom\_fields and changes optional * [#3073](https://github.com/icinga/icinga2/issues/3073) (Installation): Enhance changelog.py with wordpress blogpost output * [#2651](https://github.com/icinga/icinga2/issues/2651) (Packages): Add Icinga 2 to Chocolatey Windows Repository ## 2.3.5 (2015-06-17) ### Notes * NSClient++ is now bundled with the Windows setup wizard and can optionally be installed * Windows Wizard: "include " is set by default * Windows Wizard: Add update mode * Plugins: Add check_perfmon plugin for Windows * ITL: Add CheckCommand objects for Windows plugins ("include ") * ITL: Add CheckCommand definitions for "mongodb", "iftraffic", "disk_smb" * ITL: Add arguments to CheckCommands "dns", "ftp", "tcp", "nscp" ### Enhancement * [#3009](https://github.com/icinga/icinga2/issues/3009) (Configuration): Add the --load-all and --log options for nscp-local * [#3008](https://github.com/icinga/icinga2/issues/3008) (Configuration): Include \ by default on Windows * [#2971](https://github.com/icinga/icinga2/issues/2971) (Metrics): Add timestamp support for PerfdataWriter * [#2817](https://github.com/icinga/icinga2/issues/2817) (Configuration): Add CheckCommand objects for Windows plugins * [#2794](https://github.com/icinga/icinga2/issues/2794) (Plugins): Add check\_perfmon plugin for Windows ### Bug * [#3051](https://github.com/icinga/icinga2/issues/3051) (Plugins): plugins-contrib.d/databases.conf: wrong argument for mssql\_health * [#3043](https://github.com/icinga/icinga2/issues/3043) (Compat): Multiline vars are broken in objects.cache output * [#3039](https://github.com/icinga/icinga2/issues/3039) (Compat): Multi line output not correctly handled from compat channels * [#3007](https://github.com/icinga/icinga2/issues/3007) (Configuration): Disk and 'icinga' services are missing in the default Windows config * [#3006](https://github.com/icinga/icinga2/issues/3006) (Configuration): Some checks in the default Windows configuration fail * [#2986](https://github.com/icinga/icinga2/issues/2986) (DB IDO): Missing custom attributes in backends if name is equal to object attribute * [#2952](https://github.com/icinga/icinga2/issues/2952) (DB IDO): Incorrect type and state filter mapping for User objects in DB IDO * [#2951](https://github.com/icinga/icinga2/issues/2951) (DB IDO): Downtimes are always "fixed" * [#2945](https://github.com/icinga/icinga2/issues/2945) (DB IDO): Possible DB deadlock * [#2940](https://github.com/icinga/icinga2/issues/2940) (Configuration): node update-config reports critical and warning * [#2935](https://github.com/icinga/icinga2/issues/2935) (Configuration): WIN: syslog is not an enable-able feature in windows * [#2894](https://github.com/icinga/icinga2/issues/2894) (DB IDO): Wrong timestamps w/ historical data replay in DB IDO * [#2839](https://github.com/icinga/icinga2/issues/2839) (CLI): Node wont connect properly to master if host is is not set for Endpoint on new installs * [#2836](https://github.com/icinga/icinga2/issues/2836): Icinga2 --version: Error showing Distribution * [#2819](https://github.com/icinga/icinga2/issues/2819) (Configuration): Syntax Highlighting: host.address vs host.add ### ITL * [#3019](https://github.com/icinga/icinga2/issues/3019) (ITL): Add 'iftraffic' to plugins-contrib check command definitions * [#3003](https://github.com/icinga/icinga2/issues/3003) (ITL): Add 'disk\_smb' Plugin CheckCommand definition * [#2959](https://github.com/icinga/icinga2/issues/2959) (ITL): 'disk': wrong order of threshold command arguments * [#2956](https://github.com/icinga/icinga2/issues/2956) (ITL): Add arguments to "tcp" CheckCommand * [#2955](https://github.com/icinga/icinga2/issues/2955) (ITL): Add arguments to "ftp" CheckCommand * [#2954](https://github.com/icinga/icinga2/issues/2954) (ITL): Add arguments to "dns" CheckCommand * [#2949](https://github.com/icinga/icinga2/issues/2949) (ITL): Add 'check\_drivesize' as nscp-local check command * [#2938](https://github.com/icinga/icinga2/issues/2938) (ITL): Add SHOWALL to NSCP Checkcommand * [#2880](https://github.com/icinga/icinga2/issues/2880) (ITL): Including \ on Linux fails with unregistered function ### Documentation * [#3072](https://github.com/icinga/icinga2/issues/3072) (Documentation): Documentation: Move configuration before advanced topics * [#3069](https://github.com/icinga/icinga2/issues/3069) (Documentation): Enhance cluster docs with HA command\_endpoints * [#3068](https://github.com/icinga/icinga2/issues/3068) (Documentation): Enhance cluster/client troubleshooting * [#3062](https://github.com/icinga/icinga2/issues/3062) (Documentation): Documentation: Update the link to register a new Icinga account * [#3059](https://github.com/icinga/icinga2/issues/3059) (Documentation): Documentation: Typo * [#3057](https://github.com/icinga/icinga2/issues/3057) (Documentation): Documentation: Extend Custom Attributes with the boolean type * [#3056](https://github.com/icinga/icinga2/issues/3056) (Documentation): Wrong service table attributes in Livestatus documentation * [#3055](https://github.com/icinga/icinga2/issues/3055) (Documentation): Documentation: Typo * [#3049](https://github.com/icinga/icinga2/issues/3049) (Documentation): Update documentation for escape sequences * [#3036](https://github.com/icinga/icinga2/issues/3036) (Documentation): Explain string concatenation in objects by real-world example * [#3035](https://github.com/icinga/icinga2/issues/3035) (Documentation): Use a more simple example for passing command parameters * [#3033](https://github.com/icinga/icinga2/issues/3033) (Documentation): Add local variable scope for \*Command to documentation \(host, service, etc\) * [#3032](https://github.com/icinga/icinga2/issues/3032) (Documentation): Add typeof in 'assign/ignore where' expression as example * [#3030](https://github.com/icinga/icinga2/issues/3030) (Documentation): Add examples for function usage in "set\_if" and "command" attributes * [#3024](https://github.com/icinga/icinga2/issues/3024) (Documentation): Best practices: cluster config sync * [#3017](https://github.com/icinga/icinga2/issues/3017) (Documentation): Update service apply for documentation * [#3015](https://github.com/icinga/icinga2/issues/3015) (Documentation): Typo in Configuration Best Practice * [#2966](https://github.com/icinga/icinga2/issues/2966) (Documentation): Include Windows support details in the documentation * [#2965](https://github.com/icinga/icinga2/issues/2965) (Documentation): ITL Documentation: Add a link for passing custom attributes as command parameters * [#2950](https://github.com/icinga/icinga2/issues/2950) (Documentation): Missing "\)" in last Apply Rules example * [#2279](https://github.com/icinga/icinga2/issues/2279) (Documentation): Add documentation and CheckCommands for the windows plugins ### Support * [#3016](https://github.com/icinga/icinga2/issues/3016) (Installation): Wrong permission etc on windows * [#3011](https://github.com/icinga/icinga2/issues/3011) (Installation): Add support for installing NSClient++ in the Icinga 2 Windows wizard * [#3005](https://github.com/icinga/icinga2/issues/3005) (Installation): Determine NSClient++ installation path using MsiGetComponentPath * [#3004](https://github.com/icinga/icinga2/issues/3004) (Installation): --scm-installs fails when the service is already installed * [#2994](https://github.com/icinga/icinga2/issues/2994) (Installation): Bundle NSClient++ in Windows Installer * [#2973](https://github.com/icinga/icinga2/issues/2973) (Packages): SPEC: Give group write permissions for perfdata dir * [#2451](https://github.com/icinga/icinga2/issues/2451) (Installation): Extend Windows installer with an update mode ## 2.3.4 (2015-04-20) ### Notes * ITL: Check commands for various databases * Improve validation messages for time periods * Update max_check_attempts in generic-{host,service} templates * Update logrotate configuration * Bugfixes ### Enhancement * [#2841](https://github.com/icinga/icinga2/issues/2841): Improve timeperiod validation error messages * [#2791](https://github.com/icinga/icinga2/issues/2791) (Cluster): Agent Wizard: add options for API defaults ### Bug * [#2903](https://github.com/icinga/icinga2/issues/2903) (Configuration): custom attributes with recursive macro function calls causing sigabrt * [#2898](https://github.com/icinga/icinga2/issues/2898) (CLI): troubleshoot truncates crash reports * [#2886](https://github.com/icinga/icinga2/issues/2886): Acknowledging problems w/ expire time does not add the expiry information to the related comment for IDO and compat * [#2883](https://github.com/icinga/icinga2/issues/2883) (Notifications): Multiple log messages w/ "Attempting to send notifications for notification object" * [#2882](https://github.com/icinga/icinga2/issues/2882) (DB IDO): scheduled\_downtime\_depth column is not reset when a downtime ends or when a downtime is being removed * [#2881](https://github.com/icinga/icinga2/issues/2881) (DB IDO): Downtimes which have been triggered are not properly recorded in the database * [#2878](https://github.com/icinga/icinga2/issues/2878) (DB IDO): Don't update scheduleddowntime table w/ trigger\_time column when only adding a downtime * [#2855](https://github.com/icinga/icinga2/issues/2855): Fix complexity class for Dictionary::Get * [#2853](https://github.com/icinga/icinga2/issues/2853) (CLI): Node wizard should only accept 'y', 'n', 'Y' and 'N' as answers for boolean questions * [#2842](https://github.com/icinga/icinga2/issues/2842) (Configuration): Default max\_check\_attempts should be lower for hosts than for services * [#2840](https://github.com/icinga/icinga2/issues/2840) (Configuration): Validation errors for time ranges which span the DST transition * [#2827](https://github.com/icinga/icinga2/issues/2827) (Configuration): logrotate does not work * [#2801](https://github.com/icinga/icinga2/issues/2801) (Cluster): command\_endpoint check\_results are not replicated to other endpoints in the same zone ### ITL * [#2891](https://github.com/icinga/icinga2/issues/2891) (ITL): web.conf is not in the RPM package * [#2890](https://github.com/icinga/icinga2/issues/2890) (ITL): check\_disk order of command arguments * [#2834](https://github.com/icinga/icinga2/issues/2834) (ITL): Add arguments to the UPS check * [#2770](https://github.com/icinga/icinga2/issues/2770) (ITL): Add database plugins to ITL ### Documentation * [#2902](https://github.com/icinga/icinga2/issues/2902) (Documentation): Documentation: set\_if usage with boolean values and functions * [#2876](https://github.com/icinga/icinga2/issues/2876) (Documentation): Typo in graphite feature enable documentation * [#2868](https://github.com/icinga/icinga2/issues/2868) (Documentation): Fix a typo * [#2843](https://github.com/icinga/icinga2/issues/2843) (Documentation): Add explanatory note for Icinga2 client documentation * [#2837](https://github.com/icinga/icinga2/issues/2837) (Documentation): Fix a minor markdown error * [#2832](https://github.com/icinga/icinga2/issues/2832) (Documentation): Reword documentation of check\_address ### Support * [#2888](https://github.com/icinga/icinga2/issues/2888) (Installation): Vim syntax: Match groups before host/service/user objects * [#2852](https://github.com/icinga/icinga2/issues/2852) (Installation): Windows Build: Flex detection * [#2793](https://github.com/icinga/icinga2/issues/2793) (Packages): logrotate doesn't work on Ubuntu ## 2.3.3 (2015-03-26) ### Notes * New function: parse_performance_data * Include more details in --version * Improve documentation * Bugfixes ### Enhancement * [#2771](https://github.com/icinga/icinga2/issues/2771): Include more details in --version * [#2743](https://github.com/icinga/icinga2/issues/2743): New function: parse\_performance\_data * [#2737](https://github.com/icinga/icinga2/issues/2737) (Notifications): Show state/type filter names in notice/debug log ### Bug * [#2828](https://github.com/icinga/icinga2/issues/2828): Array in command arguments doesn't work * [#2818](https://github.com/icinga/icinga2/issues/2818) (Configuration): Local variables in "apply for" are overridden * [#2816](https://github.com/icinga/icinga2/issues/2816) (CLI): Segmentation fault when executing "icinga2 pki new-cert" * [#2812](https://github.com/icinga/icinga2/issues/2812) (Configuration): Return doesn't work inside loops * [#2807](https://github.com/icinga/icinga2/issues/2807) (Configuration): Figure out why command validators are not triggered * [#2778](https://github.com/icinga/icinga2/issues/2778) (Configuration): object Notification + apply Service fails with error "...refers to service which doesn't exist" * [#2772](https://github.com/icinga/icinga2/issues/2772) (Plugins): Plugin "check\_http" is missing in Windows environments * [#2768](https://github.com/icinga/icinga2/issues/2768) (Configuration): Add missing keywords in the syntax highlighting files * [#2760](https://github.com/icinga/icinga2/issues/2760): Don't ignore extraneous arguments for functions * [#2753](https://github.com/icinga/icinga2/issues/2753) (DB IDO): Don't update custom vars for each status update * [#2752](https://github.com/icinga/icinga2/issues/2752): startup.log broken when the DB schema needs an update * [#2749](https://github.com/icinga/icinga2/issues/2749) (Configuration): Missing config validator for command arguments 'set\_if' * [#2718](https://github.com/icinga/icinga2/issues/2718) (Configuration): Update syntax highlighting for 2.3 features * [#2557](https://github.com/icinga/icinga2/issues/2557) (Configuration): Improve error message for invalid field access * [#2548](https://github.com/icinga/icinga2/issues/2548) (Configuration): Fix VIM syntax highlighting for comments ### ITL * [#2823](https://github.com/icinga/icinga2/issues/2823) (ITL): wrong 'dns\_lookup' custom attribute default in command-plugins.conf * [#2799](https://github.com/icinga/icinga2/issues/2799) (ITL): Add "random" CheckCommand for test and demo purposes ### Documentation * [#2825](https://github.com/icinga/icinga2/issues/2825) (Documentation): Fix incorrect perfdata templates in the documentation * [#2806](https://github.com/icinga/icinga2/issues/2806) (Documentation): Move release info in INSTALL.md into a separate file * [#2779](https://github.com/icinga/icinga2/issues/2779) (Documentation): Correct HA documentation * [#2777](https://github.com/icinga/icinga2/issues/2777) (Documentation): Typo and invalid example in the runtime macro documentation * [#2776](https://github.com/icinga/icinga2/issues/2776) (Documentation): Remove prompt to create a TicketSalt from the wizard * [#2775](https://github.com/icinga/icinga2/issues/2775) (Documentation): Explain processing logic/order of apply rules with for loops * [#2774](https://github.com/icinga/icinga2/issues/2774) (Documentation): Revamp migration documentation * [#2773](https://github.com/icinga/icinga2/issues/2773) (Documentation): Typo in doc library-reference * [#2765](https://github.com/icinga/icinga2/issues/2765) (Documentation): Fix a typo in the documentation of ICINGA2\_WITH\_MYSQL and ICINGA2\_WITH\_PGSQL * [#2756](https://github.com/icinga/icinga2/issues/2756) (Documentation): Add "access objects at runtime" examples to advanced section * [#2738](https://github.com/icinga/icinga2/issues/2738) (Documentation): Update documentation for "apply for" rules * [#2501](https://github.com/icinga/icinga2/issues/2501) (Documentation): Re-order the object types in alphabetical order ### Support * [#2762](https://github.com/icinga/icinga2/issues/2762) (Installation): Flex version check does not reject unsupported versions * [#2761](https://github.com/icinga/icinga2/issues/2761) (Installation): Build warnings with CMake 3.1.3 ## 2.3.2 (2015-03-12) ### Notes * Bugfixes ### Bug * [#2747](https://github.com/icinga/icinga2/issues/2747): Log message for cli commands breaks the init script ## 2.3.1 (2015-03-12) ### Notes * Bugfixes Please note that this version fixes the default thresholds for the disk check which were inadvertently broken in 2.3.0; if you're using percent-based custom thresholds you will need to add the '%' sign to your custom attributes ### Enhancement * [#2717](https://github.com/icinga/icinga2/issues/2717) (Configuration): Implement String\#contains ### Bug * [#2739](https://github.com/icinga/icinga2/issues/2739): Crash in Dependency::Stop * [#2736](https://github.com/icinga/icinga2/issues/2736): Fix formatting for the GDB stacktrace * [#2735](https://github.com/icinga/icinga2/issues/2735): Make sure that the /var/log/icinga2/crash directory exists * [#2731](https://github.com/icinga/icinga2/issues/2731) (Configuration): Config validation fail because of unexpected new-line * [#2727](https://github.com/icinga/icinga2/issues/2727) (Cluster): Api heartbeat message response time problem * [#2716](https://github.com/icinga/icinga2/issues/2716) (CLI): Missing program name in 'icinga2 --version' * [#2672](https://github.com/icinga/icinga2/issues/2672): Kill signal sent only to check process, not whole process group ### ITL * [#2483](https://github.com/icinga/icinga2/issues/2483) (ITL): Fix check\_disk thresholds: make sure partitions are the last arguments ### Documentation * [#2732](https://github.com/icinga/icinga2/issues/2732) (Documentation): Update documentation for DB IDO HA Run-Once * [#2728](https://github.com/icinga/icinga2/issues/2728) (Documentation): Fix check\_disk default thresholds and document the change of unit ### Support * [#2742](https://github.com/icinga/icinga2/issues/2742) (Packages): Debian packages do not create /var/log/icinga2/crash ## 2.3.0 (2015-03-10) ### Notes * Improved configuration validation * Unnecessary escapes are no longer permitted (e.g. \') * Dashes are no longer permitted in identifier names (as their semantics are ambiguous) * Unused values are detected (e.g. { "-M" }) * Validation for time ranges has been improved * Additional validation rules for some object types (Notification and User) * New language features * Implement a separate type for boolean values * Support for user-defined functions * Support for conditional statements (if/else) * Support for 'for' and 'while' loops * Support for local variables using the 'var' keyword * New operators: % (modulo), ^ (xor), - (unary minus) and + (unary plus) * Implemented prototype-based methods for most built-in types (e.g. [ 3, 2 ].sort()) * Explicit access to local and global variables using the 'locals' and 'globals' keywords * Changed the order in which filters are evaluated for apply rules with 'for' * Make type objects accessible as global variables * Support for using functions in custom attributes * Access objects and their runtime attributes in functions (e.g. get_host(NodeName).state) * ITL improvements * Additional check commands were added to the ITL * Additional arguments for existing check commands * CLI improvements * Add the 'icinga2 console' CLI command which can be used to test expressions * Add the 'icinga2 troubleshoot' CLI command for collecting troubleshooting information * Performance improvements for the 'icinga2 node update-config' CLI command * Implement argument auto-completion for short options (e.g. daemon -c) * 'node setup' and 'node wizard' create backups for existing certificate files * Add ignore_soft_states option for Dependency object configuration * Fewer threads are used for socket I/O * Flapping detection for hosts and services is disabled by default * Added support for OpenTSDB * New Livestatus tables: hostsbygroup, servicesbygroup, servicesbyhostgroup * Include GDB backtrace in crash reports * Various documentation improvements * Solved a number of issues where cluster instances would not reconnect after intermittent connection problems * A lot of other, minor changes * [DB IDO schema upgrade](17-upgrading-icinga-2.md#upgrading-icinga-2) to `1.13.0` required! ### Enhancement * [#2704](https://github.com/icinga/icinga2/issues/2704): Support the SNI TLS extension * [#2702](https://github.com/icinga/icinga2/issues/2702): Add validator for time ranges in ScheduledDowntime objects * [#2701](https://github.com/icinga/icinga2/issues/2701): Remove macro argument for IMPL\_TYPE\_LOOKUP * [#2696](https://github.com/icinga/icinga2/issues/2696): Include GDB backtrace in crash reports * [#2678](https://github.com/icinga/icinga2/issues/2678) (Configuration): Add support for else-if * [#2663](https://github.com/icinga/icinga2/issues/2663) (Livestatus): Change Livestatus query log level to 'notice' * [#2657](https://github.com/icinga/icinga2/issues/2657) (Cluster): Show slave lag for the cluster-zone check * [#2635](https://github.com/icinga/icinga2/issues/2635) (Configuration): introduce time dependent variable values * [#2634](https://github.com/icinga/icinga2/issues/2634) (Cluster): Add the ability to use a CA certificate as a way of verifying hosts for CSR autosigning * [#2609](https://github.com/icinga/icinga2/issues/2609): udp check command is missing arguments. * [#2604](https://github.com/icinga/icinga2/issues/2604) (CLI): Backup certificate files in 'node setup' * [#2601](https://github.com/icinga/icinga2/issues/2601) (Configuration): Implement continue/break keywords * [#2600](https://github.com/icinga/icinga2/issues/2600) (Configuration): Implement support for Json.encode and Json.decode * [#2591](https://github.com/icinga/icinga2/issues/2591) (Metrics): Add timestamp support for Graphite * [#2588](https://github.com/icinga/icinga2/issues/2588) (Configuration): Add path information for objects in object list * [#2578](https://github.com/icinga/icinga2/issues/2578) (Configuration): Implement Array\#join * [#2553](https://github.com/icinga/icinga2/issues/2553) (Configuration): Implement validator support for function objects * [#2552](https://github.com/icinga/icinga2/issues/2552) (Configuration): Make operators &&, || behave like in JavaScript * [#2546](https://github.com/icinga/icinga2/issues/2546): Add macros $host.check\_source$ and $service.check\_source$ * [#2544](https://github.com/icinga/icinga2/issues/2544) (Configuration): Implement the while keyword * [#2531](https://github.com/icinga/icinga2/issues/2531) (Configuration): Implement keywords to explicitly access globals/locals * [#2522](https://github.com/icinga/icinga2/issues/2522) (CLI): Make invalid log-severity option output an error instead of a warning * [#2509](https://github.com/icinga/icinga2/issues/2509): Host/Service runtime macro downtime\_depth * [#2491](https://github.com/icinga/icinga2/issues/2491) (Configuration): Assignments shouldn't have a "return" value * [#2488](https://github.com/icinga/icinga2/issues/2488): Implement additional methods for strings * [#2487](https://github.com/icinga/icinga2/issues/2487) (CLI): Figure out what to do about libreadline \(license\) * [#2486](https://github.com/icinga/icinga2/issues/2486) (CLI): Figure out a better name for the repl command * [#2466](https://github.com/icinga/icinga2/issues/2466) (Configuration): Implement line-continuation for the "console" command * [#2456](https://github.com/icinga/icinga2/issues/2456) (CLI): feature enable should use relative symlinks * [#2439](https://github.com/icinga/icinga2/issues/2439) (Configuration): Document the new language features in 2.3 * [#2437](https://github.com/icinga/icinga2/issues/2437) (CLI): Implement readline support for the "console" CLI command * [#2432](https://github.com/icinga/icinga2/issues/2432) (CLI): Backport i2tcl's error reporting functionality into "icinga2 console" * [#2429](https://github.com/icinga/icinga2/issues/2429) (Configuration): Figure out how variable scopes should work * [#2426](https://github.com/icinga/icinga2/issues/2426) (Configuration): Implement a way to call methods on objects * [#2421](https://github.com/icinga/icinga2/issues/2421) (Configuration): Implement a way to remove dictionary keys * [#2418](https://github.com/icinga/icinga2/issues/2418) (Plugins): Windows plugins should behave like their Linux cousins * [#2408](https://github.com/icinga/icinga2/issues/2408) (Configuration): ConfigCompiler::HandleInclude should return an inline dictionary * [#2407](https://github.com/icinga/icinga2/issues/2407) (Configuration): Implement a boolean sub-type for the Value class * [#2405](https://github.com/icinga/icinga2/issues/2405): Disallow calling strings as functions * [#2396](https://github.com/icinga/icinga2/issues/2396) (Configuration): Evaluate usage of function\(\) * [#2391](https://github.com/icinga/icinga2/issues/2391): Improve output of ToString for type objects * [#2390](https://github.com/icinga/icinga2/issues/2390): Register type objects as global variables * [#2367](https://github.com/icinga/icinga2/issues/2367) (Configuration): The lexer shouldn't accept escapes for characters which don't have to be escaped * [#2365](https://github.com/icinga/icinga2/issues/2365) (DB IDO): Implement socket\_path attribute for the IdoMysqlConnection class * [#2355](https://github.com/icinga/icinga2/issues/2355) (Configuration): Implement official support for user-defined functions and the "for" keyword * [#2351](https://github.com/icinga/icinga2/issues/2351) (Plugins): Windows agent is missing the standard plugin check\_ping * [#2348](https://github.com/icinga/icinga2/issues/2348) (Plugins): Plugin Check Commands: Add icmp * [#2324](https://github.com/icinga/icinga2/issues/2324) (Configuration): Implement the "if" and "else" keywords * [#2323](https://github.com/icinga/icinga2/issues/2323) (Configuration): Figure out whether Number + String should implicitly convert the Number argument to a string * [#2322](https://github.com/icinga/icinga2/issues/2322) (Configuration): Make the config parser thread-safe * [#2318](https://github.com/icinga/icinga2/issues/2318) (Configuration): Implement the % operator * [#2312](https://github.com/icinga/icinga2/issues/2312): Move the cast functions into libbase * [#2310](https://github.com/icinga/icinga2/issues/2310) (Configuration): Implement unit tests for the config parser * [#2304](https://github.com/icinga/icinga2/issues/2304): Implement an option to disable building the Demo component * [#2303](https://github.com/icinga/icinga2/issues/2303): Implement an option to disable building the Livestatus module * [#2300](https://github.com/icinga/icinga2/issues/2300) (Notifications): Implement the DISABLE\_HOST\_SVC\_NOTIFICATIONS and ENABLE\_HOST\_SVC\_NOTIFICATIONS commands * [#2298](https://github.com/icinga/icinga2/issues/2298) (Plugins): Missing check\_disk output on Windows * [#2294](https://github.com/icinga/icinga2/issues/2294) (Configuration): Implement an AST Expression for T\_CONST * [#2290](https://github.com/icinga/icinga2/issues/2290): Rename \_DEBUG to I2\_DEBUG * [#2286](https://github.com/icinga/icinga2/issues/2286) (Configuration): Redesign how stack frames work for scripts * [#2265](https://github.com/icinga/icinga2/issues/2265): ConfigCompiler::Compile\* should return an AST node * [#2264](https://github.com/icinga/icinga2/issues/2264) (Configuration): ConfigCompiler::HandleInclude\* should return an AST node * [#2262](https://github.com/icinga/icinga2/issues/2262) (CLI): Add an option that hides CLI commands * [#2260](https://github.com/icinga/icinga2/issues/2260) (Configuration): Evaluate apply/object rules when the parent objects are created * [#2211](https://github.com/icinga/icinga2/issues/2211) (Configuration): Variable from for loop not usable in assign statement * [#2186](https://github.com/icinga/icinga2/issues/2186) (Configuration): Access object runtime attributes in custom vars & command arguments * [#2176](https://github.com/icinga/icinga2/issues/2176) (Configuration): Please add labels in SNMP checks * [#2043](https://github.com/icinga/icinga2/issues/2043) (Livestatus): Livestatus: Add GroupBy tables: hostsbygroup, servicesbygroup, servicesbyhostgroup * [#2027](https://github.com/icinga/icinga2/issues/2027) (Configuration): Add parent soft states option to Dependency object configuration * [#2000](https://github.com/icinga/icinga2/issues/2000) (Metrics): Add OpenTSDB Writer * [#1959](https://github.com/icinga/icinga2/issues/1959) (Configuration): extended Manubulon SNMP Check Plugin Command * [#1890](https://github.com/icinga/icinga2/issues/1890) (DB IDO): IDO should fill program\_end\_time on a clean shutdown * [#1866](https://github.com/icinga/icinga2/issues/1866) (Notifications): Disable flapping detection by default * [#1859](https://github.com/icinga/icinga2/issues/1859): Run CheckCommands with C locale \(workaround for comma vs dot and plugin api bug\) * [#1783](https://github.com/icinga/icinga2/issues/1783) (Plugins): Plugin Check Commands: add check\_vmware\_esx * [#1733](https://github.com/icinga/icinga2/issues/1733) (Configuration): Disallow side-effect-free r-value expressions in expression lists * [#1507](https://github.com/icinga/icinga2/issues/1507): Don't spawn threads for network connections * [#404](https://github.com/icinga/icinga2/issues/404) (CLI): Add troubleshooting collect cli command ### Bug * [#2707](https://github.com/icinga/icinga2/issues/2707) (DB IDO): Crash when using ido-pgsql * [#2706](https://github.com/icinga/icinga2/issues/2706): Icinga2 shuts down when service is reloaded * [#2703](https://github.com/icinga/icinga2/issues/2703) (Configuration): Attribute hints don't work for nested attributes * [#2699](https://github.com/icinga/icinga2/issues/2699) (Configuration): Dependency: Validate \*\_{host,service}\_name objects on their existance * [#2698](https://github.com/icinga/icinga2/issues/2698) (Livestatus): Improve Livestatus query performance * [#2697](https://github.com/icinga/icinga2/issues/2697) (Configuration): Memory leak in Expression::GetReference * [#2695](https://github.com/icinga/icinga2/issues/2695) (Configuration): else if doesn't work without an else branch * [#2693](https://github.com/icinga/icinga2/issues/2693): Check whether the new TimePeriod validator is working as expected * [#2692](https://github.com/icinga/icinga2/issues/2692) (CLI): Resource leak in TroubleshootCommand::ObjectInfo * [#2691](https://github.com/icinga/icinga2/issues/2691) (CLI): Resource leak in TroubleshootCommand::Run * [#2689](https://github.com/icinga/icinga2/issues/2689): Check if scheduled downtimes work properly * [#2688](https://github.com/icinga/icinga2/issues/2688) (Plugins): check\_memory tool shows incorrect memory size on windows * [#2685](https://github.com/icinga/icinga2/issues/2685) (Cluster): Don't accept config updates for zones for which we have an authoritative copy of the config * [#2684](https://github.com/icinga/icinga2/issues/2684) (Cluster): Icinga crashed on SocketEvent * [#2683](https://github.com/icinga/icinga2/issues/2683) (Cluster): Crash in ApiClient::TimeoutTimerHandler * [#2680](https://github.com/icinga/icinga2/issues/2680): Deadlock in TlsStream::Handshake * [#2679](https://github.com/icinga/icinga2/issues/2679) (Cluster): Deadlock in ApiClient::Disconnect * [#2677](https://github.com/icinga/icinga2/issues/2677): Crash in SocketEvents::Register * [#2676](https://github.com/icinga/icinga2/issues/2676) (Livestatus): Windows build fails * [#2674](https://github.com/icinga/icinga2/issues/2674) (DB IDO): Hosts: process\_performance\_data = 0 in database even though enable\_perfdata = 1 in config * [#2671](https://github.com/icinga/icinga2/issues/2671) (DB IDO): Crash in DbObject::SendStatusUpdate * [#2670](https://github.com/icinga/icinga2/issues/2670) (Compat): Valgrind warning for ExternalCommandListener::CommandPipeThread * [#2669](https://github.com/icinga/icinga2/issues/2669): Crash in ApiEvents::RepositoryTimerHandler * [#2665](https://github.com/icinga/icinga2/issues/2665) (Livestatus): livestatus limit header not working * [#2660](https://github.com/icinga/icinga2/issues/2660) (Configuration): apply-for incorrectly converts loop var to string * [#2659](https://github.com/icinga/icinga2/issues/2659) (Configuration): Config parser fails non-deterministic on Notification missing Checkable * [#2658](https://github.com/icinga/icinga2/issues/2658) (CLI): Crash in icinga2 console * [#2654](https://github.com/icinga/icinga2/issues/2654) (DB IDO): Deadlock with DB IDO dump and forcing a scheduled check * [#2650](https://github.com/icinga/icinga2/issues/2650) (CLI): SIGSEGV in CLI * [#2647](https://github.com/icinga/icinga2/issues/2647) (DB IDO): Icinga doesn't update long\_output in DB * [#2646](https://github.com/icinga/icinga2/issues/2646) (Cluster): Misleading ApiListener connection log messages on a master \(Endpoint vs Zone\) * [#2644](https://github.com/icinga/icinga2/issues/2644) (CLI): Figure out why 'node update-config' becomes slow over time * [#2642](https://github.com/icinga/icinga2/issues/2642): Icinga 2 sometimes doesn't reconnect to the master * [#2641](https://github.com/icinga/icinga2/issues/2641) (Cluster): ICINGA process crashes every night * [#2639](https://github.com/icinga/icinga2/issues/2639) (CLI): Build fails on Debian squeeze * [#2636](https://github.com/icinga/icinga2/issues/2636): Exception in WorkQueue::StatusTimerHandler * [#2631](https://github.com/icinga/icinga2/issues/2631) (Cluster): deadlock in client connection * [#2630](https://github.com/icinga/icinga2/issues/2630) (Cluster): Don't request heartbeat messages until after we've synced the log * [#2627](https://github.com/icinga/icinga2/issues/2627) (Livestatus): Livestatus query on commands table with custom vars fails * [#2626](https://github.com/icinga/icinga2/issues/2626) (DB IDO): Icinga2 segfaults when issuing postgresql queries * [#2622](https://github.com/icinga/icinga2/issues/2622): "node wizard" crashes * [#2621](https://github.com/icinga/icinga2/issues/2621): Don't attempt to restore program state from non-existing state file * [#2618](https://github.com/icinga/icinga2/issues/2618) (DB IDO): DB IDO {host,service}checks command\_line value is "Object of type 'icinga::Array'" * [#2617](https://github.com/icinga/icinga2/issues/2617) (DB IDO): Indicate that Icinga2 is shutting down in case of a fatal error * [#2615](https://github.com/icinga/icinga2/issues/2615): Make the arguments for the stats functions const-ref * [#2613](https://github.com/icinga/icinga2/issues/2613) (DB IDO): DB IDO: Duplicate entry icinga\_scheduleddowntime * [#2608](https://github.com/icinga/icinga2/issues/2608) (Plugins): Ignore the -X option for check\_disk on Windows * [#2605](https://github.com/icinga/icinga2/issues/2605): Compiler warnings * [#2599](https://github.com/icinga/icinga2/issues/2599) (Cluster): Agent writes CR CR LF in synchronized config files * [#2598](https://github.com/icinga/icinga2/issues/2598): Added downtimes must be triggered immediately if checkable is Not-OK * [#2597](https://github.com/icinga/icinga2/issues/2597) (Cluster): Config sync authoritative file never created * [#2596](https://github.com/icinga/icinga2/issues/2596) (Compat): StatusDataWriter: Wrong host notification filters \(broken fix in \#8192\) * [#2593](https://github.com/icinga/icinga2/issues/2593) (Compat): last\_hard\_state missing in StatusDataWriter * [#2589](https://github.com/icinga/icinga2/issues/2589) (Configuration): Stacktrace on Endpoint not belonging to a zone or multiple zones * [#2586](https://github.com/icinga/icinga2/issues/2586): Icinga2 master doesn't change check-status when "accept\_commands = true" is not set at client node * [#2579](https://github.com/icinga/icinga2/issues/2579) (Configuration): Apply rule '' for host does not match anywhere! * [#2572](https://github.com/icinga/icinga2/issues/2572) (Cluster): Incorrectly formatted timestamp in .timestamp file * [#2570](https://github.com/icinga/icinga2/issues/2570): Crash in ScheduledDowntime::CreateNextDowntime * [#2569](https://github.com/icinga/icinga2/issues/2569): PidPath, VarsPath, ObjectsPath and StatePath no longer read from init.conf * [#2566](https://github.com/icinga/icinga2/issues/2566) (Configuration): Don't allow comparison of strings and numbers * [#2562](https://github.com/icinga/icinga2/issues/2562) (Cluster): ApiListener::ReplayLog shouldn't hold mutex lock during call to Socket::Poll * [#2560](https://github.com/icinga/icinga2/issues/2560): notify flag is ignored in ACKNOWLEDGE\_\*\_PROBLEM commands * [#2559](https://github.com/icinga/icinga2/issues/2559) (DB IDO): Duplicate entry on icinga\_hoststatus * [#2556](https://github.com/icinga/icinga2/issues/2556) (CLI): Running icinga2 command as non privilged user raises error * [#2551](https://github.com/icinga/icinga2/issues/2551) (Livestatus): Livestatus operator =~ is not case-insensitive * [#2542](https://github.com/icinga/icinga2/issues/2542) (CLI): icinga2 node wizard: Create backups of certificates * [#2539](https://github.com/icinga/icinga2/issues/2539) (Cluster): Report missing command objects on remote agent * [#2533](https://github.com/icinga/icinga2/issues/2533) (Cluster): Problems using command\_endpoint inside HA zone * [#2529](https://github.com/icinga/icinga2/issues/2529) (CLI): CLI console fails to report errors in included files * [#2526](https://github.com/icinga/icinga2/issues/2526) (Configuration): Deadlock when accessing loop variable inside of the loop * [#2525](https://github.com/icinga/icinga2/issues/2525) (Configuration): Lexer term for T\_ANGLE\_STRING is too aggressive * [#2513](https://github.com/icinga/icinga2/issues/2513) (CLI): icinga2 node update should not write config for blacklisted zones/host * [#2503](https://github.com/icinga/icinga2/issues/2503) (CLI): Argument auto-completion doesn't work for short options * [#2502](https://github.com/icinga/icinga2/issues/2502): group assign fails with bad lexical cast when evaluating rules * [#2497](https://github.com/icinga/icinga2/issues/2497): Exception on missing config files * [#2494](https://github.com/icinga/icinga2/issues/2494) (Livestatus): Error messages when stopping Icinga * [#2493](https://github.com/icinga/icinga2/issues/2493): Compiler warnings * [#2492](https://github.com/icinga/icinga2/issues/2492): Segfault on icinga::String::operator= when compiling configuration * [#2485](https://github.com/icinga/icinga2/issues/2485) (Configuration): parsing include\_recursive * [#2482](https://github.com/icinga/icinga2/issues/2482) (Configuration): escaped backslash in string literals * [#2467](https://github.com/icinga/icinga2/issues/2467) (CLI): Icinga crashes when config file name is invalid * [#2465](https://github.com/icinga/icinga2/issues/2465) (Configuration): Debug info for indexer is incorrect * [#2457](https://github.com/icinga/icinga2/issues/2457): Config file passing validation causes segfault * [#2452](https://github.com/icinga/icinga2/issues/2452) (Cluster): Agent checks fail when there's already a host with the same name * [#2448](https://github.com/icinga/icinga2/issues/2448) (Configuration): User::ValidateFilters isn't being used * [#2447](https://github.com/icinga/icinga2/issues/2447) (Configuration): ConfigCompilerContext::WriteObject crashes after ConfigCompilerContext::FinishObjectsFile was called * [#2445](https://github.com/icinga/icinga2/issues/2445) (Configuration): segfault on startup * [#2442](https://github.com/icinga/icinga2/issues/2442) (DB IDO): POSTGRES IDO: invalid syntax for integer: "true" while trying to update table icinga\_hoststatus * [#2441](https://github.com/icinga/icinga2/issues/2441) (CLI): console: Don't repeat line when we're reporting an error for the last line * [#2436](https://github.com/icinga/icinga2/issues/2436) (Configuration): Modulo 0 crashes Icinga * [#2435](https://github.com/icinga/icinga2/issues/2435) (Configuration): Location info for strings is incorrect * [#2434](https://github.com/icinga/icinga2/issues/2434) (Configuration): Setting an attribute on an r-value fails * [#2433](https://github.com/icinga/icinga2/issues/2433) (Configuration): Confusing error message when trying to set a field on a string * [#2431](https://github.com/icinga/icinga2/issues/2431) (Configuration): icinga 2 Config Error needs to be more verbose * [#2428](https://github.com/icinga/icinga2/issues/2428) (Configuration): Debug visualizer for the Value class is broken * [#2427](https://github.com/icinga/icinga2/issues/2427) (Configuration): if doesn't work for non-boolean arguments * [#2423](https://github.com/icinga/icinga2/issues/2423) (Configuration): Require at least one user for notification objects \(user or as member of user\_groups\) * [#2419](https://github.com/icinga/icinga2/issues/2419) (Configuration): Confusing error message for import * [#2410](https://github.com/icinga/icinga2/issues/2410): The Boolean type change broke set\_if * [#2406](https://github.com/icinga/icinga2/issues/2406) (Configuration): len\(\) overflows * [#2395](https://github.com/icinga/icinga2/issues/2395) (Configuration): operator precedence for % and \> is incorrect * [#2388](https://github.com/icinga/icinga2/issues/2388): Value\(""\).IsEmpty\(\) should return true * [#2379](https://github.com/icinga/icinga2/issues/2379) (Cluster): Windows Agent: Missing directory "zones" in setup * [#2375](https://github.com/icinga/icinga2/issues/2375) (Configuration): Config validator doesn't show in which file the error was found * [#2362](https://github.com/icinga/icinga2/issues/2362): Serialize\(\) fails to serialize objects which don't have a registered type * [#2361](https://github.com/icinga/icinga2/issues/2361): Fix warnings when using CMake 3.1.0 * [#2346](https://github.com/icinga/icinga2/issues/2346) (DB IDO): Missing persistent\_comment, notify\_contact columns for acknowledgement table * [#2329](https://github.com/icinga/icinga2/issues/2329) (Configuration): - shouldn't be allowed in identifiers * [#2326](https://github.com/icinga/icinga2/issues/2326): Compiler warnings * [#2320](https://github.com/icinga/icinga2/issues/2320) (Configuration): - operator doesn't work in expressions * [#2319](https://github.com/icinga/icinga2/issues/2319) (Configuration): Set expression should check whether LHS is a null pointer * [#2317](https://github.com/icinga/icinga2/issues/2317) (Configuration): Validate array subscripts * [#2316](https://github.com/icinga/icinga2/issues/2316) (Configuration): The \_\_return keyword is broken * [#2315](https://github.com/icinga/icinga2/issues/2315) (Configuration): Return values for functions are broken * [#2314](https://github.com/icinga/icinga2/issues/2314): Scoping rules for "for" are broken * [#2313](https://github.com/icinga/icinga2/issues/2313) (Configuration): Unterminated string literals should cause parser to return an error * [#2308](https://github.com/icinga/icinga2/issues/2308) (Configuration): Change parameter type for include and include\_recursive to T\_STRING * [#2307](https://github.com/icinga/icinga2/issues/2307) (Configuration): Fix the shift/reduce conflicts in the parser * [#2289](https://github.com/icinga/icinga2/issues/2289) (DB IDO): DB IDO: Duplicate entry icinga\_{host,service}dependencies * [#2274](https://github.com/icinga/icinga2/issues/2274) (Notifications): Reminder notifications not being sent but logged every 5 secs * [#2234](https://github.com/icinga/icinga2/issues/2234): Avoid rebuilding libbase when the version number changes * [#2232](https://github.com/icinga/icinga2/issues/2232): Unity build doesn't work with MSVC * [#2194](https://github.com/icinga/icinga2/issues/2194) (Configuration): validate configured legacy timeperiod ranges * [#2174](https://github.com/icinga/icinga2/issues/2174) (Configuration): Update validators for CustomVarObject * [#2020](https://github.com/icinga/icinga2/issues/2020) (Configuration): Invalid macro results in exception * [#1899](https://github.com/icinga/icinga2/issues/1899): Scheduled start time will be ignored if the host or service is already in a problem state * [#1530](https://github.com/icinga/icinga2/issues/1530): Remove name and return value for stats functions ### ITL * [#2705](https://github.com/icinga/icinga2/issues/2705) (ITL): Add check commands for NSClient++ * [#2661](https://github.com/icinga/icinga2/issues/2661) (ITL): ITL: The procs check command uses spaces instead of tabs * [#2652](https://github.com/icinga/icinga2/issues/2652) (ITL): Rename PluginsContribDir to PluginContribDir * [#2649](https://github.com/icinga/icinga2/issues/2649) (ITL): Snmp CheckCommand misses various options * [#2614](https://github.com/icinga/icinga2/issues/2614) (ITL): add webinject checkcommand * [#2610](https://github.com/icinga/icinga2/issues/2610) (ITL): Add ITL check command for check\_ipmi\_sensor * [#2573](https://github.com/icinga/icinga2/issues/2573) (ITL): Extend disk checkcommand * [#2541](https://github.com/icinga/icinga2/issues/2541) (ITL): The check "hostalive" is not working with ipv6 * [#2012](https://github.com/icinga/icinga2/issues/2012) (ITL): ITL: ESXi-Hardware * [#2011](https://github.com/icinga/icinga2/issues/2011) (ITL): ITL: Check\_Mem.pl * [#1984](https://github.com/icinga/icinga2/issues/1984) (ITL): ITL: Interfacetable ### Documentation * [#2711](https://github.com/icinga/icinga2/issues/2711) (Documentation): Document closures \('use'\) * [#2709](https://github.com/icinga/icinga2/issues/2709) (Documentation): Fix a typo in documentation * [#2662](https://github.com/icinga/icinga2/issues/2662) (Documentation): Update Remote Client/Distributed Monitoring Documentation * [#2595](https://github.com/icinga/icinga2/issues/2595) (Documentation): Add documentation for cli command 'console' * [#2575](https://github.com/icinga/icinga2/issues/2575) (Documentation): Remote Clients: Add manual setup cli commands * [#2555](https://github.com/icinga/icinga2/issues/2555) (Documentation): The Zone::global attribute is not documented * [#2399](https://github.com/icinga/icinga2/issues/2399) (Documentation): Allow name changed from inside the object * [#2387](https://github.com/icinga/icinga2/issues/2387) (Documentation): Documentation enhancement for snmp traps and passive checks. * [#2321](https://github.com/icinga/icinga2/issues/2321) (Documentation): Document operator precedence * [#2198](https://github.com/icinga/icinga2/issues/2198) (Documentation): Variable expansion is single quoted. * [#1860](https://github.com/icinga/icinga2/issues/1860) (Documentation): Add some more PNP details ### Support * [#2616](https://github.com/icinga/icinga2/issues/2616) (Installation): Build fails on OpenBSD * [#2602](https://github.com/icinga/icinga2/issues/2602) (Packages): Icinga2 config reset after package update \(centos6.6\) * [#2511](https://github.com/icinga/icinga2/issues/2511) (Packages): '../features-available/checker.conf' does not exist \[Windows\] * [#2374](https://github.com/icinga/icinga2/issues/2374) (Packages): Move the config file for the ido-\*sql features into the icinga2-ido-\* packages * [#2302](https://github.com/icinga/icinga2/issues/2302) (Installation): Don't build db\_ido when both MySQL and PostgreSQL aren't enabled ## 2.2.4 (2015-02-05) ### Notes * Bugfixes ### Bug * [#2587](https://github.com/icinga/icinga2/issues/2587) (CLI): Output in "node wizard" is confusing * [#2577](https://github.com/icinga/icinga2/issues/2577) (Compat): enable\_event\_handlers attribute is missing in status.dat * [#2571](https://github.com/icinga/icinga2/issues/2571): Segfault in Checkable::AddNotification * [#2561](https://github.com/icinga/icinga2/issues/2561): Scheduling downtime for host and all services only schedules services * [#2558](https://github.com/icinga/icinga2/issues/2558) (CLI): Restart of Icinga hangs * [#2550](https://github.com/icinga/icinga2/issues/2550) (DB IDO): Crash in DbConnection::ProgramStatusHandler * [#2538](https://github.com/icinga/icinga2/issues/2538) (CLI): Restart fails after deleting a Host * [#2508](https://github.com/icinga/icinga2/issues/2508) (Compat): Feature statusdata shows wrong host notification options * [#2481](https://github.com/icinga/icinga2/issues/2481) (CLI): Satellite doesn't use manually supplied 'local zone name' * [#2464](https://github.com/icinga/icinga2/issues/2464): vfork\(\) hangs on OS X * [#2256](https://github.com/icinga/icinga2/issues/2256) (Notifications): kUn-Bashify mail-{host,service}-notification.sh * [#2242](https://github.com/icinga/icinga2/issues/2242): livestatus / nsca / etc submits are ignored during reload * [#1893](https://github.com/icinga/icinga2/issues/1893): Configured recurring downtimes not applied on saturdays ### ITL * [#2532](https://github.com/icinga/icinga2/issues/2532) (ITL): check\_ssmtp command does NOT support mail\_from ### Documentation * [#2521](https://github.com/icinga/icinga2/issues/2521) (Documentation): Typos in readme file for windows plugins * [#2520](https://github.com/icinga/icinga2/issues/2520) (Documentation): inconsistent URL http\(s\)://www.icinga.org * [#2512](https://github.com/icinga/icinga2/issues/2512) (Documentation): Update Icinga Web 2 uri to /icingaweb2 ### Support * [#2517](https://github.com/icinga/icinga2/issues/2517) (Packages): Fix YAJL detection on Debian squeeze * [#2462](https://github.com/icinga/icinga2/issues/2462) (Packages): Icinga 2.2.2 build fails on SLES11SP3 because of changed boost dependency ## 2.2.3 (2015-01-12) ### Notes * Bugfixes ### Bug * [#2499](https://github.com/icinga/icinga2/issues/2499) (CLI): Segfault on update-config old empty config * [#2498](https://github.com/icinga/icinga2/issues/2498) (CLI): icinga2 node update config shows hex instead of human readable names * [#2496](https://github.com/icinga/icinga2/issues/2496): Icinga 2.2.2 segfaults on FreeBSD * [#2477](https://github.com/icinga/icinga2/issues/2477): DB IDO query queue limit reached on reload * [#2473](https://github.com/icinga/icinga2/issues/2473) (CLI): check\_interval must be greater than 0 error on update-config * [#2471](https://github.com/icinga/icinga2/issues/2471) (Cluster): Arguments without values are not used on plugin exec * [#2470](https://github.com/icinga/icinga2/issues/2470) (Plugins): Windows plugin check\_service.exe can't find service NTDS * [#2459](https://github.com/icinga/icinga2/issues/2459) (CLI): Incorrect ticket shouldn't cause "node wizard" to terminate * [#2420](https://github.com/icinga/icinga2/issues/2420) (Notifications): Volatile checks trigger invalid notifications on OK-\>OK state changes ### Documentation * [#2490](https://github.com/icinga/icinga2/issues/2490) (Documentation): Typo in example of StatusDataWriter ### Support * [#2460](https://github.com/icinga/icinga2/issues/2460) (Packages): Icinga 2.2.2 doesn't build on i586 SUSE distributions ## 2.2.2 (2014-12-18) ### Notes * Bugfixes ### Bug * [#2446](https://github.com/icinga/icinga2/issues/2446) (Compat): StatusDataWriter: Wrong export of event\_handler\_enabled * [#2444](https://github.com/icinga/icinga2/issues/2444) (CLI): Remove usage info from --version * [#2416](https://github.com/icinga/icinga2/issues/2416) (DB IDO): DB IDO: Missing last\_hard\_state column update in {host,service}status tables * [#2411](https://github.com/icinga/icinga2/issues/2411): exception during config check * [#2394](https://github.com/icinga/icinga2/issues/2394): typeof does not work for numbers * [#2381](https://github.com/icinga/icinga2/issues/2381): SIGABRT while evaluating apply rules * [#2380](https://github.com/icinga/icinga2/issues/2380) (Configuration): typeof\(\) seems to return null for arrays and dictionaries * [#2376](https://github.com/icinga/icinga2/issues/2376) (Configuration): Apache 2.2 fails with new apache conf * [#2371](https://github.com/icinga/icinga2/issues/2371) (Configuration): Test Classic UI config file with Apache 2.4 * [#2370](https://github.com/icinga/icinga2/issues/2370) (Cluster): update\_config not updating configuration * [#2360](https://github.com/icinga/icinga2/issues/2360): CLI `icinga2 node update-config` doesn't sync configs from remote clients as expected * [#2354](https://github.com/icinga/icinga2/issues/2354) (DB IDO): Improve error reporting when libmysqlclient or libpq are missing * [#2350](https://github.com/icinga/icinga2/issues/2350) (Cluster): Segfault on issuing node update-config * [#2341](https://github.com/icinga/icinga2/issues/2341) (Cluster): execute checks locally if command\_endpoint == local endpoint * [#2283](https://github.com/icinga/icinga2/issues/2283) (Cluster): Cluster heartbeats need to be more aggressive * [#2266](https://github.com/icinga/icinga2/issues/2266) (CLI): "node wizard" shouldn't crash when SaveCert fails * [#2255](https://github.com/icinga/icinga2/issues/2255) (DB IDO): If a parent host goes down, the child host isn't marked as unrechable in the db ido * [#2216](https://github.com/icinga/icinga2/issues/2216) (Cluster): Repository does not support services which have a slash in their name * [#2202](https://github.com/icinga/icinga2/issues/2202) (Configuration): CPU usage at 100% when check\_interval = 0 in host object definition * [#2154](https://github.com/icinga/icinga2/issues/2154) (Cluster): update-config fails to create hosts * [#2148](https://github.com/icinga/icinga2/issues/2148) (Compat): Feature `compatlog' should flush output buffer on every new line * [#2021](https://github.com/icinga/icinga2/issues/2021): double macros in command arguments seems to lead to exception * [#2016](https://github.com/icinga/icinga2/issues/2016) (Notifications): Docs: Better explaination of dependency state filters * [#1947](https://github.com/icinga/icinga2/issues/1947) (Livestatus): Missing host downtimes/comments in Livestatus ### ITL * [#2430](https://github.com/icinga/icinga2/issues/2430) (ITL): No option to specify timeout to check\_snmp and snmp manubulon commands ### Documentation * [#2422](https://github.com/icinga/icinga2/issues/2422) (Documentation): Setting a dictionary key to null does not cause the key/value to be removed * [#2412](https://github.com/icinga/icinga2/issues/2412) (Documentation): Update host examples in Dependencies for Network Reachability documentation * [#2409](https://github.com/icinga/icinga2/issues/2409) (Documentation): Wrong command in documentation for installing Icinga 2 pretty printers. * [#2404](https://github.com/icinga/icinga2/issues/2404) (Documentation): Livestatus: Replace unixcat with nc -U * [#2180](https://github.com/icinga/icinga2/issues/2180) (Documentation): Documentation: Add note on default notification interval in getting started notifications.conf ### Support * [#2417](https://github.com/icinga/icinga2/issues/2417) (Tests): Unit tests fail on FreeBSD * [#2369](https://github.com/icinga/icinga2/issues/2369) (Packages): SUSE packages %set\_permissions post statement wasn't moved to common * [#2368](https://github.com/icinga/icinga2/issues/2368) (Packages): /usr/lib/icinga2 is not owned by a package * [#2292](https://github.com/icinga/icinga2/issues/2292) (Tests): The unit tests still crash sometimes * [#1942](https://github.com/icinga/icinga2/issues/1942) (Packages): icinga2 init-script doesn't validate configuration on reload action ## 2.2.1 (2014-12-01) ### Notes * Support arrays in [command argument macros](#command-passing-parameters) #6709 * Allows to define multiple parameters for [nrpe -a](#plugin-check-command-nrpe), [nscp -l](#plugin-check-command-nscp), [disk -p](#plugin-check-command-disk), [dns -a](#plugin-check-command-dns). * Bugfixes ### Enhancement * [#2366](https://github.com/icinga/icinga2/issues/2366): Release 2.2.1 * [#2277](https://github.com/icinga/icinga2/issues/2277) (Configuration): The classicui Apache conf doesn't support Apache 2.4 * [#1790](https://github.com/icinga/icinga2/issues/1790): Support for arrays in macros ### Bug * [#2340](https://github.com/icinga/icinga2/issues/2340) (CLI): Segfault in CA handling * [#2328](https://github.com/icinga/icinga2/issues/2328) (Cluster): Verify if master radio box is disabled in the Windows wizard * [#2311](https://github.com/icinga/icinga2/issues/2311) (Configuration): !in operator returns incorrect result * [#2293](https://github.com/icinga/icinga2/issues/2293) (Configuration): Objects created with node update-config can't be seen in Classic UI * [#2288](https://github.com/icinga/icinga2/issues/2288) (Cluster): Incorrect error message for localhost * [#2282](https://github.com/icinga/icinga2/issues/2282) (Cluster): Icinga2 node add failed with unhandled exception * [#2273](https://github.com/icinga/icinga2/issues/2273): Restart Icinga - Error Restoring program state from file '/var/lib/icinga2/icinga2.state' * [#2272](https://github.com/icinga/icinga2/issues/2272) (Cluster): Windows wizard is missing --zone argument * [#2271](https://github.com/icinga/icinga2/issues/2271) (Cluster): Windows wizard uses incorrect CLI command * [#2267](https://github.com/icinga/icinga2/issues/2267) (Cluster): Built-in commands shouldn't be run on the master instance in remote command execution mode * [#2207](https://github.com/icinga/icinga2/issues/2207) (Livestatus): livestatus large amount of submitting unix socket command results in broken pipes ### ITL * [#2285](https://github.com/icinga/icinga2/issues/2285) (ITL): Increase default timeout for NRPE checks ### Documentation * [#2344](https://github.com/icinga/icinga2/issues/2344) (Documentation): Documentation: Explain how unresolved macros are handled * [#2343](https://github.com/icinga/icinga2/issues/2343) (Documentation): Document how arrays in macros work * [#2336](https://github.com/icinga/icinga2/issues/2336) (Documentation): Wrong information in section "Linux Client Setup Wizard for Remote Monitoring" * [#2275](https://github.com/icinga/icinga2/issues/2275) (Documentation): 2.2.0 has out-of-date icinga2 man page * [#2251](https://github.com/icinga/icinga2/issues/2251) (Documentation): object and template with the same name generate duplicate object error ### Support * [#2363](https://github.com/icinga/icinga2/issues/2363) (Packages): Fix Apache config in the Debian package * [#2359](https://github.com/icinga/icinga2/issues/2359) (Packages): Wrong permission in run directory after restart * [#2301](https://github.com/icinga/icinga2/issues/2301) (Packages): Move the icinga2-prepare-dirs script elsewhere * [#2280](https://github.com/icinga/icinga2/issues/2280) (Packages): Icinga 2.2 misses the build requirement libyajl-devel for SUSE distributions * [#2278](https://github.com/icinga/icinga2/issues/2278) (Packages): /usr/sbin/icinga-prepare-dirs conflicts in the bin and common package * [#2276](https://github.com/icinga/icinga2/issues/2276) (Packages): Systemd rpm scripts are run in wrong package * [#2212](https://github.com/icinga/icinga2/issues/2212) (Packages): icinga2 checkconfig should fail if group given for command files does not exist * [#2117](https://github.com/icinga/icinga2/issues/2117) (Packages): Update spec file to use yajl-devel * [#1968](https://github.com/icinga/icinga2/issues/1968) (Packages): service icinga2 status gives wrong information when run as unprivileged user ## 2.2.0 (2014-11-17) ### Notes * DB IDO schema update to version `1.12.0` * schema files in `lib/db_ido_{mysql,pgsql}/schema` (source) * Table `programstatus`: New column `program_version` * Table `customvariables` and `customvariablestatus`: New column `is_json` (required for custom attribute array/dictionary support) * New features * [GelfWriter](#gelfwriter): Logging check results, state changes, notifications to GELF (graylog2, logstash) #7619 * Agent/Client/Node framework #7249 * Windows plugins for the client/agent parts #7242 #7243 * New CLI commands #7245 * `icinga2 feature {enable,disable}` replaces `icinga2-{enable,disable}-feature` script #7250 * `icinga2 object list` replaces `icinga2-list-objects` script #7251 * `icinga2 pki` replaces` icinga2-build-{ca,key}` scripts #7247 * `icinga2 repository` manages `/etc/icinga2/repository.d` which must be included in `icinga2.conf` #7255 * `icinga2 node` cli command provides node (master, satellite, agent) setup (wizard) and management functionality #7248 * `icinga2 daemon` for existing daemon arguments (`-c`, `-C`). Removed `-u` and `-g` parameters in favor of [init.conf](#init-conf). * bash auto-completion & terminal colors #7396 * Configuration * Former `localhost` example host is now defined in [hosts.conf](#hosts-conf) #7594 * All example services moved into advanced apply rules in [services.conf](#services-conf) * Updated downtimes configuration example in [downtimes.conf](#downtimes-conf) #7472 * Updated notification apply example in [notifications.conf](#notifications-conf) #7594 * Support for object attribute 'zone' #7400 * Support setting [object variables in apply rules](#dependencies-apply-custom-attributes) #7479 * Support arrays and dictionaries in [custom attributes](#custom-attributes-apply) #6544 #7560 * Add [apply for rules](#using-apply-for) for advanced dynamic object generation #7561 * New attribute `accept_commands` for [ApiListener](#objecttype-apilistener) #7559 * New [init.conf](#init-conf) file included first containing new constants `RunAsUser` and `RunAsGroup`. * Cluster * Add [CSR Auto-Signing support](#csr-autosigning-requirements) using generated ticket #7244 * Allow to [execute remote commands](#icinga2-remote-monitoring-client-command-execution) on endpoint clients #7559 * Perfdata * [PerfdataWriter](#writing-performance-data-files): Don't change perfdata, pass through from plugins #7268 * [GraphiteWriter](#graphite-carbon-cache-writer): Add warn/crit/min/max perfdata and downtime_depth stats values #7366 #6946 * Packages * `python-icinga2` package dropped in favor of integrated cli commands #7245 * Windows Installer for the agent parts #7243 > **Note** > > Please remove `conf.d/hosts/localhost*` after verifying your updated configuration! ### Enhancement * [#2219](https://github.com/icinga/icinga2/issues/2219): Icinga 2 should use less RAM * [#2217](https://github.com/icinga/icinga2/issues/2217) (Metrics): Add GelfWriter for writing log events to graylog2/logstash * [#2213](https://github.com/icinga/icinga2/issues/2213): Optimize class layout * [#2203](https://github.com/icinga/icinga2/issues/2203) (Configuration): Revamp sample configuration: add NodeName host, move services into apply rules schema * [#2189](https://github.com/icinga/icinga2/issues/2189) (Configuration): Refactor AST into multiple classes * [#2187](https://github.com/icinga/icinga2/issues/2187) (Configuration): Implement support for arbitrarily complex indexers * [#2184](https://github.com/icinga/icinga2/issues/2184) (Configuration): Generate objects using apply with foreach in arrays or dictionaries \(key =\> value\) * [#2183](https://github.com/icinga/icinga2/issues/2183) (Configuration): Support dictionaries in custom attributes * [#2182](https://github.com/icinga/icinga2/issues/2182) (Cluster): Execute remote commands on the agent w/o local objects by passing custom attributes * [#2179](https://github.com/icinga/icinga2/issues/2179): Implement keys\(\) * [#2178](https://github.com/icinga/icinga2/issues/2178) (CLI): Cli command Node: Disable notifications feature on client nodes * [#2161](https://github.com/icinga/icinga2/issues/2161) (CLI): Cli Command: Rename 'agent' to 'node' * [#2158](https://github.com/icinga/icinga2/issues/2158) (Cluster): Require --zone to be specified for "node setup" * [#2152](https://github.com/icinga/icinga2/issues/2152) (Cluster): Rename --agent to --zone \(for blacklist/whitelist\) * [#2140](https://github.com/icinga/icinga2/issues/2140) (CLI): Cli: Use Node Blacklist functionality in 'node update-config' * [#2138](https://github.com/icinga/icinga2/issues/2138) (CLI): Find a better name for 'repository commit --clear' * [#2131](https://github.com/icinga/icinga2/issues/2131) (Configuration): Set host/service variable in apply rules * [#2124](https://github.com/icinga/icinga2/issues/2124) (Configuration): Update downtimes.conf example config * [#2119](https://github.com/icinga/icinga2/issues/2119) (Cluster): Remove virtual agent name feature for localhost * [#2118](https://github.com/icinga/icinga2/issues/2118) (CLI): Cli command: Node Setup Wizard \(for Satellites and Agents\) * [#2115](https://github.com/icinga/icinga2/issues/2115) (CLI): Cli command: Repository remove host should remove host.conf host/ dir with services * [#2113](https://github.com/icinga/icinga2/issues/2113) (CLI): validate repository config updates * [#2108](https://github.com/icinga/icinga2/issues/2108): Only build YAJL when there's no system-provided version available * [#2107](https://github.com/icinga/icinga2/issues/2107): Replace cJSON with a better JSON parser * [#2104](https://github.com/icinga/icinga2/issues/2104) (CLI): Use "variable get" for "pki ticket" * [#2103](https://github.com/icinga/icinga2/issues/2103) (CLI): Validate number of arguments * [#2098](https://github.com/icinga/icinga2/issues/2098) (CLI): Support for writing api.conf * [#2096](https://github.com/icinga/icinga2/issues/2096) (CLI): Cli command: pki needs option to define the algorithm * [#2092](https://github.com/icinga/icinga2/issues/2092) (CLI): Rename PKI arguments * [#2088](https://github.com/icinga/icinga2/issues/2088) (CLI): Cli command: Node Setup * [#2087](https://github.com/icinga/icinga2/issues/2087) (CLI): "pki request" should ask user to verify the peer's certificate * [#2086](https://github.com/icinga/icinga2/issues/2086) (CLI): Add -h next to --help * [#2085](https://github.com/icinga/icinga2/issues/2085) (CLI): Remove "available features" list from "feature list" * [#2084](https://github.com/icinga/icinga2/issues/2084) (CLI): Implement "feature disable" for Windows * [#2081](https://github.com/icinga/icinga2/issues/2081) (CLI): CLI: List disabled features in feature list too * [#2079](https://github.com/icinga/icinga2/issues/2079): Move WSAStartup call to INITIALIZE\_ONCE * [#2076](https://github.com/icinga/icinga2/issues/2076) (CLI): Implement field attribute to hide fields in command auto-completion * [#2074](https://github.com/icinga/icinga2/issues/2074) (CLI): Add autocomplete to 'host/service add' for object attributes \(e.g. --check\_interval\) * [#2073](https://github.com/icinga/icinga2/issues/2073) (Configuration): Remove zone keyword and allow to use object attribute 'zone' * [#2071](https://github.com/icinga/icinga2/issues/2071) (Configuration): Move localhost config into repository * [#2069](https://github.com/icinga/icinga2/issues/2069) (CLI): Implement generic color support for terminals * [#2066](https://github.com/icinga/icinga2/issues/2066) (CLI): Implement support for serial files * [#2064](https://github.com/icinga/icinga2/issues/2064) (DB IDO): Add program\_version column to programstatus table * [#2062](https://github.com/icinga/icinga2/issues/2062): Release 2.2 * [#2059](https://github.com/icinga/icinga2/issues/2059) (CLI): Auto-completion for feature enable/disable * [#2055](https://github.com/icinga/icinga2/issues/2055) (CLI): Windows support for cli command feature * [#2054](https://github.com/icinga/icinga2/issues/2054) (CLI): CLI Commands: Remove timestamp prefix when logging output * [#2053](https://github.com/icinga/icinga2/issues/2053) (CLI): autocomplete should support '--key value' * [#2050](https://github.com/icinga/icinga2/issues/2050) (CLI): Cli command parser must support unregistered boost::program\_options * [#2049](https://github.com/icinga/icinga2/issues/2049) (CLI): CLI command: variable * [#2046](https://github.com/icinga/icinga2/issues/2046) (Graphite): GraphiteWriter: Add warn/crit/min/max perfdata values if existing * [#2031](https://github.com/icinga/icinga2/issues/2031) (Graphite): GraphiteWriter: Add support for customized metric prefix names * [#2003](https://github.com/icinga/icinga2/issues/2003): macro processor needs an array printer * [#1999](https://github.com/icinga/icinga2/issues/1999) (CLI): Cli command: Repository * [#1997](https://github.com/icinga/icinga2/issues/1997) (CLI): Cli Commands: Node Repository Blacklist & Whitelist * [#1996](https://github.com/icinga/icinga2/issues/1996) (CLI): Cli command: SCM * [#1995](https://github.com/icinga/icinga2/issues/1995) (CLI): Cli command: Object * [#1994](https://github.com/icinga/icinga2/issues/1994) (CLI): Cli command: Feature * [#1993](https://github.com/icinga/icinga2/issues/1993) (CLI): Node Repository * [#1992](https://github.com/icinga/icinga2/issues/1992) (CLI): Cli command: Node * [#1991](https://github.com/icinga/icinga2/issues/1991) (CLI): Cli command: pki * [#1990](https://github.com/icinga/icinga2/issues/1990) (CLI): Cli command framework * [#1989](https://github.com/icinga/icinga2/issues/1989) (CLI): Cli commands * [#1988](https://github.com/icinga/icinga2/issues/1988) (Cluster): CSR auto-signing * [#1987](https://github.com/icinga/icinga2/issues/1987) (Plugins): Windows plugins * [#1986](https://github.com/icinga/icinga2/issues/1986) (Cluster): Windows Wizard * [#1977](https://github.com/icinga/icinga2/issues/1977) (CLI): Cli commands: add filter capability to 'object list' * [#1901](https://github.com/icinga/icinga2/issues/1901) (Cluster): Windows installer * [#1895](https://github.com/icinga/icinga2/issues/1895) (Graphite): Add downtime depth as statistic metric for GraphiteWriter * [#1717](https://github.com/icinga/icinga2/issues/1717) (Configuration): Support for array in custom variable. * [#894](https://github.com/icinga/icinga2/issues/894): Add copyright header to .ti files and add support for comments in mkclass ### Bug * [#2258](https://github.com/icinga/icinga2/issues/2258) (Configuration): Names for nested objects are evaluated at the wrong time * [#2257](https://github.com/icinga/icinga2/issues/2257) (Configuration): DebugInfo is missing for nested dictionaries * [#2254](https://github.com/icinga/icinga2/issues/2254): CreateProcess fails on Windows 7 * [#2241](https://github.com/icinga/icinga2/issues/2241) (Cluster): node wizard uses incorrect path for the CA certificate * [#2237](https://github.com/icinga/icinga2/issues/2237) (Configuration): Wrong set of dependency state when a host depends on a service * [#2235](https://github.com/icinga/icinga2/issues/2235): Unit tests fail to run * [#2233](https://github.com/icinga/icinga2/issues/2233): Get rid of static boost::mutex variables * [#2222](https://github.com/icinga/icinga2/issues/2222) (DB IDO): IDO module crashes on Windows * [#2221](https://github.com/icinga/icinga2/issues/2221): Installation on Windows fails * [#2220](https://github.com/icinga/icinga2/issues/2220) (Notifications): Missing state filter 'OK' must not prevent recovery notifications being sent * [#2215](https://github.com/icinga/icinga2/issues/2215): mkclass crashes when called without arguments * [#2214](https://github.com/icinga/icinga2/issues/2214) (Cluster): Removing multiple services fails * [#2206](https://github.com/icinga/icinga2/issues/2206): Plugin execution on Windows does not work * [#2205](https://github.com/icinga/icinga2/issues/2205): Compilation Error with boost 1.56 under Windows * [#2201](https://github.com/icinga/icinga2/issues/2201): Exception when executing check * [#2200](https://github.com/icinga/icinga2/issues/2200) (Configuration): Nested templates do not work \(anymore\) * [#2199](https://github.com/icinga/icinga2/issues/2199) (CLI): Typo in output of 'icinga2 object list' * [#2197](https://github.com/icinga/icinga2/issues/2197) (Notifications): only notify users on recovery which have been notified before \(not-ok state\) * [#2195](https://github.com/icinga/icinga2/issues/2195) (Cluster): Invalid checkresult object causes Icinga 2 to crash * [#2177](https://github.com/icinga/icinga2/issues/2177) (CLI): 'pki request' fails with serial permission error * [#2172](https://github.com/icinga/icinga2/issues/2172) (Configuration): There is no \_\_name available to nested objects * [#2171](https://github.com/icinga/icinga2/issues/2171) (Configuration): Nesting an object in a template causes the template to become non-abstract * [#2170](https://github.com/icinga/icinga2/issues/2170) (Configuration): Object list dump erraneously evaluates template definitions * [#2166](https://github.com/icinga/icinga2/issues/2166) (Cluster): Error message is always shown even when the host exists * [#2165](https://github.com/icinga/icinga2/issues/2165) (Cluster): Incorrect warning message for "node update-config" * [#2164](https://github.com/icinga/icinga2/issues/2164) (Cluster): Error in migrate-hosts * [#2162](https://github.com/icinga/icinga2/issues/2162) (CLI): Change blacklist/whitelist storage * [#2156](https://github.com/icinga/icinga2/issues/2156) (Cluster): Use ScriptVariable::Get for RunAsUser/RunAsGroup * [#2155](https://github.com/icinga/icinga2/issues/2155) (Cluster): Agent health check must not have zone attribute * [#2153](https://github.com/icinga/icinga2/issues/2153) (Cluster): Misleading error messages for blacklist/whitelist remove * [#2142](https://github.com/icinga/icinga2/issues/2142) (Configuration): Icinga2 fails to start due to configuration errors * [#2141](https://github.com/icinga/icinga2/issues/2141): Build fails * [#2137](https://github.com/icinga/icinga2/issues/2137): Utility::GetFQDN doesn't work on OS X * [#2134](https://github.com/icinga/icinga2/issues/2134): Hosts/services should not have themselves as parents * [#2133](https://github.com/icinga/icinga2/issues/2133): OnStateLoaded isn't called for objects which don't have any state * [#2132](https://github.com/icinga/icinga2/issues/2132) (CLI): cli command 'node setup update-config' overwrites existing constants.conf * [#2128](https://github.com/icinga/icinga2/issues/2128) (CLI): Cli: Node Setup/Wizard running as root must chown\(\) generated files to icinga daemon user * [#2127](https://github.com/icinga/icinga2/issues/2127) (Configuration): can't assign Service to Host in nested HostGroup * [#2125](https://github.com/icinga/icinga2/issues/2125) (Metrics): Performance data via API is broken * [#2116](https://github.com/icinga/icinga2/issues/2116) (CLI): Cli command: Repository should validate if object exists before add/remove * [#2106](https://github.com/icinga/icinga2/issues/2106) (Cluster): When replaying logs the secobj attribute is ignored * [#2091](https://github.com/icinga/icinga2/issues/2091) (CLI): Cli command: pki request throws exception on connection failure * [#2083](https://github.com/icinga/icinga2/issues/2083): CMake warnings on OS X * [#2077](https://github.com/icinga/icinga2/issues/2077) (CLI): CLI: Auto-completion with colliding arguments * [#2070](https://github.com/icinga/icinga2/issues/2070) (DB IDO): CLI / MySQL error during vagrant provisioning * [#2068](https://github.com/icinga/icinga2/issues/2068) (CLI): pki new-cert doesn't check whether the files were successfully written * [#2065](https://github.com/icinga/icinga2/issues/2065) (DB IDO): Schema upgrade files are missing in /usr/share/icinga2-ido-{mysql,pgsql} * [#2063](https://github.com/icinga/icinga2/issues/2063) (CLI): Cli commands: Integers in arrays are printed incorrectly * [#2057](https://github.com/icinga/icinga2/issues/2057) (CLI): failed en/disable feature should return error * [#2056](https://github.com/icinga/icinga2/issues/2056) (CLI): Commands are auto-completed when they shouldn't be * [#2051](https://github.com/icinga/icinga2/issues/2051) (Configuration): custom attribute name 'type' causes empty vars dictionary * [#2048](https://github.com/icinga/icinga2/issues/2048) (Compat): Fix reading perfdata in compat/checkresultreader * [#2042](https://github.com/icinga/icinga2/issues/2042) (Plugins): Setting snmp\_v2 can cause snmp-manubulon-command derived checks to fail * [#2038](https://github.com/icinga/icinga2/issues/2038) (Configuration): snmp-load checkcommand has a wrong "-T" param value * [#2034](https://github.com/icinga/icinga2/issues/2034) (Configuration): Importing a CheckCommand in a NotificationCommand results in an exception without stacktrace. * [#2029](https://github.com/icinga/icinga2/issues/2029) (Configuration): Error messages for invalid imports missing * [#2026](https://github.com/icinga/icinga2/issues/2026) (Configuration): config parser crashes on unknown attribute in assign * [#2006](https://github.com/icinga/icinga2/issues/2006) (Configuration): snmp-load checkcommand has wrong threshold syntax * [#2005](https://github.com/icinga/icinga2/issues/2005) (Metrics): icinga2 returns exponentail perfdata format with check\_nt * [#2004](https://github.com/icinga/icinga2/issues/2004) (Metrics): Icinga2 changes perfdata order and removes maximum * [#2001](https://github.com/icinga/icinga2/issues/2001) (Notifications): default value for "disable\_notifications" in service dependencies is set to "false" * [#1950](https://github.com/icinga/icinga2/issues/1950) (Configuration): Typo for "HTTP Checks" match in groups.conf * [#1720](https://github.com/icinga/icinga2/issues/1720) (Notifications): delaying notifications with times.begin should postpone first notification into that window ### ITL * [#2204](https://github.com/icinga/icinga2/issues/2204) (ITL): Plugin Check Commands: disk is missing '-p', 'x' parameter * [#2017](https://github.com/icinga/icinga2/issues/2017) (ITL): ITL: check\_procs and check\_http are missing arguments ### Documentation * [#2218](https://github.com/icinga/icinga2/issues/2218) (Documentation): Documentation: Update Icinga Web 2 installation * [#2191](https://github.com/icinga/icinga2/issues/2191) (Documentation): link missing in documentation about livestatus * [#2175](https://github.com/icinga/icinga2/issues/2175) (Documentation): Documentation for arrays & dictionaries in custom attributes and their usage in apply rules for * [#2160](https://github.com/icinga/icinga2/issues/2160) (Documentation): Documentation: Explain how to manage agent config in central repository * [#2150](https://github.com/icinga/icinga2/issues/2150) (Documentation): Documentation: Move troubleshooting after the getting started chapter * [#2143](https://github.com/icinga/icinga2/issues/2143) (Documentation): Documentation: Revamp getting started with 1 host and multiple \(service\) applies * [#2130](https://github.com/icinga/icinga2/issues/2130) (Documentation): Documentation: Mention 'icinga2 object list' in config validation * [#2129](https://github.com/icinga/icinga2/issues/2129) (Documentation): Fix typos and other small corrections in documentation * [#2093](https://github.com/icinga/icinga2/issues/2093) (Documentation): Documentation: 1-about contribute links to non-existing report a bug howto * [#2052](https://github.com/icinga/icinga2/issues/2052) (Documentation): Wrong usermod command for external command pipe setup * [#2041](https://github.com/icinga/icinga2/issues/2041) (Documentation): Documentation: Cli Commands * [#2037](https://github.com/icinga/icinga2/issues/2037) (Documentation): Documentation: Wrong check command for snmp-int\(erface\) * [#2033](https://github.com/icinga/icinga2/issues/2033) (Documentation): Docs: Default command timeout is 60s not 5m * [#2028](https://github.com/icinga/icinga2/issues/2028) (Documentation): Icinga2 docs: link supported operators from sections about apply rules * [#2024](https://github.com/icinga/icinga2/issues/2024) (Documentation): Documentation: Add support for locally-scoped variables for host/service in applied Dependency * [#2013](https://github.com/icinga/icinga2/issues/2013) (Documentation): Documentation: Add host/services variables in apply rules * [#1998](https://github.com/icinga/icinga2/issues/1998) (Documentation): Documentation: Agent/Satellite Setup * [#1972](https://github.com/icinga/icinga2/issues/1972) (Documentation): Document how to use multiple assign/ignore statements with logical "and" & "or" ### Support * [#2253](https://github.com/icinga/icinga2/issues/2253) (Packages): Conditionally enable MySQL and PostgresSQL, add support for FreeBSD and DragonFlyBSD * [#2236](https://github.com/icinga/icinga2/issues/2236) (Packages): Enable parallel builds for the Debian package * [#2147](https://github.com/icinga/icinga2/issues/2147) (Packages): Feature `checker' is not enabled when installing Icinga 2 using our lates RPM snapshot packages * [#2136](https://github.com/icinga/icinga2/issues/2136) (Packages): Build fails on RHEL 6.6 * [#2123](https://github.com/icinga/icinga2/issues/2123) (Packages): Post-update script \(migrate-hosts\) isn't run on RPM-based distributions * [#2095](https://github.com/icinga/icinga2/issues/2095) (Packages): Unity build fails on RHEL 5 * [#2058](https://github.com/icinga/icinga2/issues/2058) (Packages): Debian package root permissions interfere with icinga2 cli commands as icinga user * [#2007](https://github.com/icinga/icinga2/issues/2007) (Packages): SLES \(Suse Linux Enterprise Server\) 11 SP3 package dependency failure ## 2.1.1 (2014-09-16) ### Enhancement * [#1938](https://github.com/icinga/icinga2/issues/1938): Unity builds: Detect whether \_\_COUNTER\_\_ is available * [#1933](https://github.com/icinga/icinga2/issues/1933): Implement support for unity builds * [#1932](https://github.com/icinga/icinga2/issues/1932): Ensure that namespaces for INITIALIZE\_ONCE and REGISTER\_TYPE are truly unique * [#1931](https://github.com/icinga/icinga2/issues/1931): Add include guards for mkclass files * [#1797](https://github.com/icinga/icinga2/issues/1797): Change log message for checking/sending notifications ### Bug * [#1975](https://github.com/icinga/icinga2/issues/1975): fix memory leak ido\_pgsql * [#1971](https://github.com/icinga/icinga2/issues/1971) (Livestatus): Livestatus hangs from time to time * [#1967](https://github.com/icinga/icinga2/issues/1967) (Plugins): fping4 doesn't work correctly with the shipped command-plugins.conf * [#1966](https://github.com/icinga/icinga2/issues/1966) (Cluster): Segfault using cluster in TlsStream::IsEof * [#1958](https://github.com/icinga/icinga2/issues/1958) (Configuration): Manubulon-Plugin conf Filename wrong * [#1957](https://github.com/icinga/icinga2/issues/1957): Build fails on Haiku * [#1955](https://github.com/icinga/icinga2/issues/1955) (Cluster): new SSL Errors with too many queued messages * [#1954](https://github.com/icinga/icinga2/issues/1954): Missing differentiation between service and systemctl * [#1952](https://github.com/icinga/icinga2/issues/1952) (Metrics): GraphiteWriter should ignore empty perfdata value * [#1948](https://github.com/icinga/icinga2/issues/1948): pipe2 returns ENOSYS on GNU Hurd and Debian kfreebsd * [#1946](https://github.com/icinga/icinga2/issues/1946): Exit code is not initialized for some failed checks * [#1940](https://github.com/icinga/icinga2/issues/1940): icinga2-list-objects complains about Umlauts and stops output * [#1935](https://github.com/icinga/icinga2/issues/1935): icinga2-list-objects doesn't work with Python 3 * [#1934](https://github.com/icinga/icinga2/issues/1934) (Configuration): Remove validator for the Script type * [#1930](https://github.com/icinga/icinga2/issues/1930): "Error parsing performance data" in spite of "enable\_perfdata = false" * [#1910](https://github.com/icinga/icinga2/issues/1910) (Cluster): SSL errors with interleaved SSL\_read/write * [#1862](https://github.com/icinga/icinga2/issues/1862) (Cluster): SSL\_read errors during restart * [#1849](https://github.com/icinga/icinga2/issues/1849) (Cluster): Too many queued messages * [#1782](https://github.com/icinga/icinga2/issues/1782): make test fails on openbsd * [#1522](https://github.com/icinga/icinga2/issues/1522): Link libcJSON against libm ### Documentation * [#1985](https://github.com/icinga/icinga2/issues/1985) (Documentation): clarify on db ido upgrades * [#1962](https://github.com/icinga/icinga2/issues/1962) (Documentation): Extend documentation for icinga-web on Debian systems * [#1949](https://github.com/icinga/icinga2/issues/1949) (Documentation): Explain event commands and their integration by a real life example \(httpd restart via ssh\) * [#1927](https://github.com/icinga/icinga2/issues/1927) (Documentation): Document how to use @ to escape keywords ### Support * [#1960](https://github.com/icinga/icinga2/issues/1960) (Packages): GNUInstallDirs.cmake outdated * [#1944](https://github.com/icinga/icinga2/issues/1944) (Packages): service icinga2 status - prints cat error if the service is stopped * [#1941](https://github.com/icinga/icinga2/issues/1941) (Packages): icinga2 init-script terminates with exit code 0 if $DAEMON is not in place or not executable * [#1939](https://github.com/icinga/icinga2/issues/1939) (Packages): Enable unity build for RPM/Debian packages * [#1937](https://github.com/icinga/icinga2/issues/1937) (Packages): Figure out a better way to set the version for snapshot builds * [#1936](https://github.com/icinga/icinga2/issues/1936) (Packages): Fix rpmlint errors * [#1928](https://github.com/icinga/icinga2/issues/1928) (Packages): icinga2.spec: files-attr-not-set for python-icinga2 package ## 2.1.0 (2014-08-29) ### Notes * DB IDO schema upgrade ([MySQL](#upgrading-mysql-db),[PostgreSQL](#upgrading-postgresql-db) required! * new schema version: **1.11.7** * RPMs install the schema files into `/usr/share/icinga2-ido*` instead of `/usr/share/doc/icinga2-ido*` #6881 * [Information for config objects](#list-configuration-objects) using `icinga2-list-objects` script #6702 * Add Python 2.4 as requirement #6702 * Add search path: If `-c /etc/icinga2/icinga2.conf` is omitted, use `SysconfDir + "/icinga2/icinga2.conf"` #6874 * Change log level for failed commands #6751 * Notifications are load-balanced in a [High Availability cluster setup](#high-availability-notifications) #6203 * New config attribute: `enable_ha` * DB IDO "run once" or "run everywhere" mode in a [High Availability cluster setup](#high-availability-db-ido) #6203 #6827 * New config attributes: `enable_ha` and `failover_timeout` * RPMs use the `icingacmd` group for /var/{cache,log,run}/icinga2 #6948 ### Enhancement * [#1879](https://github.com/icinga/icinga2/issues/1879): Enhance logging for perfdata/graphitewriter * [#1871](https://github.com/icinga/icinga2/issues/1871) (Configuration): add search path for icinga2.conf * [#1843](https://github.com/icinga/icinga2/issues/1843) (DB IDO): delay ido connect in ha cluster * [#1810](https://github.com/icinga/icinga2/issues/1810): Change log level for failed commands * [#1788](https://github.com/icinga/icinga2/issues/1788): Release 2.1 * [#1786](https://github.com/icinga/icinga2/issues/1786) (Configuration): Information for config objects * [#1760](https://github.com/icinga/icinga2/issues/1760) (Plugins): Plugin Check Commands: add manubulon snmp plugins * [#1548](https://github.com/icinga/icinga2/issues/1548) (Cluster): Log replay sends messages to instances which shouldn't get those messages * [#1546](https://github.com/icinga/icinga2/issues/1546) (Cluster): Better cluster support for notifications / IDO * [#1491](https://github.com/icinga/icinga2/issues/1491) (Cluster): Better log messages for cluster changes * [#977](https://github.com/icinga/icinga2/issues/977) (Cluster): Cluster support for modified attributes ### Bug * [#1916](https://github.com/icinga/icinga2/issues/1916): Build fails with Boost 1.56 * [#1903](https://github.com/icinga/icinga2/issues/1903) (Cluster): Host and service checks stuck in "pending" when hostname = localhost a parent/satellite setup * [#1902](https://github.com/icinga/icinga2/issues/1902): Commands are processed multiple times * [#1896](https://github.com/icinga/icinga2/issues/1896): check file permissions in /var/cache/icinga2 * [#1884](https://github.com/icinga/icinga2/issues/1884): External command pipe: Too many open files * [#1819](https://github.com/icinga/icinga2/issues/1819): ExternalCommandListener fails open pipe: Too many open files ### Documentation * [#1924](https://github.com/icinga/icinga2/issues/1924) (Documentation): add example selinux policy for external command pipe * [#1915](https://github.com/icinga/icinga2/issues/1915) (Documentation): how to add a new cluster node * [#1913](https://github.com/icinga/icinga2/issues/1913) (Documentation): Keyword "required" used inconsistently for host and service "icon\_image\*" attributes * [#1905](https://github.com/icinga/icinga2/issues/1905) (Documentation): Update command arguments 'set\_if' and beautify error message * [#1897](https://github.com/icinga/icinga2/issues/1897) (Documentation): Add documentation for icinga2-list-objects * [#1889](https://github.com/icinga/icinga2/issues/1889) (Documentation): Enhance Graphite Writer description * [#1881](https://github.com/icinga/icinga2/issues/1881) (Documentation): clarify on which config tools are available * [#1872](https://github.com/icinga/icinga2/issues/1872) (Documentation): Wrong parent in Load Distribution * [#1868](https://github.com/icinga/icinga2/issues/1868) (Documentation): Wrong object attribute 'enable\_flap\_detection' * [#1867](https://github.com/icinga/icinga2/issues/1867) (Documentation): Add systemd options: enable, journal * [#1865](https://github.com/icinga/icinga2/issues/1865) (Documentation): add section about disabling re-notifications * [#1864](https://github.com/icinga/icinga2/issues/1864) (Documentation): Add section for reserved keywords * [#1847](https://github.com/icinga/icinga2/issues/1847) (Documentation): Explain how the order attribute works in commands * [#1807](https://github.com/icinga/icinga2/issues/1807) (Documentation): Better explanation for HA config cluster * [#1787](https://github.com/icinga/icinga2/issues/1787) (Documentation): Documentation for zones and cluster permissions * [#1761](https://github.com/icinga/icinga2/issues/1761) (Documentation): Migration: note on check command timeouts ### Support * [#1923](https://github.com/icinga/icinga2/issues/1923) (Packages): 64-bit RPMs are not installable * [#1888](https://github.com/icinga/icinga2/issues/1888) (Packages): Recommend related packages on SUSE distributions * [#1887](https://github.com/icinga/icinga2/issues/1887) (Installation): Clean up spec file * [#1885](https://github.com/icinga/icinga2/issues/1885) (Packages): enforce /usr/lib as base for the cgi path on SUSE distributions * [#1883](https://github.com/icinga/icinga2/issues/1883) (Installation): use \_rundir macro for configuring the run directory * [#1873](https://github.com/icinga/icinga2/issues/1873) (Packages): make install does not install the db-schema ## 2.0.2 (2014-08-07) ### Notes * DB IDO schema upgrade required (new schema version: 1.11.6) ### Enhancement * [#1830](https://github.com/icinga/icinga2/issues/1830) (Plugins): Plugin Check Commands: Add timeout option to check\_ssh * [#1826](https://github.com/icinga/icinga2/issues/1826): Print application paths for --version * [#1785](https://github.com/icinga/icinga2/issues/1785): Release 2.0.2 * [#1784](https://github.com/icinga/icinga2/issues/1784) (Configuration): Require command to be an array when the arguments attribute is used * [#1781](https://github.com/icinga/icinga2/issues/1781) (Plugins): Plugin Check Commands: Add expect option to check\_http ### Bug * [#1861](https://github.com/icinga/icinga2/issues/1861): write startup error messages to error.log * [#1858](https://github.com/icinga/icinga2/issues/1858): event command execution does not call finish handler * [#1855](https://github.com/icinga/icinga2/issues/1855): Startup logfile is not flushed to disk * [#1853](https://github.com/icinga/icinga2/issues/1853) (DB IDO): exit application if ido schema version does not match * [#1852](https://github.com/icinga/icinga2/issues/1852): Error handler for getaddrinfo must use gai\_strerror * [#1848](https://github.com/icinga/icinga2/issues/1848): Missing space in error message * [#1840](https://github.com/icinga/icinga2/issues/1840): \[Patch\] Fix build issue and crash found on Solaris, potentially other Unix OSes * [#1839](https://github.com/icinga/icinga2/issues/1839): Icinga 2 crashes during startup * [#1834](https://github.com/icinga/icinga2/issues/1834) (Cluster): High Availablity does not synchronise the data like expected * [#1829](https://github.com/icinga/icinga2/issues/1829): Service icinga2 reload command does not cause effect * [#1828](https://github.com/icinga/icinga2/issues/1828): Fix notification definition if no host\_name / service\_description given * [#1816](https://github.com/icinga/icinga2/issues/1816): Config validation without filename argument fails with unhandled exception * [#1813](https://github.com/icinga/icinga2/issues/1813) (Metrics): GraphiteWriter: Malformatted integer values * [#1800](https://github.com/icinga/icinga2/issues/1800) (Cluster): TLS Connections still unstable in 2.0.1 * [#1796](https://github.com/icinga/icinga2/issues/1796): "order" attribute doesn't seem to work as expected * [#1792](https://github.com/icinga/icinga2/issues/1792) (Configuration): sample config: add check commands location hint \(itl/plugin check commands\) * [#1779](https://github.com/icinga/icinga2/issues/1779) (Configuration): Remove superfluous quotes and commas in dictionaries * [#1778](https://github.com/icinga/icinga2/issues/1778): Event Commands are triggered in OK HARD state everytime * [#1775](https://github.com/icinga/icinga2/issues/1775): additional group rights missing when Icinga started with -u and -g * [#1774](https://github.com/icinga/icinga2/issues/1774) (Cluster): Missing detailed error messages on ApiListener SSL Errors * [#1766](https://github.com/icinga/icinga2/issues/1766): RPMLint security warning - missing-call-to-setgroups-before-setuid /usr/sbin/icinga2 * [#1757](https://github.com/icinga/icinga2/issues/1757) (DB IDO): NULL vs empty string * [#1752](https://github.com/icinga/icinga2/issues/1752) (Cluster): Infinite loop in TlsStream::Close * [#1744](https://github.com/icinga/icinga2/issues/1744) (DB IDO): Two Custom Variables with same name, but Upper/Lowercase creating IDO duplicate entry * [#1741](https://github.com/icinga/icinga2/issues/1741): Command pipe blocks when trying to open it more than once in parallel * [#1730](https://github.com/icinga/icinga2/issues/1730): Check and retry intervals are incorrect * [#1729](https://github.com/icinga/icinga2/issues/1729): $TOTALHOSTSERVICESWARNING$ and $TOTALHOSTSERVICESCRITICAL$ aren't getting converted * [#1728](https://github.com/icinga/icinga2/issues/1728): Service dependencies aren't getting converted properly * [#1726](https://github.com/icinga/icinga2/issues/1726): group names quoted twice in arrays * [#1723](https://github.com/icinga/icinga2/issues/1723): add log message for invalid performance data * [#1722](https://github.com/icinga/icinga2/issues/1722): GraphiteWriter regularly sends empty lines * [#1721](https://github.com/icinga/icinga2/issues/1721) (Configuration): Add cmake constant for PluginDir * [#1684](https://github.com/icinga/icinga2/issues/1684) (Notifications): Notifications not always triggered * [#1674](https://github.com/icinga/icinga2/issues/1674): ipmi-sensors segfault due to stack size * [#1666](https://github.com/icinga/icinga2/issues/1666) (DB IDO): objects and their ids are inserted twice ### ITL * [#1825](https://github.com/icinga/icinga2/issues/1825) (ITL): The "ssl" check command always sets -D * [#1821](https://github.com/icinga/icinga2/issues/1821) (ITL): Order doesn't work in check ssh command ### Documentation * [#1802](https://github.com/icinga/icinga2/issues/1802) (Documentation): wrong path for the file 'localhost.conf' * [#1801](https://github.com/icinga/icinga2/issues/1801) (Documentation): Missing documentation about implicit dependency * [#1791](https://github.com/icinga/icinga2/issues/1791) (Documentation): icinga Web: wrong path to command pipe * [#1789](https://github.com/icinga/icinga2/issues/1789) (Documentation): update installation with systemd usage * [#1762](https://github.com/icinga/icinga2/issues/1762) (Documentation): clarify on which features are required for classic ui/web/web2 ### Support * [#1845](https://github.com/icinga/icinga2/issues/1845) (Packages): Remove if\(NOT DEFINED ICINGA2\_SYSCONFIGFILE\) in etc/initsystem/CMakeLists.txt * [#1842](https://github.com/icinga/icinga2/issues/1842) (Packages): incorrect sysconfig path on sles11 * [#1820](https://github.com/icinga/icinga2/issues/1820) (Installation): Repo Error on RHEL 6.5 * [#1780](https://github.com/icinga/icinga2/issues/1780) (Packages): Rename README to README.md * [#1763](https://github.com/icinga/icinga2/issues/1763) (Packages): Build packages for el7 * [#1754](https://github.com/icinga/icinga2/issues/1754) (Installation): Location of the run directory is hard coded and bound to "local\_state\_dir" * [#1699](https://github.com/icinga/icinga2/issues/1699) (Packages): Classic UI Debian/Ubuntu: apache 2.4 requires 'a2enmod cgi' & apacheutils installed * [#1338](https://github.com/icinga/icinga2/issues/1338) (Packages): SUSE packages ## 2.0.1 (2014-07-10) ### Notes Bugfix release ### Enhancement * [#1713](https://github.com/icinga/icinga2/issues/1713) (Configuration): Add port option to check imap/pop/smtp and a new dig * [#1049](https://github.com/icinga/icinga2/issues/1049) (Livestatus): OutputFormat python ### Bug * [#1773](https://github.com/icinga/icinga2/issues/1773) (Notifications): Problem with enable\_notifications and retained state * [#1772](https://github.com/icinga/icinga2/issues/1772) (Notifications): enable\_notifications = false for users has no effect * [#1771](https://github.com/icinga/icinga2/issues/1771) (Cluster): Icinga crashes after "Too many queued messages" * [#1769](https://github.com/icinga/icinga2/issues/1769): Build fails when MySQL is not installed * [#1767](https://github.com/icinga/icinga2/issues/1767): Increase icinga.cmd Limit * [#1753](https://github.com/icinga/icinga2/issues/1753) (Configuration): icinga2-sign-key creates ".crt" and ".key" files when the CA passphrase is invalid * [#1751](https://github.com/icinga/icinga2/issues/1751) (Configuration): icinga2-build-ca shouldn't prompt for DN * [#1749](https://github.com/icinga/icinga2/issues/1749): TLS connections are still unstable * [#1745](https://github.com/icinga/icinga2/issues/1745): Icinga stops updating IDO after a while * [#1743](https://github.com/icinga/icinga2/issues/1743) (Configuration): Please add --sni option to http check command * [#1740](https://github.com/icinga/icinga2/issues/1740) (Notifications): Notifications causing segfault from exim * [#1737](https://github.com/icinga/icinga2/issues/1737) (DB IDO): icinga2-ido-pgsql snapshot package missing dependecy dbconfig-common * [#1736](https://github.com/icinga/icinga2/issues/1736): Remove line number information from stack traces * [#1734](https://github.com/icinga/icinga2/issues/1734): Check command result doesn't match * [#1731](https://github.com/icinga/icinga2/issues/1731): Dependencies should cache their parent and child object * [#1727](https://github.com/icinga/icinga2/issues/1727): $SERVICEDESC$ isn't getting converted correctly * [#1724](https://github.com/icinga/icinga2/issues/1724): Improve systemd service definition * [#1716](https://github.com/icinga/icinga2/issues/1716) (Cluster): Icinga doesn't send SetLogPosition messages when one of the endpoints fails to connect * [#1712](https://github.com/icinga/icinga2/issues/1712): parsing of double defined command can generate unexpected errors * [#1704](https://github.com/icinga/icinga2/issues/1704): Reminder notifications are sent on disabled services * [#1698](https://github.com/icinga/icinga2/issues/1698): icinga2 cannot be built with both systemd and init.d files * [#1697](https://github.com/icinga/icinga2/issues/1697) (Livestatus): Thruk Panorama View cannot query Host Status * [#1695](https://github.com/icinga/icinga2/issues/1695): icinga2.state could not be opened * [#1691](https://github.com/icinga/icinga2/issues/1691): build warnings * [#1644](https://github.com/icinga/icinga2/issues/1644) (Cluster): base64 on CentOS 5 fails to read certificate bundles * [#1639](https://github.com/icinga/icinga2/issues/1639) (Cluster): Deadlock in ApiListener::RelayMessage * [#1609](https://github.com/icinga/icinga2/issues/1609): application fails to start on wrong log file permissions but does not tell about it * [#1206](https://github.com/icinga/icinga2/issues/1206) (DB IDO): PostgreSQL string escaping ### ITL * [#1739](https://github.com/icinga/icinga2/issues/1739) (ITL): Add more options to snmp check ### Documentation * [#1777](https://github.com/icinga/icinga2/issues/1777) (Documentation): event command execution cases are missing * [#1765](https://github.com/icinga/icinga2/issues/1765) (Documentation): change docs.icinga.org/icinga2/latest to git master * [#1742](https://github.com/icinga/icinga2/issues/1742) (Documentation): Documentation for || and && is missing * [#1702](https://github.com/icinga/icinga2/issues/1702) (Documentation): Array section confusing ### Support * [#1764](https://github.com/icinga/icinga2/issues/1764) (Installation): ICINGA2\_SYSCONFIGFILE should use full path using CMAKE\_INSTALL\_FULL\_SYSCONFDIR * [#1709](https://github.com/icinga/icinga2/issues/1709) (Packages): htpasswd should be installed with icinga2-classicui on Ubuntu * [#1696](https://github.com/icinga/icinga2/issues/1696) (Packages): Copyright problems * [#1655](https://github.com/icinga/icinga2/issues/1655) (Packages): Debian package icinga2-classicui needs versioned dependency of icinga-cgi\* ## 2.0.0 (2014-06-16) ### Notes First official release ### Enhancement * [#1600](https://github.com/icinga/icinga2/issues/1600): Prepare 2.0.0 release * [#1575](https://github.com/icinga/icinga2/issues/1575) (Cluster): Cluster: global zone for all nodes * [#1348](https://github.com/icinga/icinga2/issues/1348): move vagrant box into dedicated demo project * [#1341](https://github.com/icinga/icinga2/issues/1341): Revamp migration script * [#1322](https://github.com/icinga/icinga2/issues/1322): Update website for release * [#1320](https://github.com/icinga/icinga2/issues/1320): Update documentation for 2.0 ### Bug * [#1694](https://github.com/icinga/icinga2/issues/1694): Separate CMakeLists.txt for etc/initsystem * [#1682](https://github.com/icinga/icinga2/issues/1682) (Configuration): logrotate.conf file should rotate log files as icinga user * [#1680](https://github.com/icinga/icinga2/issues/1680) (Livestatus): Column 'host\_name' does not exist in table 'hosts' * [#1678](https://github.com/icinga/icinga2/issues/1678) (Livestatus): Nagvis does not work with livestatus \(invalid format\) * [#1673](https://github.com/icinga/icinga2/issues/1673): OpenSUSE Packages do not enable basic features * [#1669](https://github.com/icinga/icinga2/issues/1669) (Cluster): Segfault with zones without endpoints on config compile * [#1642](https://github.com/icinga/icinga2/issues/1642): Check if host recovery notifications work * [#1615](https://github.com/icinga/icinga2/issues/1615) (Cluster): Subdirectories in the zone config are not synced * [#1427](https://github.com/icinga/icinga2/issues/1427): fd-handling in Daemonize incorrect * [#1312](https://github.com/icinga/icinga2/issues/1312): Permissions error on startup is only logged but not on stderr ### ITL * [#1690](https://github.com/icinga/icinga2/issues/1690) (ITL): improve predefined command-plugins ### Documentation * [#1689](https://github.com/icinga/icinga2/issues/1689) (Documentation): explain the icinga 2 reload * [#1681](https://github.com/icinga/icinga2/issues/1681) (Documentation): Add instructions to install debug symbols on debian systems * [#1675](https://github.com/icinga/icinga2/issues/1675) (Documentation): add a note on no length restrictions for plugin output / perfdata * [#1636](https://github.com/icinga/icinga2/issues/1636) (Documentation): Update command definitions to use argument conditions * [#1572](https://github.com/icinga/icinga2/issues/1572) (Documentation): change docs.icinga.org/icinga2/snapshot to 'latest' * [#1302](https://github.com/icinga/icinga2/issues/1302) (Documentation): Replace Sphinx with Icinga Web 2 Doc Module ### Support * [#1686](https://github.com/icinga/icinga2/issues/1686) (Installation): man pages for scripts * [#1685](https://github.com/icinga/icinga2/issues/1685) (Installation): Cleanup installer for 2.0 supported features * [#1683](https://github.com/icinga/icinga2/issues/1683) (Installation): remove 0.0.x schema upgrade files * [#1670](https://github.com/icinga/icinga2/issues/1670) (Packages): Ubuntu package Release file lacks 'Suite' line * [#1645](https://github.com/icinga/icinga2/issues/1645) (Packages): Packages are not installable on CentOS 5 * [#1342](https://github.com/icinga/icinga2/issues/1342) (Installation): Less verbose start output using the initscript * [#1319](https://github.com/icinga/icinga2/issues/1319) (Tests): Release tests * [#907](https://github.com/icinga/icinga2/issues/907) (Packages): icinga2-classicui is not installable on Debian * [#788](https://github.com/icinga/icinga2/issues/788) (Packages): add systemd support icinga2-2.14.6/CMakeLists.txt000066400000000000000000000471651501332562400156760ustar00rootroot00000000000000# Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ cmake_minimum_required(VERSION 2.8.12) set(BOOST_MIN_VERSION "1.66.0") if("${CMAKE_VERSION}" VERSION_LESS "3.8") # SLES 12.5 if(NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") endif() else() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) endif() project(icinga2) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/third-party/cmake") if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) endif() if(WIN32) set(ICINGA2_MASTER OFF) else() set(ICINGA2_MASTER ON) endif() option(ICINGA2_WITH_MYSQL "Build the MySQL IDO module" ${ICINGA2_MASTER}) option(ICINGA2_WITH_PGSQL "Build the PostgreSQL IDO module" ${ICINGA2_MASTER}) option(ICINGA2_WITH_CHECKER "Build the checker module" ON) option(ICINGA2_WITH_COMPAT "Build the compat module" ${ICINGA2_MASTER}) option(ICINGA2_WITH_LIVESTATUS "Build the Livestatus module" ${ICINGA2_MASTER}) option(ICINGA2_WITH_NOTIFICATION "Build the notification module" ON) option(ICINGA2_WITH_PERFDATA "Build the perfdata module" ${ICINGA2_MASTER}) option(ICINGA2_WITH_TESTS "Run unit tests" ON) option(ICINGA2_WITH_ICINGADB "Build the IcingaDB module" ${ICINGA2_MASTER}) option (USE_SYSTEMD "Configure icinga as native systemd service instead of a SysV initscript" OFF) set(HAVE_SYSTEMD ${USE_SYSTEMD}) include(GNUInstallDirs) include(InstallConfig) include(SetFullDir) set(ICINGA2_USER "icinga" CACHE STRING "Icinga 2 user") set(ICINGA2_GROUP "icinga" CACHE STRING "Icinga 2 group") set(ICINGA2_COMMAND_GROUP "icingacmd" CACHE STRING "Icinga 2 command group") set(ICINGA2_PLUGINDIR "/usr/lib/nagios/plugins" CACHE STRING "Path for the check plugins") set(ICINGA2_GIT_VERSION_INFO ON CACHE BOOL "Whether to use git describe") set(ICINGA2_UNITY_BUILD ON CACHE BOOL "Whether to perform a unity build") set(ICINGA2_LTO_BUILD OFF CACHE BOOL "Whether to use LTO") set(ICINGA2_CONFIGDIR "${CMAKE_INSTALL_SYSCONFDIR}/icinga2" CACHE FILEPATH "Main config directory, e.g. /etc/icinga2") set(ICINGA2_CACHEDIR "${CMAKE_INSTALL_LOCALSTATEDIR}/cache/icinga2" CACHE FILEPATH "Directory for cache files, e.g. /var/cache/icinga2") set(ICINGA2_DATADIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/icinga2" CACHE FILEPATH "Data directory for the daemon, e.g. /var/lib/icinga2") set(ICINGA2_LOGDIR "${CMAKE_INSTALL_LOCALSTATEDIR}/log/icinga2" CACHE FILEPATH "Logging directory, e.g. /var/log/icinga2") set(ICINGA2_SPOOLDIR "${CMAKE_INSTALL_LOCALSTATEDIR}/spool/icinga2" CACHE FILEPATH "Spooling directory, e.g. /var/spool/icinga2") set(ICINGA2_RUNDIR "${CMAKE_INSTALL_LOCALSTATEDIR}/run" CACHE STRING "/run directory (deprecated, please use ICINGA2_INITRUNDIR)") set(ICINGA2_INITRUNDIR "${ICINGA2_RUNDIR}/icinga2" CACHE FILEPATH "Runtime data for the init system, e.g. /run/icinga2") set(ICINGA2_PKGDATADIR "${CMAKE_INSTALL_DATADIR}/icinga2" CACHE FILEPATH "Installed data, e.g. /usr/share/icinga2") set(ICINGA2_INCLUDEDIR "${ICINGA2_PKGDATADIR}/include" CACHE FILEPATH "Include directory for the ITL, e.g. /usr/share/icinga2/include") # ensure absolute paths set_full_dir(ICINGA2_FULL_CONFIGDIR "${ICINGA2_CONFIGDIR}") set_full_dir(ICINGA2_FULL_CACHEDIR "${ICINGA2_CACHEDIR}") set_full_dir(ICINGA2_FULL_DATADIR "${ICINGA2_DATADIR}") set_full_dir(ICINGA2_FULL_LOGDIR "${ICINGA2_LOGDIR}") set_full_dir(ICINGA2_FULL_SPOOLDIR "${ICINGA2_SPOOLDIR}") set_full_dir(ICINGA2_FULL_RUNDIR "${ICINGA2_RUNDIR}") set_full_dir(ICINGA2_FULL_INITRUNDIR "${ICINGA2_INITRUNDIR}") set_full_dir(ICINGA2_FULL_PKGDATADIR "${ICINGA2_PKGDATADIR}") set_full_dir(ICINGA2_FULL_INCLUDEDIR "${ICINGA2_INCLUDEDIR}") set(LOGROTATE_DIR "${CMAKE_INSTALL_SYSCONFDIR}/logrotate.d" CACHE STRING "Location of logrotate configs, e.g. /etc/logrotate.d") set(BASHCOMPLETION_DIR "${CMAKE_INSTALL_SYSCONFDIR}/bash_completion.d" CACHE STRING "Location of bash_completion files, e.g. /etc/bash_completion.d") if(NOT WIN32) set(ICINGA2_SYSCONFIGFILE "${CMAKE_INSTALL_SYSCONFDIR}/sysconfig/icinga2" CACHE PATH "where to store configuation for the init system, defaults to /etc/sysconfig/icinga2") endif() site_name(ICINGA2_BUILD_HOST_NAME) set(ICINGA2_BUILD_COMPILER_NAME "${CMAKE_CXX_COMPILER_ID}") if(NOT CMAKE_CXX_COMPILER_VERSION) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE CMAKE_CXX_COMPILER_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) endif() set(ICINGA2_BUILD_COMPILER_VERSION "${CMAKE_CXX_COMPILER_VERSION}") file(READ "${CMAKE_CURRENT_SOURCE_DIR}/COPYING" ICINGA2_LICENSE_GPL) set(ICINGA2_LICENSE "${ICINGA2_LICENSE_GPL}\n\n---\n\n${ICINGA2_LICENSE_ADDITIONS}") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt" ${ICINGA2_LICENSE}) file(STRINGS ICINGA2_VERSION SPEC_VERSION REGEX "^Version:") string(LENGTH "${SPEC_VERSION}" SPEC_VERSION_LENGTH) math(EXPR SPEC_VERSION_LENGTH "${SPEC_VERSION_LENGTH} - 9") string(SUBSTRING ${SPEC_VERSION} 9 ${SPEC_VERSION_LENGTH} SPEC_VERSION) configure_file(icinga-spec-version.h.cmake icinga-spec-version.h) include(GetGitRevisionDescription) git_describe(GIT_VERSION --tags) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/icinga-version.h.force) configure_file(icinga-version.h.force ${CMAKE_CURRENT_BINARY_DIR}/icinga-version.h COPYONLY) else() if(NOT ICINGA2_GIT_VERSION_INFO OR GIT_VERSION MATCHES "-NOTFOUND$") file(STRINGS ICINGA2_VERSION SPEC_REVISION REGEX "^Revision: ") string(LENGTH "${SPEC_REVISION}" SPEC_REVISION_LENGTH) math(EXPR SPEC_REVISION_LENGTH "${SPEC_REVISION_LENGTH} - 10") string(SUBSTRING ${SPEC_REVISION} 10 ${SPEC_REVISION_LENGTH} SPEC_REVISION) set(GIT_VERSION "r${SPEC_VERSION}-${SPEC_REVISION}") set(ICINGA2_VERSION "${SPEC_VERSION}") else() # use GIT version as ICINGA2_VERSION string(REGEX REPLACE "^[rv]" "" ICINGA2_VERSION "${GIT_VERSION}") endif() configure_file(icinga-version.h.cmake icinga-version.h) endif() # NuGet on Windows requires a semantic versioning, example: 2.10.4.123 (only 4 element, only numeric) string(REGEX REPLACE "-([0-9]+).*$" ".\\1" ICINGA2_VERSION_SAFE "${ICINGA2_VERSION}") string(REGEX REPLACE "-[^\\.]*(.*)$" "\\1" ICINGA2_VERSION_SAFE "${ICINGA2_VERSION_SAFE}") string(REGEX REPLACE "^([0-9]+\\.[0-9]+\\.[0-9]+)[\\.]?[0-9]*" "\\1" CHOCO_VERSION_SHORT "${ICINGA2_VERSION_SAFE}") message(STATUS "ICINGA2_VERSION_SAFE=${ICINGA2_VERSION_SAFE} CHOCO_VERSION_SHORT=${CHOCO_VERSION_SHORT}") if(WIN32) set(Boost_USE_STATIC_LIBS ON) # Disabled for linking issues for newer Boost versions, they link against Windows SDKs #add_definitions(-DBOOST_ALL_NO_LIB) # Disable optimization for Boost::context # https://www.boost.org/doc/libs/1_69_0/libs/context/doc/html/context/overview.html # https://docs.microsoft.com/en-us/cpp/build/reference/gl-whole-program-optimization?view=vs-2017 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj /GL- /EHs") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /GL- /EHs") # detect if 32-bit target if(CMAKE_VS_PLATFORM_NAME STREQUAL "Win32") # SAFESEH is not supported in Boost on Windows x86 # maybe it is when Boost is compiled with it... # https://lists.boost.org/Archives/boost/2013/10/206720.php # https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers?view=vs-2017 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") endif() endif() if(NOT DEFINED LOGROTATE_HAS_SU) set(LOGROTATE_HAS_SU OFF) find_program(LOGROTATE_BINARY logrotate) execute_process(COMMAND ${LOGROTATE_BINARY} ERROR_VARIABLE LOGROTATE_OUTPUT) if(LOGROTATE_OUTPUT) string(REGEX REPLACE "^logrotate ([0-9.]*).*" "\\1" LOGROTATE_VERSION ${LOGROTATE_OUTPUT}) message(STATUS "Found logrotate (found version \"${LOGROTATE_VERSION}\")") if("${LOGROTATE_VERSION}" VERSION_GREATER "3.7.9") set(LOGROTATE_HAS_SU ON) endif() endif() endif() if(LOGROTATE_HAS_SU) set(LOGROTATE_USE_SU "\n\tsu ${ICINGA2_USER} ${ICINGA2_GROUP}") else() set(LOGROTATE_CREATE "\n\tcreate 644 ${ICINGA2_USER} ${ICINGA2_GROUP}") endif() find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS coroutine context date_time filesystem iostreams thread system program_options regex REQUIRED) # Boost.Coroutine2 (the successor of Boost.Coroutine) # (1) doesn't even exist in old Boost versions and # (2) isn't supported by ASIO, yet. add_definitions(-DBOOST_COROUTINES_NO_DEPRECATION_WARNING) add_definitions(-DBOOST_FILESYSTEM_NO_DEPRECATED) # Required for Boost v1.74+ add_definitions(-DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT) link_directories(${Boost_LIBRARY_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) find_package(OpenSSL REQUIRED) include_directories(${OPENSSL_INCLUDE_DIR}) set(base_DEPS ${CMAKE_DL_LIBS} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES}) set(base_OBJS $ $ $) # JSON find_package(JSON) include_directories(${JSON_INCLUDE}) # UTF8CPP find_package(UTF8CPP) include_directories(${UTF8CPP_INCLUDE}) find_package(Editline) set(HAVE_EDITLINE "${EDITLINE_FOUND}") find_package(Termcap) set(HAVE_TERMCAP "${TERMCAP_FOUND}") include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/lib ) if(UNIX OR CYGWIN) list(APPEND base_OBJS $) endif() if(HAVE_SYSTEMD) list(APPEND base_DEPS systemd) endif() if(EDITLINE_FOUND) list(APPEND base_DEPS ${EDITLINE_LIBRARIES}) include_directories(${EDITLINE_INCLUDE_DIR}) endif() if(TERMCAP_FOUND) list(APPEND base_DEPS ${TERMCAP_LIBRARIES}) include_directories(${TERMCAP_INCLUDE_DIR}) endif() if(WIN32) list(APPEND base_DEPS ws2_32 dbghelp shlwapi msi) endif() set(CMAKE_MACOSX_RPATH 1) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${CMAKE_INSTALL_FULL_LIBDIR}/icinga2") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Qunused-arguments -fcolor-diagnostics -fno-limit-debug-info") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments -fcolor-diagnostics -fno-limit-debug-info") # Clang on Fedora requires -pthread, Apple Clang does not # AppleClang is available since CMake 3.0.0 if (NOT CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") endif() endif() if(CMAKE_C_COMPILER_ID STREQUAL "SunPro") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mt") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mt -library=stlport4") endif() if(CMAKE_C_COMPILER_ID STREQUAL "GNU") if(CMAKE_SYSTEM_NAME MATCHES AIX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -lpthread") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -lpthread") elseif(CMAKE_SYSTEM_NAME MATCHES "kOpenBSD.*|OpenBSD.*") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -pthread") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -pthread") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lpthread") set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -lpthread") else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -pthread") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -pthread") endif() endif() include(CheckCXXCompilerFlag) function(check_cxx_linker_flag flag var) set(CMAKE_REQUIRED_FLAGS ${flag}) set(result 0) check_cxx_compiler_flag(${flag} result) set(${var} ${result} PARENT_SCOPE) endfunction() check_cxx_linker_flag("-Wl,--gc-sections" LD_GC_SECTIONS) if(LD_GC_SECTIONS) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections") endif() check_cxx_linker_flag("-Wl,--no-export-dynamic" LD_NO_EXPORT_DYNAMIC) if(LD_NO_EXPORT_DYNAMIC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-export-dynamic") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-export-dynamic") endif() check_cxx_linker_flag("-Bsymbolic-functions" LD_SYMBOLIC_FUNCTIONS) if(LD_SYMBOLIC_FUNCTIONS) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Bsymbolic-functions") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Bsymbolic-functions") endif() check_cxx_linker_flag("-Wl,--dynamic-list-cpp-typeinfo" LD_DYNAMIC_LIST_CPP_TYPEINFO) if(LD_DYNAMIC_LIST_CPP_TYPEINFO) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--dynamic-list-cpp-typeinfo") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--dynamic-list-cpp-typeinfo") endif() check_cxx_linker_flag("-Wl,--dynamic-list-data" LD_DYNAMIC_LIST_DATA) if(LD_DYNAMIC_LIST_DATA) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--dynamic-list-data") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--dynamic-list-data") endif() check_cxx_compiler_flag("-Winvalid-pch" CXX_INVALID_PCH) if(CXX_INVALID_PCH) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Winvalid-pch") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Winvalid-pch") endif() if(ICINGA2_LTO_BUILD) check_cxx_compiler_flag("-flto" CXX_FLAG_LTO) if(NOT CXX_FLAG_LTO) message(WARNING "Compiler does not support LTO, falling back to non-LTO build") else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -flto") if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.0) AND NOT OPENBSD) set(CMAKE_AR "gcc-ar") set(CMAKE_RANLIB "gcc-ranlib") endif() endif() endif() if(MSVC) add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS) endif() set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/Bin/${CMAKE_BUILD_TYPE} CACHE PATH "Library output path") set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/Bin/${CMAKE_BUILD_TYPE} CACHE PATH "Executable output path") include(CheckSymbolExists) include(CheckFunctionExists) include(CheckLibraryExists) include(CheckIncludeFileCXX) check_symbol_exists(__COUNTER__ "" HAVE_COUNTER_MACRO) if(NOT HAVE_COUNTER_MACRO) message(FATAL_ERROR "Your C/C++ compiler does not support the __COUNTER__ macro.") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DI2_DEBUG") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DI2_DEBUG") check_function_exists(vfork HAVE_VFORK) check_function_exists(backtrace_symbols HAVE_BACKTRACE_SYMBOLS) check_function_exists(pipe2 HAVE_PIPE2) check_function_exists(nice HAVE_NICE) check_function_exists(malloc_info HAVE_MALLOC_INFO) check_library_exists(dl dladdr "dlfcn.h" HAVE_DLADDR) check_library_exists(execinfo backtrace_symbols "" HAVE_LIBEXECINFO) check_include_file_cxx(cxxabi.h HAVE_CXXABI_H) if(HAVE_LIBEXECINFO) set(HAVE_BACKTRACE_SYMBOLS TRUE) list(APPEND base_DEPS execinfo) endif() if(NOT WIN32) # boost::stacktrace uses _Unwind_Backtrace which is only exposed if _GNU_SOURCE is defined on most systems add_definitions(-D_GNU_SOURCE) endif() if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") set(ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS TRUE) endif() if(ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS AND NOT HAVE_BACKTRACE_SYMBOLS) message(FATAL_ERROR "ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS is set but backtrace_symbols() was not found") endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") exec_program(${CMAKE_CXX_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE _ICINGA2_COMPILER_VERSION ) if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "7.0.0") message(FATAL_ERROR "Your version of GCC (${CMAKE_CXX_COMPILER_VERSION}) is too old for building Icinga 2 (GCC >= 7.0.0 is required).") endif() endif() if(MSVC) if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "19.20") message(FATAL_ERROR "Your version of MSVC (${CMAKE_CXX_COMPILER_VERSION}) is too old for building Icinga 2 (MSVC >= 19.20 from Visual Studio 2019 is required).") endif() endif() if(NOT MSVC) check_cxx_source_compiles("class Base { public: virtual void test(void) { } }; class Derived : public Base { virtual void test(void) override { } }; int main(){}" CXX_FEATURE_OVERRIDE) if(NOT CXX_FEATURE_OVERRIDE) add_definitions("-Doverride=") endif() endif() # Architecture specifics # - Log the target architecture # - ARM needs to link against atomic if(NOT MSVC) # inspired by https://github.com/civetweb/civetweb/blob/master/cmake/DetermineTargetArchitecture.cmake execute_process( COMMAND ${CMAKE_C_COMPILER} -dumpmachine RESULT_VARIABLE RESULT OUTPUT_VARIABLE ARCH ERROR_QUIET ) if (RESULT) message(STATUS "Failed to detect target architecture with compiler ${CMAKE_C_COMPILER}: ${RESULT}") endif() string(REGEX MATCH "([^-]+).*" ARCH_MATCH "${ARCH}") if (NOT CMAKE_MATCH_1 OR NOT ARCH_MATCH) message(STATUS "Failed to match the target architecture: ${ARCH}") endif() set(ARCH ${CMAKE_MATCH_1}) message(STATUS "Target architecture - ${ARCH}") # ARM settings if("${ARCH}" STREQUAL "arm") check_cxx_source_compiles( "include ; int main(){ std::atomic x; x.fetch_add(1); x.sub_add(1); }" CXX_ATOMIC) link_libraries(atomic) endif() else() if("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "X86") set(ARCH "i686") elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "x64") set(ARCH "x86_64") elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM") set(ARCH "arm") else() message(FATAL_ERROR "Failed to determine the MSVC target architecture: ${MSVC_C_ARCHITECTURE_ID}") endif() message(STATUS "Target architecture - ${ARCH}") endif() configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h ESCAPE_QUOTES) install( FILES README.md COPYING AUTHORS CHANGELOG.md NEWS DESTINATION ${CMAKE_INSTALL_DOCDIR} ) include(CTest) enable_testing() set_property(GLOBAL PROPERTY USE_FOLDERS ON) add_subdirectory(third-party) add_subdirectory(tools) add_subdirectory(lib) add_subdirectory(icinga-app) add_subdirectory(etc) add_subdirectory(itl) add_subdirectory(agent) add_subdirectory(plugins) add_subdirectory(choco) if(NOT WIN32) add_subdirectory(doc) endif() if(MSVC) add_subdirectory(icinga-installer) endif() if(ICINGA2_WITH_TESTS) add_subdirectory(test) endif() set(CPACK_PACKAGE_NAME "Icinga 2") set(CPACK_PACKAGE_VENDOR "Icinga GmbH") set(CPACK_PACKAGE_VERSION ${ICINGA2_VERSION_SAFE}) set(CPACK_PACKAGE_INSTALL_DIRECTORY "ICINGA2") set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icinga-app\\\\icinga.ico") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt") set(CPACK_PACKAGE_EXECUTABLES "Icinga2SetupAgent;Icinga 2 Agent Wizard") set(CPACK_WIX_PRODUCT_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icinga-app\\\\icinga.ico") set(CPACK_WIX_UPGRADE_GUID "52F2BEAA-4DF0-4C3E-ABDC-C0F61DE4DF8A") set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_SOURCE_DIR}/icinga-installer/bannrbmp.bmp") set(CPACK_WIX_UI_DIALOG "${CMAKE_CURRENT_SOURCE_DIR}/icinga-installer/dlgbmp.bmp") set(CPACK_WIX_PATCH_FILE "${CMAKE_CURRENT_BINARY_DIR}/icinga-installer/icinga2.wixpatch.Debug") set(CPACK_WIX_PATCH_FILE "${CMAKE_CURRENT_BINARY_DIR}/icinga-installer/icinga2.wixpatch") set(CPACK_WIX_EXTENSIONS "WixUtilExtension" "WixNetFxExtension") set(CPACK_WIX_INSTALL_SCOPE NONE) set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "sbin") set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) include(InstallRequiredSystemLibraries) if(WIN32) if (CMAKE_VS_PLATFORM_NAME STREQUAL "x64") set(ICINGA2_OPENSSL_DLL_ARCH "-x64") else() set(ICINGA2_OPENSSL_DLL_ARCH "") endif() foreach(ICINGA2_OPENSSL_LIB crypto ssl) list(APPEND ICINGA2_OPENSSL_DLLS ${OPENSSL_INCLUDE_DIR}/../bin/lib${ICINGA2_OPENSSL_LIB}-3${ICINGA2_OPENSSL_DLL_ARCH}.dll) endforeach() install( PROGRAMS ${ICINGA2_OPENSSL_DLLS} DESTINATION ${CMAKE_INSTALL_SBINDIR} ) endif() include(CPack) icinga2-2.14.6/CONTRIBUTING.md000066400000000000000000000367501501332562400153650ustar00rootroot00000000000000# Contributing Icinga is an open source project and lives from your ideas and contributions. There are many ways to contribute, from improving the documentation, submitting bug reports and features requests or writing code to add enhancements or fix bugs. #### Table of Contents 1. [Introduction](#contributing-intro) 2. [Fork the Project](#contributing-fork) 3. [Branches](#contributing-branches) 4. [Commits](#contributing-commits) 5. [Pull Requests](#contributing-pull-requests) 6. [Testing](#contributing-testing) 7. [Source Code Patches](#contributing-patches-source-code) 8. [Documentation Patches](#contributing-patches-documentation) 9. [Contribute CheckCommand Definitions](#contributing-patches-itl-checkcommands) 10. [Review](#contributing-review) ## Introduction Please consider our [roadmap](https://github.com/Icinga/icinga2/milestones) and [open issues](https://github.com/icinga/icinga2/issues) when you start contributing to the project. Issues labeled with [help wanted](https://github.com/Icinga/icinga2/labels/help%20wanted) or [good first issue](https://github.com/Icinga/icinga2/labels/good%20first%20issue) will help you get started more easily. Before starting your work on Icinga 2, you should [fork the project](https://help.github.com/articles/fork-a-repo/) to your GitHub account. This allows you to freely experiment with your changes. When your changes are complete, submit a [pull request](https://help.github.com/articles/using-pull-requests/). All pull requests will be reviewed and merged if they suit some general guidelines: * Changes are located in a topic branch * For new functionality, proper tests are written * Changes should follow the existing coding style and standards Please continue reading in the following sections for a step by step guide. ## Fork the Project [Fork the project](https://help.github.com/articles/fork-a-repo/) to your GitHub account and clone the repository: ```bash git clone git@github.com:dnsmichi/icinga2.git cd icinga2 ``` Add a new remote `upstream` with this repository as value. ```bash git remote add upstream https://github.com/icinga/icinga2.git ``` You can pull updates to your fork's master branch: ```bash git fetch --all git pull upstream HEAD ``` Please continue to learn about [branches](CONTRIBUTING.md#contributing-branches). ## Branches Choosing a proper name for a branch helps us identify its purpose and possibly find an associated bug or feature. Generally a branch name should include a topic such as `bugfix` or `feature` followed by a description and an issue number if applicable. Branches should have only changes relevant to a specific issue. ```bash git checkout -b bugfix/service-template-typo-1234 git checkout -b feature/config-handling-1235 ``` Continue to apply your changes and test them. More details on specific changes: * [Source Code Patches](#contributing-patches-source-code) * [Documentation Patches](#contributing-patches-documentation) * [Contribute CheckCommand Definitions](#contributing-patches-itl-checkcommands) ## Commits Once you've finished your work in a branch, please ensure to commit your changes. A good commit message includes a short topic, additional body and a reference to the issue you wish to solve (if existing). Fixes: ``` Fix problem with notifications in HA cluster There was a race condition when restarting. refs #4567 ``` Features: ``` Add ITL CheckCommand printer Requires the check_printer plugin. refs #1234 ``` You can add multiple commits during your journey to finish your patch. Don't worry, you can squash those changes into a single commit later on. Ensure your name and email address in the commit metadata are correct. In your first contribution (PR) also add them to [AUTHORS](./AUTHORS). If those metadata changed since your last successful contribution, you should update [AUTHORS](./AUTHORS) and [.mailmap](./.mailmap). For the latter see [gitmailmap(5)](https://git-scm.com/docs/gitmailmap). ## Pull Requests Once you've commited your changes, please update your local master branch and rebase your bugfix/feature branch against it before submitting a PR. ```bash git checkout master git pull upstream HEAD git checkout bugfix/notifications git rebase master ``` Once you've resolved any conflicts, push the branch to your remote repository. It might be necessary to force push after rebasing - use with care! New branch: ```bash git push --set-upstream origin bugfix/notifications ``` Existing branch: ```bash git push -f origin bugfix/notifications ``` You can now either use the [hub](https://hub.github.com) CLI tool to create a PR, or nagivate to your GitHub repository and create a PR there. The pull request should again contain a telling subject and a reference with `fixes` to an existing issue id if any. That allows developers to automatically resolve the issues once your PR gets merged. ``` hub pull-request fixes #1234 ``` Thanks a lot for your contribution! ### Rebase a Branch If you accidentally sent in a PR which was not rebased against the upstream master, developers might ask you to rebase your PR. First off, fetch and pull `upstream` master. ```bash git checkout master git fetch --all git pull upstream HEAD ``` Then change to your working branch and start rebasing it against master: ```bash git checkout bugfix/notifications git rebase master ``` If you are running into a conflict, rebase will stop and ask you to fix the problems. ``` git status both modified: path/to/conflict.cpp ``` Edit the file and search for `>>>`. Fix, build, test and save as needed. Add the modified file(s) and continue rebasing. ```bash git add path/to/conflict.cpp git rebase --continue ``` Once succeeded ensure to push your changed history remotely. ```bash git push -f origin bugfix/notifications ``` If you fear to break things, do the rebase in a backup branch first and later replace your current branch. ```bash git checkout bugfix/notifications git checkout -b bugfix/notifications-rebase git rebase master git branch -D bugfix/notifications git checkout -b bugfix/notifications git push -f origin bugfix/notifications ``` ### Squash Commits > **Note:** > > Be careful with squashing. This might lead to non-recoverable mistakes. > > This is for advanced Git users. Say you want to squash the last 3 commits in your branch into a single one. Start an interactive (`-i`) rebase from current HEAD minus three commits (`HEAD~3`). ```bash git rebase -i HEAD~3 ``` Git opens your preferred editor. `pick` the commit in the first line, change `pick` to `squash` on the other lines. ``` pick e4bf04e47 Fix notifications squash d7b939d99 Tests squash b37fd5377 Doc updates ``` Save and let rebase to its job. Then force push the changes to the remote origin. ```bash git push -f origin bugfix/notifications ``` ## Testing Please follow the [documentation](https://icinga.com/docs/icinga2/snapshot/doc/21-development/#test-icinga-2) for build and test instructions. You can help test-drive the latest Icinga 2 snapshot packages inside the [Icinga 2 Vagrant boxes](https://github.com/icinga/icinga-vagrant). ## Source Code Patches Icinga 2 can be built on Linux/Unix nodes and Windows clients. In order to develop patches for Icinga 2, you should prepare your own local build environment and know how to work with C++. Please follow the [development documentation](https://icinga.com/docs/icinga2/latest/doc/21-development/) for development environments, the style guide and more advanced insights. ## Documentation Patches The documentation is written in GitHub flavored [Markdown](https://guides.github.com/features/mastering-markdown/). It is located in the `doc/` directory and can be edited with your preferred editor. You can also edit it online on GitHub. ```bash vim doc/2-getting-started.md ``` In order to review and test changes, you can install the [mkdocs](https://www.mkdocs.org) Python library. ```bash pip install mkdocs ``` This allows you to start a local mkdocs viewer instance on http://localhost:8000 ```bash mkdocs serve ``` Changes on the chapter layout can be done inside the `mkdocs.yml` file in the main tree. There also is a script to ensure that relative URLs to other sections are updated. This script also checks for broken URLs. ```bash ./doc/update-links.py doc/*.md ``` ## Contribute CheckCommand Definitions The Icinga Template Library (ITL) and its plugin check commands provide a variety of CheckCommand object definitions which can be included on-demand. Advantages of sending them upstream: * Everyone can use and update/fix them. * One single place for configuration and documentation. * Developers may suggest updates and help with best practices. * You don't need to care about copying the command definitions to your satellites and clients. #### Where do I start? Get to know the check plugin and its options. Read the general documentation on how to integrate your check plugins and how to create a good CheckCommand definition. A good command definition uses: * Command arguments including `value`, `description`, optional: `set_if`, `required`, etc. * Comments `/* ... */` to describe difficult parts. * Command name as prefix for the custom attributes referenced (e.g. `disk_`) * Default values * If `host.address` is involved, set a custom attribute (e.g. `ping_address`) to the default `$address$`. This allows users to override the host's address later on by setting the custom attribute inside the service apply definitions. * If the plugin is also capable to use ipv6, import the `ipv4-or-ipv6` template and use `$check_address$` instead of `$address$`. This allows to fall back to ipv6 if only this address is set. * If `set_if` is involved, ensure to specify a sane default value if required. * Templates if there are multiple plugins with the same basic behaviour (e.g. ping4 and ping6). * Your love and enthusiasm in making it the perfect CheckCommand. #### I have created a CheckCommand, what now? Icinga 2 developers love documentation. This isn't just because we want to annoy anyone sending a patch, it's a matter of making your contribution visible to the community. Your patch should consist of 2 parts: * The CheckCommand definition. * The documentation bits. [Fork the repository](https://help.github.com/articles/fork-a-repo/) and ensure that the master branch is up-to-date. Create a new fix or feature branch and start your work. ```bash git checkout -b feature/itl-check-printer ``` #### Add CheckCommand Definition to Contrib Plugins There already exists a defined structure for contributed plugins. Navigate to `itl/plugins-contrib.d` and verify where your command definitions fits into. ```bash cd itl/plugins-contrib.d/ ls ``` If you want to add or modify an existing Monitoring Plugin please use `itl/command-plugins.conf` instead. ```bash vim itl/command-plugins-conf ``` ##### Existing Configuration File Just edit it, and add your CheckCommand definition. ```bash vim operating-system.conf ``` Proceed to the documentation. ##### New type for CheckCommand Definition Create a new file with .conf suffix. ```bash vim printer.conf ``` Add the file to `itl/CMakeLists.txt` in the FILES line in **alpha-numeric order**. This ensures that the installation and packages properly include your newly created file. ``` vim CMakeLists.txt -FILES ipmi.conf network-components.conf operating-system.conf virtualization.conf vmware.conf +FILES ipmi.conf network-components.conf operating-system.conf printer.conf virtualization.conf vmware.conf ``` Add the newly created file to your git commit. ```bash git add printer.conf ``` Do not commit it yet but finish with the documentation. #### Create CheckCommand Documentation Edit the documentation file in the `doc/` directory. More details on documentation updates can be found [here](CONTRIBUTING.md#contributing-documentation). ```bash vim doc/10-icinga-template-library.md ``` The CheckCommand documentation should be located in the same chapter similar to the configuration file you have just added/modified. Create a section for your plugin, add a description and a table of parameters. Each parameter should have at least: * optional or required * description of its purpose * the default value, if any Look at the existing documentation and "copy" the same style and layout. #### Send a Patch Commit your changes which includes a descriptive commit message. ``` git commit -av Add printer CheckCommand definition Explain its purpose and possible enhancements/shortcomings. refs #existingticketnumberifany ``` Push the branch to the remote origin and create a [pull request](https://help.github.com/articles/using-pull-requests/). ```bash git push --set-upstream origin feature/itl-check-printer hub pull-request ``` In case developers ask for changes during review, please add them to the branch and push those changes. ## Review ### Pull Request Review This is only important for developers who will review pull requests. If you want to join the development team, kindly contact us. - Ensure that the style guide applies. - Verify that the patch fixes a problem or linked issue, if any. - Discuss new features with team members. - Test the patch in your local dev environment. If there are changes required, kindly ask for an updated patch. Once the review is completed, merge the PR via GitHub. #### Pull Request Review Fixes In order to amend the commit message, fix conflicts or add missing changes, you can add your changes to the PR. A PR is just a pointer to a different Git repository and branch. By default, pull requests allow to push into the repository of the PR creator. Example for [#4956](https://github.com/Icinga/icinga2/pull/4956): At the bottom it says "Add more commits by pushing to the bugfix/persistent-comments-are-not-persistent branch on TheFlyingCorpse/icinga2." First off, add the remote repository as additional origin and fetch its content: ```bash git remote add theflyingcorpse https://github.com/TheFlyingCorpse/icinga2 git fetch --all ``` Checkout the mentioned remote branch into a local branch (Note: `theflyingcorpse` is the name of the remote): ```bash git checkout theflyingcorpse/bugfix/persistent-comments-are-not-persistent -b bugfix/persistent-comments-are-not-persistent ``` Rebase, amend, squash or add your own commits on top. Once you are satisfied, push the changes to the remote `theflyingcorpse` and its branch `bugfix/persistent-comments-are-not-persistent`. The syntax here is `git push :`. ```bash git push theflyingcorpse bugfix/persistent-comments-are-not-persistent:bugfix/persistent-comments-are-not-persistent ``` In case you've changed the commit history (rebase, amend, squash), you'll need to force push. Be careful, this can't be reverted! ```bash git push -f theflyingcorpse bugfix/persistent-comments-are-not-persistent:bugfix/persistent-comments-are-not-persistent ``` icinga2-2.14.6/COPYING000066400000000000000000000432541501332562400141640ustar00rootroot00000000000000 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. icinga2-2.14.6/ICINGA2_VERSION000066400000000000000000000000341501332562400152620ustar00rootroot00000000000000Version: 2.14.6 Revision: 1 icinga2-2.14.6/NEWS000066400000000000000000000001241501332562400136150ustar00rootroot00000000000000News for this application can be found on the project website at https://icinga.com icinga2-2.14.6/README.md000066400000000000000000000075671501332562400144170ustar00rootroot00000000000000[![Github Tag](https://img.shields.io/github/tag/Icinga/icinga2.svg)](https://github.com/Icinga/icinga2) # Icinga 2 ![Icinga Logo](https://icinga.com/wp-content/uploads/2014/06/icinga_logo.png) #### Table of Contents 1. [About][About] 2. [Installation][Installation] 3. [Documentation][Documentation] 4. [Support][Support] 5. [License][License] 6. [Contributing][Contributing] ## About [Icinga](https://icinga.com/products/) is a monitoring system which checks the availability of your network resources, notifies users of outages, and generates performance data for reporting. Scalable and extensible, Icinga can monitor large, complex environments across multiple locations. Icinga 2 is the monitoring server and requires [Icinga Web 2](https://icinga.com/products/) on top in your Icinga Stack. The [configuration](https://icinga.com/products/configuration/) can be easily managed with either the [Icinga Director](https://icinga.com/docs/director/latest/), config management tools or plain text within the [Icinga DSL](https://icinga.com/docs/icinga2/latest/doc/17-language-reference/). ![Icinga Dashboard](https://icinga.com/wp-content/uploads/2017/12/icingaweb2-2.5.0-dashboard.png) ## Installation * [Installation](https://icinga.com/docs/icinga2/latest/doc/02-installation/) * [Monitoring Basics](https://icinga.com/docs/icinga2/latest/doc/03-monitoring-basics/) * [Configuration](https://icinga.com/docs/icinga2/latest/doc/04-configuration/) * [Distributed Monitoring](https://icinga.com/docs/icinga2/latest/doc/06-distributed-monitoring/) * [Addons, Integrations and Features](https://icinga.com/docs/icinga2/latest/doc/13-addons/) * [Troubleshooting](https://icinga.com/docs/icinga2/latest/doc/15-troubleshooting/) * [Upgrading](https://icinga.com/docs/icinga2/latest/doc/16-upgrading-icinga-2/) Once Icinga Server and Web are running in your distributed environment, make sure to check out the many [Icinga modules](https://icinga.com/docs/) for even better monitoring. ## Documentation The documentation is available on [icinga.com/docs](https://icinga.com/docs/icinga2/latest/). ## Support Check the [project website](https://icinga.com) for status updates. Join the [community channels](https://icinga.com/community/) for questions or ask an Icinga partner for [professional support](https://icinga.com/support/). ## License Icinga 2 and the Icinga 2 documentation are licensed under the terms of the GNU General Public License Version 2, you will find a copy of this license in the COPYING file included in the source package. In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library under certain conditions as described in each individual source file, and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than OpenSSL. If you modify file(s) with this exception, you may extend this exception to your version of the file(s), but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. If you delete this exception statement from all source files in the program, then also delete it here. ## Contributing There are many ways to contribute to Icinga -- whether it be sending patches, testing, reporting bugs, or reviewing and updating the documentation. Every contribution is appreciated! Please continue reading in the [contributing chapter](CONTRIBUTING.md). If you are a packager, please read the [development chapter](https://icinga.com/docs/icinga2/latest/doc/21-development/) for more details. ### Security Issues For reporting security issues please visit [this page](https://icinga.com/contact/security/). [About]: #about [License]: #license [Installation]: #installation [Documentation]: #documentation [Support]: #support [Contributing]: #contributing icinga2-2.14.6/RELEASE.md000066400000000000000000000262201501332562400145250ustar00rootroot00000000000000# Release Workflow #### Table of Content - [1. Preparations](#preparations) - [1.1. Issues](#issues) - [1.2. Backport Commits](#backport-commits) - [1.3. Windows Dependencies](#windows-dependencies) - [2. Version](#version) - [3. Changelog](#changelog) - [4. Git Tag](#git-tag) - [5. Package Builds](#package-builds) - [5.1. RPM Packages](#rpm-packages) - [5.2. DEB Packages](#deb-packages) - [6. Build Server](#build-infrastructure) - [7. Release Tests](#release-tests) - [8. GitHub Release](#github-release) - [9. Docker](#docker) - [10. Post Release](#post-release) - [10.1. Online Documentation](#online-documentation) - [10.2. Announcement](#announcement) - [10.3. Project Management](#project-management) ## Preparations Specify the release version. ```bash VERSION=2.11.0 ``` Add your signing key to your Git configuration file, if not already there. ``` vim $HOME/.gitconfig [user] email = michael.friedrich@icinga.com name = Michael Friedrich signingkey = D14A1F16 ``` ### Issues Check issues at https://github.com/Icinga/icinga2 ### Backport Commits For minor versions you need to manually backports any and all commits from the master branch which should be part of this release. ### Windows Dependencies In contrast to Linux, the bundled Windows dependencies (at least Boost and OpenSSL) aren't updated automatically. (Neither by Icinga administrators, nor at package build time.) To ensure the upcoming Icinga release ships the latest (i.e. most secure) dependencies on Windows: #### Update packages.icinga.com Add the latest Boost and OpenSSL versions to https://packages.icinga.com/windows/dependencies/ like this: ``` localhost:~$ ssh aptly.vm.icinga.com aptly:~$ sudo -i aptly:~# cd /var/www/html/aptly/public/windows/dependencies aptly:dependencies# wget https://master.dl.sourceforge.net/project/boost/boost-binaries/1.76.0/boost_1_76_0-msvc-14.2-64.exe aptly:dependencies# wget https://master.dl.sourceforge.net/project/boost/boost-binaries/1.76.0/boost_1_76_0-msvc-14.2-32.exe aptly:dependencies# wget https://slproweb.com/download/Win64OpenSSL-1_1_1k.exe aptly:dependencies# wget https://slproweb.com/download/Win32OpenSSL-1_1_1k.exe ``` #### Ensure Compatibility Preferably on a fresh Windows VM (not to accidentally build Icinga with old dependency versions) setup a dev environment using the new dependency versions: 1. Download [doc/win-dev.ps1](doc/win-dev.ps1) 2. Edit your local copy, adjust the dependency versions 3. Ensure there are 35 GB free space on C: 4. Run the following in an administrative Powershell: 1. `Enable-WindowsOptionalFeature -FeatureName "NetFx3" -Online` (reboot when asked!) 2. `powershell -NoProfile -ExecutionPolicy Bypass -File "${Env:USERPROFILE}\Downloads\win-dev.ps1"` (will take some time) Actually clone and build Icinga using the new dependency versions as described [here](https://github.com/Icinga/icinga2/blob/master/doc/21-development.md#tldr). Fix incompatibilities if any. #### Update Build Server, CI/CD and Documentation * https://git.icinga.com/infra/ansible-windows-build (don't forget to provision!) * [doc/21-development.md](doc/21-development.md) * [doc/win-dev.ps1](doc/win-dev.ps1) (also affects CI/CD) * [tools/win32/configure.ps1](tools/win32/configure.ps1) * [tools/win32/configure-dev.ps1](tools/win32/configure-dev.ps1) #### Re-provision Build Server Even if there aren't any new releases of dependencies with versions hardcoded in the repos and files listed above (Boost, OpenSSL). There may be new build versions of other dependencies (VS, MSVC). Our GitHub actions (tests) use the latest ones automatically, but the GitLab runner (release packages) doesn't. ## Version Update the version: ```bash perl -pi -e "s/Version: .*/Version: $VERSION/g" ICINGA2_VERSION ``` ## Changelog Choose the most important issues and summarize them in multiple groups/paragraphs. Provide links to the mentioned issues/PRs. At the start include a link to the milestone's closed issues. ## Git Tag ```bash git commit -v -a -m "Release version $VERSION" ``` Create a signed tag (tags/v) on the `master` branch (for major releases) or the `support` branch (for minor releases). ```bash git tag -s -m "Version $VERSION" v$VERSION ``` Push the tag: ```bash git push origin v$VERSION ``` **For major releases:** Create a new `support` branch: ```bash git checkout master git push git checkout -b support/2.12 git push -u origin support/2.12 ``` ## Package Builds ```bash mkdir $HOME/dev/icinga/packaging cd $HOME/dev/icinga/packaging ``` ### RPM Packages ```bash git clone git@git.icinga.com:packaging/rpm-icinga2.git && cd rpm-icinga2 ``` ### DEB Packages ```bash git clone git@git.icinga.com:packaging/deb-icinga2.git && cd deb-icinga2 ``` ### Raspbian Packages ```bash git clone git@git.icinga.com:packaging/raspbian-icinga2.git && cd raspbian-icinga2 ``` ### Windows Packages ```bash git clone git@git.icinga.com:packaging/windows-icinga2.git && cd windows-icinga2 ``` ### Branch Workflow For each support branch in this repo (e.g. support/2.12), there exists a corresponding branch in the packaging repos (e.g. 2.12). Each package revision is a tagged commit on these branches. When doing a major release, create the new branch, otherweise switch to the existing one. ### Switch Build Type Ensure that `ICINGA_BUILD_TYPE` is set to `release` in `.gitlab-ci.yml`. This should only be necessary after creating a new branch. ```yaml variables: ... ICINGA_BUILD_TYPE: release ... ``` Commit the change. ```bash git commit -av -m "Switch build type for 2.13" ``` #### RPM Release Preparations Set the `Version`, `revision` and `%changelog` inside the spec file: ``` perl -pi -e "s/Version:.*/Version: $VERSION/g" icinga2.spec vim icinga2.spec %changelog * Thu Sep 19 2019 Michael Friedrich 2.11.0-1 - Update to 2.11.0 ``` #### DEB and Raspbian Release Preparations Update file `debian/changelog` and add at the beginning: ``` icinga2 (2.11.0-1) icinga; urgency=medium * Release 2.11.0 -- Michael Friedrich Thu, 19 Sep 2019 10:50:31 +0200 ``` #### Windows Release Preparations Update the file `.gitlab-ci.yml`: ``` perl -pi -e "s/^ UPSTREAM_GIT_BRANCH: .*/ UPSTREAM_GIT_BRANCH: v$VERSION/g" .gitlab-ci.yml perl -pi -e "s/^ ICINGA_FORCE_VERSION: .*/ ICINGA_FORCE_VERSION: v$VERSION/g" .gitlab-ci.yml ``` ### Release Commit Commit the changes and push the branch. ```bash git commit -av -m "Release $VERSION-1" git push origin 2.11 ``` GitLab will now build snapshot packages based on the tag `v2.11.0` of Icinga 2. ### Package Tests In order to test the created packages you can download a job's artifacts: Visit [git.icinga.com](https://git.icinga.com/packaging/rpm-icinga2) and navigate to the respective pipeline under `CI / CD -> Pipelines`. There click on the job you want to download packages from. The job's output appears. On the right-hand sidebar you can browse its artifacts. Once there, navigate to `build/RPMS/noarch` where you'll find the packages. ### Release Packages To build release packages and upload them to [packages.icinga.com](https://packages.icinga.com) tag the release commit and push it. RPM/DEB/Raspbian: ```bash git tag -s $VERSION-1 -m "Release v$VERSION-1" git push origin $VERSION-1 ``` Windows: ```bash git tag -s $VERSION -m "Release v$VERSION" git push origin $VERSION ``` Now cherry pick the release commit to `master` so that the changes are transferred back to it. **Attention**: Only the release commit. *NOT* the one switching the build type! ## Build Infrastructure https://git.icinga.com/packaging/rpm-icinga2/pipelines https://git.icinga.com/packaging/deb-icinga2/pipelines https://git.icinga.com/packaging/windows-icinga2/pipelines https://git.icinga.com/packaging/raspbian-icinga2/pipelines * Verify package build changes for this version. * Test the snapshot packages for all distributions beforehand. Once the release repository tags are pushed, release builds are triggered and automatically published to packages.icinga.com ## Release Tests * Test DB IDO with MySQL and PostgreSQL. * Provision the vagrant boxes and test the release packages. * Test the [setup wizard](https://packages.icinga.com/windows/) inside a Windows VM. * Start a new docker container and install/run icinga2. ### CentOS ```bash docker run -ti centos:7 bash yum -y install https://packages.icinga.com/epel/icinga-rpm-release-7-latest.noarch.rpm yum -y install epel-release yum -y install icinga2 icinga2 daemon -C ``` ### Ubuntu ```bash docker run -ti ubuntu:bionic bash apt-get update apt-get -y install apt-transport-https wget gnupg wget -O - https://packages.icinga.com/icinga.key | apt-key add - . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \ echo "deb https://packages.icinga.com/ubuntu icinga-${DIST} main" > \ /etc/apt/sources.list.d/${DIST}-icinga.list echo "deb-src https://packages.icinga.com/ubuntu icinga-${DIST} main" >> \ /etc/apt/sources.list.d/${DIST}-icinga.list apt-get update apt-get -y install icinga2 icinga2 daemon -C ``` ## GitHub Release Create a new release for the newly created Git tag: https://github.com/Icinga/icinga2/releases > Hint: Choose [tags](https://github.com/Icinga/icinga2/tags), pick one to edit and > make this a release. You can also create a draft release. The release body should contain a short changelog, with links into the roadmap, changelog and blogpost. ## Post Release ### Online Documentation > Only required for major releases. Navigate to `puppet-customer/icinga.git` and do the following steps: #### Testing ```bash git checkout testing && git pull vim files/var/www/docs/config/icinga2-latest.yml git commit -av -m "icinga-web: Update docs for Icinga 2" git push ``` SSH into the webserver and do a manual Puppet dry run with the testing environment. ```bash puppet agent -t --environment testing --noop ``` Once succeeded, continue with production deployment. #### Production ```bash git checkout master && git pull git merge testing git push ``` SSH into the webserver and do a manual Puppet run from the production environment (default). ```bash puppet agent -t ``` #### Manual Generation SSH into the webserver or ask @bobapple. ```bash cd /usr/local/icinga-docs-tools && ./build-docs.rb -c /var/www/docs/config/icinga2-latest.yml ``` ### Announcement * Create a new blog post on [icinga.com/blog](https://icinga.com/blog) including a featured image * Create a release topic on [community.icinga.com](https://community.icinga.com) * Release email to net-tech & team ### Project Management * Add new minor version on [GitHub](https://github.com/Icinga/icinga2/milestones). icinga2-2.14.6/agent/000077500000000000000000000000001501332562400142175ustar00rootroot00000000000000icinga2-2.14.6/agent/CMakeLists.txt000066400000000000000000000010121501332562400167510ustar00rootroot00000000000000# Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ if(MSVC) include_external_msproject( icinga2setupagent ${CMAKE_CURRENT_SOURCE_DIR}/windows-setup-agent/Icinga2SetupAgent.csproj TYPE FAE04EC0-301F-11D3-BF4B-00C04F79EFBC ) install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/windows-setup-agent/bin/\${CMAKE_INSTALL_CONFIG_NAME}/Icinga2SetupAgent.exe ${CMAKE_CURRENT_SOURCE_DIR}/windows-setup-agent/bin/\${CMAKE_INSTALL_CONFIG_NAME}/Icinga2SetupAgent.exe.config DESTINATION ${CMAKE_INSTALL_SBINDIR} ) endif() icinga2-2.14.6/agent/windows-setup-agent/000077500000000000000000000000001501332562400201435ustar00rootroot00000000000000icinga2-2.14.6/agent/windows-setup-agent/.gitignore000066400000000000000000000000071501332562400221300ustar00rootroot00000000000000bin objicinga2-2.14.6/agent/windows-setup-agent/App.config000066400000000000000000000002541501332562400220530ustar00rootroot00000000000000 icinga2-2.14.6/agent/windows-setup-agent/EndpointInputBox.Designer.cs000066400000000000000000000140351501332562400255050ustar00rootroot00000000000000namespace Icinga { partial class EndpointInputBox { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.btnOK = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); this.txtHost = new System.Windows.Forms.TextBox(); this.txtPort = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.lblHost = new System.Windows.Forms.Label(); this.lblPort = new System.Windows.Forms.Label(); this.lblInstanceName = new System.Windows.Forms.Label(); this.txtInstanceName = new System.Windows.Forms.TextBox(); this.chkConnect = new System.Windows.Forms.CheckBox(); this.SuspendLayout(); // // btnOK // this.btnOK.Location = new System.Drawing.Point(196, 171); this.btnOK.Name = "btnOK"; this.btnOK.Size = new System.Drawing.Size(75, 23); this.btnOK.TabIndex = 4; this.btnOK.Text = "OK"; this.btnOK.UseVisualStyleBackColor = true; this.btnOK.Click += new System.EventHandler(this.btnOK_Click); // // btnCancel // this.btnCancel.CausesValidation = false; this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnCancel.Location = new System.Drawing.Point(277, 171); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); this.btnCancel.TabIndex = 5; this.btnCancel.Text = "Cancel"; this.btnCancel.UseVisualStyleBackColor = true; // // txtHost // this.txtHost.Location = new System.Drawing.Point(101, 103); this.txtHost.Name = "txtHost"; this.txtHost.Size = new System.Drawing.Size(251, 20); this.txtHost.TabIndex = 2; // // txtPort // this.txtPort.Location = new System.Drawing.Point(101, 134); this.txtPort.Name = "txtPort"; this.txtPort.Size = new System.Drawing.Size(100, 20); this.txtPort.TabIndex = 3; this.txtPort.Text = "5665"; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(12, 9); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(276, 13); this.label1.TabIndex = 4; this.label1.Text = "Please enter the connection details for the new endpoint:"; // // lblHost // this.lblHost.AutoSize = true; this.lblHost.Location = new System.Drawing.Point(15, 106); this.lblHost.Name = "lblHost"; this.lblHost.Size = new System.Drawing.Size(32, 13); this.lblHost.TabIndex = 5; this.lblHost.Text = "Host:"; // // lblPort // this.lblPort.AutoSize = true; this.lblPort.Location = new System.Drawing.Point(15, 137); this.lblPort.Name = "lblPort"; this.lblPort.Size = new System.Drawing.Size(29, 13); this.lblPort.TabIndex = 6; this.lblPort.Text = "Port:"; // // lblInstanceName // this.lblInstanceName.AutoSize = true; this.lblInstanceName.Location = new System.Drawing.Point(15, 41); this.lblInstanceName.Name = "lblInstanceName"; this.lblInstanceName.Size = new System.Drawing.Size(82, 13); this.lblInstanceName.TabIndex = 7; this.lblInstanceName.Text = "Instance Name:"; // // txtInstanceName // this.txtInstanceName.Location = new System.Drawing.Point(101, 37); this.txtInstanceName.Name = "txtInstanceName"; this.txtInstanceName.Size = new System.Drawing.Size(251, 20); this.txtInstanceName.TabIndex = 0; // // chkConnect // this.chkConnect.AutoSize = true; this.chkConnect.Checked = true; this.chkConnect.CheckState = System.Windows.Forms.CheckState.Checked; this.chkConnect.Location = new System.Drawing.Point(18, 73); this.chkConnect.Name = "chkConnect"; this.chkConnect.Size = new System.Drawing.Size(141, 17); this.chkConnect.TabIndex = 1; this.chkConnect.Text = "Connect to this endpoint"; this.chkConnect.UseVisualStyleBackColor = true; this.chkConnect.CheckedChanged += new System.EventHandler(this.chkConnect_CheckedChanged); // // EndpointInputBox // this.AcceptButton = this.btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; this.ClientSize = new System.Drawing.Size(360, 202); this.Controls.Add(this.chkConnect); this.Controls.Add(this.txtInstanceName); this.Controls.Add(this.lblInstanceName); this.Controls.Add(this.lblPort); this.Controls.Add(this.lblHost); this.Controls.Add(this.label1); this.Controls.Add(this.txtPort); this.Controls.Add(this.txtHost); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnOK); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "EndpointInputBox"; this.ShowIcon = false; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Add Endpoint"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnCancel; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label lblHost; private System.Windows.Forms.Label lblPort; public System.Windows.Forms.TextBox txtHost; public System.Windows.Forms.TextBox txtPort; public System.Windows.Forms.TextBox txtInstanceName; private System.Windows.Forms.Label lblInstanceName; public System.Windows.Forms.CheckBox chkConnect; } }icinga2-2.14.6/agent/windows-setup-agent/EndpointInputBox.cs000066400000000000000000000020271501332562400237440ustar00rootroot00000000000000using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Icinga { public partial class EndpointInputBox : Form { public EndpointInputBox() { InitializeComponent(); } private void Warning(string message) { MessageBox.Show(this, message, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); } private void chkConnect_CheckedChanged(object sender, EventArgs e) { txtHost.Enabled = chkConnect.Checked; txtPort.Enabled = chkConnect.Checked; } private void btnOK_Click(object sender, EventArgs e) { if (txtInstanceName.Text.Length == 0) { Warning("Please enter an instance name."); return; } if (chkConnect.Checked) { if (txtHost.Text.Length == 0) { Warning("Please enter a host name."); return; } if (txtPort.Text.Length == 0) { Warning("Please enter a port."); return; } } DialogResult = DialogResult.OK; Close(); } } } icinga2-2.14.6/agent/windows-setup-agent/EndpointInputBox.resx000066400000000000000000000131021501332562400243140ustar00rootroot00000000000000 text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 icinga2-2.14.6/agent/windows-setup-agent/GlobalZonesInputBox.Designer.cs000066400000000000000000000076071501332562400261530ustar00rootroot00000000000000namespace Icinga { partial class GlobalZonesInputBox { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.btnOK = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); this.label1 = new System.Windows.Forms.Label(); this.lblGlobalZoneName = new System.Windows.Forms.Label(); this.txtGlobalZoneName = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // btnOK // this.btnOK.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnOK.Location = new System.Drawing.Point(191, 76); this.btnOK.Name = "btnOK"; this.btnOK.Size = new System.Drawing.Size(75, 23); this.btnOK.TabIndex = 0; this.btnOK.Text = "OK"; this.btnOK.UseVisualStyleBackColor = true; this.btnOK.Click += new System.EventHandler(this.btnOK_Click); // // btnCancel // this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnCancel.Location = new System.Drawing.Point(272, 76); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); this.btnCancel.TabIndex = 1; this.btnCancel.Text = "Cancel"; this.btnCancel.UseVisualStyleBackColor = true; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(13, 13); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(231, 13); this.label1.TabIndex = 2; this.label1.Text = "Please enter the name for the new global Zone:"; // // lblGlobalZoneName // this.lblGlobalZoneName.AutoSize = true; this.lblGlobalZoneName.Location = new System.Drawing.Point(16, 46); this.lblGlobalZoneName.Name = "lblGlobalZoneName"; this.lblGlobalZoneName.Size = new System.Drawing.Size(68, 13); this.lblGlobalZoneName.TabIndex = 3; this.lblGlobalZoneName.Text = "Global Zone:"; // // txtGlobalZoneName // this.txtGlobalZoneName.Location = new System.Drawing.Point(90, 43); this.txtGlobalZoneName.Name = "txtGlobalZoneName"; this.txtGlobalZoneName.Size = new System.Drawing.Size(257, 20); this.txtGlobalZoneName.TabIndex = 0; // // GlobalZonesInputBox // this.AcceptButton = this.btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; this.ClientSize = new System.Drawing.Size(359, 111); this.Controls.Add(this.txtGlobalZoneName); this.Controls.Add(this.lblGlobalZoneName); this.Controls.Add(this.label1); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnOK); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "GlobalZonesInputBox"; this.ShowIcon = false; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Add Global Zones"; this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnCancel; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label lblGlobalZoneName; public System.Windows.Forms.TextBox txtGlobalZoneName; } }icinga2-2.14.6/agent/windows-setup-agent/GlobalZonesInputBox.cs000066400000000000000000000020541501332562400244030ustar00rootroot00000000000000using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Icinga { public partial class GlobalZonesInputBox : Form { private ListView.ListViewItemCollection globalZonesItems; public GlobalZonesInputBox(ListView.ListViewItemCollection globalZonesItems) { InitializeComponent(); this.globalZonesItems = globalZonesItems; } private void Warning(string message) { MessageBox.Show(this, message, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); } private void btnOK_Click(object sender, EventArgs e) { if (txtGlobalZoneName.Text == "global-templates" || txtGlobalZoneName.Text == "director-global") { Warning("This global zone is configured by default."); return; } foreach (ListViewItem lvw in globalZonesItems) { if (txtGlobalZoneName.Text == lvw.Text) { Warning("This global zone is already defined."); return; } } DialogResult = DialogResult.OK; Close(); } } } icinga2-2.14.6/agent/windows-setup-agent/GlobalZonesInputBox.resx000066400000000000000000000131021501332562400247530ustar00rootroot00000000000000 text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 icinga2-2.14.6/agent/windows-setup-agent/Icinga2SetupAgent.csproj000066400000000000000000000246021501332562400246450ustar00rootroot00000000000000 Debug x64 {A86F1159-66E8-4BDB-BF28-A2BDAF76517C} WinExe Properties Icinga Icinga2SetupAgent v4.6 512 publish\ true Disk false Foreground 7 Days false false true 0 1.0.0.%2a false false true x86 true full false bin\Debug\ DEBUG;TRACE prompt 4 false x86 pdbonly true bin\Release\ TRACE prompt 4 false x86 pdbonly true bin\RelWithDebInfo\ TRACE prompt 4 false x86 pdbonly true bin\MinSizeRel\ TRACE prompt 4 false x86 true full false bin\Debug\ DEBUG;TRACE prompt 4 false x86 pdbonly true bin\Release\ TRACE prompt 4 false x86 pdbonly true bin\RelWithDebInfo\ TRACE prompt 4 false x86 pdbonly true bin\MinSizeRel\ TRACE prompt 4 false x64 true full false bin\Debug\ DEBUG;TRACE prompt 4 false x64 pdbonly true bin\Release\ TRACE prompt 4 false x64 pdbonly true bin\RelWithDebInfo\ TRACE prompt 4 false x64 pdbonly true bin\MinSizeRel\ TRACE prompt 4 false icinga.ico app.manifest Form GlobalZonesInputBox.cs Form ServiceStatus.cs Form SetupWizard.cs Form EndpointInputBox.cs GlobalZonesInputBox.cs ServiceStatus.cs SetupWizard.cs EndpointInputBox.cs ResXFileCodeGenerator Resources.Designer.cs Designer True Resources.resx True SettingsSingleFileGenerator Settings.Designer.cs True Settings.settings True False Microsoft .NET Framework 4.5 %28x86 and x64%29 true False .NET Framework 3.5 SP1 Client Profile false False .NET Framework 3.5 SP1 false icinga2-2.14.6/agent/windows-setup-agent/Program.cs000066400000000000000000000052721501332562400221070ustar00rootroot00000000000000using System; using System.IO; using System.Windows.Forms; using Microsoft.Win32; using System.Runtime.InteropServices; using System.Text; namespace Icinga { internal static class NativeMethods { [DllImport("msi.dll", CharSet = CharSet.Unicode)] internal static extern int MsiEnumProducts(int iProductIndex, StringBuilder lpProductBuf); [DllImport("msi.dll", CharSet = CharSet.Unicode)] internal static extern Int32 MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len); } static class Program { public static string Icinga2InstallDir { get { StringBuilder szProduct; for (int index = 0; ; index++) { szProduct = new StringBuilder(39); if (NativeMethods.MsiEnumProducts(index, szProduct) != 0) break; int cbName = 128; StringBuilder szName = new StringBuilder(cbName); if (NativeMethods.MsiGetProductInfo(szProduct.ToString(), "ProductName", szName, ref cbName) != 0) continue; if (szName.ToString() != "Icinga 2") continue; int cbLocation = 1024; StringBuilder szLocation = new StringBuilder(cbLocation); if (NativeMethods.MsiGetProductInfo(szProduct.ToString(), "InstallLocation", szLocation, ref cbLocation) == 0) return szLocation.ToString(); } return ""; } } public static string Icinga2DataDir { get { return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\icinga2"; } } public static string Icinga2User { get { if (!File.Exists(Icinga2DataDir + "\\etc\\icinga2\\user")) return "NT AUTHORITY\\NetworkService"; System.IO.StreamReader file = new System.IO.StreamReader(Icinga2DataDir + "\\etc\\icinga2\\user"); string line = file.ReadLine(); file.Close(); if (line != null) return line; else return "NT AUTHORITY\\NetworkService"; } } public static void FatalError(Form owner, string message) { MessageBox.Show(owner, message, "Icinga 2 Setup Wizard", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); } /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); string installDir = Program.Icinga2InstallDir; if (installDir == "") { FatalError(null, "Icinga 2 does not seem to be installed properly."); return; } Form form; if (File.Exists(Program.Icinga2DataDir + "\\etc\\icinga2\\features-enabled\\api.conf")) form = new ServiceStatus(); else form = new SetupWizard(); Application.Run(form); } } } icinga2-2.14.6/agent/windows-setup-agent/Properties/000077500000000000000000000000001501332562400222775ustar00rootroot00000000000000icinga2-2.14.6/agent/windows-setup-agent/Properties/AssemblyInfo.cs000066400000000000000000000026231501332562400252240ustar00rootroot00000000000000using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("Icinga 2 Agent Wizard")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Icinga GmbH")] [assembly: AssemblyProduct("Icinga 2")] [assembly: AssemblyCopyright("Copyright © 2019 Icinga GmbH")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("51f4fcaf-8cf8-4d1c-9fde-61526c17a0d8")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] icinga2-2.14.6/agent/windows-setup-agent/Properties/Resources.Designer.cs000066400000000000000000000061241501332562400263420ustar00rootroot00000000000000//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace Icinga.Properties { using System; /// /// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Icinga.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// internal static System.Drawing.Bitmap icinga_banner { get { object obj = ResourceManager.GetObject("icinga_banner", resourceCulture); return ((System.Drawing.Bitmap)(obj)); } } } } icinga2-2.14.6/agent/windows-setup-agent/Properties/Resources.resx000066400000000000000000000137001501332562400251550ustar00rootroot00000000000000 text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\icinga-banner.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a icinga2-2.14.6/agent/windows-setup-agent/Properties/Settings.Designer.cs000066400000000000000000000020471501332562400261700ustar00rootroot00000000000000//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace Icinga.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } } } icinga2-2.14.6/agent/windows-setup-agent/Properties/Settings.settings000066400000000000000000000003621501332562400256620ustar00rootroot00000000000000 icinga2-2.14.6/agent/windows-setup-agent/ServiceStatus.Designer.cs000066400000000000000000000114221501332562400250350ustar00rootroot00000000000000namespace Icinga { partial class ServiceStatus { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ServiceStatus)); this.picBanner = new System.Windows.Forms.PictureBox(); this.lblStatus = new System.Windows.Forms.Label(); this.txtStatus = new System.Windows.Forms.TextBox(); this.btnReconfigure = new System.Windows.Forms.Button(); this.btnOK = new System.Windows.Forms.Button(); this.btnOpenConfigDir = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.picBanner)).BeginInit(); this.SuspendLayout(); // // picBanner // this.picBanner.Image = global::Icinga.Properties.Resources.icinga_banner; this.picBanner.Location = new System.Drawing.Point(0, 0); this.picBanner.Name = "picBanner"; this.picBanner.Size = new System.Drawing.Size(625, 77); this.picBanner.TabIndex = 2; this.picBanner.TabStop = false; // // lblStatus // this.lblStatus.AutoSize = true; this.lblStatus.Location = new System.Drawing.Point(12, 105); this.lblStatus.Name = "lblStatus"; this.lblStatus.Size = new System.Drawing.Size(79, 13); this.lblStatus.TabIndex = 3; this.lblStatus.Text = "Service Status:"; // // txtStatus // this.txtStatus.Location = new System.Drawing.Point(97, 102); this.txtStatus.Name = "txtStatus"; this.txtStatus.ReadOnly = true; this.txtStatus.Size = new System.Drawing.Size(278, 20); this.txtStatus.TabIndex = 3; // // btnReconfigure // this.btnReconfigure.Location = new System.Drawing.Point(195, 143); this.btnReconfigure.Name = "btnReconfigure"; this.btnReconfigure.Size = new System.Drawing.Size(89, 23); this.btnReconfigure.TabIndex = 1; this.btnReconfigure.Text = "Reconfigure"; this.btnReconfigure.UseVisualStyleBackColor = true; this.btnReconfigure.Click += new System.EventHandler(this.btnReconfigure_Click); // // btnOK // this.btnOK.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnOK.Location = new System.Drawing.Point(290, 143); this.btnOK.Name = "btnOK"; this.btnOK.Size = new System.Drawing.Size(89, 23); this.btnOK.TabIndex = 0; this.btnOK.Text = "OK"; this.btnOK.UseVisualStyleBackColor = true; this.btnOK.Click += new System.EventHandler(this.btnOK_Click); // // btnOpenConfigDir // this.btnOpenConfigDir.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnOpenConfigDir.Location = new System.Drawing.Point(100, 143); this.btnOpenConfigDir.Name = "btnOpenConfigDir"; this.btnOpenConfigDir.Size = new System.Drawing.Size(89, 23); this.btnOpenConfigDir.TabIndex = 2; this.btnOpenConfigDir.Text = "Examine Config"; this.btnOpenConfigDir.UseVisualStyleBackColor = true; this.btnOpenConfigDir.Click += new System.EventHandler(this.btnOpenConfigDir_Click); // // ServiceStatus // this.AcceptButton = this.btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnOK; this.ClientSize = new System.Drawing.Size(391, 186); this.Controls.Add(this.btnOpenConfigDir); this.Controls.Add(this.btnOK); this.Controls.Add(this.btnReconfigure); this.Controls.Add(this.txtStatus); this.Controls.Add(this.lblStatus); this.Controls.Add(this.picBanner); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.Name = "ServiceStatus"; this.Text = "Icinga Windows Agent Service Status"; ((System.ComponentModel.ISupportInitialize)(this.picBanner)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.PictureBox picBanner; private System.Windows.Forms.Label lblStatus; private System.Windows.Forms.TextBox txtStatus; private System.Windows.Forms.Button btnReconfigure; private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnOpenConfigDir; } }icinga2-2.14.6/agent/windows-setup-agent/ServiceStatus.cs000066400000000000000000000013541501332562400233010ustar00rootroot00000000000000using System; using System.Windows.Forms; using System.ServiceProcess; using System.Diagnostics; namespace Icinga { public partial class ServiceStatus : Form { public ServiceStatus() { InitializeComponent(); try { ServiceController sc = new ServiceController("icinga2"); txtStatus.Text = sc.Status.ToString(); } catch (InvalidOperationException) { txtStatus.Text = "Not Available"; } } private void btnReconfigure_Click(object sender, EventArgs e) { new SetupWizard().ShowDialog(this); } private void btnOK_Click(object sender, EventArgs e) { Close(); } private void btnOpenConfigDir_Click(object sender, EventArgs e) { Process.Start("explorer.exe", Program.Icinga2DataDir); } } } icinga2-2.14.6/agent/windows-setup-agent/ServiceStatus.resx000066400000000000000000001325441501332562400236630ustar00rootroot00000000000000 text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA IACoJQAA7h4AAAAAAAABACAA6iUAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAADDDgAAww4AAAAA AAAAAAAAv5UA/7+VAP+/lQD/v5UB/7+WAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+UAf++kwD/v5YB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/76TAP/Alwv/xZ8Z/72SAP+/lQD/v5UA/7+WAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAf++kwD/7eG3///////Orj3/vJAA/8CWA/+9kgD/v5QA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAf+/lQD/v5QA//Hoyf//////0rVQ/7yQAP/AlwX/yKMj/8CX Bf+/lAD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/76TAP/DnBb/zaw2/8WfHP+7jgD/vJAB/9a7 Xf/BmQn/vpQA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/vpQD/7qMAP/LqTT/7N+y/+na p//EnSD/vZEA/8CWAv/AlgL/wJYD/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CXBP+9kgD/7N+z//// ////////5dSX/7uPAP+/lQP/vJAA/7uOAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lAL/uYsA/+3h uP///////////+fYov/EnRX/xqEd/82tOv/Vulr/vpQA/7+VAP+/lQD/v5UA/7+VAf++kwD/xJ0S/8+v Qf/NrTr/696v/+zgtP/Fnxv/v5UA/72SAP/cxXP/9e7X/76TAP+/lQD/v5UB/7+VAP+/lgL/vJEA/8uo L//j0ZD/u48A/7uOAP/Algv/wZgQ/7uOAP+/lQD/vpMB/7+VBP+/lAD/v5UA/7+VAP+/lQD/v5UA/7+V AP++kwD/vI8A/8CWA//AlgL/wJYE/+nbqf/awWr/vJEA/8CWA/+/lQH/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UB/8CWAv+/lQH/vpQA/8GYCf/7+fD/696w/7uPAP/AlgP/v5UB/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP++kwD/w5sS/8GYC/++lAD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/76TAP++lAH/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgH/v5UB/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAoAAAAGAAAADAAAAABACAAAAAAAAAJAADDDgAAww4AAAAAAAAAAAAAv5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/wJcE/8CWAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V Af+7jwD/uo0A/7yRAP+/lgD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/72SAP/Yv2j/6t2s/82tPf+8kQD/wJYC/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP/AlgP/u48A/9K0S/////////////n16P/DnBL/vpMA/7+WAf+/lQD/v5YC/7+WAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlwT/u44A/9W6Wf////////////v5 8f/Fnxn/vpMA/7+VAf+/lgD/vZEA/72SAP+/lgD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQH/v5UA/7+VBP/k05b/9e/Z/9/Kgv++kwH/wJYE/8GYCP+7jwD/3cd6/9W6 Wf+7jgD/wJYD/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/76U AP+8kAH/vJEA/8KaFv/Mqjb/uowA/7uOAf+7jgD/17xh/8ikJP+9kgD/v5YB/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAf/AlgP/wJYD/72RAP/JpS3/3sl9/+PR kf/bxHD/wpoc/7yPAP/AlgH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5YB/72SAP/o2qb///////79+v//////3cd7/7yQAP/AlwT/v5YB/7+V AP+/lQH/v5YC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgL/vJEA/8uo L////////v37//38+f//////+PTl/8KZDP+9kQD/vpMB/76UAP+/lAH/vZIA/7+VAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/vZIA/8upMP///////v37//79+f//////+vbr/86u Pf/Kpiz/x6Ig/8KZC//Alwr/x6Mj/76TAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP++kwH/uo0A/7+VBf/x58b///////79+v//////4MuF/7yQAP/EnRL/yKMk/8ejI//q3Kv//////9K0 TP+7jwD/wJYD/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/76TAP/Fnhf/2L5k/86tPP/EnRb/3MZ2/+jZ pP/fyoH/v5UJ/7+VAP++lAD/vpMD/7qNAP/eyHz//Pr1/82sOf+8kAD/wJYD/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJYD/7uPAP/StEv//////8mlKf+7jwD/vI8D/7mLAP/EnR7/yKUp/7yQAP/AlwP/v5UB/7+V Af+9kgL/wJYH/72SAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgT/xJ4Y/7+U Af+/lgH/wJcE/8CXBP+/lAL/zKo3/8SdFv+9kQD/v5UA/7+VAP+/lQH/v5QB/7+WAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/vZIA/7+VAP+/lQD/v5UB/7+VAP+/lAD/696x//// ///VuVf/vJAA/8CWA/+/lQD/v5UB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5YC/7+VAP+/lQD/v5YB/76TAP/EnhX/+vfs///////l1Jn/u44A/8CXBP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+W Av+9kQD/1rtd/+japv/GoR//vZIA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/vJAA/7qNAP+9kgD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/wJYD/8CXBP+/lgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAA AABAAAAAAQAgAAAAAAAAEAAAww4AAMMOAAAAAAAAAAAAAL+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQH/wJYD/7+VAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYC/76TAf+8kAD/vpQB/8CWAv+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+WAf+8kAD/w5wV/86tOv/CmhH/vJEA/7+W Af+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgL/vJEA/86tPv/69+3///////j0 5f/KqDH/vZEA/8CWAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+WAf+9kgD/7+XC//// ///9/Pj//////+vfsv+8kAD/wJYC/7+VAP+/lQD/v5UA/7+WAf/AlgP/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/76U AP/z69H///////z79f//////7+XC/72RAP+/lgL/v5UA/7+VAP+/lQD/vZIA/7yPAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP/AlgP/u48A/9m/af///////v37///////Wu2H/u44A/8CXA/+/lQD/v5UB/76TAP/HoyL/0LJG/76U AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQH/vZEA/8+wQ//dyHr/0LFF/8+vQf++lAT/wJYC/8CXBP/BmAj/uo0A/9zF eP/38uD/vpMA/7+VAP+/lQH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgL/vJAA/7qOAf+6jAD/yqcv/86uP/+6jQD/u44C/7uO AP+9kQD/0rVP/8SeF/++kwD/v5UB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/wJcE/8CXBP+9kQD/zKo3/9Cy R//awm7/17xf/8+wQv/Ioyj/vJAA/8CWAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYC/7yQ AP/eyX////////7+/P///////v37/9CySf+8kAD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CW A/+8kAD/0LFF///////+/vz//v37//79+v//////+PTm/8OcFP++lAD/wJYD/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJcE/7uOAP/k0pP///////79+/////////////79+///////0rRP/7mLAP++kwP/vpQA/7+V Af/AlgL/wJYD/7+VAf/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP/AlwT/u44A/+XTl////////v37/////////////v78///////fyYD/yqcu/8il J//Cmw7/vpQA/72RAP+8kAD/vpQB/7yRAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UB/8GYB/+8kAD/z7BI///////+/vz//v36//79+v//////+vbq/8Wg HP/EnRT/y6ky/8+vQf/Qskf/y6gx/93GeP/48+L/171g/7yRAP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP++kwD/uo0A/7yQAP/LqC//6Nqn/////////v7///////37 9v/Tt1X/u48A/76UAv+9kQD/vZIA/7+WAv/HoiH/+PTm///////z69D/vpQA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgH/vpMA/8ahHf/gy4P/1rte/8qnL/+7jwD/zq8+/+DL g//cxnX/1rth/7yRA/+/lgD/v5UB/7+WAv+/lgL/v5UC/7uPAP/eyX7//Pr0/9rDb/+8kQD/wJYC/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CXBP+7jgD/2cFr///////hzoz/uYsA/8GY Bv+8kAD/u44C/7iJAP/JpjL/y6gy/72SAP/AlwT/v5UA/7+VAP+/lQD/v5UB/72RAf/Alwj/vZEA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/76TAP/EnRX/3MV2/8ah H/++kwD/v5YB/8CWA//AlwX/wJYC/8CXCf/Rs0z/u44A/7yQAP+/lgH/v5UA/7+VAP+/lQD/v5YC/7+U AP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/76T AP+6jQD/vpMA/7+VAP+/lQD/v5UA/7+VAP/AlgL/u48A/8yrQP/eyX3/zKo2/72RAP+/lgH/v5UA/7+V AP+/lQD/v5UB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UB/8CXBP+/lgH/v5UA/7+VAP+/lQD/v5UB/7+VAP+/lQL/7uO+////////////0LJG/7yQ AP/AlgP/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgL/vZIA/8agHP/9+/b//v35//// ///fy4L/uo0A/8CXBP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgH/vZIA/+fX of//////+vfr/8qnLv+9kQD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP++lAD/vpQF/8yrNf/Fnhr/vZEA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQL/vJAA/76TAf/AlgH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/v5YB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgA AAAwAAAAYAAAAAEAIAAAAAAAACQAAMMOAADDDgAAAAAAAAAAAAC/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+WAv/AlgT/wJYD/7+VAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYD/72SAP+7jgD/vJAA/7+V Av+/lgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQL/vI8A/8ij JP/Tt1T/zq49/76UBf+9kgD/wJYB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+W Af+9kQD/38uE///+/f///v7///////HoyP/Fnx3/vZIA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJYD/7uPAP/Wu1////////7+/P/+/vz//v37///////t4rv/vZIA/7+VAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/wJYC/7yRAP/u4rv///////79+//////////+///+/f/+/v3/yaYs/72R AP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/72SAP/x6Mj///////7+/f/////////////+ /v//////zKs4/7yQAP/AlgP/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJcE/8CWA/+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJcE/7uOAP/izoz///////38 +P/+/vz//v36///////48+P/wpoO/76UAP+/lQH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lAD/uo4A/7yQ AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5YB/76T AP/DnBb/9O3W/////////v3//v78///////XvWj/uo0A/8CXA/+/lQD/v5UA/7+VAP+/lQD/v5UB/7+U AP/AlwX/3MV1/9GzSf+9kgD/v5YC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/8CWAf+9kgD/wpoT/9/Jf//s4LX/5tWc/9GySf/XvWT/v5UH/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJYD/7yQAP/NrDr///////Pr0f++lAD/v5UA/7+VAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgH/vpQB/7qOAP+8jwD/u48C/7mLAP/OrkH/1blc/7uO AP/AlwP/v5UB/8CWAv/AlgL/wJYC/72SAP/FnyD/7eG5/9O2Uf+9kgD/v5YC/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/8CXBP/AlgP/wJYE/8CX Bf+7jwD/2L5m/8qoM/+8kQD/vpQC/7yQAP+9kQD/v5YC/7yQAP/XvGP/xqAl/7mMAP/AlgH/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAf++lAD/wZgP/9rCcP++lAf/w5wT/8yqNP/Kpy3/vZIA/8ijLP/WvGH/vJAA/8CX Bf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlwP/uo0A/86tSP/y6cv/+vbq////////////9e7X/+nb qv/Alxb/vpMA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CWAv+9kgD/x6Il//fy4P/////////+//// //////////7+///////l05j/vZEA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAf+9kgD/7eK8//// ///+/fr///7+/////////////v79//79+///////1bpe/7uPAP/AlgP/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYD/7yQ AP/Nqzj///////7+/f////////////////////////////7+/P//////8ObD/76TAP/AlgP/v5UB/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJcE/7uOAP/ZwGj///////79+//////////////////////////////+/v//////+fbq/8CX Ef+8jwD/v5QB/7+WAv/AlgP/v5YB/7+VAP+/lQD/v5UA/7+VAf/AlgT/wJYC/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/wJcE/7uOAP/ZwWr///////79+/////////////////////////////// /v///////Pr0/9W5WP/IpCb/wpkL/72RAP+8jwD/vZEA/76UAP+/lgH/wJcD/76UAf+7jgD/vZEA/8CW Av+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYD/7yQAP/Orj7///////7+/f////////////// //////////////7+/f//////8unM/8qnLv/Ut1T/2L5l/9e8Yv/Rs0v/yaYr/8KaDP+9kgD/u44A/8Kb E//UuFP/yqcu/7yRAP+/lgH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/7+WAf++kwD/7uS///// ///+/fn////+///////////////+//79+v//////2L9q/7iKAP+9kQT/vpMA/8OcEv/LqTL/07ZS/9i+ Zf/XvWH/0rVP//Tt1P///////////9W5WP+8kAD/wJYD/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CWAv+/lQH/wJcD/76U Av+8kQD/3cd5//z79v/////////+//7+/P///v3//v79///////q3K3/vZIA/8CWAv/AlgP/v5UB/76T AP+8kAD/vI8A/76UA/+/lgL/4MyH///////8+vT///////Dnxf+9kgD/v5YB/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5YA/72R AP++kwH/u48A/8KaEv/cxnf/yaYt/8eiJP/u5L7//v79///////+/v3//v38/+TSk/+9kgL/v5QB/7+W Af+/lQD/v5UA/7+VAf+/lgL/wJYD/8CXBP+6jQD/0bNP///////+/fr//////+rcrf+8kAD/wJYC/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP/AlgL/vZEA/8yqNf/z69D/6duq/9vDcP/GoCD/vJAA/72SAf+8kQH/yKUm/9GzSv/OrTv/yKQk/9W5 Xf+9kgD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQH/vpMA/+DMiP/59en/7+S//8ah Iv+9kgD/v5YC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP/AlgP/vI8A/+rdrv///////////9S4XP+5iwD/wZgF/7+WAv/AlgL/vZEA/7uP AP+9kQP/uo0A/9W6Xv/KqDT/vJEA/7+WAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/7yQ AP/BmAf/vZIC/72SAP+/lgD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/vI8A/9zEdP//////+/jv/8qnLf+9kgD/v5YC/7+V AP+/lQD/v5YC/8CWA//AlgT/vpMA/8SdGv/Zv23/vZEA/8CXA/+/lQH/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UB/8CWA/+/lAD/v5YC/7+WAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/72SAf/NrDn/x6Mk/72R AP+/lgH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYC/7uPAP/Wu2H/yaYv/7qNAP+/lQL/wJYC/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V Af+8kAD/vZIB/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/76TAP/Cmxn/171k/8ah Hf/CmQ//vJAA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP/AlgP/v5YC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYC/72R AP/LqDP/+PPj///////59ef/0rVS/7yQAP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQH/v5UA/8CWBf/07NP///////7+/P//////+/jv/8agHP+9kgD/v5YC/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lgL/vZEA/8ilKP/9/Pn///79/////v/+/fn//////9K0TP+7jwD/wJYD/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQH/vpQA/8KbD//48+T///////79+v///////v38/8mm K/+9kQD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYD/7yQAP/VuVz//v37//// /v//////3sh9/7yQAP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+W Af+8kAD/x6Ij/9S4Vv/Kpy7/vJAA/7+VAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP/AlgL/vZIA/7uOAP+9kQD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5YC/8CWBP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJUE5HDQoaCgAAAA1JSERSAAABAAAA AQAIAgAAANMQPzEAACWxSURBVHja7Z15fF1Xde9/a+9z7qDharImS/I8JrZjO4mHzCEUAiGEkhJCBwih rw2EqZQOD0qB5qWE1xI+vEfyQmlLKVAIJKShJcEhITij49gZPM+2bGuer3Sv7r3n7L3eH1uSHQ+JbEu6 5/rs78efxNZH0j1XWt9z9rD2WoT7nobFElZEvi/AYsknVgBLqLECWEKNFcASaqwAllBjBbCEGiuAJdRY ASyhxgpgCTVWAEuosQJYQo0VwBJqrACWUGMFsIQaK4Al1FgBLKHGCmAJNVYAS6ixAlhCjRXAEmqsAJZQ YwWwhBorgCXUWAEsocYKYAk1VgBLqLECWEKNFcASaqwAllBjBbCEGiuAJdRYASyhxgpgCTVWAEuosQJY Qo0VwBJqrACWUGMFsIQaK4Al1FgBLKHGCmAJNVYAS6ixAlhCjZPvC7CcFkEQRACUZvMRIhIEZmhmzvfl nR9YAQIHAZJIg7Wvta8BwBEgAsBaaV9DCjhCCsGAtiKcG1aAYCGIwOxnPUixeFrJmtrEBZXF88rikghA Mudv60293jP0YnuyP5khKaQr7dPgXLACBAhJpDw/IuV7F9ffvrj+7Y0VrqATPocBAlpS2R/v7fzXnW07 O5LCdUiQfRScHYT7ns73NVgAE/1Zb0ld2f1XL7iyvowZRNDMms3wBwBMkEtBAAjIKv21Vw7fs+lQ1tfC kdaBs8AKEAgkQWXVx1c03XvFvJgUihmAIKLTfL5maLAACcLLnYO3rtt+oDclo87YdNkyTuwyaP6RRCqr PnfprPuvXhARQjFLInn66AcgCA4REXzNl9aUrnvvRXMri1VOiTf7IsspsALkGTPy+cSKpm9cPtfc+OW4 g5gAR5CveV5Z/LEblzWURrXSVoEzwgqQTwSR8vzldWX/+/K5AAgkzjx8jQMLyou+eeV8aJ3v91RgWAHy iWaGlPdeOb/YkYr5LKLf4AhSzB+YV3Pr4nrOqfE/QyxWgLwhiZDzb54z7dqGcs18jlFrvvgLK2e4UUdp tgaMEytA3tBgSPHhRXUAzn3tRhAxY2lVyfVNlfDsbHi8WAHygyCwrxdWlbxzRiWACYlXDQZw6/waCOIJ cCoUWAHygyCCr1fXlEal0DwxIxYCAbisriwWdbQdBY0PK0A+ubCqBMBEbV6Zp0h9caShJArNdhA0HqwA +UExwxFzEjEAExWpBDAQlWJ+WRyaCdaAt8YKkE/Oet3zzbHLoOPHCpAnTFrb5ESqnf+OHytAfhBE0NyT 8TGa43nu8OhuwEDOB1kNxoUVID8QAUrv6EtN+Hfuy/o7+9IQwp6TGQ9WgPzADEixpScFwJmgqYCJ+F19 6d6MN1nTi/MOK0B+0MxwxIvtAweSGUzQSqj5Jk8c6UXOd4js/X88WAHyAwNSiqGh7IN7OzERZ9sZcARl lP7Rng5Ioe0UYHxYAfIGM8MR39/dlsz5jjjXG7Y5C/bw/q693UPCkfZk2DixAuQNzZCO3N05ePfmZhxX /OfsvpUjqD2d+9uXDkCQXQgdP1aAfKKYKeL8wyuH17f2m3MtZ/FNGDCpb1/YcOBAd0q69vZ/BlgB8gwR seY/emLHjr60I8g7w+DVDHOW4O83N39vW4uIufZc/BlhBcgzmlk48khy+F2/eG17X9oV5I+v0hWbhCJA Ev39K81ffG6frYxyFlgB8o9mlq5zOJm59uev/GhPhyNG0tg0s3FhLKh5NO7HQr83633kqV1ffG6fcKVN gD4LJG64Ld/XYAEDQorhnHp4T8fr/em1tYnyqMMgUxpoLLDN34lIEGV8/ZO9nR9ct/3ZQz0y6rKd+Z4V tjRiUNDMQgoI+u99XXetmg3gpY5ksSsWVRRHRrd1NaMv6+3uH368ueeHezsO9aRIkIzbcf/ZYwUIEIKg s/5ty5uWVBYfHcre9NjWrmFvdllsTiIuCJKoN+Pv7k8nsz7nfDhCRByAbfSfC1aAoECAr9iNuXdcOB3A d3e0dQ0My5h7sC99sCd17JOEgCAn5mqwnfKeO1aAoCCJ/Jz3ewumX1xd2jmc+5cdrXAlA2JsUmwmwcwA fBv6E4QVIBAQ4DOLiPPJJQ0AvrezvaUvfdzg3ob7ZGGXQQOBIELOf9/saZfVl/Xn/H/a3grHJvRPBVaA QKCY4co7lzUA+Pdd7Qd6hqRNaJsSzhMBRhfIC7IQgiRCTt0ws+ptDRVpXz+wtRVS2OCfGgpeAEEwucSs mRUzsykaXkCFETQzHLpzaQOAH+3p2NmVlDapYaoobAEkkfa1P+wJoCzu1hRHSyIOmP1hj9W5lpudsrfA nnp7U+W7ZlZ5mu/fchTC3v6njkJdBSJAEFTWm11VctviuutnVM5LxGOOTPtqW0/qv5t7/m1nW89gVkYd FexbqQaD6BNLGwD8ZG/Hax1JEXHs7X/KKNQeYQLQvv7kiqa7V89ORBw+LmHG/L0tlbvzmT2P7OkQkeDO JgWRzvlXNFY8e/NKDVz2s80vtfUL1wowdRTkEEgQtK/+4cr5//fK+SWu4+tjWZOmd7Riri+O/PxdS+5Y 3qQD3jmLcOeyRgAP7eu00T/1FJ4Akkhn1ceWNn5+RZM5QuWIkZZyNNpmXRJpZmbcf/WCa2dW6ZwfwPmA INKef2l92S3zagDct6XF7ndNPQUmABGU0tMSsa+umgVA0GmbagkiDSbg79fOIVeqCSpBPsEwPrm0URAe Pdj9TEsfReziz1RTYAJIInjqQ/NrGoqjvn6LplqSiIE1tYm3N1YErWmKINKeWlabuHVBLYD7t7RAsyjI bYzCpsAEMFXFr2kox/iqiptcmt9pqgxavXwCoPUnljZEBK073PvEkV7zmMr3dYWOQhKAANZwXbmgvAij DVHe4ksIAOaWxeCI4ISXIChfLawu/cOFtQDu29oCXwfqARUeCkkAAAALopg8s8uOSQEKULlkAkHpO5ZM L3bkb1v6/+tQNyL29p8fCk0AopzS3RkPwHiShE1QdWU8KB2Q7AgiKF/Nqiz+yKJ6mNu/Zzv75o1CEoDN vDanXusewpkUlN3ak4LSAamXbNrj/cmF0yuizovtyZ8f7ELBbv2aRWdHkCAigiA4RIWViFVIAoxAeGR/ F8bRWtTUi+3L+j/Z0xGQICOC8vX0iqKPLq4HcN+2Fp0tyErOJvSZWWV9P53Tns++1p72M54/7LGvBVFB zGoKLBdIMZMrnzjc+6vDvdfPqPQ0u6e/sZuSaYIwv7yopS9N0iXK8yETQaQ8//bF9XVFkVe7hn66rxNu 0LOVTvkuWGuV8+PxyNtmTVtZXbqgPF7kSE/r9nRuc+fg+raBw6ZiRUTqINx4Tk+BCYCRWoL6c8/uveh3 V9QXRTzNzkm3GmZosCRSzGUR5/Ebl3362b3ffe2IjDhMNIG/ERq5pOP/xYyR6Qmf9MnK11WJ2B9fUA/g /u0t3rDnxN2zKwmaL6QglfVLYu6nLp71xxfUzUnET07EGvLUQ/u7/vG1w9vbkjLm6AC37S68wlimsn7n YOaZ9uS7ZlVVRB0wGOwzmEcmBgQSRBs7B9/72Na6osiSyuIbZ01LxCO/bu7RzFKKc1GAAEEkBQHEAJjZ 1GobqeTG0GyO58iRTxvBEaSz/icuarplXs2O3tSnn93nBWhpalxIIpX1Lmuq/MV7lt46v6Y86gJQmk2I 8+jELCLFimklty2qG2RsaO0XIrgnlQpPABgHHHm0P/3jfZ0VMXdRRVFECkEkiUzVtL6s943Xj/7pb3Yd 7ks9fKCrOOpeVpdYW5e4uLbsicO9qWHPOasSypJImCwjX+msz2AhZYkrG0pjjaWxWWVFDaWxRMyJudJn 9jVrT2lPMQBBriBfcWnc/c41C6ti7l2bmp9v7nEiTgHd/SWRyvnvmV/76LuXmp14GslGecMfMwVWml1B 755ZVVkUefxAtzjnBgiTRKGmQ8OMRJVmX8+aVnxdQ8WiiqJiVw5k/a09qSeO9HYnh8mVQgpoVjn/Y8ub /s8V84ocuaMv/aF127e0DThxV417MCSJGKxzCpqjRZEV00rW1CUurSldUFY0szSWiEhB5BAB8Ji15p6s dyCZ2d2f3tiRfL49ubs3hZxSvvr4qln3X7Vgf3L4kp9u7s96VDjTXxP9lzVWPHnT8rgjFL/1eSNTudoR dPem5r95fl8wzzkUsAAYaTRN2lfwNQAQQWsQwZVSCpMjTQQBUhnvqllVP/ydC5pKor1Z749/s/uRXe0y 5ui36lJq1jp0zocUq6aXf2Bu9XtnTVtQHh//RSrm17uHfrq/61eHe//9ukXLqkr+54YD92w44MQKZvRP ADOXRpxn37/ioqqS8US/gQFmCMLbH33tqUM9MhK4GX9hC2AQNLIkyjwyHz351u4I8jPejMriH7/jwsvq Er7mL208dM/GA0IKCHHKO5N5vqucL6S4fva0zy5rvK6xYmxIr5jNr/bUi94MBmsG0bFu2DmlI1J0Zbyl P9jQkc45UWf8j6D8IolUxvvrtXO+tmaOr/mM2loaWzZ2JNc+/Io2LuX77bzhrRXiHOAEeORpe+wvJ6MZ 0pX96dxP9nY0lcZXVJe8vbFiTnnxukM9OV9J58RpsSAihs75FzdU/PAdF3zx4plzyuJEJrvObPqMjHfH ziG84Q+N1HAWRKacmwYcIQDEpZxeGnu1N9U7mJFSBH8URIBmLolHvnPNwsqYC5zZPpf5CTSWRDe0D+zr SUlHBur9ng8CjBNmCCl8rR/Z25FlumZ6+YrqkmubKp5s6e8fzB4/LZaCtKfijrjnqgXfvWbh3LK4GU2N Bv2Zve5YQXPzdxCWVZXcvrh+GHixtR8MEexT8Gb3/XdmVX5yaSPjbBoQK82CKKv5F/u7RMAqvhTgTvA5 oJlZkHTlPS/uv2Xd9t6sd1ld2XPvX3nVzEp/2JNERJCCVMa/oLpk/c0rP3dRIxEUs1liOsdXp9H/KuZi V37z8nmP3risuiiiPV8GJE/jlJdNAPPq2jKcbSc/8+Yuri41c4BAvdVwCQCM7BU4cfeRXe3XPvLajr5U U0n08RuXfWxFk8p6kqGGvXfPq37h5pWX1JT6emJC/wTMAU5f83tnTXvx91YuqUmojDdR/eInHM0MKeaV xTG+MxgnYx6asxOx8qgzMT3BJ47QCQCAAV+zE3e3dCSv/vmrv2zuLXLkP1+z8N5rF/lK/9HShv9899Ky iKP4FHvMEwURTFvIOYn4b25afuWMKj8T0OcAM0CIn2EK+sm4QsSlADhQm2JhFMDga5ZRp3vYu+m/Xr/3 9aMA/uyixg0fvOTbVy1wBWnGFKQoO4IUc3Xc/cV7lq5uLFcZL5gOADj3qNXMGaWBYO1+h1cAmMmZFBD0 57/dffvTu9K+Xl2TKHHF2U31zg6TsFQecR5+15JF1aUqYEVcCHAFQXPzYAZvtWdyWhgA+rJ+2teBuv0j 5ALADHAFQdCzh/sySgM424Hu2WMcaCiO/sc7L0xEHa11fhUwGyAmy5+Zta+Rzr3ensTZ3hc0GMDLncl0 1qOA5USEXQAyWSuO+N47LqiMOoo5L2MQSeRrXjGt5B+umAdfT33u2IlB7yl/OKdzvivF4uqS29fMvmFu teYz3AJ4I+tbB+DroJ19K7x06IlFCFIZ74uXz7uivmz8O/yTgZkP/MmF0399tO+hnW1y8nu+j25QQDNr zexr7Ss4Ihp1F1cXralNrKopvaK+fG5ZfOymcBYXZM7xtaVzP97TgeBVvgi1AIJI5dTS2sTnVzRhHEfM Jhtz479r9exfH+4dyPmTsUl8UtAr7Ws4MhZzLqwpXlNngr5sdiI+9rMY9vWr3YPrWwba0tm7Vs8ue2Ml 1rdEaXYEfXtLS1dyWEZdK0CAML+Kv1s9p9iRPrOTbwEEQTEvKi/63PKmLz+/T0xQuJjhjdnR4+OCPh5z ltaWralNrKotvaK+bGZpbOxLUr7a1Dn4YntyY2fypY7BtlRW5JTy/GJXjqUDjeeHZY7srW8d+PorzQE5 lXoC4RXAVGa+vLHifXOmAch79I9dFYA7ljQ8sK21LZUlSWcXM8eCXjMzK09BabiyOOYuqypeU5tYVZO4 or6ssSQ69iWDnnq5M/lie3Jjx+DGzmRHKsc5HwQ4EoIo5rhR556XDzWVRD+xpMFnNseCT3cBzFDMrqBd /enbfr1DKS0C2fUjvAIYTFuu/I7+j8ckStTE3Y8srrtnwwEhXTXugfcbgl6zUiNBXxJ3l08vWVObWFWb uLyubHpxZOxLkjn/pY7ki+3JjZ2DL3cOdqazyKmxoHfirjlcCoavmQgkxCef3jPk6b9c0QRAM2vGG/Kj eGTNR4AcQRs6kh94fNvRZEa4QYx+nB/p0GeBIGhfz6ko3nbrpXFHnNGgdrLRDEHY05++6MFNGV+/eUWv E4IeSkNpRJxEzF0xbTTo6xO18WNB35f1N3QkN7QnN3YmN3UOdg/nkFNmaxqCHEFjQX/y6xJBMFTOv35e zdfXzllWVXLyj858ZCDnf/3VI9/Y3JwL6r3fENIngCDSvr5p9rRxHm6a2msDAwvKi66ZXv6r/V3ipCY3 p7jTa4Yry+PuxdWlq2pK19QmLqsvmxZzx76kJ+O92J7c0JF8qSO5uWuwb9iDNxL0JEiO3umZ8eZndJih ARF1f7W/68nDvTfMnva7s6ddUlM6KxEjkADah3M7+9KPN/c8uK+zc2BYuE6Qox/hFMAkoiEib5pdle9r OTVm5eSmOdN+tb8Lo0nUAscFva/ADFdWFkUuqS5ZVZtYU5tYW5uoPC7ou4a9F9oHTNC/0j00YIJeEORx Qc9sMqPGf23meIPJ63x0d/ujezrcqFMedWJSMNCd8TI5BU/BlTLqauaAdzsOowBmoN2YiF1aU4oArH6e jLmktzWUx+JuTjMAVqx8HwxE5LTiyKXVpatqE2trE6trE+XRY7/E9nTu+faBlzoGX+oYeK07lRzOwVcQ 4hyD/mRMVrOMugA8xV2p3EiahCDzQqZQRr5/kG9NGAUQIOX7a2sTRY40A+6gYZSclYjPKors6kiKokh1 cXRVbemqmtK1dWWrakoTkWO/uJZU9vm25MbO5Ib25Os9Q0MZD56CFJCCpJCunKigPwE21erN1RKNXDRj wl9oUgmjAESA5pXVpQA0cwCfAObgbETQncub2tK5dzZVrqwuKXHl2CccGco+1zZggn5Lbyo9FvSOIGcS g/6U8Bv+V2CEUQDNDFfOScQw9Ylv48Zc1yeXNph/MnBoMPNc28DGjuSGjuS23tRwxoev4AjINwY9wy+E sUdACJ0AZNYZHTnXHHHK9/WcDrOY2Jv1/+tQtwn67b3pbNYEvYQk4QrTAZZt0J8DoRMAAJijjqiOuxhf m5m8YCr7buocvO3x7WAmKfiNQW/KTuX7MgueUAoAOEQjQ+qAxv8IRY4QUSmIzPDGBv2EE0oBGBEpIiLQ ZyGMmEWOJJCpwmkDfzIIdBBMHqa5fL6vYhzXyUEuLX4+EEoBCD5zRp2qhn9gMNc1mFO6cNbUC5FQCgB4 mvuzHoIb/yMMegp2/DOZhE4As3WZ89VImYOghpYZoB0azATwHO35ROgEgDnG4euDySzOus7HFEAAcCiZ AQerktR5RhgFIAKU3tGXQoB3gs0Jte29KZxbQyfLmxNGATQDjnyxPWnKvwUwuswl9WS8V7oGIUVBLFgV KGEUgJkhaVtvqiWVBYI4wTQRv7Ej2TscuEpS5xmhFACQQqTTuceaezCa0xtA1h3pg6eCWy30vCCMAozx 6MFuAEGLMFNJKu3rRw92w7Hjn8klpAKYjOgnj/Zt6RkiBKtmvYn4x5t7DvWlyRGBurbzj5AKwIAjyRv2 vrO9FQHbDTAHdB7Y1gJmYVdAJ5mQCgDT7Scif7inY39yWBIF5EZrzto+daTvySN9Aaykef4RXgHMVDg5 lP3a5sMIzEPA3PLv3nwIym4ATwXhFQBm/Sfi/MuO1vWt/aZIf36vx1Rf+9edbU8f6hXB6yl9XhJqAWAG 3Er/xXP7Ur7K76aYZnYEHUxm/nbDQTgiIE+k856wC6CZZcR5uaX/r17YD+TtvBUDJvvn4+v3tAykT27c bZkkwi4ATKewmHPfa0e/t6vddGrJzzUQvvTSwXX7O2V00ltjWMawAgDmBizFHb/Z9cvmXtO9dCpf2pTb //bWlv+14YCM2qH/lGIFAABmCEE5zX+wbtv61n7jwBSEIfNIGdDv727/1Po95Eqd7x9F2LACjKCZhRQD OfWeX7z+nwe7HUFK86Q+CTRDgx1B39py9LYndggiUIDPJ5ynWAGOYRxI+fqWx7Z+e2uLI86lJ+JbYFoR a8bnX9j/2ad3SylY2OjPAxI33JbvawgQDJAQAH65r2v3YObahvIiR2pmPUFFpBkjJTsF0e7+9Psf3/7g jlYZdbS99+cJ+wQ4EWbWgBNzfrKl5d2/2OJrFkSSyJQfPOsoNT2zcFxfra3dQ88f6nZirmYb/XnDCnAK 2JwVdsUfLqp1BO0bGH7iSB8RHCLTw8vX46rXw4BmU4MIRJBEmvkHu9s/vn5PTunfm1dz0+J6P+MFsDx1 eAhlZbi3QgpSGe/mRXWfWtYI4C9f2P/Irva3za3+H4vrr59RWR51xnI0x+7rAEaaefGxbzJaN58I6Ejn HjnYff+21q0dSXj+yurSOy6c/uVLZz15uDflq8loCWwZDyFtkvcmCCLtqxmlsfU3r5xVGrt/a8udT+2S UUfnfAZqy+I3zqy6trFibW1iZmn0zW/enua9/ekNHYOPH+759ZG+gaEsBMmIVL5uKI6+8IGLZ5RE/+al g3e/sF/G7eZXfrACnIggaE8/dMPSm+dWv9YzdO3Dr/Z7PgkSIAa00vAUJMWi7oLy+PyyorllsbqiaIkr S1ypmNO+GsypI0PZ5sHMzr70vuSwyvqmn5cUwkyCpSA17P3pyqYHrl7Yn/Uvf2jzjt5UwJvJna9YAd6A Cc07Vsz4f9csUMzX/edr6w/3yuMSM0eH8tBaQzG0hhngC9MjiEcG/swQApIghBkLqTdOoAlgxm/et/za hvKf7eu85bGtwg1iI/XzHjsJPoYgUjm1pDZx99rZAO7e1Ly+ueeE3AQemdQyEQlXyqjrFEWcuCsjjnCF cB0ZcZy46xRFZNQRjiCCYj55+UgQwVdf3XgQwAfm1bxnbo3O+vYAwNRjBRiBAGYWUnzr6gWVUXd968Bd Lx9CxDldbVozmDErQr5mNVq8/4SPnO6WrphFxFnf3Pudba0AvrpqVlHcVVpbA6YYK8AIQhDn/C9cMvNt DeX9Of8zz+zxfSUmc3GGwXDE3ZsOHRnKrqwu/exFjcgpEbASFec9VgAAkEQq61/RVPmlS2cB+NKGg6+3 DcjI5A7KmSEdcaQv/bXNzQA+v2LG4ppS5Sm7LTCVWAFABKV1Iu5+66oFEUGPHuz+9utHRMyZgnVJpRlR 54Htretb+yuizldWz7Z7wlOMFQACBE/dtWbOyuqSI0PZP3tmL4Apax4midhTX3npIIBb5tXcMLfazoan krALIAWprHfj/NpPL2sE8BfP7zvYl5Lu1C3Jm9nwb5t7/2m7mQ3PjsddpdkaMDWEWgBBUL6enojfe8U8 AP+yo+3BXe1TfyKRwZB098uHjqayF1eXfuaiRuR8OxueGkItAEDQ+h+vnD+vLL69N/XXL+yDFHrKyzEw Q7ry8Ohs+C9WzFhYXap85QiSRI6dFE8m4RVACtIZ7/YlDR+aXwPgM8/u6x7K5ascw8hseFvrM639lWY2 nFUq56uc7w97zGwtmCRCeiBGEGlPLaou+eE7Lix25T2bm7/7+hEZy2dGmiTSvtqbzPzRwrolVcWN5UXv nVP9/vk1RTHn6FBuOOsJKe0K0YQT0nRoZoagb121oCbuvtA+8JWNh+A6+W1IqgEQ7esbbk/nmkqiH1tc LwgM3Lao7shQ9g9+vePZw71ikrcmQsh5MgSi0T/jQQrirP9XF894R1PFkKc+88zerOfLvDZiIYA1R135 H9df0FQSVcya2desNCvmppLouhsvunZmlc7ZFdIJpoAFEASHyBFk7pQ8ehZFjHzw1JFiNn1XN1Z8+dLZ AL688eCmln6Z70KcUhBy/ueWN72tocLXbOa+5o+p1RV3xN+tnm3qRVsDJpDCE4AAszCife1nPT+d0/5o DhkzmHXO99M57fnMLImOnz4SoLQuijrfunpB3BGPNffc+8phEZ2KTd83f0e+Zhlzb55bDeDk9U9HkGZc UV/2zqZK2FyJCaWQ5gBkMpa19od9OGLhtJKLp5UuKI9fUFncVBL1NeeU9pnb07lNnYMbOwe39aZSqSyE EK6EqXpCpHL+3102b3VNaVs691mz6Ut5LslABPb1rMriCyuLAZzy0cVggOaWxaGZbOf4iaNgBBBEYFZZ L1EcvXFh3YcX1l7bUOGeZrfowwvrGGhP5R7c3/nA9tbdnYNEFIk6ueHc9XNr/nxFE4C/emH/3u6hIJxF NM3rM75+kwkuM0CoiDqwQ6AJpTAEkETKU0LQHStn/O3FM+uLowyY3l6amWhk+mvCh0dLMNQXRz67rPGO C6c/erD7rk3N21v66sqLv3nlPAD/vrv9B9tbRV7XPY/BAKE/6w/mVJEjT/kpZtiztScFYbuGTSQFIIAk Ujn/gprSb1+14NqG8uNrSwk6Vb0qAkZLmzA4KsUH59XcMLPqzmf2Xj29bFF50Z7+4b98bh9kUGrwm141 qeHcg/s6P72s0dd8wpNNMUuiw0PZp1r64Nq+kRNJ0AVwiPyM94EL6r9/3eK4IxQzgcYzCzQlSQBiQDEX u/L71y0C4Gn+1LN7OoayeV/5OR4GQ9C9rx65ZV5NXVHE0ywINLI6OiL5VzYeTKVzditgYgn0KpAk8rPe h5c1/vgdF5jol0RnmiRGphgbwxQ9PziYebF1AFIEqg6zZghHNg8Mv/u/txxIZlxBBBIEMrlAhC9sOPC9 rS0iYitHTDDBTYWQglTW/+iyxn+7bpG5kZ/LHhARBJFmnhZzl9eUPryvy9dMQdKfASFF28Dwzw50dWb8 uCMU48DA8JNH+z7y1K6H97SLiLSj/wknoGVRzLj/kvqy9e9fWeQIzZio7GDzGPnezrbbn9gRwOGEIGKl OefLqOs4Iqc15xQItmjKJBGke+AoZrsqHnXuu2ZhkSMU8wTmxptukB9dXP++BbU66wUts0AzQ5JTFNGE rK+YISKOjf7JI4gCCCJ4+kuXzlpVU2pu2BP7/c2q6dfXzq0qjSmlA6bASOkhYKSoqGa20T95BE4AIihf NVUU3bGkARNUlf/E90zwNS8oj39ueRN8Jabq+O8ZcXx2k2XyCJwAkgi+/vCiuoqo40/arqd5qvz+gtqS 4qgtRxVmgiUAAb7SpSXRjy6ug6nXMEkvRNDMs0pjN86ssullYSZYAggi+PryurK5iThjwlZ+TokZXXxw fg2k3VsNL8ESgAhQ+tLaUphjspP6zokAXFZXVhpz2WaYhZVgCaA0I+JcUlOKkUSGSaci6swqjUHxJHaE tASYAAlg6jPHI3L5tBJM5gRg7OU0wxF0QWUx7Dw4rARIAABgOEQJ1wGmojahGfrPK4tDT+Rem6WACJgA gOlJOpWvaCM/zARJAAKAqJzqooAZpWG3nMJKkARgwOz8T9krEgD4dg00xARJAABE/Vn/UDIDTMU5dfPm B7L+FC05WYJHgARgQAj4ntrem8JIHYRJfjkiX/OmrkFIe9A2pARIAIz2TtwzkMYUPAEYAI4MZff2D0MS 24FQKAmWAMyAFM+0DgBwJnkubMqgv9SRzGR9kde6iJY8EiwBNDNc+duWvle6BjG6Tj9JmFMBjx7qhtZk 10LDSrAEYMARpDL+j/d2Api8cbk5Y7mtN/Xz/d2w561CTLAEAKCY4cqf7O3sGvacSRuZmIj/5x1tueGc I+34J7wETgBmSCmO9qXu3nwIkzMK0syOoB196X/b1YaIDERxOEueCJwAABQzRZxvvX706ZZ+Uxx8Ar85 A2YD7NPP7BkYykkhbPiHmSAKAFMhWfGfP7u3P+c7gibwOaA0C8Ldm5qfOtgtowEqDmfJCwEVQDNLV77a kbx13fa0rwXRuUcqA75mR9BD+7u+/NJBCl5RIMvUE1ABYCpYRZ11+7p+/4ntOc3y3BzQzEqzI+hHezs+ 9KttCgyyCXCWAAsAQGmWcffRPZ03/nLL0VTWOHCmGpjiuARyBD2wvfXD63YogER+2qFagkagBYBxIOo8 sb975YObHjrQZVoeaYZifvOyOSbujS2S6Egqe/O67R9/aqcpqW4THyyG4BbHHYMB6cpU1v/pno5dyeFZ pbHGkqjpgWe6a2k+VkZKj2yfjZRWFkQpT313R9uHntj+Sku/jLjapv5bjiOgxXFPxmQG6awvXXndzKqP Xzj9qullFVH3dDkMmvnV7qEf7O742f7O1v5hkkI4wi75W06gYAQwSCLNzDkFQWXFkYuqilfXli2uKIpK coWISTHkqZ196V19qR196d29KT/rw5VCCtNpwmI5gQITwCCJGKwVQ2koDSlg+oQRQTN8BUGQgqSQgjTb 0LeclqC3SDolZmpLgoR0TI9Tc3qGGSRJRKT5yFiZZYvldBSkAAazznPClJZ5cpOoLecZQV8GtVgmFSuA JdRYASyhxgpgCTVWAEuosQJYQo0VwBJqrACWUGMFsIQaK4Al1FgBLKHGCmAJNVYAS6ixAlhCjRXAEmqs AJZQYwWwhBorgCXUWAEsocYKYAk1VgBLqLECWEKNFcASaqwAllBjBbCEGiuAJdRYASyhxgpgCTVWAEuo sQJYQo0VwBJqrACWUGMFsIQaK4Al1FgBLKHGCmAJNVYAS6ixAlhCjRXAEmqsAJZQYwWwhBorgCXUWAEs oeb/A5fj85sn5OS0AAAAAElFTkSuQmCC icinga2-2.14.6/agent/windows-setup-agent/SetupWizard.Designer.cs000066400000000000000000001056611501332562400245230ustar00rootroot00000000000000namespace Icinga { partial class SetupWizard { /// /// Required designer variable. /// private System.ComponentModel.IContainer components = null; /// /// Clean up any resources being used. /// /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SetupWizard)); this.btnBack = new System.Windows.Forms.Button(); this.btnNext = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); this.tabFinish = new System.Windows.Forms.TabPage(); this.lblSetupCompleted = new System.Windows.Forms.Label(); this.tabConfigure = new System.Windows.Forms.TabPage(); this.lblConfigStatus = new System.Windows.Forms.Label(); this.prgConfig = new System.Windows.Forms.ProgressBar(); this.tabParameters = new System.Windows.Forms.TabPage(); this.groupBox4 = new System.Windows.Forms.GroupBox(); this.btnEditGlobalZone = new System.Windows.Forms.Button(); this.btnRemoveGlobalZone = new System.Windows.Forms.Button(); this.btnAddGlobalZone = new System.Windows.Forms.Button(); this.lvwGlobalZones = new System.Windows.Forms.ListView(); this.colGlobalZoneName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.introduction1 = new System.Windows.Forms.Label(); this.groupBox3 = new System.Windows.Forms.GroupBox(); this.chkDisableConf = new System.Windows.Forms.CheckBox(); this.txtUser = new System.Windows.Forms.TextBox(); this.chkRunServiceAsThisUser = new System.Windows.Forms.CheckBox(); this.chkAcceptConfig = new System.Windows.Forms.CheckBox(); this.chkAcceptCommands = new System.Windows.Forms.CheckBox(); this.txtTicket = new System.Windows.Forms.TextBox(); this.lblTicket = new System.Windows.Forms.Label(); this.txtInstanceName = new System.Windows.Forms.TextBox(); this.lblInstanceName = new System.Windows.Forms.Label(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.rdoNoListener = new System.Windows.Forms.RadioButton(); this.txtListenerPort = new System.Windows.Forms.TextBox(); this.lblListenerPort = new System.Windows.Forms.Label(); this.rdoListener = new System.Windows.Forms.RadioButton(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.btnEditEndpoint = new System.Windows.Forms.Button(); this.btnRemoveEndpoint = new System.Windows.Forms.Button(); this.btnAddEndpoint = new System.Windows.Forms.Button(); this.lvwEndpoints = new System.Windows.Forms.ListView(); this.colInstanceName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.colHost = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.colPort = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.tbcPages = new System.Windows.Forms.TabControl(); this.tabRetrieveCertificate = new System.Windows.Forms.TabPage(); this.lblRetrieveCertificate = new System.Windows.Forms.Label(); this.prgRetrieveCertificate = new System.Windows.Forms.ProgressBar(); this.tabVerifyCertificate = new System.Windows.Forms.TabPage(); this.grpX509Fields = new System.Windows.Forms.GroupBox(); this.txtX509Field = new System.Windows.Forms.TextBox(); this.lvwX509Fields = new System.Windows.Forms.ListView(); this.colField = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.colValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.txtX509Subject = new System.Windows.Forms.TextBox(); this.txtX509Issuer = new System.Windows.Forms.TextBox(); this.lblX509Subject = new System.Windows.Forms.Label(); this.lblX509Issuer = new System.Windows.Forms.Label(); this.lblX509Prompt = new System.Windows.Forms.Label(); this.tabError = new System.Windows.Forms.TabPage(); this.txtError = new System.Windows.Forms.TextBox(); this.lblError = new System.Windows.Forms.Label(); this.picBanner = new System.Windows.Forms.PictureBox(); this.linkLabelDocs = new System.Windows.Forms.LinkLabel(); this.tabFinish.SuspendLayout(); this.tabConfigure.SuspendLayout(); this.tabParameters.SuspendLayout(); this.groupBox4.SuspendLayout(); this.groupBox3.SuspendLayout(); this.groupBox2.SuspendLayout(); this.groupBox1.SuspendLayout(); this.tbcPages.SuspendLayout(); this.tabRetrieveCertificate.SuspendLayout(); this.tabVerifyCertificate.SuspendLayout(); this.grpX509Fields.SuspendLayout(); this.tabError.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picBanner)).BeginInit(); this.SuspendLayout(); // // btnBack // this.btnBack.Enabled = false; this.btnBack.Location = new System.Drawing.Point(376, 587); this.btnBack.Name = "btnBack"; this.btnBack.Size = new System.Drawing.Size(75, 23); this.btnBack.TabIndex = 1; this.btnBack.Text = "< &Back"; this.btnBack.UseVisualStyleBackColor = true; this.btnBack.Click += new System.EventHandler(this.btnBack_Click); // // btnNext // this.btnNext.Location = new System.Drawing.Point(457, 587); this.btnNext.Name = "btnNext"; this.btnNext.Size = new System.Drawing.Size(75, 23); this.btnNext.TabIndex = 2; this.btnNext.Text = "&Next >"; this.btnNext.UseVisualStyleBackColor = true; this.btnNext.Click += new System.EventHandler(this.btnNext_Click); // // btnCancel // this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnCancel.Location = new System.Drawing.Point(538, 587); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); this.btnCancel.TabIndex = 3; this.btnCancel.Text = "Cancel"; this.btnCancel.UseVisualStyleBackColor = true; this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); // // tabFinish // this.tabFinish.Controls.Add(this.lblSetupCompleted); this.tabFinish.Location = new System.Drawing.Point(4, 5); this.tabFinish.Name = "tabFinish"; this.tabFinish.Padding = new System.Windows.Forms.Padding(3); this.tabFinish.Size = new System.Drawing.Size(617, 495); this.tabFinish.TabIndex = 5; this.tabFinish.Text = "Finish"; this.tabFinish.UseVisualStyleBackColor = true; // // lblSetupCompleted // this.lblSetupCompleted.AutoSize = true; this.lblSetupCompleted.Location = new System.Drawing.Point(34, 35); this.lblSetupCompleted.Name = "lblSetupCompleted"; this.lblSetupCompleted.Size = new System.Drawing.Size(252, 13); this.lblSetupCompleted.TabIndex = 0; this.lblSetupCompleted.Text = "The Icinga Windows agent was set up successfully."; // // tabConfigure // this.tabConfigure.Controls.Add(this.lblConfigStatus); this.tabConfigure.Controls.Add(this.prgConfig); this.tabConfigure.Location = new System.Drawing.Point(4, 5); this.tabConfigure.Name = "tabConfigure"; this.tabConfigure.Padding = new System.Windows.Forms.Padding(3); this.tabConfigure.Size = new System.Drawing.Size(617, 495); this.tabConfigure.TabIndex = 4; this.tabConfigure.Text = "Configure Icinga 2"; this.tabConfigure.UseVisualStyleBackColor = true; // // lblConfigStatus // this.lblConfigStatus.AutoSize = true; this.lblConfigStatus.Location = new System.Drawing.Point(184, 204); this.lblConfigStatus.Name = "lblConfigStatus"; this.lblConfigStatus.Size = new System.Drawing.Size(141, 13); this.lblConfigStatus.TabIndex = 1; this.lblConfigStatus.Text = "Updating the configuration..."; // // prgConfig // this.prgConfig.Location = new System.Drawing.Point(184, 223); this.prgConfig.Name = "prgConfig"; this.prgConfig.Size = new System.Drawing.Size(289, 23); this.prgConfig.TabIndex = 0; // // tabParameters // this.tabParameters.Controls.Add(this.linkLabelDocs); this.tabParameters.Controls.Add(this.groupBox4); this.tabParameters.Controls.Add(this.introduction1); this.tabParameters.Controls.Add(this.groupBox3); this.tabParameters.Controls.Add(this.txtTicket); this.tabParameters.Controls.Add(this.lblTicket); this.tabParameters.Controls.Add(this.txtInstanceName); this.tabParameters.Controls.Add(this.lblInstanceName); this.tabParameters.Controls.Add(this.groupBox2); this.tabParameters.Controls.Add(this.groupBox1); this.tabParameters.Location = new System.Drawing.Point(4, 5); this.tabParameters.Name = "tabParameters"; this.tabParameters.Padding = new System.Windows.Forms.Padding(3); this.tabParameters.Size = new System.Drawing.Size(617, 495); this.tabParameters.TabIndex = 3; this.tabParameters.Text = "Agent Parameters"; this.tabParameters.UseVisualStyleBackColor = true; // // groupBox4 // this.groupBox4.Controls.Add(this.btnEditGlobalZone); this.groupBox4.Controls.Add(this.btnRemoveGlobalZone); this.groupBox4.Controls.Add(this.btnAddGlobalZone); this.groupBox4.Controls.Add(this.lvwGlobalZones); this.groupBox4.Location = new System.Drawing.Point(8, 210); this.groupBox4.Name = "groupBox4"; this.groupBox4.Size = new System.Drawing.Size(601, 110); this.groupBox4.TabIndex = 9; this.groupBox4.TabStop = false; this.groupBox4.Text = "Global Zones"; // // btnEditGlobalZone // this.btnEditGlobalZone.Enabled = false; this.btnEditGlobalZone.Location = new System.Drawing.Point(520, 48); this.btnEditGlobalZone.Name = "btnEditGlobalZone"; this.btnEditGlobalZone.Size = new System.Drawing.Size(75, 23); this.btnEditGlobalZone.TabIndex = 7; this.btnEditGlobalZone.Text = "Edit"; this.btnEditGlobalZone.UseVisualStyleBackColor = true; this.btnEditGlobalZone.Click += new System.EventHandler(this.btnEditGlobalZone_Click); // // btnRemoveGlobalZone // this.btnRemoveGlobalZone.Enabled = false; this.btnRemoveGlobalZone.Location = new System.Drawing.Point(520, 77); this.btnRemoveGlobalZone.Name = "btnRemoveGlobalZone"; this.btnRemoveGlobalZone.Size = new System.Drawing.Size(75, 23); this.btnRemoveGlobalZone.TabIndex = 6; this.btnRemoveGlobalZone.Text = "Remove"; this.btnRemoveGlobalZone.UseVisualStyleBackColor = true; this.btnRemoveGlobalZone.Click += new System.EventHandler(this.btnRemoveGlobalZone_Click); // // btnAddGlobalZone // this.btnAddGlobalZone.Location = new System.Drawing.Point(520, 19); this.btnAddGlobalZone.Name = "btnAddGlobalZone"; this.btnAddGlobalZone.Size = new System.Drawing.Size(75, 23); this.btnAddGlobalZone.TabIndex = 5; this.btnAddGlobalZone.Text = "Add"; this.btnAddGlobalZone.UseVisualStyleBackColor = true; this.btnAddGlobalZone.Click += new System.EventHandler(this.btnAddGlobalZone_Click); // // lvwGlobalZones // this.lvwGlobalZones.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.colGlobalZoneName}); this.lvwGlobalZones.FullRowSelect = true; this.lvwGlobalZones.Location = new System.Drawing.Point(6, 19); this.lvwGlobalZones.Name = "lvwGlobalZones"; this.lvwGlobalZones.Size = new System.Drawing.Size(500, 81); this.lvwGlobalZones.TabIndex = 4; this.lvwGlobalZones.UseCompatibleStateImageBehavior = false; this.lvwGlobalZones.View = System.Windows.Forms.View.Details; this.lvwGlobalZones.SelectedIndexChanged += new System.EventHandler(this.lvwGlobalZones_SelectedIndexChanged); // // colGlobalZoneName // this.colGlobalZoneName.Text = "Zone Name"; this.colGlobalZoneName.Width = 496; // // introduction1 // this.introduction1.AutoSize = true; this.introduction1.Location = new System.Drawing.Point(11, 3); this.introduction1.Name = "introduction1"; this.introduction1.Size = new System.Drawing.Size(262, 13); this.introduction1.TabIndex = 6; this.introduction1.Text = "Welcome to the Icinga Windows Agent Setup Wizard!"; // // groupBox3 // this.groupBox3.Controls.Add(this.chkDisableConf); this.groupBox3.Controls.Add(this.txtUser); this.groupBox3.Controls.Add(this.chkRunServiceAsThisUser); this.groupBox3.Controls.Add(this.chkAcceptConfig); this.groupBox3.Controls.Add(this.chkAcceptCommands); this.groupBox3.Location = new System.Drawing.Point(308, 326); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(301, 163); this.groupBox3.TabIndex = 5; this.groupBox3.TabStop = false; this.groupBox3.Text = "Advanced Options"; // // chkDisableConf // this.chkDisableConf.AutoSize = true; this.chkDisableConf.Checked = true; this.chkDisableConf.CheckState = System.Windows.Forms.CheckState.Checked; this.chkDisableConf.Location = new System.Drawing.Point(9, 137); this.chkDisableConf.Name = "chkDisableConf"; this.chkDisableConf.Size = new System.Drawing.Size(211, 17); this.chkDisableConf.TabIndex = 9; this.chkDisableConf.Text = "Disable including local \'conf.d\' directory"; this.chkDisableConf.UseVisualStyleBackColor = true; // // txtUser // this.txtUser.Enabled = false; this.txtUser.Location = new System.Drawing.Point(28, 88); this.txtUser.Name = "txtUser"; this.txtUser.Size = new System.Drawing.Size(178, 20); this.txtUser.TabIndex = 8; this.txtUser.Text = "NT AUTHORITY\\NetworkService"; // // chkRunServiceAsThisUser // this.chkRunServiceAsThisUser.AutoSize = true; this.chkRunServiceAsThisUser.Location = new System.Drawing.Point(9, 65); this.chkRunServiceAsThisUser.Name = "chkRunServiceAsThisUser"; this.chkRunServiceAsThisUser.Size = new System.Drawing.Size(183, 17); this.chkRunServiceAsThisUser.TabIndex = 7; this.chkRunServiceAsThisUser.Text = "Run Icinga 2 service as this user:"; this.chkRunServiceAsThisUser.UseVisualStyleBackColor = true; this.chkRunServiceAsThisUser.CheckedChanged += new System.EventHandler(this.chkRunServiceAsThisUser_CheckedChanged); // // chkAcceptConfig // this.chkAcceptConfig.AutoSize = true; this.chkAcceptConfig.Location = new System.Drawing.Point(9, 42); this.chkAcceptConfig.Name = "chkAcceptConfig"; this.chkAcceptConfig.Size = new System.Drawing.Size(284, 17); this.chkAcceptConfig.TabIndex = 1; this.chkAcceptConfig.Text = "Accept config updates from master/satellite instance(s)"; this.chkAcceptConfig.UseVisualStyleBackColor = true; // // chkAcceptCommands // this.chkAcceptCommands.AutoSize = true; this.chkAcceptCommands.Location = new System.Drawing.Point(9, 19); this.chkAcceptCommands.Name = "chkAcceptCommands"; this.chkAcceptCommands.Size = new System.Drawing.Size(265, 17); this.chkAcceptCommands.TabIndex = 0; this.chkAcceptCommands.Text = "Accept commands from master/satellite instance(s)"; this.chkAcceptCommands.UseVisualStyleBackColor = true; // // txtTicket // this.txtTicket.Location = new System.Drawing.Point(164, 56); this.txtTicket.Name = "txtTicket"; this.txtTicket.Size = new System.Drawing.Size(350, 20); this.txtTicket.TabIndex = 1; // // lblTicket // this.lblTicket.AutoSize = true; this.lblTicket.Location = new System.Drawing.Point(9, 59); this.lblTicket.Name = "lblTicket"; this.lblTicket.Size = new System.Drawing.Size(149, 13); this.lblTicket.TabIndex = 4; this.lblTicket.Text = "CSR Signing Ticket (optional):"; // // txtInstanceName // this.txtInstanceName.Location = new System.Drawing.Point(164, 27); this.txtInstanceName.Name = "txtInstanceName"; this.txtInstanceName.Size = new System.Drawing.Size(350, 20); this.txtInstanceName.TabIndex = 0; // // lblInstanceName // this.lblInstanceName.AutoSize = true; this.lblInstanceName.Location = new System.Drawing.Point(11, 30); this.lblInstanceName.Name = "lblInstanceName"; this.lblInstanceName.Size = new System.Drawing.Size(121, 13); this.lblInstanceName.TabIndex = 3; this.lblInstanceName.Text = "Instance Name (FQDN):"; // // groupBox2 // this.groupBox2.Controls.Add(this.rdoNoListener); this.groupBox2.Controls.Add(this.txtListenerPort); this.groupBox2.Controls.Add(this.lblListenerPort); this.groupBox2.Controls.Add(this.rdoListener); this.groupBox2.Location = new System.Drawing.Point(8, 326); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(298, 163); this.groupBox2.TabIndex = 2; this.groupBox2.TabStop = false; this.groupBox2.Text = "TCP Listener"; // // rdoNoListener // this.rdoNoListener.AutoSize = true; this.rdoNoListener.Checked = true; this.rdoNoListener.Location = new System.Drawing.Point(11, 82); this.rdoNoListener.Name = "rdoNoListener"; this.rdoNoListener.Size = new System.Drawing.Size(163, 17); this.rdoNoListener.TabIndex = 9; this.rdoNoListener.TabStop = true; this.rdoNoListener.Text = "Do not listen for connections."; this.rdoNoListener.UseVisualStyleBackColor = true; this.rdoNoListener.CheckedChanged += new System.EventHandler(this.RadioListener_CheckedChanged); // // txtListenerPort // this.txtListenerPort.Enabled = false; this.txtListenerPort.Location = new System.Drawing.Point(66, 47); this.txtListenerPort.Name = "txtListenerPort"; this.txtListenerPort.Size = new System.Drawing.Size(84, 20); this.txtListenerPort.TabIndex = 8; this.txtListenerPort.Text = "5665"; // // lblListenerPort // this.lblListenerPort.AutoSize = true; this.lblListenerPort.Location = new System.Drawing.Point(31, 51); this.lblListenerPort.Name = "lblListenerPort"; this.lblListenerPort.Size = new System.Drawing.Size(29, 13); this.lblListenerPort.TabIndex = 1; this.lblListenerPort.Text = "Port:"; // // rdoListener // this.rdoListener.AutoSize = true; this.rdoListener.Location = new System.Drawing.Point(11, 24); this.rdoListener.Name = "rdoListener"; this.rdoListener.Size = new System.Drawing.Size(283, 17); this.rdoListener.TabIndex = 7; this.rdoListener.Text = "Listen for connections from master/satellite instance(s):"; this.rdoListener.UseVisualStyleBackColor = true; this.rdoListener.CheckedChanged += new System.EventHandler(this.RadioListener_CheckedChanged); // // groupBox1 // this.groupBox1.Controls.Add(this.btnEditEndpoint); this.groupBox1.Controls.Add(this.btnRemoveEndpoint); this.groupBox1.Controls.Add(this.btnAddEndpoint); this.groupBox1.Controls.Add(this.lvwEndpoints); this.groupBox1.Location = new System.Drawing.Point(8, 94); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(601, 110); this.groupBox1.TabIndex = 1; this.groupBox1.TabStop = false; this.groupBox1.Text = "Parent master/satellite instance(s) for this agent"; // // btnEditEndpoint // this.btnEditEndpoint.Enabled = false; this.btnEditEndpoint.Location = new System.Drawing.Point(520, 48); this.btnEditEndpoint.Name = "btnEditEndpoint"; this.btnEditEndpoint.Size = new System.Drawing.Size(75, 23); this.btnEditEndpoint.TabIndex = 7; this.btnEditEndpoint.Text = "Edit"; this.btnEditEndpoint.UseVisualStyleBackColor = true; this.btnEditEndpoint.Click += new System.EventHandler(this.btnEditEndpoint_Click); // // btnRemoveEndpoint // this.btnRemoveEndpoint.Enabled = false; this.btnRemoveEndpoint.Location = new System.Drawing.Point(520, 77); this.btnRemoveEndpoint.Name = "btnRemoveEndpoint"; this.btnRemoveEndpoint.Size = new System.Drawing.Size(75, 23); this.btnRemoveEndpoint.TabIndex = 6; this.btnRemoveEndpoint.Text = "Remove"; this.btnRemoveEndpoint.UseVisualStyleBackColor = true; this.btnRemoveEndpoint.Click += new System.EventHandler(this.btnRemoveEndpoint_Click); // // btnAddEndpoint // this.btnAddEndpoint.Location = new System.Drawing.Point(520, 19); this.btnAddEndpoint.Name = "btnAddEndpoint"; this.btnAddEndpoint.Size = new System.Drawing.Size(75, 23); this.btnAddEndpoint.TabIndex = 5; this.btnAddEndpoint.Text = "Add"; this.btnAddEndpoint.UseVisualStyleBackColor = true; this.btnAddEndpoint.Click += new System.EventHandler(this.btnAddEndpoint_Click); // // lvwEndpoints // this.lvwEndpoints.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.colInstanceName, this.colHost, this.colPort}); this.lvwEndpoints.FullRowSelect = true; this.lvwEndpoints.Location = new System.Drawing.Point(6, 19); this.lvwEndpoints.Name = "lvwEndpoints"; this.lvwEndpoints.Size = new System.Drawing.Size(500, 81); this.lvwEndpoints.TabIndex = 4; this.lvwEndpoints.UseCompatibleStateImageBehavior = false; this.lvwEndpoints.View = System.Windows.Forms.View.Details; this.lvwEndpoints.SelectedIndexChanged += new System.EventHandler(this.lvwEndpoints_SelectedIndexChanged); // // colInstanceName // this.colInstanceName.Text = "Instance Name"; this.colInstanceName.Width = 200; // // colHost // this.colHost.Text = "Host"; this.colHost.Width = 200; // // colPort // this.colPort.Text = "Port"; this.colPort.Width = 80; // // tbcPages // this.tbcPages.Appearance = System.Windows.Forms.TabAppearance.FlatButtons; this.tbcPages.Controls.Add(this.tabParameters); this.tbcPages.Controls.Add(this.tabRetrieveCertificate); this.tbcPages.Controls.Add(this.tabVerifyCertificate); this.tbcPages.Controls.Add(this.tabConfigure); this.tbcPages.Controls.Add(this.tabFinish); this.tbcPages.Controls.Add(this.tabError); this.tbcPages.ItemSize = new System.Drawing.Size(0, 1); this.tbcPages.Location = new System.Drawing.Point(0, 80); this.tbcPages.Margin = new System.Windows.Forms.Padding(0); this.tbcPages.Name = "tbcPages"; this.tbcPages.SelectedIndex = 0; this.tbcPages.Size = new System.Drawing.Size(625, 504); this.tbcPages.SizeMode = System.Windows.Forms.TabSizeMode.Fixed; this.tbcPages.TabIndex = 0; this.tbcPages.SelectedIndexChanged += new System.EventHandler(this.tbcPages_SelectedIndexChanged); // // tabRetrieveCertificate // this.tabRetrieveCertificate.Controls.Add(this.lblRetrieveCertificate); this.tabRetrieveCertificate.Controls.Add(this.prgRetrieveCertificate); this.tabRetrieveCertificate.Location = new System.Drawing.Point(4, 5); this.tabRetrieveCertificate.Name = "tabRetrieveCertificate"; this.tabRetrieveCertificate.Padding = new System.Windows.Forms.Padding(3); this.tabRetrieveCertificate.Size = new System.Drawing.Size(617, 495); this.tabRetrieveCertificate.TabIndex = 7; this.tabRetrieveCertificate.Text = "Checking Certificate"; this.tabRetrieveCertificate.UseVisualStyleBackColor = true; // // lblRetrieveCertificate // this.lblRetrieveCertificate.AutoSize = true; this.lblRetrieveCertificate.Location = new System.Drawing.Point(164, 229); this.lblRetrieveCertificate.Name = "lblRetrieveCertificate"; this.lblRetrieveCertificate.Size = new System.Drawing.Size(110, 13); this.lblRetrieveCertificate.TabIndex = 3; this.lblRetrieveCertificate.Text = "Checking certificate..."; // // prgRetrieveCertificate // this.prgRetrieveCertificate.Location = new System.Drawing.Point(164, 248); this.prgRetrieveCertificate.Name = "prgRetrieveCertificate"; this.prgRetrieveCertificate.Size = new System.Drawing.Size(289, 23); this.prgRetrieveCertificate.TabIndex = 2; // // tabVerifyCertificate // this.tabVerifyCertificate.Controls.Add(this.grpX509Fields); this.tabVerifyCertificate.Controls.Add(this.txtX509Subject); this.tabVerifyCertificate.Controls.Add(this.txtX509Issuer); this.tabVerifyCertificate.Controls.Add(this.lblX509Subject); this.tabVerifyCertificate.Controls.Add(this.lblX509Issuer); this.tabVerifyCertificate.Controls.Add(this.lblX509Prompt); this.tabVerifyCertificate.Location = new System.Drawing.Point(4, 5); this.tabVerifyCertificate.Name = "tabVerifyCertificate"; this.tabVerifyCertificate.Padding = new System.Windows.Forms.Padding(3); this.tabVerifyCertificate.Size = new System.Drawing.Size(617, 495); this.tabVerifyCertificate.TabIndex = 6; this.tabVerifyCertificate.Text = "Verify Certificate"; this.tabVerifyCertificate.UseVisualStyleBackColor = true; // // grpX509Fields // this.grpX509Fields.Controls.Add(this.txtX509Field); this.grpX509Fields.Controls.Add(this.lvwX509Fields); this.grpX509Fields.Location = new System.Drawing.Point(11, 115); this.grpX509Fields.Name = "grpX509Fields"; this.grpX509Fields.Size = new System.Drawing.Size(598, 369); this.grpX509Fields.TabIndex = 8; this.grpX509Fields.TabStop = false; this.grpX509Fields.Text = "X509 Fields"; // // txtX509Field // this.txtX509Field.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.txtX509Field.Location = new System.Drawing.Point(6, 197); this.txtX509Field.Multiline = true; this.txtX509Field.Name = "txtX509Field"; this.txtX509Field.ReadOnly = true; this.txtX509Field.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.txtX509Field.Size = new System.Drawing.Size(586, 166); this.txtX509Field.TabIndex = 9; // // lvwX509Fields // this.lvwX509Fields.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.colField, this.colValue}); this.lvwX509Fields.Location = new System.Drawing.Point(6, 19); this.lvwX509Fields.Name = "lvwX509Fields"; this.lvwX509Fields.Size = new System.Drawing.Size(586, 172); this.lvwX509Fields.TabIndex = 8; this.lvwX509Fields.UseCompatibleStateImageBehavior = false; this.lvwX509Fields.View = System.Windows.Forms.View.Details; this.lvwX509Fields.SelectedIndexChanged += new System.EventHandler(this.lvwX509Fields_SelectedIndexChanged); // // colField // this.colField.Text = "Field"; this.colField.Width = 200; // // colValue // this.colValue.Text = "Value"; this.colValue.Width = 350; // // txtX509Subject // this.txtX509Subject.Location = new System.Drawing.Point(71, 73); this.txtX509Subject.Name = "txtX509Subject"; this.txtX509Subject.ReadOnly = true; this.txtX509Subject.Size = new System.Drawing.Size(532, 20); this.txtX509Subject.TabIndex = 4; // // txtX509Issuer // this.txtX509Issuer.Location = new System.Drawing.Point(71, 47); this.txtX509Issuer.Name = "txtX509Issuer"; this.txtX509Issuer.ReadOnly = true; this.txtX509Issuer.Size = new System.Drawing.Size(532, 20); this.txtX509Issuer.TabIndex = 3; // // lblX509Subject // this.lblX509Subject.AutoSize = true; this.lblX509Subject.Location = new System.Drawing.Point(8, 77); this.lblX509Subject.Name = "lblX509Subject"; this.lblX509Subject.Size = new System.Drawing.Size(46, 13); this.lblX509Subject.TabIndex = 2; this.lblX509Subject.Text = "Subject:"; // // lblX509Issuer // this.lblX509Issuer.AutoSize = true; this.lblX509Issuer.Location = new System.Drawing.Point(8, 50); this.lblX509Issuer.Name = "lblX509Issuer"; this.lblX509Issuer.Size = new System.Drawing.Size(38, 13); this.lblX509Issuer.TabIndex = 1; this.lblX509Issuer.Text = "Issuer:"; // // lblX509Prompt // this.lblX509Prompt.AutoSize = true; this.lblX509Prompt.Location = new System.Drawing.Point(8, 15); this.lblX509Prompt.Name = "lblX509Prompt"; this.lblX509Prompt.Size = new System.Drawing.Size(241, 13); this.lblX509Prompt.TabIndex = 0; this.lblX509Prompt.Text = "Please verify the master/satellite\'s SSL certificate:"; // // tabError // this.tabError.Controls.Add(this.txtError); this.tabError.Controls.Add(this.lblError); this.tabError.Location = new System.Drawing.Point(4, 5); this.tabError.Name = "tabError"; this.tabError.Padding = new System.Windows.Forms.Padding(3); this.tabError.Size = new System.Drawing.Size(617, 495); this.tabError.TabIndex = 8; this.tabError.Text = "Error"; this.tabError.UseVisualStyleBackColor = true; // // txtError // this.txtError.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.txtError.Location = new System.Drawing.Point(11, 38); this.txtError.Multiline = true; this.txtError.Name = "txtError"; this.txtError.ReadOnly = true; this.txtError.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.txtError.Size = new System.Drawing.Size(598, 397); this.txtError.TabIndex = 1; // // lblError // this.lblError.AutoSize = true; this.lblError.Location = new System.Drawing.Point(8, 12); this.lblError.Name = "lblError"; this.lblError.Size = new System.Drawing.Size(209, 13); this.lblError.TabIndex = 0; this.lblError.Text = "An error occurred while setting up Icinga 2:"; // // picBanner // this.picBanner.Image = ((System.Drawing.Image)(resources.GetObject("picBanner.Image"))); this.picBanner.Location = new System.Drawing.Point(0, 0); this.picBanner.Name = "picBanner"; this.picBanner.Size = new System.Drawing.Size(625, 77); this.picBanner.TabIndex = 1; this.picBanner.TabStop = false; // // linkLabelDocs // this.linkLabelDocs.AutoSize = true; this.linkLabelDocs.LinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(149)))), ((int)(((byte)(191))))); this.linkLabelDocs.Location = new System.Drawing.Point(525, 3); this.linkLabelDocs.Name = "linkLabelDocs"; this.linkLabelDocs.Size = new System.Drawing.Size(79, 13); this.linkLabelDocs.TabIndex = 10; this.linkLabelDocs.TabStop = true; this.linkLabelDocs.Text = "Documentation"; this.linkLabelDocs.VisitedLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(149)))), ((int)(((byte)(191))))); this.linkLabelDocs.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelDocs_LinkClicked); // // SetupWizard // this.AcceptButton = this.btnNext; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; this.ClientSize = new System.Drawing.Size(625, 622); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnNext); this.Controls.Add(this.btnBack); this.Controls.Add(this.picBanner); this.Controls.Add(this.tbcPages); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.Name = "SetupWizard"; this.Text = "Icinga Windows Agent Setup Wizard"; this.Load += new System.EventHandler(this.SetupWizard_Load); this.tabFinish.ResumeLayout(false); this.tabFinish.PerformLayout(); this.tabConfigure.ResumeLayout(false); this.tabConfigure.PerformLayout(); this.tabParameters.ResumeLayout(false); this.tabParameters.PerformLayout(); this.groupBox4.ResumeLayout(false); this.groupBox3.ResumeLayout(false); this.groupBox3.PerformLayout(); this.groupBox2.ResumeLayout(false); this.groupBox2.PerformLayout(); this.groupBox1.ResumeLayout(false); this.tbcPages.ResumeLayout(false); this.tabRetrieveCertificate.ResumeLayout(false); this.tabRetrieveCertificate.PerformLayout(); this.tabVerifyCertificate.ResumeLayout(false); this.tabVerifyCertificate.PerformLayout(); this.grpX509Fields.ResumeLayout(false); this.grpX509Fields.PerformLayout(); this.tabError.ResumeLayout(false); this.tabError.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.picBanner)).EndInit(); this.ResumeLayout(false); } #endregion private System.Windows.Forms.PictureBox picBanner; private System.Windows.Forms.Button btnBack; private System.Windows.Forms.Button btnNext; private System.Windows.Forms.Button btnCancel; private System.Windows.Forms.TabPage tabFinish; private System.Windows.Forms.Label lblSetupCompleted; private System.Windows.Forms.TabPage tabConfigure; private System.Windows.Forms.Label lblConfigStatus; private System.Windows.Forms.ProgressBar prgConfig; private System.Windows.Forms.TabPage tabParameters; private System.Windows.Forms.TextBox txtInstanceName; private System.Windows.Forms.Label lblInstanceName; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.RadioButton rdoNoListener; private System.Windows.Forms.TextBox txtListenerPort; private System.Windows.Forms.Label lblListenerPort; private System.Windows.Forms.RadioButton rdoListener; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.Button btnRemoveEndpoint; private System.Windows.Forms.Button btnAddEndpoint; private System.Windows.Forms.ListView lvwEndpoints; private System.Windows.Forms.ColumnHeader colHost; private System.Windows.Forms.ColumnHeader colPort; private System.Windows.Forms.TabControl tbcPages; private System.Windows.Forms.TabPage tabVerifyCertificate; private System.Windows.Forms.Label lblX509Prompt; private System.Windows.Forms.TextBox txtX509Subject; private System.Windows.Forms.TextBox txtX509Issuer; private System.Windows.Forms.Label lblX509Subject; private System.Windows.Forms.Label lblX509Issuer; private System.Windows.Forms.GroupBox grpX509Fields; private System.Windows.Forms.ListView lvwX509Fields; private System.Windows.Forms.ColumnHeader colField; private System.Windows.Forms.ColumnHeader colValue; private System.Windows.Forms.TextBox txtX509Field; private System.Windows.Forms.TabPage tabRetrieveCertificate; private System.Windows.Forms.Label lblRetrieveCertificate; private System.Windows.Forms.ProgressBar prgRetrieveCertificate; private System.Windows.Forms.TabPage tabError; private System.Windows.Forms.TextBox txtError; private System.Windows.Forms.Label lblError; private System.Windows.Forms.TextBox txtTicket; private System.Windows.Forms.Label lblTicket; private System.Windows.Forms.ColumnHeader colInstanceName; private System.Windows.Forms.GroupBox groupBox3; private System.Windows.Forms.CheckBox chkAcceptConfig; private System.Windows.Forms.CheckBox chkAcceptCommands; private System.Windows.Forms.TextBox txtUser; private System.Windows.Forms.CheckBox chkRunServiceAsThisUser; private System.Windows.Forms.Button btnEditEndpoint; private System.Windows.Forms.Label introduction1; private System.Windows.Forms.GroupBox groupBox4; private System.Windows.Forms.Button btnEditGlobalZone; private System.Windows.Forms.Button btnRemoveGlobalZone; private System.Windows.Forms.Button btnAddGlobalZone; private System.Windows.Forms.ListView lvwGlobalZones; private System.Windows.Forms.ColumnHeader colGlobalZoneName; private System.Windows.Forms.CheckBox chkDisableConf; private System.Windows.Forms.LinkLabel linkLabelDocs; } } icinga2-2.14.6/agent/windows-setup-agent/SetupWizard.cs000066400000000000000000000367331501332562400227670ustar00rootroot00000000000000using System; using System.IO; using System.Text; using System.Windows.Forms; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Net.NetworkInformation; using System.Diagnostics; using System.Security.AccessControl; namespace Icinga { public partial class SetupWizard : Form { private string _TrustedFile; private string Icinga2User; public SetupWizard() { InitializeComponent(); txtInstanceName.Text = Icinga2InstanceName; Icinga2User = Program.Icinga2User; txtUser.Text = Icinga2User; } private void Warning(string message) { MessageBox.Show(this, message, Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); } private string Icinga2InstanceName { get { IPGlobalProperties props = IPGlobalProperties.GetIPGlobalProperties(); string fqdn = props.HostName; if (props.DomainName != "") fqdn += "." + props.DomainName; return fqdn.ToLower(); } } private bool GetMasterHostPort(out string host, out string port) { foreach (ListViewItem lvi in lvwEndpoints.Items) { if (lvi.SubItems.Count > 1) { host = lvi.SubItems[1].Text.Trim(); port = lvi.SubItems[2].Text.Trim(); return true; } } host = null; port = null; return false; } private void EnableFeature(string feature) { FileStream fp = null; try { fp = File.Open(Program.Icinga2DataDir + String.Format("\\etc\\icinga2\\features-enabled\\{0}.conf", feature), FileMode.Create); using (StreamWriter sw = new StreamWriter(fp, Encoding.ASCII)) { fp = null; sw.Write(String.Format("include \"../features-available/{0}.conf\"\n", feature)); } } finally { if (fp != null) fp.Dispose(); } } private void SetRetrievalStatus(int pct) { if (InvokeRequired) { Invoke((MethodInvoker)delegate { SetRetrievalStatus(pct); }); return; } prgRetrieveCertificate.Value = pct; } private void SetConfigureStatus(int pct, string message) { if (InvokeRequired) { Invoke((MethodInvoker)delegate { SetConfigureStatus(pct, message); }); return; } prgConfig.Value = pct; lblConfigStatus.Text = message; } private void ShowErrorText(string text) { if (InvokeRequired) { Invoke((MethodInvoker)delegate { ShowErrorText(text); }); return; } txtError.Text = text; tbcPages.SelectedTab = tabError; } private bool RunProcess(string filename, string arguments, out string output) { ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = filename; psi.Arguments = arguments; psi.CreateNoWindow = true; psi.UseShellExecute = false; psi.RedirectStandardOutput = true; psi.RedirectStandardError = true; String result = ""; using (Process proc = Process.Start(psi)) { proc.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs args) { result += args.Data + "\r\n"; }; proc.OutputDataReceived += delegate (object sender, DataReceivedEventArgs args) { result += args.Data + "\r\n"; }; proc.BeginOutputReadLine(); proc.BeginErrorReadLine(); proc.WaitForExit(); output = result; if (proc.ExitCode != 0) return false; } return true; } private void VerifyCertificate(string host, string port) { SetRetrievalStatus(25); string pathPrefix = Program.Icinga2DataDir + "\\etc\\icinga2\\pki\\" + txtInstanceName.Text; string processArguments = "pki new-cert --cn \"" + txtInstanceName.Text + "\" --key \"" + pathPrefix + ".key\" --cert \"" + pathPrefix + ".crt\""; string output; if (!File.Exists(pathPrefix + ".crt")) { if (!RunProcess(Program.Icinga2InstallDir + "\\sbin\\icinga2.exe", processArguments, out output)) { ShowErrorText("Running command 'icinga2.exe " + processArguments + "' produced the following output:\n" + output); return; } } SetRetrievalStatus(50); _TrustedFile = Path.GetTempFileName(); processArguments = "pki save-cert --host \"" + host + "\" --port \"" + port + "\" --trustedcert \"" + _TrustedFile + "\""; if (!RunProcess(Program.Icinga2InstallDir + "\\sbin\\icinga2.exe", processArguments, out output)) { ShowErrorText("Running command 'icinga2.exe " + processArguments + "' produced the following output:\n" + output); return; } SetRetrievalStatus(100); try { X509Certificate2 cert = new X509Certificate2(_TrustedFile); Invoke((MethodInvoker)delegate { ShowCertificatePrompt(cert); }); } catch (Exception e) { ShowErrorText("Failed to receive certificate: " + e.Message); } } private void ConfigureService() { SetConfigureStatus(0, "Updating configuration files..."); string output; string args = ""; Invoke((MethodInvoker)delegate { string master_host, master_port; GetMasterHostPort(out master_host, out master_port); args += " --master_host " + master_host + "," + master_port; foreach (ListViewItem lvi in lvwEndpoints.Items) { args += " --endpoint " + lvi.SubItems[0].Text.Trim(); if (lvi.SubItems.Count > 1) args += "," + lvi.SubItems[1].Text.Trim() + "," + lvi.SubItems[2].Text.Trim(); } }); if (rdoListener.Checked) args += " --listen ::," + txtListenerPort.Text.Trim(); if (chkAcceptConfig.Checked) args += " --accept-config"; if (chkAcceptCommands.Checked) args += " --accept-commands"; string ticket = txtTicket.Text.Trim(); if (ticket.Length > 0) args += " --ticket \"" + ticket + "\""; args += " --trustedcert \"" + _TrustedFile + "\""; args += " --cn \"" + txtInstanceName.Text.Trim() + "\""; args += " --zone \"" + txtInstanceName.Text.Trim() + "\""; foreach (ListViewItem lvi in lvwGlobalZones.Items) { args += " --global_zones " + lvi.SubItems[0].Text.Trim(); } if (chkDisableConf.Checked) args += " --disable-confd"; if (!RunProcess(Program.Icinga2InstallDir + "\\sbin\\icinga2.exe", "node setup" + args, out output)) { ShowErrorText("Running command 'icinga2.exe " + "node setup" + args + "' produced the following output:\n" + output); return; } SetConfigureStatus(50, "Setting ACLs for the Icinga 2 directory..."); string serviceUser = txtUser.Text.Trim(); DirectoryInfo di = new DirectoryInfo(Program.Icinga2InstallDir); DirectorySecurity ds = di.GetAccessControl(); FileSystemAccessRule rule = new FileSystemAccessRule(serviceUser, FileSystemRights.Modify, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow); try { ds.AddAccessRule(rule); di.SetAccessControl(ds); } catch (System.Security.Principal.IdentityNotMappedException) { ShowErrorText("Could not set ACLs for user \"" + serviceUser + "\". Identitiy is not mapped.\n"); return; } SetConfigureStatus(75, "Installing the Icinga 2 service..."); RunProcess(Program.Icinga2InstallDir + "\\sbin\\icinga2.exe", "--scm-uninstall", out output); if (!RunProcess(Program.Icinga2InstallDir + "\\sbin\\icinga2.exe", "daemon --validate", out output)) { ShowErrorText("Running command 'icinga2.exe daemon --validate' produced the following output:\n" + output); return; } if (!RunProcess(Program.Icinga2InstallDir + "\\sbin\\icinga2.exe", "--scm-install --scm-user \"" + serviceUser + "\" daemon", out output)) { ShowErrorText("\nRunning command 'icinga2.exe --scm-install --scm-user \"" + serviceUser + "\" daemon' produced the following output:\n" + output); return; } SetConfigureStatus(100, "Finished."); // Override the completed text lblSetupCompleted.Text = "The Icinga Windows agent was set up successfully."; // Add a note for the user for ticket-less signing if (ticket.Length == 0) { lblSetupCompleted.Text += "\n\nTicket was not specified. Please sign the certificate request on the Icinga 2 master node (requires v2.8+)."; } FinishConfigure(); } private void FinishConfigure() { if (InvokeRequired) { Invoke((MethodInvoker)FinishConfigure); return; } tbcPages.SelectedTab = tabFinish; } private void btnBack_Click(object sender, EventArgs e) { if (tbcPages.SelectedTab == tabError) { tbcPages.SelectedIndex = 0; return; } int offset = 1; if (tbcPages.SelectedTab == tabVerifyCertificate) offset++; tbcPages.SelectedIndex -= offset; } private void btnNext_Click(object sender, EventArgs e) { if (tbcPages.SelectedTab == tabParameters) { if (txtInstanceName.Text.Length == 0) { Warning("Please enter an instance name."); return; } if (lvwEndpoints.Items.Count == 0) { Warning("You need to add at least one master/satellite endpoint."); return; } string host, port; if (!GetMasterHostPort(out host, out port)) { Warning("Please enter a remote host and port for at least one of your endpoints."); return; } if (rdoListener.Checked && (txtListenerPort.Text == "")) { Warning("You need to specify a listener port."); return; } if (txtUser.Text.Length == 0) { Warning("Icinga 2 service user may not be empty."); return; } } if (tbcPages.SelectedTab == tabFinish || tbcPages.SelectedTab == tabError) Application.Exit(); tbcPages.SelectedIndex++; } private void btnCancel_Click(object sender, EventArgs e) { Application.Exit(); } private void tbcPages_SelectedIndexChanged(object sender, EventArgs e) { Refresh(); btnBack.Enabled = (tbcPages.SelectedTab == tabVerifyCertificate || tbcPages.SelectedTab == tabError); btnNext.Enabled = (tbcPages.SelectedTab == tabParameters || tbcPages.SelectedTab == tabVerifyCertificate || tbcPages.SelectedTab == tabFinish); if (tbcPages.SelectedTab == tabFinish) { btnNext.Text = "&Finish >"; btnCancel.Enabled = false; } if (tbcPages.SelectedTab == tabRetrieveCertificate) { ListViewItem lvi = lvwEndpoints.Items[0]; string master_host, master_port; GetMasterHostPort(out master_host, out master_port); Thread thread = new Thread((ThreadStart)delegate { VerifyCertificate(master_host, master_port); }); thread.Start(); } if (tbcPages.SelectedTab == tabConfigure) { Thread thread = new Thread(ConfigureService); thread.Start(); } } private void RadioListener_CheckedChanged(object sender, EventArgs e) { txtListenerPort.Enabled = rdoListener.Checked; } private void AddCertificateField(string name, string shortValue, string longValue = null) { ListViewItem lvi = new ListViewItem(); lvi.Text = name; lvi.SubItems.Add(shortValue); if (longValue == null) longValue = shortValue; lvi.Tag = longValue; lvwX509Fields.Items.Add(lvi); } private string PadText(string input) { string output = ""; for (int i = 0; i < input.Length; i += 2) { if (output != "") output += " "; int len = 2; if (input.Length - i < 2) len = input.Length - i; output += input.Substring(i, len); } return output; } private void ShowCertificatePrompt(X509Certificate2 certificate) { txtX509Issuer.Text = certificate.Issuer; txtX509Subject.Text = certificate.Subject; lvwX509Fields.Items.Clear(); AddCertificateField("Version", "V" + certificate.Version.ToString()); AddCertificateField("Serial number", certificate.SerialNumber); AddCertificateField("Signature algorithm", certificate.SignatureAlgorithm.FriendlyName); AddCertificateField("Valid from", certificate.NotBefore.ToString()); AddCertificateField("Valid to", certificate.NotAfter.ToString()); string pkey = BitConverter.ToString(certificate.PublicKey.EncodedKeyValue.RawData).Replace("-", " "); AddCertificateField("Public key", certificate.PublicKey.Oid.FriendlyName + " (" + certificate.PublicKey.Key.KeySize + " bits)", pkey); string thumbprint = PadText(certificate.Thumbprint); AddCertificateField("Thumbprint", thumbprint); tbcPages.SelectedTab = tabVerifyCertificate; } private void btnAddEndpoint_Click(object sender, EventArgs e) { EndpointInputBox eib = new EndpointInputBox(); if (eib.ShowDialog(this) == DialogResult.Cancel) return; ListViewItem lvi = new ListViewItem(); lvi.Text = eib.txtInstanceName.Text; if (eib.chkConnect.Checked) { lvi.SubItems.Add(eib.txtHost.Text); lvi.SubItems.Add(eib.txtPort.Text); } lvwEndpoints.Items.Add(lvi); } private void lvwEndpoints_SelectedIndexChanged(object sender, EventArgs e) { btnRemoveEndpoint.Enabled = lvwEndpoints.SelectedItems.Count > 0; btnEditEndpoint.Enabled = lvwEndpoints.SelectedItems.Count > 0; } private void lvwX509Fields_SelectedIndexChanged(object sender, EventArgs e) { if (lvwX509Fields.SelectedItems.Count == 0) return; ListViewItem lvi = lvwX509Fields.SelectedItems[0]; txtX509Field.Text = Convert.ToString(lvi.Tag); } private void btnRemoveEndpoint_Click(object sender, EventArgs e) { while (lvwEndpoints.SelectedItems.Count > 0) { lvwEndpoints.Items.Remove(lvwEndpoints.SelectedItems[0]); } } private void chkRunServiceAsThisUser_CheckedChanged(object sender, EventArgs e) { txtUser.Enabled = !txtUser.Enabled; if (!txtUser.Enabled) txtUser.Text = Icinga2User; } private void btnEditEndpoint_Click(object sender, EventArgs e) { ListViewItem lvi = lvwEndpoints.SelectedItems[0]; EndpointInputBox eib = new EndpointInputBox(); eib.Text = "Edit Endpoint"; eib.txtInstanceName.Text = lvi.SubItems[0].Text; if (lvi.SubItems.Count >= 2) { eib.txtHost.Text = lvi.SubItems[1].Text; eib.txtPort.Text = lvi.SubItems[2].Text; eib.chkConnect.Checked = true; } if (eib.ShowDialog(this) == DialogResult.Cancel) return; lvwEndpoints.Items.Remove(lvi); ListViewItem lvi2 = new ListViewItem(); lvi2.Text = eib.txtInstanceName.Text; if (eib.chkConnect.Checked) { lvi2.SubItems.Add(eib.txtHost.Text); lvi2.SubItems.Add(eib.txtPort.Text); } lvwEndpoints.Items.Add(lvi2); } private void btnAddGlobalZone_Click(object sender, EventArgs e) { GlobalZonesInputBox gzib = new GlobalZonesInputBox(lvwGlobalZones.Items); if (gzib.ShowDialog(this) == DialogResult.Cancel) return; ListViewItem lvi = new ListViewItem(); lvi.Text = gzib.txtGlobalZoneName.Text; lvwGlobalZones.Items.Add(lvi); } private void btnRemoveGlobalZone_Click(object sender, EventArgs e) { while (lvwGlobalZones.SelectedItems.Count > 0) { lvwGlobalZones.Items.Remove(lvwGlobalZones.SelectedItems[0]); } } private void lvwGlobalZones_SelectedIndexChanged(object sender, EventArgs e) { btnEditGlobalZone.Enabled = lvwGlobalZones.SelectedItems.Count > 0; btnRemoveGlobalZone.Enabled = lvwGlobalZones.SelectedItems.Count > 0; } private void btnEditGlobalZone_Click(object sender, EventArgs e) { ListViewItem lvi = lvwGlobalZones.SelectedItems[0]; GlobalZonesInputBox gzib = new GlobalZonesInputBox(lvwGlobalZones.Items); gzib.Text = "Edit Global Zone"; gzib.txtGlobalZoneName.Text = lvi.SubItems[0].Text; if (gzib.ShowDialog(this) == DialogResult.Cancel) return; lvwGlobalZones.Items.Remove(lvi); ListViewItem lvi2 = new ListViewItem(); lvi2.Text = gzib.txtGlobalZoneName.Text; lvwGlobalZones.Items.Add(lvi2); } private void SetupWizard_Load(object sender, EventArgs e) { this.MinimumSize = this.Size; this.MaximumSize = this.Size; } private void linkLabelDocs_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { linkLabelDocs.LinkVisited = true; Process.Start("https://icinga.com/docs/icinga2/latest/"); } } } icinga2-2.14.6/agent/windows-setup-agent/SetupWizard.resx000066400000000000000000003563331501332562400233440ustar00rootroot00000000000000 text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 iVBORw0KGgoAAAANSUhEUgAAAnIAAABOCAYAAACkCftqAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfiChgPIB4skikEAADGP0lEQVR4XuydB3gVV5K2 PeNAMjkKISQQIucMTjjngAPGOIExOeecFVBEOeeIkIQkEAgQOWdwnvGMZzy7k2cn7+yE3f3rr6/61tVR qyWEjT32rO7zfM/t2923b4dzTr23zqk6t33nxU10K/XdlzbX1Ctbauj2SVtr6pUAS6/W1h2TA92687Wg GrpryvZauvON4BvqrjdDqMlboaKmb4dVa1q4qNk7EbXUdKqlZtN2uNX8nUi3mk6vrWbvRrnVfEZ0DbWY GSO6e1asWy1mW7p7Tly9au5Sy7nxorvnJdRSy/mJbrVakFJLLRdaarUotZZaL06rpTZL0mup7dIMt9ot y3RU++VZog4rsmuo7cpqtVuV46j2q3Pd6rAmr4Y6rs13VId1ljquL6ilTht21qkOG3ZRx41Fok6biutU 580ltdRly+5a6rzVUpdtpfXKw79M1DWg3KW9DtJt5eQZWCHqGrSnWvhsk2fQPkvb94q6bd/vlm4z13kF V9aSZ0htdQs9cFPyCjt4y9Q9/FCD5BVRLad19m0NldM53ayc7lF9cnoG5jMyn2F9cpcHlatcQI7lx0HO ZdOSlmOnMq51QeqDQ11ROdUtlVNd1PoKof5CqMudNxZSl027RFq/tf532VBInrxft02F1J2399hSJO+d 1hW425Uua/LJY22BvNdoW1xtD9ojp/bKbNMgs73TdhByaidNme2qU7urbbJT263S9l3aeHe7n+QW7ILd ZrRgWwKJTTHsTV1Se1VDLrumUntn2kInW2naUlOws2J3nWyyy16bNlztOgQ7r7IzwB2vbxc5MoSNMyCT Q2pxivKLjWvs3GPnIid2+jJqBDlVI8iJTIBTOTUoZoPj1CBBjSBX27CZ+meCnAkETvJ0gAgn2KhPTjDz ReUEV05ygjVznX2bd0SVW7ruRnI6v4bI6R7VJ6dnYD4j87nWJ3d5UH2NIGfKY6slxzrjULdUTnXRCeQU 4jw2F9ULcp4bdwrA+fJ+PTYXk8c6bgNcbYuCHCRtitHeKPA5wZzZpkFme9cIcjcPci2m8/5sZ5u8XYdN bgS5GrqlIGee6O0vM7SxzIuxX6xc8CT/2jeHVRfAqcybrw/G/sBU5kM1H7ZZCBxBzgC3hsCbyiy49QGc U2VwqjSqVkaFs1dEqOX8ZJFZaU2Ac8uh8kO3At5UZuMFmQ2bvRE0VRe82aWNa8e13FCzOq9nGKsH3uyf ZV0D4A1yMi4qtyEyPQ8ORsxJTkZRVW1E97jlaHQdjLOuczLqKhMIPF2QcCOYsG9zgpWGygmQ6pMJXG7w 2lFbTrDmuM34jlu2/aFax7qBnK61obLf3xtJn4v5LFXms3aXESe5yky3YC5L/F7jzwGWXboZoDPVdRu/ K8BxmTfridQVA+bcdclWx5zqpCmtx6Y3Dsv2+i6Qt3EXdd1URN14fx9+99lSTF7YVyCNhT+C3K50ccEc wM5sb/C58+pqmHOCOsgEOrMddGorVWb7Cjm1wWYb7dSGQ84gVy39kw+bYbcn7s8O9seUo+2CTTNADjLt n2kXVXbbadpYu/01bbMd5Ey7Dpk234kJTJksobLzRr0wBzmxjck+ykMGI0FOHPVF1AhyjSDnltlIODUi ZiPj1BCZMhsv6P86yDkaOQdjqPqmgFx9coKRhsoJgupTQ0HOO/JwtWz7mdvM77i313Ncp3NyktO1NlRO 97g+6XMzn6WT9Jm7y4opV5n5JoGcSuuYU500pfVYAU5lr+8KchA8cwA4gJw3f4a3DiDXbr3Lq89ti90z BwHiFO6gbzvI2dUIcpbsvPF/AuTsJycyLsKUXKS6Ix26VM2bZr+ZkONNd3g4KvOBqkyAazLVgjizkLgL i6s7Fe9mAYPsBRDSwqmF1izEZuF2AjmnymKXCXJ1wVxd8FajcjtU/voADmoIvEFmo2XCmzZskFPDpwBX H8hVw5shG7yZsjfkkDb6ppyMgwlrdtUwNmqQbOBmVw3jZnSXWlJjiO5TG7QZxtRtVBXYIMMom6BmyjTq ni7jb8oJEpzkBB/1yQ03pifMtU6hyZR7HyeQ+rbJdZ2mnO5RfXJ6Bk5yeqbmM3cqEyqz/NgFuHOXO1d5 rP6DAaizl+NqmWXdqT6o6gM6p7pn1k9d1nqs3jgFOnvdV5DDO0AOy923FFGPrcXUfQMfg/8Q6vAMqMva QjfMqScObRXaInzWdZ1W5VLHlTUBTpe1/TPbRcip7VTdDNBh2ak9d8vBFsBGqL2or5tVh/E42SLItF81 ZNg6SG2g2keVkw2121lIbXAt+6wwVwfQ4bPafCc2gBraxXpDkDOZxgZ0kJuBbJzkxFNfRI0g1whyokaQ qym7ATFVw9g0glydcgNMI8iJnO5RfXJ6Bk5yeqbmM3cqEyqz/Nj1fwHkEPjgwzAHr5x0rxogB7DTLlaF OW2bAHCmFORMNYJcI8ip3Axk4yQnnvoiagS5RpATNYJcTdkNiKkaxuYbDHKmMVd5Ohh9JzhwkhNsqJxg xb2ugSDnCETfVrmusy6Z96kuOT0DJzk9U/OZ28uFKbP82PVtATnVFwE5BD4A5Hpu5WO6ulWrxe0FtzGA uK68DKEdQnsFcAPAqWcOXjltu7RNawS5RpBTuRnIxklOPPVFdMvGyJknZ46Nc7qoGhdtuyH2m2a/oU43 vSHj48yHrA9d5CoI9kIi4gIEORUuewG0F1KVE8Q5Fn6WU2WBTHiD7BXPrIx2kKsP3kxpw+AEc9qgODU6 KrNxcgI4bdycZAIcVDfAoWF1yQHcVPYGHDIjU+uDOLvhgGoZGJfxcQI4NVwmuFkGzYI1D382im5wYxAT o2iDtzrkNrIGyDkZZ9OIQ56GgXcCASc5wYQJGVANMLGBmsgJcL5iOY2DM9fZt32tMu+Ng+z310nm82io 7OUBspcZE+BU3QxVA5xVVk2Z5dkuez2w1xfIrE9Sp7SeOdRFlb3OemDd5l2iDgxn7vpttAEKcoA8gThE rLre0b0KuINXrrq9YZhztT+mZw4A59ReYb12s0Jm+2e2iTeCORPi7EJ7bLbVppzadXf7b9gEsQvzk2vZ DhVsjGZFuFEUq6MdczkqxNYZtk+BzoQ6ux1VmbZW7bACnQl1dpCDnEDuRjCnUqawc4fJInZmgTDWX2Wy jhvglIds4+ScWMrUnS9uZE4KoqYT1ztuVzWC3FcEcmahNQvzvzLIqcxGqxHkLFUbtq8G5JyMtcrzS4Bc faoBIk6wYkLMl5QThH2RdfZtX6vMe+Mgp3tsl9OzupGcyoQJcZAJcCoT5LxQxrCfAXDVsiDPLNcqez2w 1xfIrE9Sp7SeOdRFlb3OAuQ6b+E6vanQktZvow1wAjkEOWDZmwGwO47rAHLt11ptUOc11QEQsp7bKrMN 025WSGGuEeQaQc7UzYLcXZM307iVMXTbs+sct6tuadeqnqQJcu4LMC8OF2u7EXWBm116o5u8HuyW08OB 9AHqQ3UCuVpdq0ahUZmFyqnQNQTgVCbIOVUMu1CR1MV9I5CzV1ZV64W1K7i9EagL3lRmA2NvdOwQp42X Cg2dvttVF8CZjalKuzzQKDcE4DS/lBPE2Q1BfTIhTmQzQuZnqNpw1e+tcBvAIN4PwrJNTgbWlBpi00h7 3gS0OcGCk2oAx1fkfXMCrm+DnK6loarRtaz31+H+1yen5+okLRdmWXGCOHSpioL4j4JLus2pjLrLr0MZ N6X14ma7W53qpF1al+31XIU2ACCH1CMAOQgpSOCF0+UeW0ukq7XzWm6LXN2qVnvkSk3CwjqP9RbQqQdO gc5sx0zvnL1NNNtLyN6m2qXtrr2Ntrfh9jbelAJdTajDn35LTkCnctsdwy456YuAHORkU02ba9piO8ip 3EBnQJ3ae6g+kDOlfKGy84dyisrOMSKTdewcxGxkhzkVWOq2iRstvbCB99tE3jMjaXFyGfWZE0bffWGj HMPOX/I9p5U3Kz2RRpBrBLlGkPt6QE4B7qsCOTtU6GdZ1whyNeR0LQ2VE8ipzOdRn5yeq5O0XJhlBbKX pf+LIId3pCJBFCtAreP6QqvNcQC5LuvyBOR0fBzaLnt7VpdnDjLbS8jeptql7a69jba34fY23lQjyH07 QA7vALnbX9xAo9dmkMebW+m+LTtp/MYcuvulDbzN2YvXCHKNICeyNxLaeKjMBsXeyJiNUiPIffUgpwbX NMKmYfb8loGcT9QRkRMkfRvkdE0NlRPI6WfzedQnp+fqJC0XZllRaTkS/YuDHN7RPpgg15XBDSDns62E um5Ae+IMcvgMj512sUJou9CWaRtngpx65cz20GwvIXubape2u/Y22t6G29t4U40g980HOXjhAHHt+Z4M WBRLd/HnOycF0JOBeXTby0H0aGAx89ZX5JGrdUJ6wrYLkc91jIuz3xzIvHmANfsN1j5tx4dhAJwJcm4Z D10LgbtAaEGxAZzKXuDMAmkWVBPcTHgz5VQZTLnHKNgqFSqdygQ2JwHinEAOMhsBeyOhjYfKqYExGyMA nMpstExoc5Id4FRYbwc4J3gzZQc5syE3wU1Vl0GoAW2mHIwOBOOk75ahcjZkkMKbAJxNJqypahhYlml0 TUPs6TLSkJMRVzmBgJNqQJoNMJyApKFyAqEvKgXAWyWn37gVcroP9cnxPruegdOzcpLTs9fy0T3kgFta fuoqYyqnsukuu0EWyJnj5pzKvgp/cFT2OmTKDnQqs+7is9ZbJ5ltgB3kzICHLhuKyHszZnookpQk9rFy kL1NkgAIVxcstqm0XYPUK2d2s5oy21CnNhbSNtjeRmu7bbbjkFNb7wxy1VJ7YtoaldohdShATvYKqmXj 6oA5025Cdrtqt7tqj02oEzUQ5JQFVE7cANk5w+QQlZ1V7Dyj7OMkNw8ZMHfbS8xSL2+muyauI9/5ceQx LYi+88Iaun3iJtE9GzIY5LZR+zf9ZR/ZH+z1wkY3hzWCXCPIieyNhAlxkFMDYzZCZuPUCHLOBgz6vwhy TnBzK+QEY19GTr9xK+R0T+rTVwVyqkaQqw1y2N5Vc8ptda1ztT8qs01CAASCHwBz1vRe1ZGsZvsGeLN7 58y20mxDndpYSNtgexut7bbZjkNObX0jyH1zQe72F9dR74Xx5D03mm57djV9l6ENXagANoDc/Zuz6Tuv +FPTF7fQg1vyqBl6NPn73+HjKIfdUpCTkzPBzS4XyNm7Vs2bojfKvHE3A3Lmw7I/SEgesFPuOFsBsRck lVnYFN60MGohhczC+0VBDtAmlcaoVApyUsHqAjmHiqyyV3yzYbgRuNllNkKQNk5mQ+YkbfDs8KayGkv8 03XJAdpUdniDtOF2athVagjsshsNMRRqUGyGBmoIvEFuA2eAm8rJSNoNKdQ12JKnAW0qJ4OtcjL0TjKh rQZENEBOAHOzcoIrL15vV3de/3XJ6Tft5+h0LTeS0z1skMxn5JLTs3SSU9lQKdCZMsueUxlVOZVphbua dYDXG58hrT9OdUul9c+EOq2rmPrLrL+o2/a6b7YHADkdJ4fJ9bEMaNNxc5ZXDvtVe+VqeuesNslsr7SL Fct2kFMB4iD10Jkgh7bUXK5PZhtttt32Nt2p7XfLwWbYIc78DBskdseQk72Catk4dWQY9tC0k6YNNW2r KbW9dhstqgfkTJlcANm5QWXnDBm6ZbAIZPKKyuQZt8PKxj/KRfC+3TmJOYmBrcmkTTR4WSq1nuLvyFcA ufs2ZdNtL2+l217cSK1e20zj1qXz+i10x4vV4+UaQa4R5NwyGwmnRsQuE+KgRpCrW40gd2PZAQkyAeqb Ivs5Ol3LjeR0Dxsk8xm55PQsneRUNlQ3AjmVU1l1KtNfNchBMn8r6qdRf1G3Gwpy6qGD1EvntXmXRK8i 6KHzem5PGOJuBHIa9IDt+OwEc4A3SL1yKgW4RpD7vwFy0B2vbqO7Jm+nDm8H0fDlCdKNeserzmPfLI9c joAc+OrOlzdR3/kx1OGd7dT0OYZC136NINcIcm6ZjYRTI2KXCXHaGDWCnLMaQe7GsgMS5ARS/2zZz9Hp Wm4kp3vYIJnPyCWnZ+kkp7Kh+raBnE7Eb6+/qNsNBTkIy5JPzgVyXTYUiFcOQo65hoAcvGwyuwPvp+vs bR7aRQU5O8xp24l3p3bWlNlGm223vU13avvdcrAZjSDn4gcbZ3wVIIcu0xErEqnbtO30nZe2iaftzsl1 e+Qe2JJL33mF95NgCOasSZvpBf9Cum1y9X5fCuRMiGsQyJkXa8h+U+w3DtIbWxfAqfRB2eHNVA2A04Lg GhenqgveTNnhzZS74NoKtsqpEkCoMHaZFcyUHeTcYyBsFReV2/5ZK7wps5FwakRMmeCmqm9cnMKbXWaD qKpuNF1yADioLoAzG267dL3Z+JvQpqphPGyGRY1PTYCrPU2RjoUTA+Ygu0G0G00YUydwczLEppyMuJMU BHozjAyIO0L944+Qb6TD+CybnMCkoVL4cQIkJ3lHHxU1dN3NqqHHMPezy6nb98uAntM9d5J7LN1NQp1T mTGl5aw+qKtRfjVBNS+7y3eQC+RMOdQRO9Cp7HUOUpBTiHPyyKns9V5leuAAcjpODuvQhsALh2AHmUh/ C4IguK3hNghjdNvLMiDOWqfSdgswZ49kdZICnAl1CnIqextstst4t7fdkLbrpsx2X1XXWDlNEuwktUWA OnEu1CNHe1cH0KkTROVkZ01bLPbYZavl3cmW24DOZIEbgZzKhDmVnUlMZrEzjTirDPaBFw7dqT4zwqjv smQZF4c8ceheFW4yOAqRq8pYt720QcbI3fai4X3D+LlnltNz24qoKViLv//1gNzLvA3rJ21z1O2vwkNX rTsmA+6qhZvWf1EcRe05Rdd/8DmtSt9LbabyDReo4xtq6M43AHl849/kh+FSk7cAdtVqOo0fsE1N8NCn 8sN3qdk0LhQuNeHC4aSm0xn63gXQ1VbzGYA81iwGOwe1mA3Iq63mc2JrqcVcAF5t3T0P3jmEjlu6e4Gl lguTa6jVIlTcmp+h1osBddVqswRwZ6nt0vQaDYldjSD37QY5NfwAgQFxx+je9DN0T8YJ6htbRT0YXHpE HhH57GD4cskJOm5WTiBXHyyZMPVNkf3czPNV/auBnErLZo3y+zWCnAlxtxLkIHwGrGF8XO/AMhoUvIf8 AkqpO38PgCcBV3WAHNoy9cx5ri90r3NqC9FWmiBnjptrBLl/TZBrOcWfhixPo/ZTQyx2QkDDiy5WugHI PbAlRzx3uu6OV7ZSUz5+y7cDqOUkPtYL/B3d2FDhR8wfVeFk6gQ5l+xdqpB5M8ybpDcO72NWJtLuU9fo f/73f+m//+d/6A9//gsdu/wBb2PIM2++6yFB+uD0YcoDdepSVTl44twFx1aw7IUPsnvi3AXXqVA7FH7I dF1Ddm+c6e62V0KpiFpBHSqvWbmdGgFtKLSxcJI2MioT3uqDOMiEN8gEN3yubhitrouGgBuEeRVV9QGc U2OvulmAq4a3ugDOoRvVZcxMaDOXTZmGEwZV5WR0nWQ33DUMvSsHnAogAE/cuNQzND7lDPWLqSK/6CPU M+oo+UYfE5jTZbxDCnmmFEKcAMZc5wQ9JiR9G1TfeZvXZZd5H/TeNFR2eKtL5rOW520rC3Y5lR+VWfbs IKfSMmyXG96MOuD+U2OrP1adqq4/9cEc6qhCnL3uSv211W2zDUDb4LHZ6k4FyGEqL8CbeuSwDMEbNyKs gh6Jr6L7oytpUMg+Br7qNskCumqIM9sxvKOLFRPsA9Dw2ak9RFupQIf9IEAd2lWnttcus60223GznVc5 2QORgw0x7Y1dCnMQYK5ZHbbM0ebVAXJ2qT017a2TTVZ77ZZhy+sDOXw2OQEyGUKlPX8myCmTmDLZRZnm u8w6iCgV7uHPrd8Kpv5LUuguOKqUhVyc5ARykPLW7RO30kMb8uiuF2qzGPRIQA7d8eLWrwfkdB36eQFz pvTiITvU6c1bkX2I/vGPf5D5+utf/0YTVsVQ0zfhgbNuvPkg9CGZD/Gut/ndBXO1xHSvpG9Xk3dqyixk qrqArvms2nIq6JC9QqCymJXHrEz492TX3QssKdCZMiuwU2U3G4O6gK4R5L65IOdkpFU1DLsL4BQM4Gnr HVVFfWOOsY5Qn+jDDHJVNYBNAQ4wd2MdcUs8ezY5wc8/Uz583XY5bTfXNUS3GuTcMqHNAe7MZy3P26E8 mHIqSyqz7P0rgBzUdYsr5chmbisMkIMAd123FNOA7eX0RGIVvZ53kl7LPkmPJxymXv6WV07HzKmq261q zxyWtZsVy1hnbw8V5FRO3az29tdUI8jZ7PQ3COTumhJIt728mdq+FULD12ZT69eYj17dJt2rXwTkHt6Y T03qmNHhzudW0T2IanXaWJ/sP2jCm5yUAXAiBDe8zAAH1dOtau9O1S5V3LzA3afof/7nf+h///f/uTCO 6P/9v/9H9y/aTk3f4H3kYQDkLKH71LFbdSpAjh9mA7tU6+padepSdXel1tOl6tSVqmrm0t1zUDksOXWn tpwPzxxU3aXq1kJAXG1pV6ops0sV3aj2blV716od4FQ3gjgFN8iEtxpy5Ykz1WCQM2ZtsDfapuwNPORu /OuBNxgWXXYGOWsQt8JbLYBzyex+UtmN4s12ozoZZlNqzO2GXpe1y7RHJMCNjVXUIYE4CCDms+NQjS5V hRCFMhPgesUcJ7/YE/K9XjFHeRnrjrp03C3dX+EQUtBxAiKVCUQqE76+TjmdX0Nknrs5pk6X7ZBnejzl OeD5ueDtpnQLoc78k2EHO7Nsq9xAZ8isK9VgV/PPkNY1ATquowpvXbdx/WNp3YXqq+OmOm22QK3blhJ5 hxdOu1ZlHX/utqWU+geVCby9lXeKXs89TU8mHZZuVkSydsMMERsKa7ZNLohToNPPAD3AHKAOn7VNBKzZ pe2pAh2W269kYFtutcMmuOmyHeTw2Q50jgDHqvVH3w1zSW5wM3uAWjC86bJ2r8o6A+CcVAvqDJCzw5zp EDFBTvVFQc6EOTvIOUEcZAc4lQlxkIIcOAgBC+KQesWfBi5OoJ4L4gTebpvEgGfjohrMVA/IfXfianp4 Uw7d/uKaGhymwvF9Zkd+XSDnb8nmjTM9cnpDTOnNe2pLBr3/6Y9dCGe9PvnBZ9RlGu8HarY9EDwwfVD6 AEVTq7tXVU3eBsBZ3rib8chpgVOZBVJ0E544CP9u7P9wUFHsQuWyxJBml61yqpwqsvmPzWwAtEHQRkLV CHL/+iCn7wJ1DGDiVQNEuOBCQcNJCnc9Y46IfGMZ4OIY5lgAvPrkG3ucv+MMSiZAfVNknt/N6MuAnK5z BLUb6VsOcnaIg/DZhDmpxw51vIYYxDy3lgi0wSPnHifHy+qVA8z1DSij+6IP0nNpR+mp5CM0LqpS4A5p SRDNKhPrr7dk98qZIId3dLFKNyuiWjEWzgVq6n2zgxyWdVuHVdzeMsxpG6xtsrbP+tlst3W5EeS+XpC7 7aWtdOergdSceaT/Cr7vrzP3vLLJgjZmHzsX1WCm+jxyDHAAuTteWluDw1ToIb3jpfXfbJDDjcLNazkl gN4KzqL3v/dD+s3v/0iHL71PrwRmVt904wFAeGCNIGdUUoeK3AhyjSBnBzkTyhTm4EXDZxMwVAogCiG6 nwV0x9wyPXJOIKfqFVdbCk89GPbsMuHKSQ3d72blBGkNkQlypuwgp2oEuWqQA7x5+vM2A+TscqrjptQj B2DTrlVI1jPAWTC3i3z9d9PgkL0McPtoWPge6rltt0CcL7cPPV3RrJinFfOz6swOTkCHtk27WAFzWIYU 5EyZUKfrOq/GZ6vNNdtibZ+1jTbbbV1uBLmvF+S++1ogecyKoKGr06kJkv3yZ0lBwmxzmzE2TlWDmeoB OQAcQO6uV9bX4LBqWSlJvjTIiYyTkhMzT5hhDWPjbneCNtfnWutdEpCD+Ab2nhVKCyIyaVnGAbp/ZZzc bBkX5+rLrvUgFORc8GaqoSBnBziFOAjLdoirAXQ3AXEo8Fo5AHMmuJkVCLLDW33j4iCz8prwphVepQ2D uWw2HibIQfXBm+qGEPclAU5VF8g5NebmP3i3DHBzkmlU7AbHgrja4KYSY+Z6h0zDZwpG0fMWAZx9HJwp E+B0Wce/ARiq4Q7j3I5R72gLwABkdoAzYcQJXJykcAcvnEqhrXfcSZFffP3S/U2oc4I2+zpzvy8j8zfs crrm+gToVdlBzpTeeyc5PWdHfQmg03JpBznIsTy71A1l3pD9T4/KrFPdtpdS+00MTgF7BKoU3gTkeDvq YY066lCnneo+2oSuvM0Ncq52owvWM8hhwvwe/Hu+/qXUm3+nf9Ae6oXf523oTsU7ulcx8wM8c0gejFQl 6G4Vr9t6jO+1AM5s97BO05JoUINdJshVA122wBzeAXQW1GWI2i1Dl2v18BcT4tosQQYCVe1xc6ZNgMRO GCCnMGeCHPRdtm9vpRygkIrTtKbgEtu1yFrgZlctW3eDsXJqUyET4iAT5EzZQc6U2HjYfBvQQfWBnMoO clDTN0KEV8AngLTWb/rTiPV5Epmq7KJM43ZYmUxk5yUHkFPd+fI6um9NWo2uVXjhVPiurNONDZXTj9U6 MfOk9UL4oppOCSSvWTvIe3YktXyTQQwXbQCcSbomxLV5K5hGLo2h4UtiJUGfJOmz33AXuLkBTgncgDZV jQdtgzezgNgLEmQWMi18ZoF0F1B7AXYo5CqNUIUAc2blgaq9cLUTADsBmymzAldX9GpYs0ObuWzqVoKc +x/r/3GQMw0h3tVYQk7GVOVkfGuoHpBTSDNBDsAGmNNtst0FEOpRA9ApbJgAd7MgV5dMUDIhT+Gtd8Kp WuoTXy3drycDnso85q2UE8CpnK6tPn2TQc5xnavMmjLLtOrLgJzX1jJ6LPkwxZ77IcWcfL8GyNWCOMih TjvVfQU5HSOnbQZArjtvB8D5BlpdqL34uH2CyqlnANd/QJ+rHcKYOi/e3w5ykCcLk+jDS6dAB6H9A8Dp eDkncDN7OdxalSUCwAHmoA4r0BY7g1y10MtiyWzzVaZtcNsKt02pG+QmxRZR4N6LtHrvR7T50FmanXvW 0Z6ZqmUH/wVADqyCd3CNz4IEGrw6g+56mXnnVXCM5aW7VSAHgLtnVYqMlTM5TCHuuxPX092vfkmQw4Hk YPYTwwnDrYhuVb6I77yCiwyg4UvjKar8JGUcPEsPb0hzXbBT3jhAHd8sF8j5Tg+i3jN4HW6ueOD4Zjnk j6udO04jVa0AB3ugg6iOAAfIHuQAIdDBHuxgBjm0mAmY40J5E4EOEPLFIdjBDGwwc8ghZxzeGxrgANUV 3KByCnAwZQc5s5GpD+RMgHOCOCsPk/Xv1Q50dojTBtSu+gAOsjfijo19PV2qJrxVA5x2p1YbHXeXkQFv 7i4kGC6Xahk6lwGsYRBdxrIumYbVlBhnF7xB2nVqGnCFNjfEuQBAPW8AOawDNChUyD78DphD16cd5pzA xJQT6KicAKl+Acws+TKwQQpvdYGe7ufkwbsVsOfN982HIRfAifuC+4T13WOcr928Nwpv5jqVwrF6PiGF Nke5nndDpUBnyqlcmdIy6DThfo0ybCvn7iEFxrACd50xpH+IoN5BFeR/8aeUceWHdPJHv6Yu/rw9eDd5 BvD3/fdSN4a6jpsZwLie1qjDTnXc1g5A0r3KsIYxchrs0J2PBWiDMGk+vHN+gQxy2ywPnnSdutoijKsD wHXn73vz97vxOk/eJjC3vtAteOnQzrVfnS8gZ4c5bUO1HcW72cZC+scZyxbwWSCn76bM9touE+TactsP tWG7oMut2V5AgLjW4jRgG8JqITaG95sVTxEVFyjp2If0/uf/TrkXfkjbDr5HzebHUCuGvNazoCRqMzue Ws1JZJsGcEPwXk2guxHImbLDnBPEQaYjxg51NwI5U3aIg0yAazKFeWVKEN32egjd8cpmGrUylTryMbFN nVEqBTmFOeWhumBOxEwFQMM7ukzBW/j+wOXJdNuL2Gbx1u28rd2bAdR9Zhj1XRxPXWdHfH0gh/03ZFbQ 7/70nxKssKP4MN3+/BrXhZsgV+2Zww1q9uoW6jN1M/m5QM4J4qCaIGdBXFNEr75tda82glwjyNVq5E0j YEDcvxrI6Wc7yEHarWoHORPYsKzj2/CO/euCEFNOMKOyQ9GNVQ1yus70vim0merFMAf1STwt0s+Q+V2V HvdmzxMwpwLU+cTVPIbK6R45SUHOlBvaHITnaZc+cyfZIU7Kj0O5MuVUHj0dulvt5fyLgFy3gD00a/dF yjn3CV37+e9oxZ5r9GD6Beq9HWNWuX4GWF451Eu83yzIAeIgeNrQXQoPnRd/3w5yvfh37CCn7VHn9fkC cIA5CCCnY+EgN9TxOzx02qWKd4Ac3tE2or1sKMhZwgT7aJMtj5zpfXOCNicpvCnMQQpxLRcny+eOS1Oo 67I08uM2e+jWnTQysJimJpZT7MEL9OG//5LSj12ndbtP0NANhTR4SxF5LEuk1vNiqTmS1M9mezUbXryk fymQwxCuJswa7adtp8Hrc6jZpM283uIVE+KgLwJySPSrbIWJ9cFWt03aQoMWRVPLVwPJY1ow+c6Lop6z Iqnz1GBqOXkrfef5DdZ+TrBWn/SHoJsCOX6fE7OLfvLL/xCQiyiqojueXem6cJcnjpdxU5rwTYNw8+5f uoNGLIyQm3inDd5M2UGuHV8ovHhtpmySh9kIco0gV6uRdxmAf3WQU+Pu7jbFZxccAMpuBHJ4x3ZAXN+Y E9SHhe84QYgTwDjJCYjqlwFy8ZZMgNJtJpgp0KmHzgQ5hTvTg6cyYdAOeabg5cMxhiafpOGpp2lYyinq l3hG1jtds9P9cpId4vQZ1CV9rqZMcLPLDnFSfhzKlSktg55h1eoaWimqUYZt5fyLgNyEbL5X/nsY3Iro 6bgyejb/LC0qvUgPpZ6gkSEldF/yGeoevE/qZY067FTHbe0A1I3hDALIAeBUGB9nghwgzgnkLGEe1kLy WLeLvDZa3jkdKwdQq4Y6zPRQM9hBvXJo+9A+NgTkILTDgDh0tapHru2SrGq5ulad4M0cYqPet3bc7rfn dr7Dsgzy4GN6rs6hPgwofdflkC+fDyDOZ3kmteV9u6/ZSS0W59LC/BOUcPhjGr0xl7xWpNE9gXyPl6XS nYuSqN3COOq/KZeGBxZRDz5W50Vp/1Ig14pBaujaDGqHXj7kigOTuBxOtwLklKmQOLgTM4b3nAjyeDeC Ri2Po/ZvIegzkL77gjXrgzAYL9/x0kaJkG0wyJkA55bTybBMkLMuBPni+P2FdfS6fwrdv3A79X1zDY2Y E0St37C8bwC5znyjHlibTFN4n8n+qXTPqkQaviCCuk4FqPGNtXWrat44U3hAw1ck0M4j5wUYf/Yff6DH N6XwA7ceqgAdHqorb1xDQE7h7UYQZwc5AbR6IM7MGWdCmylrGi6MV1A1HOQgO8gB0EyAqwvk2nHlNhsR E95UdoAz5QRx1TBndTlAaAxrNpCWnOBNwc2uG0Ec5NTI2+HNBDgT1uwgZxodO7yJUTIADhKDZixDMHqe X3A8XA0D7II3LLsNtc0Tp8ZdPDUuL44AHkOAeuTEw+YCOVnP4GH3uul4OeSIg8T75AIUO7RATvDjLBeg OcgHUPQF1TMOIHbSfaz6IA8ClPVNOuOGPMiEP5V+tw/D5Ii0M/T4zkv0dMFleqLwMk3IuUhDkvl7/Bv2 63S6R+b9VSlIO0mfD+S0Tp+vKS0PTjLLj7tMOZQ5szya5RPSclwv0KH8G0BX448Pq3PgXvIJKqPHMs/Q 0Mj9XOf28OcKGhZVRXPLLtCQkP30dMphmll0XurjwJAyujf5MI2LOSD7tt+21/LUcb0267u9HYAAcV7+ pTUgDh46n62lAnOQghzGy3kx2Ekgg0M7Bal3DkCH1CSYn1WjWJF2BB45RLhCGEMHuIMAdNgu7aQDwJnL dlV3rVqAZwe4anBD25/C61KpI0NZR27bO63Ioq6AN17uzu1xzw2F1GNtLn9OFSjrytvbsc1os4DhjNWd 23N0t97vv5P6r0ilYetTqc/ydPJenU0t50TTsMASGsL3oO1cK6tCqznx1ImXe67IoBHbdtKAdZnUZWUq NZkTKd46jAlvigDAG0AcZAYY1gV1CnAY747gxWaw6bDtbO8V5hTkFOYAbnaYMwEO4/ABaBbMBZLnnB3U d1kK3fXaNuEVu+oDOeiOSbyehewdd0xi8HqNNXmreNyav7KJOk0LJa950dRtbhS1fyOAWkzaKMETzZhp /BZG0XefXyfMha5Xk8vgxXsscNfXA3KmmvNNacLEeSer/ZQt5PPGBuo3J5Re2ppGn//iN/SrP/xZul9/ +8f/pN//51/pxNWP6bXgXGrxtutGg4JdN9t8CCo8nHnJe+l///d/BeSQOPizn/2SWs3gB84PVR5sPQEO prTQaKFSmQXO/GcBuf9x4N+H65+I/iuxq77puFRWgIM1ANUSg5kpHaxah7RCawXXSm+Xet5UtRuORpD7 MiBn19cBck6eONPAw/CrRw5AoOsgJ5BTyEB+OYAc4KcuQIHsIFO3asKbKSdAa6jsINcjFufrEoMYpPtY qt1F6wRyCK6A521Y2ml6JP8SvVpylV7ffZ2msF4qukZjM8/JvbF78pzukSnzHtclfT6Q+Rzt60yZ4GbX PxvktI70DK6gJ7Mu0KCIcgEywFl3BrnBDHKPpp2iaeUfUq+IAzQq/jjN3vuBBE505H3QDXtvfBXdl3BY vGkY99ZpS/0gB3Dz5jqNLlWVE8ghOrUhIAcJoDHAiXeOwQifAWlWD4TVEwG4w3HgoZMxdfwZANiZIQrd rgpuCm/msqq6jU7nzxnuQAlsQ1ep6WUDsHXmdhrLHRjkOvG2brzOb+Mu6rmRf5vb6bYLk2Sb19o86rqK 2/RFydR6XrKAHKDPk7/fYj7bohnhNDX7JB+Df3dZGk2M2UtN56Tyd9Oo+dxY8lqcSGOCSwXsAH0YN9dq Xjw1m8M2am4SefPvDOX7g25YnxV8frxfS7alluOjpg21bCtsrTpM6g98UIhz23M4Ym4ByEHN3wyigasy qMfcGGr6Rih9d3JtiGsIyIGFAHHgo7te2UwdGdB6MgP0nBVFHaeGULOXN1JTBrrWbwRSq6nbqdnkbQJt t728lbrPDrfmU7VBHNR/XhS1YY66qa7VukBO3YXqMqwP5CC9WNyAbtOCaG1qKf30178T6LK/MKPD9/7t FzQztpjumMI3DTfaBXPmQ2gxNYzavulPfWYEUFLFSde3rdenP/xRg0HOXmCgG4GcCW92OQGcCvCmcgI4 fXcCufqiVav/jdWEOFVd8GbKhDxtUBoCcXXBm0q7UqUB5GWRqzE0ZQKcPTq1LnizQ1wNaFMZ0FZ/lypD mQvcFN7wDgNiQptpjOqTGrQaxs5mEE3ZDanKNLgiB+OsUohzMu4w+gADc8yb2ZWnIAeZIAcBOuBx6htr pQsBsAiIMNyZ4FKtajBTOYGXezsD1DdFvgxtlqrhDpAGkBuTfo6e3XWZ3tjzAb2z5yN6s/wDmlL2Ht2f e1E8e7h2q9u3bpkgp7Lfb5X5fEzdCORUTmVEJX8AXBCnZcte9iCnsqrydAEdZAe6GnUhaC95MNB1Dizn z/upR+AeejjtGPXZYf0h0kjW3gx1A6L3UY+oSnoo5QiNCdlDvuGV4o1bXnyGRsXw8QMqqOOWMvJkiBsS cZgeTD5JQwN2WbnmNpWR9yau5/6l1JGBTNsEQJwP/zHTLlbx0HFbYI2VK5auVXjjkGoEkazd+F1nc3D/ qbS1V7LNBWoIoJCuVv7cZS1/j/+wmm0gEgOLl24DPHkF1H0jf4dBSqJSV/I+quXclrLaLuP2djm3r6w2 DGKtl1f/0e7Cn61u0Szy4WN7rMiV7W25DW+zJIW6MMT1WJtNfXE+a/hYy9OpFWzC/BSBOvkOA5vYlPnJ 0o0KAOvJENqZ17dcmEhNFxfQU1Hl0h2LLle8byg+S83nJ1Enl+cONgxptsYGFlOHxQkCeW3fjZDgB8nE 4FKzOTHUnm1aL76+EVsLqc9KBs+5vJ6B7q65KdR2RozY6rvfiaLWM2Kp1btsX99l6OP1LaYz+KnQGyY9 ZJbdbjEtUsCw3axI6sBw1Bq23gVz1hh5a9kJ6FRgCqQWufP1ELqdIa4jA9UItk8t3rLGx5ndrCoT5MA2 WG72Kn+etJ2+8+p2WYfEwC3e3EYecyKo74J48prJ3DElmBlqq8wC0ZaP3R6/j55LjHdzBTyIJvlTt5mh dMeLRpLgSYA61osbaez6DP69m+hahWpAHNRAkMPJmFKYw5i4hzdl0tXvV8/aAJgzhRe8a+c//hE9sTXL TcxQO745D6+JoxFzA6nrm5up3ZTN1H16ED3vn0m7jl2gzz//nM5eukovBqTzw3dBHB7sF8wd5wR2plfO njsOcoI7leaOg0yogwBx+g6Yq1ayqKHzqtYHdias2QWY08aiEeS+GMipETP1dYCcGu4vA3L4XJdXDsAG 4ADMQYA5p67EahmQ5tK3BeT0nEzPHa4JkbKDU07Tw3kX6c2K92n63g/prb3v0+Td79F9OZeoX/JZl0cO cronluwQB9W63y6Zz8fUtxHkIMDakOjDNC6Jyxl/B92rnVGfXCDnF15GA2P20yAux/dmnqZXcs5Rn+17 qGfYfuobfJxGRpTRuyXXyTewhDwYCjsF7LGiWbmeD4zYRxOSTlF/eNI3cXuxlWEP3jUGM4AcolRNkKv2 zhWRjJUD3G3eZb0z2AHOzDbJqc3S9gxAhyCH7twewePWZV11+4f2sbqtzBZvnBXxannqAHSaCNgp/UiX VQxerihYtM3tWGivu6zIJA9e7sVta1++jn7ctgHQ2i9GZCoDGdsBeOw8GPIAdFjfcmES24dktgku5wDb lXZLU8lzJQMjw5k6EfosS6DRgUXyuQ9fG2xS+JEPZUwc4AyevtawW7PiqRmDG7po7+X9O8xiwIOt4/UK ck0Y2CRXKgvdq4C0VgxeXZcmU/+NOTRwXTZ1XcBg904I3e2yny35O61c+7o1I0oEoGvFNrgDb++xOIlG bMgWeS1KoLthrxXgGgxy26n11FAauCqdPOfG0J0uiLv9NWeQgwBv8NTdzlDWbEoQtWCu6T4rmnouiCXv udESYfqdlxnOmIvuenEbteTvtJ0aTK3eDKRmkxncXmZIA0sxU7njDlyMBY+cx/Tt7rFxEODvuxPX0n1b 8um7fDx0r35NIFd7flWAXKu3QmhecgX97W9/E2BzeinM/edf/0ZpVRfJb1Yw9Zi6mfrM2k7eb2+mwfNC qee7geKNa/Z6ADV/K5haTwulwcvi6K0dBfTw+iRq9laQ60GCzKvHyAmxM8g5eeScAhzqGiNXV4ADQE4L sMqCOBRQBj3X2Din8XEa3IBK4+SRu5uXofrGxdnHx1kCyFmyj4szZY6RawS5Lw9yJsC5jZyDMVQ5GVHI DXAqJ6PsMtxfFch1j3N53+ItkINnDt2NdcOcAk21vi0gpx65nnGn3cK5Yh1gbXzmWXq++CpNKrpOE4uu 0tM7L9KorPONIKdl3AHkvLZznfEvpyF8D8fEVUn3KepS56AS3s6ygdyAkP003L+CuoWX0mu7zlNHroeD Qguob8Qx6hu6h97ZfZUGRRyQOu+xqZS6bi6nLlv3SBetT9AueiTpJD3AwAjPHwAOEg+cDeQQ1ACQQxct PHEAOXStdt/Gx20AyJnrNRAC3azSfbqev8cQhDawHYOUiNtLTNkFKNOgCEjH0PnwdyHAHWAO3anqkYPH DQL0+W4uov58jt4b0M2KP+Hcti9Pp7u5jW+12Opi9VqbI2Pf2s5HUEIa3c1/+NssShN40/eOy7MJ4+HE 5rCdgBMA69/KOsrvbDsWJksABOyQf8VFhi/L0dCGhTF3ALZW82IF6pqx7RoVyL/HIIOuV7f9czk8LDto zWYE26mAdifb1Hb8nQErkmnYpnzqsZQhkfcRaDM8cvgMwGvLdrQjH7fbgkTJ5/ZwQAE94J9HvZayrWTA u1mQ67YwlgavYhv6JiJU0fsXQk2nhNAdU4LrhDjs14qPjZxyvRbFU4fpvP+rW2QeVOSVg2eu+aQg6jR1 B7WbFkJNpliTJKhTCxGqGqVqQhyEtCOdpwVKdKpy2G3PbaRO74ZS77cYAp9bQbc9ve7WgJwd5kR8gion kMMNaM9QtS7vsHSf3uj1j//+byo9c52Gzg0WgOvNQNfh7UC6yxXgoHI/JMOdCk9cjYhVDIg0ulXvnhZB bd/lmzwjUjx3Frwp1MErZ8Fccy5kWFfDC8cFSmFOAhsgVyGFWvLntkz27bgwt5ptbUOBlnFxNwA5hbiW 8xJl0GkH/geFithyHv5JWd62mwE5eOG029TyyDkLEKcgpxAH2aHNLkCcyg5w1ZGqlm5mbJwJcnaAM2VC nB3kNLKtfnjDWDiFt+oxchAMi47rMWUaKFN2iPM0jJzKbgjtRrOWMXWNZ8KyfTycqfrGxUEKcVbwghXs 4AQOkBNomAKMoLsRIIcuR4U5a5sFMnZgg5ygqT71xJizf6JqnAufv9XFeoKGpp6ie7MvisYxwI1MP0OD kk/RgORz0v2K/eDFwzXbx8zVJfs9VgHanJ6RE9TZn7kppzJTQy6QM1WjHLpkL7+mtIybMIcp6LoFM5Cx xiadouHRB6h/JO9rr1tBe8Rj1yuslIbEVIp3rXvAHhodf1TmPfWSGR54e/BeGhheyfuV0+Sci/RE5mmr 7m8rl3ouY+V4GdGpPtuK6Z7oIzSB728fPo9Om3ZbdZ4BCCAnk+i78ssh7YjMKLGpyB3BCpCTSFVuj5za LZHRvqlnDl2rADnLO2elIkF7iDZS5l11dbNqXjoBP3j0+PtdGPaw3RpDh3FwGeTBf6J78n5+W/nc+DsI YMCYOHjVxEPHIIcxbBA8b93xp5nX4Q+8vXfG+sz2gW1GNz4njIlz9+zMT6TmDHhtFybQUP9C8eh1YBvU ZUkK26s4mhhfKQEMGrzQbkGq2Ch45JB6pCVyyTHYDd+cSwNWJcnQI3jjTNsow5FcdtQU7Cvs7N0z2CbP iiTfJXE0aEMm9V6dTl0Y8tBl25ntqQf/XleGJ08+/6683HNJskSVDl/P4Mq2ssU7bOPVYWMDOWUFgbi3 Iqj5m8HUd3kiec2PEyeTgt1dDHAYGwePXBN45V4LoKav+VPrt4Jl3158P7qy/W75dpBwD+BNulr5velr gdSGeaMdnEeY9cEFd3ZWcjOUC+RqeuS2UcvJm+lO5JF7fr1sw3i6+zZl020vrHOz2T8V5DpMC6WNBUdd qFb/629//wdlVF2kFnxD5AYbJC0pR2SdlQgY+ePazwinvotjqPs8LhQMdQpyzQByri7VzjMj6eEt2bQ0 6xCt4/PYUHicluceptdjSqknk3lTDJp8F5EzvD8KBbpSGeg85sXQkJVJ1Jn/fbTgQuf2yrkgDv84ui6M owf9c2gJH28tHxdakX+UXoosoZ7LrPw66DpVmKsBcgA9rkgduBKN35pDs9IP0tqiU7S++DStLjxBU5P3 07CNXLEF1LgySRdrHSDHlRIQ15YrrveKNHoyvJj/VTGoadeqA9A1gty3G+QU4m4FyDUEMLANwNI3oTrS 0/rOvybI4Vpxjf2TTtOg1HMMbWdEfRlOAG8YH+fnioAdmHhW7ovOOmHez7rkdI+hrwvk3GXrFoOcd8h+ 6hVaQaOTjtPIuGPku90KDMIMEDXqVZAFcvDIDY3lehF8gHry5wERB8gvrJLeLr7IdZXrsf8e8g4sp8FR h6gTg9oIhrxXc87RqGius1znZTaIgFKBwO7+FfIOcMNcqcPCK+i+uCoasL1cPHT1gRy6WqV7ltsgtEdO 7ZaoRvvmAjaGNHStdmfo8uXf7sW/gVkh4HHTthI9HHiHZ85MGNyVAa43f29ocDkNCNpNvTZz+7gyUwIY 2nN7jNxxLZfyH3R44HgZnjdv/n53/j6AD4EPADtswx93O8gB4jDGDkEPbRYkSv44dLl25P27LU+m7vwb 7+bwn7S12TSAQfbBkCIa7b+LnojdT2nvf0r++9+jhxiih/O6EYG76f6wPTRy2y7qvSaLfFemU4/lqdRl sRXYMGILA+s8Bjy2edozVR/IiZeO7Wgr3hceuc7zksiDbaLngjjyW55CY/l3xmzJlyhawB28b+hKbT83 QbpVOwIWGwByCIzoszSJ/JYlW5Gqb4dKVyoYA2r2ZqjAmMescPJdmkKebJ9b8nfvnOwv+8NTJ+DH70hJ guCItu+EUwtmkCbS3coMJD2TYB8bI7l0I5Br9vJ6ATl8RjfqA1sz6M7nN9JtL1WzWb0gV2PQnSH3j9UD cuo2FJDTuVYNAeTaTg2hlVkH6R//+IcL1+p+/e0f/03Jh6/QHUzEcpORfgQDEAFwhvBwWjEgPh2QRXlV 52jLzipq9Q4eGsQPkgGuBT+8UWvTaWXmfjr34Q9q/f5vf/d7iiw7Ro8wiLVn8se/A42e8VoQS3MSS6ng yHlalFZBLeEmBsQB6KTgxdJopuU1eQfpzAef0t///nfXUa2xfp/9+88puPQ4jdmUJfsC5qRgu3Q3PnOB 9+aCNSt1H+059x7913/9l7uLGe9//NOfKOfoJXo9fg914Yos/6AY5gBtqtaotC6hEqNyrs2vorMffI+2 FbMB58ppeecY3gBzhtphjBxLu1br607VxsiUHeBE6xjI3HLuToXsECcNZx3dqaq64K2GbPCmMiGuJsgZ YsNSl5zADYIBM6WGDXIyfE6GUuSCNyeDawrAplKIU8Otxl2lEIf0IXWBnAkQChd24FBQg3Q6LU3boVGb SI5bY3yZC4ZM2WHJBKhvpPi6AG1DU87RwJTzAmz9k84K3EH4jOuHsDyIYQ6AZ92Tk+Qdw9cJwJVAiOp7 aL+/5jMwZX9WpuxAB5kQZ5dTWXLrBiAHOZVlSMs6ZoDw2L5PlnuHVopXbVhsFfUMszxzWn/cEa0sHUPX M7yUBsVy3QqoIN8dXKcC99JIhrbhCSfo8ZRj1In3wR8zv5AK6h/OMMjANTz6EE3MOk2Ppp0QMOsWWCYe N4yN07ZAo1YRlTooZC89mHSExkUfJo+NO6XLV8fIYTJ97IuuVgW5DrxPe6QXQbvkarPwud16DBNBF+ou 6rKhSMbIYWJ9BElAHrwdQnoSL14P7xy8dmgvtZu1LUOaDwNg/0C+bj5vPwbOzhhHx20vIK0L79OV21Sd f1XG0PEf7i68Dzxv2E8iV13JguHBw3ewHmPoZBwdxtvx76ALdSAff9DWQuq7IVeWod6bCsh7dSZ5rUii 8QHF9GDobklN0nVlBo3g6+uyPImmZ/P9DyuhxTu5DeFjTQgro+FbdlLbmTtkvBzSabWbE09efC5eDD89 lqfL2Lfn4w7S03GHaFTALhrlX0L912dTr1UZ5MPX4MkQiS7Slu/uoNYzo6j9rDj+nCAAh23d2U514+N1 ZtvYjo/fhiEQArD5LU+j/msyyY+P1XlOFHWbF0ud+FgKcHdhSBTGwr8dwZ9DBdbw+e63g2kYn1cHeACZ G777pjVLAyCsy6xoy9s2O4LaTefvvRFijZWbEkTNXg+huxjStHu15Vvh1I6P15qhrzlDHcAOMp1ZbinY maxkcBSk3axgrdte2SCpSJq8xMw0cRsNX5lEbV7fao25e4nfldVMcLPrloGcywtnCiDXnG/MW5HF9Ic/ /tENKU7C61e//yOtzatyQRyI2VJ1EmBLeCDdmJ7DSo7I95DKpPtseOEsTxy6U8etTaXiU9fcAIeu3V/9 7g/0i//4Pf3pz9bME3h98OOf0vNhhdSCCxf+JQDmJmzOpKufWsEZf/7zn6kt4IsL1N34N8GF6oFtuVR2 /kP3sf/7v/+bfs3HxvH/8pf/knUAuoOXPqR7t2RZXjmR5Y1ryQXVc1kqBRcf4XP5s+yP8/vtH/9Ev/zt H+gPfH6aWgXHnZNcTggft3vizO5UaNTWfPc5/eW//kqvxJRSB4Y7N8wZMj1yjSD37QE50wsHqbE2jTr0 VYAcPgNwFGAU5rRrsSEg920Rrm1wylmGOAa05LP1ghyk2/smWBGvGF9X895V30NT5jMwZX9Wpr5pINcl mOtG6H4JUBiZcJwGRFVSn6gqATYBvHpArkfYbhocx4DGdbA3gxrq69jE4/xeTq/mctkJrJA6C88culn7 RR6kLgG7xdP3KAPDC+l8v7mOAsbgiUM74LHVCnaA0PWK73dGSoxtxXRf9EG6N/Ywg1QJ+WAWCYY3jJ0D 2GH8HOZkdbdL6DYFoG205ljFXK0YUwdQQxoSQJq0f9zWiXgZbSPWC+TxPhq1ijFuA7eXU2+GR0+GKgCa HJ8BD5639gxLUKc1Fsh1X5tDPvzdwUHl1G/rLuq1uVCS+QLSOkv3K4PRamtcXJ+NhdQPY+h4v35bGNo2 7yQk6+3H547vtF6IHp00/vOfyH/iU6gb2wOJWF2ZSzPyT0t3KxwLXvz7IxjAno2ppAFb02lcwH4KO/ID 6sG/1Xx+GnksSaDx4fsYjNKp48Jkasog1mJBupVeazYvz0sRh0XvJUkCcR3mx8p6wFiH+ZHktSSeQSyN Bq3LopFbd9KEYMsDCN0bkE8jNzAMrkgn74UAPIYwhqvm0sO2g1pOj6bmU/mdl72XpgqAjtrCwIuxebD7 zAR3AehYd6LHjrmhC8PgSL6HTd4OohZvBkgPns+ieBlb13lmOLWYGkzffd1yGgHgzDFyd74WILDXBkOy 3tlBLcAk6E5leMO7LtcAONXNghxDHDxytz8P79xa6j03StKX3D4RfGaMmzPBza5bBXKQUqpKL7jH7B2U efCcwEpdEIf3tANn6I4XVlsgx9JuVXN8nLpLvWaGUvDOA/Ld3/zxL9RzLkjceuht+AGlHDgnMIMX4ObY 5fdp4tod9PCyMApI20m///NfZBteZScv0cjVSRbITY+kR/1z3VG2//W3f1Bbhi8BOVbLt/wpveq8+7z/ k8Gt6vxVmrQ5hp5eG0kpJfvoP/7wJ9mGV+rBs9R7meWBU3VcnExr8g4JAOL1v//7/+js9Q9pcUwOPb56 B21MK6Lv/+hz92/89W9/p2eC8/ifGOCt2m2uAAf5rc+lgtPvu+8pQDD1+Hs0iP9FAeTsUoBrBLlvD8gp xCHBr0Acusdcxto06tBXAXLaZarzngJe0KWI5VsNcr4MUnWpofs77eckp/0BZUNcXaqAOhPkAK66Du8Q 1sEjNzAJ7xYIyr0w7p+lmvfXfAam7M/K1DcN5DADhN+Og5L/bSC/I3DBO5SBK6jC2t4QkGNg6x3K+yBY IcCalqtX+GF6c+c5ao9IV3/U4z00KIABjI+LsWyINH004yS9mH1GAiE6bGNg4/YBIIeuVICclW6E6/zm MvLcVEYdNu8m762FNDaygp5J5j8lOEcGOIAc9vXg71vfAdhhnlZX8l+0UWi/1uyiTmuLqPO6Ylt7t1O6 WNsxIGHZhwFxcMheGs33Yhhfb891eQJ1OJbn2p3SPYpcb+iOBbi5vWr8jnxvgLHeG/Olq7UvXwu8d4MD i/n6i3hbPvms5/3WZFLnZckyVg6RqNYUXpaXzot/B+DWZnEidVuRRj4rUiUNSZclbDt4X0zTNXRznnQ3 NpuXKF7Cjgti6LXEKhq+JVvG1PVfmk0bCy/wMfn7y1KoxZwMKyfdolR6NLhYulvb834IesCYOnSPtuTl OzHGm4Hqnm1F1JVhrtO8WGq7IJ66LEqmnovTyZPPs+sSdMlmMuDxec9JotYMhQiEaDsjSjxtGA/Xh8Fv 0KpUGrI2mUbzuSJSdRhfNzxzA9dnybi8PktieTsvr84mT/wuQx1+e/D6bBqyOoW8FsVJYmNPvhet3oli WAunJm+G0e1vhcu4OIyJu+NNC+QwNq45r2vL0Njx3R3U6u0QuuO1rbIPvHSy7yQGv1cttjHZp4ZuFuQm b6a7Jq4RkHt0TZaMs7vtxS2SjgTj7dysZoKbXXaQuxG8ifREMahPVNsj556SywVzPd/dTsevfChgorCh oILXrqPn3XOtmrM41OWR85oZRiGFB+W7v/nTX6jHHAQ8WN2q0+LL6Yc/t6YJQ7RscOEhiXa1Ahus4IYB s4PEO6fnsCqviiHOGiP36LYcuvy9H8n6v/z17wJy8MRBwRUX6Pf/aXnd4DkLLz1OLaaHyz8RHRfw1OYk +tHPfiX7ACI3l54RgENhx7sP/8P55W+t38b2pL3HuLCZ0arJNG5zFh28+L4cA/td+cFPJMs2AM7JGzdy awF98rPf1Livn/zbL+il2D3UHuMoGN5qe+MwHYw1Nu5mQK4mxCFKlRs5lv4zdTd6dUjhzYxSdYI3lQlx KoW3+sbFQdUAx1DmBjcdF8dGhQ2IU9Jft/ExhO12mPNUY8ZyMnZOhtEtF8DpeCUZs+RgbNUTB4BTb5wa aTXkatxVMPiIVrVmaTghUId1JizYoaLm+C47gFSDHJYBKb0Y4gTmWAJzCQC2amhrKMiZ8PXPVM/4M3JN vfl6BqahS/WsjIMDpAHi+qecc4MchG2Quc434Tj1Sz7N+1v3Rr9ffW9r3tPq+10t8xmpTJBT2Z85VB/Y OZWtGrpJqMNnjIkbm8h/GsKraEQ8lymGMXS11qgjrvqDcXKmEB3uE1rKIIe6t496bC+X76P+3cf3zSuo nIZE7qUXdl4mj4AK6QZFPe4TUkGDdvBx/fdKHR/N1zshpoqeyTzD8FRKQUc/o+AzP6Y5hddk/FwXBj4I 34cHDkmB4cXrH7KHevkX01j+zWcz+Hlt53Zic6HVLnE7hYnzuzJoIcoUnj3vjdb4OoCfF7dLELpWkXgX 3rZhoWXi6eu2Ht45buukTcwlzAqBJMKAK3jnsH+fbcXU179EPG4jGGjH8rkMD9pN/Tcx7K3IEi+Zdp9q WhIIsAfBo4excRg7hxkdMBYOaUcGbttNA/nPu/f6POrMn1uzbUD0KgIZdPzc3fPjyYth79nEAzLjA8bM eSxJohdSqsh3aZJ0uw7h+9pteTbdG2rBWqe5ieSxiiFwfqK7h6njkmTquDCeJkRUkB9/B8DWcnaCTNvV kaGq66JE6rMmgx4LraDuDIxIP9JuXhx1YHBsA1uJ4EEGNx3SBFXbaFO83zu8z4xYQqowpCNpMzuSuiyI lbFy6Grtz/fiUYbczflH6MOf/pRGrYyVMXxDGfJGbimi4RtyaTAD4ICVaeTHcIuUIV3nRJPH7Cjq/G4E dZmxgzq+EyawBlBTz5xEtapjaTKvcwmRqrfzfnBmQVaE6lZJMeIEcpDJVaKX/ek25i1Mnt/i5U3Uj+9v m9eZo4w0JDVYzWml6isHOZdnDgP4fN9YR5n7T9KHP/opfcag8+Nf/IYufPIjSireR/eviJabZQ1C/IIg xySOQYtxFafp967u06SKU9T29a1SEBDQ4M4bx8sPrYykn/3md7JfQMkJajfTilZ9ZFu2I8i1nR1NGcev 01///g+BpcT9Z6j5W4FugINkeUYkrc7eR79gWMOr/PwHNGxNshT+NnNj6JktyRKhi2N88tNf0YiNWW6I Qyi4jIdj4HtgaxYD4S/lGOhi7bE2xxHkunBlfjd5L/3+j39yQxxegNgVhSfIc6XlhWsEuW8nyKknTiHu nw5yDCYq9czBGwUvFKDGCdbscgKpL6Je/NuQ07abVa+EswxxFrAhwAHLCmgmyAFWJS0LLyvM4d5Bvomu mSF4HTxzGGeHZXgxrWhfu2o+A8h8RioT4FT2Zw59nSCHCNWRyScZ3A7SiLjD1H8Hg13oQfKw1xFX/QG8 dQ+uFNlBDkmDvQNLpXsW9XJk1GHqwmDVa/tBmlZwgl7L5OMzcPluKyRvBpWB20toRBR/n4EIiX/7Be+l B1OOUMTpzyn+zEcUeuRjCq265s4nByE1iV/gXhkb5xdYzjCHIIgS8QD2Cd5NI8P3SRqT8dGHyBftCUPX M8nH6Y2so+IdQ3vVaV0ew9hO6sEw14+PMWD7XhmHhy7SbhsZ8ngfjI/rw5A2MHiPeNIGBJUJ6CF9SK8t VhJhBTJEpfoAUJEseLXVnkreOPScuEBNu13NfHNIM4IABu+1+eTLoAhh7Bvgrd0SbtvxPT4OAA+55O5e kCggB9sCGzIti+/vinRqzlCFsdWPJxyiXgw+/TftlEnxh2zKJW/+bofFSeQ1jyGLbRu6dDuyjYIda8dg h5kdAG2AM5/lSfRAaAkN25TD0JYqMztg/Bwm5e+yIF629V2b6Q52aMYQV0MIMsQ4NgeQk6wT/A5PXbdF SeTDQIgccOM2ZNOjQYV0j38ejWIb+mr8PgG2sVtyGfriqckbAcIKUDNwA7MEJsSXYIWpwTJdVvf5MeQx K0KmzfJdkihTdA1iKB3Bx4GGwPvH8NePQdRzDsPjzHDqOD1Evt+Sj3/Xq0j4C3baKCx0MyCHYIqh8yNp 0+7zFFR6nt4MSaPvvLBOcsg5sprTSpVj16rtB+0nVA1y1TKjVVV3ujxyTacEUddp22nA9C1Cvz4MM94z Q8l7Vjh58Q1sMy2URizeQSOWWjAnQQ51gJwVmcrfm+XkkYsgX6btEx9aEPa73/2OFqbskYLQfJqVYkSF AtKFST6k5ChVnLlKz27Pc3etPhZQs2u1HfK9cUH2XhBFxWfeky7i3zE0rcg5aHniBOIwfs4S1j0WlEdX Pv2JdHH+8Bf/QdNTK8Ub57s6g0rOfeD2nB28/gPqzYBmBTNYeeNaLcCEx6nkxZVhQ0EVVV37Hq3LOygV SUHOgjkmeAY5uMhLLnws54tjHjh/nf6bzxGvXSev0Jht+W6QU4izg5wTwJmqG+KsAcCWsOxSHfCmwr9d hbj6YK4ugHPLgDa7AGsKctUQZ0ngLciCNpEL5ExwU5lGCWpIN6rKNIJiIF3wBjkaUxXvC7AzvXFqpE2p AfeCoeZ3GHh3tCqDg0qBwAkc7JJ98R2AhwvYTNWAMpdnDvACTxbeAT49Emvup7Bk/3wjKajVgLVkXr4J mceodSxDfonnqF8SIO4CDUy7YAFakrUNENeXJev0Gvg6cc0YQ9eL9+vB4Ib7g/3xGxbMnaEBCQbk4p7K fcYzsd4bCnUNATmVE8iZcixzLLN8iozyCyF4oXs4l0sENTCkem3fI564gTGHGey4/rjqBOqIWWekHgXt 5f0rXLK8cr0iK2lYIsBuD3mF7KVeXGeQGw5wNTz6MN2Teoz8D1ylqs9+RasPXqNpO0/TnLKrNLv0Cq3c /x5tOvEDWl35KW2q+oy2Hf8xXf71X+jDX/6RfvCr/6STP/wVreLvLiu/SPOKztH0vHP0asYZeib1CD2V XEWPxu2n8ZF7aVgwQ0ZkEZ/DTmq/JVs8Z8ND9vDvXKboYx/T9qqrFHj4Q+rL5zg+rMrdXTqIQW1I2D7q w0AIcOuxBWlIMC6OgWoNt4Grcqktw1n71fzndrU1Hg4BC738d0t0qzfaRVdAA6JZEcmKthjQJpGo3Ga3 WWrNumO13xgXlyOpSTBuDt21CGjotiabevFvYm5WdK9KF+sSaxovBEaIzVhopR1B123PVZk0PrxUen7g OHh4Rzndzcd/nK+l3eJ4cSj0WFNAXvhjz8B2z2YAYZpM4+W9km3V3DiJgEWqkq5sf9BN2m1ZOnVbjjla c+iJiD107/Zi8sAYOd4XgRGAN4DioHXZ4oWDrb1jxg6BuLtnMXRNZ4jDDA9sf9vxOszjCpDstzqLeixj cEV6rndDyHtRrHjWRqzLov4rGBLnRko+uomR5eJVa/NuJI1ZmyvwdgcAbmo4c0OIjJu7e2oEtXknitoh AwUiTt+ycsypx82UeuMQ0dqUeQTzoTZlaGsxJYABzsrGgd/rwTDYa2Ec9V6cQANx/WuyaNCKFF5Opn5L kshvQRx5MwBiYvx2DJB3vxZATSZtkYnw73h+DW3OP8iqopzj12lL0Sm6YxID4QtrnVnNaaXqqwQ5jJO7 i0Guy9TtNHBmALV/kwnW5bKUwYXifbNuXOepgeQ3fRvfqK3WjZQbfPMg14dp/dz3/03Wf/+Hn9ErwQxo AnLVEKdCgfJeGE99+Ka3nw03L0BuR50g57comkrPWiD301//lual73d546ohTkFuyKokOnjlYxkH95Pf /J7mZB4SkOu3IYcu/9jysgG6EivPUg+uWKhkmgAYIIfK1IYroffKDBq8LoO6M9Ths0IcBIhrx5X1jZQD 9Iv/sKY/+8Uvf0lDVyfR2fes3/7rX/9K83KOSENgqRHkvg0gZ0Kc2xvHBvqrBjkFjYaCnH4WLxQDDcAG 0ALPlLmfCUx21QdXus2UE6zVJ8djOPxGn+Rz0qU6OO28XAu23QjkcN0AOV1v3jN47nAvtPsZ4wmrYc5J tZ9HfSCn0jJgygneTDmVOcgsnyKj/ELeO/jYIRU0OpWvN6yChjDM9ebfkzFvXN61TjiBHACue7D1Dm8c PHMKcuhaxdg5P4YJTKyPiNV3y6+Qr385TS+9JtD2fMZJmpx/mR5MO03eAUUy/Zcf0p2E7aV+O/bR+PST lHzxR3TmJ7+l9377B9r/6c9pIP9e7+2V0pU6KKSIRkXvpcfiK+mJxIP0ZNIhmphylF5IPkIvZxyjSdkn 6cWs4/RmwUl6p+A0HfrJn+jD//gD/dsvfktl732Pnk47SWOi9lLfgALqvj7TmgwfAMVw1m5DkUS1Ijq1 85pd0lai3UTXKiJVkZ7EZ0uRC+Bck+rzdwF3HVej29RKTSLzsTIswSuHaFWMn4PHDkKqEqyzxsFhO6bt yhWwa7883ZowH2069sFwGhbgDt20nRkCvdHNy8v3he+hzosZjJZk0ePRe8h7uTXN15jteVaKEoYm2B8v BiUENEzPOSbdttiGIAdfhisPhizAmyf/LlKReC1F/rk06sg2qsWCWDn+0K07BWyQ1LfpvDhqzuq0NIFG bs2nVmx/W7wdIWPhfBgEe/JvoSsU4+faz2M7yHCHwIXWbJcR/DCE7SYiYwF4SA+G7BHe8+NpesZBmhDA AMyfEbEKr93otQUCcE2mhkiwBLZ1mhUrU3opwJns4SRJU8KcIr2JLlapMf4f4+RYt78WIsmAb3ulOvDh u5MsYTou1d2vbaN2rweS1zvB5MdgN4w55f616ZRx8Dxln3yPwoqO0KaC49Rk4nK68yV0tzqwmtNK1Rfp WtUgB32Xi9N3vVC+AXITJgdQl7cDqN/M6lBeuUG2G4c5Vp8LyKLEipM0bm2KrLPyxtkCHiRfXBh5zQ6v CXJzrem5enOBOvPJ57L+w+99ShMD+R8AgxyCILRb1epaxQwO1X3zgDgREz1A7oqra9UEud6LY6j83PsW yP3mdzQ/o9IFctXdqhCieAYsj6d9Fz4QmPr817+nWVzgAHIDN+bR1Z/8Wo4N8Irec1LGzFkeOf6HBIhz jWewC/+KJN0IPHEub1znxUm0POeQeP7+6+//oOCSI5JeZGZyOf3id1akcPyBc+TL/xIU5jTAARnEG9Kl aoc3uwBxdeWMg+wAZ3ap3gzEmSBXX5eqwpslhjQHiKvRnerSjeDNlBosqD54U2mXVQ05GFJIjC2DHOAN QQoKbVhvBzgnw66GXwIdGBrw7gQJChAKbZB0D7pAxC4FGCdhO2DIzwVzABtACwSos0OTE3A5qVfK2XpV 3344F7vMY5uCRw3dqUPSL0miX79EXg84c4HcgNTzAnICYnrNLlhFF6xCrNO9wr1Q75xGwOIe4153jztO 3vF879Fd20CgUzk9exPm3GXEADiVU7lTaTc/pEDnE3aIuoYfpJHxB2l4zHHqsuMgDYvl42M8nKvcm3XC rCvuOhTCEMeSlCTby2UZwRFj4w8JwI2N3kfPZp2he5OPSooQz8376Z28ffRY1lV6t/QqvZB5hpBceELc IRoRv49mFV2l13eepjExh2g0H2dSJj+TqEoKO/kjSjz9E9p08BotrvyEhmwvo/abdnObgqTA1fOwIqCh V1A5+SKQgIFvROQeGpO0nyalHqeH06voCQbE97jt/uTf/0jrjn0sXanoUvXYWExd1pdIHjoEWUyI3U/P px6iZ5Iq6cHIchq1HRGuBdR1fQ715OvATBRteH8AXxt0q67JlG2IXvVkwENqkS6IVuVlr407pftVomJd k+VX/wlnod1emiXBDQioANRJrlCX5w6BDp0REcvwCGjrziCHFCeIcsX3+q5LowdDSqjToiR6mp8fbAjm RQWMYUxcUwYr9BphnlbAXXsGs5CjH/L3s0WAuz4MlH3WpAvcYR/PRWnkuSCD7p6fTk1mx1HTuUnUZE6i qNO8aOkGfYOf0VP8u178vS4L08iPIfQe/wJqMpNt63RmA0S9su3FuDV0bY7dWihpTTC7A+wyxr4D3pq+ Eyv55F6O4+fF96/3ilSGtxiZCaId23MkGH5gEwPx7Ehq8y7v/7aVT84uMAXSjUieuDerha5XCJ635q/5 y8T2SEOCsXMyRRcCH1i3vR5Ct/H7XQxzTfm9OX/2nBFGPuiinR8n6s723oMhtj3zCqJe74KDi/kKYIcp u257fi0F7L1Cm3Yepq35R2l90Rm6/ZkV1HRSoDOrOa1U3TKQc+neVYn0btQums4avTyOevBDGjQnmFq/ 6QI4BTylXIOM1+RVSU62HaXH6G7sbwCc9nXfCOT8llSD3Eef/pBe2p7jBjmz3x0C0OkASzfM8bvpkcMY uXZuj1yMeOQAZxhbNz/zgBvkFOD0feCKBDfI/fhXv6sFcoA4KLbidDXIudRzVQY9G1ZIU2J306vRJTQ5 Zjc9FrzTAjkD4qDHworp3Ec/kHP9w1/+SkP5nyIq/LDN+XT9xz+X9f/2i1/TWymVsl4hDpVeIa4R5L55 IOfUpSrrXctuI+1gzNXQf50gBymoiVfOBTYCdC4Y+qaCHM4H5wuQQ5cqlvUcAXJYNkFOrwXbcN2APlwr JOuNeyL3he+deOaM4BAFXb23uPffZJDz4DI8MP449Ys5Ql0YcIbHHKXBcVzWGPC03Jt1wqwr7jpkgBw8 cN4MgWN2VNJLuSfp4dSzkh8OAQ99w63vdAkup2UHvk+vFl2jSXln6e1dF+iepGP0dPpZmpx/kQZH7yff bUX00s5ztLDiCo0LLZN246mYvTQ6upKmFJyixXsu09Si8zQq3JoJAkmGJYdcQKm8I3CiX1AJDYsoo8eT T9IYBkp4yZB8eMflH9OzSVUUVHVdpsbCoH4k7R0QXCpj9IaEVtCIHQcY5g5SL4y927SLfDftFHAcvaOc 7o2rpCdSGAgTq2QM2riIShrozxDI4AbYkmTA23ZT/6A95MuACO8b2mZ0t7q7WfmzCXKYVgtj67pv4HZU ulItiFMB5DA+DgETSD/iu57bXF7XiYEPUaOTMo7zn/9kejKB//AvxHjsJOrD4INgB4AfAidGwNvJx+rO 5+jJvxVw8D3qu36XpCxB6hJ43bqvhBMhmdoyBGICfgQydOdjdF+ZKmPhMENDL14GMCKwoSkDXds5UfRg wB7qvz6L7p4dJVNv3bstR5IAD12XTUMYzDCuDilGYK9ht6W79d1YunNquMzF6rMwTsbCtZ8RSl7wAM6O pi7z4iS1SB+GW8wSMW5TjqQcuWsaf78ekMPUXHYpkzR7k3njDd6X14FFkGcOY+m8F8RSz8UJ0pWKblXM t9p5aqh425ogLuAVjJljTmKOwrys7ihXhjfdrtN1tXs7lJq/vIae9s+ip4MKqflzKyRi9faXqyNVa7Ca 00rVLQM5PtG5CWV0+PKH9PNf/or+/ee/oKrLH9Gq5BIaPNvliXNBnBPI3cEU/NSWdNpZdYYWJ5dKwl8F uZvxyJkg9+H3f1AD5EyPnEqhriEgB49cXSBn98gNXFHtkQPIzWwgyLVekEjTU/bT+z/8nL7343+jD/gd Ovn+pzRqI/9TcnWpQggRX198SiJf/+uvf6P8oxekcqLCd16SQokHz9Mf/tNKs5J56gMZeKogBzV65L55 IAcjC1Azu1RNA/xNBjmVeKAYhgA+gBuAnAKcyg5TdckJ0BqqhoIcPGoAOICcwFqKtb4nHwPvdYGc7MOf NdJVAdB+PzBeEN+DtKtVPXP4bu2cc7WflQlwKqdnbwKcu4wY5UflVPZUTiA3PO4YDYg7IstDYo9S/3he DuO6wGVby71ZJ+z1RWSAnC/D2vjk4/R46gmamGtFqHoGMNwxEPXiuoEZG55MOUG9ww/QwvJLNLX0Oi2o fJ/eKrjI9bGUevL+E1L5PjKEPZd9VoIOXtp5hd7NPU/3hO1icNtHE9MqacC2QklhMm3neYaqI5JuBEET CHToxTA3NraK7k84RoPD9shsEB6B3MZsLJUu1FdSD9PY8P209OA1yR03El3J4XslChXpT9C2dWF4gxfN b8tOiVhFypH+QWU0gtuQ0QyqI8MPWusCi2jQ1gKBzUcYQJ+IP0RPJ2Gs3hF6OGY/71vK51ok+eMsD53V 1Wr3yGH8Hqb2Uk8colIV4sQmLE4RSPRZz+3y8myrW9XV5Xpf+G56IHg3PR13mDosSaYWDGLdlzJ0cbvc l68D3aXwsD3A19id2/Uea7IE5l5PKKc+/JuYKL8T2x90ocIzN9zfSjTca022NU5uOR+T7WDzmWwTMYn+ 7ASZsgvZGjCMCd661vMTyGdRIj0dXkovxO0XgLs/iAF4Kab+4u/OsKCt5QzLywa7jLQkLd4Jp4e25tMj Ibup9fQdEkDRbsYO8luWJLNACNDNjaY7GI6GrclgFgiju95x9sgpT2DKLqQr6TA9jDrP3CHeQHTX9liY SL58bzCvqicfF7M4iGPJ5ZmTyFaXkHsOnrrvMKzdMUkV4IY4XYY3DjAnaUeYoVrzNTYDS720VVKNIFDi tonMYC9YHObIak4rVSbEOYGcI8wxvJkCyN2/OkGS59pfH3/+c3pyU1p1l6oL5JCXxQ1yLNzcO17eQM2f X0ptMJYON5uFdxPkZAoO+xi5P2KMnJUIuDf/M6jLI+cEcApx1SBXd9eqH4Ncmatr1QnkpMDis8sjt//i h3WCHF5OINeRC9H28jPyG5D5WhC3kytTNciN4H8eRWesFCVIRrwiuYiejSyl56LK6MHAPNq++5i7e/Wj z39GbyVWSMPQ4QuAnB3ozPFwGq1qBziVCXLQjSBOoQ3LCm61ZIM3E+DMZTvEieoBuPpADgZKZYKbKTvA QTeCN5VAmssTJzAH48xGtyHwZkrzxyFSsjpaUqGgGhgU3mrAWpwrjYZr+UYQ54YaQxbYWB65fgxAABw/ gSbeLu815QRhX1RO8Oa0nwrb+zPEoUsVMGeBZ/U5yfnxZwU57O90zfDK1eg2dbhXEGBOu1oV6vCO5yQA bXtG9YGcKadyYMKclBsbzNlllkX5zOUV4+HGpJ8jHwYqfB6XeYF6MoRhGWXbqQ6IXHVGZ3zAuDjkmhub cpqGRjLgxB6mwTFHaGhEBd2XdFzSmEgwBINcHwafUQyOT6cfpWHRh2nZgY/o2ZRjNDqUQSrqAA2IPkKe W4skh9wzmScl6KBH6F7pLp2YeYym5Zyi2YXH6DEGlvGJR6kHQ96UjLMCjC9lHqXHk47So8kMptuRjqRQ JtHHNF3ISwch0GH9oQ/osagqAbm30s5KUAOCF4by++CwMsn/hvQjvQL2yLvVbZonastC1yiiWRH9ii5Q gFk7Bh7IY02OABkiVuFRHBS4m4YFl9K48D30QMQ+mhC5lx6NqaTnEw/QMwkMfYlH6B4GwPsj9lIPTMzP 59FuaTa1WZpDLZfxMrfl8NR5cxuN7W0XJknPDda1W55EmOKr7doCejVuN72YzmVzFQMhAyNShoxisEOe uZHbS/j6kqnnigwa659PA9al02C+joHcXiNn2+uJ+8hvRTy1Z9ABjCGAoSXbPE8GxKazYti28e+w3UOq khZzE92OjeazIq3xchuzadS2Auq3ms9tQQzdOZNt77RQ8lmWRuOCdtPgtZY9az87iu58l7/LkNZkOtvV OTskJ9wrkYdk0np47LwZTjFDBAIbOsxPps4LUkUt3o2g5m9vlzQeADtMswkPGhIA92bI7LU0kXoujhcP HiCwLX9fxsy5ulPvmmKlHdHxcXYpu6jMnkjIzkVILwIhnkA8dYhqZZDrNCOS7hbPW7VMBnPiNOhrAbmD Fz+gv//DSnALQNEXlvNPvkd38nGsm4Hxc3zRfNPghVNhPJyMi1N4k+VqYX5VkVOwA0ButoJcEp3+2GmM XM1AB+SSq+GJU/HDfdS/Oo9czWAHyyNXV7BD9eT4NwY59cjVGCPHwj4vRe2m8nPv0eHr36c/uHLW4Te3 5HODuNKCOGhp3mH6wx/+INv//t//Q5/8+6/o2g9+Qtd/+BO68unn9NkvfiPTnuGF80g89p4FcuKyz2SQ y2wEuW8YyJndqWpgv3Ug54Ih9czVhDlLfqkMRS6ZYPVl1VCAg/DbffjcBmdcEvXhz4DNHja4xLFMkNPr M68Z3ay4PgRF4LplndP94nsJmEPaFoU5lXXPq5+PJX1u1fo6QK5b+EH5UzE2/axEqGI7Zm3ADA5Yr2Xd Xv5VXUMtzxsADuA1JvmUjCcbEX+ERiVW55sbuGO/gBzmVx3E5zyAf6df2H6avfc6DYo8SIMjK+mxpCoa F8/1LqCEnik4S89mnaJnC69Sn6BSSQ6M7tYB4RWSguT53FP0VNw+ejiBzz2yguYVX5YuzUERpTQ58yyt 2f8BTc7lMsnn1SWQQXNrqYyVQ1errz8vbyykjYc/YmjcQ2MYQh+MPUrjow/QuKiD3NblyuT3DzNUjuTf 9mTQ0fYP+en8uM2C+mwqIQ8kCeZ2st0qtJcFkiy408p8UbvVO91Cu4pgCPyxRmoRTNeFKFR41DAeD8mA x4eU0gM7GHgZ9J6I2UMTk6vo5Yyj9HzyIXoiag+NDy6je0LKJUEwZm6Alw49N4hYHc/PIvDAB5R85D2a llZJmPGh97pcmegek+KP9t9Jo4L4viLoJLCExm0vZYjLpF6rMR47gZovQDL7JFpddk6SDwPikLIENg7g hpkb4KHDZ9jCDgsSqAPbSqQgGbR5Fw3buJN6LkqipjOQwiSRmsxKplbvxojHTSbYn8kQyNswzu2B7UX0 bBSXr0WJDFkIUthBr/DncWszJZrWiwG148wokSc8e0tSqS+f04j1GfRAYD71ZnDtyeeAmSMw6X6rqdvd Q7K++9YOt9Cjhym87norjO54w+INq1ewboiDbhbkNChUvHRI08Zs1eFtpC0JsjjqqwI590GdIE4jVSHb CeMiMNhe4USF11//hi6/y9RlqhXsoDfB9Mi5PXMumFO5oc4lcYvyA6jVtWp45Prwg3V75FxdqwA2J28c IK4TQ5rX4iSZhsvsWlWPnOSRm68gh6jV6+6u1Xm2YAdxDeOzC+T2Mdxi31rBDp//yn2P4vZVe+RkDtVF qdQG2bPnx9E4/wL68N8t6APIrU4v439AaQJxfbmiFZ//SM5RjwWZL/v6C5/+Gz0VtsuCN5c3zgngTJkw Z8k1i4Mr4SXUEIhDd6qqPpBTiDNlAlxd3akmvKE79aa7VPlfu8gGce5uIZaTwbLLDnHaNaVdVaaxVGE9 jCMkSX9hiA0DqxGpYowNQ20aayybhh0GX7081mcLDBTe7ABnygIOS3YQkW2ADpsUbgRwXLCGZYUqeL0A c70FjmqC0q3SzUBhz5TzAl4DMs7T0IzLNCj9Ip+bBWoCa8a+OGd469weOdf12YXrxT7SxYr7hC5T1/20 C88GMAfoU+EzpEBnPVOF7/qBziwTprR8QPqHwPyTYKobl0WvMP6zEXGUfBmiHsk8J7niuoVX0phEPt8o bLeVbxb+2Mgy15GuDGeY6QGfkVsOud0QyDBkRyXdw9fovZ3hKZihiEHKJ2wP3Zt4hCbuuij54/qF7KPh cUcloAHj1by37WPIO0oj+VyeY/jzidpLLySfoxm7r9JIBhiMb8Pcrr4MXUOiD9ObuSclKnVy8hEBt7Gh e+mlhEM0t+x9mlZwgV5Kr6JeW0poVvo5mrLzGIMiX6v/Puq4eTf5BXHbsymfppecpedyLlP/rfkSFHFP XCX1Cz1MT0TvI79Abn8xlm3zTpqQeJyGMyAisa/kkdvEbZtrhgdTAnrcbko7upbBDuPvVnPbuIrXrwTo oWckw90WYz9MvdV9bRZ1XZVNffB7DJAdBfYY0BDosCyTWq/h9pm/N4Tv4+jgchoXVsFgd4JeTTtGU7NP 0kuJB2li9B5KPfshJZ76kE7/+OcUdvh9BtQyidh9MaWKHowollkckLS3D9phPvbYoN3ksSJVEga3W5RM dzOYdVqWQUFHvk8eDJ4Y84aZHdBzhPQj7RYkky+fd3cGrb7rcmgcP8N7GSoR0dphkTV3KsbmYf5URKh2 5+9itoduC+P59xjM+B3j87ozgPZcHEsD16bTu1lHaH3xSVq08xQN3pxP/ddmsN3MFe+dJ/+ueNTmMEQy CKLbtePsSEl10nrqDrr97UBJOIzACQy1qqtr1ZSdO+xcoiAHyDNBDnICOV0GvCFXHPgJLIX0I/hs8pUw 1jcJ5M5c/YD+YXjkVP/1t79TetUlavWG5basyyMHmbnj7GlH1Ct319vwyoVRdxvI+bg9csl0yuWRQx65 RWn7XCBX0xsHiOs8L5Z27DlNZz/6IZP/7mqQ868L5OCRcwI5yyPXzOWVqwY5yyNnglxvrqAVV74n9wbw e+i9z6jv+lyXRw6DT62EwAC6AZsL6MqPfyH74t5O3p5OHTF4VLxxR+jn/2ElM/7b3/9Ov/ndH+jnv/4N /eI3/+EWPv+S98EUX3j98S9/pR2HrkqjYXWrcqNgQJuTGkHuqwc5hTgnbxxUH8iZMg07DP03CeQAOPDM 4d2CuVurm/XuYV+cz+CMC+KNs87ry4OcjpUDmKGL2en+QXgukHa1miBnQSA/CwE267mZAKcyn7dTeYBu BuSw3nPHAerHADYm8Qx5RR2QdcNTT9GQeAZL15g4uzwZ3lC2uzJUIQ/ciPjjNDqJyx1DYN/o0zQu+bTM veoRvl/qWJ8IRLwepb4MgCMjK+n5vPM0KPaIdIGie/W++KPktaOcv3+Ans45RwNC99HjGafoIYaqd0ou M/BV0pOph2S9T9Ae8cp5bC6iSYUX6IWMs/RMGkNK/D6amHGGXiw4S8MjK2RC/d4MYksrPyTfHfvoyZj9 NIuBcCADUM+A3dQtYA+9nHuGFu48KuPvxkRVUPctRfR42nHqwyD3Ujr/wdpaIgmFEemKY2FcHMbcdV1f aEEbt3doCwFsGEMHL5wpbTfbrykUb1zbVbzMbau0swA1lpX015pvdcDmQuqxNlumzxJxO4qACnjrBm7J p7Fh5dIlOnB7KQ1hmB0RWkrDQ3bTqPC9ksftxZhyOvrRv9OnP/0dffL5z+jYT35DIQc/oE2V12lb5TWa lnmCXo7fT4+GFdNo/100GNcbuZeGMtCiy7XfuiyZpB4zPfjvv0KDGGBl3eps6rk8iQauTqXx2/Lp0cgy eiS0kHrxtXgsTiOf5ZkCd5gIH+lEevDnIevSaMSmLBrvXyDTez0VUU6vxvAzYth8OryEnggppvu25NLQ LRl037Y0mpq+j+56J8ry1rGdbj2Tbes7ruTADG+IXAWsYbnrgjjx3rXl/ZtM3S5zuwrEYRjWPwHkVIA2 wBzUhrml7dRQN9RhnZuxvkkgd9/yaPr9n61uQIU4vDAJ/Nqcg+6boTfgVnrkfv3H/6Qec6xIlzbvhFHc 3lP0+z9ZMztElp2gJlO21fDKqTfu0c3p9Pmvfiv7Be0+Se1nRoqrF3Ot1g1y1cEON/LIVVyo7ZFrx4Xy 5W0pAl+4Rx//9Nc0aK2VRw7wVv2eTPcF5NNnv/yt7Acg7jk3jLdZszrEV12W80OQQ/qRy9Rh9g7+B5VC 7Rn0VB34nxD+vUUfuizRwAiKKDn/EfXifzjilWv0yH0jQE6DGsQbx+92A6sAVxfIqSE3DTsM/dcBcibA qUywUTAC4ACEFIhMUPoy6p12XtQn/YK8O+3jJHSjDs44R0Mzra5fwNqtADlAGPaTfTWFie3+QXqvFeRw fxTkzO5W6d7+mkAOZXEgQ9Sg2GPUKeoQ+YYdpgEJRxnOuC7wNinL9vLN6rx9Dw1KOk7jGfh6hu2VujI2 oZKGxh2TXHE9GNyG8PliMn3P0L2SugRdqKNiDtKYmMM0IZ2vJ+SQ1DeAIPK1Dd5xSMDv5ZyL4jl7KvcY zS+6SB47jvG2PTSUofGR9FPkHczHCyijvqEVMon+q9knaSXDih+m+9q2hx6L20uPZx7nY3Ad5vbFl4Ht 8ZxDdD9D4KTs0xR+4hNKu/gZZZ//AQVWXKVx4VU0jK/z+fRjDIrl9DSfW5ctZTSt+LLM2NB+o9XewbPW G9Ns8bUjGbDnxgKZVN+b26ge2xjyAsupD7cng0IsYYzdmJAKGhe2X7ptRzB8DQ0opiGYAWLLLgk28OP2 0pchEBGsmCS/89pcmQWi+4Yi+W1PhsOuG/KpV2AJdVyNblgrPQny0Hmsz5cAhcHbdtFD0ZU0OY2vIbKY lhaeo9Of/IxyL/2QBq9Joh6rdtLgwP3UZl4ytVjE8Lg0XcbMIWL0EYapt5NKaE5GFa0uOk9zs47Tq4kH aDTDYtnlTyiq6gI9HVHE8FVGT0WV0oNBhfR01D56Wj6X07PRe2nMtjzqtz6X+vG5eS/LorvnplHTuSnU bG4sNZ0TQ3fOjqK7GLQgGWc3M1rAq/28GPJaFCszRPgsT6R+m7Il+W+H2Wx7Gdhgs5ELFmrJthuS1CQM dpgHthum6prBtvddKwkwGAH6Z4CcBoFiPByA7W5mluavbHJ76Ey+Esb6siBnftkOcO4faSDI3TU5gNYk 7qRPf/Iz+v0f/ki/+e3v6Qf/9nNanblfZniwIM7yxkF2b9wt8chNtbxyU7gAf/YLa67VP//nXyi49CRv swAQBaLNjB00Zm2KJOrFC7C1OvcgF4oIF8jZ5lqtAXJ1e+TMMXL9kUfO8MjNTD8gINdqQRL5rcmi3/ze CkIAYCUeukTDNuW6c8i1nJ9I9/jnU8m5D91AfOnjH5A3Vzh44+ZnV7mv7+cMyuuLTwiwIXJJo5tUGHvx evwe+uDHP5X9f8TnMq/ghEBca7jPGwRv1aoeF4cGzVJ9AKeqC9zqgjdTJsgptDnBXL0gx//c7XLDmwvg VHaQQ9cR1CBwY+l4OICbgpwd3iDTC6cQp4bW9MKpnAy1acjxrkYeXXOAAvXs1AdvTqABiJOISoYJO7jp uwk1Jvg4CZCE8WiAJvXMAab8Up33b6jgWQPA4d0up/3Rpdo77Rz1Y4gblMWQkM7nwpBW1/4QQA5dw31t oGhCnPs+AMhYGFOnnjnz/jnda0juKb9DCnQQPlvj5qrhTZf1s70c1CctSybQSVnkZQQ1IMUIyqVXxAEa nnCCBjCMWV2uB6U8e7rKNNKOdEfwQtJpGhfL5xjOQBe+j4YlnpJpu/pG7BcoHJzIfyYiD5JHcLl0sQ7j 4w+KPizeuh5cp5C646FM3j+EzyFyPz2fw88jhCGM62QfBo4n88/RlF3XpPt09u73ZWL8p7LPCyCOTTpM A0PKaHzMEZqx+z0aHlYukPNGwVmakHiUYaqQ4SpPZnB4LPmwRKrid3sFFdD4+GPUwX8/xV/+KZ379z/S 9V/8no589mt6Of8SvZxexQBYQffuKKcpBWfo3vgqCqi8Ts8BVmP20bjoChobtZdGBu+hZxKO0fgdFXRP 7GEJugDUAfB8NxeJ90zVYyMCG0qo59Zi8t64SwIgIOzXa0sxydg6Brhh3Fb153au16bd5Lcxn/ptKaDB 3NYN37abHtyxjwGwhPpvK6IBW0tp0BaGQT7m0O276f6wMpqcfIjeYmh9OrKcHoook3QpqxhA7wvK5nUl NGxrCQ3ZtpPGhHIbifF43P4jF1z/DXkykf+4IIbFdTnUfX029d3KAMmQ13ddHkNvAV3+7LdUefH74q1r w3YM4+aaz0lgOIu3IG0e2z54zxbx+nnxkvOt8+JUsYumswO6m8ENgRJt2U4C4vA7nReyXUS07oJ4Seo7 YE0GjWKYg71WwbbDAweAg0cOUIdo1s78+13gJGEoxLyr8Map4JVToFPZgc4OcnY1FORUiEC9g4HtOy9t pVb8e8gjB4hzs5RLbsb6JoEc1PatYBoyP4Je2JhAT6+NpSELo6jttDDrRsiF32qQOyBwApDrORceOQvk 2kwNpsxD52WuUbx+/+e/UOXlj2lp2h6aGrVLZlNQEMJr/9lrNH59mkAcgh0eD8yja59a3bN/+8f/uEGu jyQErg52qE4IXH+wA4BxtmtmB4BcBy7gyzL2CcSJt+3v/6CTH/2INhUeoXcSSimk/BS99/kv3IEKf/rT n+j5EP4XuAQDUFMo8eh1+svf/iHbSs6+T14LogXa2vB2TMNlCiDXdkECRVackXP5y9/+TjvPfUTeXGFb cyVuBLl/PsippIvVZWD/1UBOBbgByMHDhXcL5uoGL1O6382qxjFSLlhRqpkXaWAmw1m6BZnmPnbVBXLm b+h9QMoSpFvBdQJWAXXm/XO61yrtaq1LJtCpzGevy/VJy5KWs+74AxHBUJTBzySGt0dwGQw/QCMzGXQZ uLwxjsxVVqVMh+ynPlxWR/O1jeVz8gyroC4MaP0YjB7ka0ZAxOC44wxvXPa3W9GkQ3j/EXEMawx73YMq yCf0oIBgr/DDvK2KHsw4QX23H6Aewbvp5cKrkprEm8FvUHwFrdn3KY1kkOrkv4+ez+Oyw+sfTT0k3bIv ZF+kt3e9R/0Z5u7P4vKNAAoGm7eLLlGPLUU0OtKaEmw8n+cgPuZz6SfoHoaue2OO07tFF2hVxXXKf/8z OvWDn9FP//Rnyj3/PRrPMHp/8gnpQvVg4IInrcPG3TSv5Dr5bdlDHTaVUPuNxZY2F1Kbtdk0gu8BpsXC pPuYh9XqsbDaSsyfCmEWCARKQDKn6kpuZxF0xvCCYIfWmB2BAQ2ettYrM6jNav6TvbqQv4fu213UJ6CQ em3Nl+E2mBTfb1sB9WbYGhZaIulMnkusolHBReS3KZcGM4R7rcmmB8PL6c3UIwJso8J2cpufzeBXJCmq JLqV7RCCIvpsKhAHwaiAneS1JIPhrYDuCeFnuiGb4SqZnmUon5lyiCZE76LxEXsZwKKpFYNbq7kxMvNC Wwa69nOsAAhEsbbm91YueGvHNs+EOAgBEu0YADF+rjOGFDGAAeZavruDevC1I5q0x6I4GsfQieFOCnJI RyLi7QpynefHSToSj7lxMusDJtH/Z4Mcol8xgX5rZpj2DJpIP2ICnMrNWF8G5MwvumUAnPtH9IcbAHKi V/2pxWvbJCMyZnXAxeMm4KLRnaqyuy8h941z3WC94SJ+GPJA+MHgAXWbHUFhJUcEZv7r7/9NXjNC3SAH d+vg5YlUevqaTFGFF8aj/YyBCl2pf3RFguL13g9+TM9tz6OWTPkCcvw+YVMGXf/UlUfuL3+htq6o1Z4L Iqnq6iey/nd//DMtyWY44wKraUe0axXA1ndpLB177/uy769+/yeam3lQIM5SskT1bN1ZJd2deAHosN9P fv07+u0frW5hvH7729/SosxK6rTUmiDfgwvq3qufyjZ8N3jvWW5ELE+c5hNSqUcOmhRTKh5SvL7/s1/T 8MAiR4iDFOScYE5BTrtVRTcAOft0XHaQU9UJb6bqhDcL4Cxw00nxy8kzkIGNZe9OdXep1gFvppwAzpQd 4uqDNxU8ITCOOiYO0i4uy8DWDXBqtCG7YYexh9CtanXN3RzAQQocgDWFOU2MKyDngpabATgV4E88c+kW UInnSmDIBmoMXFDv1Itu6TZznV36vRrfdQEYvgsYG5hxiYZmXbECMPj39bj2c1XhOwPSL7qh02kfFa5P pV2sbiDGPcO76/7WJUCbjpvDsgIe3hXM61J9QFejTO3AnwdeH1ZJYzIYVhni8MejF0PO2ORjAmaAOt8w ywvXdcch6sPHeCT9OA2Itspwl/CTNBQZ+3PPSbdq3xj+AxJuRbz6hVRI1yrGy8Fb1yPsgByrZ+gh6hFS HSDRP/YwPZvB9yXhPL1efIF8AneTV8AB8crN3neBBsYepMH8fdTt8YmH6fmM/RK1+kDCEa63u2kcvz/K GsLQNiCM6+/WvTRt33vUN3SPAN7rBSdoUfF5ejf/Ar2dd07ytvWLOiCANC6hSiJpP/oF0Se//BMtLrlA z8ccoEcTD5FvYKlEj/oFlFK7DQU0s/R98t6KLs5C8kAbhUS7vAy15T/FQxlQ228uov7c5nTeaLWB8kfX 1n5C1jysgDwL+AB/6E5F3jgBvjW5/Nt51Iu/PxiRuehOZWjsv3UnjdxeTA9F76UnWY9HltMzcftpBN8z vw1FMi5tcOAuhsQ06rwugybxdQzYmE+dV6TQA9t30qCgYv68i//Ysy1hO9RrbSG1WxhDgxmYEFDwUOR+ GYeHCfn7r8+WgIVHIvbRCN4+PngX+TKE9lieSoO3MMCyjbtrJlKRWJPnQ7CFiGTtyjAmXjNe12kpg5oA XIy1z6xY6sogiZymbWbzd2dEUs+VKeKdgyeuE9tGryUMZ2yLuy5iOJwa7AY5HSMHkJPuVWaBznOS5Le6 zubvL4yV+U4xhZeygls2iINuFuRMOUGcrgMTYT7VFm+HCtBBJsBBNRjLBnKQE7N9rSCnpKpSkIOcoK3G DbMBnEnR5kMByLV+N5wmBmVT8eHTFLjzILV+J0wgTkEOGr02jdZm7aMz1z+qlePuV7/6FcWXH6MnA3Oo w1wuaFxwVD6L4mlJSintPnKaVmbs5X8X1j+J1rMiaU7ibio6fIr8dx6QWRTEI8eFENLxcQC5tnzMBcml tKvqFG0uOEADuGJVg1yKyHtpMs3nhunAuau1zu/3v/897Tx6jt5JriAPhj5AHNR2cQrNS91LJXxuEbuP 0HiuuAptdinEQb3W5tDitD1UceIcbS3if9frETHVCHL/DJBTWHN74nj5/xLIwQOG7k0AErxyFlBZXaQq J5BzbzfXNUQ4Hh8f4+gAcUMyL8s7fl+32WWe8xcFuWqv3NmbBjlTCnDmOjxX+7OHGgpy6C7tHX9U8sJJ uY06LoEOIzL5GqO4XPH+gDJ43+7jZ4QuUinbDH6Y1/TR7FP0cO4ZGf8G4EN5Bwii63Rkwgnqz6AIgPNh AJT0JSH73V5t/F4vBihoUGwlPZd9jh6IPiRQ1inA6iodFr2PJqQdlXlUJyScpIdSTtGTGcfpwfgq8o2s pHcLr0vQweDQClpUdpaeTj5AU3JO0ws5l2jbiU9pTOQB8aohGMI3sIQm8nUNDmXoYaAcEXeIum0skYTA RZc+pZCLH9Ly8isyp+uTDKYvpJ+U9CV9/POpN7cx3dbn08vpJ2R/pChBIEOnddVtXed1iFwtopEMqG03 5Mpcql6bGahsbae7TV2HSNYc6sTCBPo4PoTcclB/hkhElw7030V9tu2SHHNjcB927KeHd+yV+WEfiqyQ btK+/Lvd1+XyeyF58bGR+BdAODSwQGalaLUoWdYhyADzonquypQxcYhS7ccg12d9Dg3fspO816RTxyXJ 5LGC91mZLSlKHo+ppB4MWQ9HVdKAzWwvFqVQP5zn4mRxBMAb12IegxrbPBXsYbOZUYTJ/O+eZdlTJBJu w6AlE+wDzlw9WC1nMsQxtLZBdykLY93ggfNblSaT6APQBq7LlvHskibMZdcBcgA9pDlpMc0KZOyMNCiL 42kEQ/U/E+TAQ63e3E5tpkVYAPfqNvqOyVEu1WCsbxLImcum9KLlIm+BRw5Sl2mnmeE0cEGEzHEGgMN8 bDInmwFzbaaF0sObM2hNdiUF5O+X7tiNuZU0P2UP+WA2CC4gAnCIgoF4+W5+7zYvmkYsj6G2M8KpBQqk /KvgfxPzo2kYr+++IEoKraNHzgVz3fgfwrAVcdSd3/EZEIfxb63mW5PiQxjwed+WTFqSdYC2Fx+l0OIq CuR35KgbsS5NghsU4nRqLp/lKQypyeS3IrmWF86UCXQYFNuT/6mN35BKvqvT6g12aAS5rw7kFNQg8cYZ 3an/F0BOAwp803jZBXNI/QGYc4Ma4OoWgpzCWb9MyxM3LPOKeAT7pJ+nXvgt13bz981z/jIgJ93Hyfwd vW8NADk7uNk/6/g5+7OHGgpyA/h496SfI18GLs8I/KGoopEpp6U7tRtvH8jP+wHcr0TeHnOAekbzH1cG v4ezztF9aQxw4bxfmDVWbiAD3LjUMzQ83oIznfHBAr+D4vVDd63pkZO0Jlx3+sVU0fN8zGkV70u06FM5 V2gsH2cw14t3ys7R8/knGVyOUy8Gtnv4+oYyUI1POkdvlpynV/N5e/oRmr/7Ko2KOkSj+TfaBpXSrPKP qcfWYvLcWkKDNu+XtgFj4jCt15A4htPg3TScrxHj3BaVXaa1FZ/S60Vn6ZXMSppZwNfG8DQ+ooyeTuDz 3babOm3Np2fiD1L/kAqGuTJu3yyQ0/YNYNYFULQlh/psLZeuWES1eiAwwqHthDcPCYUHBmNqrkIZIwf1 Yfgbzm3VMIakfgxpg5AfLnyvzPqAgAOcz7jgYvJdz7DIx0H0Krx1QwN2M2BxO7zSmkR/RFAxPRCO2Rhy qSVDl8fSdHo2toJ68L5+fO6YYeLupbBBSBicQh0WJ9D94RUyt2n7xSkMfKn0WFS5dHti5oeBazNpaPBe STI8eFsxeS9PI4+FcfI7gDT1yinIwZmB6bQwK0Q7JOtdmCTTdbWbG23ZyZlWdywgDbB2O9tpn2UZhGwS LeckUn++PgRDYJYHRN8KxKEr1WXTJVp1eqR49ppPjaIm/LnjLKQxSaAxmwr+aSAH/mn+Vhh1mR4uCYDd EFfP+DhhrK8K5Ow/Kj88yd8thTYT3sxllQKcygneTLlvnOsG14A5F8ThoTSDGOZUgDcT5MQrZ8Ccumab vraVmkzaQE3eDrEKhksAOC0sWIb7F1J4gzB4825+V3hzi9cB4CD1zIlXDoIrGQWcC7qAHANcS0Py2RWl Ct09cwfdPTWIWvI/HZ1XVcTbdFlhrga02T+zanjmWJoIGFJgcwI5Z4irHalaDXSsekDOKVLVCeKgukBO I1VvHK2KBMDVEGeBnCtSlf+ZO46Nc8kOcvAeqOzgBpnwpkZLBc+Eyg5xWAcvnAQ3sHFViFPVBW+QCXAq uyFXkAPEwdhjuT54M6FCIcMUAARQYgKcE8DcSApLdmiClwwQB/UDLPFnX2xXEHPtJ3CVdvELyvqdgVmX JcAB3jiNcoUUGk3peWM7QA7nh3fzmuoT7pMFc1aaE2usnAuOZbluoDOflcKbvZtVl+X52soAZJYRLT/w wmHb4OQTNCztNJdFBDAcJM8dR2lEykmGHAa4+OPS1YouT8zgMIivY0jSCRqdcILGZZzjMnuIukVWUo8o K4XImGQ+Ly7zADUPV/4479CD1HPHIeoVdVgkXrtQrlch++Qdwj4IVNhx5jPK//jX9Gb2KXp6z3s0fEc5 g9oZeoDP55WM0zQ2rpJeyz9NE/PO0VuF52lyyWV6ltd39d9ND8TtpwGRR2l07CF6Kv2kJAxG+pJZFdfJ m7fLxPsMRt0ZvoYziPYK2k2PpxyjQSH7yYdhLfDkD2nNwffpufRTtHLvdZpXfomm7bpE3oGFki/uSQbI x5KPytizoaG7ZG5XgJxAHEOXtnFuAcQi+BoZ4Dqv3yXdspg5ArM8eHKb6L25iHx4nyEMm8NC9lB/f4Y/ /xKGuF0SsDAmrJwGMzSODNsjU4wNCSoSiMNMFGOCywXgMM9qF26n0Y4jYGEgXzNmacByl1V5/LlUxtFN yToh+w/l9nPcjjIaG8B/5hcnib3BXKyYdL8FcsCtzSPMw4pAiE6rM6g3PHDhZTIbQzf+HYyT67ggjvz4 NzAvay++Fp9VvG4xputKkGTCmM0B4+4AdLCJCIBA12u3Jcni/WvL65FzDmPnMD4O49t6r8mRfVuz3VRP HQAPY+CwrRlDHGzwgLVZMnZO7LvLjjeTMXKR4pFTG49jAjzv3ZorkCec4HL4mCB3szAHLnGCODfTMOdg Hd4x5ZeMiTPYCBJmsvNUPSBnchqmUHUvmxtU5hfd+hIg5wRvtW6Aw40yVQveWO4H4HogJsCpFN5U+nBV TY2UIxCWa4DcTIyNs97FI+cAclANgDOkHjkFN7vcIOfywplCxTJhTlUD5FzwZqo+cBN4M7pV1SNnBzkn NYLcVwtyOi4OMGd64FQmuNllGmeV3YB/G0EOnrG+GRdoQPol6o8uzwwGujSGLZbuBzlD2o2F4w/IvCQQ NyCLgYx/q/q3bV4/l/Q8sV3H890syMm9S7TSrgDmkIC4ISCnwvOye+NMmdvsQGeWES0/PaIP06iscwxX h6yuUy6D8Bw/tfMiPZB5kQZJlOoRBrdT4rHrGXFYvHSjUvjYkVXUa8dBGhF/jEYlclmKqJTyrWUf+/bi Mu4XeYj68b59+bcwwT7Um8u1H5dz6WoNraTuwfvIl3839tKPKfni53T6Jz+jio9+RCsrP6KXCi7Rkzln 6OG045LXrQ8DzUBXIuJeEftpQiIfh6EHARQYK/dQ+hmpvw8nHZYExIC2WQyEmKu1i/9ebhN2y+wNSAky ir8/gM/7weQDFHTkE5pZdJ5m7LKCNqbnnqaN+9+jRxIP0TsF16njpny6N/m4AN2IHRU0MfMoDQ3fLZGn fRgOO26q2esAdeO2DVOHDWdgxJi2nogoDUBet33UL6CY+gWW0ig+FqJa/RicemzcRYMCy2hMqNWVisn2 e/P3AWf3hO+RwAxAmhe3seiGRX45pByB5w0RrRjPhoCJTivgicuiEfw9DLV5q+A83Ru6R6APueH8NmRR r43WfKsdl6ZR2+Vp1G9LoczJOnDbbgl46L0ik8GxhIYwXAKkEHTQbEks3c/3DtDmuYi/t9iaKB/zqmId HBbobsVvYA5WjG/rwrYLiXsxF2vrebGSV67t/CSxnwA+ePAwJZh45fj77ecmSPJhtcuw3x1msZ3GnKvT ImUcHKbY0u0Kch4MhohYlflY+TuANyQCvm9bnkDd1wVy+AzuafpGCLV8K9jNQyYn3XKQM1eaX3SrHpDT kzJlApxd5sWq6upSVeHG6Y1VuW+64ZFzy+WBM6UwZ87kYOaPg7CsUAeZUCeaxWDnIDvYQSbImR45U4A4 vJveONXdXPgV5kzVB3V2sLNDnRPYQUgCrLJ3rZoAZwe5GtCmIOcAb5C9cVOIcwI3XQ9w03cT4NxygDeo NsBZEaranSpdqi54q6tL1d61qt2pADhVQ0BOVE+XqnShspzGxJldXnV54yDTOJtGG1KAg0zDjzxkPkgP gWVDdohQsHBLoc0FcionaLFLIchchpfLBKUaoIXuRxYADt2fAzIvu7o+re9gH9/06v39GPgaIl8GOAvE GFL4mIhUBSwi3Yge60Zyg5zLi6fXdTNCl6yAIAIfXEBsBzqV+UxM2YFOP6vQlQ5hJoheiSf4mR+Rqdn6 xKK8HCff6CN0b9Yl6pd4SgIdMI3biLQz9HLJNZlNYQTuUcIxBq6j5Mf7jk0/TROyTotnri9vH556mgYn cjmLQjnGn5WDDGxHaGTcceofd4z6xR6lPgxvmE+1d/h+gTxAW0+uK32jD9FQ/t69yUcZ0s7SS4WXaUbF +3Tih3+ko5//ByEcrfSjz+m5RC77wVyPuY72jz4oU29hrldM1QVvXs/gPTQ6sYoBbQ89nHiMhkUep8eS TpAHgIlh7/7kU9IOzC+/Tp4BpVz/y6x3eMYY6B5JP0F9o47Ts6mnaHPFRZpRdk0iPmV2icwLtOXQR/Rq PkNkDK+LPUD3xR+nThvzBASHRpTRxKQ9NIIBC92m3bfvkdkckIi426ZCSR4McMOYt74Mk48lH5Oxbr25 /RocVE5DtxfTML62XpuKxGPXe2uhTP01Npyvlb/Xc+su6sfHujf8AA0PKaNu63PJY22egFunVQxrhgB7 GFPXcUUGYd5WjJMbxBA3mgG318YcejashHx5O2aGQLoSdG322ZApOdpgBzyR4201pgHj723Jlxkc7gku pX4bC6jdkgzquDCZBmzIo+Hrc2SWB8zh2gaT1M9Npg4MbJjrtOuyDMsDNy9JUo4M3JxH3ssSZaJ9TNnV lrfBA4dxct34PNFl2m5eHA3iY6I7tT1vhxevI0Ne+7lsO11OFEShihOFYU3t8biAQpniSz+7u1WnW04b dd50mJ1A921nm8MgiIjWO128INxwC0EOAs/gHayDCfU9ZkbWYCKTk5xADjJBTmHODnVfO8jZoc1+4XLR LlirSzXAzSX3A3DBWw1vnAvaTLm9cC5oM6XghmUtFJAWIrccgA2ye+IgjAswgc1JN/LImdDmBG8mtDnB mx3YILtHDlJ4u1GXaiPIfTUgp8ENCnDfRJBzA4YL5EyIu1mQg9SbVh/IqXcMIAcB5OBBU88coKwXg5Qd 1G4sC+LQlTo464q8a/et+fv16VaAHNKXVHvlqr11pm4EcvpcVXaYU5DzZaDCcXwSTpIXL3fFd7m8jMu5 JCltAHQjMs7SAxlnrGjTzPMCYYC3njFHJAHwuPTLDGVcpvh7Y1LP0qCkI+Kt68/7DWPYgwbFVFG/uCoa mHiURvH2cSnH6cGsc/Ro3iV6LPc8PZl2gl7MO0evFpynNwsv0cuF5+nRjNM0hgFzCMMeAiS2X/iMsi78 G334mz/S+5//lgaH7qL74k7R41mnaGL2cbovmesHw8+wGK5zDHFewWU0JMqqv4hkfSj5OE0uOEteDEq+ DFb9+bjwFsIjhwn0uzLAdWPoggBzmEB/HEPlwrLrtBBzuW4toJfyuPzx9rkFp+m5tNO0uuoq+QQfpHfy jhFy0XVg6OrKbZA3Q9mzDI+Y3/R5vo7uW3P5ewxO/vC0lVN/bmP6B5WJ4HnDOLf7oyvJh7+LXHHoSvXd Vijj7+7dUUnjd+yn/pvyyQ/JgP2L6L6wvTRmx17qsSGbuiIYwuV9g9A+I5IVADaAQRHf6cdtHqAQEabw sqHLs9vaTHot/Qz125ZPHtzGowsXwQvd2B4M4fMdsInhcDUfe5n1HczSgLlXJ0Tsob783S58LHjN0KWK OVOfjT9GnVam00AG1eZzY6nNPIaz+Ql8rGLyXonxb0kCcwA339VZNCxgF7VbmCDrAXx4B9Ah8K/36kzq tSZb7Cg8euh6xTg6T7ZfyBShttd3ZSbdMXUHtZgeKrYZtnoEg6vYe5f9RsQqcsYBCE2Qazsjlu4JzJd5 W1u8s+MrBTlNRQKI68jnLcl++XMjyLEaQa4R5P5VQU4hDkAn8Mbrvi0gh89fBuQEgOoBOYyJ03FsgDdA E0CufxYDxZcAORxrYMZlGpp1iYZkX3V32wLwzN+vT7cC5NClisAHeOXsIKf3V+55PSCnz1jBzQnkJAgi DjN6HKetJz6noMu/oWfyrjHE8T2PPETjsy/QI7lXGbpO0mM7r9GwRCvXIDx3/ZPO0oO5V+heBoF7kVR2 5wUZTzYu8xQ9wRD8DMPYs7su08MMf/dnnKR7Uo/RyMRD1C/mkBx7KB/joZzr9FLRNXqRv/tQzlkaHM9l PqJSpu7qHsL1I4RBJWIfeYXvpQFBxdSbl5fvv0pVn/yM4fEwhZz4MQ1mKOzM9fH+5GP0HIPcE5lnafKu a5KbDl6w4fGHyIPreLfNe+jVXefptTwG0OAK2QYP3PiE4zS1hJ8z6q4L4hTkEKzwUvYpWlh+lR6KP0CP pfN1hBbTcznnaVrmMXoi9gA9kXGEXss9Td22lNAr+Vwn+LhIOYLI1yfTjtF9/L1XGVIn8vkO3l5Cw0IZ 3hjSAHWIcO3J38NYOOSgG7i9nIZH7hcvXZ+gSnok+gA9yvcLyXYBgD7bSmh0xH4awQDkAQ/aup3kuYrb TeSeW5Ut8AavHH4fQQ2AP3jcuq7NltQlrZdkytyrSCzst7mY+q7fRROiSmnAljJqvzhJxr+1W5ZOnrzf SP888b4BEFstZpvB8NVxeS49GVFCj0ftZxhLYcCzcsgh7QgSBQ9cmyUpWEZvL+PvpMm8qkj2O4zPvSfb EHjluq7IJi+2LS3nJIuXzYeBrRXvA4DDuDgAHY49eF2ejINrtTBRjg+vW9vZyEMX6548H+rD19Z0VgK1 QQAj22rYZ0yS32pmhNuGt5sTL7njxGtngFzr6dE0PiBPEgR/1SAHxmn2Zih1nRUlszXc+XpIDR4yOemW g5wpc2f3geoBOQ2ltXTzEAfVB3J6Q82bDNUHcmZX6o1ATiHODnI1AI7lNDauLohT1TdGrjrlSHXakbq6 UJ0gzgQ5QFtDIE4FeDPHxtUFcSbIKbyZ+jIgB1gzpRAHmSCnMgGurrFxJsAhUrU6WtUB5FzgVgPidGyc AXAmxEFO8Aaos8ObOTbODm8CaxG1IU6lXaw3gri64M1S9dgoBbnqHGSnZZwVvDN2MFBoUICDFDJUJoxI yhB0DRrrTJnwpqoL3OzS8XCqvumXpYsVIAeAwjLgywnW6hOgbVD2Fcsb5zqWgqGTHM9NIO6iePJwPDMQ Q6/T6X7Yhf3QpQvPnDlWzlR9IFdDLqCzw5ys52MHnP05RV79GWVd+zHt/ujntP349yWZ7vMFV+hZhrkZ lT+kV0reo+d2XqJXd1+kFwrP0WNZxwXQBscymEUdY0Dj34ngMhleRZ5RB6nvjkMCfo/zMV4ofI9eZT2a c4ZGxByUCe+RXgRlHSlMPPnPjL3uILgBARGYeB9j7TCODnVuTNJhWrH/Q3q3/Br58e+9tesizSi9KHnp ZPYHhrBB4fvIN2QfDQyvpKdST9DDKackYvWldIbF0BIaEm3lmescuJf3q6TF+95nECuSOV29A8vJi9d3 Y9B6kq9v7eGPaVL2SfLeWkzTyq5RX4ZAJBl+OfM0jeTfmVH6Pr2TUUXP5V+kFYe+TwMj9tIYvrahDKsz yq7QBOTYCyim+xkoH2XoHBtZIbM1oGu1KwMVIlI9GMoGcNszjiF2VMRueiruCA2NqiC/gBLqvamAJkRb c8x231wgoAahnUUOOc91ReS9Pk+8bgP53HrxPn39S6g7vHSrqv+Uy1hnBiKkK8HUXm1WptNEBk2/DTmE Se6HMbR2WZEpgREeS5Np2KYcGsLtaHvM5rMkg7osT6En4/bJXKpjgndLN2cX/h7SgXRZkU4PxOyT8XDw 3A3330U9GfA6L00XD1yP5ek0FDDKkAdvHAAPzgoI3aR+G/KoFQNO67kJksYE860iNYgvn2PnudES8NBl caIEOWCsnNhsDF3iZYyvgx3W+dBFbOtH+RfRXdPY5jMDAAjhjVOQE3vPLIB1Y7fwOc2LE6+dMIKLG0wp WyhzmHJiE3CLsAuzDcbCgWWavh5EbaaF1eAeJ4hzg5xm/FCecrFWLRlcBjWCXCPINYLcNwDkFOIaQa5u 2UEO+wPeIIxpG8gghuXeGZdFJnzZ1+lnCF20w7KvCsTJuDs+xj8L5CDcP3jl0NX6VYAc1CPuNIVc+gkl n/8x/fQv/0N7v/9zCr/2CxqdyEY+7hCNzjlNfRKO0KiMc/RQ3lXx0g3BpPYxJ6g3Zl/gcjYIk+anHBPv 27NFV+iZnVfogazzkn6kB0Mb0osgRQm6R7vtOCqfpT4w9PVkISWJ1g/UG4li5fWAuN6RSDnCdSWY62TI AXog7QTNLXuflpTz/eX6geAGdMkuP/gxg+Q+STvSM4jrNdfdzv6lNDDmMA2POSKBEI/EH6YXii6KB240 n3ef7XsY3PbS8soPqR+DDCbTR5coJsQfH8NwlnWC1jE09gvbJyD1UGIV9QsqkahXeLuezjxHc/Zep3d2 n6UpGefpmcQD9FbhBfIJKZdjzS29SiOjD0hKkv58/piS64GYSoY5htjNu2SeVczugICGwfwdHHsEH/dB hl2MicMYubFhB6jH1jzpTu28Mle6UWXGBwYoBEAMQnLfrbxtdY5Eofbm3+rAQNaa4anjKm5/V1oRq+2W W0EPyCHXY701tVY/FsbPDQooYvDKk67YNmwj4BUbsimXhnLbCU8cZnoYv303PbK9RCJY4alrvzhVvHAe DHmdliaR9/IkSUWCIIb+m3aSF9sNQBkmzsdyX/4tjH0D2OG77WHL2N4B0hTmkKYEXrm2vI/n4iSZ5cGP zxndtj1XZEmUKexn61lx4pVrNydevGmWva622XfNiKERGzLpTl7XbmYstZ1jzbNqBznMEDF8HV/H/HjJ M4cxdCbAqZQtTIBTObGJghy6UyF44jrPjKrFPspD/xyQczoYy4Q4+WGcjO0EbxbknG4SZN5IE+IgE+RM iHMCOX2oTiBnFY7aIKcwB4BTfVGQg8wuVvxD+TIgpwBnglxDAA6yQ5yCXH0QZ6omyLngTeQCOgeIg6oh bhd1rgPgVCbA3QzI1YS5miBnj1B1A5zCmwvgVHaIA6yZqg/kakCcCXK8DO+EDPh2jY0zAU5lApwd5BTe TNUGOAviFODUwGuqCkcIYJnwJgBRB7zZhYAEO8y5wc3oOgUA1QVGELaZ4GbClKo3QxMEAAPIDULXKAOZ 3TNnBzmrC/YCQ9tF8cQNzrkqx8B3cTzzuw0R4E2+7+paRRewXoder0AdX7/cA2w37o9d6KbVJMH2e28+ F8jp2ZmyQxwEr9+U3e9Tyfs/pZ1Xv0/X/uM/6aXckzSGf+/pwiv0eN4FmlT2ET3HgIaozHFJx+iJ/Is0 sfQDeomBCtA2If2kjIPrF83wF+WKenWVZ/NPSq3y75JVN6xIU8zZivQjmBUCYAZPnKQhYYhDvXsi8zS9 U3JZPGxYxn7D447R2sqP6Q2GNEBbj+1WGhF0qQ6PPkQTGEiHRB2l3qH76J6UUzS54Dz1CGd4YrgaGXuY 1h34SFJ2eAcBuCrJb0clPZJ6khbs+YBeyztDntsO0Ys5x2lI8G4BuIfiD0nC3Ufiq2he8UWaWXiWXss+ JfOs3h+9Xyai9+a2ZmoR/7Hgc+nJEDaEobELt2HIV4dI10cSD8uxxuzYR8NCd9Pw0L2SrLjHxgJZnpxz SjxtXTYUWjM5MBwBuJB6BOPqfBiQEMAgY+G4HfVYmyvbAGuAN5W247ABODaiaJuuLKBJDKWIYu0vwFZC SCkCj5zYiyVJNHRzHvXh3+i6NJnGhTKYrs6UuVp783cwhg6zMQDIEI0KsLt7cTa1n5dEdy+Mo56r0qnH WgY5tgWAs+4YN8fH8+PP8MZBADmMr8MYOtjLPmuyaMSWAhknB5jThMEYZ+e3Jp28liaQF/9WWwY/BETA M9eR7Wcb2FH+DBvuBrl3oshnYSrDXrxAWot3LWjTMXJi7wFyU0Oo55JE2ac9b2+lnKAAN9UVMOliCjvM ObEJpPwCb1zz1wOp65zoaqYxuOdmQK4GW5nsZUCcSpmtEeRcagS5RpD7OkDODnF2T9y3GeTMKa1q6CsC OXjRAGEDstE9esUFZPUL3zG7VNUbZ0Kgub/5u3bdapBDBCuCHvqm8H5fEuTMZ65C2fHgMuF/5Hu0+PAP 6c2ia5R05Wc0e+9FmrfvfVp06BOaWn6VXiu9LmPeJmSfo3uyzskMD+g67Rtzgo9xgrz4OF7R1py/8Boj ZQ7UK7JaprdZpWUfY0UlCTCDHKJZ4ckbwMcTgAvnuuMCuRd3XqJXck9Jt+nkwnPkHbxXPH8Ts07TixkX aEbxeQmQQAQskggPYliazEAFIATcIV/cE6nHyTe4nMGuknpzPUS+uUeTquiBpMP0dPpRmlZyhablHqWF u8/JPKp9gkolAGNc1D56Ou0kPZ5wiO6POSDHeYqh7pHYffTGzvN0f0QpPZZ4hKYUvyft5Ms5pyXi1Gdb sUDjwO2lMhcrptF6Pv0YPZt2lB6I2i9A14chbWz4fhoduYd8thZS1y3FEqUKmOvH14iACHSbwlMHjxza VJ2LFSAH7xzGyWFMWw2QY6F990IXLuYlXcpgtSqJno6slOAGQCO6TtHtCk+egtwwhrN+m7JpTGCJzPAA b1qXNTk0mq+j05I06s/nB5BD9+pj8ZhOMoU6sjozuPXB1GFL0wXsEOGKBMPD/YvJdwVvX5bqBjl4/jot jBdvHYCxC++LKb1gI2UsOdtReOz8GCK9+ZyQekRSmfB2RLj2XJEmgIYEv7Dhaq+RZQJRqGCALmxTJXGw A8i1mhZK3RfECsh1xG+5mOHLghyYBl64u17dSl3mxFOTKbWZB/raQA5uOvtO6FJVmQes9WP1gNyNYE5d k3V1rZo30w5vpuoCObzrA3U/WBvEQfWBnFPXqh3Y7NIgBxPeFOBuBcjdCObsQIfPOoZCdStArj3GcGCM hiEniIMU5G6UO64+gHPLBm8mwCm4OcoFbyIX0JnwZgKcCXGQCW521QlwLim83QjgILNLVeHNlDPEKbxV yzTkWAbA2UFOocAOCg2BN1PwxtUCORfAmKCmMoHINxWJfi/cAN5qAhnUJ/OKW4C4gTnoKr0igGXBXvV+ eEeOOEAcghsAcg0BP5XTOVkgxzCZzufgOm+na3UDHd8Tp3unwnZ4zSyY4/uXzOtcAQ/6PKSL2/as3PDm kuYFVCGoxTfeClx4eOeH9O7eD6l/0mnqHX+aHmZIO/ab/6Lpe75PTxVdpodzLjG8XaB7M85L2pF+8ehW PU794k6TX9wpGpBQRcOQhDbtFD2QfI7G87GRhsQ38qDMBCHlHGU3AmWdAS7sEAMb8sRZXjpAHMANACdj 4qIOSbBCD96uQs45zL8KKHs27Th1DNlPM8o/ksCDQQwlYxP5esKqxEv3bOZJernoggQ0dI/YT88UnJWU Jt2CK8gnpIIe4PN8NO0EdeG67Mv18/Wi69Q7eI8c650S/n7KMdp86H2ZZ/WZ1CO0svIKvVZ4kV7IOkov 5GJGh3P0YFwl3RO5j0ZFV9BT2Wcld90rWWdoQiwDXtphmpx5nu5NrqABYaX0SMQR8guqoGERlTQyai8N gzcwbI98/430E/RcxhEBqq7rC2WaLYAewM17U6F0zQLa0MZ68h9j5IdDBCpy0CFPJxIEo1sV4+FMgBOI 4za84+psOU7ntTk0AJP4M5C9XXCc2/E8GhtSRq0XVQ+/wVRd6JLFfKePhZdIIAPyw6F7tdcathn8jhxw 6F7FGDkfbutHbckhv7VZ5MXbvVYzVPJxWvM2CPtAsGsdGMAw5+pAbuvhhcN6j4UJEgiBd3j8OjLUwRuH +V4BcE1nxZHHskTxuMF+IqEwcsx5L2Wbx8vDN+RJ9yrywCHFiNprsbWzY2jsthwraTDLDnJQu+kR1O7d MJmztQvbX0y+32xqTZgTGSBXF8wpu2h36p2TtlBnBlnhGeYdvNuZx+QhOyvVBXImc4lsfObYtdoIco0g 1whyjSDn1tcIcg2RE1zZQc70zPVhwLLvB+hCdyoEoPuyIAdPngRKNBDkJNXKDWAO9xAgp+lIbiXIDeHv jsq8SG/t+YQGpSO1yHF6tegKvZRzmoo//QW9Xvoe3Z97kUYkn5JZHAbGH6GxDDL3Zl8UjUo7TQMSuQzF cpljEPOJPCDqG3WURjBcjUw6RaNTztDwJIY7BjS/qAMy4T7y1UkKk6jD0j06kNdhEn3fmCoaEn9MPHMY K6cCxGGcHLxwmEEB9QvghZkURjIQjUCXKsMggikmMIA9n32aJhe/R/3Cy+n+lMPUmYGnWxC8cPtoWMwh ejH/IvXYvpcGcZ17o/gK+TEYwsP2cMoJWld5jabtukiPpjOghR+g2TtP032hDHq8HdN7IYXJQylHaGDQ XurLx3ucz8dnSzGNjCinB2IO0KvZJ2lh0Xl6NuEwjQwvpXvjD1LfzWXSdQpgu5fPFx69+7he+/rn0ZNJ hxnqAIaVAnAy08PaXJkRAuPfAGKY7QFRqh7r82V6rgEBuyS6Fd44wJomALaDHLpevbg97rEph7oxaA0P KqOh24pk0n2vNdnUZkUOtXXZArUJQ7buohei98jYuB4bcmXdoK0Mg8uSre5RBrk2DGZIBPxMfBWN5vay w7x4tj8pErUK24WkwfDYKchh3RB+Bn58rt34nDAurt+GQuowP5aBEAEWqRKtCpCDdw4RtAiAwHJTBjmM ifPkYyIFSftFidSONZCBD0l9AXPocoU9hr0Wmz4rmh6PLKc7GcycPHIQolvbTg+lDnxMgBy6V+HJ+6Ig B4BDd2qzN7ZLShMT3sxllclDdlZqBDlDjSDXCHKNIPfPBznAilsugHGCGzsUCQRlWHICKHOdygQ5QJWC 3KDca9RXYK56e98syws3hLcNzAHEXZJ9nI7rJPM8VTcLcuh+VZhTOd1HQJymI7mVIPdg/nXyjT1MT+Zd pf78O/fnXqbJ5R/Q6MzzNGnXZYq5/Dk9tfOyeNswTdcQdAfzd5EzDnnkMKUWvG9DE46LxqSfo7EZ52WG hwFxALJDMv0WZnqAx20En+/otLNWt+wOJP+1vHBIOwJ4w3cwowO6UxEEoYJHDuunFF2gJ9NOUu+wwzSK AWli7ll6PuccDcSxWP0ZIofsYCiKqaSn04/L9FuPpcGrhwjVvTQs9oikMXkl94zM3DAm4QS9XXaVBoRX yLHm7b5E66o+lqCDsVEHaWzsQZq684RA1iPw0KXzfQgtk+UnE4/Rw3GH6LnEKln3cPwBGsOAhvxzc8su UuCR9yj49Me0rPgiea0vlmAJ5Iq7L/ogjeLzwTRg/RkGvRjcHuTjjIzYK+PcMFWXJ6/rsi6POq7KlZke PBngOjLcAeiwP5IHIwAC29uv5m2r8qkTL0MmyCFCFhGtGFPXenk2Tc84Qe2WZtMEhpx23N6rHVDbgNki +q3LpLGBuyS3XF/+HrYhp1z/bXky8wLsCgIvRmzbKePnuq/l31qWIePlkKRYPXKYxQGCLWs2N0HSiPjw OWBs3OiA3ZKkF12zbRYwjPE+CJRAVCu6XXssS6ERDI8ANESztmJYg+3FNF6tEMCwKI4hz4I4CN2ueEfQ Qqt3GaKmR9Dw1cnU5O1wSS3iBHJd5sRS62nB1I7Xe7DtRfeqTtdVQy6+qA/k3BCHwIa5sdTktWqeUdmZ x+QhOyvdUpCz72SHN1WNH9MTsJ2YedKQeUH2C74ZiKsL5OwQJ3IYG6dyAjgT3uwA5wRyN4I5HcBZP8hZ 8GaqPohDpaoL5LSCmqoP5BTeTNUFcia4Vcs1NZcL3gBoTvCmUoiT/eoAOFVdIFffuDjkiqsGOeSNqy2N VFXZAa4uiPOsY1ycwptddoBTKcCp7ACHMUfQjQAOyxa8mTIgzmXAFeIQrQhjDoiD7CCgAjC4ZQOMGwlQ AkhB1yDezfFidpkwZEKSHZ5MmVBWlwBr0sXKwDaYlwdkAeiuUt9sBi6Gt6E51wTkAHzqtbMfo67fsp8P JFN78bH6ZVyR89d8dk7XbJd6K/0cgA6fMeWXBD4Y6yEFOoFsAJ7x/OxAp8JUYCMzz9GgZHjTTsgyIG54 6il6be/HDHWnJPL0ibyztOn4j+j13VdpfMYFiV7tF3+MesUclVx0fROP8/JxGQ+H8ov18LJ5xxymri7v nF90lczmMCKhisannpBZH+ChG8wg2Ad50mKraGTCUbo37ZzAYH/8wcD4Udc8qxAmzkeX7POFp2lECv82 1wm/sEp6u/Q6TSq+Itu6cV1F4EPPsArxlCGg4N2979Or2cdoyi5+XoFlNATnwuf0YPwReqPwFI1POEnT Ci7RxPwrMj8spgEDkD3CwDYq6gCNitknMzu8mHdKxry9wfs9wICHQAfAF/K+AQgnpRygidlH6PX8U/Rc wiGaU3yBzn/+H1T4/i8p69L3qfTDn9LD/Nu9QneTF9ozjFljIENaE8zH2nVDvnSTPppyWOCp+zYrvxxy wgHgxkczEG/Mox5bisjT1dUqU28FlLjaZMAct8sugIOXDuPuuvA79sc+CGzowu3+6Ig95L0m3QVy/L4s TYBqbChD5ZpM8lyVKTMeSFdqUKlAWe+NuTITBCa277mhkGEwme7ne4y0JL7rcqjtnBTJUTfUn7/nAjhT LeZaMzdgBog+6xH0kCRj77ryb6tdRD45eOQ6LkyUKbW6LYmnIRsLJEEwYA4Rr5jZoftSPudZkdRhDttl dLuyDUYkazsGM0vxMjYO3rvey605WQFxZtQq5LckTt6RYw4euY6zo2WcnMkRIgPilDdMkMN78zdCmWUC qNOMSIE4gJ2dayCTe1TKRMpK6gSTd5OtXKrBXzZGgxpBrhHkGkHOBnFfJci54c0Au28KyNUAOJUNIG4k wMdXAXJOUKUSSHOpN8Nbn+yrvL46AAJdqIC3oflXaXg+v+ddF6CDJ+6bDHIQAh8G8r3UsXK6/ouAXI+4 w/TQrvekTAxkqBqecZGe2HmVBiedosd3XqKhSRhXdpjuZciZXPI+LT70EU3d96F0pcLjNjzptDWdF5dL QBy8dP0YDtFtCi9dn8hjEgjhE8lllIX0I5hsvxuvx/yqfaKqCLnmRjK43cfnjXF4wxkKMbH+AN4+iH97 KEPWkPgTMl5uGMMi9n8s8xANwzypiScZ9o7IXKvPZjJIBnP9DK6gkQxy8M5hntWJuy7TQ4kH6fVdlyRp 7+QiBvfw/TIlGMbKTSu6Svfw78/f/Z54wZ5OrqIH+Bwm5fE1xh6kQREHZIL8exNP0JTC83RPVAXdk1RF o2P30/0Jx+jFrJMyNReSCs8ovUz38nWOidovs0lkXvsJnfzsl/SXv/+DSq79gMKO/ZA8N5VRF3RRcjvn sbHYmrJr4y6Zsgsw58nQ0mV1ukTZ9tyMHHF5NGD7XurFbRmWn0o6LulDkD8O4IY2F9MnIhIV7TLaa3jk kGcOEaqYcxXXhSCG5guzGUJPkQ9D2IiQfdR+JdsAbvMR/ACQG4fEy2uyCVN4Ia3IuO2F1J6BafC2YskN N3h9tkwPhshWAB5mXuiyMpntRrpEvXZgW9RyUToN2pJnpRcxBJCTMXGLU+gRvq/dl2G9BXftFyVKgmDM o9oM9nN+PLVn9V3LMLqEv8NA139DAbVmyJLgCQAXgx6CH5Bbru0ctqFsgwFrADckDIZ6sn3D8e8NKhBv nJNHrt+KJOmdQ7QqxsnBk9YG4+T4s8kS9YGcckizt4LIc35C9Rg5sIqNayCTe1TKRMpKXwvIfedlXnYC OJUL5Oxdq04QZ16YebH1gRz0dYGcHeYAbnagu3Vdq0n8nlwnyDlBHGSCnAlxKieAcwI5QNyNQE67UesC OXukKsZ4OAEcZELcjUDODnF1gZwd5gBqCnLVMFfdpdqQCfJhHEyYs4OcCXH1wVxdIOcEbyqzO9UJ5BTi aoOcAXAsABsMtnanmVCHyfIBcjDuJgAovLkBwQCK+qQQAmn3ISBOuxAVWhDIoLDmFNCgYOQETSZMuQVg s8u1zS+Hv+fqNgW43V/8Hj3OxvsRfh+R/750hfbLvsbC/nwu/N2+DHsQvmeXXyZDFwvHtp/TgOzL0l1r nq9eE+Z/VZkAp3LfL0Pu+8rgZnax9uZnI12qtmejz8sJ5PQz3h8qYIjjsuKXwqCSdY0mFX5EvinH6Z60 4/RA3hXJFYdZHAB2EzLPS0LgWXvep7n7r9MAhs1xuWdpPEPdwAQuY5FHXJPqW384+nAZw1g7AJ2Oh4PQ xYp1AD+Ue0Sy+oZXynReZv3APkhlgumzxjIwIpBhXMJB6Up9Kv8ITcg+wvDGz4xB6z6+lqmFF+lBjFnj Y+LzcIbAvlEnaHLBGXoy5YTA3JtlVxm+DtJLJdcIMzf04no6IukETUjYR+8Un6ERvC3s5KfUb8c+msJA i0CHIWEH6LXC05Inb0r+eXqWfx8g8lAqw2XIQXpjJz9bdMEmHqU1FR/S9OwTNJsh+AUGY3jmPvz5r+mn v/srJZ37mI69/zk9zLCERMNo0+BpA8h1YIjrtHkXdV6fT1783mMrt20Ma/cknqLhYbtlyq5hgSU0PGQP eazbKTM7tF9TSK3XWkAn8MbwhblXOzKcoesVXaI4FpL7wkMH6Bu8NZ2GbyqiCaF7qcd6q5sVueXarUin e7bvIR8k8MUk+bx/m0VpNDawWMbOYVqw4f6FNHST5aHD2DfM2vAQP7cWCxG0kCDTenWUAIYkGe+mXatQ B/4O1J3BC3nlMMUXPHGwm+rYALwBHhEc0JzBDMDXhgEOgQ3t5zDs8XbM4AAb22RWlKQcGboWEasRAoXo TgWkAeAAc23mRJHHPIbMeVE0iu9D63fCqM0sgFxN2z90fSbdOXWHfLcDf9eDfwdTeYEVTJawgxwE/gCL oDu1yRR/8pqXQs0wW4OLW/BuMo1KeQcymQhSVhJ2UoeYA2OZIAcmMxmtwV2rjSDXCHKNIPfFQU4hrhHk vnqQq/bMWRAHj9yYne/TsxWf0NRDP6TXD31K9xR/KJ45c5wcgA771yXLawfVPg8FOSzr+eo1mdBm/wy5 75ch9311gRy8cYA5TOGFz+a9h+oDOZU3l5GxfK0oGz5JZ+mZne/ROIbLPmmn6Jld12kkZkAAKHL56Bt3 nO7LuUT3ZZ2hSWXvSyDECwWnaBA/3yEpJ+neDCsNCeZk9Wb4Qpm1ym6VrEN0K2AOXaEIagDgoesVgQ7o PkWXK8DNBLnumFs1nOsSxspxffIOq6TeYXtksv6HC47ShLxT9Nauq/RgxglJB+J/+jN6bTc/26TDktOu X9QBGhBRSfcmVckk/Q9lnqXHU0/R87mXaND2Cnou9xz1DOK2gOvxjsM/oMk7T9E7DKavlZ6n+xjonkk5 TPMYWp9JPUbTdp/n3zhFk7NOyxRf2C7j8rLOkf/BH9Drqadlxoa3809S5y2FNDr+MD2WeYqW7b1Gxz/9 FV372R8o7tRnNCGugu6P2ktL975HL6QeJs8NDFobuL3jtg/drJ03cpu4Lk9grWdAKXXjtvN+vl8P8++h OxWeNa/NhTJHqvdGBkC0tzI+LtcdmYqEwm0ZkjDtF7pM4clrzYDUZnEyvZN/hXw25pKPP7e1K7NkfddV 8LxxGyfzpjJIoc1nuwBYGxu0U4IuRjB49t2QTUO375ZxcAhygDdtAG+TdCUMb0hH4svnBODC7A41QI6/ g+m5MME+ZmzAhPnIK4cxbwpykoaL7SfGx3VakChTeWE9ulPhhWvL9tFraYrMq9rKZUf7r04lH6RbmRMt 4/bgqQPgQUgmjJkaWs0OJy8GTKQYkZxzDHMtpkeJYPMV5NDl2l4CHuLkHaxgskRdIAc1mxpKHnPjBOLA LrdPYZ5hRmkEOVYjyDWCnKl/JZDT7lRVI8g1DOScZHajOoGc5WWzPG2D867T0Lz3aELJhzSl8ns098hn NPXg9+nhsk9oXOE1GlFwlYYXvC8eu2EMe0Pyr9Og3KsSJGEXgBAyf19/CzCIVCZyTq7zdF+L6zohBbyG ghygDTAHgAPIAeg0Iti8//WBHD7juaOr2weD/pMvUDeGqQXHP+dycoqB6zA9upOvMe0MDUnm3+Dnjy7T QXy8B7Iv0UO5F2hi/hl6Ou88Td97me5niOuTeJJGJZ+me3j70GQuUwxz8MyhbOPdO9IV6BB5REAO4980 zcgwRLsy0HULMyCO5Qa40INWmhJe7hNtBSbcl3OYhqZU0ZMA6aiDMh/qtN2XaRAf+770E/RE1imJUp3P APYkQ/WjmZdpfOJheiL7NI1JPEgj4vfT0B1HaHjyPlq46xoFHr9MC0ov0Jqqj+jeuCM0a/dFvrartLbi Mm0/+j1aeeA6rWQoW1BygabvPkMjGSh7Be+lXuFH6IW0czQqsErA6cnkAzI919MMl29mHaAFZVdozaHv 0YZDn9Cyysv0YCxf87bddG8E1+Nt+2Qe1VllH9ADfC981pdSOwY45NL03FAs3a09t5TKhP0e6zJlmjEP bnORJ85n8y4aFYyJ8Mukje3ObaEVscpt+MocGh25zxofx+0dQAtDXSbEchu0KZ+GYA7YFbnS9nfj9rov gikwXm1JliQXBgRignxMr/XEjlK2H6nUi89r4JadNCriACGFCGzEwC351GxJInVblCNj7iQ6lSFt4KYC ajOb4Yztmar7Gj7HZYkCXR0Bdmyz4F3ryPYKMztArecx9IkNTCCfZSkS0NB8nmUnAXwIjuiMLtrZoeTH 96HN7ETqszKN7p4dJfu2YRusEIcuWi+GS4zHazErgtpOj6Z7t7Md4W3wuiF4AvsD9IZtyKIm77CdZzaA Jw6RpgA+gJ3JEnaQU/bAem/+LeEY5pLb32BuedNilG8UyDlFrZoHkQPZf0hPwIA4SE/WvBCnC4VMaLNL Ic4EOb2p7gR+Jsi54M1UXQB3UyDngjdTTvCmQoGtH+R0eq6aAKdygjjICd4gBbi6IA6yQ9wXAznXuDhj bFzDQW6XWwpyDYE5hTg7yJkQpyBnl8KbAJyDAG0qhTc7xEF2eAPU1QVvKkCbOzqVl90JgQ14U2k3lTk+ zoQ5BbhqeDNlAZwPG02VQhwkRl2WT1pddInVhh/SLrsvBHCucV4CIQakAF76ptYPbaZMYLNL4cmEtmqg uiKC56w/csgJwDGc5V2lkTvfowcZ5Cbu/Zgm7/8evbzvezSh6CMau/M6gxwr/33RsPz3RPiepiUBwElO Onx2LetvQRhfNxiBE3wuGIOnsIf1TurHIALpMvLP6TqAlgrj4iBAsIjvtXav4h3PSp+BG+Lw3ADhxjOF eiScI9+E4/RowWUX3J2UCNLni65LxOqwlJP0YM55GphynqHshOSY8+XyNCCBwY63Tci+QMP5d9/e9zG9 kH9BolsREOHHANQ//giNYAAck8plAd45Lrf4I4JACMCddL+ysA3dpoA4pBnBPKraBSvRrREHRb4Mf+6x dAw7A6OO0aM55+jx7GM0ILqcnuTzxGwSGBOHnHAYF/cUg+ao+OPkFVROD2XxfglHZTqtB/jcEbzwdvF5 mph7mt7dfY5eL7hArxZclIn3UxDgkHCY5pacp+CTH1PMxR9TwNH3KebcZ/Ry1hHJK3dP3AFJGeIdUES+ /uU0OLKSXsg8xW0Br+N26K2iC/Ry9llJDry47DK9zFD5wI4yiYJdvueSfL87t0lIQfIAX1uHdWhHi2lQ aDm9ln+anoyrpO4bCqmLf5EkLR7uXyFdp5iTFTD0YNIRhsgKaXPh/Xo0iaHYv5DarCyQtrkNJs1fW0De 3LYODymT6bYQydp2ZSZNTONnw/cH6zy4TceMDQP8iwX4ZKJ9BkF4ztDlitke4GG7J6hQQBAJfEcyCHkj iGIx26jFGXRvWLl47SB40dRu3RdaSi0XpIm9unteCvVYk8Xfy5LjYfJ7ABmWh20rJK/lbJv4swDc/Hh5 hxcO+7RkW+q1Ik3SkbSbZ0WtiubFSqTrQLYx8M4h0AHbIXj6ms2MknQkgDkZK8efEQQxLoCvhfeFt83U GAbS5jNi2c5Hytg4gBzUmrlBEgqrg8glN2swXzSZGiLJfptOsZjEzikNATmVyUZuZqoD5Oz8ZeezRpBr BLlGkGN91SDn9sL9HwU5THAP3QqQM7s7qz1iFmjBA4fuUoUydJ8qyD1e+iE9Wf4xPVH2Cd1T9AGNYZBD 8MOQXMtrB4AT+HPBHI6D4+G4KjvIAdowLRjAz4yC7eeCM6gukLPvh3laq8XAxpKIVRVD18CMSzQI2xnm AHcQJtcXsHM9UxXm0LXm0T1BY7MvUn8GHF8GqYFJx+mRnZdpXMYZCaJ4aOdVSfzbP+msgBz2R3mC1xZd pIN53YScizSEwW1y+TV6LPMkvclAPJZBaQADFLpihyafpvEpfLwELnMMaCbEyUwPvA7dqZijVRL98mfk j+vP78glh9kcBsUC1qx1mJGhNwPdgMijAnKP5JygPjv2CLwNi62i+xgeh8YcpsfT+NhcDxH1OZiPPSbm pHjYEDwB2BvN5zeCl2W8XdxhWrr3As3YeZK2n/mUfvCnf9Daysu0cs9lWlZxnRaWXadpxZdpxb7r9ELO KSs6NfoAw1AF9WFY6bGlnHwDyyTXHtqgCalnaPouTNN1kiZmH6c3Cy/QrAK+JwG7aHLOSXon5xg9knBQ 2rkuSB/CYDSC24sBATvJy7+U27QyGszwOYV/6/WsM/QgQ2KHTTlWu8jtKLph4YkbHLibHk48JrnkOjHI IA0LwA1A1m5VlnTBSiTr1iLqG1Amy0+lHBBo67QakLeTj1EsINeF4RDbu65lkON3pD1BcANSk7RdnErj thewbcgQL9zo4CIBJPT6+K7PpZ5rs2VfqNuKLLFbGFc3fGuBdAmjd6nPJis5MGZ4kJ6mRehtwkwPKdR3 baZMpI80IxgHJ/aOoQi55ABnsKVtGKgwxyqADsmBZU5WtpOIWvViGByywUr222xGhHTZwqPWdkE8deXf AJghCXCrmQxkDGpe8+Oo7bsR1HaWNQYOEAfv3D3+BRIs0e7dGGqLcXJzoiXgAYmBkbJEkgMjD50d5N7Y Th4Mli3etIIe1Atn6hsNcuLGMw5i/5E7Xt0mbkGVHeTsFwA5XqztpphSiDNvrNxc3Gx1hZogZ+omQc4O cRC6Us3uVFNOAKcyQc6EOOhGIOcEcNqdWle36o1ATiHOCeRMeLPLGeYs2btWRTaAUwHkkDvOzB8HYLO/ 1wVwKieAg6q7U7UrVWHO6FJ1UF0gB3gDrJkyQc4OcSoFOIU4hbe6AA5eDLNLVcHNlEJcXSCn8KZdqJDm j9NuNnxGlypADkYeAKfdqdql6gRsdvkZAGeHNxPiBORcEFcfyDkDW00ptLm9ceIBu8yAZUGUSoFseMEH AmUjdr1PE3Z/QBOKPxCgg8YXfijj5mScXP518eINzgO48fcLqkFO3yH1zPVFtKuKYQzrdB8T0HAtuDa9 dr0Xdd2Tfmn8PZfUM6dgpzAHuBuMWSnSrc/quXMU4I6feb/kk5I3zi/1LHkzxD2Wf5keKLgqCX4Bck/s ukbDGZB6M4QhUbBZpvox+KGLFXnixqWeov7J52kKAzHGn71SfJHuSb0gYIhxcYA4pDIZzZ8RWdojio8Z baUpQaoRBD7A42Z54g7zZ/4OQxwiVBGpiim3BscepiH8u/DGYYYIv7gqeiznMk3KPS+zHdyXfEpSjTyR cYSG8nHe2nmFBkeeoBlF12h08mGJOB244yANiDpIY+IO0iNpx+hR/g66f98puSjRqS/kXqDDP/gDVX7/ ZxR9/Do9V3ieFpd9QAv3vUeL9lyh5Qx12w5+Ru/uOk338TEwv+pjSZXkEbCf2oYV0YyCiwK4SGUys+gi rahkuE2qohHBu2g5HwPdsA8l7qXnMw7RGwX8DIK4PdrIIOi/W9rGfsGlMh2Xz7YS6SIeFFxGI8Iwl2sV TWIoHLWd28b1edR27S4Grl00dEsxDdy2mx6L3i8zNeDP89PJB8mToU/mWWV46sNgCLBDNGt/Pu6LaUeo N9rJtVk0fAuD45ps6rqpiG1EqqQN6b2lRGaMgE2ArYDt6Mjw9UjkHpmEvwMD10MRe+gujH1bninBHrAZ mNYLwRHeqzMt+zU/nnpsLKSu+N0NeTL+DnnlxI4xyGEfFUCsPwMhxtMB5lovTLVyyvF6HTcHSbcr74+A BiT4hf3FZ3TTdlmaQN0Wxsp6eOJ6rMghzwXWBPzY7/+3d25PVZVhGL/CtEzTLDuMiuggsFEgUhCMEkhM bahpshvRMWLEQ2liOnnIQ5KDoignZbM5KLgVt6AgHkaJ4iCZOgqC03T4C/onnp7n3Szcbmmm6cLxgotn 9tqLdfrWYn/fb953fe9jY3nOUY7VmvxQhudzCzFuBcWxXJMjlF6dv4/3lmBozg7rig34pn113GBOJUnG rFJUzs8aft4owHOEt6mEUkFcSNbhYRlF+q8g50CcFMhLkjFUEGNJjzFYUGpVGgG5QY2A3JMA52gE5P4f yAWnU591kBsO2oaTQZz0FEFOEsgJuiQXwUngJRBz4E1ygExSNG7B+QGk+AaQ2NA/tDyPsKa/xTdQZ/u5 be9QlE0SnGmdc3xHgkadW9voMxjkAlOrKkUSqMD74Nwbaeh+8D46cu7vUGq1SsuEMwKcy3PLX45E6/Us LCL3pPQ8NQM17Vw/ppe183s3MrwPMIswk3GO7eaxYghdirYl1PF4FV2I47EFf45k36WJDwYuZ+4juaob sfIVJfgkE+5WNvcjvrITSbWESsKXzPPn8FyL6nuQeuqWlRaZV9Fp54kmqElzuE7wJqkQcFRpOyJLfoSr +AZmE+5UmkRSujTO044PCU6fnua1ymievxV5pb5fTUDk70/RwdjSa0jhNS339do+qiUXoaK/hLA07p/u 6UZMyWUr2pt+8mcUdPxhadWiW38R2Ppwoe9vpLr979pl1t1EOj8XlF8z8EsgSCaWtyGzth0uAlkqj/dl 622sbuwzE/39nX8i29tlhXaXea5ine9XzC1qRWKRD2nuK0h337DJCHr/TbXjZIY/meAzlQAmy66ogy3m 5qBi6krVyjs1/tAFfMTzLK9h2/KbrH9WlkPFfdPYBhXvFbAls43R+RcM3CZvY5++lX38t14kHWzEgqOt ePkbDxYRaMN2qJ+uQ9huFRRu9Pf3ei+O+zjjgsaSN9m3pxw8b+OIZrMuZvte3FKD8O01Vipk3NdKq1YZ yIURBpViHb/RXxdO9ebC2e9P0DYbBsexIJBT9G022yCgE5hNWlcBzWbVepnkOzXjBHNOhE7v1ykipzIi mjgxdm0pQvOqLMUqU/wxa0usZMmEXH/WTBqd4y/mP/aLYqtHp5St3n9zNGd7NV5YU44JOSWEt3JM21SJ t3bWIYGSmf747GMICfBaHb3ysEXixmT5OSQk69CwjCKNgJwaO8yNcTQCciMgNwJyTwfkBBDB4BYsBzSe dkTOVd/3GFwNQZvAy5EBGKGO4JGkaNz5fiRwWcCWfO6haW7DA4O4OL0nR7hR9C7qdB8i63st0udE/zSJ QfCmczwCRb9mE9yCQU7LDsi5agh91Vyu5bX/C9AF3hPHZ1by19570vlBUDfLrRmsj0BOgOY8P6VYHel5 zyQoqdhvGLeLKu8243s9+6W+PpuB+k79TSRW9yC+lpB4guBQ+Yv9jziSBZesuGL5jOMIY2neHkTzfG9X 3zQj+4RTd7G+dcBcDbSsdGkMjysf0qyLvWb1lVFHoHN32CxXScV/ZfsliBP8ORLQmeNDSZt9uvi7iCFg LfHewSdewuuRSxaFk+F9yonrCCtsQ3RpM96t72QburHizD0ke3rgklPEYEQuiQCXeeo2MhvuYObRq1jv u48DHXex5acB5Lfew56O37Dj8h2sanpo0THZfyUTxGTxpTImcn6Ysb+JYNSCD9jmWPYJ3135HeEEnvfK 2pBV2WozTJdUd2FN431k81o+86qAcJdNxlAx4djCZkz/4aKVBpnCfmvaPh9C9/rgOnQJkQXNmLTjLF6y CQgyw29A2N5mROxvxFxew7Kq61jquW4Ru1e2ec2XdWGhDxnH2zD/cIsBYUxBE2bs8Vl6U9vkNt7Fq3nV +JgAO3On+us6xOzyIXJvA8eMSkzczH6c/b9SrIFjw2uEw9QjF22cCWf/LFP8sTzOwtIWwpnfZ1VRNG03 XfC0yWP+q3H5DXh9s9siZor4qY7bcCCn7xE7TyKM++v7lI0cswhiVm9uQwUM5rheY6Yf5oo55sq9ocze m9OkCtWcU5pVkyNC82psm1CeW1ZhOobG7xCO+TLQlxNE6oFmjF4fUBg4uwgReW6MyuH4/Pkxe0dOadn4 XbVI+b4eUVvdlm41i69BkHsjtxwTVxciZCUhjhq16lkGud34B+aXO5I36oUUAAAAAElFTkSuQmCC AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA IACoJQAA7h4AAAAAAAABACAA6iUAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAADDDgAAww4AAAAA AAAAAAAAv5UA/7+VAP+/lQD/v5UB/7+WAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+UAf++kwD/v5YB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/76TAP/Alwv/xZ8Z/72SAP+/lQD/v5UA/7+WAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAf++kwD/7eG3///////Orj3/vJAA/8CWA/+9kgD/v5QA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAf+/lQD/v5QA//Hoyf//////0rVQ/7yQAP/AlwX/yKMj/8CX Bf+/lAD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/76TAP/DnBb/zaw2/8WfHP+7jgD/vJAB/9a7 Xf/BmQn/vpQA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/vpQD/7qMAP/LqTT/7N+y/+na p//EnSD/vZEA/8CWAv/AlgL/wJYD/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CXBP+9kgD/7N+z//// ////////5dSX/7uPAP+/lQP/vJAA/7uOAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lAL/uYsA/+3h uP///////////+fYov/EnRX/xqEd/82tOv/Vulr/vpQA/7+VAP+/lQD/v5UA/7+VAf++kwD/xJ0S/8+v Qf/NrTr/696v/+zgtP/Fnxv/v5UA/72SAP/cxXP/9e7X/76TAP+/lQD/v5UB/7+VAP+/lgL/vJEA/8uo L//j0ZD/u48A/7uOAP/Algv/wZgQ/7uOAP+/lQD/vpMB/7+VBP+/lAD/v5UA/7+VAP+/lQD/v5UA/7+V AP++kwD/vI8A/8CWA//AlgL/wJYE/+nbqf/awWr/vJEA/8CWA/+/lQH/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UB/8CWAv+/lQH/vpQA/8GYCf/7+fD/696w/7uPAP/AlgP/v5UB/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP++kwD/w5sS/8GYC/++lAD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/76TAP++lAH/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgH/v5UB/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAoAAAAGAAAADAAAAABACAAAAAAAAAJAADDDgAAww4AAAAAAAAAAAAAv5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/wJcE/8CWAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V Af+7jwD/uo0A/7yRAP+/lgD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/72SAP/Yv2j/6t2s/82tPf+8kQD/wJYC/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP/AlgP/u48A/9K0S/////////////n16P/DnBL/vpMA/7+WAf+/lQD/v5YC/7+WAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlwT/u44A/9W6Wf////////////v5 8f/Fnxn/vpMA/7+VAf+/lgD/vZEA/72SAP+/lgD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQH/v5UA/7+VBP/k05b/9e/Z/9/Kgv++kwH/wJYE/8GYCP+7jwD/3cd6/9W6 Wf+7jgD/wJYD/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/76U AP+8kAH/vJEA/8KaFv/Mqjb/uowA/7uOAf+7jgD/17xh/8ikJP+9kgD/v5YB/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAf/AlgP/wJYD/72RAP/JpS3/3sl9/+PR kf/bxHD/wpoc/7yPAP/AlgH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5YB/72SAP/o2qb///////79+v//////3cd7/7yQAP/AlwT/v5YB/7+V AP+/lQH/v5YC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgL/vJEA/8uo L////////v37//38+f//////+PTl/8KZDP+9kQD/vpMB/76UAP+/lAH/vZIA/7+VAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/vZIA/8upMP///////v37//79+f//////+vbr/86u Pf/Kpiz/x6Ig/8KZC//Alwr/x6Mj/76TAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP++kwH/uo0A/7+VBf/x58b///////79+v//////4MuF/7yQAP/EnRL/yKMk/8ejI//q3Kv//////9K0 TP+7jwD/wJYD/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/76TAP/Fnhf/2L5k/86tPP/EnRb/3MZ2/+jZ pP/fyoH/v5UJ/7+VAP++lAD/vpMD/7qNAP/eyHz//Pr1/82sOf+8kAD/wJYD/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJYD/7uPAP/StEv//////8mlKf+7jwD/vI8D/7mLAP/EnR7/yKUp/7yQAP/AlwP/v5UB/7+V Af+9kgL/wJYH/72SAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgT/xJ4Y/7+U Af+/lgH/wJcE/8CXBP+/lAL/zKo3/8SdFv+9kQD/v5UA/7+VAP+/lQH/v5QB/7+WAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/vZIA/7+VAP+/lQD/v5UB/7+VAP+/lAD/696x//// ///VuVf/vJAA/8CWA/+/lQD/v5UB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5YC/7+VAP+/lQD/v5YB/76TAP/EnhX/+vfs///////l1Jn/u44A/8CXBP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+W Av+9kQD/1rtd/+japv/GoR//vZIA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/vJAA/7qNAP+9kgD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/wJYD/8CXBP+/lgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAA AABAAAAAAQAgAAAAAAAAEAAAww4AAMMOAAAAAAAAAAAAAL+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQH/wJYD/7+VAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYC/76TAf+8kAD/vpQB/8CWAv+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+WAf+8kAD/w5wV/86tOv/CmhH/vJEA/7+W Af+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgL/vJEA/86tPv/69+3///////j0 5f/KqDH/vZEA/8CWAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+WAf+9kgD/7+XC//// ///9/Pj//////+vfsv+8kAD/wJYC/7+VAP+/lQD/v5UA/7+WAf/AlgP/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/76U AP/z69H///////z79f//////7+XC/72RAP+/lgL/v5UA/7+VAP+/lQD/vZIA/7yPAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP/AlgP/u48A/9m/af///////v37///////Wu2H/u44A/8CXA/+/lQD/v5UB/76TAP/HoyL/0LJG/76U AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQH/vZEA/8+wQ//dyHr/0LFF/8+vQf++lAT/wJYC/8CXBP/BmAj/uo0A/9zF eP/38uD/vpMA/7+VAP+/lQH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgL/vJAA/7qOAf+6jAD/yqcv/86uP/+6jQD/u44C/7uO AP+9kQD/0rVP/8SeF/++kwD/v5UB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/wJcE/8CXBP+9kQD/zKo3/9Cy R//awm7/17xf/8+wQv/Ioyj/vJAA/8CWAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYC/7yQ AP/eyX////////7+/P///////v37/9CySf+8kAD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CW A/+8kAD/0LFF///////+/vz//v37//79+v//////+PTm/8OcFP++lAD/wJYD/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJcE/7uOAP/k0pP///////79+/////////////79+///////0rRP/7mLAP++kwP/vpQA/7+V Af/AlgL/wJYD/7+VAf/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP/AlwT/u44A/+XTl////////v37/////////////v78///////fyYD/yqcu/8il J//Cmw7/vpQA/72RAP+8kAD/vpQB/7yRAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UB/8GYB/+8kAD/z7BI///////+/vz//v36//79+v//////+vbq/8Wg HP/EnRT/y6ky/8+vQf/Qskf/y6gx/93GeP/48+L/171g/7yRAP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP++kwD/uo0A/7yQAP/LqC//6Nqn/////////v7///////37 9v/Tt1X/u48A/76UAv+9kQD/vZIA/7+WAv/HoiH/+PTm///////z69D/vpQA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgH/vpMA/8ahHf/gy4P/1rte/8qnL/+7jwD/zq8+/+DL g//cxnX/1rth/7yRA/+/lgD/v5UB/7+WAv+/lgL/v5UC/7uPAP/eyX7//Pr0/9rDb/+8kQD/wJYC/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CXBP+7jgD/2cFr///////hzoz/uYsA/8GY Bv+8kAD/u44C/7iJAP/JpjL/y6gy/72SAP/AlwT/v5UA/7+VAP+/lQD/v5UB/72RAf/Alwj/vZEA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/76TAP/EnRX/3MV2/8ah H/++kwD/v5YB/8CWA//AlwX/wJYC/8CXCf/Rs0z/u44A/7yQAP+/lgH/v5UA/7+VAP+/lQD/v5YC/7+U AP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/76T AP+6jQD/vpMA/7+VAP+/lQD/v5UA/7+VAP/AlgL/u48A/8yrQP/eyX3/zKo2/72RAP+/lgH/v5UA/7+V AP+/lQD/v5UB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UB/8CXBP+/lgH/v5UA/7+VAP+/lQD/v5UB/7+VAP+/lQL/7uO+////////////0LJG/7yQ AP/AlgP/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgL/vZIA/8agHP/9+/b//v35//// ///fy4L/uo0A/8CXBP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lgH/vZIA/+fX of//////+vfr/8qnLv+9kQD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP++lAD/vpQF/8yrNf/Fnhr/vZEA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQL/vJAA/76TAf/AlgH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/v5YB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgA AAAwAAAAYAAAAAEAIAAAAAAAACQAAMMOAADDDgAAAAAAAAAAAAC/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+WAv/AlgT/wJYD/7+VAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYD/72SAP+7jgD/vJAA/7+V Av+/lgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQL/vI8A/8ij JP/Tt1T/zq49/76UBf+9kgD/wJYB/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+W Af+9kQD/38uE///+/f///v7///////HoyP/Fnx3/vZIA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJYD/7uPAP/Wu1////////7+/P/+/vz//v37///////t4rv/vZIA/7+VAf+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/wJYC/7yRAP/u4rv///////79+//////////+///+/f/+/v3/yaYs/72R AP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/72SAP/x6Mj///////7+/f/////////////+ /v//////zKs4/7yQAP/AlgP/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJcE/8CWA/+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJcE/7uOAP/izoz///////38 +P/+/vz//v36///////48+P/wpoO/76UAP+/lQH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lAD/uo4A/7yQ AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5YB/76T AP/DnBb/9O3W/////////v3//v78///////XvWj/uo0A/8CXA/+/lQD/v5UA/7+VAP+/lQD/v5UB/7+U AP/AlwX/3MV1/9GzSf+9kgD/v5YC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/8CWAf+9kgD/wpoT/9/Jf//s4LX/5tWc/9GySf/XvWT/v5UH/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJYD/7yQAP/NrDr///////Pr0f++lAD/v5UA/7+VAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgH/vpQB/7qOAP+8jwD/u48C/7mLAP/OrkH/1blc/7uO AP/AlwP/v5UB/8CWAv/AlgL/wJYC/72SAP/FnyD/7eG5/9O2Uf+9kgD/v5YC/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/8CXBP/AlgP/wJYE/8CX Bf+7jwD/2L5m/8qoM/+8kQD/vpQC/7yQAP+9kQD/v5YC/7yQAP/XvGP/xqAl/7mMAP/AlgH/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAf++lAD/wZgP/9rCcP++lAf/w5wT/8yqNP/Kpy3/vZIA/8ijLP/WvGH/vJAA/8CX Bf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlwP/uo0A/86tSP/y6cv/+vbq////////////9e7X/+nb qv/Alxb/vpMA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CWAv+9kgD/x6Il//fy4P/////////+//// //////////7+///////l05j/vZEA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAf+9kgD/7eK8//// ///+/fr///7+/////////////v79//79+///////1bpe/7uPAP/AlgP/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYD/7yQ AP/Nqzj///////7+/f////////////////////////////7+/P//////8ObD/76TAP/AlgP/v5UB/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/wJcE/7uOAP/ZwGj///////79+//////////////////////////////+/v//////+fbq/8CX Ef+8jwD/v5QB/7+WAv/AlgP/v5YB/7+VAP+/lQD/v5UA/7+VAf/AlgT/wJYC/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/wJcE/7uOAP/ZwWr///////79+/////////////////////////////// /v///////Pr0/9W5WP/IpCb/wpkL/72RAP+8jwD/vZEA/76UAP+/lgH/wJcD/76UAf+7jgD/vZEA/8CW Av+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYD/7yQAP/Orj7///////7+/f////////////// //////////////7+/f//////8unM/8qnLv/Ut1T/2L5l/9e8Yv/Rs0v/yaYr/8KaDP+9kgD/u44A/8Kb E//UuFP/yqcu/7yRAP+/lgH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/7+WAf++kwD/7uS///// ///+/fn////+///////////////+//79+v//////2L9q/7iKAP+9kQT/vpMA/8OcEv/LqTL/07ZS/9i+ Zf/XvWH/0rVP//Tt1P///////////9W5WP+8kAD/wJYD/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/8CWAv+/lQH/wJcD/76U Av+8kQD/3cd5//z79v/////////+//7+/P///v3//v79///////q3K3/vZIA/8CWAv/AlgP/v5UB/76T AP+8kAD/vI8A/76UA/+/lgL/4MyH///////8+vT///////Dnxf+9kgD/v5YB/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5YA/72R AP++kwH/u48A/8KaEv/cxnf/yaYt/8eiJP/u5L7//v79///////+/v3//v38/+TSk/+9kgL/v5QB/7+W Af+/lQD/v5UA/7+VAf+/lgL/wJYD/8CXBP+6jQD/0bNP///////+/fr//////+rcrf+8kAD/wJYC/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP/AlgL/vZEA/8yqNf/z69D/6duq/9vDcP/GoCD/vJAA/72SAf+8kQH/yKUm/9GzSv/OrTv/yKQk/9W5 Xf+9kgD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQH/vpMA/+DMiP/59en/7+S//8ah Iv+9kgD/v5YC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP/AlgP/vI8A/+rdrv///////////9S4XP+5iwD/wZgF/7+WAv/AlgL/vZEA/7uP AP+9kQP/uo0A/9W6Xv/KqDT/vJEA/7+WAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/7yQ AP/BmAf/vZIC/72SAP+/lgD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP/AlgP/vI8A/9zEdP//////+/jv/8qnLf+9kgD/v5YC/7+V AP+/lQD/v5YC/8CWA//AlgT/vpMA/8SdGv/Zv23/vZEA/8CXA/+/lQH/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UB/8CWA/+/lAD/v5YC/7+WAv+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/72SAf/NrDn/x6Mk/72R AP+/lgH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYC/7uPAP/Wu2H/yaYv/7qNAP+/lQL/wJYC/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQH/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V Af+8kAD/vZIB/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UB/76TAP/Cmxn/171k/8ah Hf/CmQ//vJAA/7+WAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP/AlgP/v5YC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYC/72R AP/LqDP/+PPj///////59ef/0rVS/7yQAP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQH/v5UA/8CWBf/07NP///////7+/P//////+/jv/8agHP+9kgD/v5YC/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lgL/vZEA/8ilKP/9/Pn///79/////v/+/fn//////9K0TP+7jwD/wJYD/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQH/vpQA/8KbD//48+T///////79+v///////v38/8mm K/+9kQD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/wJYD/7yQAP/VuVz//v37//// /v//////3sh9/7yQAP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+W Af+8kAD/x6Ij/9S4Vv/Kpy7/vJAA/7+VAf+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP/AlgL/vZIA/7uOAP+9kQD/wJYC/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5YC/8CWBP/AlgL/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+VAP+/lQD/v5UA/7+V AP+/lQD/v5UA/7+VAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJUE5HDQoaCgAAAA1JSERSAAABAAAA AQAIAgAAANMQPzEAACWxSURBVHja7Z15fF1Xde9/a+9z7qDharImS/I8JrZjO4mHzCEUAiGEkhJCBwih rw2EqZQOD0qB5qWE1xI+vEfyQmlLKVAIJKShJcEhITij49gZPM+2bGuer3Sv7r3n7L3eH1uSHQ+JbEu6 5/rs78efxNZH0j1XWt9z9rD2WoT7nobFElZEvi/AYsknVgBLqLECWEKNFcASaqwAllBjBbCEGiuAJdRY ASyhxgpgCTVWAEuosQJYQo0VwBJqrACWUGMFsIQaK4Al1FgBLKHGCmAJNVYAS6ixAlhCjRXAEmqsAJZQ YwWwhBorgCXUWAEsocYKYAk1VgBLqLECWEKNFcASaqwAllBjBbCEGiuAJdRYASyhxgpgCTVWAEuosQJY Qo0VwBJqrACWUGMFsIQaK4Al1FgBLKHGCmAJNVYAS6ixAlhCjZPvC7CcFkEQRACUZvMRIhIEZmhmzvfl nR9YAQIHAZJIg7Wvta8BwBEgAsBaaV9DCjhCCsGAtiKcG1aAYCGIwOxnPUixeFrJmtrEBZXF88rikghA Mudv60293jP0YnuyP5khKaQr7dPgXLACBAhJpDw/IuV7F9ffvrj+7Y0VrqATPocBAlpS2R/v7fzXnW07 O5LCdUiQfRScHYT7ns73NVgAE/1Zb0ld2f1XL7iyvowZRNDMms3wBwBMkEtBAAjIKv21Vw7fs+lQ1tfC kdaBs8AKEAgkQWXVx1c03XvFvJgUihmAIKLTfL5maLAACcLLnYO3rtt+oDclo87YdNkyTuwyaP6RRCqr PnfprPuvXhARQjFLInn66AcgCA4REXzNl9aUrnvvRXMri1VOiTf7IsspsALkGTPy+cSKpm9cPtfc+OW4 g5gAR5CveV5Z/LEblzWURrXSVoEzwgqQTwSR8vzldWX/+/K5AAgkzjx8jQMLyou+eeV8aJ3v91RgWAHy iWaGlPdeOb/YkYr5LKLf4AhSzB+YV3Pr4nrOqfE/QyxWgLwhiZDzb54z7dqGcs18jlFrvvgLK2e4UUdp tgaMEytA3tBgSPHhRXUAzn3tRhAxY2lVyfVNlfDsbHi8WAHygyCwrxdWlbxzRiWACYlXDQZw6/waCOIJ cCoUWAHygyCCr1fXlEal0DwxIxYCAbisriwWdbQdBY0PK0A+ubCqBMBEbV6Zp0h9caShJArNdhA0HqwA +UExwxFzEjEAExWpBDAQlWJ+WRyaCdaAt8YKkE/Oet3zzbHLoOPHCpAnTFrb5ESqnf+OHytAfhBE0NyT 8TGa43nu8OhuwEDOB1kNxoUVID8QAUrv6EtN+Hfuy/o7+9IQwp6TGQ9WgPzADEixpScFwJmgqYCJ+F19 6d6MN1nTi/MOK0B+0MxwxIvtAweSGUzQSqj5Jk8c6UXOd4js/X88WAHyAwNSiqGh7IN7OzERZ9sZcARl lP7Rng5Ioe0UYHxYAfIGM8MR39/dlsz5jjjXG7Y5C/bw/q693UPCkfZk2DixAuQNzZCO3N05ePfmZhxX /OfsvpUjqD2d+9uXDkCQXQgdP1aAfKKYKeL8wyuH17f2m3MtZ/FNGDCpb1/YcOBAd0q69vZ/BlgB8gwR seY/emLHjr60I8g7w+DVDHOW4O83N39vW4uIufZc/BlhBcgzmlk48khy+F2/eG17X9oV5I+v0hWbhCJA Ev39K81ffG6frYxyFlgB8o9mlq5zOJm59uev/GhPhyNG0tg0s3FhLKh5NO7HQr83633kqV1ffG6fcKVN gD4LJG64Ld/XYAEDQorhnHp4T8fr/em1tYnyqMMgUxpoLLDN34lIEGV8/ZO9nR9ct/3ZQz0y6rKd+Z4V tjRiUNDMQgoI+u99XXetmg3gpY5ksSsWVRRHRrd1NaMv6+3uH368ueeHezsO9aRIkIzbcf/ZYwUIEIKg s/5ty5uWVBYfHcre9NjWrmFvdllsTiIuCJKoN+Pv7k8nsz7nfDhCRByAbfSfC1aAoECAr9iNuXdcOB3A d3e0dQ0My5h7sC99sCd17JOEgCAn5mqwnfKeO1aAoCCJ/Jz3ewumX1xd2jmc+5cdrXAlA2JsUmwmwcwA fBv6E4QVIBAQ4DOLiPPJJQ0AvrezvaUvfdzg3ob7ZGGXQQOBIELOf9/saZfVl/Xn/H/a3grHJvRPBVaA QKCY4co7lzUA+Pdd7Qd6hqRNaJsSzhMBRhfIC7IQgiRCTt0ws+ptDRVpXz+wtRVS2OCfGgpeAEEwucSs mRUzsykaXkCFETQzHLpzaQOAH+3p2NmVlDapYaoobAEkkfa1P+wJoCzu1hRHSyIOmP1hj9W5lpudsrfA nnp7U+W7ZlZ5mu/fchTC3v6njkJdBSJAEFTWm11VctviuutnVM5LxGOOTPtqW0/qv5t7/m1nW89gVkYd FexbqQaD6BNLGwD8ZG/Hax1JEXHs7X/KKNQeYQLQvv7kiqa7V89ORBw+LmHG/L0tlbvzmT2P7OkQkeDO JgWRzvlXNFY8e/NKDVz2s80vtfUL1wowdRTkEEgQtK/+4cr5//fK+SWu4+tjWZOmd7Riri+O/PxdS+5Y 3qQD3jmLcOeyRgAP7eu00T/1FJ4Akkhn1ceWNn5+RZM5QuWIkZZyNNpmXRJpZmbcf/WCa2dW6ZwfwPmA INKef2l92S3zagDct6XF7ndNPQUmABGU0tMSsa+umgVA0GmbagkiDSbg79fOIVeqCSpBPsEwPrm0URAe Pdj9TEsfReziz1RTYAJIInjqQ/NrGoqjvn6LplqSiIE1tYm3N1YErWmKINKeWlabuHVBLYD7t7RAsyjI bYzCpsAEMFXFr2kox/iqiptcmt9pqgxavXwCoPUnljZEBK073PvEkV7zmMr3dYWOQhKAANZwXbmgvAij DVHe4ksIAOaWxeCI4ISXIChfLawu/cOFtQDu29oCXwfqARUeCkkAAAALopg8s8uOSQEKULlkAkHpO5ZM L3bkb1v6/+tQNyL29p8fCk0AopzS3RkPwHiShE1QdWU8KB2Q7AgiKF/Nqiz+yKJ6mNu/Zzv75o1CEoDN vDanXusewpkUlN3ak4LSAamXbNrj/cmF0yuizovtyZ8f7ELBbv2aRWdHkCAigiA4RIWViFVIAoxAeGR/ F8bRWtTUi+3L+j/Z0xGQICOC8vX0iqKPLq4HcN+2Fp0tyErOJvSZWWV9P53Tns++1p72M54/7LGvBVFB zGoKLBdIMZMrnzjc+6vDvdfPqPQ0u6e/sZuSaYIwv7yopS9N0iXK8yETQaQ8//bF9XVFkVe7hn66rxNu 0LOVTvkuWGuV8+PxyNtmTVtZXbqgPF7kSE/r9nRuc+fg+raBw6ZiRUTqINx4Tk+BCYCRWoL6c8/uveh3 V9QXRTzNzkm3GmZosCRSzGUR5/Ebl3362b3ffe2IjDhMNIG/ERq5pOP/xYyR6Qmf9MnK11WJ2B9fUA/g /u0t3rDnxN2zKwmaL6QglfVLYu6nLp71xxfUzUnET07EGvLUQ/u7/vG1w9vbkjLm6AC37S68wlimsn7n YOaZ9uS7ZlVVRB0wGOwzmEcmBgQSRBs7B9/72Na6osiSyuIbZ01LxCO/bu7RzFKKc1GAAEEkBQHEAJjZ 1GobqeTG0GyO58iRTxvBEaSz/icuarplXs2O3tSnn93nBWhpalxIIpX1Lmuq/MV7lt46v6Y86gJQmk2I 8+jELCLFimklty2qG2RsaO0XIrgnlQpPABgHHHm0P/3jfZ0VMXdRRVFECkEkiUzVtL6s943Xj/7pb3Yd 7ks9fKCrOOpeVpdYW5e4uLbsicO9qWHPOasSypJImCwjX+msz2AhZYkrG0pjjaWxWWVFDaWxRMyJudJn 9jVrT2lPMQBBriBfcWnc/c41C6ti7l2bmp9v7nEiTgHd/SWRyvnvmV/76LuXmp14GslGecMfMwVWml1B 755ZVVkUefxAtzjnBgiTRKGmQ8OMRJVmX8+aVnxdQ8WiiqJiVw5k/a09qSeO9HYnh8mVQgpoVjn/Y8ub /s8V84ocuaMv/aF127e0DThxV417MCSJGKxzCpqjRZEV00rW1CUurSldUFY0szSWiEhB5BAB8Ji15p6s dyCZ2d2f3tiRfL49ubs3hZxSvvr4qln3X7Vgf3L4kp9u7s96VDjTXxP9lzVWPHnT8rgjFL/1eSNTudoR dPem5r95fl8wzzkUsAAYaTRN2lfwNQAQQWsQwZVSCpMjTQQBUhnvqllVP/ydC5pKor1Z749/s/uRXe0y 5ui36lJq1jp0zocUq6aXf2Bu9XtnTVtQHh//RSrm17uHfrq/61eHe//9ukXLqkr+54YD92w44MQKZvRP ADOXRpxn37/ioqqS8US/gQFmCMLbH33tqUM9MhK4GX9hC2AQNLIkyjwyHz351u4I8jPejMriH7/jwsvq Er7mL208dM/GA0IKCHHKO5N5vqucL6S4fva0zy5rvK6xYmxIr5jNr/bUi94MBmsG0bFu2DmlI1J0Zbyl P9jQkc45UWf8j6D8IolUxvvrtXO+tmaOr/mM2loaWzZ2JNc+/Io2LuX77bzhrRXiHOAEeORpe+wvJ6MZ 0pX96dxP9nY0lcZXVJe8vbFiTnnxukM9OV9J58RpsSAihs75FzdU/PAdF3zx4plzyuJEJrvObPqMjHfH ziG84Q+N1HAWRKacmwYcIQDEpZxeGnu1N9U7mJFSBH8URIBmLolHvnPNwsqYC5zZPpf5CTSWRDe0D+zr SUlHBur9ng8CjBNmCCl8rR/Z25FlumZ6+YrqkmubKp5s6e8fzB4/LZaCtKfijrjnqgXfvWbh3LK4GU2N Bv2Zve5YQXPzdxCWVZXcvrh+GHixtR8MEexT8Gb3/XdmVX5yaSPjbBoQK82CKKv5F/u7RMAqvhTgTvA5 oJlZkHTlPS/uv2Xd9t6sd1ld2XPvX3nVzEp/2JNERJCCVMa/oLpk/c0rP3dRIxEUs1liOsdXp9H/KuZi V37z8nmP3risuiiiPV8GJE/jlJdNAPPq2jKcbSc/8+Yuri41c4BAvdVwCQCM7BU4cfeRXe3XPvLajr5U U0n08RuXfWxFk8p6kqGGvXfPq37h5pWX1JT6emJC/wTMAU5f83tnTXvx91YuqUmojDdR/eInHM0MKeaV xTG+MxgnYx6asxOx8qgzMT3BJ47QCQCAAV+zE3e3dCSv/vmrv2zuLXLkP1+z8N5rF/lK/9HShv9899Ky iKP4FHvMEwURTFvIOYn4b25afuWMKj8T0OcAM0CIn2EK+sm4QsSlADhQm2JhFMDga5ZRp3vYu+m/Xr/3 9aMA/uyixg0fvOTbVy1wBWnGFKQoO4IUc3Xc/cV7lq5uLFcZL5gOADj3qNXMGaWBYO1+h1cAmMmZFBD0 57/dffvTu9K+Xl2TKHHF2U31zg6TsFQecR5+15JF1aUqYEVcCHAFQXPzYAZvtWdyWhgA+rJ+2teBuv0j 5ALADHAFQdCzh/sySgM424Hu2WMcaCiO/sc7L0xEHa11fhUwGyAmy5+Zta+Rzr3ensTZ3hc0GMDLncl0 1qOA5USEXQAyWSuO+N47LqiMOoo5L2MQSeRrXjGt5B+umAdfT33u2IlB7yl/OKdzvivF4uqS29fMvmFu teYz3AJ4I+tbB+DroJ19K7x06IlFCFIZ74uXz7uivmz8O/yTgZkP/MmF0399tO+hnW1y8nu+j25QQDNr zexr7Ss4Ihp1F1cXralNrKopvaK+fG5ZfOymcBYXZM7xtaVzP97TgeBVvgi1AIJI5dTS2sTnVzRhHEfM Jhtz479r9exfH+4dyPmTsUl8UtAr7Ws4MhZzLqwpXlNngr5sdiI+9rMY9vWr3YPrWwba0tm7Vs8ue2Ml 1rdEaXYEfXtLS1dyWEZdK0CAML+Kv1s9p9iRPrOTbwEEQTEvKi/63PKmLz+/T0xQuJjhjdnR4+OCPh5z ltaWralNrKotvaK+bGZpbOxLUr7a1Dn4YntyY2fypY7BtlRW5JTy/GJXjqUDjeeHZY7srW8d+PorzQE5 lXoC4RXAVGa+vLHifXOmAch79I9dFYA7ljQ8sK21LZUlSWcXM8eCXjMzK09BabiyOOYuqypeU5tYVZO4 or6ssSQ69iWDnnq5M/lie3Jjx+DGzmRHKsc5HwQ4EoIo5rhR556XDzWVRD+xpMFnNseCT3cBzFDMrqBd /enbfr1DKS0C2fUjvAIYTFuu/I7+j8ckStTE3Y8srrtnwwEhXTXugfcbgl6zUiNBXxJ3l08vWVObWFWb uLyubHpxZOxLkjn/pY7ki+3JjZ2DL3cOdqazyKmxoHfirjlcCoavmQgkxCef3jPk6b9c0QRAM2vGG/Kj eGTNR4AcQRs6kh94fNvRZEa4QYx+nB/p0GeBIGhfz6ko3nbrpXFHnNGgdrLRDEHY05++6MFNGV+/eUWv E4IeSkNpRJxEzF0xbTTo6xO18WNB35f1N3QkN7QnN3YmN3UOdg/nkFNmaxqCHEFjQX/y6xJBMFTOv35e zdfXzllWVXLyj858ZCDnf/3VI9/Y3JwL6r3fENIngCDSvr5p9rRxHm6a2msDAwvKi66ZXv6r/V3ipCY3 p7jTa4Yry+PuxdWlq2pK19QmLqsvmxZzx76kJ+O92J7c0JF8qSO5uWuwb9iDNxL0JEiO3umZ8eZndJih ARF1f7W/68nDvTfMnva7s6ddUlM6KxEjkADah3M7+9KPN/c8uK+zc2BYuE6Qox/hFMAkoiEib5pdle9r OTVm5eSmOdN+tb8Lo0nUAscFva/ADFdWFkUuqS5ZVZtYU5tYW5uoPC7ou4a9F9oHTNC/0j00YIJeEORx Qc9sMqPGf23meIPJ63x0d/ujezrcqFMedWJSMNCd8TI5BU/BlTLqauaAdzsOowBmoN2YiF1aU4oArH6e jLmktzWUx+JuTjMAVqx8HwxE5LTiyKXVpatqE2trE6trE+XRY7/E9nTu+faBlzoGX+oYeK07lRzOwVcQ 4hyD/mRMVrOMugA8xV2p3EiahCDzQqZQRr5/kG9NGAUQIOX7a2sTRY40A+6gYZSclYjPKors6kiKokh1 cXRVbemqmtK1dWWrakoTkWO/uJZU9vm25MbO5Ib25Os9Q0MZD56CFJCCpJCunKigPwE21erN1RKNXDRj wl9oUgmjAESA5pXVpQA0cwCfAObgbETQncub2tK5dzZVrqwuKXHl2CccGco+1zZggn5Lbyo9FvSOIGcS g/6U8Bv+V2CEUQDNDFfOScQw9Ylv48Zc1yeXNph/MnBoMPNc28DGjuSGjuS23tRwxoev4AjINwY9wy+E sUdACJ0AZNYZHTnXHHHK9/WcDrOY2Jv1/+tQtwn67b3pbNYEvYQk4QrTAZZt0J8DoRMAAJijjqiOuxhf m5m8YCr7buocvO3x7WAmKfiNQW/KTuX7MgueUAoAOEQjQ+qAxv8IRY4QUSmIzPDGBv2EE0oBGBEpIiLQ ZyGMmEWOJJCpwmkDfzIIdBBMHqa5fL6vYhzXyUEuLX4+EEoBCD5zRp2qhn9gMNc1mFO6cNbUC5FQCgB4 mvuzHoIb/yMMegp2/DOZhE4As3WZ89VImYOghpYZoB0azATwHO35ROgEgDnG4euDySzOus7HFEAAcCiZ AQerktR5RhgFIAKU3tGXQoB3gs0Jte29KZxbQyfLmxNGATQDjnyxPWnKvwUwuswl9WS8V7oGIUVBLFgV KGEUgJkhaVtvqiWVBYI4wTQRv7Ej2TscuEpS5xmhFACQQqTTuceaezCa0xtA1h3pg6eCWy30vCCMAozx 6MFuAEGLMFNJKu3rRw92w7Hjn8klpAKYjOgnj/Zt6RkiBKtmvYn4x5t7DvWlyRGBurbzj5AKwIAjyRv2 vrO9FQHbDTAHdB7Y1gJmYVdAJ5mQCgDT7Scif7inY39yWBIF5EZrzto+daTvySN9Aaykef4RXgHMVDg5 lP3a5sMIzEPA3PLv3nwIym4ATwXhFQBm/Sfi/MuO1vWt/aZIf36vx1Rf+9edbU8f6hXB6yl9XhJqAWAG 3Er/xXP7Ur7K76aYZnYEHUxm/nbDQTgiIE+k856wC6CZZcR5uaX/r17YD+TtvBUDJvvn4+v3tAykT27c bZkkwi4ATKewmHPfa0e/t6vddGrJzzUQvvTSwXX7O2V00ltjWMawAgDmBizFHb/Z9cvmXtO9dCpf2pTb //bWlv+14YCM2qH/lGIFAABmCEE5zX+wbtv61n7jwBSEIfNIGdDv727/1Po95Eqd7x9F2LACjKCZhRQD OfWeX7z+nwe7HUFK86Q+CTRDgx1B39py9LYndggiUIDPJ5ynWAGOYRxI+fqWx7Z+e2uLI86lJ+JbYFoR a8bnX9j/2ad3SylY2OjPAxI33JbvawgQDJAQAH65r2v3YObahvIiR2pmPUFFpBkjJTsF0e7+9Psf3/7g jlYZdbS99+cJ+wQ4EWbWgBNzfrKl5d2/2OJrFkSSyJQfPOsoNT2zcFxfra3dQ88f6nZirmYb/XnDCnAK 2JwVdsUfLqp1BO0bGH7iSB8RHCLTw8vX46rXw4BmU4MIRJBEmvkHu9s/vn5PTunfm1dz0+J6P+MFsDx1 eAhlZbi3QgpSGe/mRXWfWtYI4C9f2P/Irva3za3+H4vrr59RWR51xnI0x+7rAEaaefGxbzJaN58I6Ejn HjnYff+21q0dSXj+yurSOy6c/uVLZz15uDflq8loCWwZDyFtkvcmCCLtqxmlsfU3r5xVGrt/a8udT+2S UUfnfAZqy+I3zqy6trFibW1iZmn0zW/enua9/ekNHYOPH+759ZG+gaEsBMmIVL5uKI6+8IGLZ5RE/+al g3e/sF/G7eZXfrACnIggaE8/dMPSm+dWv9YzdO3Dr/Z7PgkSIAa00vAUJMWi7oLy+PyyorllsbqiaIkr S1ypmNO+GsypI0PZ5sHMzr70vuSwyvqmn5cUwkyCpSA17P3pyqYHrl7Yn/Uvf2jzjt5UwJvJna9YAd6A Cc07Vsz4f9csUMzX/edr6w/3yuMSM0eH8tBaQzG0hhngC9MjiEcG/swQApIghBkLqTdOoAlgxm/et/za hvKf7eu85bGtwg1iI/XzHjsJPoYgUjm1pDZx99rZAO7e1Ly+ueeE3AQemdQyEQlXyqjrFEWcuCsjjnCF cB0ZcZy46xRFZNQRjiCCYj55+UgQwVdf3XgQwAfm1bxnbo3O+vYAwNRjBRiBAGYWUnzr6gWVUXd968Bd Lx9CxDldbVozmDErQr5mNVq8/4SPnO6WrphFxFnf3Pudba0AvrpqVlHcVVpbA6YYK8AIQhDn/C9cMvNt DeX9Of8zz+zxfSUmc3GGwXDE3ZsOHRnKrqwu/exFjcgpEbASFec9VgAAkEQq61/RVPmlS2cB+NKGg6+3 DcjI5A7KmSEdcaQv/bXNzQA+v2LG4ppS5Sm7LTCVWAFABKV1Iu5+66oFEUGPHuz+9utHRMyZgnVJpRlR 54Htretb+yuizldWz7Z7wlOMFQACBE/dtWbOyuqSI0PZP3tmL4Apax4midhTX3npIIBb5tXcMLfazoan krALIAWprHfj/NpPL2sE8BfP7zvYl5Lu1C3Jm9nwb5t7/2m7mQ3PjsddpdkaMDWEWgBBUL6enojfe8U8 AP+yo+3BXe1TfyKRwZB098uHjqayF1eXfuaiRuR8OxueGkItAEDQ+h+vnD+vLL69N/XXL+yDFHrKyzEw Q7ry8Ohs+C9WzFhYXap85QiSRI6dFE8m4RVACtIZ7/YlDR+aXwPgM8/u6x7K5ascw8hseFvrM639lWY2 nFUq56uc7w97zGwtmCRCeiBGEGlPLaou+eE7Lix25T2bm7/7+hEZy2dGmiTSvtqbzPzRwrolVcWN5UXv nVP9/vk1RTHn6FBuOOsJKe0K0YQT0nRoZoagb121oCbuvtA+8JWNh+A6+W1IqgEQ7esbbk/nmkqiH1tc LwgM3Lao7shQ9g9+vePZw71ikrcmQsh5MgSi0T/jQQrirP9XF894R1PFkKc+88zerOfLvDZiIYA1R135 H9df0FQSVcya2desNCvmppLouhsvunZmlc7ZFdIJpoAFEASHyBFk7pQ8ehZFjHzw1JFiNn1XN1Z8+dLZ AL688eCmln6Z70KcUhBy/ueWN72tocLXbOa+5o+p1RV3xN+tnm3qRVsDJpDCE4AAszCife1nPT+d0/5o DhkzmHXO99M57fnMLImOnz4SoLQuijrfunpB3BGPNffc+8phEZ2KTd83f0e+Zhlzb55bDeDk9U9HkGZc UV/2zqZK2FyJCaWQ5gBkMpa19od9OGLhtJKLp5UuKI9fUFncVBL1NeeU9pnb07lNnYMbOwe39aZSqSyE EK6EqXpCpHL+3102b3VNaVs691mz6Ut5LslABPb1rMriCyuLAZzy0cVggOaWxaGZbOf4iaNgBBBEYFZZ L1EcvXFh3YcX1l7bUOGeZrfowwvrGGhP5R7c3/nA9tbdnYNEFIk6ueHc9XNr/nxFE4C/emH/3u6hIJxF NM3rM75+kwkuM0CoiDqwQ6AJpTAEkETKU0LQHStn/O3FM+uLowyY3l6amWhk+mvCh0dLMNQXRz67rPGO C6c/erD7rk3N21v66sqLv3nlPAD/vrv9B9tbRV7XPY/BAKE/6w/mVJEjT/kpZtiztScFYbuGTSQFIIAk Ujn/gprSb1+14NqG8uNrSwk6Vb0qAkZLmzA4KsUH59XcMLPqzmf2Xj29bFF50Z7+4b98bh9kUGrwm141 qeHcg/s6P72s0dd8wpNNMUuiw0PZp1r64Nq+kRNJ0AVwiPyM94EL6r9/3eK4IxQzgcYzCzQlSQBiQDEX u/L71y0C4Gn+1LN7OoayeV/5OR4GQ9C9rx65ZV5NXVHE0ywINLI6OiL5VzYeTKVzditgYgn0KpAk8rPe h5c1/vgdF5jol0RnmiRGphgbwxQ9PziYebF1AFIEqg6zZghHNg8Mv/u/txxIZlxBBBIEMrlAhC9sOPC9 rS0iYitHTDDBTYWQglTW/+iyxn+7bpG5kZ/LHhARBJFmnhZzl9eUPryvy9dMQdKfASFF28Dwzw50dWb8 uCMU48DA8JNH+z7y1K6H97SLiLSj/wknoGVRzLj/kvqy9e9fWeQIzZio7GDzGPnezrbbn9gRwOGEIGKl OefLqOs4Iqc15xQItmjKJBGke+AoZrsqHnXuu2ZhkSMU8wTmxptukB9dXP++BbU66wUts0AzQ5JTFNGE rK+YISKOjf7JI4gCCCJ4+kuXzlpVU2pu2BP7/c2q6dfXzq0qjSmlA6bASOkhYKSoqGa20T95BE4AIihf NVUU3bGkARNUlf/E90zwNS8oj39ueRN8Jabq+O8ZcXx2k2XyCJwAkgi+/vCiuoqo40/arqd5qvz+gtqS 4qgtRxVmgiUAAb7SpSXRjy6ug6nXMEkvRNDMs0pjN86ssullYSZYAggi+PryurK5iThjwlZ+TokZXXxw fg2k3VsNL8ESgAhQ+tLaUphjspP6zokAXFZXVhpz2WaYhZVgCaA0I+JcUlOKkUSGSaci6swqjUHxJHaE tASYAAlg6jPHI3L5tBJM5gRg7OU0wxF0QWUx7Dw4rARIAABgOEQJ1wGmojahGfrPK4tDT+Rem6WACJgA gOlJOpWvaCM/zARJAAKAqJzqooAZpWG3nMJKkARgwOz8T9krEgD4dg00xARJAABE/Vn/UDIDTMU5dfPm B7L+FC05WYJHgARgQAj4ntrem8JIHYRJfjkiX/OmrkFIe9A2pARIAIz2TtwzkMYUPAEYAI4MZff2D0MS 24FQKAmWAMyAFM+0DgBwJnkubMqgv9SRzGR9kde6iJY8EiwBNDNc+duWvle6BjG6Tj9JmFMBjx7qhtZk 10LDSrAEYMARpDL+j/d2Api8cbk5Y7mtN/Xz/d2w561CTLAEAKCY4cqf7O3sGvacSRuZmIj/5x1tueGc I+34J7wETgBmSCmO9qXu3nwIkzMK0syOoB196X/b1YaIDERxOEueCJwAABQzRZxvvX706ZZ+Uxx8Ar85 A2YD7NPP7BkYykkhbPiHmSAKAFMhWfGfP7u3P+c7gibwOaA0C8Ldm5qfOtgtowEqDmfJCwEVQDNLV77a kbx13fa0rwXRuUcqA75mR9BD+7u+/NJBCl5RIMvUE1ABYCpYRZ11+7p+/4ntOc3y3BzQzEqzI+hHezs+ 9KttCgyyCXCWAAsAQGmWcffRPZ03/nLL0VTWOHCmGpjiuARyBD2wvfXD63YogER+2qFagkagBYBxIOo8 sb975YObHjrQZVoeaYZifvOyOSbujS2S6Egqe/O67R9/aqcpqW4THyyG4BbHHYMB6cpU1v/pno5dyeFZ pbHGkqjpgWe6a2k+VkZKj2yfjZRWFkQpT313R9uHntj+Sku/jLjapv5bjiOgxXFPxmQG6awvXXndzKqP Xzj9qullFVH3dDkMmvnV7qEf7O742f7O1v5hkkI4wi75W06gYAQwSCLNzDkFQWXFkYuqilfXli2uKIpK coWISTHkqZ196V19qR196d29KT/rw5VCCtNpwmI5gQITwCCJGKwVQ2koDSlg+oQRQTN8BUGQgqSQgjTb 0LeclqC3SDolZmpLgoR0TI9Tc3qGGSRJRKT5yFiZZYvldBSkAAazznPClJZ5cpOoLecZQV8GtVgmFSuA JdRYASyhxgpgCTVWAEuosQJYQo0VwBJqrACWUGMFsIQaK4Al1FgBLKHGCmAJNVYAS6ixAlhCjRXAEmqs AJZQYwWwhBorgCXUWAEsocYKYAk1VgBLqLECWEKNFcASaqwAllBjBbCEGiuAJdRYASyhxgpgCTVWAEuo sQJYQo0VwBJqrACWUGMFsIQaK4Al1FgBLKHGCmAJNVYAS6ixAlhCjRXAEmqsAJZQYwWwhBorgCXUWAEs oeb/A5fj85sn5OS0AAAAAElFTkSuQmCC icinga2-2.14.6/agent/windows-setup-agent/app.manifest000066400000000000000000000053631501332562400224620ustar00rootroot00000000000000 icinga2-2.14.6/agent/windows-setup-agent/icinga-banner.png000066400000000000000000001244631501332562400233600ustar00rootroot00000000000000PNG  IHDRrN jbKGDC pHYs  tIME  ,) IDATxy%}9t]>̀HXe8dٲrE8ةJ.*Ib%v*JH*IZiJ4$HyKo;U(>}~O5m,B}ܪn>beC5c݊/iUPyg6΅ hNw^6C뺓[>SoiwuJtv7Oh.ʐb}lҒnʴ(:_7p^؂-z9FoƘq!B Mm,~1&V٤Yk{ڱPvt]'yQϙmnz_mU9Ǝ>!G<رm7], iU^+r;AۥFMWFlpe .b#AB.$ +{co@hoDzv$1ɂm*f{/ #kwSO)ewSf*">iok'1됴a^rw ȽC9x^K!jw1bgn`l1u4ڞwSrԸwv;gO,PX8mv<קD:lafL9fFd hZ\ܖŬY\)06im%8JkQӹZMt產EuQSi8Zz.mdR+vT6s=ki֗;q)mkXƎ+5r=Iќ핽ǀ;;1; [)ow"7)IL H6`D6 A]3!ߦS{{IwDnUnG8uڍװc ]շIؤiX ݍN)G3F;`†ѤSQ3l@.Lzۉoco[gr`f6*`e^lkwvʢ1 L톏{;Ÿ'z=9ae5&&90Q's85}֍Rpo^l4-`<Վ#[ ; DMmb5%F (GE-,=LY.ώiQ\n$Fnͽm<95X4]Nmn{(;iXE3v3?Wes&C_W^+{e1& v%Ew?<(ڼ\{n=^+or7v_&tNߦwPDVX@<6-]+޷+oA WdFar.2v#;6Y5?wOۈ! lCL#)MER<߹ s*KLF6d6Uo~Wjp)* l$__@LOE;]rw/bE&Ƣ:MZq- 0#4`M>Rkf뗉H7V_DV p:wE WHXĤ͗Rخ] _ƨo=d(2sy{Ժ6 J 4k;mŘ1=`17 FVN ?}/ǝzR}|a61(UP,DteqN{rO{3rNv~zńLT?^3Pc4AB2u2ӳ`;W~B6`iL7aWǷAN~^6NN\;2TXG;}pVH;/Ir'vS&aR:d'b&B-r8ð0p1߸:;ò>L\ή3$ Gh5xRxlC ۯkCB$qc;n{ིW]a؉wV*Z@)>oE{eXQ6>|sps;Ɗ:EgJ)4x!*M-W>FnN[N-"8ϫ:nby7K,lÞ\͝jϤAHDlD*b\]Y;'EO-{ΓeW T=􄩴n6LM˘[)؏רgݹU~4kaAOd:s"6< X$"tm\x߻˜ՉUZ\$JH"̠H "c@XQE\F0A=uj EY.Ͽ\RԖc1KA5myI.]! dkZ['WPvX=AིWʛEz'?,bl'|cT!qDOh|Jeb9Ͽ~U*{J*ڑa}BJvtr약W^y"i0z>X>[q{S/`;֯Zc"-8GNįv?v K Sj&4},J#vReqvDY 1/9 vG/zmWU?qAM è E&?6I;w; $93j7{pNq1w>YEI;Ԡ+TldxZ< ق99|kF= mu| +@[1hmS:ԃsHxgq 4/FvU\e\irTƀd{HjWQ Pg|)۸`#m^߸)g&kq F\;^2c{{.Q;.tA oZ!%`ё3~O?e"{LƀXٚ !y'>ο}L3=׊/_3k1ŧ?(ZCGGs2%-D"2cEe$m5`й~[ٟ}asZlBGݻGvc3Ofcӌ.~28$c6 !Sg9"}7Eױ~pҍdӵ݁59 GTͣis1XiiHv2w#$%%8f741F$ڜ#zyqkBkbYޤAt62Kk=jwvIs(8w4iL@ycv͇&Njwxp7{}v7ޚ`b*FAu."!g, )`t[vcƽSU[}c6Df7ɒ粿^bi%*͐vfۏ;:rGv$ݜfavDֺE|Wq0dRCp3nxnV×O=@B$&9 Y'Í&8YWRk)sV*y ֦&@۹H@TmX#Mti'`dbQ;/;߿>ݝ2v]$Hbno}X"s-._g7"fGHc40C0kl0}%f9fgp#3TY(TzAyVW} G_lE7b£"+> e̳I0B0#f(cuOq}7tg +* d*l@HH #IN4DҾV1lcVHba;TOٱLsҦr"?o9 @柟m0|]Og~l;6xH-S>D!Q+0ciiË.[Ia0-Ex+u޸vGdž?|ccg]-Cle;'NL,1%g TnEb1qĢm@JR-(a¼ r vL lǙzNgHA;)fIv(i|mG̘c\ZfÏeÏƠD(5"̕3e RQsY.5;?wJ+)9{4!jÈV:rY~5? 4//۬F*{e,΢)+%;CBbxlblh`x2`o~iݛ@$F'&a,#7"%M?$1~l%&U@Ȅa$cXb~OL ˤ2ϧmJ!1`ʝ/s7[hJ {[h/{;u&3w{#ˡZxE 8k;fN!,>#v)JS  80"U)!1"qQS}#3MnA.#Tn,>_SlOSv hB3FϲgO4Jeh 6Lzjh &?ԿtwW pbm uޑ dXVIYؐoS c{&CiWa;GsD_]M6ģjXfV O=#og_z!"Sq Nw b_`KIEH)a΃ws_֦MKeHąaνjz1whbW TB hG:b>$Wu2\io9a8fd8x9<1?cMN'0f?MS Y)>Y.IUxd/ҿYf>\dF.U 8:ǧs/6j?||/:tnwDf )0FRbRpm X8챔 4)çs:rI+zb$B6/N<\Ø_ g;ƒY5KG?<;n\qR82}Z9;I&M&zkVGNE9~#FcH6s7$,H Dw&s穏0a灜.t,O߸tBKdt!%D SdA&Yp?'/ڑy]V>A))Zd2D(u𢡊1~Ql0bC2w>؃Ԕ}aEC\BZ uSJ.pv&I}7, J&Z K*SbRMI/7g tGBEu,O*}va2+9f?$Qf9<ΧI@ |<æ:1&mұ4} V򩓳xM2A#4FHS,gӚ ka˓fjllҋ#*3ƟDG[f#ԈdcWށ 57is4o.S^;dEE ! Pj Rv}Չun{竔m~T\=g);GJhhBP;o1"eRDK&O&Ylٚ΂&8 gk{UWVQ8ËWoCH䁅Grkk"QZ'\I0fB` GOKC;^@TIDm|f\zUQors:w1A9ln,ԒZ]Dtflya5LLVjҰ,7,{Nr'Y@M}X!݌0[dwEhy<%ފ4גHI; Ƈ;lS뻎o.qz r.8 C\Z ]1daȷY`QGe{Ma QR`@ N>7V8s [5Eg _)|Fų]W4UL7ڠA D"G3*QV%6h=y/WWY^ߤVmh䜥Ã8ZWcڭ7n2 '_O<ŵM<}e;q9ѓ䰼Y1~Wf"0.^i86{^@!d,Ð\Q (dfo 3+嵡:AN@oB '#_1\jXԉx~N jLJ8X%}5 ?4Cv>a uE#Fݣh8Gb!X*Bs,olrSRj33rl|wKA͐ \!6cړÚ&REZƅa\qIMeF m-Ƥ]ՙK46%F؎jp>!nrR8)tK%1t01jfgeA-_;kQL+m( *,V}(f}g]Hke0m옝j(.b$O2쟫0Ss l51`JLXVT^Sjñ .-RO<rRR USË_4JW&~aR)^|ǟ~Ͼ|P̹k"> obt2%J {=N9!/( B6eOft!JS M"}?\ؑE)D}I٤}ʮeRbpRj-o4}1q2<4@n[eu/Isua%WK9o]e\KK $ޅ BXۦF,5]<)R9\[:8V M,DS^:$!R8YӇdRtIQs2Mk F#xCRA fʕ Zk|GǠVُ?yu|oR/ ZA%ჼ| Ryȸ°,qjlh4LȤm{"s"k-,=3(i8uךFE IDAT|8N08XJeffflF+R H"?DNq6F w^Iɸ*]-?ĻO#} |~ge>ɓd%ρ#s=nݚ‘_@m+ ##'`1| qEq(=**Vm98s i$rY 5=Gx}m!FPU. 3K+ VNZ'%Zn&-_Ef"≕@"J*DEФv_M2s,Gի tG)Fn8"+$kB*ez9L3Xi."dsVl ?lRBR @G y00˅JN| z&Q~bƕR8Sl\Xmt;#B:6ǜmm6Hǥ(R1~g9:nI;Tڬ;&Ie5 FF/C6ASv&5cƴ: =nyԁaQiRb &M$9+E$XVhh&=ο~{M]W/0SʺvhHan-Pṉ:6 ˹UGW b+YܢeKuK DOEX 1-vCfc0sn)( tjk:(NW"iQ"\)l4dVrV)AHd46}ǔR&Gqsf +lZ#sĭs*6?k#MMV9ֶ4+;CZkCl-Vf+bW82_aZBV($b6?v1#%eGP+qdqZK'ͽACX|Kŕwd++:Q$:JK%fh!M?fsMl,'p6f;u5 mk ;.<Ͼt + v($xC' >rC76^knmh?|-.7y"onkX C H;Zs[pj;EB Nsu;ۥd^hЧ\M"Ad%(fˏ)YIIdcƂ5)[D,HWdD!>_D|a-yip???xo^\fy dYiR!9D\nZwX-K&P3Ӫ+TvdF'K5*JX1qƤLT{^RRfb0~+HʮnPpGIՔe*Jh ]a-Vz;)RJeGDVh*CeW>bNf& 5--Ì'94WfNݿfALc[fS}u+-rl¸2)>x*l4\XO*A[EEVW"43 yWAȁ 12SD93k090hm`E)b:)1D#9.^_l aӠ|rO{E6!jC2hmAGxcyfAmQQ*dm)R$2/+,aMvZE+-c JT]q8PX'N맔j.,h F!i4R&Z{J JG+P:?kbNQqI2G|='^tGg?g@t؟E KZl-~EDBY͎)>p?6N`M:<~4OO7_UI3RSc~ l S.^<K˜pK{Q~c{OS.;qϝs^ /Ӵ=-&zqp:+fH.ɫ:!h(.l1 k8}Gl4@k#|QN[UOQ>Z;n kc¢1d^Of4CZ0T6qb#$"4Il,ڀE-v$KX e² e,jJ)) UM? lRg Cp:ᵰET[툃߽у H\5(kAUx!bZMS+Sf)@qY(f%H@|u0Fr !mI9F{N>]}lK?0V/fim<$+5Z <)b`MIi8& C(LS8AIc QdYm^l5]Ed,[[[Xu`D$ՙc2F>r+4H*(Hf*e 6~͘[UxB!P<%+Z'{Q"q0v["DZ=3W]Va ȉbD۴m\wfśkFw֓Ѓ M/O=zxu],obVrY\<ßz +[˟xO˧ ~KDǏ_u[X^8u0A;O7i\w-ʇNZ eaV~I~M~r@1kWG?q\Ë75Pv{ [댣Mr`̑25}&NW)<)SͰіCIkqHc;"lhOXfkUa ? 0H8.jVKvhzk 6[>f|^Aԅ CKڽ 57֨H-`bmk8uXLbMB -('YT3P۞+)@Db*e04˛[H'quːJ$A*j( Hl1MU/˄~DXo4ZAb RԤyᓇsjI^<Ǭ:ı0\WsCnrU{l:GsKp:A,P1c~L٩S*8Qhd dl(ȠF X\rj?9cbb_ܠ,Kl5GS'" A/˿EW|Wl/<|js|Ms>q[ 5oO_TA$Œ4zTDIp$RAUUGV8MQPNGTry̕,JJ.fCQL; f"Z~0X+3$҉/gl%6?QȂW郉#}>i?sU_d# YMVP&1W6ac?u8 buQÖb^Gn7aі h>Q(aZmhG1flr`}"fIoS/}? l2jz,Δj JCP)&f@'.R:,]ɭ}ܑecPk'8s*A;hڜ_5!3^ WGySTJ.RJ7^|۪gAYG_Ez|F;?a-YN*^۴86Zl=:򛗹һHKZ{GpA/ HeiyPCRO9y`Sx_;ʜ`xR_Hm dNIe؉Mͻz:2 )řL3ɱ)N1(AG!iOZspε6kvbp*={emF|"ai --A7׸)Yn48Q?NY4iSI6F+KXo5Vp-X_^f-qlaVssA3 x̗߱ 8w5 (a^CKְfVV#RY.B'(&4?4D\)%J a6fT[&vSpe`3 r8aF6EHx]%m\seZ!ˣᥳW(q}e^}MUŬ. E$5ċ.1[qxjXmH/B /^'rs}Fr8gL5HUGU8JPwfʭ\f,wGReil'Rarߜã*kOiK_ޝNXȽGX__{ JͬI^|٫6MDEn2ZfDRec6:wp\V80?}YK?$N{yeX& M-r~[]>_z\rá2?Z |G(JpxG.LYb0tAe]>XܷCe'DwHfgӃ<ٳ:^`M_  k4^ȹgwY! 766wMRcdס}7i_OYUaYȷ, *Zl*( qK(rzQ!4iVc۲[۞? QtJHs`~k!К0Bv\͒1e)"rphpdNoaN _zrْCV%hYJq%?e@I(o7Yі8CB#44:G4#I;i 7m.X쟩#sUZCGϝgY 6"d]JJ(6hc*P IDAT M1mqWxRR)= ,J8U'.kF$Yel0PJ%AǚZʎZ+@4!]Hkjj2U4gVi1JH=g^>7^‘.[x%Lʼnlm4|}:~#(()P^J\gCGC](>XsgqxƩs[^G ѸBCdcđ$P\e?~ ?آU-q`ӏRG_÷Æ-*ˬ#RA,oqݱο4XHc0aۥ:*Uͩo>[`/#altm>~9vd?Q]†-m%Rq,mm ӅP#DNnUXBYJ4}kmkS~:bW){+ FNNVъtz577l7HGᥚppϡ[DZ@֭<'N7'Yǜr&E TYb 'C^н`3sv?p(3R_K عdv^0cI}5Gړ[.Rbe)Uaǀw:c=riSnjΎQ3 Ȅe/0N!炐ܔq.g8 poϰIV Ӕ7{q/O8YD]#;{f+WwGrA //UǯĠP8qΎSy-OE .e??fX82\nd9qxT+(X tP$e;QEAԈC ER MZJ #e=+ɨiAVhl&&d)asjAQXqQ|oT tczhqt|_v kj4 7J {aG*ꡢ1HҥSX:2r.\y^Zsզ_nZni:(^G?b7lvRrc͟y &. #kH~=e-zfPcpɬYR3Hǡt%ǚ*ɲ n#eFn:g|_ kD.E.p#HK"O_eݣIn͑CJ}gcNcrxv%1e9<qpaWR CC֛u~;~#2_ˌͶlH8.rFm*)q1i{4Οeߧ&޾)g5yB1{kTT0l+T*р76]nNsiQL#rh>g=p=qǫoa8(kd:7|64=}Ͽ}t<&~ʐ|Tgƕ$>5ewNOq^U )-Dvri {$2q|.0{NMֿsGj5\TH?:=:ЗjR`1(L>&KZ yL p\ZY&޸ӏ\"筭XQ! ëK!bGYWC3Tΰ[[•_|]c)lP]kZ$Y.K (U! MiJ_iʣ2SV@*֨Em Lr(4{qZ4J'.-'wIX>(&n@9TP`,o^5q:BR[ZrQSQv/a&/rf)nޣznsOl,roQА[CzeXГ2KUz,#t$' r)KnHG}+pՁH֚<e%Vzf""v"JlAYQL5A)%ըB<ڐM+ѪL-ͻ>28ju Xn{Nwk-R*W/Νg?s%3}CO~=9l řbGO yB9X}>c7C^8u]ڃ._z~̿t1qVШ'..'ܵV"E>+@!kHAa̓\G;8c޺|V0p;; Zzű…Xm:c}yvR8`lO8ۉ4sYVHajFyLMW-v-(@*Mup;;zNUέpcs|]^ܨ9|ŸזC )!nk`E'>{wc5nXiX\|#2YF%@q% H qI"p,W"4!rE ~R;!C:XF EA3C%I,8Q8A2_:a4fͽ6K '4S) (^Kյ R-$N?^8j#) b\hVj`0޹s U*3-rc)pqܜGxjyi4,4cTnD?Iy8 <.r 1rKeX;@~($7ٕs°zhUIct_jdN%zQu"0r0[Hο/7s'i>OPk%hea݁D q>= Õ}/Ǧ3G bmy67/?~F%DkrSO'B$I,*4ܓ|% >c[?<>xFn6_Cb_Tsh3 2Sc+rŽ33@󼰷#HWv|{d37a/˿ }'5T7`]U>Օp,xT`H^[O R.EK|6/,"2 k[l,0!Ƒa#><᥵u(6.qeu>m65JJ?pUdY~1~kZUC{D Z=wV"$-A$V(|=4/GHSZWbOqR Q" 8vMoc0)O]g`5|}[ W׸rnq B7 ^K-qXQˋ|[(VԠ7Et\ &4jucvFEJv#z"G|#Ot ~)nG7ҨUIFrxJ PQ|6wE8ekd$dq:9L&Y[oW@;6,UB8&-r3`T򙗞941M\eP,UyNZJEZ!=X'/LJ 0 w*,<%0s><롄Rž`^߉@ z҆d-?HINN3Uw]gd4/W.̹5D@# PJ0 ,}ZqΰDSw="/"$I g0 Ҩ氍|QH6"K.~uG,gXdg&]Fmx, @7o; oPK|}b#O']VujިR ): cV'J6RXvFZe,K1Q^K @ )ԸAf%4CQ6.r%FT]AR(RFVnU(?OY9ܾIίU<HsK>^ KRCPVfYV?~ Ŏ' !A K*(r̿:&0VdR~#?6Ƶ;|2f+KUlG["}$B=j]^?ܟ^s].,pM1,a-Q<@a uE6jsKM$_gL6q<~?sRgC=7~hY#%QvQqY>"{65Ƙi"DsS:e*Q4^eYA[c MCtH-w*^O XԩNe Ր֠OZHꞏCA@WSjD &G8LCvt][>+nf-n(X,^ ` (`7`7E(pW["FO;o瞿A?ߡoun߻Kxp%5afQ+ֈGQTc Kx9[R|W[G< B(9t)df1mHC&4/ߍmd / рL:"69>}?WO+*6t1_CHuHh0rb׶ҵm~儅ZITX9J&(ԢS4Ŀ\B6J_g_W[2 _\Ym"okw^g?QSiw镫| ^|<}Q~k0F@k:2|;4NwrHӞ'3hf8.kE90|PnK a$)CGr쁘)L->8"%XY2)N]60XU(%&d[S1sӡ:+g"0f&H}Rx^kMsؾI)YW&)F'5qH,ʔyp "ء|u%-',4* arX(~1#<;ۤFR7Heコ̝8AN5$ B\9*-0r->},@s;Ȯ7[5~ l4T+x2UZx?'_|nfJ5VJԔz%wnɋprw;~gp]xfc?zwZ=>g_x/>J?Xc֛umٟ^} .ϽuO\Z k#~e~tê !kC` RVD484!Ͼ8ҺglroxO/A 0,>;QbDz`D/7H[ S+U |YwQeF_gd9e՘nB0 YTiy oAxTXy#i4Wx ;q}FĦ e~k wOȥ& ^Jqk;8*݄AR^X[᭭mXiv;<;X[]b$e7,LkaqS+A=h[d $H"\ai ) tRY JD˵v(%l,;]\Zi ;;,t3(*rT2~KAQ)! u _ݸCԨ!vB"EEZAJ\GX)$ rH-Q>K{0YVhD=Z:KuY#b(Py(u16%LPHSn sw $OG#V`vP|Ik{a0L%TA -Qէ7q“0pG>f7V*uv%)O?.xzcd16ָbTXBܐiJPUCzp||K?Y` MwU 9F'4+ 1s5Аuy cu]aA;hY pEr 9{egy -.B)x;T%>|I^pZX,t\^sikqIW WwLww YE,-Y'oʝ=8w5i#K'gis]^o3\cvN񝧵UYCzE䴢 eBjr?f2Q%J.AnA'?)K]9Ac*eiЮg+>Jy ֺ}ʤVW-zաrPTBpDTju- c'7WH[&GR Lwà ͙B 5~9֚5~ߡPgMhWjVɝQ+UA8 { _̀<,Gm"!-N`4e;s^?b#rMv9 FO+G5K.X{p81Q>ڃ>9AjPqL*92N ?zF3T̉>!@s1G3FZ#0&FyUEg׮C dƬ ֔=y8(MegJ-Bq"5Z;՞u Be )e5 (#X\YFULg,U}V*;#$jHQcr,HJ*h 1mЦ 5.BH/ Tk.0 <+5NK7o-^ȵbF[q{iU.9K "ܤ+qp视0xr(`d$_^Qn _hNLf5#8QJb5jt­vmJ )k~ZhV#FYNxC#qigt%% )=9Q$H,+ ZÄ~9 ' R;hWH c0lZ6}'i *bur΍cDh4P2-No4VNAX@[prS2Rx/XhV(p%c;)n=(#w`;+sx"H9#_`‡}`xC0Nkő'iCǡI6%.b!݇ɕmJ\`Y~O BX*~?%P h/ Z# Oe"! Tő ը4% RIE;*huc}VJsV\ԸRQ"K G9X1iYp;X,\C?ɌacI..̚^(4EUZocq};mʝ?vz`P8NbTB-ňݹIݏQ͵ֲrvN3O/1RoKaH^k8dEczO ,T+dDe4ѨDuʏ<_wQVڬq#T9-XVA,y:[{-:@? <ݛ7.=' Z[trEJ8)X\\>ؒcs*FHuiT+D*~2M9Fwc!5VX/&I2v23e>&.p%aXa)sAi=YDrrZ\~W}%Nsq6@o*T4.s@8>Vr!s(R rYer#;Ň`O4Wa:׵f@NEGY_zgz!cbRp &1# <">|<{#9ue~ +;[U0YBT-lԫxL8i5k)=%hgCTY%0 n/Fgȷ:#6;{! mA=]ŚusvDKbc iF5i\Rk ,q,nJf\]R\޸Mcq}.mS$㉅?SG6KqA JֈAKIa 0dZKIj'+ ˵0dۦ_R\ Q5J@"e)IHoe SCoSXAVEIE`pأ; `Ph#hTI7dF`IJP XTȲxP,V+dְRH8BO G+!4+vQzCJ8$99T Ր~f)lyqmʹw]tŴgR fH}>k9<8 Q@C8{c @4 لR3j |O['S4 HHY1YQ)ϓ`x?@C'QD@/IUGa:-G%r[G cO0}P<,|bƳkV~Gw8bTJb%s5= kM~{j)t&'ך|2:~ ^LߧQrԹsQ*//rsŒoҎ5wG#dڐhCZY #6RA2v1s Hcic!K+M%WkH.Y3ր54Jo ɐO<{#.[:&8 #zIKWVzpv#p1%ŴbLJ s'ٿNJ.9d&3#N`9Qf.;:oߧ4޼E=y>{aIR h"͈iNw8{!ȓeΡoZ}Q8`5#2T03DW"įzH0  <A3t7$KkxU=Þ3D(. ]钀 @ /f8M{kˬ\c=<"=LLKXUfٱc|}?C)3fƠ$U8<GԎ_wx*z/Ϧoa_-`5 eE$dzE( 맼 "MXUN'ΐO2QLux:>!!UnQyKbb-(M4/yCpKR~r2F)J r7!PKdCE۴}הѦN6 ;"r'+ѓ;]D*Y7ދwөec"⯹["nF)7xR(fӉӪJ/8gKnі_xWq7q]zezٹo/df-h+[CbetU>c6MޮZ.^6V<-L-w).>px&nQ_a"jw _Ȭ y4yшD{i%sЏDGx2U^2JJqR!lG,$U)q׆N6i ݕ؊@̫SA?! Z$T$- i(j<'e h:JxB%^g=+v; x1Ǽ8Џ@R nqT1YAG]1ސHaQW nJ4nQ[Lɣ]~򈓪*!1Gekn2g;,RVO#tht^y+-c=xawÃ]^MhDB$y ucx]^ 4! DyI^vSI l̪@K-P:QsW(!M[T4^Dݔ(X̂KA sw5^(fAlyufcnLlRNgLC,4_1"z)ΔHP Ia=p4s89!szZ48mǵS O КHyeJ>%z=vw(45|0k-#6/f>Ӌβ'5#,%1o3 RLjʇ;;ʊQp/%Q1fg^_!;|1{z|"!$QL RHcIY"Ҏ8+,ΐ{;~lƨ'+KR|pBE3v: (8XK ʒi^ Ӫ9n#-q"vcEqnauxwU!#ƬU΃0-Z7G{Ƙ 5 )皒pdzgˁܭW N QWZl:_RqrV_[ɷp@r. [\ݻ}3ÿ́-9=>Жk!63VMkfQs.\/z%^! .ܮ<}Š|s:nӵ-@X>VcVV]s2KjY|\_nȵ>ӺE6d-炏(W݈s$u9*!tg!1eٜqRڑ9Ŵ5V] $8dWt#  )kv~U! ݍb. !VJW|5>Ps:S$GkE?CRVe+ȨƐU5> 9A'gc8j**LmaƠ8@7(~ìl~䆅(voa2 h3t4s}t@#VyFa4PDj%Tk5{B,=i)I'ɚvBE(-#C>NAGcfHPbqA@,ߍ3x~h˃4 [fG?.-2cEt W 4D_8& 34MCEҚiAVϋn,wjcI8 "`f~~ųGàuwuz^""R p۰=0/JDAL/ 8r^&'zQ=XOMh Y1LQo/&o q˷S7B4u1Wo/xٮp.G`IMJ_5!_K{/^uDϯ9:]g.E*=ifiRnJ "5Y[yE񅸅$G,ڴ^ҡeȵY⻿R\ 4D,:e!eUx>OnӒ IKQxaQ>?ITU8˸1dA@wtYK"O ӯy^eL*N(qx x^-fVh!QJre|KS-9Lʚ:Un"=HgAV|~ʇx~xB$ ;(-줊WӒAtF㔢1tpk߼nuަ56 Hfy}AXY6nLN?!B էM[[Y)B^g 48%1MQଣp-l GVjnŭF^vq%6-֘sM/{B4cid_'iLy}/ݥ="~{ 1FK+rmuէ},V%[,~7eв}?r-)sTK,#t79sɜnď:,$Hg)+LUU4N15ץ1deEm,= =BXh*%ulu: Ӕa)(8īyPgk@z$*Qh7/^..O!c AD!3vU=2sJ :}Ό#N|;;PZh-$)N_xZjk>ՒJ~}1/j[UZVuE_~V OغvJs4M޶&Bng ^) ~8MF1=^aP8ۺC!XBC!sv/^Р)*O%ipo(J2k*0L;hҷiKM A]-LM/MQH$[İ<փ4*`o{bZ<皚w4mH #ۈ]UXMNvވ0m\6iY^q}]?{wv S. 6B;=ϕ%ύv,y#<\ N[[˅Es=Hw(^PN Un~"ُpQMc)pK!8֢} >{@m@6U+/t"hEH ZsޙVLH! qJʷv[^<ˁ˅O>ϟ8E64aR7Hڊay l_xgY)9*t;(,= iS´PKV,4q^8ZyA4yT$eZx61/O$TIB2! BrFgSD'8ѽ{ĽHF>?:lKç{H {IH@(&G%Ü I$0Bq+s0ьjSëIxQŸ#dp)5ZHZD$7^y10d/"Jg54uCV>y˛D{ٳBc9a@O)^4uQHiƒ~G0PDid!1L'M $9$_!R{igX(/8@H%eiSn=JI;ܡ,Pf:$EuA:)Z>{Z؊gp<rA3H,I)9v`-$d^ iHb (Dc m]@G̫j!m1^a2lSًwjor(IDATUsk>.u5}f+s@n3Ƌ+oBoԫ!RMhMy/MzuV;ުhuwڅ/o|G+J71 W/"wsKi_>FIv@TkD6kK嵝헯.eSQcå-x |\/3Ҏ5O+R!h٢@b*%ȅo+KT$./@|_׊aTX/pk<ޝYN`@5_SB/BBx<#-Y[D]4ւD4A._!JAaJkbژ@S44 7;/Oy3 "嘕Sc:aM [MR..Ad[](,詐Jtd ; 6qdɛqmmyFa@)}#wׅMwwS:JI?aHwFD YHl‰i8!Rh#y6>je1J˗'h5'<ғ[k?"OzO#(M;ègOue@c%Blp6˙yEYI7J:t8oR҉;*%@V|xˤx/RT;[qf$y<2++jg)BۢKVX8Dsɤn Rbv0-:[ʺƣ€7ٜX"d1llTZ먽DJB61ޢpH@(V-{{qYFb|Ɖun\8$1[DnLBl4 "Y5U]^^eµQl5w?A춨U]gw/.#ksKK wGqѬ0w^+VޞKA3#P@TnFjk۠S hZ]%$e+5ȅ~BoMʺ>8ZK.],sօܲ x9Έ㊏w:4a^(a8gh ; $ Ph:xX0]K3 UJ#(x'! ܴ~G;kCYUxeU|{ϴ|o-|~vvΓ |Cv5<;9rYb4WE+$~?rq듌hEeZ[+,4Yɤ*f}~=Ucwh*Ca ݔi8bA0P4N5ǓnOt6 juցO8kwэ4aJi dxJŬF8Ũt2\GF-pq7ĥ# .Ejn:-RhSƷ瞯%Bi /Z$]h) .872ExUrgP^lg_"x>ΦcDZ7Y v~'l f\n˦iPJF)8TŤ(Qv-%T-Bi1aź6R8! ѢYQTu3Ô:# 6( :a{{Xgǔ/?$! 4q#b"k 7pK~oOxxhk@V8̈́nGp05 A(&)I'|!舩s<18ʨ1߲ٿiֻaǣ"вFϰCzбEϯAxʧ/ή?ҵOĞ̪7вGn׼_ϰBȣ(вIбEÜғҴOӗɀʧ.ȥ'›ϰHŠĝ˩2ϯAвG˨1x׽`˨/ڧӷUǢ!ơ˃ֻ^ʧ/ί>˃uֻa~okΌɦ2˨2ĝvơ ѳL̫@}̪6вFƠ˂סʧ.̫5Ş(0` $ȣ$ӷTή=˄şֻ_ɦ,̫8ΌšÜ׽huѳIš՜ѲI׽dͬ:ήAչ\ş ӶQؾfʨ3׼cƠ%pÜ̪4ʧ-ȣ,ּaέH۪Ǣ%Әպ^ͫ8hjչXȤ&™ ή>ʧ.ԷTؾe׼bѳKɦ+š ›ԸSʧ.ؿjÜ˩2ӶRؾe׽aҵOչXyܭ̇šwɦ-Ǣ$ғѳOܭ̪5۪pƠ ȥ&ѳJέ;Ȥ$չ]̈ơ"ݮԸ\պ^ʨ4tʧ-ĝٿmͬ9ǣ$ֻaɦ/›׽dơ™˨3ҵRƠȥ(ҴL›ɦ+չ\}Ǣ#ԸVʧ.PNG  IHDR?1%IDATxy|]Wuksj&K<&c;!!B J楄>GBiK)P$%!!8<϶lkt[lKǟG=WZsZVD/b'VKXBjPc+%X, ` 5VKXBjPc+%X, ` 5VKXBjPc+%X, ` 5VKXBjPc+%X, ` 5VKXBjPc+%X, ` 5VKXB ADf"fhfXH Zi_C 8B "V`!g=HxZɚ@2oM3b{?!)+\IZRםm;;uH}5XYoI]W/D̚LKA*W߳P‘ց $AeW4{ż |fh ˝~7%t2N2hD*>w^B1K"y |͗֔{Es+UN7")3Ċo\>布Gy^Y5FV3 Oue$<| ʋy|hT`Xf^9ؑ,RWszΩ?C,V!o3چr|Qk +gQGi+@`HEu}F1ciUMlxX VsF% W p p*X WהF<1#,u+@>Dm^H}q$ v4A1s10b~Y ր Ozͱˠ 'LZD+@~Dܓ1yn@Y ƅ ?JKMw;žV H']}ތ7YӋ+@~pċLJ&OEw $n-`BzxO鵵 Sh,߉He|\C=2겝4bPB }]w ॎd+UGFu5/~{;Hqcm˛T֮aovYlN".7O'>|8BDm V@؍w\8wwu ˘{/}'u쓄 'j;V { _\]9p%blRl&| 3% /}ކdaA Bi՗ &OV@;5]zMhF $BN0m i_?R ^A0Ĭ3)^@43siٕ6a(l$? ,GK"aչz{SfVyrB]"@T֛]UrgTKcLj[O꿛{mg[`VF[KdokIq(aо䊦WND>.a-=&W4V<{J \/ 0uH%cYwb/]KXޤ9pF?Hgǖ6~~E9B刑r4f]iffkgV Ҟi}-jܷwM=&@ij " &!W *A>0>Q=LKETS`H"xCk~Z57Vi ҞZVuA-@(m¦0Uůi(\i Z|'6D;đ^uBp] QK (_-.Å_ I <ˎI PdA;L/vo[P7" MxMPue<("(_ͪ,Ȣzۿg;Bͼ6^™ړlɅ+΋ɟBnEgG " 8DUH@xdZԋ? #􊢏.p߶-J&Ye}?ӞϾ֞3?챯QAj ,H1+8ýϨ4i0/M%!A6.xi{/'ҕOv4WTbNyC=9_Ii "7T|sD&lw!pD!ĥ^{7;RDf.Gsʘ > 4D7IIGf)|ۑefzk*l?-⎸߽fܲMXAswUܾ~x SfwfU~ri#l+͂(D*N9Yt=/eެwY]s_yJؓDDTƿd+?wQ#Yb:W*bW~y޸(=_$O㔗M2m'?..5s@p 8q]>ڎTSI}lEzwϫ~敗ԔzbBN_{gM{V.I7Q' )13'c31=' _wt$l-r?_kJ҆|Ҳ{L[9onZ~*?3@a ɸBĥ8PbakQ{ػ^ W-pi(;su{n,W/8`~Wə}ӻҾ^](qMTq~גEե*`E\pAs`ogrZ~ׁ# pAг2J8ہch(;/LDu~0 &˟νޞ4˝t֣D]2Y+;.:9/cIk^1_O}؉A)8s+̾an3x#[렝}+tERϻl;Ʌ}mr{nP@3kk+8"uWM)|nY|pds?ӁUHW4aG&sk_I|R+k82s.)^Sglv">݃[ٻV.{c%ַDiv}{KKWrXF]+@0[=ؑ>oA1/*//?OLP>s֖M-lfilKR9b{rcgTVbWeo+9zTf}s{];4<-%Ig3ǂ^33+OAi8.*^SXU$:%z3b{rcdG*98(Q瞗5D?g6ǂOwP̮]~C)-#L[$Jݏ,g!]5^R#A_wO/YSXUlzqdK9ɍ/wvȩw9\ $'3\@3kxdGA:x|dFA~g h_ϩ(vqGѠv AӟM_yEJCiDD]1m4cAߗ7t$7'7v&7uvSfkAcAA0Tο~^YVUr|d #ܜ ' Ҿiqnk ʋ^]&7k+եjJ&./sǾ'؞Б|#ko؃7$Hgtuý7̞]RS:+#ڇs;ҏ76`~Ko*= gW`Q WI0o\'62ph0\Ǝ䆎pƇ7=/G@d9q؛P l$ mП_`*n`&)AoN2 P 8D#CEQ)J)""g!E$i2tL|bA.-~>J>sF`05Sp P x# z v3NuHD9,κ@p(yF їBw )[C'˛F4|=iʿ0%dW!EA,X(a!i[o%84#;JRBӹǚ{0@郧[- nA0SI*Gvñ%'m"fǛ{ # 0tfaW@' '"crXFk>u#}y^T89C|nOf'ˎH~T_םmO)}^j`JsR輦fvLfvA8" O ey^& Onm$.LskGtj5u;et[cXư,^ӽt*_ڔ֖ဌڡbfA9n~!Hn=JEذ9_AJ> 4CAr'v"P'XaHǶ~{k#Υ'[`Zk_٧wK)X7ܖk ~k`چ"Gjf=AE#%;Vu 8fրs~ݿkDȔ<(5=p\_Cvbfy p ؜v.u~H"ÀfSDD?~ONߛWsz?  $Ţeh+K\Ӿ̩#CξL 5ʦ^؟/hTɝXހ ;V,Pk3GZC1 #G  7N `o޷چ屭 b#; > R96qԼ2 WʨE+#ppqEd b>yHW_xռgncfR|Qw}]/B9]mZ31+Bf5ZEYmjVQUZ[+B/\2m 93}%&sqpݛʮ.E)=VD*_TKg҆ ʙ!q/>bR)-0X@u"~AGD̙uIQ[+WV϶{SOݵf#C?{f/)k&S_y [0Ά wO/k;ؗ-ɛo{i ώ]05ZAP{<]S"tˇW~F|;B-@?,7/z10Cl/VXX]|DO&@ % _3lx[3f6U*竜{l-$Bz FiO-.;.,v=gF$Ҿڛº%UōES5E1Pn8 ) фthfo]&>𕍇:mHnOJ[\/ ܶP~ýb&By2?A WxGSŐ>ެ˼6b!5G]_TU̚׬4+榒/vf d.:ߺzA5aM7Gfso[ OGf\Q_ΦJ\ d2}8bᴒ.(_PYT5ӹM;R,zBr]6ouMi[:YKy.@ +`šl`D`VY/Qqa݇^Pf hOݝD:sk|Eza E43~ .3@:C 0DSB+g3닣 ^hdk‡GK0G> ?zM[ʋy<[E^=?T#O)fس'aM$ $R9o_چkK :U*FK08*0g^=lQyў|ndPj^5܃:?|“M1KC٧ZھIp #33 4%Ib@1-iԳ{:y_9Cнe^M]Q,4::"W6Lsv+`b *$އ5Dg$F=?8yuRfG6 Hf\A2@/l8-"b+GL0MTnfsה>LAҟ!Etuf#G>Ԯ 'eQ̸_Y͘`ζ۟ b9˨8"5h${(f*ufa#ƛn]\:-@3CSф!"#"xKZUSjnͪέ*)H!`f?yN"(_5UݱTL5/(ny|%q|ve𢺊Oڮyڒ-Gf%ҥ%я.0I/D̳Jc7άea&X"򺲹8cV~N]|p~ [ /PRcΉ\VWVsf` 4#\RSDI"*A$v `3#rL`4tAe1<8H`8D 6+CO^I:h#?IꢀaJ`O+v 4IDYP2L9u-9YG`@ޛHI~9"_AH{6HN3< eCہP( ̀ϴp&y.lʠԑd}׺<,43\ۖW1N?ISdBJ`2vq9c7ݰBLʟIm#'NfH)|3 ̎}Ն Dq8K3Eo~~S|9fI!l S!Y??;&94 ݛ:-*g @3KWڑuѹG*fGCA ^Q P`*XEu~9J#G{;>m p @iq=7rT8pr=v(D~ڡZFq <{僛:eZib~9&-H*{j)n,T鞎]Yƒgki>VFJlVD)O}wGۇJKڦ[#qOd/]y̪_8eQt9 aB8.[N`0H"9AeőWז-(JrI1䩝}]}}ݽ)?ÕB ib9 Ci( )`A3|A4зH:%fjKtLSsz$IDXets”yr-A_X&+%X, ` 5VKXBjPc+%X, ` 5VKXBjPc+%X, ` 5VKXBjPc+%X, ` 5VKXBjPc+%X, ` 5VKXBjPc+%X,'IENDB`icinga2-2.14.6/choco/000077500000000000000000000000001501332562400142145ustar00rootroot00000000000000icinga2-2.14.6/choco/CMakeLists.txt000066400000000000000000000003121501332562400167500ustar00rootroot00000000000000# Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ if(WIN32) configure_file(icinga2.nuspec.cmake icinga2.nuspec) configure_file(chocolateyInstall.ps1.template.cmake chocolateyInstall.ps1.template) endif() icinga2-2.14.6/choco/chocolateyInstall.ps1.template.cmake000066400000000000000000000012321501332562400232110ustar00rootroot00000000000000$packageName= 'icinga2' $toolsDir = "$(Split-Path -Parent $MyInvocation.MyCommand.Definition)" $url = 'https://packages.icinga.com/windows/Icinga2-v${CHOCO_VERSION_SHORT}-x86.msi' $url64 = 'https://packages.icinga.com/windows/Icinga2-v${CHOCO_VERSION_SHORT}-x86_64.msi' $packageArgs = @{ packageName = $packageName fileType = 'msi' url = $url url64bit = $url64 silentArgs = "/qn /norestart" validExitCodes= @(0) softwareName = 'Icinga 2*' checksum = '%CHOCO_32BIT_CHECKSUM%' checksumType = 'sha256' checksum64 = '%CHOCO_64BIT_CHECKSUM%' checksumType64= 'sha256' } Install-ChocolateyPackage @packageArgsicinga2-2.14.6/choco/chocolateyUninstall.ps1000066400000000000000000000015071501332562400206700ustar00rootroot00000000000000$packageName = "Icinga 2"; $fileType = 'msi'; $silentArgs = '/qr /norestart' $validExitCodes = @(0) $packageGuid = Get-ChildItem HKLM:\SOFTWARE\Classes\Installer\Products | Get-ItemProperty -Name 'ProductName' | ? { $_.ProductName -like $packageName + "*"} | Select -ExpandProperty PSChildName -First 1 $properties = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\$packageGuid\InstallProperties $file = $properties.LocalPackage # Would like to use the following, but looks like there is a bug in this method when uninstalling MSI's # Uninstall-ChocolateyPackage $packageName $fileType $silentArgs $file -validExitCodes $validExitCodes # Use this instead $msiArgs = "/x $file $silentArgs"; Start-ChocolateyProcessAsAdmin "$msiArgs" 'msiexec' -validExitCodes $validExitCodes icinga2-2.14.6/choco/icinga2.nuspec.cmake000077500000000000000000000036601501332562400200360ustar00rootroot00000000000000 icinga2 Icinga 2 ${ICINGA2_VERSION_SAFE} Icinga GmbH Icinga GmbH icinga2 - Monitoring Agent for Windows Icinga is an open source monitoring platform which notifies users about host and service outages. https://icinga.com/ icinga2 icinga agent monitoring admin https://github.com/Icinga/icinga2/blob/master/COPYING https://github.com/Icinga/icinga2/blob/master/ChangeLog https://icinga.com/docs/icinga2/latest/ https://github.com/Icinga/icinga2/issues https://github.com/Icinga/icinga2 https://github.com/Icinga/icinga2 false https://raw.githubusercontent.com/Icinga/icinga2/master/icinga-app/icinga.ico icinga2-2.14.6/cmake/000077500000000000000000000000001501332562400142015ustar00rootroot00000000000000icinga2-2.14.6/cmake/FindJSON.cmake000066400000000000000000000004211501332562400165520ustar00rootroot00000000000000FIND_PATH (JSON_INCLUDE json.hpp HINTS "${PROJECT_SOURCE_DIR}/third-party/nlohmann_json") if (JSON_INCLUDE) set(JSON_BuildTests OFF CACHE INTERNAL "") message(STATUS "Found JSON: ${JSON_INCLUDE}" ) else () message(FATAL_ERROR "Unable to include json.hpp") endif () icinga2-2.14.6/cmake/FindUTF8CPP.cmake000066400000000000000000000003541501332562400170770ustar00rootroot00000000000000FIND_PATH (UTF8CPP_INCLUDE utf8.h HINTS "${PROJECT_SOURCE_DIR}/third-party/utf8cpp/source") if (UTF8CPP_INCLUDE) message(STATUS "Found UTF8CPP: ${UTF8CPP_INCLUDE}" ) else () message(FATAL_ERROR "Unable to include utf8.h") endif () icinga2-2.14.6/cmake/InstallConfig.cmake000066400000000000000000000026741501332562400177500ustar00rootroot00000000000000# Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ # # Install $src into directory $dest - usually only used for config files # # * similar to install() a non absolute path is prefixed with CMAKE_INSTALL_PREFIX on runtime # * in case of CPack path with be prefixed with share/skel/ # * DESTDIR is prefixed as well # # also see https://cmake.org/cmake/help/latest/command/install.html function(install_if_not_exists src dest) if(NOT IS_ABSOLUTE "${src}") set(src "${CMAKE_CURRENT_SOURCE_DIR}/${src}") endif() get_filename_component(src_name "${src}" NAME) install(CODE " set(dest \"${dest}\") if (\"\${CMAKE_INSTALL_PREFIX}\" MATCHES .*/_CPack_Packages/.*) set(dest \"share/skel/\${dest}\") set(force_overwrite TRUE) else() set(force_overwrite FALSE) endif() if(NOT IS_ABSOLUTE \"\${dest}\") set(dest \"\${CMAKE_INSTALL_PREFIX}/\${dest}\") endif() set(full_dest \"\$ENV{DESTDIR}\${dest}/${src_name}\") if(force_overwrite OR NOT EXISTS \"\${full_dest}\") message(STATUS \"Installing: ${src} into \${full_dest}\") execute_process(COMMAND \${CMAKE_COMMAND} -E copy \"${src}\" \"\${full_dest}\" RESULT_VARIABLE copy_result ERROR_VARIABLE error_output) if(copy_result) message(FATAL_ERROR \${error_output}) endif() else() message(STATUS \"Skipping : \${full_dest}\") endif() ") endfunction(install_if_not_exists) icinga2-2.14.6/cmake/SetFullDir.cmake000066400000000000000000000007551501332562400172270ustar00rootroot00000000000000# Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ # # Ensures a directory is absolute by prefixing CMAKE_INSTALL_PREFIX if it is not # similar to CMAKE_INSTALL_FULL_... https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html function(set_full_dir var path) if(NOT IS_ABSOLUTE "${path}") message(STATUS "Prefixing in ${var} \"${path}\" with ${CMAKE_INSTALL_PREFIX}") set(path "${CMAKE_INSTALL_PREFIX}/${path}") endif() set(${var} "${path}" PARENT_SCOPE) endfunction(set_full_dir) icinga2-2.14.6/config.h.cmake000066400000000000000000000025261501332562400156230ustar00rootroot00000000000000#ifndef CONFIG_H #define CONFIG_H #cmakedefine HAVE_BACKTRACE_SYMBOLS #cmakedefine HAVE_PIPE2 #cmakedefine HAVE_VFORK #cmakedefine HAVE_DLADDR #cmakedefine HAVE_LIBEXECINFO #cmakedefine HAVE_CXXABI_H #cmakedefine HAVE_NICE #cmakedefine HAVE_MALLOC_INFO #cmakedefine HAVE_EDITLINE #cmakedefine HAVE_SYSTEMD #cmakedefine ICINGA2_UNITY_BUILD #cmakedefine ICINGA2_STACKTRACE_USE_BACKTRACE_SYMBOLS #define ICINGA_CONFIGDIR "${ICINGA2_FULL_CONFIGDIR}" #define ICINGA_DATADIR "${ICINGA2_FULL_DATADIR}" #define ICINGA_LOGDIR "${ICINGA2_FULL_LOGDIR}" #define ICINGA_CACHEDIR "${ICINGA2_FULL_CACHEDIR}" #define ICINGA_SPOOLDIR "${ICINGA2_FULL_SPOOLDIR}" #define ICINGA_INITRUNDIR "${ICINGA2_FULL_INITRUNDIR}" #define ICINGA_INCLUDECONFDIR "${ICINGA2_FULL_INCLUDEDIR}" #define ICINGA_USER "${ICINGA2_USER}" #define ICINGA_GROUP "${ICINGA2_GROUP}" #define ICINGA_BUILD_HOST_NAME "${ICINGA2_BUILD_HOST_NAME}" #define ICINGA_BUILD_COMPILER_NAME "${ICINGA2_BUILD_COMPILER_NAME}" #define ICINGA_BUILD_COMPILER_VERSION "${ICINGA2_BUILD_COMPILER_VERSION}" // Deprecated options? #define ICINGA_PKGDATADIR "${ICINGA2_FULL_PKGDATADIR}" #define ICINGA_PREFIX "${CMAKE_INSTALL_PREFIX}" #define ICINGA_SYSCONFDIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}" #define ICINGA_RUNDIR "${ICINGA2_FULL_RUNDIR}" #define ICINGA_LOCALSTATEDIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}" #endif /* CONFIG_H */ icinga2-2.14.6/doc/000077500000000000000000000000001501332562400136665ustar00rootroot00000000000000icinga2-2.14.6/doc/.gitignore000066400000000000000000000000141501332562400156510ustar00rootroot00000000000000build *.rst icinga2-2.14.6/doc/01-about.md000066400000000000000000000061661501332562400155510ustar00rootroot00000000000000# About Icinga 2 ## What is Icinga 2? [Icinga](https://icinga.com/products/) is a monitoring system which checks the availability of your network resources, notifies users of outages, and generates performance data for reporting. Scalable and extensible, Icinga can monitor large, complex environments across multiple locations. This includes your data center as well as your private, public, or hybrid clouds. Icinga 2 is the monitoring server and requires [Icinga Web 2](https://icinga.com/products/) on top in your Icinga Stack. The [configuration](https://icinga.com/products/configuration/) can be easily managed with either the [Icinga Director](https://icinga.com/docs/director/latest/), config management tools or plain text within the [Icinga DSL](04-configuration.md#configuration). ![Icinga 2 Distributed Master and Satellites with Agents](images/distributed-monitoring/icinga2_distributed_monitoring_scenarios_master_satellites_agents.png) ## Start with Icinga * [Installation](02-installation.md#installation) * [Monitoring Basics](03-monitoring-basics.md#monitoring-basics) * [Configuration](04-configuration.md#configuration) * [Distributed Monitoring](06-distributed-monitoring.md#distributed-monitoring) * [Addons, Integrations and Features](13-addons.md#addons) * [Troubleshooting](15-troubleshooting.md#troubleshooting) * [Upgrading](16-upgrading-icinga-2.md#upgrading-icinga-2) Once Icinga Server and Web are running in your distributed environment, make sure to check out the many [Icinga modules](https://icinga.com/docs/) for even better monitoring. ## What's New You can follow the development and release milestones on [GitHub](https://github.com/icinga/icinga2/issues). Please follow our release announcements on [icinga.com](https://icinga.com/blog/) too. ## Support Check the project website at [icinga.com](https://icinga.com) for status updates. Join the [community channels](https://icinga.com/community/) for questions or get in touch for [professional support](https://icinga.com/subscription/). ## Contribute There are many ways to contribute to Icinga -- whether it be sending patches, testing, reporting bugs or reviewing and updating the documentation. Every contribution is appreciated! Please continue reading in the [Contributing chapter](https://github.com/Icinga/icinga2/blob/master/CONTRIBUTING.md). ### Security Issues For reporting security issues please visit [this page](https://icinga.com/contact/security/). ### Icinga 2 Development The Git repository is located on [GitHub](https://github.com/Icinga/icinga2). Icinga 2 is written in C++ and can be built on Linux/Unix and Windows. Read more about development builds in the [development chapter](21-development.md#development). ## License Icinga 2 and the Icinga 2 documentation are licensed under the terms of the GNU General Public License Version 2. You will find a copy of this license in the LICENSE file included in the source package. icinga2-2.14.6/doc/02-installation.md000066400000000000000000000442241501332562400171360ustar00rootroot00000000000000 # Installation This tutorial is a step-by-step introduction to install Icinga 2. It assumes that you are familiar with the operating system you're using to install Icinga 2. Please follow the steps listed for your operating system. Packages for distributions other than the ones listed here may also be available. Please refer to [icinga.com/get-started/download](https://icinga.com/get-started/download/#community) for a full list of available community repositories. ## Upgrade In case you are upgrading an existing setup, please ensure to follow the [upgrade documentation](16-upgrading-icinga-2.md#upgrading-icinga-2). ## Add Icinga Package Repository We recommend using our official repositories. All the following commands should be executed as the root user. As pipes and nested commands are used, it is recommended to switch to a root user session, e.g., using `sudo -i`. Here's how to add it to your system: ### Debian Repository ```bash apt update apt -y install apt-transport-https wget wget -O icinga-archive-keyring.deb "https://packages.icinga.com/icinga-archive-keyring_latest+debian$( . /etc/os-release; echo "$VERSION_ID" ).deb" apt install ./icinga-archive-keyring.deb DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \ echo "deb [signed-by=/usr/share/keyrings/icinga-archive-keyring.gpg] https://packages.icinga.com/debian icinga-${DIST} main" > \ /etc/apt/sources.list.d/${DIST}-icinga.list echo "deb-src [signed-by=/usr/share/keyrings/icinga-archive-keyring.gpg] https://packages.icinga.com/debian icinga-${DIST} main" >> \ /etc/apt/sources.list.d/${DIST}-icinga.list apt update ``` ### Ubuntu Repository ```bash apt update apt -y install apt-transport-https wget wget -O icinga-archive-keyring.deb "https://packages.icinga.com/icinga-archive-keyring_latest+ubuntu$( . /etc/os-release; echo "$VERSION_ID" ).deb" apt install ./icinga-archive-keyring.deb . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \ echo "deb [signed-by=/usr/share/keyrings/icinga-archive-keyring.gpg] https://packages.icinga.com/ubuntu icinga-${DIST} main" > \ /etc/apt/sources.list.d/${DIST}-icinga.list echo "deb-src [signed-by=/usr/share/keyrings/icinga-archive-keyring.gpg] https://packages.icinga.com/ubuntu icinga-${DIST} main" >> \ /etc/apt/sources.list.d/${DIST}-icinga.list apt update ``` ### RHEL Repository !!! info A paid repository subscription is required for RHEL repositories. Get more information on [icinga.com/subscription](https://icinga.com/subscription) Don't forget to fill in the username and password section with your credentials in the local .repo file. ```bash wget https://packages.icinga.com/subscription/rhel/ICINGA-release.repo -O /etc/yum.repos.d/ICINGA-release.repo ``` If you are using RHEL you need to additionally enable the `codeready-builder` repository before installing the [EPEL rpm package](https://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F). #### RHEL 8 or Later ```bash ARCH=$(/bin/arch) OSVER=$(. /etc/os-release; echo "${VERSION_ID%%.*}") subscription-manager repos --enable "codeready-builder-for-rhel-${OSVER}-${ARCH}-rpms" dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-${OSVER}.noarch.rpm ``` ### Fedora Repository ```bash dnf install -y 'dnf-command(config-manager)' dnf config-manager --add-repo https://packages.icinga.com/fedora/$(. /etc/os-release; echo "$VERSION_ID")/release ``` ### SLES Repository !!! info A paid repository subscription is required for SLES repositories. Get more information on [icinga.com/subscription](https://icinga.com/subscription) Don't forget to fill in the username and password section with your credentials in the local .repo file. ```bash zypper ar https://packages.icinga.com/subscription/sles/ICINGA-release.repo zypper ref ``` You need to additionally add the `PackageHub` repository to fulfill dependencies: ```bash source /etc/os-release SUSEConnect -p PackageHub/$VERSION_ID/x86_64 ``` ### openSUSE Repository ```bash zypper ar https://packages.icinga.com/openSUSE/ICINGA-release.repo zypper ref ``` ### Amazon Linux Repository !!! info A paid repository subscription is required for Amazon Linux repositories. Get more information on [icinga.com/subscription](https://icinga.com/subscription) Don't forget to fill in the username and password section with your credentials in the local .repo file. ```bash wget https://packages.icinga.com/subscription/amazon/ICINGA-release.repo -O /etc/yum.repos.d/ICINGA-release.repo ``` The packages for **Amazon Linux 2** depend on other packages which are distributed as part of the [EPEL repository](https://fedoraproject.org/wiki/EPEL). ```bash yum install epel-release ``` The packages for newer versions of Amazon Linux don't require additional repositories. ### Icinga for Windows Repository [Icinga for Windows](https://icinga.com/docs/icinga-for-windows/latest/doc/000-Introduction/) is the recommended way to install and update Icinga 2 on Windows. We provide a dedicated repository for Windows to simplify the installation. Please refer to the official [Icinga for Windows installation docs](https://icinga.com/docs/icinga-for-windows/latest/doc/110-Installation/01-Getting-Started/) ## Install Icinga 2 You can install Icinga 2 by using your distribution's package manager to install the `icinga2` package. The following commands must be executed with `root` permissions unless noted otherwise. !!! tip If you have [SELinux](22-selinux.md) enabled, the package `icinga2-selinux` is also required. #### Debian / Ubuntu / Raspberry Pi OS ```bash apt install icinga2 ``` #### RHEL 8 or Later ```bash dnf install icinga2 systemctl enable icinga2 systemctl start icinga2 ``` #### Fedora ```bash dnf install icinga2 systemctl enable icinga2 systemctl start icinga2 ``` #### SLES / openSUSE ```bash zypper install icinga2 ``` #### Amazon Linux ```bash yum install icinga2 systemctl enable icinga2 systemctl start icinga2 ``` ### Systemd Service The majority of supported distributions use systemd. The Icinga 2 packages automatically install the necessary systemd unit files. If you're stuck with configuration errors, you can manually invoke the [configuration validation](11-cli-commands.md#config-validation). ```bash icinga2 daemon -C ``` !!! tip If you are running into fork errors with systemd enabled distributions, please check the [troubleshooting chapter](15-troubleshooting.md#check-fork-errors). ## Set up Check Plugins Without plugins Icinga 2 does not know how to check external services. The [Monitoring Plugins Project](https://www.monitoring-plugins.org/) provides an extensive set of plugins which can be used with Icinga 2 to check whether services are working properly. These plugins are required to make the [example configuration](04-configuration.md#configuring-icinga2-overview) work out-of-the-box. Depending on which directory your plugins are installed into you may need to update the global `PluginDir` constant in your [Icinga 2 configuration](04-configuration.md#constants-conf). This constant is used by the check command definitions contained in the Icinga Template Library to determine where to find the plugin binaries. !!! tip Please refer to the [service monitoring](05-service-monitoring.md#service-monitoring-plugins) chapter for details about how to integrate additional check plugins into your Icinga 2 setup. #### Debian / Ubuntu / Raspberry Pi OS ```bash apt install monitoring-plugins ``` #### RHEL The packages for RHEL depend on other packages which are distributed as part of the EPEL repository. #### RHEL 8 or Later ```bash dnf install nagios-plugins-all ``` #### Fedora ```bash dnf install nagios-plugins-all ``` #### SLES / openSUSE The packages depend on other packages which are distributed as part of the [server:monitoring repository](https://build.opensuse.org/project/repositories/server:monitoring). Please make sure to enable this repository beforehand. ```bash zypper install --recommends monitoring-plugins-all ``` #### Amazon Linux The packages for **Amazon Linux 2** depend on other packages which are distributed as part of the EPEL repository. ```bash amazon-linux-extras install epel yum install nagios-plugins-all ``` Unfortunately newer versions of Amazon Linux don't provide those plugins, yet. ## Set up Icinga 2 API Almost every Icinga 2 setup requires the Icinga 2 API as Icinga Web connects to it, Icinga DB requires it, and it enables cluster communication functionality for highly available and distributed setups. !!! info If you set up a highly available and/or distributed Icinga monitoring environment, please read the [Distributed Monitoring](06-distributed-monitoring.md#distributed-monitoring) chapter as the commands to set up the API are different from setting up a single node setup. See the [API](12-icinga2-api.md#icinga2-api-setup) chapter for details, or follow the steps below to set up the API quickly: Run the following command to: * enable the `api` feature, * set up certificates, and * add the API user `root` with an auto-generated password in the configuration file `/etc/icinga2/conf.d/api-users.conf`. ```bash icinga2 api setup ``` Restart Icinga 2 for these changes to take effect. ```bash systemctl restart icinga2 ``` ## Set up Icinga DB Icinga DB is a set of components for publishing, synchronizing and visualizing monitoring data in the Icinga ecosystem, consisting of: * Icinga 2 with its `icingadb` feature enabled, responsible for publishing monitoring data to a Redis server, i.e. configuration and its runtime updates, check results, state changes, downtimes, acknowledgements, notifications, and other events such as flapping * The [Icinga DB daemon](https://icinga.com/docs/icinga-db), which synchronizes the data between the Redis server and a database * And Icinga Web with the [Icinga DB Web](https://icinga.com/docs/icinga-db-web) module enabled, which connects to both Redis and the database to display and work with the most up-to-date data ![Icinga DB Architecture](images/icingadb/icingadb-architecture.png) !!! info Setting up Icinga 2's Icinga DB feature is only required for Icinga 2 master nodes or single-node setups. ### Set up Redis Server A Redis server from version 6.2 is required. !!! info This guide sets up the `icingadb-redis` package provided by Icinga, which ships a current Redis Server version and is preconfigured for the Icinga DB components. Using own Redis server setups is supported as long as the version requirements are met. ![Icinga DB Redis](images/icingadb/icingadb-redis.png) !!! tip Although the Redis server can run anywhere in an Icinga environment, we recommend to install it where the corresponding Icinga 2 node is running to keep latency between the components low. #### Install Icinga DB Redis Package Use your distribution's package manager to install the `icingadb-redis` package as follows: ##### Amazon Linux ```bash yum install icingadb-redis ``` ##### Debian / Ubuntu / Raspberry Pi OS ```bash apt install icingadb-redis ``` ##### RHEL 8 or Later ```bash dnf install icingadb-redis ``` ##### SLES ```bash zypper install icingadb-redis ``` #### Run Icinga DB Redis The `icingadb-redis` package automatically installs the necessary systemd unit files to run Icinga DB Redis. Please run the following command to enable and start its service: ```bash systemctl enable --now icingadb-redis ``` #### Enable Remote Redis Connections By default, `icingadb-redis` only listens on `127.0.0.1`. If Icinga Web or Icinga 2 is running on another node, remote access to the Redis server must be allowed. This requires the following directives to be set in the `/etc/icingadb-redis/icingadb-redis.conf` configuration file: * Set `protected-mode` to `no`, i.e. `protected-mode no` * Set `bind` to the desired binding interface or bind all interfaces, e.g. `bind 0.0.0.0` !!! warning By default, Redis has no authentication preventing others from accessing it. When opening Redis to an external interface, make sure to set a password, set up appropriate firewall rules, or configure TLS with certificate authentication on Redis and its consumers, i.e. Icinga 2, Icinga DB and Icinga Web. Restart Icinga DB Redis for these changes to take effect: ```bash systemctl restart icingadb-redis ``` ### Enable Icinga DB Feature With the [Icinga DB feature](14-features.md#icinga-db) enabled, Icinga 2 publishes all of its monitoring data to the Redis server. This includes configuration and its runtime updates via the Icinga 2 API, check results, state changes, downtimes, acknowledgments, notifications and other events such as flapping. ![Icinga DB Icinga 2](images/icingadb/icingadb-icinga2.png) Icinga 2 installs the feature configuration file to `/etc/icinga2/features-available/icingadb.conf`, pre-configured for a local setup. Update this file in case Redis is running on a different host or to set credentials. All available settings are explained in the [Icinga DB object](09-object-types.md#icingadb) chapter. !!! important For single-node and high-availability setups, please read the note about the [environment ID](https://icinga.com/docs/icinga-db/latest/doc/05-Distributed-Setups/#environment-id), which is common to all Icinga DB components and generated by the Icinga DB feature. To enable the `icingadb` feature use the following command: ```bash icinga2 feature enable icingadb ``` Restart Icinga 2 for these changes to take effect: ```bash systemctl restart icinga2 ``` ### Install Icinga DB Daemon After installing Icinga 2, setting up a Redis server and enabling the `icingadb` feature, the Icinga DB daemon that synchronizes monitoring data between the Redis server and a database is now set up. ![Icinga DB Daemon](images/icingadb/icingadb-daemon.png) !!! tip Although the Icinga DB daemon can run anywhere in an Icinga environment, we recommend to install it where the corresponding Icinga 2 node and Redis server is running to keep latency between the components low. The Icinga DB daemon package is also included in the Icinga repository, and since it is already set up, you have completed the instructions here and can proceed to [install the Icinga DB daemon on Amazon Linux](https://icinga.com/docs/icinga-db/latest/doc/02-Installation/Amazon-Linux/#installing-the-package), [install the Icinga DB daemon on Debian](https://icinga.com/docs/icinga-db/latest/doc/02-Installation/Debian/#installing-the-package), [install the Icinga DB daemon on RHEL](https://icinga.com/docs/icinga-db/latest/doc/02-Installation/RHEL/#installing-the-package), [install the Icinga DB daemon on SLES](https://icinga.com/docs/icinga-db/latest/doc/02-Installation/SLES/#installing-the-package), [install the Icinga DB daemon on Ubuntu](https://icinga.com/docs/icinga-db/latest/doc/02-Installation/Ubuntu/#installing-the-package), which will also guide you through the setup of the database and Icinga DB Web. ## Backup Ensure to include the following in your backups: * Configuration files in `/etc/icinga2` * Certificate files in `/var/lib/icinga2/ca` (Master CA key pair) and `/var/lib/icinga2/certs` (node certificates) * Runtime files in `/var/lib/icinga2` icinga2-2.14.6/doc/02-installation.md.d/000077500000000000000000000000001501332562400174275ustar00rootroot00000000000000icinga2-2.14.6/doc/02-installation.md.d/01-Debian.md000066400000000000000000000001521501332562400213470ustar00rootroot00000000000000# Install Icinga 2 on Debian icinga2-2.14.6/doc/02-installation.md.d/02-Ubuntu.md000066400000000000000000000001521501332562400214500ustar00rootroot00000000000000# Install Icinga 2 on Ubuntu icinga2-2.14.6/doc/02-installation.md.d/03-Raspberry-Pi-OS.md000066400000000000000000000001631501332562400230270ustar00rootroot00000000000000# Install Icinga 2 on Raspberry Pi OS icinga2-2.14.6/doc/02-installation.md.d/04-Fedora.md000066400000000000000000000001521501332562400213700ustar00rootroot00000000000000# Install Icinga 2 on Fedora icinga2-2.14.6/doc/02-installation.md.d/06-RHEL.md000066400000000000000000000001461501332562400207270ustar00rootroot00000000000000# Install Icinga 2 on RHEL icinga2-2.14.6/doc/02-installation.md.d/07-OpenSUSE.md000066400000000000000000000001561501332562400216000ustar00rootroot00000000000000# Install Icinga 2 on openSUSE icinga2-2.14.6/doc/02-installation.md.d/08-SLES.md000066400000000000000000000001461501332562400207450ustar00rootroot00000000000000# Install Icinga 2 on SLES icinga2-2.14.6/doc/02-installation.md.d/09-Amazon-Linux.md000066400000000000000000000001661501332562400225240ustar00rootroot00000000000000# Install Icinga 2 on Amazon Linux icinga2-2.14.6/doc/02-installation.md.d/10-Windows.md000066400000000000000000000001541501332562400216210ustar00rootroot00000000000000# Install Icinga 2 on Windows icinga2-2.14.6/doc/03-monitoring-basics.md000066400000000000000000003352321501332562400200670ustar00rootroot00000000000000# Monitoring Basics This part of the Icinga 2 documentation provides an overview of all the basic monitoring concepts you need to know to run Icinga 2. Keep in mind these examples are made with a Linux server. If you are using Windows, you will need to change the services accordingly. See the [ITL reference](10-icinga-template-library.md#windows-plugins) for further information. ## Attribute Value Types The Icinga 2 configuration uses different value types for attributes. Type | Example -------------------------------------------------------|--------------------------------------------------------- [Number](17-language-reference.md#numeric-literals) | `5` [Duration](17-language-reference.md#duration-literals) | `1m` [String](17-language-reference.md#string-literals) | `"These are notes"` [Boolean](17-language-reference.md#boolean-literals) | `true` [Array](17-language-reference.md#array) | `[ "value1", "value2" ]` [Dictionary](17-language-reference.md#dictionary) | `{ "key1" = "value1", "key2" = false }` It is important to use the correct value type for object attributes as otherwise the [configuration validation](11-cli-commands.md#config-validation) will fail. ## Hosts and Services Icinga 2 can be used to monitor the availability of hosts and services. Hosts and services can be virtually anything which can be checked in some way: * Network services (HTTP, SMTP, SNMP, SSH, etc.) * Printers * Switches or routers * Temperature sensors * Other local or network-accessible services Host objects provide a mechanism to group services that are running on the same physical device. Here is an example of a host object which defines two child services: ``` object Host "my-server1" { address = "10.0.0.1" check_command = "hostalive" } object Service "ping4" { host_name = "my-server1" check_command = "ping4" } object Service "http" { host_name = "my-server1" check_command = "http" } ``` The example creates two services `ping4` and `http` which belong to the host `my-server1`. It also specifies that the host should perform its own check using the `hostalive` check command. The `address` attribute is used by check commands to determine which network address is associated with the host object. Details on troubleshooting check problems can be found [here](15-troubleshooting.md#troubleshooting). ### Host States Hosts can be in any one of the following states: Name | Description ------------|-------------- UP | The host is available. DOWN | The host is unavailable. ### Service States Services can be in any one of the following states: Name | Description ------------|-------------- OK | The service is working properly. WARNING | The service is experiencing some problems but is still considered to be in working condition. CRITICAL | The check successfully determined that the service is in a critical state. UNKNOWN | The check could not determine the service's state. ### Check Result State Mapping [Check plugins](05-service-monitoring.md#service-monitoring-plugins) return with an exit code which is converted into a state number. Services map the states directly while hosts will treat `0` or `1` as `UP` for example. Value | Host State | Service State ------|------------|-------------- 0 | Up | OK 1 | Up | Warning 2 | Down | Critical 3 | Down | Unknown ### Hard and Soft States When detecting a problem with a host/service, Icinga re-checks the object a number of times (based on the `max_check_attempts` and `retry_interval` settings) before sending notifications. This ensures that no unnecessary notifications are sent for transient failures. During this time the object is in a `SOFT` state. After all re-checks have been executed and the object is still in a non-OK state, the host/service switches to a `HARD` state and notifications are sent. Name | Description ------------|-------------- HARD | The host/service's state hasn't recently changed. `check_interval` applies here. SOFT | The host/service has recently changed state and is being re-checked with `retry_interval`. ### Host and Service Checks Hosts and services determine their state by running checks in a regular interval. ``` object Host "router" { check_command = "hostalive" address = "10.0.0.1" } ``` The `hostalive` command is one of several built-in check commands. It sends ICMP echo requests to the IP address specified in the `address` attribute to determine whether a host is online. > **Tip** > > `hostalive` is the same as `ping` but with different default thresholds. > Both use the `ping` CLI command to execute sequential checks. > > If you need faster ICMP checks, look into the [icmp](10-icinga-template-library.md#plugin-check-command-icmp) CheckCommand. A number of other [built-in check commands](10-icinga-template-library.md#icinga-template-library) are also available. In addition to these commands the next few chapters will explain in detail how to set up your own check commands. #### Host Check Alternatives If the host is not reachable with ICMP, HTTP, etc. you can also use the [dummy](10-icinga-template-library.md#itl-dummy) CheckCommand to set a default state. ``` object Host "dummy-host" { check_command = "dummy" vars.dummy_state = 0 //Up vars.dummy_text = "Everything OK." } ``` This method is also used when you send in [external check results](08-advanced-topics.md#external-check-results). A more advanced technique is to calculate an overall state based on all services. This is described [here](08-advanced-topics.md#access-object-attributes-at-runtime-cluster-check). ## Templates Templates may be used to apply a set of identical attributes to more than one object: ``` template Service "generic-service" { max_check_attempts = 3 check_interval = 5m retry_interval = 1m enable_perfdata = true } apply Service "ping4" { import "generic-service" check_command = "ping4" assign where host.address } apply Service "ping6" { import "generic-service" check_command = "ping6" assign where host.address6 } ``` In this example the `ping4` and `ping6` services inherit properties from the template `generic-service`. Objects as well as templates themselves can import an arbitrary number of other templates. Attributes inherited from a template can be overridden in the object if necessary. You can also import existing non-template objects. > **Note** > > Templates and objects share the same namespace, i.e. you can't define a template > that has the same name like an object. ### Multiple Templates The following example uses [custom variables](03-monitoring-basics.md#custom-variables) which are provided in each template. The `web-server` template is used as the base template for any host providing web services. In addition to that it specifies the custom variable `webserver_type`, e.g. `apache`. Since this template is also the base template, we import the `generic-host` template here. This provides the `check_command` attribute by default and we don't need to set it anywhere later on. ``` template Host "web-server" { import "generic-host" vars = { webserver_type = "apache" } } ``` The `wp-server` host template specifies a Wordpress instance and sets the `application_type` custom variable. Please note the `+=` [operator](17-language-reference.md#dictionary-operators) which adds [dictionary](17-language-reference.md#dictionary) items, but does not override any previous `vars` attribute. ``` template Host "wp-server" { vars += { application_type = "wordpress" } } ``` The final host object imports both templates. The order is important here: First the base template `web-server` is added to the object, then additional attributes are imported from the `wp-server` object. ``` object Host "wp.example.com" { import "web-server" import "wp-server" address = "192.168.56.200" } ``` If you want to override specific attributes inherited from templates, you can specify them on the host object. ``` object Host "wp1.example.com" { import "web-server" import "wp-server" vars.webserver_type = "nginx" //overrides attribute from base template address = "192.168.56.201" } ``` ## Custom Variables In addition to built-in object attributes you can define your own custom attributes inside the `vars` attribute. > **Tip** > > This is called `custom variables` throughout the documentation, backends and web interfaces. > > Older documentation versions referred to this as `custom attribute`. The following example specifies the key `ssh_port` as custom variable and assigns an integer value. ``` object Host "localhost" { check_command = "ssh" vars.ssh_port = 2222 } ``` `vars` is a [dictionary](17-language-reference.md#dictionary) where you can set specific keys to values. The example above uses the shorter [indexer](17-language-reference.md#indexer) syntax. An alternative representation can be written like this: ``` vars = { ssh_port = 2222 } ``` or ``` vars["ssh_port"] = 2222 ``` ### Custom Variable Values Valid values for custom variables include: * [Strings](17-language-reference.md#string-literals), [numbers](17-language-reference.md#numeric-literals) and [booleans](17-language-reference.md#boolean-literals) * [Arrays](17-language-reference.md#array) and [dictionaries](17-language-reference.md#dictionary) * [Functions](03-monitoring-basics.md#custom-variables-functions) You can also define nested values such as dictionaries in dictionaries. This example defines the custom variable `disks` as dictionary. The first key is set to `disk /` is itself set to a dictionary with one key-value pair. ``` vars.disks["disk /"] = { disk_partitions = "/" } ``` This can be written as resolved structure like this: ``` vars = { disks = { "disk /" = { disk_partitions = "/" } } } ``` Keep this in mind when trying to access specific sub-keys in apply rules or functions. Another example which is shown in the example configuration: ``` vars.notification["mail"] = { groups = [ "icingaadmins" ] } ``` This defines the `notification` custom variable as dictionary with the key `mail`. Its value is a dictionary with the key `groups` which itself has an array as value. Note: This array is the exact same as the `user_groups` attribute for [notification apply rules](#03-monitoring-basics.md#using-apply-notifications) expects. ``` vars.notification = { mail = { groups = [ "icingaadmins" ] } } ``` ### Functions as Custom Variables Icinga 2 lets you specify [functions](17-language-reference.md#functions) for custom variables. The special case here is that whenever Icinga 2 needs the value for such a custom variable it runs the function and uses whatever value the function returns: ``` object CheckCommand "random-value" { command = [ PluginDir + "/check_dummy", "0", "$text$" ] vars.text = {{ Math.random() * 100 }} } ``` This example uses the [abbreviated lambda syntax](17-language-reference.md#nullary-lambdas). These functions have access to a number of variables: Variable | Description -------------|--------------- user | The User object (for notifications). service | The Service object (for service checks/notifications/event handlers). host | The Host object. command | The command object (e.g. a CheckCommand object for checks). Here's an example: ``` vars.text = {{ host.check_interval }} ``` In addition to these variables the [macro](18-library-reference.md#scoped-functions-macro) function can be used to retrieve the value of arbitrary macro expressions: ``` vars.text = {{ if (macro("$address$") == "127.0.0.1") { log("Running a check for localhost!") } return "Some text" }} ``` The `resolve_arguments` function can be used to resolve a command and its arguments much in the same fashion Icinga does this for the `command` and `arguments` attributes for commands. The `by_ssh` command uses this functionality to let users specify a command and arguments that should be executed via SSH: ``` arguments = { "-C" = {{ var command = macro("$by_ssh_command$") var arguments = macro("$by_ssh_arguments$") if (typeof(command) == String && !arguments) { return command } var escaped_args = [] for (arg in resolve_arguments(command, arguments)) { escaped_args.add(escape_shell_arg(arg)) } return escaped_args.join(" ") }} ... } ``` Accessing object attributes at runtime inside these functions is described in the [advanced topics](08-advanced-topics.md#access-object-attributes-at-runtime) chapter. ## Runtime Macros Macros can be used to access other objects' attributes and [custom variables](03-monitoring-basics.md#custom-variables) at runtime. For example they are used in command definitions to figure out which IP address a check should be run against: ``` object CheckCommand "my-ping" { command = [ PluginDir + "/check_ping" ] arguments = { "-H" = "$ping_address$" "-w" = "$ping_wrta$,$ping_wpl$%" "-c" = "$ping_crta$,$ping_cpl$%" "-p" = "$ping_packets$" } // Resolve from a host attribute, or custom variable. vars.ping_address = "$address$" // Default values vars.ping_wrta = 100 vars.ping_wpl = 5 vars.ping_crta = 250 vars.ping_cpl = 10 vars.ping_packets = 5 } object Host "router" { check_command = "my-ping" address = "10.0.0.1" } ``` In this example we are using the `$address$` macro to refer to the host's `address` attribute. We can also directly refer to custom variables, e.g. by using `$ping_wrta$`. Icinga automatically tries to find the closest match for the attribute you specified. The exact rules for this are explained in the next section. > **Note** > > When using the `$` sign as single character you must escape it with an > additional dollar character (`$$`). ### Evaluation Order When executing commands Icinga 2 checks the following objects in this order to look up macros and their respective values: 1. User object (only for notifications) 2. Service object 3. Host object 4. Command object 5. Global custom variables in the `Vars` constant This execution order allows you to define default values for custom variables in your command objects. Here's how you can override the custom variable `ping_packets` from the previous example: ``` object Service "ping" { host_name = "localhost" check_command = "my-ping" vars.ping_packets = 10 // Overrides the default value of 5 given in the command } ``` If a custom variable isn't defined anywhere, an empty value is used and a warning is written to the Icinga 2 log. You can also directly refer to a specific attribute -- thereby ignoring these evaluation rules -- by specifying the full attribute name: ``` $service.vars.ping_wrta$ ``` This retrieves the value of the `ping_wrta` custom variable for the service. This returns an empty value if the service does not have such a custom variable no matter whether another object such as the host has this attribute. ### Host Runtime Macros The following host custom variables are available in all commands that are executed for hosts or services: Name | Description -----------------------------|-------------- host.name | The name of the host object. host.display\_name | The value of the `display_name` attribute. host.state | The host's current state. Can be one of `UNREACHABLE`, `UP` and `DOWN`. host.state\_id | The host's current state. Can be one of `0` (up), `1` (down) and `2` (unreachable). host.state\_type | The host's current state type. Can be one of `SOFT` and `HARD`. host.check\_attempt | The current check attempt number. host.max\_check\_attempts | The maximum number of checks which are executed before changing to a hard state. host.last\_state | The host's previous state. Can be one of `UNREACHABLE`, `UP` and `DOWN`. host.last\_state\_id | The host's previous state. Can be one of `0` (up), `1` (down) and `2` (unreachable). host.last\_state\_type | The host's previous state type. Can be one of `SOFT` and `HARD`. host.last\_state\_change | The last state change's timestamp. host.downtime\_depth | The number of active downtimes. host.duration\_sec | The time since the last state change. host.latency | The host's check latency. host.execution\_time | The host's check execution time. host.output | The last check's output. host.perfdata | The last check's performance data. host.last\_check | The timestamp when the last check was executed. host.check\_source | The monitoring instance that performed the last check. host.num\_services | Number of services associated with the host. host.num\_services\_ok | Number of services associated with the host which are in an `OK` state. host.num\_services\_warning | Number of services associated with the host which are in a `WARNING` state. host.num\_services\_unknown | Number of services associated with the host which are in an `UNKNOWN` state. host.num\_services\_critical | Number of services associated with the host which are in a `CRITICAL` state. In addition to these specific runtime macros [host object](09-object-types.md#objecttype-host) attributes can be accessed too. ### Service Runtime Macros The following service macros are available in all commands that are executed for services: Name | Description -----------------------------|-------------- service.name | The short name of the service object. service.display\_name | The value of the `display_name` attribute. service.check\_command | The short name of the command along with any arguments to be used for the check. service.state | The service's current state. Can be one of `OK`, `WARNING`, `CRITICAL` and `UNKNOWN`. service.state\_id | The service's current state. Can be one of `0` (ok), `1` (warning), `2` (critical) and `3` (unknown). service.state\_type | The service's current state type. Can be one of `SOFT` and `HARD`. service.check\_attempt | The current check attempt number. service.max\_check\_attempts | The maximum number of checks which are executed before changing to a hard state. service.last\_state | The service's previous state. Can be one of `OK`, `WARNING`, `CRITICAL` and `UNKNOWN`. service.last\_state\_id | The service's previous state. Can be one of `0` (ok), `1` (warning), `2` (critical) and `3` (unknown). service.last\_state\_type | The service's previous state type. Can be one of `SOFT` and `HARD`. service.last\_state\_change | The last state change's timestamp. service.downtime\_depth | The number of active downtimes. service.duration\_sec | The time since the last state change. service.latency | The service's check latency. service.execution\_time | The service's check execution time. service.output | The last check's output. service.perfdata | The last check's performance data. service.last\_check | The timestamp when the last check was executed. service.check\_source | The monitoring instance that performed the last check. In addition to these specific runtime macros [service object](09-object-types.md#objecttype-service) attributes can be accessed too. ### Command Runtime Macros The following custom variables are available in all commands: Name | Description -----------------------|-------------- command.name | The name of the command object. ### User Runtime Macros The following custom variables are available in all commands that are executed for users: Name | Description -----------------------|-------------- user.name | The name of the user object. user.display\_name | The value of the `display_name` attribute. In addition to these specific runtime macros [user object](09-object-types.md#objecttype-user) attributes can be accessed too. ### Notification Runtime Macros Name | Description -----------------------|-------------- notification.type | The type of the notification. notification.author | The author of the notification comment if existing. notification.comment | The comment of the notification if existing. In addition to these specific runtime macros [notification object](09-object-types.md#objecttype-notification) attributes can be accessed too. ### Global Runtime Macros The following macros are available in all executed commands: Name | Description -------------------------|-------------- icinga.timet | Current UNIX timestamp. icinga.long\_date\_time | Current date and time including timezone information. Example: `2014-01-03 11:23:08 +0000` icinga.short\_date\_time | Current date and time. Example: `2014-01-03 11:23:08` icinga.date | Current date. Example: `2014-01-03` icinga.time | Current time including timezone information. Example: `11:23:08 +0000` icinga.uptime | Current uptime of the Icinga 2 process. The following macros provide global statistics: Name | Description ------------------------------------|------------------------------------ icinga.num\_services\_ok | Current number of services in state 'OK'. icinga.num\_services\_warning | Current number of services in state 'Warning'. icinga.num\_services\_critical | Current number of services in state 'Critical'. icinga.num\_services\_unknown | Current number of services in state 'Unknown'. icinga.num\_services\_pending | Current number of pending services. icinga.num\_services\_unreachable | Current number of unreachable services. icinga.num\_services\_flapping | Current number of flapping services. icinga.num\_services\_in\_downtime | Current number of services in downtime. icinga.num\_services\_acknowledged | Current number of acknowledged service problems. icinga.num\_hosts\_up | Current number of hosts in state 'Up'. icinga.num\_hosts\_down | Current number of hosts in state 'Down'. icinga.num\_hosts\_unreachable | Current number of unreachable hosts. icinga.num\_hosts\_pending | Current number of pending hosts. icinga.num\_hosts\_flapping | Current number of flapping hosts. icinga.num\_hosts\_in\_downtime | Current number of hosts in downtime. icinga.num\_hosts\_acknowledged | Current number of acknowledged host problems. ### Environment Variable Runtime Macros All environment variables of the Icinga process are available as runtime macros named `env.`. E.g. `$env.ProgramFiles$` for ProgramFiles which is especially useful on Windows. In contrast to the other runtime macros env vars require the `env.` prefix. ## Apply Rules Several object types require an object relation, e.g. [Service](09-object-types.md#objecttype-service), [Notification](09-object-types.md#objecttype-notification), [Dependency](09-object-types.md#objecttype-dependency), [ScheduledDowntime](09-object-types.md#objecttype-scheduleddowntime) objects. The object relations are documented in the linked chapters. If you for example create a service object you have to specify the [host_name](09-object-types.md#objecttype-service) attribute and reference an existing host attribute. ``` object Service "ping4" { check_command = "ping4" host_name = "icinga2-agent1.localdomain" } ``` This isn't comfortable when managing a huge set of configuration objects which could [match](03-monitoring-basics.md#using-apply-expressions) on a common pattern. Instead you want to use **[apply](17-language-reference.md#apply) rules**. If you want basic monitoring for all your hosts, add a `ping4` service apply rule for all hosts which have the `address` attribute specified. Just one rule for 1000 hosts instead of 1000 service objects. Apply rules will automatically generate them for you. ``` apply Service "ping4" { check_command = "ping4" assign where host.address } ``` More explanations on assign where expressions can be found [here](03-monitoring-basics.md#using-apply-expressions). ### Apply Rules: Prerequisites Before you start with apply rules keep the following in mind: * Define the best match. * A set of unique [custom variables](03-monitoring-basics.md#custom-variables) for these hosts/services? * Or [group](03-monitoring-basics.md#groups) memberships, e.g. a host being a member of a hostgroup which should have a service set? * A generic pattern [match](18-library-reference.md#global-functions-match) on the host/service name? * [Multiple expressions combined](03-monitoring-basics.md#using-apply-expressions) with `&&` or `||` [operators](17-language-reference.md#expression-operators) * All expressions must return a boolean value (an empty string is equal to `false` e.g.) More specific object type requirements are described in these chapters: * [Apply services to hosts](03-monitoring-basics.md#using-apply-services) * [Apply notifications to hosts and services](03-monitoring-basics.md#using-apply-notifications) * [Apply dependencies to hosts and services](03-monitoring-basics.md#using-apply-dependencies) * [Apply scheduled downtimes to hosts and services](03-monitoring-basics.md#using-apply-scheduledowntimes) ### Apply Rules: Usage Examples You can set/override object attributes in apply rules using the respectively available objects in that scope (host and/or service objects). ``` vars.application_type = host.vars.application_type ``` [Custom variables](03-monitoring-basics.md#custom-variables) can also store nested dictionaries and arrays. That way you can use them for not only matching for their existence or values in apply expressions, but also assign ("inherit") their values into the generated objected from apply rules. Remember the examples shown for [custom variable values](03-monitoring-basics.md#custom-variables-values): ``` vars.notification["mail"] = { groups = [ "icingaadmins" ] } ``` You can do two things here: * Check for the existence of the `notification` custom variable and its nested dictionary key `mail`. If this is boolean true, the notification object will be generated. * Assign the value of the `groups` key to the `user_groups` attribute. ``` apply Notification "mail-icingaadmin" to Host { [...] user_groups = host.vars.notification.mail.groups assign where host.vars.notification.mail } ``` A more advanced example is to use [apply rules with for loops on arrays or dictionaries](03-monitoring-basics.md#using-apply-for) provided by [custom atttributes](03-monitoring-basics.md#custom-variables) or groups. Remember the examples shown for [custom variable values](03-monitoring-basics.md#custom-variables-values): ``` vars.disks["disk /"] = { disk_partitions = "/" } ``` You can iterate over all dictionary keys defined in `disks`. You can optionally use the value to specify additional object attributes. ``` apply Service for (disk => config in host.vars.disks) { [...] vars.disk_partitions = config.disk_partitions } ``` Please read the [apply for chapter](03-monitoring-basics.md#using-apply-for) for more specific insights. > **Tip** > > Building configuration in that dynamic way requires detailed information > of the generated objects. Use the `object list` [CLI command](11-cli-commands.md#cli-command-object) > after successful [configuration validation](11-cli-commands.md#config-validation). ### Apply Rules Expressions You can use simple or advanced combinations of apply rule expressions. Each expression must evaluate into the boolean `true` value. An empty string will be for instance interpreted as `false`. In a similar fashion undefined attributes will return `false`. Returns `false`: ``` assign where host.vars.attribute_does_not_exist ``` Multiple `assign where` condition rows are evaluated as `OR` condition. You can combine multiple expressions for matching only a subset of objects. In some cases, you want to be able to add more than one assign/ignore where expression which matches a specific condition. To achieve this you can use the logical `and` and `or` operators. #### Apply Rules Expressions Examples Assign a service to a specific host in a host group [array](18-library-reference.md#array-type) using the [in operator](17-language-reference.md#expression-operators): ``` assign where "hostgroup-dev" in host.groups ``` Assign an object when a custom variable is [equal](17-language-reference.md#expression-operators) to a value: ``` assign where host.vars.application_type == "database" assign where service.vars.sms_notify == true ``` Assign an object if a dictionary [contains](18-library-reference.md#dictionary-contains) a given key: ``` assign where host.vars.app_dict.contains("app") ``` Match the host name by either using a [case insensitive match](18-library-reference.md#global-functions-match): ``` assign where match("webserver*", host.name) ``` Match the host name by using a [regular expression](18-library-reference.md#global-functions-regex). Please note the [escaped](17-language-reference.md#string-literals-escape-sequences) backslash character: ``` assign where regex("^webserver-[\\d+]", host.name) ``` [Match](18-library-reference.md#global-functions-match) all `*mysql*` patterns in the host name and (`&&`) custom variable `prod_mysql_db` matches the `db-*` pattern. All hosts with the custom variable `test_server` set to `true` should be ignored, or any host name ending with `*internal` pattern. ``` object HostGroup "mysql-server" { display_name = "MySQL Server" assign where match("*mysql*", host.name) && match("db-*", host.vars.prod_mysql_db) ignore where host.vars.test_server == true ignore where match("*internal", host.name) } ``` Similar example for advanced notification apply rule filters: If the service attribute `notes` [matches](18-library-reference.md#global-functions-match) the `has gold support 24x7` string `AND` one of the two condition passes, either the `customer` host custom variable is set to `customer-xy` `OR` the host custom variable `always_notify` is set to `true`. The notification is ignored for services whose host name ends with `*internal` `OR` the `priority` custom variable is [less than](17-language-reference.md#expression-operators) `2`. ``` template Notification "cust-xy-notification" { users = [ "noc-xy", "mgmt-xy" ] command = "mail-service-notification" } apply Notification "notify-cust-xy-mysql" to Service { import "cust-xy-notification" assign where match("*has gold support 24x7*", service.notes) && (host.vars.customer == "customer-xy" || host.vars.always_notify == true) ignore where match("*internal", host.name) || (service.vars.priority < 2 && host.vars.is_clustered == true) } ``` More advanced examples are covered [here](08-advanced-topics.md#use-functions-assign-where). ### Apply Services to Hosts The sample configuration already includes a detailed example in [hosts.conf](04-configuration.md#hosts-conf) and [services.conf](04-configuration.md#services-conf) for this use case. The example for `ssh` applies a service object to all hosts with the `address` attribute being defined and the custom variable `os` set to the string `Linux` in `vars`. ``` apply Service "ssh" { import "generic-service" check_command = "ssh" assign where host.address && host.vars.os == "Linux" } ``` Other detailed examples are used in their respective chapters, for example [apply services with custom command arguments](03-monitoring-basics.md#command-passing-parameters). ### Apply Notifications to Hosts and Services Notifications are applied to specific targets (`Host` or `Service`) and work in a similar manner: ``` apply Notification "mail-noc" to Service { import "mail-service-notification" user_groups = [ "noc" ] assign where host.vars.notification.mail } ``` In this example the `mail-noc` notification will be created as object for all services having the `notification.mail` custom variable defined. The notification command is set to `mail-service-notification` and all members of the user group `noc` will get notified. It is also possible to generally apply a notification template and dynamically overwrite values from the template by checking for custom variables. This can be achieved by using [conditional statements](17-language-reference.md#conditional-statements): ``` apply Notification "host-mail-noc" to Host { import "mail-host-notification" // replace interval inherited from `mail-host-notification` template with new notfication interval set by a host custom variable if (host.vars.notification_interval) { interval = host.vars.notification_interval } // same with notification period if (host.vars.notification_period) { period = host.vars.notification_period } // Send SMS instead of email if the host's custom variable `notification_type` is set to `sms` if (host.vars.notification_type == "sms") { command = "sms-host-notification" } else { command = "mail-host-notification" } user_groups = [ "noc" ] assign where host.address } ``` In the example above the notification template `mail-host-notification` contains all relevant notification settings. The apply rule is applied on all host objects where the `host.address` is defined. If the host object has a specific custom variable set, its value is inherited into the local notification object scope, e.g. `host.vars.notification_interval`, `host.vars.notification_period` and `host.vars.notification_type`. This overwrites attributes already specified in the imported `mail-host-notification` template. The corresponding host object could look like this: ``` object Host "host1" { import "host-linux-prod" display_name = "host1" address = "192.168.1.50" vars.notification_interval = 1h vars.notification_period = "24x7" vars.notification_type = "sms" } ``` ### Apply Dependencies to Hosts and Services Detailed examples can be found in the [dependencies](03-monitoring-basics.md#dependencies) chapter. ### Apply Recurring Downtimes to Hosts and Services The sample configuration includes an example in [downtimes.conf](04-configuration.md#downtimes-conf). Detailed examples can be found in the [recurring downtimes](08-advanced-topics.md#recurring-downtimes) chapter. ### Using Apply For Rules Next to the standard way of using [apply rules](03-monitoring-basics.md#using-apply) there is the requirement of applying objects based on a set (array or dictionary) using [apply for](17-language-reference.md#apply-for) expressions. The sample configuration already includes a detailed example in [hosts.conf](04-configuration.md#hosts-conf) and [services.conf](04-configuration.md#services-conf) for this use case. Take the following example: A host provides the snmp oids for different service check types. This could look like the following example: ``` object Host "router-v6" { check_command = "hostalive" address6 = "2001:db8:1234::42" vars.oids["if01"] = "1.1.1.1.1" vars.oids["temp"] = "1.1.1.1.2" vars.oids["bgp"] = "1.1.1.1.5" } ``` The idea is to create service objects for `if01` and `temp` but not `bgp`. The oid value should also be used as service custom variable `snmp_oid`. This is the command argument required by the [snmp](10-icinga-template-library.md#plugin-check-command-snmp) check command. The service's `display_name` should be set to the identifier inside the dictionary, e.g. `if01`. ``` apply Service for (identifier => oid in host.vars.oids) { check_command = "snmp" display_name = identifier vars.snmp_oid = oid ignore where identifier == "bgp" //don't generate service for bgp checks } ``` Icinga 2 evaluates the `apply for` rule for all objects with the custom variable `oids` set. It iterates over all dictionary items inside the `for` loop and evaluates the `assign/ignore where` expressions. You can access the loop variable in these expressions, e.g. to ignore specific values. In this example the `bgp` identifier is ignored. This avoids to generate unwanted services. A different approach would be to match the `oid` value with a [regex](18-library-reference.md#global-functions-regex)/[wildcard match](18-library-reference.md#global-functions-match) pattern for example. ``` ignore where regex("^\d.\d.\d.\d.5$", oid) ``` > **Note** > > You don't need an `assign where` expression which checks for the existence of the > `oids` custom variable. This method saves you from creating multiple apply rules. It also moves the attribute specification logic from the service to the host. #### Apply For and Custom Variable Override Imagine a different more advanced example: You are monitoring your network device (host) with many interfaces (services). The following requirements/problems apply: * Each interface service should be named with a prefix and a name defined in your host object (which could be generated from your CMDB, etc.) * Each interface has its own VLAN tag * Some interfaces have QoS enabled * Additional attributes such as `display_name` or `notes`, `notes_url` and `action_url` must be dynamically generated. > **Tip** > > Define the SNMP community as global constant in your [constants.conf](04-configuration.md#constants-conf) file. ``` const IftrafficSnmpCommunity = "public" ``` Define the `interfaces` [custom variable](03-monitoring-basics.md#custom-variables) on the `cisco-catalyst-6509-34` host object and add three example interfaces as dictionary keys. Specify additional attributes inside the nested dictionary as learned with [custom variable values](03-monitoring-basics.md#custom-variables-values): ``` object Host "cisco-catalyst-6509-34" { import "generic-host" display_name = "Catalyst 6509 #34 VIE21" address = "127.0.1.4" /* "GigabitEthernet0/2" is the interface name, * and key name in service apply for later on */ vars.interfaces["GigabitEthernet0/2"] = { /* define all custom variables with the * same name required for command parameters/arguments * in service apply (look into your CheckCommand definition) */ iftraffic_units = "g" iftraffic_community = IftrafficSnmpCommunity iftraffic_bandwidth = 1 vlan = "internal" qos = "disabled" } vars.interfaces["GigabitEthernet0/4"] = { iftraffic_units = "g" //iftraffic_community = IftrafficSnmpCommunity iftraffic_bandwidth = 1 vlan = "remote" qos = "enabled" } vars.interfaces["MgmtInterface1"] = { iftraffic_community = IftrafficSnmpCommunity vlan = "mgmt" interface_address = "127.99.0.100" #special management ip } } ``` Start with the apply for definition and iterate over `host.vars.interfaces`. This is a dictionary and should use the variables `interface_name` as key and `interface_config` as value for each generated object scope. `"if-"` specifies the object name prefix for each service which results in `if-` for each iteration. ``` /* loop over the host.vars.interfaces dictionary * for (key => value in dict) means `interface_name` as key * and `interface_config` as value. Access config attributes * with the indexer (`.`) character. */ apply Service "if-" for (interface_name => interface_config in host.vars.interfaces) { ``` Import the `generic-service` template, assign the [iftraffic](10-icinga-template-library.md#plugin-contrib-command-iftraffic) `check_command`. Use the dictionary key `interface_name` to set a proper `display_name` string for external interfaces. ``` import "generic-service" check_command = "iftraffic" display_name = "IF-" + interface_name ``` The `interface_name` key's value is the same string used as command parameter for `iftraffic`: ``` /* use the key as command argument (no duplication of values in host.vars.interfaces) */ vars.iftraffic_interface = interface_name ``` Remember that `interface_config` is a nested dictionary. In the first iteration it looks like this: ``` interface_config = { iftraffic_units = "g" iftraffic_community = IftrafficSnmpCommunity iftraffic_bandwidth = 1 vlan = "internal" qos = "disabled" } ``` Access the dictionary keys with the [indexer](17-language-reference.md#indexer) syntax and assign them to custom variables used as command parameters for the `iftraffic` check command. ``` /* map the custom variables as command arguments */ vars.iftraffic_units = interface_config.iftraffic_units vars.iftraffic_community = interface_config.iftraffic_community ``` If you just want to inherit all attributes specified inside the `interface_config` dictionary, add it to the generated service custom variables like this: ``` /* the above can be achieved in a shorter fashion if the names inside host.vars.interfaces * are the _exact_ same as required as command parameter by the check command * definition. */ vars += interface_config ``` If the user did not specify default values for required service custom variables, add them here. This also helps to avoid unwanted configuration validation errors or runtime failures. Please read more about conditional statements [here](17-language-reference.md#conditional-statements). ``` /* set a default value for units and bandwidth */ if (interface_config.iftraffic_units == "") { vars.iftraffic_units = "m" } if (interface_config.iftraffic_bandwidth == "") { vars.iftraffic_bandwidth = 1 } if (interface_config.vlan == "") { vars.vlan = "not set" } if (interface_config.qos == "") { vars.qos = "not set" } ``` If the host object did not specify a custom SNMP community, set a default value specified by the [global constant](17-language-reference.md#constants) `IftrafficSnmpCommunity`. ``` /* set the global constant if not explicitely * not provided by the `interfaces` dictionary on the host */ if (len(interface_config.iftraffic_community) == 0 || len(vars.iftraffic_community) == 0) { vars.iftraffic_community = IftrafficSnmpCommunity } ``` Use the provided values to [calculate](17-language-reference.md#expression-operators) more object attributes which can be e.g. seen in external interfaces. ``` /* Calculate some additional object attributes after populating the `vars` dictionary */ notes = "Interface check for " + interface_name + " (units: '" + interface_config.iftraffic_units + "') in VLAN '" + vars.vlan + "' with ' QoS '" + vars.qos + "'" notes_url = "https://foreman.company.com/hosts/" + host.name action_url = "https://snmp.checker.company.com/" + host.name + "/if-" + interface_name } ``` > **Tip** > > Building configuration in that dynamic way requires detailed information > of the generated objects. Use the `object list` [CLI command](11-cli-commands.md#cli-command-object) > after successful [configuration validation](11-cli-commands.md#config-validation). Verify that the apply-for-rule successfully created the service objects with the inherited custom variables: ``` # icinga2 daemon -C # icinga2 object list --type Service --name *catalyst* Object 'cisco-catalyst-6509-34!if-GigabitEthernet0/2' of type 'Service': ...... * vars % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 59:3-59:26 * iftraffic_bandwidth = 1 * iftraffic_community = "public" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 53:3-53:65 * iftraffic_interface = "GigabitEthernet0/2" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 49:3-49:43 * iftraffic_units = "g" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 52:3-52:57 * qos = "disabled" * vlan = "internal" Object 'cisco-catalyst-6509-34!if-GigabitEthernet0/4' of type 'Service': ... * vars % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 59:3-59:26 * iftraffic_bandwidth = 1 * iftraffic_community = "public" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 53:3-53:65 % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 79:5-79:53 * iftraffic_interface = "GigabitEthernet0/4" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 49:3-49:43 * iftraffic_units = "g" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 52:3-52:57 * qos = "enabled" * vlan = "remote" Object 'cisco-catalyst-6509-34!if-MgmtInterface1' of type 'Service': ... * vars % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 59:3-59:26 * iftraffic_bandwidth = 1 % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 66:5-66:32 * iftraffic_community = "public" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 53:3-53:65 * iftraffic_interface = "MgmtInterface1" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 49:3-49:43 * iftraffic_units = "m" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 52:3-52:57 % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 63:5-63:30 * interface_address = "127.99.0.100" * qos = "not set" % = modified in '/etc/icinga2/conf.d/iftraffic.conf', lines 72:5-72:24 * vlan = "mgmt" ``` ### Use Object Attributes in Apply Rules Since apply rules are evaluated after the generic objects, you can reference existing host and/or service object attributes as values for any object attribute specified in that apply rule. ``` object Host "opennebula-host" { import "generic-host" address = "10.1.1.2" vars.hosting["cust1"] = { http_uri = "/shop" customer_name = "Customer 1" customer_id = "7568" support_contract = "gold" } vars.hosting["cust2"] = { http_uri = "/" customer_name = "Customer 2" customer_id = "7569" support_contract = "silver" } } ``` `hosting` is a custom variable with the Dictionary value type. This is mandatory to iterate with the `key => value` notation in the below apply for rule. ``` apply Service for (customer => config in host.vars.hosting) { import "generic-service" check_command = "ping4" vars.qos = "disabled" vars += config vars.http_uri = "/" + customer + "/" + config.http_uri display_name = "Shop Check for " + vars.customer_name + "-" + vars.customer_id notes = "Support contract: " + vars.support_contract + " for Customer " + vars.customer_name + " (" + vars.customer_id + ")." notes_url = "https://foreman.company.com/hosts/" + host.name action_url = "https://snmp.checker.company.com/" + host.name + "/" + vars.customer_id } ``` Each loop iteration has different values for `customer` and config` in the local scope. 1. ``` customer = "cust 1" config = { http_uri = "/shop" customer_name = "Customer 1" customer_id = "7568" support_contract = "gold" } ``` 2. ``` customer = "cust2" config = { http_uri = "/" customer_name = "Customer 2" customer_id = "7569" support_contract = "silver" } ``` You can now add the `config` dictionary into `vars`. ``` vars += config ``` Now it looks like the following in the first iteration: ``` customer = "cust 1" vars = { http_uri = "/shop" customer_name = "Customer 1" customer_id = "7568" support_contract = "gold" } ``` Remember, you know this structure already. Custom attributes can also be accessed by using the [indexer](17-language-reference.md#indexer) syntax. ``` vars.http_uri = ... + config.http_uri ``` can also be written as ``` vars += config vars.http_uri = ... + vars.http_uri ``` ## Groups A group is a collection of similar objects. Groups are primarily used as a visualization aid in web interfaces. Group membership is defined at the respective object itself. If you have a hostgroup name `windows` for example, and want to assign specific hosts to this group for later viewing the group on your alert dashboard, first create a HostGroup object: ``` object HostGroup "windows" { display_name = "Windows Servers" } ``` Then add your hosts to this group: ``` template Host "windows-server" { groups += [ "windows" ] } object Host "mssql-srv1" { import "windows-server" vars.mssql_port = 1433 } object Host "mssql-srv2" { import "windows-server" vars.mssql_port = 1433 } ``` This can be done for service and user groups the same way: ``` object UserGroup "windows-mssql-admins" { display_name = "Windows MSSQL Admins" } template User "generic-windows-mssql-users" { groups += [ "windows-mssql-admins" ] } object User "win-mssql-noc" { import "generic-windows-mssql-users" email = "noc@example.com" } object User "win-mssql-ops" { import "generic-windows-mssql-users" email = "ops@example.com" } ``` ### Group Membership Assign Instead of manually assigning each object to a group you can also assign objects to a group based on their attributes: ``` object HostGroup "prod-mssql" { display_name = "Production MSSQL Servers" assign where host.vars.mssql_port && host.vars.prod_mysql_db ignore where host.vars.test_server == true ignore where match("*internal", host.name) } ``` In this example all hosts with the `vars` attribute `mssql_port` will be added as members to the host group `mssql`. However, all hosts [matching](18-library-reference.md#global-functions-match) the string `\*internal` or with the `test_server` attribute set to `true` are **not** added to this group. Details on the `assign where` syntax can be found in the [Language Reference](17-language-reference.md#apply). ## Notifications Notifications for service and host problems are an integral part of your monitoring setup. When a host or service is in a downtime, a problem has been acknowledged or the dependency logic determined that the host/service is unreachable, no notifications are sent. You can configure additional type and state filters refining the notifications being actually sent. There are many ways of sending notifications, e.g. by email, XMPP, IRC, Twitter, etc. On its own Icinga 2 does not know how to send notifications. Instead it relies on external mechanisms such as shell scripts to notify users. More notification methods are listed in the [addons and plugins](13-addons.md#notification-scripts-interfaces) chapter. A notification specification requires one or more users (and/or user groups) who will be notified in case of problems. These users must have all custom attributes defined which will be used in the `NotificationCommand` on execution. The user `icingaadmin` in the example below will get notified only on `Warning` and `Critical` problems. In addition to that `Recovery` notifications are sent (they require the `OK` state). ``` object User "icingaadmin" { display_name = "Icinga 2 Admin" enable_notifications = true states = [ OK, Warning, Critical ] types = [ Problem, Recovery ] email = "icinga@localhost" } ``` If you don't set the `states` and `types` configuration attributes for the `User` object, notifications for all states and types will be sent. Details on troubleshooting notification problems can be found [here](15-troubleshooting.md#troubleshooting). > **Note** > > Make sure that the [notification](11-cli-commands.md#enable-features) feature is enabled > in order to execute notification commands. You should choose which information you (and your notified users) are interested in case of emergency, and also which information does not provide any value to you and your environment. An example notification command is explained [here](03-monitoring-basics.md#notification-commands). You can add all shared attributes to a `Notification` template which is inherited to the defined notifications. That way you'll save duplicated attributes in each `Notification` object. Attributes can be overridden locally. ``` template Notification "generic-notification" { interval = 15m command = "mail-service-notification" states = [ Warning, Critical, Unknown ] types = [ Problem, Acknowledgement, Recovery, Custom, FlappingStart, FlappingEnd, DowntimeStart, DowntimeEnd, DowntimeRemoved ] period = "24x7" } ``` The time period `24x7` is included as example configuration with Icinga 2. Use the `apply` keyword to create `Notification` objects for your services: ``` apply Notification "notify-cust-xy-mysql" to Service { import "generic-notification" users = [ "noc-xy", "mgmt-xy" ] assign where match("*has gold support 24x7*", service.notes) && (host.vars.customer == "customer-xy" || host.vars.always_notify == true ignore where match("*internal", host.name) || (service.vars.priority < 2 && host.vars.is_clustered == true) } ``` Instead of assigning users to notifications, you can also add the `user_groups` attribute with a list of user groups to the `Notification` object. Icinga 2 will send notifications to all group members. > **Note** > > Only users who have been notified of a problem before (`Warning`, `Critical`, `Unknown` states for services, `Down` for hosts) will receive `Recovery` notifications. Icinga 2 v2.10 allows you to configure a `User` object with `Acknowledgement` and/or `Recovery` without a `Problem` notification. These notifications will be sent without any problem notifications beforehand, and can be used for e.g. ticket systems. ``` object User "ticketadmin" { display_name = "Ticket Admin" enable_notifications = true states = [ OK, Warning, Critical ] types = [ Acknowledgement, Recovery ] email = "ticket@localhost" } ``` ### Notifications: Users from Host/Service A common pattern is to store the users and user groups on the host or service objects instead of the notification object itself. The sample configuration provided in [hosts.conf](04-configuration.md#hosts-conf) and [notifications.conf](04-configuration.md#notifications-conf) already provides an example for this question. > **Tip** > > Please make sure to read the [apply](03-monitoring-basics.md#using-apply) and > [custom variable values](03-monitoring-basics.md#custom-variables-values) chapter to > fully understand these examples. Specify the user and groups as nested custom variable on the host object: ``` object Host "icinga2-agent1.localdomain" { [...] vars.notification["mail"] = { groups = [ "icingaadmins" ] users = [ "icingaadmin" ] } vars.notification["sms"] = { users = [ "icingaadmin" ] } } ``` As you can see, there is the option to use two different notification apply rules here: One for `mail` and one for `sms`. This example assigns the `users` and `groups` nested keys from the `notification` custom variable to the actual notification object attributes. Since errors are hard to debug if host objects don't specify the required configuration attributes, you can add a safety condition which logs which host object is affected. ``` critical/config: Host 'icinga2-client3.localdomain' does not specify required user/user_groups configuration attributes for notification 'mail-icingaadmin'. ``` You can also use the [script debugger](20-script-debugger.md#script-debugger) for more advanced insights. ``` apply Notification "mail-host-notification" to Host { [...] /* Log which host does not specify required user/user_groups attributes. This will fail immediately during config validation and help a lot. */ if (len(host.vars.notification.mail.users) == 0 && len(host.vars.notification.mail.user_groups) == 0) { log(LogCritical, "config", "Host '" + host.name + "' does not specify required user/user_groups configuration attributes for notification '" + name + "'.") } users = host.vars.notification.mail.users user_groups = host.vars.notification.mail.groups assign where host.vars.notification.mail && typeof(host.vars.notification.mail) == Dictionary } apply Notification "sms-host-notification" to Host { [...] /* Log which host does not specify required user/user_groups attributes. This will fail immediately during config validation and help a lot. */ if (len(host.vars.notification.sms.users) == 0 && len(host.vars.notification.sms.user_groups) == 0) { log(LogCritical, "config", "Host '" + host.name + "' does not specify required user/user_groups configuration attributes for notification '" + name + "'.") } users = host.vars.notification.sms.users user_groups = host.vars.notification.sms.groups assign where host.vars.notification.sms && typeof(host.vars.notification.sms) == Dictionary } ``` The example above uses [typeof](18-library-reference.md#global-functions-typeof) as safety function to ensure that the `mail` key really provides a dictionary as value. Otherwise the configuration validation could fail if an admin adds something like this on another host: ``` vars.notification.mail = "yes" ``` You can also do a more fine granular assignment on the service object: ``` apply Service "http" { [...] vars.notification["mail"] = { groups = [ "icingaadmins" ] users = [ "icingaadmin" ] } [...] } ``` This notification apply rule is different to the one above. The service notification users and groups are inherited from the service and if not set, from the host object. A default user is set too. ``` apply Notification "mail-service-notification" to Service { [...] if (service.vars.notification.mail.users) { users = service.vars.notification.mail.users } else if (host.vars.notification.mail.users) { users = host.vars.notification.mail.users } else { /* Default user who receives everything. */ users = [ "icingaadmin" ] } if (service.vars.notification.mail.groups) { user_groups = service.vars.notification.mail.groups } else if (host.vars.notification.mail.groups) { user_groups = host.vars.notification.mail.groups } assign where ( host.vars.notification.mail && typeof(host.vars.notification.mail) == Dictionary ) || ( service.vars.notification.mail && typeof(service.vars.notification.mail) == Dictionary ) } ``` ### Notification Escalations When a problem notification is sent and a problem still exists at the time of re-notification you may want to escalate the problem to the next support level. A different approach is to configure the default notification by email, and escalate the problem via SMS if not already solved. You can define notification start and end times as additional configuration attributes making the `Notification` object a so-called `notification escalation`. Using templates you can share the basic notification attributes such as users or the `interval` (and override them for the escalation then). Using the example from above, you can define additional users being escalated for SMS notifications between start and end time. ``` object User "icinga-oncall-2nd-level" { display_name = "Icinga 2nd Level" vars.mobile = "+1 555 424642" } object User "icinga-oncall-1st-level" { display_name = "Icinga 1st Level" vars.mobile = "+1 555 424642" } ``` Define an additional [NotificationCommand](03-monitoring-basics.md#notification-commands) for SMS notifications. > **Note** > > The example is not complete as there are many different SMS providers. > Please note that sending SMS notifications will require an SMS provider > or local hardware with an active SIM card. ``` object NotificationCommand "sms-notification" { command = [ PluginDir + "/send_sms_notification", "$mobile$", "..." } ``` The two new notification escalations are added onto the local host and its service `ping4` using the `generic-notification` template. The user `icinga-oncall-2nd-level` will get notified by SMS (`sms-notification` command) after `30m` until `1h`. > **Note** > > The `interval` was set to 15m in the `generic-notification` > template example. Lower that value in your escalations by using a secondary > template or by overriding the attribute directly in the `notifications` array > position for `escalation-sms-2nd-level`. If the problem does not get resolved nor acknowledged preventing further notifications, the `escalation-sms-1st-level` user will be escalated `1h` after the initial problem was notified, but only for one hour (`2h` as `end` key for the `times` dictionary). ``` apply Notification "mail" to Service { import "generic-notification" command = "mail-notification" users = [ "icingaadmin" ] assign where service.name == "ping4" } apply Notification "escalation-sms-2nd-level" to Service { import "generic-notification" command = "sms-notification" users = [ "icinga-oncall-2nd-level" ] times = { begin = 30m end = 1h } assign where service.name == "ping4" } apply Notification "escalation-sms-1st-level" to Service { import "generic-notification" command = "sms-notification" users = [ "icinga-oncall-1st-level" ] times = { begin = 1h end = 2h } assign where service.name == "ping4" } ``` ### Notification Delay Sometimes the problem in question should not be announced when the notification is due (the object reaching the `HARD` state), but after a certain period. In Icinga 2 you can use the `times` dictionary and set `begin = 15m` as key and value if you want to postpone the notification window for 15 minutes. Leave out the `end` key -- if not set, Icinga 2 will not check against any end time for this notification. > **Note** > > Setting the `end` key to `0` will stop sending notifications immediately > when a problem occurs, effectively disabling the notification. Make sure to specify a relatively low notification `interval` to get notified soon enough again. ``` apply Notification "mail" to Service { import "generic-notification" command = "mail-notification" users = [ "icingaadmin" ] interval = 5m times.begin = 15m // delay notification window assign where service.name == "ping4" } ``` Also note that this mechanism doesn't take downtimes etc. into account, only the `HARD` state change time matters. E.g. for a problem which occurred in the middle of a downtime from 2 PM to 4 PM `times.begin = 2h` means 5 PM, not 6 PM. ### Disable Re-notifications If you prefer to be notified only once, you can disable re-notifications by setting the `interval` attribute to `0`. ``` apply Notification "notify-once" to Service { import "generic-notification" command = "mail-notification" users = [ "icingaadmin" ] interval = 0 // disable re-notification assign where service.name == "ping4" } ``` ### Notification Filters by State and Type If there are no notification state and type filter attributes defined at the `Notification` or `User` object, Icinga 2 assumes that all states and types are being notified. Available state and type filters for notifications are: ``` template Notification "generic-notification" { states = [ OK, Warning, Critical, Unknown ] types = [ Problem, Acknowledgement, Recovery, Custom, FlappingStart, FlappingEnd, DowntimeStart, DowntimeEnd, DowntimeRemoved ] } ``` ## Commands Icinga 2 uses three different command object types to specify how checks should be performed, notifications should be sent, and events should be handled. ### Check Commands [CheckCommand](09-object-types.md#objecttype-checkcommand) objects define the command line how a check is called. [CheckCommand](09-object-types.md#objecttype-checkcommand) objects are referenced by [Host](09-object-types.md#objecttype-host) and [Service](09-object-types.md#objecttype-service) objects using the `check_command` attribute. > **Note** > > Make sure that the [checker](11-cli-commands.md#enable-features) feature is enabled in order to > execute checks. #### Integrate the Plugin with a CheckCommand Definition Unless you have done so already, download your check plugin and put it into the [PluginDir](04-configuration.md#constants-conf) directory. The following example uses the `check_mysql` plugin contained in the Monitoring Plugins package. The plugin path and all command arguments are made a list of double-quoted string arguments for proper shell escaping. Call the `check_mysql` plugin with the `--help` parameter to see all available options. Our example defines warning (`-w`) and critical (`-c`) thresholds. ``` icinga@icinga2 $ /usr/lib64/nagios/plugins/check_mysql --help ... This program tests connections to a MySQL server Usage: check_mysql [-d database] [-H host] [-P port] [-s socket] [-u user] [-p password] [-S] [-l] [-a cert] [-k key] [-C ca-cert] [-D ca-dir] [-L ciphers] [-f optfile] [-g group] ``` Next step is to understand how [command parameters](03-monitoring-basics.md#command-passing-parameters) are being passed from a host or service object, and add a [CheckCommand](09-object-types.md#objecttype-checkcommand) definition based on these required parameters and/or default values. Please continue reading in the [plugins section](05-service-monitoring.md#service-monitoring-plugins) for additional integration examples. #### Passing Check Command Parameters from Host or Service Check command parameters are defined as custom variables which can be accessed as runtime macros by the executed check command. The check command parameters for ITL provided plugin check command definitions are documented [here](10-icinga-template-library.md#icinga-template-library), for example [disk](10-icinga-template-library.md#plugin-check-command-disk). In order to practice passing command parameters you should [integrate your own plugin](03-monitoring-basics.md#command-plugin-integration). The following example will use `check_mysql` provided by the [Monitoring Plugins](https://www.monitoring-plugins.org/). Define the default check command custom variables, for example `mysql_user` and `mysql_password` (freely definable naming schema) and optional their default threshold values. You can then use these custom variables as runtime macros for [command arguments](03-monitoring-basics.md#command-arguments) on the command line. > **Tip** > > Use a common command type as prefix for your command arguments to increase > readability. `mysql_user` helps understanding the context better than just > `user` as argument. The default custom variables can be overridden by the custom variables defined in the host or service using the check command `my-mysql`. The custom variables can also be inherited from a parent template using additive inheritance (`+=`). ``` # vim /etc/icinga2/conf.d/commands.conf object CheckCommand "my-mysql" { command = [ PluginDir + "/check_mysql" ] //constants.conf -> const PluginDir arguments = { "-H" = "$mysql_host$" "-u" = { required = true value = "$mysql_user$" } "-p" = "$mysql_password$" "-P" = "$mysql_port$" "-s" = "$mysql_socket$" "-a" = "$mysql_cert$" "-d" = "$mysql_database$" "-k" = "$mysql_key$" "-C" = "$mysql_ca_cert$" "-D" = "$mysql_ca_dir$" "-L" = "$mysql_ciphers$" "-f" = "$mysql_optfile$" "-g" = "$mysql_group$" "-S" = { set_if = "$mysql_check_slave$" description = "Check if the slave thread is running properly." } "-l" = { set_if = "$mysql_ssl$" description = "Use ssl encryption" } } vars.mysql_check_slave = false vars.mysql_ssl = false vars.mysql_host = "$address$" } ``` The check command definition also sets `mysql_host` to the `$address$` default value. You can override this command parameter if for example your MySQL host is not running on the same server's ip address. Make sure pass all required command parameters, such as `mysql_user`, `mysql_password` and `mysql_database`. `MysqlUsername` and `MysqlPassword` are specified as [global constants](04-configuration.md#constants-conf) in this example. ``` # vim /etc/icinga2/conf.d/services.conf apply Service "mysql-icinga-db-health" { import "generic-service" check_command = "my-mysql" vars.mysql_user = MysqlUsername vars.mysql_password = MysqlPassword vars.mysql_database = "icinga" vars.mysql_host = "192.168.33.11" assign where match("icinga2*", host.name) ignore where host.vars.no_health_check == true } ``` Take a different example: The example host configuration in [hosts.conf](04-configuration.md#hosts-conf) also applies an `ssh` service check. Your host's ssh port is not the default `22`, but set to `2022`. You can pass the command parameter as custom variable `ssh_port` directly inside the service apply rule inside [services.conf](04-configuration.md#services-conf): ``` apply Service "ssh" { import "generic-service" check_command = "ssh" vars.ssh_port = 2022 //custom command parameter assign where (host.address || host.address6) && host.vars.os == "Linux" } ``` If you prefer this being configured at the host instead of the service, modify the host configuration object instead. The runtime macro resolving order is described [here](03-monitoring-basics.md#macro-evaluation-order). ``` object Host "icinga2-agent1.localdomain { ... vars.ssh_port = 2022 } ``` #### Passing Check Command Parameters Using Apply For The host `localhost` with the generated services from the `basic-partitions` dictionary (see [apply for](03-monitoring-basics.md#using-apply-for) for details) checks a basic set of disk partitions with modified custom variables (warning thresholds at `10%`, critical thresholds at `5%` free disk space). The custom variable `disk_partition` can either hold a single string or an array of string values for passing multiple partitions to the `check_disk` check plugin. ``` object Host "my-server" { import "generic-host" address = "127.0.0.1" address6 = "::1" vars.local_disks["basic-partitions"] = { disk_partitions = [ "/", "/tmp", "/var", "/home" ] } } apply Service for (disk => config in host.vars.local_disks) { import "generic-service" check_command = "my-disk" vars += config vars.disk_wfree = "10%" vars.disk_cfree = "5%" } ``` More details on using arrays in custom variables can be found in [this chapter](03-monitoring-basics.md#custom-variables). #### Command Arguments Next to the short `command` array specified in the command object, it is advised to define plugin/script parameters in the `arguments` dictionary attribute. The value of the `--parameter` key itself is a dictionary with additional keys. They allow to create generic command objects and are also for documentation purposes, e.g. with the `description` field copying the plugin's help text in there. The Icinga Director uses this field to show the argument's purpose when selecting it. ``` arguments = { "--parameter" = { description = "..." value = "..." } } ``` Each argument is optional by default and is omitted if the value is not set. Learn more about integrating plugins with CheckCommand objects in [this chapter](05-service-monitoring.md#service-monitoring-plugin-checkcommand). There are additional possibilities for creating a command only once, with different parameters and arguments, shown below. ##### Command Arguments: Value In order to find out about the command argument, call the plugin's help or consult the README. ``` ./check_systemd.py --help ... -u UNIT, --unit UNIT Name of the systemd unit that is beeing tested. ``` Whenever the long parameter name is available, prefer this over the short one. ``` arguments = { "--unit" = { } } ``` Define a unique `prefix` for the command's specific arguments. Best practice is to follow this schema: ``` _ ``` Therefore use `systemd_` as prefix, and use the long plugin parameter name `unit` inside the [runtime macro](03-monitoring-basics.md#runtime-macros) syntax. ``` arguments = { "--unit" = { value = "$systemd_unit$" } } ``` In order to specify a default value, specify a [custom variable](03-monitoring-basics.md#custom-variables) inside the CheckCommand object. ``` vars.systemd_unit = "icinga2" ``` This value can be overridden from the host/service object as command parameters. ##### Command Arguments: Description Best practice, also inside the [ITL](10-icinga-template-library.md#icinga-template-library), is to always copy the command parameter help output into the `description` field of your check command. Learn more about integrating plugins with CheckCommand objects in [this chapter](05-service-monitoring.md#service-monitoring-plugin-checkcommand). With the [example above](03-monitoring-basics.md#command-arguments-value), inspect the parameter's help text. ``` ./check_systemd.py --help ... -u UNIT, --unit UNIT Name of the systemd unit that is beeing tested. ``` Copy this into the command arguments `description` entry. ``` arguments = { "--unit" = { value = "$systemd_unit$" description = "Name of the systemd unit that is beeing tested." } } ``` ##### Command Arguments: Required Specifies whether this command argument is required, or not. By default all arguments are optional. > **Tip** > > Good plugins provide optional parameters in square brackets, e.g. `[-w SECONDS]`. The `required` field can be toggled with a [boolean](17-language-reference.md#boolean-literals) value. ``` arguments = { "--host" = { value = "..." description = "..." required = true } } ``` Whenever the check is executed and the argument is missing, Icinga logs an error. This allows to better debug configuration errors instead of sometimes unreadable plugin errors when parameters are missing. ##### Command Arguments: Skip Key The `arguments` attribute requires a key, empty values are not allowed. To overcome this for parameters which don't need the name in front of the value, use the `skip_key` [boolean](17-language-reference.md#boolean-literals) toggle. ``` command = [ PrefixDir + "/bin/icingacli", "businessprocess", "process", "check" ] arguments = { "--process" = { value = "$icingacli_businessprocess_process$" description = "Business process to monitor" skip_key = true required = true order = -1 } } ``` The service specifies the [custom variable](03-monitoring-basics.md#custom-variables) `icingacli_businessprocess_process`. ``` vars.icingacli_businessprocess_process = "bp-shop-web" ``` This results in this command line without the `--process` parameter: ```bash '/bin/icingacli' 'businessprocess' 'process' 'check' 'bp-shop-web' ``` You can use this method to put everything into the `arguments` attribute in a defined order and without keys. This avoids entries in the `command` attributes too. ##### Command Arguments: Set If This can be used for the following scenarios: **Parameters without value, e.g. `--sni`.** ``` command = [ PluginDir + "/check_http"] arguments = { "--sni" = { set_if = "$http_sni$" } } ``` Whenever a host/service object sets the `http_sni` [custom variable](03-monitoring-basics.md#custom-variables) to `true`, the parameter is added to the command line. ```bash '/usr/lib64/nagios/plugins/check_http' '--sni' ``` [Numeric](17-language-reference.md#numeric-literals) values are allowed too. **Parameters with value, but additionally controlled with an extra custom variable boolean flag.** The following example is taken from the [postgres]() CheckCommand. The host parameter should use a `value` but only whenever the `postgres_unixsocket` [custom variable](03-monitoring-basics.md#custom-variables) is set to false. Note: `set_if` is using a runtime lambda function because the value is evaluated at runtime. This is explained in [this chapter](08-advanced-topics.md#use-functions-object-config). ``` command = [ PluginContribDir + "/check_postgres.pl" ] arguments = { "-H" = { value = "$postgres_host$" set_if = {{ macro("$postgres_unixsocket$") == false }} description = "hostname(s) to connect to; defaults to none (Unix socket)" } ``` An executed check for this host and services ... ``` object Host "postgresql-cluster" { // ... vars.postgres_host = "192.168.56.200" vars.postgres_unixsocket = false } ``` ... use the following command line: ```bash '/usr/lib64/nagios/plugins/check_postgres.pl' '-H' '192.168.56.200' ``` Host/service objects which set `postgres_unixsocket` to `false` don't add the `-H` parameter and its value to the command line. References: [abbreviated lambda syntax](17-language-reference.md#nullary-lambdas), [macro](18-library-reference.md#scoped-functions-macro). ##### Command Arguments: Order Plugin may require parameters in a special order. One after the other, or e.g. one parameter always in the first position. ``` arguments = { "--first" = { value = "..." description = "..." order = -5 } "--second" = { value = "..." description = "..." order = -4 } "--last" = { value = "..." description = "..." order = 99 } } ``` Keep in mind that positional arguments need to be tested thoroughly. ##### Command Arguments: Repeat Key Parameters can use [Array](17-language-reference.md#array) as value type. Whenever Icinga encounters an array, it repeats the parameter key and each value element by default. ``` command = [ NscpPath + "\\nscp.exe", "client" ] arguments = { "-a" = { value = "$nscp_arguments$" description = "..." repeat_key = true } } ``` On a host/service object, specify the `nscp_arguments` [custom variable](03-monitoring-basics.md#custom-variables) as an array. ``` vars.nscp_arguments = [ "exclude=sppsvc", "exclude=ShellHWDetection" ] ``` This translates into the following command line: ``` nscp.exe 'client' '-a' 'exclude=sppsvc' '-a' 'exclude=ShellHWDetection' ``` If the plugin requires you to pass the list without repeating the key, set `repeat_key = false` in the argument definition. ``` command = [ NscpPath + "\\nscp.exe", "client" ] arguments = { "-a" = { value = "$nscp_arguments$" description = "..." repeat_key = false } } ``` This translates into the following command line: ``` nscp.exe 'client' '-a' 'exclude=sppsvc' 'exclude=ShellHWDetection' ``` ##### Command Arguments: Key The `arguments` attribute requires unique keys. Sometimes, you'll need to override this in the resulting command line with same key names. Therefore you can specifically override the arguments key. ``` arguments = { "--key1" = { value = "..." key = "-specialkey" } "--key2" = { value = "..." key = "-specialkey" } } ``` This results in the following command line: ``` '-specialkey' '...' '-specialkey' '...' ``` #### Environment Variables The `env` command object attribute specifies a list of environment variables with values calculated from custom variables which should be exported as environment variables prior to executing the command. This is useful for example for hiding sensitive information on the command line output when passing credentials to database checks: ``` object CheckCommand "mysql" { command = [ PluginDir + "/check_mysql" ] arguments = { "-H" = "$mysql_address$" "-d" = "$mysql_database$" } vars.mysql_address = "$address$" vars.mysql_database = "icinga" vars.mysql_user = "icinga_check" vars.mysql_pass = "password" env.MYSQLUSER = "$mysql_user$" env.MYSQLPASS = "$mysql_pass$" } ``` The executed command line visible with `ps` or `top` looks like this and hides the database credentials in the user's environment. ```bash /usr/lib/nagios/plugins/check_mysql -H 192.168.56.101 -d icinga ``` > **Note** > > If the CheckCommand also supports setting the parameter in the command line, > ensure to use a different name for the custom variable. Otherwise Icinga 2 > adds the command line parameter. If a specific CheckCommand object provided with the [Icinga Template Library](10-icinga-template-library.md#icinga-template-library) needs additional environment variables, you can import it into a new custom CheckCommand object and add additional `env` keys. Example for the [mysql_health](10-icinga-template-library.md#plugin-contrib-command-mysql_health) CheckCommand: ``` object CheckCommand "mysql_health_env" { import "mysql_health" // https://labs.consol.de/nagios/check_mysql_health/ env.NAGIOS__SERVICEMYSQL_USER = "$mysql_health_env_username$" env.NAGIOS__SERVICEMYSQL_PASS = "$mysql_health_env_password$" } ``` Specify the custom variables `mysql_health_env_username` and `mysql_health_env_password` in the service object then. > **Note** > > Keep in mind that the values are still visible with the [debug console](11-cli-commands.md#cli-command-console) > and the inspect mode in the [Icinga Director](https://icinga.com/docs/director/latest/). You can also set global environment variables in the application's sysconfig configuration file, e.g. `HOME` or specific library paths for Oracle. Beware that these environment variables can be used by any CheckCommand object and executed plugin and can leak sensitive information. ### Notification Commands [NotificationCommand](09-object-types.md#objecttype-notificationcommand) objects define how notifications are delivered to external interfaces (email, XMPP, IRC, Twitter, etc.). [NotificationCommand](09-object-types.md#objecttype-notificationcommand) objects are referenced by [Notification](09-object-types.md#objecttype-notification) objects using the `command` attribute. > **Note** > > Make sure that the [notification](11-cli-commands.md#enable-features) feature is enabled > in order to execute notification commands. While it's possible to specify an entire notification command right in the NotificationCommand object it is generally advisable to create a shell script in the `/etc/icinga2/scripts` directory and have the NotificationCommand object refer to that. A fresh Icinga 2 install comes with with two example scripts for host and service notifications by email. Based on the Icinga 2 runtime macros (such as `$service.output$` for the current check output) it's possible to send email to the user(s) associated with the notification itself (`$user.email$`). Feel free to take these scripts as a starting point for your own individual notification solution - and keep in mind that nearly everything is technically possible. Information needed to generate notifications is passed to the scripts as arguments. The NotificationCommand objects `mail-host-notification` and `mail-service-notification` correspond to the shell scripts `mail-host-notification.sh` and `mail-service-notification.sh` in `/etc/icinga2/scripts` and define default values for arguments. These defaults can always be overwritten locally. > **Note** > > This example requires the `mail` binary installed on the Icinga 2 > master. > > Depending on the distribution, you need a local mail transfer > agent (MTA) such as Postfix, Exim or Sendmail in order > to send emails. > > These tools virtually provide the `mail` binary executed > by the notification scripts below. #### mail-host-notification The `mail-host-notification` NotificationCommand object uses the example notification script located in `/etc/icinga2/scripts/mail-host-notification.sh`. Here is a quick overview of the arguments that can be used. See also [host runtime macros](03-monitoring-basics.md#-host-runtime-macros) for further information. Name | Description -------------------------------|--------------------------------------- `notification_date` | **Required.** Date and time. Defaults to `$icinga.long_date_time$`. `notification_hostname` | **Required.** The host's `FQDN`. Defaults to `$host.name$`. `notification_hostdisplayname` | **Required.** The host's display name. Defaults to `$host.display_name$`. `notification_hostoutput` | **Required.** Output from host check. Defaults to `$host.output$`. `notification_useremail` | **Required.** The notification's recipient(s). Defaults to `$user.email$`. `notification_hoststate` | **Required.** Current state of host. Defaults to `$host.state$`. `notification_type` | **Required.** Type of notification. Defaults to `$notification.type$`. `notification_hostnotes` | **Optional.** The host's notes. Defaults to `$host.notes$`. `notification_address` | **Optional.** The host's IPv4 address. Defaults to `$address$`. `notification_address6` | **Optional.** The host's IPv6 address. Defaults to `$address6$`. `notification_author` | **Optional.** Comment author. Defaults to `$notification.author$`. `notification_comment` | **Optional.** Comment text. Defaults to `$notification.comment$`. `notification_from` | **Optional.** Define a valid From: string (e.g. `"Icinga 2 Host Monitoring "`). Requires `GNU mailutils` (Debian/Ubuntu) or `mailx` (RHEL/SUSE). `notification_icingaweb2url` | **Optional.** Define URL to your Icinga Web 2 (e.g. `"https://www.example.com/icingaweb2"`) `notification_logtosyslog` | **Optional.** Set `true` to log notification events to syslog; useful for debugging. Defaults to `false`. #### mail-service-notification The `mail-service-notification` NotificationCommand object uses the example notification script located in `/etc/icinga2/scripts/mail-service-notification.sh`. Here is a quick overview of the arguments that can be used. See also [service runtime macros](03-monitoring-basics.md#-service-runtime-macros) for further information. Name | Description ----------------------------------|--------------------------------------- `notification_date` | **Required.** Date and time. Defaults to `$icinga.long_date_time$`. `notification_hostname` | **Required.** The host's `FQDN`. Defaults to `$host.name$`. `notification_servicename` | **Required.** The service name. Defaults to `$service.name$`. `notification_hostdisplayname` | **Required.** Host display name. Defaults to `$host.display_name$`. `notification_servicedisplayname` | **Required.** Service display name. Defaults to `$service.display_name$`. `notification_serviceoutput` | **Required.** Output from service check. Defaults to `$service.output$`. `notification_useremail` | **Required.** The notification's recipient(s). Defaults to `$user.email$`. `notification_servicestate` | **Required.** Current state of host. Defaults to `$service.state$`. `notification_type` | **Required.** Type of notification. Defaults to `$notification.type$`. `notification_hostnotes` | **Optional.** The host's notes. Defaults to `$host.notes$`. `notification_servicenotes` | **Optional.** The service's notes. Defaults to `$service.notes$`. `notification_address` | **Optional.** The host's IPv4 address. Defaults to `$address$`. `notification_address6` | **Optional.** The host's IPv6 address. Defaults to `$address6$`. `notification_author` | **Optional.** Comment author. Defaults to `$notification.author$`. `notification_comment` | **Optional.** Comment text. Defaults to `$notification.comment$`. `notification_from` | **Optional.** Define a valid From: string (e.g. `"Icinga 2 Host Monitoring "`). Requires `GNU mailutils` (Debian/Ubuntu) or `mailx` (RHEL/SUSE). `notification_icingaweb2url` | **Optional.** Define URL to your Icinga Web 2 (e.g. `"https://www.example.com/icingaweb2"`) `notification_logtosyslog` | **Optional.** Set `true` to log notification events to syslog; useful for debugging. Defaults to `false`. ### Event Commands Unlike notifications, event commands for hosts/services are called on every check execution if one of these conditions matches: * The host/service is in a [soft state](03-monitoring-basics.md#hard-soft-states) * The host/service state changes into a [hard state](03-monitoring-basics.md#hard-soft-states) * The host/service state recovers from a [soft or hard state](03-monitoring-basics.md#hard-soft-states) to [OK](03-monitoring-basics.md#service-states)/[Up](03-monitoring-basics.md#host-states) [EventCommand](09-object-types.md#objecttype-eventcommand) objects are referenced by [Host](09-object-types.md#objecttype-host) and [Service](09-object-types.md#objecttype-service) objects with the `event_command` attribute. Therefore the `EventCommand` object should define a command line evaluating the current service state and other service runtime attributes available through runtime variables. Runtime macros such as `$service.state_type$` and `$service.state$` will be processed by Icinga 2 and help with fine-granular triggered events If the host/service is located on a client as [command endpoint](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) the event command will be executed on the client itself (similar to the check command). Common use case scenarios are a failing HTTP check which requires an immediate restart via event command. Another example would be an application that is not responding and therefore requires a restart. You can also use event handlers to forward more details on state changes and events than the typical notification alerts provide. #### Use Event Commands to Send Information from the Master This example sends a web request from the master node to an external tool for every event triggered on a `businessprocess` service. Define an [EventCommand](09-object-types.md#objecttype-eventcommand) object `send_to_businesstool` which sends state changes to the external tool. ``` object EventCommand "send_to_businesstool" { command = [ "/usr/bin/curl", "-s", "-X PUT" ] arguments = { "-H" = { value ="$businesstool_url$" skip_key = true } "-d" = "$businesstool_message$" } vars.businesstool_url = "http://localhost:8080/businesstool" vars.businesstool_message = "$host.name$ $service.name$ $service.state$ $service.state_type$ $service.check_attempt$" } ``` Set the `event_command` attribute to `send_to_businesstool` on the Service. ``` object Service "businessprocess" { host_name = "businessprocess" check_command = "icingacli-businessprocess" vars.icingacli_businessprocess_process = "icinga" vars.icingacli_businessprocess_config = "training" event_command = "send_to_businesstool" } ``` In order to test this scenario you can run: ```bash nc -l 8080 ``` This allows to catch the web request. You can also enable the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) and search for the event command execution log message. ```bash tail -f /var/log/icinga2/debug.log | grep EventCommand ``` Feed in a check result via REST API action [process-check-result](12-icinga2-api.md#icinga2-api-actions-process-check-result) or via Icinga Web 2. Expected Result: ``` # nc -l 8080 PUT /businesstool HTTP/1.1 User-Agent: curl/7.29.0 Host: localhost:8080 Accept: */* Content-Length: 47 Content-Type: application/x-www-form-urlencoded businessprocess businessprocess CRITICAL SOFT 1 ``` #### Use Event Commands to Restart Service Daemon via Command Endpoint on Linux This example triggers a restart of the `httpd` service on the local system when the `procs` service check executed via Command Endpoint fails. It only triggers if the service state is `Critical` and attempts to restart the service before a notification is sent. Requirements: * Icinga 2 as client on the remote node * icinga user with sudo permissions to the httpd daemon Example on RHEL: ``` # visudo icinga ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart httpd ``` Note: Distributions might use a different name. On Debian/Ubuntu the service is called `apache2`. Define an [EventCommand](09-object-types.md#objecttype-eventcommand) object `restart_service` which allows to trigger local service restarts. Put it into a [global zone](06-distributed-monitoring.md#distributed-monitoring-global-zone-config-sync) to sync its configuration to all clients. ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/global-templates/eventcommands.conf object EventCommand "restart_service" { command = [ PluginDir + "/restart_service" ] arguments = { "-s" = "$service.state$" "-t" = "$service.state_type$" "-a" = "$service.check_attempt$" "-S" = "$restart_service$" } vars.restart_service = "$procs_command$" } ``` This event command triggers the following script which restarts the service. The script only is executed if the service state is `CRITICAL`. Warning and Unknown states are ignored as they indicate not an immediate failure. ``` [root@icinga2-agent1.localdomain /]# vim /usr/lib64/nagios/plugins/restart_service #!/bin/bash while getopts "s:t:a:S:" opt; do case $opt in s) servicestate=$OPTARG ;; t) servicestatetype=$OPTARG ;; a) serviceattempt=$OPTARG ;; S) service=$OPTARG ;; esac done if ( [ -z $servicestate ] || [ -z $servicestatetype ] || [ -z $serviceattempt ] || [ -z $service ] ); then echo "USAGE: $0 -s servicestate -z servicestatetype -a serviceattempt -S service" exit 3; else # Only restart on the third attempt of a critical event if ( [ $servicestate == "CRITICAL" ] && [ $servicestatetype == "SOFT" ] && [ $serviceattempt -eq 3 ] ); then sudo /usr/bin/systemctl restart $service fi fi [root@icinga2-agent1.localdomain /]# chmod +x /usr/lib64/nagios/plugins/restart_service ``` Add a service on the master node which is executed via command endpoint on the client. Set the `event_command` attribute to `restart_service`, the name of the previously defined EventCommand object. ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/icinga2-agent1.localdomain.conf object Service "Process httpd" { check_command = "procs" event_command = "restart_service" max_check_attempts = 4 host_name = "icinga2-agent1.localdomain" command_endpoint = "icinga2-agent1.localdomain" vars.procs_command = "httpd" vars.procs_warning = "1:10" vars.procs_critical = "1:" } ``` In order to test this configuration just stop the `httpd` on the remote host `icinga2-agent1.localdomain`. ``` [root@icinga2-agent1.localdomain /]# systemctl stop httpd ``` You can enable the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) and search for the executed command line. ``` [root@icinga2-agent1.localdomain /]# tail -f /var/log/icinga2/debug.log | grep restart_service ``` #### Use Event Commands to Restart Service Daemon via Command Endpoint on Windows This example triggers a restart of the `httpd` service on the remote system when the `service-windows` service check executed via Command Endpoint fails. It only triggers if the service state is `Critical` and attempts to restart the service before a notification is sent. Requirements: * Icinga 2 as client on the remote node * Icinga 2 service with permissions to execute Powershell scripts (which is the default) Define an [EventCommand](09-object-types.md#objecttype-eventcommand) object `restart_service-windows` which allows to trigger local service restarts. Put it into a [global zone](06-distributed-monitoring.md#distributed-monitoring-global-zone-config-sync) to sync its configuration to all clients. ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/global-templates/eventcommands.conf object EventCommand "restart_service-windows" { command = [ "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe", PluginDir + "/restart_service.ps1" ] arguments = { "-ServiceState" = "$service.state$" "-ServiceStateType" = "$service.state_type$" "-ServiceAttempt" = "$service.check_attempt$" "-Service" = "$restart_service$" "; exit" = { order = 99 value = "$$LASTEXITCODE" } } vars.restart_service = "$service_win_service$" } ``` This event command triggers the following script which restarts the service. The script only is executed if the service state is `CRITICAL`. Warning and Unknown states are ignored as they indicate not an immediate failure. Add the `restart_service.ps1` Powershell script into `C:\Program Files\Icinga2\sbin`: ``` param( [string]$Service = '', [string]$ServiceState = '', [string]$ServiceStateType = '', [int]$ServiceAttempt = '' ) if (!$Service -Or !$ServiceState -Or !$ServiceStateType -Or !$ServiceAttempt) { $scriptName = GCI $MyInvocation.PSCommandPath | Select -Expand Name; Write-Host "USAGE: $scriptName -ServiceState servicestate -ServiceStateType servicestatetype -ServiceAttempt serviceattempt -Service service" -ForegroundColor red; exit 3; } # Only restart on the third attempt of a critical event if ($ServiceState -eq "CRITICAL" -And $ServiceStateType -eq "SOFT" -And $ServiceAttempt -eq 3) { Restart-Service $Service; } exit 0; ``` Add a service on the master node which is executed via command endpoint on the client. Set the `event_command` attribute to `restart_service-windows`, the name of the previously defined EventCommand object. ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/icinga2-agent2.localdomain.conf object Service "Service httpd" { check_command = "service-windows" event_command = "restart_service-windows" max_check_attempts = 4 host_name = "icinga2-agent2.localdomain" command_endpoint = "icinga2-agent2.localdomain" vars.service_win_service = "httpd" } ``` In order to test this configuration just stop the `httpd` on the remote host `icinga2-agent1.localdomain`. ``` C:> net stop httpd ``` You can enable the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) and search for the executed command line in `C:\ProgramData\icinga2\var\log\icinga2\debug.log`. #### Use Event Commands to Restart Service Daemon via SSH This example triggers a restart of the `httpd` daemon via SSH when the `http` service check fails. Requirements: * SSH connection allowed (firewall, packet filters) * icinga user with public key authentication * icinga user with sudo permissions to restart the httpd daemon. Example on Debian: ``` # ls /home/icinga/.ssh/ authorized_keys # visudo icinga ALL=(ALL) NOPASSWD: /etc/init.d/apache2 restart ``` Define a generic [EventCommand](09-object-types.md#objecttype-eventcommand) object `event_by_ssh` which can be used for all event commands triggered using SSH: ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/local_eventcommands.conf /* pass event commands through ssh */ object EventCommand "event_by_ssh" { command = [ PluginDir + "/check_by_ssh" ] arguments = { "-H" = "$event_by_ssh_address$" "-p" = "$event_by_ssh_port$" "-C" = "$event_by_ssh_command$" "-l" = "$event_by_ssh_logname$" "-i" = "$event_by_ssh_identity$" "-q" = { set_if = "$event_by_ssh_quiet$" } "-w" = "$event_by_ssh_warn$" "-c" = "$event_by_ssh_crit$" "-t" = "$event_by_ssh_timeout$" } vars.event_by_ssh_address = "$address$" vars.event_by_ssh_quiet = false } ``` The actual event command only passes the `event_by_ssh_command` attribute. The `event_by_ssh_service` custom variable takes care of passing the correct daemon name, while `test $service.state_id$ -gt 0` makes sure that the daemon is only restarted when the service is not in an `OK` state. ``` object EventCommand "event_by_ssh_restart_service" { import "event_by_ssh" //only restart the daemon if state > 0 (not-ok) //requires sudo permissions for the icinga user vars.event_by_ssh_command = "test $service.state_id$ -gt 0 && sudo systemctl restart $event_by_ssh_service$" } ``` Now set the `event_command` attribute to `event_by_ssh_restart_service` and tell it which service should be restarted using the `event_by_ssh_service` attribute. ``` apply Service "http" { import "generic-service" check_command = "http" event_command = "event_by_ssh_restart_service" vars.event_by_ssh_service = "$host.vars.httpd_name$" //vars.event_by_ssh_logname = "icinga" //vars.event_by_ssh_identity = "/home/icinga/.ssh/id_rsa.pub" assign where host.vars.httpd_name } ``` Specify the `httpd_name` custom variable on the host to assign the service and set the event handler service. ``` object Host "remote-http-host" { import "generic-host" address = "192.168.1.100" vars.httpd_name = "apache2" } ``` In order to test this configuration just stop the `httpd` on the remote host `icinga2-agent1.localdomain`. ``` [root@icinga2-agent1.localdomain /]# systemctl stop httpd ``` You can enable the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) and search for the executed command line. ``` [root@icinga2-agent1.localdomain /]# tail -f /var/log/icinga2/debug.log | grep by_ssh ``` ## Dependencies Icinga 2 uses host and service [Dependency](09-object-types.md#objecttype-dependency) objects for determining their network reachability. A service can depend on a host, and vice versa. A service has an implicit dependency (parent) to its host. A host to host dependency acts implicitly as host parent relation. When dependencies are calculated, not only the immediate parent is taken into account but all parents are inherited. The `parent_host_name` and `parent_service_name` attributes are mandatory for service dependencies, `parent_host_name` is required for host dependencies. [Apply rules](03-monitoring-basics.md#using-apply) will allow you to [determine these attributes](03-monitoring-basics.md#dependencies-apply-custom-variables) in a more dynamic fashion if required. ``` parent_host_name = "core-router" parent_service_name = "uplink-port" ``` Notifications are suppressed by default if a host or service becomes unreachable. You can control that option by defining the `disable_notifications` attribute. ``` disable_notifications = false ``` If the dependency should be triggered in the parent object's soft state, you need to set `ignore_soft_states` to `false`. The dependency state filter must be defined based on the parent object being either a host (`Up`, `Down`) or a service (`OK`, `Warning`, `Critical`, `Unknown`). The following example will make the dependency fail and trigger it if the parent object is **not** in one of these states: ``` states = [ OK, Critical, Unknown ] ``` > **In other words** > > If the parent service object changes into the `Warning` state, this > dependency will fail and render all child objects (hosts or services) unreachable. You can determine the child's reachability by querying the `last_reachable` attribute via the [REST API](12-icinga2-api.md#icinga2-api). > **Note** > > Reachability calculation depends on fresh and processed check results. If dependencies > disable checks for child objects, this won't work reliably. ### Implicit Dependencies for Services on Host Icinga 2 automatically adds an implicit dependency for services on their host. That way service notifications are suppressed when a host is `DOWN` or `UNREACHABLE`. This dependency does not overwrite other dependencies and implicitly sets `disable_notifications = true` and `states = [ Up ]` for all service objects. Service checks are still executed. If you want to prevent them from happening, you can apply the following dependency to all services setting their host as `parent_host_name` and disabling the checks. `assign where true` matches on all `Service` objects. ``` apply Dependency "disable-host-service-checks" to Service { disable_checks = true assign where true } ``` ### Dependencies for Network Reachability A common scenario is the Icinga 2 server behind a router. Checking internet access by pinging the Google DNS server `google-dns` is a common method, but will fail in case the `dsl-router` host is down. Therefore the example below defines a host dependency which acts implicitly as parent relation too. Furthermore the host may be reachable but ping probes are dropped by the router's firewall. In case the `dsl-router`'s `ping4` service check fails, all further checks for the `ping4` service on host `google-dns` service should be suppressed. This is achieved by setting the `disable_checks` attribute to `true`. ``` object Host "dsl-router" { import "generic-host" address = "192.168.1.1" } object Host "google-dns" { import "generic-host" address = "8.8.8.8" } apply Service "ping4" { import "generic-service" check_command = "ping4" assign where host.address } apply Dependency "internet" to Host { parent_host_name = "dsl-router" disable_checks = true disable_notifications = true assign where host.name != "dsl-router" } apply Dependency "internet" to Service { parent_host_name = "dsl-router" parent_service_name = "ping4" disable_checks = true assign where host.name != "dsl-router" } ``` ### Redundancy Groups Sometimes you want dependencies to accumulate, i.e. to consider the parent reachable only if no dependency is violated. Sometimes you want them to be regarded as redundant, i.e. to consider the parent unreachable only if no dependency is fulfilled. Think of a host connected to both a network and a storage switch vs. a host connected to redundant routers. Sometimes you even want a mixture of both. Think of a service like SSH depeding on both LDAP and DNS to function, while operating redundant LDAP servers as well as redundant DNS resolvers. Before v2.12, Icinga regarded all dependecies as cumulative. In v2.12 and v2.13, Icinga regarded all dependencies redundant. The latter led to unrelated services being inadvertantly regarded to be redundant to each other. v2.14 restored the former behavior and allowed to override it. I.e. all dependecies are regarded as essential for the parent by default. Specifying the `redundancy_group` attribute for two dependecies of a child object with the equal value causes them to be regarded as redundant (only inside that redundancy group). ### Apply Dependencies based on Custom Variables You can use [apply rules](03-monitoring-basics.md#using-apply) to set parent or child attributes, e.g. `parent_host_name` to other objects' attributes. A common example are virtual machines hosted on a master. The object name of that master is auto-generated from your CMDB or VMWare inventory into the host's custom variables (or a generic template for your cloud). Define your master host object: ``` /* your master */ object Host "master.example.com" { import "generic-host" } ``` Add a generic template defining all common host attributes: ``` /* generic template for your virtual machines */ template Host "generic-vm" { import "generic-host" } ``` Add a template for all hosts on your example.com cloud setting custom variable `vm_parent` to `master.example.com`: ``` template Host "generic-vm-example.com" { import "generic-vm" vars.vm_parent = "master.example.com" } ``` Define your guest hosts: ``` object Host "www.example1.com" { import "generic-vm-master.example.com" } object Host "www.example2.com" { import "generic-vm-master.example.com" } ``` Apply the host dependency to all child hosts importing the `generic-vm` template and set the `parent_host_name` to the previously defined custom variable `host.vars.vm_parent`. ``` apply Dependency "vm-host-to-parent-master" to Host { parent_host_name = host.vars.vm_parent assign where "generic-vm" in host.templates } ``` You can extend this example, and make your services depend on the `master.example.com` host too. Their local scope allows you to use `host.vars.vm_parent` similar to the example above. ``` apply Dependency "vm-service-to-parent-master" to Service { parent_host_name = host.vars.vm_parent assign where "generic-vm" in host.templates } ``` That way you don't need to wait for your guest hosts becoming unreachable when the master host goes down. Instead the services will detect their reachability immediately when executing checks. > **Note** > > This method with setting locally scoped variables only works in > apply rules, but not in object definitions. ### Dependencies for Agent Checks Another good example are agent based checks. You would define a health check for the agent daemon responding to your requests, and make all other services querying that daemon depend on that health check. ``` apply Service "agent-health" { check_command = "cluster-zone" display_name = "cluster-health-" + host.name /* This follows the convention that the agent zone name is the FQDN which is the same as the host object name. */ vars.cluster_zone = host.name assign where host.vars.agent_endpoint } ``` Now, make all other agent based checks dependent on the OK state of the `agent-health` service. ``` apply Dependency "agent-health-check" to Service { parent_service_name = "agent-health" states = [ OK ] // Fail if the parent service state switches to NOT-OK disable_notifications = true assign where host.vars.agent_endpoint // Automatically assigns all agent endpoint checks as child services on the matched host ignore where service.name == "agent-health" // Avoid a self reference from child to parent } ``` This is described in detail in [this chapter](06-distributed-monitoring.md#distributed-monitoring-health-checks). icinga2-2.14.6/doc/04-configuration.md000066400000000000000000000677471501332562400173250ustar00rootroot00000000000000# Configuration The Icinga [configuration](https://icinga.com/products/configuration/) can be easily managed with either the [Icinga Director](https://icinga.com/docs/director/latest/), config management tools or plain text within the [Icinga DSL](04-configuration.md#configuration). Before looking into web based configuration or any sort of automation, we recommend to start with the configuration files and fully understand the possibilities of the Icinga DSL (Domain Specific Language). The package installation provides example configuration which already monitors the local Icinga server. You can view the monitoring details in Icinga Web. ![Icinga Web Local Server](images/configuration/icinga_web_local_server.png) The [Language Reference](17-language-reference.md#language-reference) chapter explains details on value types (string, number, dictionaries, etc.) and the general configuration syntax. ## Configuration Best Practice If you are ready to configure additional hosts, services, notifications, dependencies, etc., you should think about the requirements first and then decide for a possible strategy. There are many ways of creating Icinga 2 configuration objects: * The [Icinga Director](https://icinga.com/docs/director/latest/) as web based and/or automation configuration interface * [Monitoring Automation with Icinga - The Director](https://icinga.com/2019/04/23/monitoring-automation-with-icinga-the-director/) * Manually with your preferred editor, for example vi(m), nano, notepad, etc. * Generated by a [configuration management tool](13-addons.md#configuration-tools) such as Puppet, Chef, Ansible, etc. * A custom exporter script from your CMDB or inventory tool * etc. Find the best strategy for your own configuration and ask yourself the following questions: * Do your hosts share a common group of services (for example linux hosts with disk, load, etc. checks)? * Only a small set of users receives notifications and escalations for all hosts/services? If you can at least answer one of these questions with yes, look for the [apply rules](03-monitoring-basics.md#using-apply) logic instead of defining objects on a per host and service basis. * You are required to define specific configuration for each host/service? * Does your configuration generation tool already know about the host-service-relationship? Then you should look for the object specific configuration setting `host_name` etc. accordingly. You decide on the "best" layout for configuration files and directories. Ensure that the [icinga2.conf](04-configuration.md#icinga2-conf) configuration file includes them. Consider these ideas: * tree-based on locations, host groups, specific host attributes with sub levels of directories. * flat `hosts.conf`, `services.conf`, etc. files for rule based configuration. * generated configuration with one file per host and a global configuration for groups, users, etc. * one big file generated from an external application (probably a bad idea for maintaining changes). * your own. In either way of choosing the right strategy you should additionally check the following: * Are there any specific attributes describing the host/service you could set as `vars` custom variables? You can later use them for applying assign/ignore rules, or export them into external interfaces. * Put hosts into hostgroups, services into servicegroups and use these attributes for your apply rules. * Use templates to store generic attributes for your objects and apply rules making your configuration more readable. Details can be found in the [using templates](03-monitoring-basics.md#object-inheritance-using-templates) chapter. * Apply rules may overlap. Keep a central place (for example, [services.conf](04-configuration.md#services-conf) or [notifications.conf](04-configuration.md#notifications-conf)) storing the configuration instead of defining apply rules deep in your configuration tree. * Every plugin used as check, notification or event command requires a `Command` definition. Further details can be looked up in the [check commands](03-monitoring-basics.md#check-commands) chapter. If you are planning to use a distributed monitoring setup with master, satellite and client installations take the configuration location into account too. Everything configured on the master, synced to all other nodes? Or any specific local configuration (e.g. health checks)? There is a detailed chapter on [distributed monitoring scenarios](06-distributed-monitoring.md#distributed-monitoring-scenarios). Please ensure to have read the [introduction](06-distributed-monitoring.md#distributed-monitoring) at first glance. If you happen to have further questions, do not hesitate to join the [community forum](https://community.icinga.com) and ask community members for their experience and best practices. ## Your Configuration If you prefer to organize your own local object tree, you can also remove `include_recursive "conf.d"` from your icinga2.conf file. Create a new configuration directory, e.g. `objects.d` and include it in your icinga2.conf file. ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/objects.d [root@icinga2-master1.localdomain /]# vim /etc/icinga2/icinga2.conf /* Local object configuration on our master instance. */ include_recursive "objects.d" ``` This approach is used by the [Icinga 2 Puppet module](https://icinga.com/products/integrations/puppet/). If you plan to setup a distributed setup with HA clusters and clients, please refer to [this chapter](#06-distributed-monitoring.md#distributed-monitoring-top-down) for examples with `zones.d` as configuration directory. ## Configuration Overview ### icinga2.conf An example configuration file is installed for you in `/etc/icinga2/icinga2.conf`. Here's a brief description of the example configuration: ``` /** * Icinga 2 configuration file * -- this is where you define settings for the Icinga application including * which hosts/services to check. * * For an overview of all available configuration options please refer * to the documentation that is distributed as part of Icinga 2. */ ``` Icinga 2 supports [C/C++-style comments](17-language-reference.md#comments). /** * The constants.conf defines global constants. */ include "constants.conf" The `include` directive can be used to include other files. ``` /** * The zones.conf defines zones for a cluster setup. * Not required for single instance setups. */ include "zones.conf" ``` The [Icinga Template Library](10-icinga-template-library.md#icinga-template-library) provides a set of common templates and [CheckCommand](03-monitoring-basics.md#check-commands) definitions. ``` /** * The Icinga Template Library (ITL) provides a number of useful templates * and command definitions. * Common monitoring plugin command definitions are included separately. */ include include include include /** * This includes the Icinga 2 Windows plugins. These command definitions * are required on a master node when a client is used as command endpoint. */ include /** * This includes the NSClient++ check commands. These command definitions * are required on a master node when a client is used as command endpoint. */ include /** * The features-available directory contains a number of configuration * files for features which can be enabled and disabled using the * icinga2 feature enable / icinga2 feature disable CLI commands. * These commands work by creating and removing symbolic links in * the features-enabled directory. */ include "features-enabled/*.conf" ``` This `include` directive takes care of including the configuration files for all the features which have been enabled with `icinga2 feature enable`. See [Enabling/Disabling Features](11-cli-commands.md#enable-features) for more details. ``` /** * Although in theory you could define all your objects in this file * the preferred way is to create separate directories and files in the conf.d * directory. Each of these files must have the file extension ".conf". */ include_recursive "conf.d" ``` You can put your own configuration files in the [conf.d](04-configuration.md#conf-d) directory. This directive makes sure that all of your own configuration files are included. ### constants.conf The `constants.conf` configuration file can be used to define global constants. By default, you need to make sure to set these constants: * The `PluginDir` constant must be set to the path where the [Monitoring Project](https://www.monitoring-plugins.org/) plugins are installed. This constant is used by a number of [built-in check command definitions](10-icinga-template-library.md#icinga-template-library). * The `NodeName` constant defines your local node name. Should be set to FQDN which is the default if not set. This constant is required for local host configuration, monitoring remote clients and cluster setup. Example: ``` /* The directory which contains the plugins from the Monitoring Plugins project. */ const PluginDir = "/usr/lib64/nagios/plugins" /* The directory which contains the Manubulon plugins. * Check the documentation, chapter "SNMP Manubulon Plugin Check Commands", for details. */ const ManubulonPluginDir = "/usr/lib64/nagios/plugins" /* Our local instance name. By default this is the server's hostname as returned by `hostname --fqdn`. * This should be the common name from the API certificate. */ //const NodeName = "localhost" /* Our local zone name. */ const ZoneName = NodeName /* Secret key for remote node tickets */ const TicketSalt = "" ``` The `ZoneName` and `TicketSalt` constants are required for remote client and distributed setups. The `node setup/wizard` CLI tools take care of populating these values. ### zones.conf This file can be used to specify the required [Zone](09-object-types.md#objecttype-zone) and [Endpoint](09-object-types.md#objecttype-endpoint) configuration object for [distributed monitoring](06-distributed-monitoring.md#distributed-monitoring). By default the `NodeName` and `ZoneName` [constants](04-configuration.md#constants-conf) will be used. It also contains several [global zones](06-distributed-monitoring.md#distributed-monitoring-global-zone-config-sync) for distributed monitoring environments. Please ensure to modify this configuration with real names i.e. use the FQDN mentioned in [this chapter](06-distributed-monitoring.md#distributed-monitoring-conventions) for your `Zone` and `Endpoint` object names. ### The conf.d Directory This directory contains **example configuration** which should help you get started with monitoring the local host and its services. It is included in the [icinga2.conf](04-configuration.md#icinga2-conf) configuration file by default. It can be used as reference example for your own configuration strategy. Just keep in mind to include the main directories in the [icinga2.conf](04-configuration.md#icinga2-conf) file. > **Note** > > You can remove the include directive in [icinga2.conf](04-configuration.md#icinga2-conf) > if you prefer your own way of deploying Icinga 2 configuration. Further details on configuration best practice and how to build your own strategy is described in [this chapter](04-configuration.md#configuration-best-practice). Available configuration files which are installed by default: * [hosts.conf](04-configuration.md#hosts-conf) * [services.conf](04-configuration.md#services-conf) * [users.conf](04-configuration.md#users-conf) * [notifications.conf](04-configuration.md#notifications-conf) * [commands.conf](04-configuration.md#commands-conf) * [groups.conf](04-configuration.md#groups-conf) * [templates.conf](04-configuration.md#templates-conf) * [downtimes.conf](04-configuration.md#downtimes-conf) * [timeperiods.conf](04-configuration.md#timeperiods-conf) * [api-users.conf](04-configuration.md#api-users-conf) * [app.conf](04-configuration.md#app-conf) #### hosts.conf The `hosts.conf` file contains an example host based on your `NodeName` setting in [constants.conf](04-configuration.md#constants-conf). You can use global constants for your object names instead of string values. The `import` keyword is used to import the `generic-host` template which takes care of setting up the host check command to `hostalive`. If you require a different check command, you can override it in the object definition. The `vars` attribute can be used to define custom variables which are available for check and notification commands. Most of the [Plugin Check Commands](10-icinga-template-library.md#icinga-template-library) in the Icinga Template Library require an `address` attribute. The custom variable `os` is evaluated by the `linux-servers` group in [groups.conf](04-configuration.md#groups-conf) making the local host a member. The example host will show you how to: * define http vhost attributes for the `http` service apply rule defined in [services.conf](04-configuration.md#services-conf). * define disks (all, specific `/`) and their attributes for the `disk` service apply rule defined in [services.conf](04-configuration.md#services-conf). * define notification types (`mail`) and set the groups attribute. This will be used by notification apply rules in [notifications.conf](04-configuration.md#notifications-conf). If you've installed [Icinga Web 2](https://icinga.com/docs/icinga-web-2/latest/doc/02-Installation/), you can uncomment the http vhost attributes and reload Icinga 2. The apply rules in [services.conf](04-configuration.md#services-conf) will automatically generate a new service checking the `/icingaweb2` URI using the `http` check. ``` /* * Host definitions with object attributes * used for apply rules for Service, Notification, * Dependency and ScheduledDowntime objects. * * Tip: Use `icinga2 object list --type Host` to * list all host objects after running * configuration validation (`icinga2 daemon -C`). */ /* * This is an example host based on your * local host's FQDN. Specify the NodeName * constant in `constants.conf` or use your * own description, e.g. "db-host-1". */ object Host NodeName { /* Import the default host template defined in `templates.conf`. */ import "generic-host" /* Specify the address attributes for checks e.g. `ssh` or `http`. */ address = "127.0.0.1" address6 = "::1" /* Set custom variable `os` for hostgroup assignment in `groups.conf`. */ vars.os = "Linux" /* Define http vhost attributes for service apply rules in `services.conf`. */ vars.http_vhosts["http"] = { http_uri = "/" } /* Uncomment if you've successfully installed Icinga Web 2. */ //vars.http_vhosts["Icinga Web 2"] = { // http_uri = "/icingaweb2" //} /* Define disks and attributes for service apply rules in `services.conf`. */ vars.disks["disk"] = { /* No parameters. */ } vars.disks["disk /"] = { disk_partitions = "/" } /* Define notification mail attributes for notification apply rules in `notifications.conf`. */ vars.notification["mail"] = { /* The UserGroup `icingaadmins` is defined in `users.conf`. */ groups = [ "icingaadmins" ] } } ``` This is only the host object definition. Now we'll need to make sure that this host and your additional hosts are getting [services](04-configuration.md#services-conf) applied. > **Tip** > > If you don't understand all the attributes and how to use [apply rules](17-language-reference.md#apply), > don't worry -- the [monitoring basics](03-monitoring-basics.md#monitoring-basics) chapter will explain > that in detail. #### services.conf These service [apply rules](17-language-reference.md#apply) will show you how to monitor the local host, but also allow you to re-use or modify them for your own requirements. You should define all your service apply rules in `services.conf` or any other central location keeping them organized. By default, the local host will be monitored by the following services Service(s) | Applied on host(s) --------------------------------------------|------------------------ `load`, `procs`, `swap`, `users`, `icinga` | The `NodeName` host only. `ping4`, `ping6` | All hosts with `address` resp. `address6` attribute. `ssh` | All hosts with `address` and `vars.os` set to `Linux` `http`, optional: `Icinga Web 2` | All hosts with custom variable `http_vhosts` defined as dictionary. `disk`, `disk /` | All hosts with custom variable `disks` defined as dictionary. The Debian packages also include an additional `apt` service check applied to the local host. The command object `icinga` for the embedded health check is provided by the [Icinga Template Library (ITL)](10-icinga-template-library.md#icinga-template-library) while `http_ip`, `ssh`, `load`, `processes`, `users` and `disk` are all provided by the [Plugin Check Commands](10-icinga-template-library.md#icinga-template-library) which we enabled earlier by including the `itl` and `plugins` configuration file. Example `load` service apply rule: ``` apply Service "load" { import "generic-service" check_command = "load" /* Used by the ScheduledDowntime apply rule in `downtimes.conf`. */ vars.backup_downtime = "02:00-03:00" assign where host.name == NodeName } ``` The `apply` keyword can be used to create new objects which are associated with another group of objects. You can `import` existing templates, define (custom) attributes. The custom variable `backup_downtime` is defined to a specific timerange string. This variable value will be used for applying a `ScheduledDowntime` object to these services in [downtimes.conf](04-configuration.md#downtimes-conf). In this example the `assign where` condition is a boolean expression which is evaluated for all objects of type `Host` and a new service with name "load" is created for each matching host. [Expression operators](17-language-reference.md#expression-operators) may be used in `assign where` conditions. Multiple `assign where` conditions can be combined with `AND` using the `&&` operator as shown in the `ssh` example: ``` apply Service "ssh" { import "generic-service" check_command = "ssh" assign where host.address && host.vars.os == "Linux" } ``` In this example, the service `ssh` is applied to all hosts having the `address` attribute defined `AND` having the custom variable `os` set to the string `Linux`. You can modify this condition to match multiple expressions by combining `AND` and `OR` using `&&` and `||` [operators](17-language-reference.md#expression-operators), for example `assign where host.address && (vars.os == "Linux" || vars.os == "Windows")`. A more advanced example is shown by the `http` and `disk` service apply rules. While one `apply` rule for `ssh` will only create a service for matching hosts, you can go one step further: Generate apply rules based on array items or dictionary key-value pairs. The idea is simple: Your host in [hosts.conf](04-configuration.md#hosts-conf) defines the `disks` dictionary as custom variable in `vars`. Remember the example from [hosts.conf](04-configuration.md#hosts-conf): ``` ... /* Define disks and attributes for service apply rules in `services.conf`. */ vars.disks["disk"] = { /* No parameters. */ } vars.disks["disk /"] = { disk_partition = "/" } ... ``` This dictionary contains multiple service names we want to monitor. `disk` should just check all available disks, while `disk /` will pass an additional parameter `disk_partition` to the check command. You'll recognize that the naming is important -- that's the very same name as it is passed from a service to a check command argument. Read about services and passing check commands in [this chapter](03-monitoring-basics.md#command-passing-parameters). Using `apply Service for` omits the service name, it will take the key stored in the `disk` variable in `key => config` as new service object name. The `for` keyword expects a loop definition, for example `key => value in dictionary` as known from Perl and other scripting languages. Once defined like this, the `apply` rule defined below will do the following: * only match hosts with `host.vars.disks` defined through the `assign where` condition * loop through all entries in the `host.vars.disks` dictionary. That's `disk` and `disk /` as keys. * call `apply` on each, and set the service object name from the provided key * inside apply, the `generic-service` template is imported * defining the [disk](10-icinga-template-library.md#plugin-check-command-disk) check command requiring command arguments like `disk_partition` * adding the `config` dictionary items to `vars`. Simply said, there's now `vars.disk_partition` defined for the generated service Configuration example: ``` apply Service for (disk => config in host.vars.disks) { import "generic-service" check_command = "disk" vars += config } ``` A similar example is used for the `http` services. That way you can make your host the information provider for all apply rules. Define them once, and only manage your hosts. Look into [notifications.conf](04-configuration.md#notifications-conf) how this technique is used for applying notifications to hosts and services using their type and user attributes. Don't forget to install the check plugins required by the hosts and services and their check commands. Further details on the monitoring configuration can be found in the [monitoring basics](03-monitoring-basics.md#monitoring-basics) chapter. #### users.conf Defines the `icingaadmin` User and the `icingaadmins` UserGroup. The latter is used in [hosts.conf](04-configuration.md#hosts-conf) for defining a custom host attribute later used in [notifications.conf](04-configuration.md#notifications-conf) for notification apply rules. ``` object User "icingaadmin" { import "generic-user" display_name = "Icinga 2 Admin" groups = [ "icingaadmins" ] email = "icinga@localhost" } object UserGroup "icingaadmins" { display_name = "Icinga 2 Admin Group" } ``` #### notifications.conf Notifications for check alerts are an integral part or your Icinga 2 monitoring stack. The examples in this file define two notification apply rules for hosts and services. Both `apply` rules match on the same condition: They are only applied if the nested dictionary attribute `notification.mail` is set. Please note that the `to` keyword is important in [notification apply rules](03-monitoring-basics.md#using-apply-notifications) defining whether these notifications are applies to hosts or services. The `import` keyword imports the specific mail templates defined in [templates.conf](04-configuration.md#templates-conf). The `interval` attribute is not explicitly set -- it [defaults to 30 minutes](09-object-types.md#objecttype-notification). By setting the `user_groups` to the value provided by the respective [host.vars.notification.mail](04-configuration.md#hosts-conf) attribute we'll implicitely use the `icingaadmins` UserGroup defined in [users.conf](04-configuration.md#users-conf). ``` apply Notification "mail-icingaadmin" to Host { import "mail-host-notification" user_groups = host.vars.notification.mail.groups users = host.vars.notification.mail.users assign where host.vars.notification.mail } apply Notification "mail-icingaadmin" to Service { import "mail-service-notification" user_groups = host.vars.notification.mail.groups users = host.vars.notification.mail.users assign where host.vars.notification.mail } ``` More details on defining notifications and their additional attributes such as filters can be read in [this chapter](03-monitoring-basics.md#alert-notifications). #### commands.conf This is the place where your own command configuration can be defined. By default only the notification commands used by the notification templates defined in [templates.conf](04-configuration.md#templates-conf). You can freely customize these notification commands, and adapt them for your needs. Read more on that topic [here](03-monitoring-basics.md#notification-commands). #### groups.conf The example host defined in [hosts.conf](#hosts-conf) already has the custom variable `os` set to `Linux` and is therefore automatically a member of the host group `linux-servers`. This is done by using the [group assign](17-language-reference.md#group-assign) expressions similar to previously seen [apply rules](03-monitoring-basics.md#using-apply). ``` object HostGroup "linux-servers" { display_name = "Linux Servers" assign where host.vars.os == "Linux" } object HostGroup "windows-servers" { display_name = "Windows Servers" assign where host.vars.os == "Windows" } ``` Service groups can be grouped together by similar pattern matches. The [match function](18-library-reference.md#global-functions-match) expects a wildcard match string and the attribute string to match with. ``` object ServiceGroup "ping" { display_name = "Ping Checks" assign where match("ping*", service.name) } object ServiceGroup "http" { display_name = "HTTP Checks" assign where match("http*", service.check_command) } object ServiceGroup "disk" { display_name = "Disk Checks" assign where match("disk*", service.check_command) } ``` #### templates.conf Most of the example configuration objects use generic global templates by default: ``` template Host "generic-host" { max_check_attempts = 5 check_interval = 1m retry_interval = 30s check_command = "hostalive" } template Service "generic-service" { max_check_attempts = 3 check_interval = 1m retry_interval = 30s } ``` The `hostalive` check command is part of the [Plugin Check Commands](10-icinga-template-library.md#icinga-template-library). ``` template Notification "mail-host-notification" { command = "mail-host-notification" states = [ Up, Down ] types = [ Problem, Acknowledgement, Recovery, Custom, FlappingStart, FlappingEnd, DowntimeStart, DowntimeEnd, DowntimeRemoved ] period = "24x7" } template Notification "mail-service-notification" { command = "mail-service-notification" states = [ OK, Warning, Critical, Unknown ] types = [ Problem, Acknowledgement, Recovery, Custom, FlappingStart, FlappingEnd, DowntimeStart, DowntimeEnd, DowntimeRemoved ] period = "24x7" } ``` More details on `Notification` object attributes can be found [here](09-object-types.md#objecttype-notification). #### downtimes.conf The `load` service apply rule defined in [services.conf](04-configuration.md#services-conf) defines the `backup_downtime` custom variable. The ScheduledDowntime apply rule uses this attribute to define the default value for the time ranges required for recurring downtime slots. Learn more about downtimes in [this chapter](08-advanced-topics.md#downtimes). ``` apply ScheduledDowntime "backup-downtime" to Service { author = "icingaadmin" comment = "Scheduled downtime for backup" ranges = { monday = service.vars.backup_downtime tuesday = service.vars.backup_downtime wednesday = service.vars.backup_downtime thursday = service.vars.backup_downtime friday = service.vars.backup_downtime saturday = service.vars.backup_downtime sunday = service.vars.backup_downtime } assign where service.vars.backup_downtime != "" } ``` #### timeperiods.conf This file contains the default timeperiod definitions for `24x7`, `9to5` and `never`. TimePeriod objects are referenced by `*period` objects such as hosts, services or notifications. #### api-users.conf Provides the default [ApiUser](09-object-types.md#objecttype-apiuser) object named "root" for the [API authentication](12-icinga2-api.md#icinga2-api-authentication). #### app.conf Provides the default [IcingaApplication](09-object-types.md#objecttype-icingaapplication) object named "app" for additional settings such as disabling notifications globally, etc. icinga2-2.14.6/doc/05-service-monitoring.md000066400000000000000000001175761501332562400202760ustar00rootroot00000000000000# Service Monitoring The power of Icinga 2 lies in its modularity. There are thousands of community plugins available next to the standard plugins provided by the [Monitoring Plugins project](https://www.monitoring-plugins.org). Start your research on [Icinga Exchange](https://exchange.icinga.com) and look which services are already [covered](05-service-monitoring.md#service-monitoring-overview). The [requirements chapter](05-service-monitoring.md#service-monitoring-requirements) guides you through the plugin setup, tests and their integration with an [existing](05-service-monitoring.md#service-monitoring-plugin-checkcommand) or [new](05-service-monitoring.md#service-monitoring-plugin-checkcommand-new) CheckCommand object and host/service objects inside the [Director](05-service-monitoring.md#service-monitoring-plugin-checkcommand-integration-director) or [Icinga config files](05-service-monitoring.md#service-monitoring-plugin-checkcommand-integration-config-files). It also adds hints on [modifying](05-service-monitoring.md#service-monitoring-plugin-checkcommand-modify) existing commands. Plugins follow the [Plugin API specification](05-service-monitoring.md#service-monitoring-plugin-api) which is enriched with examples and also code examples to get you started with [your own plugin](05-service-monitoring.md#service-monitoring-plugin-new). ## Requirements ### Plugins All existing Icinga or Nagios plugins work with Icinga 2. Community plugins can be found for example on [Icinga Exchange](https://exchange.icinga.com). The recommended way of setting up these plugins is to copy them into the `PluginDir` directory. If you have plugins with many dependencies, consider creating a custom RPM/DEB package which handles the required libraries and binaries. Configuration management tools such as Puppet, Ansible, Chef or Saltstack also help with automatically installing the plugins on different operating systems. They can also help with installing the required dependencies, e.g. Python libraries, Perl modules, etc. ### Plugin Setup Good plugins provide installations and configuration instructions in their docs and/or README on GitHub. Sometimes dependencies are not listed, or your distribution differs from the one described. Try running the plugin after setup and [ensure it works](05-service-monitoring.md#service-monitoring-plugins-it-works). #### Ensure it works Prior to using the check plugin with Icinga 2 you should ensure that it is working properly by trying to run it on the console using whichever user Icinga 2 is running as: RHEL/Fedora ```bash sudo -u icinga /usr/lib64/nagios/plugins/check_mysql_health --help ``` Debian/Ubuntu ```bash sudo -u nagios /usr/lib/nagios/plugins/check_mysql_health --help ``` Additional libraries may be required for some plugins. Please consult the plugin documentation and/or the included README file for installation instructions. Sometimes plugins contain hard-coded paths to other components. Instead of changing the plugin it might be easier to create a symbolic link to make sure it doesn't get overwritten during the next update. Sometimes there are plugins which do not exactly fit your requirements. In that case you can modify an existing plugin or just write your own. #### Plugin Dependency Errors Plugins can be scripts (Shell, Python, Perl, Ruby, PHP, etc.) or compiled binaries (C, C++, Go). These scripts/binaries may require additional libraries which must be installed on every system they are executed. > **Tip** > > Don't test the plugins on your master instance, instead > do that on the satellites and clients which execute the > checks. There are errors, now what? Typical errors are missing libraries, binaries or packages. ##### Python Example Example for a Python plugin which uses the `tinkerforge` module to query a network service: ``` ImportError: No module named tinkerforge.ip_connection ``` Its [documentation](https://github.com/NETWAYS/check_tinkerforge#installation) points to installing the `tinkerforge` Python module. ##### Perl Example Example for a Perl plugin which uses SNMP: ``` Can't locate Net/SNMP.pm in @INC (you may need to install the Net::SNMP module) ``` Prior to installing the Perl module via CPAN, look for a distribution specific package, e.g. `libnet-snmp-perl` on Debian/Ubuntu or `perl-Net-SNMP` on RHEL. #### Optional: Custom Path If you are not using the default `PluginDir` directory, you can create a custom plugin directory and constant and reference this in the created CheckCommand objects. Create a common directory e.g. `/opt/monitoring/plugins` and install the plugin there. ```bash mkdir -p /opt/monitoring/plugins cp check_snmp_int.pl /opt/monitoring/plugins chmod +x /opt/monitoring/plugins/check_snmp_int.pl ``` Next create a new global constant, e.g. `CustomPluginDir` in your [constants.conf](04-configuration.md#constants-conf) configuration file: ``` vim /etc/icinga2/constants.conf const PluginDir = "/usr/lib/nagios/plugins" const CustomPluginDir = "/opt/monitoring/plugins" ``` ### CheckCommand Definition Each plugin requires a [CheckCommand](09-object-types.md#objecttype-checkcommand) object in your configuration which can be used in the [Service](09-object-types.md#objecttype-service) or [Host](09-object-types.md#objecttype-host) object definition. Please check if the Icinga 2 package already provides an [existing CheckCommand definition](10-icinga-template-library.md#icinga-template-library). If that's the case, thoroughly check the required parameters and integrate the check command into your host and service objects. Best practice is to run the plugin on the CLI with the required parameters first. Example for database size checks with [check_mysql_health](10-icinga-template-library.md#plugin-contrib-command-mysql_health). ```bash /usr/lib64/nagios/plugins/check_mysql_health --hostname '127.0.0.1' --username root --password icingar0xx --mode sql --name 'select sum(data_length + index_length) / 1024 / 1024 from information_schema.tables where table_schema = '\''icinga'\'';' '--name2' 'db_size' --units 'MB' --warning 4096 --critical 8192 ``` The parameter names inside the ITL commands follow the `_` schema. #### Icinga Director Integration Navigate into `Commands > External Commands` and search for `mysql_health`. Select `mysql_health` and navigate into the `Fields` tab. In order to access the parameters, the Director requires you to first define the needed custom data fields: * `mysql_health_hostname` * `mysql_health_username` and `mysql_health_password` * `mysql_health_mode` * `mysql_health_name`, `mysql_health_name2` and `mysql_health_units` * `mysql_health_warning` and `mysql_health_critical` Create a new host template and object where you'll generic settings like `mysql_health_hostname` (if it differs from the host's `address` attribute) and `mysql_health_username` and `mysql_health_password`. Create a new service template for `mysql-health` and set the `mysql_health` as check command. You can also define a default for `mysql_health_mode`. Next, create a service apply rule or a new service set which gets assigned to matching host objects. #### Icinga Config File Integration Create or modify a host object which stores the generic database defaults and prepares details for a service apply for rule. ``` object Host "icinga2-master1.localdomain" { check_command = "hostalive" address = "..." // Database listens locally, not external vars.mysql_health_hostname = "127.0.0.1" // Basic database size checks for Icinga DBs vars.databases["icinga"] = { mysql_health_warning = 4096 //MB mysql_health_critical = 8192 //MB } vars.databases["icingaweb2"] = { mysql_health_warning = 4096 //MB mysql_health_critical = 8192 //MB } } ``` The host object prepares the database details and thresholds already for advanced [apply for](03-monitoring-basics.md#using-apply-for) rules. It also uses conditions to fetch host specified values, or set default values. ``` apply Service "db-size-" for (db_name => config in host.vars.databases) { check_interval = 1m retry_interval = 30s check_command = "mysql_health" if (config.mysql_health_username) { vars.mysql_health_username = config.mysql_health_username } else { vars.mysql_health_username = "root" } if (config.mysql_health_password) { vars.mysql_health_password = config.mysql_health_password } else { vars.mysql_health_password = "icingar0xx" } vars.mysql_health_mode = "sql" vars.mysql_health_name = "select sum(data_length + index_length) / 1024 / 1024 from information_schema.tables where table_schema = '" + db_name + "';" vars.mysql_health_name2 = "db_size" vars.mysql_health_units = "MB" if (config.mysql_health_warning) { vars.mysql_health_warning = config.mysql_health_warning } if (config.mysql_health_critical) { vars.mysql_health_critical = config.mysql_health_critical } vars += config } ``` #### New CheckCommand This chapter describes how to add a new CheckCommand object for a plugin. Please make sure to follow these conventions when adding a new command object definition: * Use [command arguments](03-monitoring-basics.md#command-arguments) whenever possible. The `command` attribute must be an array in `[ ... ]` for shell escaping. * Define a unique `prefix` for the command's specific arguments. Best practice is to follow this schema: ``` _ ``` That way you can safely set them on host/service level and you'll always know which command they control. * Use command argument default values, e.g. for thresholds. * Use [advanced conditions](09-object-types.md#objecttype-checkcommand) like `set_if` definitions. Before starting with the CheckCommand definition, please check the existing objects available inside the ITL. They follow best practices and are maintained by developers and our community. This example picks a new plugin called [check_systemd](https://exchange.icinga.com/joseffriedrich/check_systemd) uploaded to Icinga Exchange in June 2019. First, [install](05-service-monitoring.md#service-monitoring-plugins-setup) the plugin and ensure that [it works](05-service-monitoring.md#service-monitoring-plugins-it-works). Then run it with the `--help` parameter to see the actual parameters (docs might be outdated). ``` ./check_systemd.py --help usage: check_systemd.py [-h] [-c SECONDS] [-e UNIT | -u UNIT] [-v] [-V] [-w SECONDS] ... optional arguments: -h, --help show this help message and exit -c SECONDS, --critical SECONDS Startup time in seconds to result in critical status. -e UNIT, --exclude UNIT Exclude a systemd unit from the checks. This option can be applied multiple times. For example: -e mnt- data.mount -e task.service. -u UNIT, --unit UNIT Name of the systemd unit that is beeing tested. -v, --verbose Increase output verbosity (use up to 3 times). -V, --version show program's version number and exit -w SECONDS, --warning SECONDS Startup time in seconds to result in warning status. ``` The argument description is important, based on this you need to create the command arguments. > **Tip** > > When you are using the Director, you can prepare the commands as files > e.g. inside the `global-templates` zone. Then run the kickstart wizard > again to import the commands as external reference. > > If you prefer to use the Director GUI/CLI, please apply the steps > in the `Add Command` form. Start with the basic plugin call without any parameters. ``` object CheckCommand "systemd" { // Plugin name without 'check_' prefix command = [ PluginContribDir + "/check_systemd.py" ] // Use the 'PluginContribDir' constant, see the contributed ITL commands } ``` Run a config validation to see if that works, `icinga2 daemon -C` Next, analyse the plugin parameters. Plugins with a good help output show optional parameters in square brackes. This is the case for all parameters for this plugin. If there are required parameters, use the `required` key inside the argument. The `arguments` attribute is a dictionary which takes the parameters as keys. ``` arguments = { "--unit" = { ... } } ``` If there a long parameter names available, prefer them. This increases readability in both the configuration as well as the executed command line. The argument value itself is a sub dictionary which has additional keys: * `value` which references the runtime macro string * `description` where you copy the plugin parameter help text into * `required`, `set_if`, etc. for advanced parameters, check the [CheckCommand object](09-object-types.md#objecttype-checkcommand) chapter. The runtime macro syntax is required to allow value extraction when the command is executed. > **Tip** > > Inside the Director, store the new command first in order to > unveil the `Arguments` tab. Best practice is to use the command name as prefix, in this specific case e.g. `systemd_unit`. ``` arguments = { "--unit" = { value = "$systemd_unit$" // The service parameter would then be defined as 'vars.systemd_unit = "icinga2"' description = "Name of the systemd unit that is beeing tested." } "--warning" = { value = "$systemd_warning$" description = "Startup time in seconds to result in warning status." } "--critical" = { value = "$systemd_critical$" description = "Startup time in seconds to result in critical status." } } ``` This may take a while -- validate the configuration in between up until the CheckCommand definition is done. Then test and integrate it into your monitoring configuration. Remember: Do it once and right, and never touch the CheckCommand again. Optional arguments allow different use cases and scenarios. Once you have created your really good CheckCommand, please consider sharing it with our community by creating a new PR on [GitHub](https://github.com/Icinga/icinga2/blob/master/CONTRIBUTING.md). _Please also update the documentation for the ITL._ > **Tip** > > Inside the Director, you can render the configuration in the Deployment > section. Extract the static configuration object and use that as a source > for sending it upstream. #### Modify Existing CheckCommand Sometimes an existing CheckCommand inside the ITL is missing a parameter. Or you don't need a default parameter value being set. Instead of copying the entire configuration object, you can import an object into another new object. ``` object CheckCommand "http-custom" { import "http" // Import existing http object arguments += { // Use additive assignment to add missing parameters "--key" = { value = "$http_..." // Keep the parameter name the same as with http } } // Override default parameters vars.http_address = "..." } ``` This CheckCommand can then be referenced in your host/service object definitions. ### Plugin API Icinga 2 supports the native plugin API specification from the Monitoring Plugins project. It is defined in the [Monitoring Plugins](https://www.monitoring-plugins.org) guidelines. The Icinga documentation revamps the specification into our own guideline enriched with examples and best practices. #### Output The output should be as short and as detailed as possible. The most common cases include: - Viewing a problem list in Icinga Web and dashboards - Getting paged about a problem - Receiving the alert on the CLI or forwarding it to external (ticket) systems Examples: ``` : OK: MySQL connection time is fine (0.0002s) WARNING: MySQL connection time is slow (0.5s > 0.1s threshold) CRITICAL: MySQL connection time is causing degraded performance (3s > 0.5s threshold) ``` Icinga supports reading multi-line output where Icinga Web only shows the first line in the listings and everything in the detail view. Example for an end2end check with many smaller test cases integrated: ``` OK: Online banking works. Testcase 1: Site reached. Testcase 2: Attempted login, JS loads. Testcase 3: Login succeeded. Testcase 4: View current state works. Testcase 5: Transactions fine. ``` If the extended output shouldn't be visible in your monitoring, but only for testing, it is recommended to implement the `--verbose` plugin parameter to allow developers and users to debug further. Check [here](05-service-monitoring.md#service-monitoring-plugin-api-verbose) for more implementation tips. > **Tip** > > More debug output also helps when implementing your plugin. > > Best practice is to have the plugin parameter and handling implemented first, > then add it anywhere you want to see more, e.g. from initial database connections > to actual query results. #### Status Value | Status | Description ------|-----------|------------------------------- 0 | OK | The check went fine and everything is considered working. 1 | Warning | The check is above the given warning threshold, or anything else is suspicious requiring attention before it breaks. 2 | Critical | The check exceeded the critical threshold, or something really is broken and will harm the production environment. 3 | Unknown | Invalid parameters, low level resource errors (IO device busy, no fork resources, TCP sockets, etc.) preventing the actual check. Higher level errors such as DNS resolving, TCP connection timeouts should be treated as `Critical` instead. Whenever the plugin reaches its timeout (best practice) it should also terminate with `Unknown`. Keep in mind that these are service states. Icinga automatically maps the [host state](03-monitoring-basics.md#check-result-state-mapping) from the returned plugin states. #### Thresholds A plugin calculates specific values and may decide about the exit state on its own. This is done with thresholds - warning and critical values which are compared with the actual value. Upon this logic, the exit state is determined. Imagine the following value and defined thresholds: ``` ptc_value = 57.8 warning = 50 critical = 60 ``` Whenever `ptc_value` is higher than warning or critical, it should return the appropriate [state](05-service-monitoring.md#service-monitoring-plugin-api-status). The threshold evaluation order also is important: * Critical thresholds are evaluated first and superseed everything else. * Warning thresholds are evaluated second * If no threshold is matched, return the OK state Avoid using hardcoded threshold values in your plugins, always add them to the argument parser. Example for Python: ```python import argparse import signal import sys if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("-w", "--warning", help="Warning threshold. Single value or range, e.g. '20:50'.") parser.add_argument("-c", "--critical", help="Critical threshold. Single vluae or range, e.g. '25:45'.") args = parser.parse_args() ``` Users might call plugins only with the critical threshold parameter, leaving out the warning parameter. Keep this in mind when evaluating the thresholds, always check if the parameters have been defined before. ```python if args.critical: if ptc_value > args.critical: print("CRITICAL - ...") sys.exit(2) # Critical if args.warning: if ptc_value > args.warning: print("WARNING - ...") sys.exit(1) # Warning print("OK - ...") sys.exit(0) # OK ``` The above is a simplified example for printing the [output](05-service-monitoring.md#service-monitoring-plugin-api-output) and using the [state](05-service-monitoring.md#service-monitoring-plugin-api-status) as exit code. Before diving into the implementation, learn more about required [performance data metrics](05-service-monitoring.md#service-monitoring-plugin-api-performance-data-metrics) and more best practices below. ##### Threshold Ranges Threshold ranges can be used to specify an alert window, e.g. whenever a calculated value is between a lower and higher critical threshold. The schema for threshold ranges looks as follows. The `@` character in square brackets is optional. ``` [@]start:end ``` There are a few requirements for ranges: * `start <= end`. Add a check in your code and let the user know about problematic values. ``` 10:20 # OK 30:10 # Error ``` * `start:` can be omitted if its value is 0. This is the default handling for single threshold values too. ``` 10 # Every value > 10 and < 0, outside of 0..10 ``` * If `end` is omitted, assume end is infinity. ``` 10: # < 10, outside of 10..∞ ``` * In order to specify negative infinity, use the `~` character. ``` ~:10 # > 10, outside of -∞..10 ``` * Raise alert if value is outside of the defined range. ``` 10:20 # < 10 or > 20, outside of 10..20 ``` * Start with `@` to raise an alert if the value is **inside** the defined range, inclusive start/end values. ``` @10:20 # >= 10 and <= 20, inside of 10..20 ``` Best practice is to either implement single threshold values, or fully support ranges. This requires parsing the input parameter values, therefore look for existing libraries already providing this functionality. [check_tinkerforge](https://github.com/NETWAYS/check_tinkerforge/blob/master/check_tinkerforge.py) implements a simple parser to avoid dependencies. #### Performance Data Metrics Performance data metrics must be appended to the plugin output with a preceding `|` character. The schema is as follows: ``` | 'label'=value[UOM];[warn];[crit];[min];[max] ``` The label should be encapsulated with single quotes. Avoid spaces or special characters such as `%` in there, this could lead to problems with metric receivers such as Graphite. Labels must not include `'` and `=` characters. Keep the label length as short and unique as possible. Example: ``` 'load1'=4.7 ``` Values must respect the C/POSIX locale and not implement e.g. German locale for floating point numbers with `,`. Icinga sets `LC_NUMERIC=C` to enforce this locale on plugin execution. ##### Unit of Measurement (UOM) ``` 'rta'=12.445000ms 'pl'=0% ``` The UoMs are written as-is into the [core backends](14-features.md#core-backends) (IDO, API). I.e. 12.445000ms remain 12.445000ms. In contrast, the [metric backends](14-features.md#metrics) (Graphite, InfluxDB, etc.) get perfdata (including warn, crit, min, max) normalized by Icinga. E.g. 12.445000ms become 0.012445 seconds. Some plugins change the UoM for different sizing, e.g. returning the disk usage in MB and later GB for the same performance data label. This is to ensure that graphs always look the same. [Icinga DB](14-features.md#core-backends-icingadb) gets both the as-is and the normalized perfdata. What metric backends get... | ... from which perfdata UoMs (case-insensitive if possible) ----------------------------|--------------------------------------- bytes (B) | B, KB, MB, ..., YB, KiB, MiB, ..., YiB bits (b) | b, kb, mb, ..., yb, kib, mib, ..., yib packets | packets seconds (s) | ns, us, ms, s, m, h, d percent | % amperes (A) | nA, uA, mA, A, kA, MA, GA, ..., YA ohms (O) | nO, uO, mO, O, kO, MO, GO, ..., YO volts (V) | nV, uV, mV, V, kV, MV, GV, ..., YV watts (W) | nW, uW, mW, W, kW, MW, GW, ..., YW ampere seconds (As) | nAs, uAs, mAs, As, kAs, MAs, GAs, ..., YAs ampere seconds | nAm, uAm, mAm, Am (ampere minutes), kAm, MAm, GAm, ..., YAm ampere seconds | nAh, uAh, mAh, Ah (ampere hours), kAh, MAh, GAh, ..., YAh watt hours | nWs, uWs, mWs, Ws (watt seconds), kWs, MWs, GWs, ..., YWs watt hours | nWm, uWm, mWm, Wm (watt minutes), kWm, MWm, GWm, ..., YWm watt hours (Wh) | nWh, uWh, mWh, Wh, kWh, MWh, GWh, ..., YWh lumens | lm decibel-milliwatts | dBm grams (g) | ng, ug, mg, g, kg, t degrees Celsius | C degrees Fahrenheit | F degrees Kelvin | K liters (l) | ml, l, hl The UoM "c" represents a continuous counter (e.g. interface traffic counters). Unknown UoMs are discarted (as if none was given). A value without any UoM may be an integer or floating point number for any type (processes, users, etc.). ##### Thresholds and Min/Max Next to the performance data value, warn, crit, min, max can optionally be provided. They must be separated with the semi-colon `;` character. They share the same UOM with the performance data value. ``` $ check_ping -4 -H icinga.com -c '200,15%' -w '100,5%' PING OK - Packet loss = 0%, RTA = 12.44 ms|rta=12.445000ms;100.000000;200.000000;0.000000 pl=0%;5;15;0 ``` ##### Multiple Performance Data Values Multiple performance data values must be joined with a space character. The below example is from the [check_load](10-icinga-template-library.md#plugin-check-command-load) plugin. ``` load1=4.680;1.000;2.000;0; load5=0.000;5.000;10.000;0; load15=0.000;10.000;20.000;0; ``` #### Timeout Icinga has a safety mechanism where it kills processes running for too long. The timeout can be specified in [CheckCommand objects](09-object-types.md#objecttype-checkcommand) or on the host/service object. Best practice is to control the timeout in the plugin itself and provide a clear message followed by the Unknown state. Example in Python taken from [check_tinkerforge](https://github.com/NETWAYS/check_tinkerforge/blob/master/check_tinkerforge.py): ```python import argparse import signal import sys def handle_sigalrm(signum, frame, timeout=None): output('Plugin timed out after %d seconds' % timeout, 3) if __name__ == '__main__': parser = argparse.ArgumentParser() # ... add more arguments parser.add_argument("-t", "--timeout", help="Timeout in seconds (default 10s)", type=int, default=10) args = parser.parse_args() signal.signal(signal.SIGALRM, partial(handle_sigalrm, timeout=args.timeout)) signal.alarm(args.timeout) # ... perform the check and generate output/status ``` #### Versions Plugins should provide a version via `-V` or `--version` parameter which is bumped on releases. This allows to identify problems with too old or new versions on the community support channels. Example in Python taken from [check_tinkerforge](https://github.com/NETWAYS/check_tinkerforge/blob/master/check_tinkerforge.py): ```python import argparse import signal import sys __version__ = '0.9.1' if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-V', '--version', action='version', version='%(prog)s v' + sys.modules[__name__].__version__) ``` #### Verbose Plugins should provide a verbose mode with `-v` or `--verbose` in order to show more detailed log messages. This helps to debug and analyse the flow and execution steps inside the plugin. Ensure to add the parameter prior to implementing the check logic into the plugin. Example in Python taken from [check_tinkerforge](https://github.com/NETWAYS/check_tinkerforge/blob/master/check_tinkerforge.py): ```python import argparse import signal import sys if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-v', '--verbose', action='store_true') if args.verbose: print("Verbose debug output") ``` ### Create a new Plugin Sometimes an existing plugin does not satisfy your requirements. You can either kindly contact the original author about plans to add changes and/or create a patch. If you just want to format the output and state of an existing plugin it might also be helpful to write a wrapper script. This script could pass all configured parameters, call the plugin script, parse its output/exit code and return your specified output/exit code. On the other hand plugins for specific services and hardware might not yet exist. > **Tip** > > Watch this presentation from Icinga Camp Berlin to learn more > about [How to write checks that don't suck](https://www.youtube.com/watch?v=Ey_APqSCoFQ). Common best practices: * Choose the programming language wisely * Scripting languages (Bash, Python, Perl, Ruby, PHP, etc.) are easier to write and setup but their check execution might take longer (invoking the script interpreter as overhead, etc.). * Plugins written in C/C++, Go, etc. improve check execution time but may generate an overhead with installation and packaging. * Use a modern VCS such as Git for developing the plugin, e.g. share your plugin on GitHub and let it sync to [Icinga Exchange](https://exchange.icinga.com). * **Look into existing plugins endorsed by community members.** Implementation hints: * Add parameters with key-value pairs to your plugin. They should allow long names (e.g. `--host localhost`) and also short parameters (e.g. `-H localhost`) * `-h|--help` should print the version and all details about parameters and runtime invocation. Note: Python's ArgParse class provides this OOTB. * `--version` should print the plugin [version](05-service-monitoring.md#service-monitoring-plugin-api-versions). * Add a [verbose/debug output](05-service-monitoring.md#service-monitoring-plugin-api-verbose) functionality for detailed on-demand logging. * Respect the exit codes required by the [Plugin API](05-service-monitoring.md#service-monitoring-plugin-api). * Always add [performance data](05-service-monitoring.md#service-monitoring-plugin-api-performance-data-metrics) to your plugin output. * Allow to specify [warning/critical thresholds](05-service-monitoring.md#service-monitoring-plugin-api-thresholds) as parameters. Example skeleton: ``` # 1. include optional libraries # 2. global variables # 3. helper functions and/or classes # 4. define timeout condition if () then print "UNKNOWN - Timeout (...) reached | 'time'=30.0 endif # 5. main method if () then print "CRITICAL - ... | 'time'=0.1 'myperfdatavalue'=5.0 exit(2) else if () then print "WARNING - ... | 'time'=0.1 'myperfdatavalue'=3.0 exit(1) else print "OK - ... | 'time'=0.2 'myperfdatavalue'=1.0 endif ``` There are various plugin libraries available which will help with plugin execution and output formatting too, for example [nagiosplugin from Python](https://pypi.python.org/pypi/nagiosplugin/). > **Note** > > Ensure to test your plugin properly with special cases before putting it > into production! Once you've finished your plugin please upload/sync it to [Icinga Exchange](https://exchange.icinga.com/new). Thanks in advance! ## Service Monitoring Overview The following examples should help you to start implementing your own ideas. There is a variety of plugins available. This collection is not complete -- if you have any updates, please send a documentation patch upstream. Please visit our [community forum](https://community.icinga.com) which may provide an answer to your use case already. If not, do not hesitate to create a new topic. ### General Monitoring If the remote service is available (via a network protocol and port), and if a check plugin is also available, you don't necessarily need a local client. Instead, choose a plugin and configure its parameters and thresholds. The following examples are included in the [Icinga 2 Template Library](10-icinga-template-library.md#icinga-template-library): * [ping4](10-icinga-template-library.md#plugin-check-command-ping4), [ping6](10-icinga-template-library.md#plugin-check-command-ping6), [fping4](10-icinga-template-library.md#plugin-check-command-fping4), [fping6](10-icinga-template-library.md#plugin-check-command-fping6), [hostalive](10-icinga-template-library.md#plugin-check-command-hostalive) * [tcp](10-icinga-template-library.md#plugin-check-command-tcp), [udp](10-icinga-template-library.md#plugin-check-command-udp), [ssl](10-icinga-template-library.md#plugin-check-command-ssl) * [ntp_time](10-icinga-template-library.md#plugin-check-command-ntp-time) ### Linux Monitoring * [disk](10-icinga-template-library.md#plugin-check-command-disk) * [mem](10-icinga-template-library.md#plugin-contrib-command-mem), [swap](10-icinga-template-library.md#plugin-check-command-swap) * [procs](10-icinga-template-library.md#plugin-check-command-processes) * [users](10-icinga-template-library.md#plugin-check-command-users) * [running_kernel](10-icinga-template-library.md#plugin-contrib-command-running_kernel) * package management: [apt](10-icinga-template-library.md#plugin-check-command-apt), [yum](10-icinga-template-library.md#plugin-contrib-command-yum), etc. * [ssh](10-icinga-template-library.md#plugin-check-command-ssh) * performance: [iostat](10-icinga-template-library.md#plugin-contrib-command-iostat), [check_sar_perf](https://github.com/NETWAYS/check-sar-perf) ### Windows Monitoring !!! important [Icinga for Windows](https://icinga.com/docs/icinga-for-windows/latest/doc/000-Introduction/) is the recommended way to monitor Windows via Icinga 2. Even if the plugins it ships out-of-the-box don't already cover your needs, you can [create your own](https://icinga.com/docs/icinga-for-windows/latest/doc/900-Developer-Guide/11-Custom-Plugins/). Other (legacy) solutions include: * [check_wmi_plus](https://edcint.co.nz/checkwmiplus/) * [NSClient++](https://www.nsclient.org) (in combination with the Icinga 2 client and either [check_nscp_api](10-icinga-template-library.md#nscp-check-api) or [nscp-local](10-icinga-template-library.md#nscp-plugin-check-commands) check commands) * [Icinga 2 Windows Plugins](10-icinga-template-library.md#windows-plugins) (disk, load, memory, network, performance counters, ping, procs, service, swap, updates, uptime, users * vbs and Powershell scripts ### Database Monitoring * MySQL/MariaDB: [mysql_health](10-icinga-template-library.md#plugin-contrib-command-mysql_health), [mysql](10-icinga-template-library.md#plugin-check-command-mysql), [mysql_query](10-icinga-template-library.md#plugin-check-command-mysql-query) * PostgreSQL: [postgres](10-icinga-template-library.md#plugin-contrib-command-postgres) * Oracle: [oracle_health](10-icinga-template-library.md#plugin-contrib-command-oracle_health) * MSSQL: [mssql_health](10-icinga-template-library.md#plugin-contrib-command-mssql_health) * DB2: [db2_health](10-icinga-template-library.md#plugin-contrib-command-db2_health) * MongoDB: [mongodb](10-icinga-template-library.md#plugin-contrib-command-mongodb) * Elasticsearch: [elasticsearch](10-icinga-template-library.md#plugin-contrib-command-elasticsearch) * Redis: [redis](10-icinga-template-library.md#plugin-contrib-command-redis) ### SNMP Monitoring * [Manubulon plugins](10-icinga-template-library.md#snmp-manubulon-plugin-check-commands) (interface, storage, load, memory, process) * [snmp](10-icinga-template-library.md#plugin-check-command-snmp), [snmpv3](10-icinga-template-library.md#plugin-check-command-snmpv3) ### Network Monitoring * [nwc_health](10-icinga-template-library.md#plugin-contrib-command-nwc_health) * [interfaces](10-icinga-template-library.md#plugin-contrib-command-interfaces) * [interfacetable](10-icinga-template-library.md#plugin-contrib-command-interfacetable) * [iftraffic](10-icinga-template-library.md#plugin-contrib-command-iftraffic), [iftraffic64](10-icinga-template-library.md#plugin-contrib-command-iftraffic64) ### Web Monitoring * [http](10-icinga-template-library.md#plugin-check-command-http) * [ftp](10-icinga-template-library.md#plugin-check-command-ftp) * [webinject](10-icinga-template-library.md#plugin-contrib-command-webinject) * [squid](10-icinga-template-library.md#plugin-contrib-command-squid) * [apache-status](10-icinga-template-library.md#plugin-contrib-command-apache-status) * [nginx_status](10-icinga-template-library.md#plugin-contrib-command-nginx_status) * [kdc](10-icinga-template-library.md#plugin-contrib-command-kdc) * [rbl](10-icinga-template-library.md#plugin-contrib-command-rbl) * [Icinga Certificate Monitoring](https://icinga.com/products/icinga-certificate-monitoring/) ### Java Monitoring * [jmx4perl](10-icinga-template-library.md#plugin-contrib-command-jmx4perl) ### DNS Monitoring * [dns](10-icinga-template-library.md#plugin-check-command-dns) * [dig](10-icinga-template-library.md#plugin-check-command-dig) * [dhcp](10-icinga-template-library.md#plugin-check-command-dhcp) ### Backup Monitoring * [check_bareos](https://github.com/widhalmt/check_bareos) ### Log Monitoring * [check_logfiles](https://labs.consol.de/nagios/check_logfiles/) * [check_logstash](https://github.com/NETWAYS/check_logstash) * [check_graylog2_stream](https://github.com/Graylog2/check-graylog2-stream) ### Virtualization Monitoring ### VMware Monitoring * [Icinga Module for vSphere](https://icinga.com/products/icinga-module-for-vsphere/) * [esxi_hardware](10-icinga-template-library.md#plugin-contrib-command-esxi-hardware) * [VMware](10-icinga-template-library.md#plugin-contrib-vmware) **Tip**: If you are encountering timeouts using the VMware Perl SDK, check [this blog entry](https://www.claudiokuenzler.com/blog/650/slow-vmware-perl-sdk-soap-request-error-libwww-version). Ubuntu 16.04 LTS can have troubles with random entropy in Perl asked [here](https://monitoring-portal.org/t/check-vmware-api-slow-when-run-multiple-times/2868). In that case, [haveged](https://issihosts.com/haveged/) may help. ### SAP Monitoring * [check_sap_health](https://labs.consol.de/nagios/check_sap_health/index.html) * [SAP CCMS](https://sourceforge.net/projects/nagios-sap-ccms/) ### Mail Monitoring * [smtp](10-icinga-template-library.md#plugin-check-command-smtp), [ssmtp](10-icinga-template-library.md#plugin-check-command-ssmtp) * [imap](10-icinga-template-library.md#plugin-check-command-imap), [simap](10-icinga-template-library.md#plugin-check-command-simap) * [pop](10-icinga-template-library.md#plugin-check-command-pop), [spop](10-icinga-template-library.md#plugin-check-command-spop) * [mailq](10-icinga-template-library.md#plugin-check-command-mailq) ### Hardware Monitoring * [hpasm](10-icinga-template-library.md#plugin-contrib-command-hpasm) * [ipmi-sensor](10-icinga-template-library.md#plugin-contrib-command-ipmi-sensor) ### Metrics Monitoring * [graphite](10-icinga-template-library.md#plugin-contrib-command-graphite) icinga2-2.14.6/doc/06-distributed-monitoring.md000066400000000000000000004316021501332562400211460ustar00rootroot00000000000000# Distributed Monitoring with Master, Satellites and Agents This chapter will guide you through the setup of a distributed monitoring environment, including high-availability clustering and setup details for Icinga masters, satellites and agents. ## Roles: Master, Satellites and Agents Icinga 2 nodes can be given names for easier understanding: * A `master` node which is on top of the hierarchy. * A `satellite` node which is a child of a `satellite` or `master` node. * An `agent` node which is connected to `master` and/or `satellite` nodes. ![Icinga 2 Distributed Roles](images/distributed-monitoring/icinga2_distributed_monitoring_roles.png) Rephrasing this picture into more details: * A `master` node has no parent node. * A `master`node is where you usually install Icinga Web 2. * A `master` node can combine executed checks from child nodes into backends and notifications. * A `satellite` node has a parent and a child node. * A `satellite` node may execute checks on its own or delegate check execution to child nodes. * A `satellite` node can receive configuration for hosts/services, etc. from the parent node. * A `satellite` node continues to run even if the master node is temporarily unavailable. * An `agent` node only has a parent node. * An `agent` node will either run its own configured checks or receive command execution events from the parent node. A client can be a secondary master, a satellite or an agent. It typically requests something from the primary master or parent node. The following sections will refer to these roles and explain the differences and the possibilities this kind of setup offers. > **Note** > > Previous versions of this documentation used the term `Icinga client`. > This has been refined into `Icinga agent` and is visible in the docs, > backends and web interfaces. **Tip**: If you just want to install a single master node that monitors several hosts (i.e. Icinga agents), continue reading -- we'll start with simple examples. In case you are planning a huge cluster setup with multiple levels and lots of satellites and agents, read on -- we'll deal with these cases later on. The installation on each system is the same: Follow the [installation instructions](02-installation.md) for the Icinga 2 package and the required check plugins. The required configuration steps are mostly happening on the command line. You can also [automate the setup](06-distributed-monitoring.md#distributed-monitoring-automation). The first thing you need learn about a distributed setup is the hierarchy of the single components. ## Zones The Icinga 2 hierarchy consists of so-called [zone](09-object-types.md#objecttype-zone) objects. Zones depend on a parent-child relationship in order to trust each other. ![Icinga 2 Distributed Zones](images/distributed-monitoring/icinga2_distributed_monitoring_zones.png) Have a look at this example for the `satellite` zones which have the `master` zone as a parent zone: ``` object Zone "master" { //... } object Zone "satellite region 1" { parent = "master" //... } object Zone "satellite region 2" { parent = "master" //... } ``` There are certain limitations for child zones, e.g. their members are not allowed to send configuration commands to the parent zone members. Vice versa, the trust hierarchy allows for example the `master` zone to send configuration files to the `satellite` zone. Read more about this in the [security section](06-distributed-monitoring.md#distributed-monitoring-security). `agent` nodes also have their own unique zone. By convention you must use the FQDN for the zone name. ## Endpoints Nodes which are a member of a zone are so-called [Endpoint](09-object-types.md#objecttype-endpoint) objects. ![Icinga 2 Distributed Endpoints](images/distributed-monitoring/icinga2_distributed_monitoring_endpoints.png) Here is an example configuration for two endpoints in different zones: ``` object Endpoint "icinga2-master1.localdomain" { host = "192.168.56.101" } object Endpoint "icinga2-satellite1.localdomain" { host = "192.168.56.105" } object Zone "master" { endpoints = [ "icinga2-master1.localdomain" ] } object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain" ] parent = "master" } ``` All endpoints in the same zone work as high-availability setup. For example, if you have two nodes in the `master` zone, they will load-balance the check execution. Endpoint objects are important for specifying the connection information, e.g. if the master should actively try to connect to an agent. The zone membership is defined inside the `Zone` object definition using the `endpoints` attribute with an array of `Endpoint` names. > **Note** > > There is a known [problem](https://github.com/Icinga/icinga2/issues/3533) > with >2 endpoints in a zone and a message routing loop. > The config validation will log a warning to let you know about this too. If you want to check the availability (e.g. ping checks) of the node you still need a [Host](09-object-types.md#objecttype-host) object. ## ApiListener In case you are using the CLI commands later, you don't have to write this configuration from scratch in a text editor. The [ApiListener](09-object-types.md#objecttype-apilistener) object is used to load the TLS certificates and specify restrictions, e.g. for accepting configuration commands. It is also used for the [Icinga 2 REST API](12-icinga2-api.md#icinga2-api) which shares the same host and port with the Icinga 2 Cluster protocol. The object configuration is stored in the `/etc/icinga2/features-enabled/api.conf` file. Depending on the configuration mode the attributes `accept_commands` and `accept_config` can be configured here. In order to use the `api` feature you need to enable it and restart Icinga 2. ```bash icinga2 feature enable api ``` ## Conventions By convention all nodes should be configured using their FQDN. Furthermore, you must ensure that the following names are exactly the same in all configuration files: * Host certificate common name (CN). * Endpoint configuration object for the host. * NodeName constant for the local host. Setting this up on the command line will help you to minimize the effort. Just keep in mind that you need to use the FQDN for endpoints and for common names when asked. ## Security While there are certain mechanisms to ensure a secure communication between all nodes (firewalls, policies, software hardening, etc.), Icinga 2 also provides additional security: * TLS v1.2+ is required. * TLS cipher lists are hardened [by default](09-object-types.md#objecttype-apilistener). * TLS certificates are mandatory for communication between nodes. The CLI command wizards help you create these certificates. * Child zones only receive updates (check results, commands, etc.) for their configured objects. * Child zones are not allowed to push configuration updates to parent zones. * Zones cannot interfere with other zones and influence each other. Each checkable host or service object is assigned to **one zone** only. * All nodes in a zone trust each other. * [Config sync](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync) and [remote command endpoint execution](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) is disabled by default. The underlying protocol uses JSON-RPC event notifications exchanged by nodes. The connection is secured by TLS. The message protocol uses an internal API, and as such message types and names may change internally and are not documented. Zones build the trust relationship in a distributed environment. If you do not specify a zone for an agent/satellite and specify the parent zone, its zone members e.g. the master instance won't trust the agent/satellite. Building this trust is key in your distributed environment. That way the parent node knows that it is able to send messages to the child zone, e.g. configuration objects, configuration in global zones, commands to be executed in this zone/for this endpoint. It also receives check results from the child zone for checkable objects (host/service). Vice versa, the agent/satellite trusts the master and accepts configuration and commands if enabled in the api feature. If the agent/satellite would send configuration to the parent zone, the parent nodes will deny it. The parent zone is the configuration entity, and does not trust agents/satellites in this matter. An agent/satellite could attempt to modify a different agent/satellite for example, or inject a check command with malicious code. While it may sound complicated for agent/satellite setups, it removes the problem with different roles and configurations for a master and child nodes. Both of them work the same way, are configured in the same way (Zone, Endpoint, ApiListener), and you can troubleshoot and debug them in just one go. ## Versions and Upgrade It generally is advised to use the newest releases with the same version on all instances. Prior to upgrading, make sure to plan a maintenance window. The Icinga project aims to allow the following compatibility: ``` master (2.11) >= satellite (2.10) >= agent (2.9) ``` Older agent versions may work, but there's no guarantee. Always keep in mind that older versions are out of support and can contain bugs. In terms of an upgrade, ensure that the master is upgraded first, then involved satellites, and last the Icinga agents. If you are on v2.10 currently, first upgrade the master instance(s) to 2.11, and then proceed with the satellites. Things are getting easier with any sort of automation tool (Puppet, Ansible, etc.). Releases and new features may require you to upgrade master/satellite instances at once, this is highlighted in the [upgrading docs](16-upgrading-icinga-2.md#upgrading-icinga-2) if needed. One example is the CA Proxy and on-demand signing feature available since v2.8 where all involved instances need this version to function properly. ## Master Setup This section explains how to install a central single master node using the `node wizard` command. If you prefer to do an automated installation, please refer to the [automated setup](06-distributed-monitoring.md#distributed-monitoring-automation) section. Follow the [installation instructions](02-installation.md) for the Icinga 2 package and the required check plugins if you haven't done so already. **Note**: Windows is not supported for a master node setup. The next step is to run the `node wizard` CLI command. Prior to that ensure to collect the required information: Parameter | Description --------------------|-------------------- Common name (CN) | **Required.** By convention this should be the host's FQDN. Defaults to the FQDN. Master zone name | **Optional.** Allows to specify the master zone name. Defaults to `master`. Global zones | **Optional.** Allows to specify more global zones in addition to `global-templates` and `director-global`. Defaults to `n`. API bind host | **Optional.** Allows to specify the address the ApiListener is bound to. For advanced usage only. API bind port | **Optional.** Allows to specify the port the ApiListener is bound to. For advanced usage only (requires changing the default port 5665 everywhere). Disable conf.d | **Optional.** Allows to disable the `include_recursive "conf.d"` directive except for the `api-users.conf` file in the `icinga2.conf` file. Defaults to `y`. Configuration on the master is discussed below. The setup wizard will ensure that the following steps are taken: * Enable the `api` feature. * Generate a new certificate authority (CA) in `/var/lib/icinga2/ca` if it doesn't exist. * Create a certificate for this node signed by the CA key. * Update the [zones.conf](04-configuration.md#zones-conf) file with the new zone hierarchy. * Update the [ApiListener](06-distributed-monitoring.md#distributed-monitoring-apilistener) and [constants](04-configuration.md#constants-conf) configuration. * Update the [icinga2.conf](04-configuration.md#icinga2-conf) to disable the `conf.d` inclusion, and add the `api-users.conf` file inclusion. Here is an example of a master setup for the `icinga2-master1.localdomain` node: ``` [root@icinga2-master1.localdomain /]# icinga2 node wizard Welcome to the Icinga 2 Setup Wizard! We will guide you through all required configuration details. Please specify if this is a satellite/agent setup ('n' installs a master setup) [Y/n]: n Starting the Master setup routine... Please specify the common name (CN) [icinga2-master1.localdomain]: icinga2-master1.localdomain Reconfiguring Icinga... Checking for existing certificates for common name 'icinga2-master1.localdomain'... Certificates not yet generated. Running 'api setup' now. Generating master configuration for Icinga 2. Enabling feature api. Make sure to restart Icinga 2 for these changes to take effect. Master zone name [master]: Default global zones: global-templates director-global Do you want to specify additional global zones? [y/N]: N Please specify the API bind host/port (optional): Bind Host []: Bind Port []: Do you want to disable the inclusion of the conf.d directory [Y/n]: Disabling the inclusion of the conf.d directory... Checking if the api-users.conf file exists... Done. Now restart your Icinga 2 daemon to finish the installation! ``` You can verify that the CA public and private keys are stored in the `/var/lib/icinga2/ca` directory. Keep this path secure and include it in your backups. In case you lose the CA private key you have to generate a new CA for signing new agent/satellite certificate requests. You then have to also re-create new signed certificates for all existing nodes. Once the master setup is complete, you can also use this node as primary [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing) master. The following section will explain how to use the CLI commands in order to fetch their signed certificate from this master node. ## Signing Certificates on the Master All certificates must be signed by the same certificate authority (CA). This ensures that all nodes trust each other in a distributed monitoring environment. This CA is generated during the [master setup](06-distributed-monitoring.md#distributed-monitoring-setup-master) and should be the same on all master instances. You can avoid signing and deploying certificates [manually](06-distributed-monitoring.md#distributed-monitoring-advanced-hints-certificates-manual) by using built-in methods for auto-signing certificate signing requests (CSR): * [CSR Auto-Signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing) which uses a client (an agent or a satellite) ticket generated on the master as trust identifier. * [On-Demand CSR Signing](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing) which allows to sign pending certificate requests on the master. Both methods are described in detail below. > **Note** > > [On-Demand CSR Signing](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing) is available in Icinga 2 v2.8+. ### CSR Auto-Signing A client can be a secondary master, a satellite or an agent. It sends a certificate signing request (CSR) and must authenticate itself in a trusted way. The master generates a client ticket which is included in this request. That way the master can verify that the request matches the previously trusted ticket and sign the request. > **Note** > > Icinga 2 v2.8 added the possibility to forward signing requests on a satellite > to the master node. This is called `CA Proxy` in blog posts and design drafts. > This functionality helps with the setup of [three level clusters](06-distributed-monitoring.md#distributed-monitoring-scenarios-master-satellite-agents) > and more. Advantages: * Nodes (secondary master, satellites, agents) can be installed by different users who have received the client ticket. * No manual interaction necessary on the master node. * Automation tools like Puppet, Ansible, etc. can retrieve the pre-generated ticket in their client catalog and run the node setup directly. Disadvantages: * Tickets need to be generated on the master and copied to client setup wizards. * No central signing management. #### CSR Auto-Signing: Preparation Prior to using this mode, ensure that the following steps are taken on the signing master: * The [master setup](06-distributed-monitoring.md#distributed-monitoring-setup-master) was run successfully. This includes: * Generated a CA key pair * Generated a private ticket salt stored in the `TicketSalt` constant, set as `ticket_salt` attribute inside the [api](09-object-types.md#objecttype-apilistener) feature. * Restart of the master instance. #### CSR Auto-Signing: On the master Setup wizards for agent/satellite nodes will ask you for this specific client ticket. There are two possible ways to retrieve the ticket: * [CLI command](11-cli-commands.md#cli-command-pki) executed on the master node. * [REST API](12-icinga2-api.md#icinga2-api) request against the master node. Required information: Parameter | Description --------------------|-------------------- Common name (CN) | **Required.** The common name for the agent/satellite. By convention this should be the FQDN. The following example shows how to generate a ticket on the master node `icinga2-master1.localdomain` for the agent `icinga2-agent1.localdomain`: ``` [root@icinga2-master1.localdomain /]# icinga2 pki ticket --cn icinga2-agent1.localdomain ``` Querying the [Icinga 2 API](12-icinga2-api.md#icinga2-api) on the master requires an [ApiUser](12-icinga2-api.md#icinga2-api-authentication) object with at least the `actions/generate-ticket` permission. ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/conf.d/api-users.conf object ApiUser "client-pki-ticket" { password = "bea11beb7b810ea9ce6ea" //change this permissions = [ "actions/generate-ticket" ] } [root@icinga2-master1.localdomain /]# systemctl restart icinga2 Retrieve the ticket on the master node `icinga2-master1.localdomain` with `curl`, for example: [root@icinga2-master1.localdomain /]# curl -k -s -u client-pki-ticket:bea11beb7b810ea9ce6ea -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/generate-ticket' -d '{ "cn": "icinga2-agent1.localdomain" }' ``` Store that ticket number for the [agent/satellite setup](06-distributed-monitoring.md#distributed-monitoring-setup-agent-satellite) below. > **Note** > > Never expose the ticket salt and/or ApiUser credentials to your client nodes. > Example: Retrieve the ticket on the Puppet master node and send the compiled catalog > to the authorized Puppet agent node which will invoke the > [automated setup steps](06-distributed-monitoring.md#distributed-monitoring-automation-cli-node-setup). ### On-Demand CSR Signing The client can be a secondary master, satellite or agent. It sends a certificate signing request to specified parent node without any ticket. The admin on the primary master is responsible for reviewing and signing the requests with the private CA key. This could either be directly the master, or a satellite which forwards the request to the signing master. Advantages: * Central certificate request signing management. * No pre-generated ticket is required for client setups. Disadvantages: * Asynchronous step for automated deployments. * Needs client verification on the master. #### On-Demand CSR Signing: Preparation Prior to using this mode, ensure that the following steps are taken on the signing master: * The [master setup](06-distributed-monitoring.md#distributed-monitoring-setup-master) was run successfully. This includes: * Generated a CA key pair * Restart of the master instance. #### On-Demand CSR Signing: On the master You can list pending certificate signing requests with the `ca list` CLI command. ``` [root@icinga2-master1.localdomain /]# icinga2 ca list Fingerprint | Timestamp | Signed | Subject -----------------------------------------------------------------|---------------------|--------|-------- 71700c28445109416dd7102038962ac3fd421fbb349a6e7303b6033ec1772850 | 2017/09/06 17:20:02 | | CN = icinga2-agent2.localdomain ``` In order to show all requests, use the `--all` parameter. ``` [root@icinga2-master1.localdomain /]# icinga2 ca list --all Fingerprint | Timestamp | Signed | Subject -----------------------------------------------------------------|---------------------|--------|-------- 403da5b228df384f07f980f45ba50202529cded7c8182abf96740660caa09727 | 2017/09/06 17:02:40 | * | CN = icinga2-agent1.localdomain 71700c28445109416dd7102038962ac3fd421fbb349a6e7303b6033ec1772850 | 2017/09/06 17:20:02 | | CN = icinga2-agent2.localdomain ``` **Tip**: Add `--json` to the CLI command to retrieve the details in JSON format. If you want to sign a specific request, you need to use the `ca sign` CLI command and pass its fingerprint as argument. ``` [root@icinga2-master1.localdomain /]# icinga2 ca sign 71700c28445109416dd7102038962ac3fd421fbb349a6e7303b6033ec1772850 information/cli: Signed certificate for 'CN = icinga2-agent2.localdomain'. ``` > **Note** > > `ca list` cannot be used as historical inventory. Certificate > signing requests older than 1 week are automatically deleted. You can also remove an undesired CSR using the `ca remove` command using the syntax as the `ca sign` command. ``` [root@pym ~]# icinga2 ca remove 5c31ca0e2269c10363a97e40e3f2b2cd56493f9194d5b1852541b835970da46e information/cli: Certificate 5c31ca0e2269c10363a97e40e3f2b2cd56493f9194d5b1852541b835970da46e removed. ``` If you want to restore a certificate you have removed, you can use `ca restore`. ## Agent/Satellite Setup This section describes the setup of an agent or satellite connected to an existing master node setup. If you haven't done so already, please [run the master setup](06-distributed-monitoring.md#distributed-monitoring-setup-master). Icinga 2 on the master node must be running and accepting connections on port `5665`. ### Agent/Satellite Setup on Linux Please ensure that you've run all the steps mentioned in the [agent/satellite section](06-distributed-monitoring.md#distributed-monitoring-setup-agent-satellite). Follow the [installation instructions](02-installation.md) for the Icinga 2 package and the required check plugins if you haven't done so already. The next step is to run the `node wizard` CLI command. In this example we're generating a ticket on the master node `icinga2-master1.localdomain` for the agent `icinga2-agent1.localdomain`: ``` [root@icinga2-master1.localdomain /]# icinga2 pki ticket --cn icinga2-agent1.localdomain 4f75d2ecd253575fe9180938ebff7cbca262f96e ``` Note: You don't need this step if you have chosen to use [On-Demand CSR Signing](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing). Start the wizard on the agent `icinga2-agent1.localdomain`: ``` [root@icinga2-agent1.localdomain /]# icinga2 node wizard Welcome to the Icinga 2 Setup Wizard! We will guide you through all required configuration details. ``` Press `Enter` or add `y` to start a satellite or agent setup. ``` Please specify if this is an agent/satellite setup ('n' installs a master setup) [Y/n]: ``` Press `Enter` to use the proposed name in brackets, or add a specific common name (CN). By convention this should be the FQDN. ``` Starting the Agent/Satellite setup routine... Please specify the common name (CN) [icinga2-agent1.localdomain]: icinga2-agent1.localdomain ``` Specify the direct parent for this node. This could be your primary master `icinga2-master1.localdomain` or a satellite node in a multi level cluster scenario. ``` Please specify the parent endpoint(s) (master or satellite) where this node should connect to: Master/Satellite Common Name (CN from your master/satellite node): icinga2-master1.localdomain ``` Press `Enter` or choose `y` to establish a connection to the parent node. ``` Do you want to establish a connection to the parent node from this node? [Y/n]: ``` > **Note:** > > If this node cannot connect to the parent node, choose `n`. The setup > wizard will provide instructions for this scenario -- signing questions are disabled then. Add the connection details for `icinga2-master1.localdomain`. ``` Please specify the master/satellite connection information: Master/Satellite endpoint host (IP address or FQDN): 192.168.56.101 Master/Satellite endpoint port [5665]: 5665 ``` You can add more parent nodes if necessary. Press `Enter` or choose `n` if you don't want to add any. This comes in handy if you have more than one parent node, e.g. two masters or two satellites. ``` Add more master/satellite endpoints? [y/N]: ``` Verify the parent node's certificate: ``` Parent certificate information: Subject: CN = icinga2-master1.localdomain Issuer: CN = Icinga CA Valid From: Sep 7 13:41:24 2017 GMT Valid Until: Sep 3 13:41:24 2032 GMT Fingerprint: AC 99 8B 2B 3D B0 01 00 E5 21 FA 05 2E EC D5 A9 EF 9E AA E3 Is this information correct? [y/N]: y ``` The setup wizard fetches the parent node's certificate and ask you to verify this information. This is to prevent MITM attacks or any kind of untrusted parent relationship. You can verify the fingerprint by running the following command on the node to connect to: ```bash openssl x509 -noout -fingerprint -sha256 -in \ "/var/lib/icinga2/certs/$(hostname --fqdn).crt" ``` Note: The certificate is not fetched if you have chosen not to connect to the parent node. Proceed with adding the optional client ticket for [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing): ``` Please specify the request ticket generated on your Icinga 2 master (optional). (Hint: # icinga2 pki ticket --cn 'icinga2-agent1.localdomain'): 4f75d2ecd253575fe9180938ebff7cbca262f96e ``` In case you've chosen to use [On-Demand CSR Signing](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing) you can leave the ticket question blank. Instead, Icinga 2 tells you to approve the request later on the master node. ``` No ticket was specified. Please approve the certificate signing request manually on the master (see 'icinga2 ca list' and 'icinga2 ca sign --help' for details). ``` You can optionally specify a different bind host and/or port. ``` Please specify the API bind host/port (optional): Bind Host []: Bind Port []: ``` The next step asks you to accept configuration (required for [config sync mode](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync)) and commands (required for [command endpoint mode](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint)). ``` Accept config from parent node? [y/N]: y Accept commands from parent node? [y/N]: y ``` Next you can optionally specify the local and parent zone names. This will be reflected in the generated zone configuration file. Set the local zone name to something else, if you are installing a satellite or secondary master instance. ``` Local zone name [icinga2-agent1.localdomain]: ``` Set the parent zone name to something else than `master` if this agents connects to a satellite instance instead of the master. ``` Parent zone name [master]: ``` You can add more global zones in addition to `global-templates` and `director-global` if necessary. Press `Enter` or choose `n`, if you don't want to add any additional. ``` Reconfiguring Icinga... Default global zones: global-templates director-global Do you want to specify additional global zones? [y/N]: N ``` Last but not least the wizard asks you whether you want to disable the inclusion of the local configuration directory in `conf.d`, or not. Defaults to disabled, as agents either are checked via command endpoint, or they receive configuration synced from the parent zone. ``` Do you want to disable the inclusion of the conf.d directory [Y/n]: Y Disabling the inclusion of the conf.d directory... ``` The wizard proceeds and you are good to go. ``` Done. Now restart your Icinga 2 daemon to finish the installation! ``` > **Note** > > If you have chosen not to connect to the parent node, you cannot start > Icinga 2 yet. The wizard asked you to manually copy the master's public > CA certificate file into `/var/lib/icinga2/certs/ca.crt`. > > You need to [manually sign the CSR on the master node](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing-master). Restart Icinga 2 as requested. ``` [root@icinga2-agent1.localdomain /]# systemctl restart icinga2 ``` Here is an overview of all parameters in detail: Parameter | Description --------------------|-------------------- Common name (CN) | **Required.** By convention this should be the host's FQDN. Defaults to the FQDN. Master common name | **Required.** Use the common name you've specified for your master node before. Establish connection to the parent node | **Optional.** Whether the node should attempt to connect to the parent node or not. Defaults to `y`. Master/Satellite endpoint host | **Required if the the agent needs to connect to the master/satellite.** The parent endpoint's IP address or FQDN. This information is included in the `Endpoint` object configuration in the `zones.conf` file. Master/Satellite endpoint port | **Optional if the the agent needs to connect to the master/satellite.** The parent endpoints's listening port. This information is included in the `Endpoint` object configuration. Add more master/satellite endpoints | **Optional.** If you have multiple master/satellite nodes configured, add them here. Parent Certificate information | **Required.** Verify that the connecting host really is the requested master node. Request ticket | **Optional.** Add the [ticket](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing) generated on the master. API bind host | **Optional.** Allows to specify the address the ApiListener is bound to. For advanced usage only. API bind port | **Optional.** Allows to specify the port the ApiListener is bound to. For advanced usage only (requires changing the default port 5665 everywhere). Accept config | **Optional.** Whether this node accepts configuration sync from the master node (required for [config sync mode](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync)). For [security reasons](06-distributed-monitoring.md#distributed-monitoring-security) this defaults to `n`. Accept commands | **Optional.** Whether this node accepts command execution messages from the master node (required for [command endpoint mode](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint)). For [security reasons](06-distributed-monitoring.md#distributed-monitoring-security) this defaults to `n`. Local zone name | **Optional.** Allows to specify the name for the local zone. This comes in handy when this instance is a satellite, not an agent. Defaults to the FQDN. Parent zone name | **Optional.** Allows to specify the name for the parent zone. This is important if the agent has a satellite instance as parent, not the master. Defaults to `master`. Global zones | **Optional.** Allows to specify more global zones in addition to `global-templates` and `director-global`. Defaults to `n`. Disable conf.d | **Optional.** Allows to disable the inclusion of the `conf.d` directory which holds local example configuration. Clients should retrieve their configuration from the parent node, or act as command endpoint execution bridge. Defaults to `y`. The setup wizard will ensure that the following steps are taken: * Enable the `api` feature. * Create a certificate signing request (CSR) for the local node. * Request a signed certificate (optional with the provided ticket number) on the master node. * Allow to verify the parent node's certificate. * Store the signed agent/satellite certificate and ca.crt in `/var/lib/icinga2/certs`. * Update the `zones.conf` file with the new zone hierarchy. * Update `/etc/icinga2/features-enabled/api.conf` (`accept_config`, `accept_commands`) and `constants.conf`. * Update `/etc/icinga2/icinga2.conf` and comment out `include_recursive "conf.d"`. You can verify that the certificate files are stored in the `/var/lib/icinga2/certs` directory. > **Note** > > If the agent is not directly connected to the certificate signing master, > signing requests and responses might need some minutes to fully update the agent certificates. > > If you have chosen to use [On-Demand CSR Signing](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing) > certificates need to be signed on the master first. Ticket-less setups require at least Icinga 2 v2.8+ on all involved instances. Now that you've successfully installed a Linux/Unix agent/satellite instance, please proceed to the [configuration modes](06-distributed-monitoring.md#distributed-monitoring-configuration-modes). ### Agent Setup on Windows !!! important [Icinga for Windows](https://icinga.com/docs/icinga-for-windows/latest/doc/000-Introduction/) is the recommended way to install, setup and update Icinga 2 on Windows. This section describes the classic installation and configuration procedure. The supported Windows agent versions are listed [here](https://icinga.com/subscription/support-details/). Requirements: * [Microsoft .NET Framework 4.6](https://www.microsoft.com/en-US/download/details.aspx?id=53344) or higher. This is the default on Windows Server 2016 or later. * [Universal C Runtime for Windows](https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows) for Windows Server 2012 and older. #### Agent Setup on Windows: Installer Download the MSI-Installer package from [https://packages.icinga.com/windows/](https://packages.icinga.com/windows/). The preferred flavor is `x86_64` for modern Windows systems. The Windows package provides native [monitoring plugin binaries](06-distributed-monitoring.md#distributed-monitoring-windows-plugins) to get you started more easily. > **Note** > > Please note that Icinga 2 was designed to run as light-weight agent on Windows. > There is no support for satellite instances. Run the MSI-Installer package and follow the instructions shown in the screenshots. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_installer_01.png) ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_installer_02.png) ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_installer_03.png) ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_installer_04.png) ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_installer_05.png) The graphical installer offers to run the [Icinga Agent setup wizard](06-distributed-monitoring.md#distributed-monitoring-setup-agent-windows-configuration-wizard) after the installation. Select the check box to proceed. > **Tip** > > You can also run the Icinga agent setup wizard from the Start menu later. #### Agent Setup on Windows: Configuration Wizard On a fresh installation the setup wizard guides you through the initial configuration. It also provides a mechanism to send a certificate request to the [CSR signing master](06-distributed-monitoring.md#distributed-monitoring-setup-sign-certificates-master). The following configuration details are required: Parameter | Description --------------------|-------------------- Instance name | **Required.** By convention this should be the host's FQDN. Defaults to the FQDN. Setup ticket | **Optional.** Paste the previously generated [ticket number](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing). If left blank, the certificate request must be [signed on the master node](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing). Fill in the required information and click `Add` to add a new master connection. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_01.png) Add the following details: Parameter | Description -------------------------------|------------------------------- Instance name | **Required.** The master/satellite endpoint name where this agent is a direct child of. Master/Satellite endpoint host | **Required.** The master or satellite's IP address or FQDN. This information is included in the `Endpoint` object configuration in the `zones.conf` file. Master/Satellite endpoint port | **Optional.** The master or satellite's listening port. This information is included in the `Endpoint` object configuration. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_02.png) When needed you can add an additional global zone (the zones `global-templates` and `director-global` are added by default): ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_02_global_zone.png) Optionally enable the following settings: Parameter | Description --------------------------------------------------------|---------------------------------- Accept commands from master/satellite instance(s) | **Optional.** Whether this node accepts command execution messages from the master node (required for [command endpoint mode](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint)). For [security reasons](06-distributed-monitoring.md#distributed-monitoring-security) this is disabled by default. Accept config updates from master/satellite instance(s) | **Optional.** Whether this node accepts configuration sync from the master node (required for [config sync mode](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync)). For [security reasons](06-distributed-monitoring.md#distributed-monitoring-security) this is disabled by default. Run Icinga 2 service as this user | **Optional.** Specify a different Windows user. This defaults to `NT AUTHORITY\Network Service` and is required for more privileged service checks. Disable including local 'conf.d' directory | **Optional.** Allows to disable the `include_recursive "conf.d"` directive except for the `api-users.conf` file in the `icinga2.conf` file. Defaults to `true`. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_03.png) Verify the certificate from the master/satellite instance where this node should connect to. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_04.png) #### Finish Windows Agent Setup Finish the Windows setup wizard. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_06_finish_with_ticket.png) If you did not provide a setup ticket, you need to sign the certificate request on the master. The setup wizards tells you to do so. The Icinga 2 service is running at this point already and will automatically receive and update a signed client certificate. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_06_finish_no_ticket.png) Icinga 2 is automatically started as a Windows service. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_running_service.png) The Icinga 2 configuration is stored inside the `C:\ProgramData\icinga2` directory. Click `Examine Config` in the setup wizard to open a new Explorer window. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_examine_config.png) The configuration files can be modified with your favorite editor e.g. Notepad++ or vim in Powershell (via chocolatey). In order to use the [top down](06-distributed-monitoring.md#distributed-monitoring-top-down) agent configuration prepare the following steps. You don't need any local configuration on the agent except for CheckCommand definitions which can be synced using the global zone above. Therefore disable the inclusion of the `conf.d` directory in the `icinga2.conf` file. Navigate to `C:\ProgramData\icinga2\etc\icinga2` and open the `icinga2.conf` file in your preferred editor. Remove or comment (`//`) the following line: ``` // Commented out, not required on an agent with top down mode //include_recursive "conf.d" ``` > **Note** > > Packages >= 2.9 provide an option in the setup wizard to disable this. > Defaults to disabled. Validate the configuration on Windows open an administrative Powershell and run the following command: ``` C:\> cd C:\Program Files\ICINGA2\sbin C:\Program Files\ICINGA2\sbin> .\icinga2.exe daemon -C ``` **Note**: You have to run this command in a shell with `administrator` privileges. Now you need to restart the Icinga 2 service. Run `services.msc` from the start menu and restart the `icinga2` service. Alternatively open an administrative Powershell and run the following commands: ``` C:\> Restart-Service icinga2 C:\> Get-Service icinga2 ``` Now that you've successfully installed a Windows agent, please proceed to the [detailed configuration modes](06-distributed-monitoring.md#distributed-monitoring-configuration-modes). ## Configuration Modes There are different ways to ensure that the Icinga 2 cluster nodes execute checks, send notifications, etc. The preferred method is to configure monitoring objects on the master and distribute the configuration to satellites and agents. The following chapters explain this in detail with hands-on manual configuration examples. You should test and implement this once to fully understand how it works. Once you are familiar with Icinga 2 and distributed monitoring, you can start with additional integrations to manage and deploy your configuration: * [Icinga Director](https://icinga.com/docs/director/latest/) provides a web interface to manage configuration and also allows to sync imported resources (CMDB, PuppetDB, etc.) * [Ansible Roles](https://icinga.com/products/integrations/) * [Puppet Module](https://icinga.com/products/integrations/puppet/) * [Chef Cookbook](https://icinga.com/products/integrations/chef/) More details can be found [here](13-addons.md#configuration-tools). ### Top Down There are two different behaviors with check execution: * Send a command execution event remotely: The scheduler still runs on the parent node. * Sync the host/service objects directly to the child node: Checks are executed locally. Again, technically it does not matter whether this is an `agent` or a `satellite` which is receiving configuration or command execution events. ### Top Down Command Endpoint This mode forces the Icinga 2 node to execute commands remotely on a specified endpoint. The host/service object configuration is located on the master/satellite and the agent only needs the CheckCommand object definitions available. Every endpoint has its own remote check queue. The amount of checks executed simultaneously can be limited on the endpoint with the `MaxConcurrentChecks` constant defined in [constants.conf](04-configuration.md#constants-conf). Icinga 2 may discard check requests, if the remote check queue is full. ![Icinga 2 Distributed Top Down Command Endpoint](images/distributed-monitoring/icinga2_distributed_monitoring_agent_checks_command_endpoint.png) Advantages: * No local checks need to be defined on the child node (agent). * Light-weight remote check execution (asynchronous events). * No [replay log](06-distributed-monitoring.md#distributed-monitoring-advanced-hints-command-endpoint-log-duration) is necessary for the child node. * Pin checks to specific endpoints (if the child zone consists of 2 endpoints). Disadvantages: * If the child node is not connected, no more checks are executed. * Requires additional configuration attribute specified in host/service objects. * Requires local `CheckCommand` object configuration. Best practice is to use a [global config zone](06-distributed-monitoring.md#distributed-monitoring-global-zone-config-sync). To make sure that all nodes involved will accept configuration and/or commands, you need to configure the `Zone` and `Endpoint` hierarchy on all nodes. * `icinga2-master1.localdomain` is the configuration master in this scenario. * `icinga2-agent1.localdomain` acts as agent which receives command execution messages via command endpoint from the master. In addition, it receives the global check command configuration from the master. Include the endpoint and zone configuration on **both** nodes in the file `/etc/icinga2/zones.conf`. The endpoint configuration could look like this, for example: ``` [root@icinga2-agent1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { host = "192.168.56.101" } object Endpoint "icinga2-agent1.localdomain" { host = "192.168.56.111" log_duration = 0 // Disable the replay log for command endpoint agents } ``` Next, you need to define two zones. There is no naming convention, best practice is to either use `master`, `satellite`/`agent-fqdn` or to choose region names for example `Europe`, `USA` and `Asia`, though. **Note**: Each agent requires its own zone and endpoint configuration. Best practice is to use the agent's FQDN for all object names. The `master` zone is a parent of the `icinga2-agent1.localdomain` zone: ``` [root@icinga2-agent1.localdomain /]# vim /etc/icinga2/zones.conf object Zone "master" { endpoints = [ "icinga2-master1.localdomain" ] //array with endpoint names } object Zone "icinga2-agent1.localdomain" { endpoints = [ "icinga2-agent1.localdomain" ] parent = "master" //establish zone hierarchy } ``` You don't need any local configuration on the agent except for CheckCommand definitions which can be synced using the global zone above. Therefore disable the inclusion of the `conf.d` directory in `/etc/icinga2/icinga2.conf`. ``` [root@icinga2-agent1.localdomain /]# vim /etc/icinga2/icinga2.conf // Commented out, not required on an agent as command endpoint //include_recursive "conf.d" ``` > **Note** > > Packages >= 2.9 provide an option in the setup wizard to disable this. > Defaults to disabled. Now it is time to validate the configuration and to restart the Icinga 2 daemon on both nodes: ``` [root@icinga2-agent1.localdomain /]# icinga2 daemon -C [root@icinga2-agent1.localdomain /]# systemctl restart icinga2 [root@icinga2-master1.localdomain /]# icinga2 daemon -C [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` Once the agents have successfully connected, you are ready for the next step: **execute a remote check on the agent using the command endpoint**. Include the host and service object configuration in the `master` zone -- this will help adding a secondary master for high-availability later. ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/master ``` Add the host and service objects you want to monitor. There is no limitation for files and directories -- best practice is to sort things by type. By convention a master/satellite/agent host object should use the same name as the endpoint object. You can also add multiple hosts which execute checks against remote services/agents. The following example adds the `agent_endpoint` custom variable to the host and stores its name (FQDN). _Versions older than 2.11 used the `client_endpoint` custom variable._ This custom variable serves two purposes: 1) Service apply rules can match against it. 2) Apply rules can retrieve its value and assign it to the `command_endpoint` attribute. ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim hosts.conf object Host "icinga2-agent1.localdomain" { check_command = "hostalive" //check is executed on the master address = "192.168.56.111" vars.agent_endpoint = name //follows the convention that host name == endpoint name } ``` Given that you are monitoring a Linux agent, add a remote [disk](10-icinga-template-library.md#plugin-check-command-disk) check. ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim services.conf apply Service "disk" { check_command = "disk" // Specify the remote agent as command execution endpoint, fetch the host custom variable command_endpoint = host.vars.agent_endpoint // Only assign where a host is marked as agent endpoint assign where host.vars.agent_endpoint } ``` If you have your own custom `CheckCommand` definition, add it to the global zone: ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/global-templates [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/global-templates/commands.conf object CheckCommand "my-cmd" { //... } ``` Save the changes and validate the configuration on the master node: ``` [root@icinga2-master1.localdomain /]# icinga2 daemon -C ``` Restart the Icinga 2 daemon: ``` [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` The following steps will happen: * Icinga 2 validates the configuration on `icinga2-master1.localdomain` and restarts. * The `icinga2-master1.localdomain` node schedules and executes the checks. * The `icinga2-agent1.localdomain` node receives the execute command event with additional command parameters. * The `icinga2-agent1.localdomain` node maps the command parameters to the local check command, executes the check locally, and sends back the check result message. As you can see, no interaction from your side is required on the agent itself, and it's not necessary to reload the Icinga 2 service on the agent. You have learned the basics about command endpoint checks. Proceed with the [scenarios](06-distributed-monitoring.md#distributed-monitoring-scenarios) section where you can find detailed information on extending the setup. ### Top Down Config Sync This mode syncs the object configuration files within specified zones. It comes in handy if you want to configure everything on the master node and sync the satellite checks (disk, memory, etc.). The satellites run their own local scheduler and will send the check result messages back to the master. ![Icinga 2 Distributed Top Down Config Sync](images/distributed-monitoring/icinga2_distributed_monitoring_satellite_config_sync.png) Advantages: * Sync the configuration files from the parent zone to the child zones. * No manual restart is required on the child nodes, as syncing, validation, and restarts happen automatically. * Execute checks directly on the child node's scheduler. * Replay log if the connection drops (important for keeping the check history in sync, e.g. for SLA reports). * Use a global zone for syncing templates, groups, etc. Disadvantages: * Requires a config directory on the master node with the zone name underneath `/etc/icinga2/zones.d`. * Additional zone and endpoint configuration needed. * Replay log is replicated on reconnect after connection loss. This might increase the data transfer and create an overload on the connection. > **Note** > > This mode only supports **configuration text files** for Icinga. Do not abuse > this for syncing binaries, this is not supported and may harm your production > environment. The config sync uses checksums to detect changes, binaries may > trigger reload loops. > > This is a fair warning. If you want to deploy plugin binaries, create > packages for dependency management and use infrastructure lifecycle tools > such as Foreman, Puppet, Ansible, etc. To make sure that all involved nodes accept configuration and/or commands, you need to configure the `Zone` and `Endpoint` hierarchy on all nodes. * `icinga2-master1.localdomain` is the configuration master in this scenario. * `icinga2-satellite1.localdomain` acts as satellite which receives configuration from the master. Checks are scheduled locally. Include the endpoint and zone configuration on **both** nodes in the file `/etc/icinga2/zones.conf`. The endpoint configuration could look like this: ``` [root@icinga2-satellite1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { host = "192.168.56.101" } object Endpoint "icinga2-satellite1.localdomain" { host = "192.168.56.105" } ``` Next, you need to define two zones. There is no naming convention, best practice is to either use `master`, `satellite`/`agent-fqdn` or to choose region names for example `Europe`, `USA` and `Asia`, though. The `master` zone is a parent of the `satellite` zone: ``` [root@icinga2-agent2.localdomain /]# vim /etc/icinga2/zones.conf object Zone "master" { endpoints = [ "icinga2-master1.localdomain" ] //array with endpoint names } object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain" ] parent = "master" //establish zone hierarchy } ``` Edit the `api` feature on the satellite `icinga2-satellite1.localdomain` in the `/etc/icinga2/features-enabled/api.conf` file and set `accept_config` to `true`. ``` [root@icinga2-satellite1.localdomain /]# vim /etc/icinga2/features-enabled/api.conf object ApiListener "api" { //... accept_config = true } ``` Now it is time to validate the configuration and to restart the Icinga 2 daemon on both nodes: ``` [root@icinga2-satellite1.localdomain /]# icinga2 daemon -C [root@icinga2-satellite1.localdomain /]# systemctl restart icinga2 [root@icinga2-master1.localdomain /]# icinga2 daemon -C [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` **Tip**: Best practice is to use a [global zone](06-distributed-monitoring.md#distributed-monitoring-global-zone-config-sync) for common configuration items (check commands, templates, groups, etc.). Once the satellite(s) have connected successfully, it's time for the next step: **execute a local check on the satellite using the configuration sync**. Navigate to `/etc/icinga2/zones.d` on your master node `icinga2-master1.localdomain` and create a new directory with the same name as your satellite/agent zone name: ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/satellite ``` Add the host and service objects you want to monitor. There is no limitation for files and directories -- best practice is to sort things by type. By convention a master/satellite/agent host object should use the same name as the endpoint object. You can also add multiple hosts which execute checks against remote services/agents via [command endpoint](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) checks. ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/satellite [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim hosts.conf object Host "icinga2-satellite1.localdomain" { check_command = "hostalive" address = "192.168.56.112" zone = "master" //optional trick: sync the required host object to the satellite, but enforce the "master" zone to execute the check } ``` Given that you are monitoring a Linux satellite add a local [disk](10-icinga-template-library.md#plugin-check-command-disk) check. ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim services.conf object Service "disk" { host_name = "icinga2-satellite1.localdomain" check_command = "disk" } ``` Save the changes and validate the configuration on the master node: ``` [root@icinga2-master1.localdomain /]# icinga2 daemon -C ``` Restart the Icinga 2 daemon: ``` [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` The following steps will happen: * Icinga 2 validates the configuration on `icinga2-master1.localdomain`. * Icinga 2 copies the configuration into its zone config store in `/var/lib/icinga2/api/zones`. * The `icinga2-master1.localdomain` node sends a config update event to all endpoints in the same or direct child zones. * The `icinga2-satellite1.localdomain` node accepts config and populates the local zone config store with the received config files. * The `icinga2-satellite1.localdomain` node validates the configuration and automatically restarts. Again, there is no interaction required on the satellite itself. You can also use the config sync inside a high-availability zone to ensure that all config objects are synced among zone members. **Note**: You can only have one so-called "config master" in a zone which stores the configuration in the `zones.d` directory. Multiple nodes with configuration files in the `zones.d` directory are **not supported**. Now that you've learned the basics about the configuration sync, proceed with the [scenarios](06-distributed-monitoring.md#distributed-monitoring-scenarios) section where you can find detailed information on extending the setup. If you are eager to start fresh instead you might take a look into the [Icinga Director](https://icinga.com/docs/director/latest/). ## Scenarios The following examples should give you an idea on how to build your own distributed monitoring environment. We've seen them all in production environments and received feedback from our [community](https://community.icinga.com/) and [partner support](https://icinga.com/support/) channels: * [Single master with agents](06-distributed-monitoring.md#distributed-monitoring-master-agents). * [HA master with agents as command endpoint](06-distributed-monitoring.md#distributed-monitoring-scenarios-ha-master-agents) * [Three level cluster](06-distributed-monitoring.md#distributed-monitoring-scenarios-master-satellite-agents) with config HA masters, satellites receiving config sync, and agents checked using command endpoint. You can also extend the cluster tree depth to four levels e.g. with 2 satellite levels. Just keep in mind that multiple levels become harder to debug in case of errors. You can also start with a single master setup, and later add a secondary master endpoint. This requires an extra step with the [initial sync](06-distributed-monitoring.md#distributed-monitoring-advanced-hints-initial-sync) for cloning the runtime state. This is described in detail [here](06-distributed-monitoring.md#distributed-monitoring-scenarios-ha-master-agents). ### Master with Agents In this scenario, a single master node runs the check scheduler, notifications and IDO database backend and uses the [command endpoint mode](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) to execute checks on the remote agents. ![Icinga 2 Distributed Master with Agents](images/distributed-monitoring/icinga2_distributed_monitoring_scenarios_master_with_agents.png) * `icinga2-master1.localdomain` is the primary master node. * `icinga2-agent1.localdomain` and `icinga2-agent2.localdomain` are two child nodes as agents. Setup requirements: * Set up `icinga2-master1.localdomain` as [master](06-distributed-monitoring.md#distributed-monitoring-setup-master). * Set up `icinga2-agent1.localdomain` and `icinga2-agent2.localdomain` as [agent](06-distributed-monitoring.md#distributed-monitoring-setup-agent-satellite). Edit the `zones.conf` configuration file on the master: ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // That's us } object Endpoint "icinga2-agent1.localdomain" { host = "192.168.56.111" // The master actively tries to connect to the agent log_duration = 0 // Disable the replay log for command endpoint agents } object Endpoint "icinga2-agent2.localdomain" { host = "192.168.56.112" // The master actively tries to connect to the agent log_duration = 0 // Disable the replay log for command endpoint agents } object Zone "master" { endpoints = [ "icinga2-master1.localdomain" ] } object Zone "icinga2-agent1.localdomain" { endpoints = [ "icinga2-agent1.localdomain" ] parent = "master" } object Zone "icinga2-agent2.localdomain" { endpoints = [ "icinga2-agent2.localdomain" ] parent = "master" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` The two agent nodes do not need to know about each other. The only important thing is that they know about the parent zone and their endpoint members (and optionally the global zone). If you specify the `host` attribute in the `icinga2-master1.localdomain` endpoint object, the agent will actively try to connect to the master node. Since you've specified the agent endpoint's attribute on the master node already, you don't want the agents to connect to the master. **Choose one [connection direction](06-distributed-monitoring.md#distributed-monitoring-advanced-hints-connection-direction).** ``` [root@icinga2-agent1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute } object Endpoint "icinga2-agent1.localdomain" { // That's us } object Zone "master" { endpoints = [ "icinga2-master1.localdomain" ] } object Zone "icinga2-agent1.localdomain" { endpoints = [ "icinga2-agent1.localdomain" ] parent = "master" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` ``` [root@icinga2-agent2.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute } object Endpoint "icinga2-agent2.localdomain" { // That's us } object Zone "master" { endpoints = [ "icinga2-master1.localdomain" ] } object Zone "icinga2-agent2.localdomain" { endpoints = [ "icinga2-agent2.localdomain" ] parent = "master" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` Now it is time to define the two agent hosts and apply service checks using the command endpoint execution method on them. Note: You can also use the config sync mode here. Create a new configuration directory on the master node: ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/master ``` Add the two agent nodes as host objects: ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim hosts.conf object Host "icinga2-agent1.localdomain" { check_command = "hostalive" address = "192.168.56.111" vars.agent_endpoint = name //follows the convention that host name == endpoint name } object Host "icinga2-agent2.localdomain" { check_command = "hostalive" address = "192.168.56.112" vars.agent_endpoint = name //follows the convention that host name == endpoint name } ``` Add services using command endpoint checks: ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim services.conf apply Service "ping4" { check_command = "ping4" //check is executed on the master node assign where host.address } apply Service "disk" { check_command = "disk" // Execute the check on the remote command endpoint command_endpoint = host.vars.agent_endpoint // Assign the service onto an agent assign where host.vars.agent_endpoint } ``` Validate the configuration and restart Icinga 2 on the master node `icinga2-master1.localdomain`. ``` [root@icinga2-master1.localdomain /]# icinga2 daemon -C [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` Open Icinga Web 2 and check the two newly created agent hosts with two new services -- one executed locally (`ping4`) and one using command endpoint (`disk`). > **Note** > > You don't necessarily need to add the agent endpoint/zone configuration objects > into the master's zones.conf file. Instead, you can put them into `/etc/icinga2/zones.d/master` > either in `hosts.conf` shown above, or in a new file called `agents.conf`. > **Tip**: > > It's a good idea to add [health checks](06-distributed-monitoring.md#distributed-monitoring-health-checks) to make sure that your cluster notifies you in case of failure. In terms of health checks, consider adding the following for this scenario: - Master node(s) check the connection to the agents - Optional: Add dependencies for the agent host to prevent unwanted notifications when agents are unreachable Proceed in [this chapter](06-distributed-monitoring.md#distributed-monitoring-health-checks-master-agents). ### High-Availability Master with Agents This scenario is similar to the one in the [previous section](06-distributed-monitoring.md#distributed-monitoring-master-agents). The only difference is that we will now set up two master nodes in a high-availability setup. These nodes must be configured as zone and endpoints objects. ![Icinga 2 Distributed High Availability Master with Agents](images/distributed-monitoring/icinga2_distributed_monitoring_scenario_ha_masters_with_agents.png) The setup uses the capabilities of the Icinga 2 cluster. All zone members replicate cluster events between each other. In addition to that, several Icinga 2 features can enable [HA functionality](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Best practice is to run the database backend on a dedicated server/cluster and only expose a virtual IP address to Icinga and the IDO feature. By default, only one endpoint will actively write to the backend then. Typical setups for MySQL clusters involve Master-Master-Replication (Master-Slave-Replication in both directions) or Galera, more tips can be found on our [community forums](https://community.icinga.com/). The IDO object must have the same `instance_name` on all master nodes. **Note**: All nodes in the same zone require that you enable the same features for high-availability (HA). Overview: * `icinga2-master1.localdomain` is the config master master node. * `icinga2-master2.localdomain` is the secondary master master node without config in `zones.d`. * `icinga2-agent1.localdomain` and `icinga2-agent2.localdomain` are two child nodes as agents. Setup requirements: * Set up `icinga2-master1.localdomain` as [master](06-distributed-monitoring.md#distributed-monitoring-setup-master). * Set up `icinga2-master2.localdomain` as [satellite](06-distributed-monitoring.md#distributed-monitoring-setup-agent-satellite) (**we will modify the generated configuration**). * Set up `icinga2-agent1.localdomain` and `icinga2-agent2.localdomain` as [agents](06-distributed-monitoring.md#distributed-monitoring-setup-agent-satellite) (when asked for adding multiple masters, set to `y` and add the secondary master `icinga2-master2.localdomain`). In case you don't want to use the CLI commands, you can also manually create and sync the required TLS certificates. We will modify and discuss all the details of the automatically generated configuration here. Since there are now two nodes in the same zone, we must consider the [high-availability features](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). * Checks and notifications are balanced between the two master nodes. That's fine, but it requires check plugins and notification scripts to exist on both nodes. * The IDO feature will only be active on one node by default. Since all events are replicated between both nodes, it is easier to just have one central database. One possibility is to use a dedicated MySQL cluster VIP (external application cluster) and leave the IDO feature with enabled HA capabilities. Alternatively, you can disable the HA feature and write to a local database on each node. Both methods require that you configure Icinga Web 2 accordingly (monitoring backend, IDO database, used transports, etc.). > **Note** > > You can also start with a single master shown [here](06-distributed-monitoring.md#distributed-monitoring-master-agents) and later add > the second master. This requires an extra step with the [initial sync](06-distributed-monitoring.md#distributed-monitoring-advanced-hints-initial-sync) > for cloning the runtime state after done. Once done, proceed here. In this scenario, we are not adding the agent configuration immediately to the `zones.conf` file but will establish the hierarchy later. The first master looks like this: ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // That's us } object Endpoint "icinga2-master2.localdomain" { host = "192.168.56.102" // Actively connect to the secondary master } object Zone "master" { endpoints = [ "icinga2-master1.localdomain", "icinga2-master2.localdomain" ] } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` The secondary master waits for connection attempts from the first master, and therefore does not try to connect to it again. ``` [root@icinga2-master2.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // The first master already connects to us } object Endpoint "icinga2-master2.localdomain" { // That's us } object Zone "master" { endpoints = [ "icinga2-master1.localdomain", "icinga2-master2.localdomain" ] } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` Restart both masters and ensure the initial connection and TLS handshake works. The two agent nodes do not need to know about each other. The only important thing is that they know about the parent zone and their endpoint members (and optionally about the global zone). If you specify the `host` attribute in the `icinga2-master1.localdomain` and `icinga2-master2.localdomain` endpoint objects, the agent will actively try to connect to the master node. Since we've specified the agent endpoint's attribute on the master node already, we don't want the agent to connect to the master nodes. **Choose one [connection direction](06-distributed-monitoring.md#distributed-monitoring-advanced-hints-connection-direction).** ``` [root@icinga2-agent1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute } object Endpoint "icinga2-master2.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute } object Endpoint "icinga2-agent1.localdomain" { // That's us } object Zone "master" { endpoints = [ "icinga2-master1.localdomain", "icinga2-master2.localdomain" ] } object Zone "icinga2-agent1.localdomain" { endpoints = [ "icinga2-agent1.localdomain" ] parent = "master" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` ``` [root@icinga2-agent2.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute } object Endpoint "icinga2-master2.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute } object Endpoint "icinga2-agent2.localdomain" { //That's us } object Zone "master" { endpoints = [ "icinga2-master1.localdomain", "icinga2-master2.localdomain" ] } object Zone "icinga2-agent2.localdomain" { endpoints = [ "icinga2-agent2.localdomain" ] parent = "master" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` Now it is time to define the two agent hosts and apply service checks using the command endpoint execution method. Create a new configuration directory on the master node `icinga2-master1.localdomain`. **Note**: The secondary master node `icinga2-master2.localdomain` receives the configuration using the [config sync mode](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync). ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/master ``` Add the two agent nodes with their zone/endpoint and host object configuration. > **Note** > > In order to keep things in sync between the two HA masters, > keep the `zones.conf` file as small as possible. > > You can create the agent zone and endpoint objects inside the > master zone and have them synced to the secondary master. > The cluster config sync enforces a reload allowing the secondary > master to connect to the agents as well. Edit the `zones.conf` file and ensure that the agent zone/endpoint objects are **not** specified in there. Then navigate into `/etc/icinga2/zones.d/master` and create a new file `agents.conf`. ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim agents.conf //----------------------------------------------- // Endpoints object Endpoint "icinga2-agent1.localdomain" { host = "192.168.56.111" // The master actively tries to connect to the agent log_duration = 0 // Disable the replay log for command endpoint agents } object Endpoint "icinga2-agent2.localdomain" { host = "192.168.56.112" // The master actively tries to connect to the agent log_duration = 0 // Disable the replay log for command endpoint agents } //----------------------------------------------- // Zones object Zone "icinga2-agent1.localdomain" { endpoints = [ "icinga2-agent1.localdomain" ] parent = "master" } object Zone "icinga2-agent2.localdomain" { endpoints = [ "icinga2-agent2.localdomain" ] parent = "master" } ``` Whenever you need to add an agent again, edit the mentioned files. Next, create the corresponding host objects for the agents. Use the same names for host and endpoint objects. ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim hosts.conf object Host "icinga2-agent1.localdomain" { check_command = "hostalive" address = "192.168.56.111" vars.agent_endpoint = name //follows the convention that host name == endpoint name } object Host "icinga2-agent2.localdomain" { check_command = "hostalive" address = "192.168.56.112" vars.agent_endpoint = name //follows the convention that host name == endpoint name } ``` Add services using command endpoint checks: ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim services.conf apply Service "ping4" { check_command = "ping4" // Check is executed on the master node assign where host.address } apply Service "disk" { check_command = "disk" // Check is executed on the remote command endpoint command_endpoint = host.vars.agent_endpoint assign where host.vars.agent_endpoint } ``` Validate the configuration and restart Icinga 2 on the master node `icinga2-master1.localdomain`. ``` [root@icinga2-master1.localdomain /]# icinga2 daemon -C [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` Open Icinga Web 2 and check the two newly created agent hosts with two new services -- one executed locally (`ping4`) and one using command endpoint (`disk`). > **Tip**: > > It's a good idea to add [health checks](06-distributed-monitoring.md#distributed-monitoring-health-checks) to make sure that your cluster notifies you in case of failure. In terms of health checks, consider adding the following for this scenario: - Master node(s) check the connection to the agents - Optional: Add dependencies for the agent host to prevent unwanted notifications when agents are unreachable Proceed in [this chapter](06-distributed-monitoring.md#distributed-monitoring-health-checks-master-agents). ### Three Levels with Masters, Satellites and Agents This scenario combines everything you've learned so far: High-availability masters, satellites receiving their configuration from the master zone, and agents checked via command endpoint from the satellite zones. ![Icinga 2 Distributed Master and Satellites with Agents](images/distributed-monitoring/icinga2_distributed_monitoring_scenarios_master_satellites_agents.png) > **Tip**: > > It can get complicated, so grab a pen and paper and bring your thoughts to life. > Play around with a test setup before using it in a production environment! There are various reasons why you might want to have satellites in your environment. The following list explains the more common ones. * Monitor remote locations. Besides reducing connections and traffic between different locations this setup also helps when the network connection to the remote network is lost. Satellites will keep checking and collecting data on their own and will send their check results when the connection is restored. * Reduce connections between security zones. Satellites in a different zone (e.g. DMZ) than your masters will help reduce connections through firewalls. * Offload resource hungry checks to other hosts. In very big setups running lots of plugins on your masters or satellites might have a significant impact on the performance during times of high load. You can introduce another level of satellites just to run these plugins and send their results to the upstream hosts. Best practice is to run the database backend on a dedicated server/cluster and only expose a virtual IP address to Icinga and the IDO feature. By default, only one endpoint will actively write to the backend then. Typical setups for MySQL clusters involve Master-Master-Replication (Master-Slave-Replication in both directions) or Galera, more tips can be found on our [community forums](https://community.icinga.com/). Overview: * `icinga2-master1.localdomain` is the configuration master master node. * `icinga2-master2.localdomain` is the secondary master master node without configuration in `zones.d`. * `icinga2-satellite1.localdomain` and `icinga2-satellite2.localdomain` are satellite nodes in a `master` child zone. They forward CSR signing requests to the master zone. * `icinga2-agent1.localdomain` and `icinga2-agent2.localdomain` are two child nodes as agents. Setup requirements: * Set up `icinga2-master1.localdomain` as [master](06-distributed-monitoring.md#distributed-monitoring-setup-master). * Set up `icinga2-master2.localdomain`, `icinga2-satellite1.localdomain` and `icinga2-satellite2.localdomain` as [agents](06-distributed-monitoring.md#distributed-monitoring-setup-agent-satellite) (we will modify the generated configuration). * Set up `icinga2-agent1.localdomain` and `icinga2-agent2.localdomain` as [agents](06-distributed-monitoring.md#distributed-monitoring-setup-agent-satellite). When being asked for the parent endpoint providing CSR auto-signing capabilities, please add one of the satellite nodes. **Note**: This requires Icinga 2 v2.8+ and the `CA Proxy` on all master, satellite and agent nodes. Example for `icinga2-agent1.localdomain`: ``` Please specify the parent endpoint(s) (master or satellite) where this node should connect to: ``` Parent endpoint is the first satellite `icinga2-satellite1.localdomain`: ``` Master/Satellite Common Name (CN from your master/satellite node): icinga2-satellite1.localdomain Do you want to establish a connection to the parent node from this node? [Y/n]: y Please specify the master/satellite connection information: Master/Satellite endpoint host (IP address or FQDN): 192.168.56.105 Master/Satellite endpoint port [5665]: 5665 ``` Add the second satellite `icinga2-satellite2.localdomain` as parent: ``` Add more master/satellite endpoints? [y/N]: y Master/Satellite Common Name (CN from your master/satellite node): icinga2-satellite2.localdomain Do you want to establish a connection to the parent node from this node? [Y/n]: y Please specify the master/satellite connection information: Master/Satellite endpoint host (IP address or FQDN): 192.168.56.106 Master/Satellite endpoint port [5665]: 5665 Add more master/satellite endpoints? [y/N]: n ``` The specified parent nodes will forward the CSR signing request to the master instances. Proceed with adding the optional client ticket for [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing): ``` Please specify the request ticket generated on your Icinga 2 master (optional). (Hint: # icinga2 pki ticket --cn 'icinga2-agent1.localdomain'): 4f75d2ecd253575fe9180938ebff7cbca262f96e ``` In case you've chosen to use [On-Demand CSR Signing](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing) you can leave the ticket question blank. Instead, Icinga 2 tells you to approve the request later on the master node. ``` No ticket was specified. Please approve the certificate signing request manually on the master (see 'icinga2 ca list' and 'icinga2 ca sign --help' for details). ``` You can optionally specify a different bind host and/or port. ``` Please specify the API bind host/port (optional): Bind Host []: Bind Port []: ``` The next step asks you to accept configuration (required for [config sync mode](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync)) and commands (required for [command endpoint mode](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint)). ``` Accept config from parent node? [y/N]: y Accept commands from parent node? [y/N]: y ``` Next you can optionally specify the local and parent zone names. This will be reflected in the generated zone configuration file. ``` Local zone name [icinga2-agent1.localdomain]: icinga2-agent1.localdomain ``` Set the parent zone name to `satellite` for this agent. ``` Parent zone name [master]: satellite ``` You can add more global zones in addition to `global-templates` and `director-global` if necessary. Press `Enter` or choose `n`, if you don't want to add any additional. ``` Reconfiguring Icinga... Default global zones: global-templates director-global Do you want to specify additional global zones? [y/N]: N ``` Last but not least the wizard asks you whether you want to disable the inclusion of the local configuration directory in `conf.d`, or not. Defaults to disabled, since agents are checked via command endpoint and the example configuration would collide with this mode. ``` Do you want to disable the inclusion of the conf.d directory [Y/n]: Y Disabling the inclusion of the conf.d directory... ``` **We'll discuss the details of the required configuration below. Most of this configuration can be rendered by the setup wizards.** The zone hierarchy can look like this. We'll define only the directly connected zones here. The master instances should actively connect to the satellite instances, therefore the configuration on `icinga2-master1.localdomain` and `icinga2-master2.localdomain` must include the `host` attribute for the satellite endpoints: ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // That's us } object Endpoint "icinga2-master2.localdomain" { host = "192.168.56.102" // Actively connect to the second master. } object Endpoint "icinga2-satellite1.localdomain" { host = "192.168.56.105" // Actively connect to the satellites. } object Endpoint "icinga2-satellite2.localdomain" { host = "192.168.56.106" // Actively connect to the satellites. } object Zone "master" { endpoints = [ "icinga2-master1.localdomain", "icinga2-master2.localdomain" ] } ``` The endpoint configuration on the secondary master looks similar, but changes the connection attributes - the first master already tries to connect, there is no need for a secondary attempt. ``` [root@icinga2-master2.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // First master already connects to us } object Endpoint "icinga2-master2.localdomain" { // That's us } object Endpoint "icinga2-satellite1.localdomain" { host = "192.168.56.105" // Actively connect to the satellites. } object Endpoint "icinga2-satellite2.localdomain" { host = "192.168.56.106" // Actively connect to the satellites. } ``` The zone configuration on both masters looks the same. Add this to the corresponding `zones.conf` entries for the endpoints. ``` object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain", "icinga2-satellite2.localdomain" ] parent = "master" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` In contrast to that, the satellite instances `icinga2-satellite1.localdomain` and `icinga2-satellite2.localdomain` should not actively connect to the master instances. ``` [root@icinga2-satellite1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // This endpoint will connect to us } object Endpoint "icinga2-master2.localdomain" { // This endpoint will connect to us } object Endpoint "icinga2-satellite1.localdomain" { // That's us } object Endpoint "icinga2-satellite2.localdomain" { host = "192.168.56.106" // Actively connect to the secondary satellite } ``` Again, only one side is required to establish the connection inside the HA zone. Since satellite1 already connects to satellite2, leave out the `host` attribute for `icinga2-satellite1.localdomain` on satellite2. ``` [root@icinga2-satellite2.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { // This endpoint will connect to us } object Endpoint "icinga2-master2.localdomain" { // This endpoint will connect to us } object Endpoint "icinga2-satellite1.localdomain" { // First satellite already connects to us } object Endpoint "icinga2-satellite2.localdomain" { // That's us } ``` The zone configuration on both satellites looks the same. Add this to the corresponding `zones.conf` entries for the endpoints. ``` object Zone "master" { endpoints = [ "icinga2-master1.localdomain", "icinga2-master2.localdomain" ] } object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain", "icinga2-satellite2.localdomain" ] parent = "master" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` Keep in mind to control the endpoint [connection direction](06-distributed-monitoring.md#distributed-monitoring-advanced-hints-connection-direction) using the `host` attribute, also for other endpoints in the same zone. Since we want to use [top down command endpoint](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) checks, we must configure the agent endpoint and zone objects. In order to minimize the effort, we'll sync the agent zone and endpoint configuration to the satellites where the connection information is needed as well. Note: This only works with satellite and agents, since there already is a trust relationship between the master and the satellite zone. The cluster config sync to the satellite invokes an automated reload causing the agent connection attempts. `icinga2-master1.localdomain` is the configuration master where everything is stored: ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/{master,satellite,global-templates} [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/satellite [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim icinga2-agent1.localdomain.conf object Endpoint "icinga2-agent1.localdomain" { host = "192.168.56.111" // The satellite actively tries to connect to the agent log_duration = 0 // Disable the replay log for command endpoint agents } object Zone "icinga2-agent1.localdomain" { endpoints = [ "icinga2-agent1.localdomain" ] parent = "satellite" } [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim icinga2-agent2.localdomain.conf object Endpoint "icinga2-agent2.localdomain" { host = "192.168.56.112" // The satellite actively tries to connect to the agent log_duration = 0 // Disable the replay log for command endpoint agents } object Zone "icinga2-agent2.localdomain" { endpoints = [ "icinga2-agent2.localdomain" ] parent = "satellite" } ``` The two agent nodes do not need to know about each other. The only important thing is that they know about the parent zone (the satellite) and their endpoint members (and optionally the global zone). > **Tipp** > > In the example above we've specified the `host` attribute in the agent endpoint configuration. In this mode, > the satellites actively connect to the agents. This costs some resources on the satellite -- if you prefer to > offload the connection attempts to the agent, or your DMZ requires this, you can also change the **[connection direction](06-distributed-monitoring.md#distributed-monitoring-advanced-hints-connection-direction).** > > 1) Don't set the `host` attribute for the agent endpoints put into `zones.d/satellite`. > 2) Modify each agent's zones.conf file and add the `host` attribute to all parent satellites. You can automate this with using the `node wizard/setup` CLI commands. The agents are waiting for the satellites to connect, therefore they don't specify the `host` attribute in the endpoint objects locally. Example for `icinga2-agent1.localdomain`: ``` [root@icinga2-agent1.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-satellite1.localdomain" { // Do not actively connect to the satellite by leaving out the 'host' attribute } object Endpoint "icinga2-satellite2.localdomain" { // Do not actively connect to the satellite by leaving out the 'host' attribute } object Endpoint "icinga2-agent1.localdomain" { // That's us } object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain", "icinga2-satellite2.localdomain" ] } object Zone "icinga2-agent1.localdomain" { endpoints = [ "icinga2-agent1.localdomain" ] parent = "satellite" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` Example for `icinga2-agent2.localdomain`: ``` [root@icinga2-agent2.localdomain /]# vim /etc/icinga2/zones.conf object Endpoint "icinga2-satellite1.localdomain" { // Do not actively connect to the satellite by leaving out the 'host' attribute } object Endpoint "icinga2-satellite2.localdomain" { // Do not actively connect to the satellite by leaving out the 'host' attribute } object Endpoint "icinga2-agent2.localdomain" { // That's us } object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain", "icinga2-satellite2.localdomain" ] } object Zone "icinga2-agent2.localdomain" { endpoints = [ "icinga2-agent2.localdomain" ] parent = "satellite" } /* sync global commands */ object Zone "global-templates" { global = true } object Zone "director-global" { global = true } ``` Now it is time to define the two agents hosts on the master, sync them to the satellites and apply service checks using the command endpoint execution method to them. Add the two agent nodes as host objects to the `satellite` zone. We've already created the directories in `/etc/icinga2/zones.d` including the files for the zone and endpoint configuration for the agents. ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/satellite ``` Add the host object configuration for the `icinga2-agent1.localdomain` agent. You should have created the configuration file in the previous steps and it should contain the endpoint and zone object configuration already. ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim icinga2-agent1.localdomain.conf object Host "icinga2-agent1.localdomain" { check_command = "hostalive" address = "192.168.56.111" vars.agent_endpoint = name // Follows the convention that host name == endpoint name } ``` Add the host object configuration for the `icinga2-agent2.localdomain` agent configuration file: ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim icinga2-agent2.localdomain.conf object Host "icinga2-agent2.localdomain" { check_command = "hostalive" address = "192.168.56.112" vars.agent_endpoint = name // Follows the convention that host name == endpoint name } ``` Add a service object which is executed on the satellite nodes (e.g. `ping4`). Pin the apply rule to the `satellite` zone only. ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim services.conf apply Service "ping4" { check_command = "ping4" // Check is executed on the satellite node assign where host.zone == "satellite" && host.address } ``` Add services using command endpoint checks. Pin the apply rules to the `satellite` zone only. ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim services.conf apply Service "disk" { check_command = "disk" // Execute the check on the remote command endpoint command_endpoint = host.vars.agent_endpoint assign where host.zone == "satellite" && host.vars.agent_endpoint } ``` Validate the configuration and restart Icinga 2 on the master node `icinga2-master1.localdomain`. ``` [root@icinga2-master1.localdomain /]# icinga2 daemon -C [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` Open Icinga Web 2 and check the two newly created agent hosts with two new services -- one executed locally (`ping4`) and one using command endpoint (`disk`). > **Tip**: > > It's a good idea to add [health checks](06-distributed-monitoring.md#distributed-monitoring-health-checks) to make sure that your cluster notifies you in case of failure. In terms of health checks, consider adding the following for this scenario: - Master nodes check whether the satellite zone is connected - Satellite nodes check the connection to the agents - Optional: Add dependencies for the agent host to prevent unwanted notifications when agents are unreachable Proceed in [this chapter](06-distributed-monitoring.md#distributed-monitoring-health-checks-master-satellite-agent). ## Best Practice We've put together a collection of configuration examples from community feedback. If you like to share your tips and tricks with us, please join the [community channels](https://icinga.com/community/)! ### Global Zone for Config Sync Global zones can be used to sync generic configuration objects to all nodes depending on them. Common examples are: * Templates which are imported into zone specific objects. * Command objects referenced by Host, Service, Notification objects. * Apply rules for services, notifications and dependencies. * User objects referenced in notifications. * Group objects. * TimePeriod objects. Plugin scripts and binaries must not be synced, this is for Icinga 2 configuration files only. Use your preferred package repository and/or configuration management tool (Puppet, Ansible, Chef, etc.) for keeping packages and scripts uptodate. **Note**: Checkable objects (hosts and services) cannot be put into a global zone. The configuration validation will terminate with an error. Apply rules work as they are evaluated locally on each endpoint. The zone object configuration must be deployed on all nodes which should receive the global configuration files: ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.conf object Zone "global-commands" { global = true } ``` The default global zones generated by the setup wizards are called `global-templates` and `director-global`. While you can and should use `global-templates` for your global configuration, `director-global` is reserved for use by [Icinga Director](https://icinga.com/docs/director/latest/). Please don't place any configuration in it manually. Similar to the zone configuration sync you'll need to create a new directory in `/etc/icinga2/zones.d`: ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/global-commands ``` Next, add a new check command, for example: ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/global-commands/web.conf object CheckCommand "webinject" { //... } ``` Restart the endpoints(s) which should receive the global zone before before restarting the parent master/satellite nodes. Then validate the configuration on the master node and restart Icinga 2. **Tip**: You can copy the example configuration files located in `/etc/icinga2/conf.d` into the default global zone `global-templates`. Example: ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/conf.d [root@icinga2-master1.localdomain /etc/icinga2/conf.d]# cp {commands,groups,notifications,services,templates,timeperiods,users}.conf /etc/icinga2/zones.d/global-templates ``` ### Health Checks In case of network failures or other problems, your monitoring might either have late check results or just send out mass alarms for unknown checks. In order to minimize the problems caused by this, you should configure additional health checks. #### cluster-zone with Masters and Agents The `cluster-zone` check will test whether the configured target zone is currently connected or not. This example adds a health check for the [ha master with agents scenario](06-distributed-monitoring.md#distributed-monitoring-scenarios-ha-master-agents). ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/services.conf apply Service "agent-health" { check_command = "cluster-zone" display_name = "cluster-health-" + host.name /* This follows the convention that the agent zone name is the FQDN which is the same as the host object name. */ vars.cluster_zone = host.name assign where host.vars.agent_endpoint } ``` In order to prevent unwanted notifications, add a service dependency which gets applied to all services using the command endpoint mode. ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/dependencies.conf apply Dependency "agent-health-check" to Service { parent_service_name = "agent-health" states = [ OK ] // Fail if the parent service state switches to NOT-OK disable_notifications = true assign where host.vars.agent_endpoint // Automatically assigns all agent endpoint checks as child services on the matched host ignore where service.name == "agent-health" // Avoid a self reference from child to parent } ``` #### cluster-zone with Masters, Satellites and Agents This example adds health checks for the [master, satellites and agents scenario](06-distributed-monitoring.md#distributed-monitoring-scenarios-master-satellite-agents). Whenever the connection between the master and satellite zone breaks, you may encounter late check results in Icinga Web. In order to view this failure and also send notifications, add the following configuration: First, add the two masters as host objects to the master zone, if not already existing. ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/hosts.conf object Host "icinga2-master1.localdomain" { check_command = "hostalive" address = "192.168.56.101" } object Host "icinga2-master2.localdomain" { check_command = "hostalive" address = "192.168.56.102" } ``` Add service health checks against the satellite zone. ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/health.conf apply Service "satellite-zone-health" { check_command = "cluster-zone" check_interval = 30s retry_interval = 10s vars.cluster_zone = "satellite" assign where match("icinga2-master*.localdomain", host.name) } ``` **Don't forget to create notification apply rules for these services.** Next are health checks for agents connected to the satellite zone. Navigate into the satellite directory in `zones.d`: ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/satellite ``` You should already have configured agent host objects following [the master, satellite, agents scenario](06-distributed-monitoring.md#distributed-monitoring-scenarios-master-satellite-agents). Add a new configuration file where all the health checks are defined. ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim health.conf apply Service "agent-health" { check_command = "cluster-zone" display_name = "agent-health-" + host.name // This follows the convention that the agent zone name is the FQDN which is the same as the host object name. vars.cluster_zone = host.name // Create this health check for agent hosts in the satellite zone assign where host.zone == "satellite" && host.vars.agent_endpoint } ``` In order to prevent unwanted notifications, add a service dependency which gets applied to all services using the command endpoint mode. ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/satellite]# vim health.conf apply Dependency "agent-health-check" to Service { parent_service_name = "agent-health" states = [ OK ] // Fail if the parent service state switches to NOT-OK disable_notifications = true assign where host.zone == "satellite" && host.vars.agent_endpoint // Automatically assigns all agent endpoint checks as child services on the matched host ignore where service.name == "agent-health" // Avoid a self reference from child to parent } ``` This is all done on the configuration master, and requires the scenario to be fully up and running. #### Cluster Check The `cluster` check will check if all endpoints in the current zone and the directly connected zones are working properly. The disadvantage of using this check is that you cannot monitor 3 or more cluster levels with it. ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/icinga2-master1.localdomain.conf object Host "icinga2-master1.localdomain" { check_command = "hostalive" address = "192.168.56.101" } [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/cluster.conf object Service "cluster" { check_command = "cluster" check_interval = 5s retry_interval = 1s host_name = "icinga2-master1.localdomain" } ``` ### Pin Checks in a Zone In case you want to pin specific checks to their endpoints in a given zone you'll need to use the `command_endpoint` attribute. This is reasonable if you want to execute a local disk check in the `master` Zone on a specific endpoint then. ``` [root@icinga2-master1.localdomain /]# mkdir -p /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/icinga2-master1.localdomain.conf object Host "icinga2-master1.localdomain" { check_command = "hostalive" address = "192.168.56.101" } [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.d/master/services.conf apply Service "disk" { check_command = "disk" command_endpoint = host.name //requires a host object matching the endpoint object name e.g. icinga2-master1.localdomain assign where host.zone == "master" && match("icinga2-master*", host.name) } ``` The `host.zone` attribute check inside the expression ensures that the service object is only created for host objects inside the `master` zone. In addition to that the [match](18-library-reference.md#global-functions-match) function ensures to only create services for the master nodes. ### Windows Firewall #### ICMP Requests By default ICMP requests are disabled in the Windows firewall. You can change that by [adding a new rule](https://support.microsoft.com/en-us/kb/947709). ``` C:\> netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow ``` #### Icinga 2 If your master/satellite nodes should actively connect to the Windows agent you'll also need to ensure that port `5665` is enabled. ``` C:\> netsh advfirewall firewall add rule name="Open port 5665 (Icinga 2)" dir=in action=allow protocol=TCP localport=5665 ``` #### NSClient++ API If the [check_nscp_api](06-distributed-monitoring.md#distributed-monitoring-windows-nscp-check-api) plugin is used to query NSClient++, you need to ensure that its port is enabled. ``` C:\> netsh advfirewall firewall add rule name="Open port 8443 (NSClient++ API)" dir=in action=allow protocol=TCP localport=8443 ``` For security reasons, it is advised to enable the NSClient++ HTTP API for local connection from the Icinga agent only. Remote connections to the HTTP API are not recommended with using the legacy HTTP API. ### Windows Agent and Plugins The Icinga 2 package on Windows already provides several plugins. Detailed [documentation](10-icinga-template-library.md#windows-plugins) is available for all check command definitions. Based on the [master with agents](06-distributed-monitoring.md#distributed-monitoring-master-agents) scenario we'll now add a local disk check. First, add the agent node as host object: ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim hosts.conf object Host "icinga2-agent2.localdomain" { check_command = "hostalive" address = "192.168.56.112" vars.agent_endpoint = name //follows the convention that host name == endpoint name vars.os_type = "windows" } ``` Next, add the disk check using command endpoint checks (details in the [disk-windows](10-icinga-template-library.md#windows-plugins-disk-windows) documentation): ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim services.conf apply Service "disk C:" { check_command = "disk-windows" vars.disk_win_path = "C:" //specify where the check is executed command_endpoint = host.vars.agent_endpoint assign where host.vars.os_type == "windows" && host.vars.agent_endpoint } ``` Validate the configuration and restart Icinga 2. ``` [root@icinga2-master1.localdomain /]# icinga2 daemon -C [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` Open Icinga Web 2 and check your newly added Windows disk check :) ![Icinga Windows Agent](images/distributed-monitoring/icinga2_distributed_windows_client_disk_icingaweb2.png) If you want to add your own plugins please check [this chapter](05-service-monitoring.md#service-monitoring-requirements) for the requirements. ### Windows Agent and NSClient++ There are two methods available for querying NSClient++: * Query the [HTTP API](06-distributed-monitoring.md#distributed-monitoring-windows-nscp-check-api) locally from an Icinga agent (requires a running NSClient++ service) * Run a [local CLI check](06-distributed-monitoring.md#distributed-monitoring-windows-nscp-check-local) (does not require NSClient++ as a service) Both methods have their advantages and disadvantages. One thing to note: If you rely on performance counter delta calculations such as CPU utilization, please use the HTTP API instead of the CLI sample call. #### NSCLient++ with check_nscp_api In addition to the Windows plugins you can use the [nscp_api command](10-icinga-template-library.md#nscp-check-api) provided by the Icinga Template Library (ITL). The initial setup for the NSClient++ API and the required arguments is the described in the ITL chapter for the [nscp_api](10-icinga-template-library.md#nscp-check-api) CheckCommand. Based on the [master with agents](06-distributed-monitoring.md#distributed-monitoring-master-agents) scenario we'll now add a local nscp check which queries the NSClient++ API to check the free disk space. Define a host object called `icinga2-agent2.localdomain` on the master. Add the `nscp_api_password` custom variable and specify the drives to check. ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim hosts.conf object Host "icinga2-agent1.localdomain" { check_command = "hostalive" address = "192.168.56.111" vars.agent_endpoint = name //follows the convention that host name == endpoint name vars.os_type = "Windows" vars.nscp_api_password = "icinga" vars.drives = [ "C:", "D:" ] } ``` The service checks are generated using an [apply for](03-monitoring-basics.md#using-apply-for) rule based on `host.vars.drives`: ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim services.conf apply Service "nscp-api-" for (drive in host.vars.drives) { import "generic-service" check_command = "nscp_api" command_endpoint = host.vars.agent_endpoint //display_name = "nscp-drive-" + drive vars.nscp_api_host = "localhost" vars.nscp_api_query = "check_drivesize" vars.nscp_api_password = host.vars.nscp_api_password vars.nscp_api_arguments = [ "drive=" + drive ] ignore where host.vars.os_type != "Windows" } ``` Validate the configuration and restart Icinga 2. ``` [root@icinga2-master1.localdomain /]# icinga2 daemon -C [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` Two new services ("nscp-drive-D:" and "nscp-drive-C:") will be visible in Icinga Web 2. ![Icinga 2 Distributed Monitoring Windows Agent with NSClient++ nscp-api](images/distributed-monitoring/icinga2_distributed_windows_nscp_api_drivesize_icingaweb2.png) Note: You can also omit the `command_endpoint` configuration to execute the command on the master. This also requires a different value for `nscp_api_host` which defaults to `host.address`. ``` //command_endpoint = host.vars.agent_endpoint //vars.nscp_api_host = "localhost" ``` You can verify the check execution by looking at the `Check Source` attribute in Icinga Web 2 or the REST API. If you want to monitor specific Windows services, you could use the following example: ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim hosts.conf object Host "icinga2-agent1.localdomain" { check_command = "hostalive" address = "192.168.56.111" vars.agent_endpoint = name //follows the convention that host name == endpoint name vars.os_type = "Windows" vars.nscp_api_password = "icinga" vars.services = [ "Windows Update", "wscsvc" ] } [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim services.conf apply Service "nscp-api-" for (svc in host.vars.services) { import "generic-service" check_command = "nscp_api" command_endpoint = host.vars.agent_endpoint //display_name = "nscp-service-" + svc vars.nscp_api_host = "localhost" vars.nscp_api_query = "check_service" vars.nscp_api_password = host.vars.nscp_api_password vars.nscp_api_arguments = [ "service=" + svc ] ignore where host.vars.os_type != "Windows" } ``` #### NSCLient++ with nscp-local In addition to the Windows plugins you can use the [nscp-local commands](10-icinga-template-library.md#nscp-plugin-check-commands) provided by the Icinga Template Library (ITL). Add the following `include` statement on all your nodes (master, satellite, agent): ``` vim /etc/icinga2/icinga2.conf include ``` The CheckCommand definitions will automatically determine the installed path to the `nscp.exe` binary. Based on the [master with agents](06-distributed-monitoring.md#distributed-monitoring-master-agents) scenario we'll now add a local nscp check querying a given performance counter. First, add the agent node as host object: ``` [root@icinga2-master1.localdomain /]# cd /etc/icinga2/zones.d/master [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim hosts.conf object Host "icinga2-agent1.localdomain" { check_command = "hostalive" address = "192.168.56.111" vars.agent_endpoint = name //follows the convention that host name == endpoint name vars.os_type = "windows" } ``` Next, add a performance counter check using command endpoint checks (details in the [nscp-local-counter](10-icinga-template-library.md#nscp-check-local-counter) documentation): ``` [root@icinga2-master1.localdomain /etc/icinga2/zones.d/master]# vim services.conf apply Service "nscp-local-counter-cpu" { check_command = "nscp-local-counter" command_endpoint = host.vars.agent_endpoint vars.nscp_counter_name = "\\Processor(_total)\\% Processor Time" vars.nscp_counter_perfsyntax = "Total Processor Time" vars.nscp_counter_warning = 1 vars.nscp_counter_critical = 5 vars.nscp_counter_showall = true assign where host.vars.os_type == "windows" && host.vars.agent_endpoint } ``` Validate the configuration and restart Icinga 2. ``` [root@icinga2-master1.localdomain /]# icinga2 daemon -C [root@icinga2-master1.localdomain /]# systemctl restart icinga2 ``` Open Icinga Web 2 and check your newly added Windows NSClient++ check :) ![Icinga 2 Distributed Monitoring Windows Agent with NSClient++ nscp-local](images/distributed-monitoring/icinga2_distributed_windows_nscp_counter_icingaweb2.png) > **Tip** > > In order to measure CPU load, you'll need a running NSClient++ service. > Therefore it is advised to use a local [nscp-api](06-distributed-monitoring.md#distributed-monitoring-windows-nscp-check-api) > check against its REST API. ## Advanced Hints You can find additional hints in this section if you prefer to go your own route with automating setups (setup, certificates, configuration). ### Certificate Auto-Renewal Icinga 2 v2.8+ added the possibility that nodes request certificate updates on their own. If their expiration date is soon enough, they automatically renew their already signed certificate by sending a signing request to the parent node. You'll also see a message in the logs if certificate renewal isn't necessary. ### High-Availability for Icinga 2 Features All nodes in the same zone require that you enable the same features for high-availability (HA). By default, the following features provide advanced HA functionality: * [Checks](06-distributed-monitoring.md#distributed-monitoring-high-availability-checks) (load balanced, automated failover). * [Notifications](06-distributed-monitoring.md#distributed-monitoring-high-availability-notifications) (load balanced, automated failover). * [DB IDO](06-distributed-monitoring.md#distributed-monitoring-high-availability-db-ido) (Run-Once, automated failover). * [Elasticsearch](09-object-types.md#objecttype-elasticsearchwriter) * [Gelf](09-object-types.md#objecttype-gelfwriter) * [Graphite](09-object-types.md#objecttype-graphitewriter) * [InfluxDB](09-object-types.md#objecttype-influxdb2writer) (v1 and v2) * [OpenTsdb](09-object-types.md#objecttype-opentsdbwriter) * [Perfdata](09-object-types.md#objecttype-perfdatawriter) (for PNP) #### High-Availability with Checks All instances within the same zone (e.g. the `master` zone as HA cluster) must have the `checker` feature enabled. Example: ```bash icinga2 feature enable checker ``` All nodes in the same zone load-balance the check execution. If one instance shuts down, the other nodes will automatically take over the remaining checks. #### High-Availability with Notifications All instances within the same zone (e.g. the `master` zone as HA cluster) must have the `notification` feature enabled. Example: ```bash icinga2 feature enable notification ``` Notifications are load-balanced amongst all nodes in a zone. By default this functionality is enabled. If your nodes should send out notifications independently from any other nodes (this will cause duplicated notifications if not properly handled!), you can set `enable_ha = false` in the [NotificationComponent](09-object-types.md#objecttype-notificationcomponent) feature. #### High-Availability with DB IDO All instances within the same zone (e.g. the `master` zone as HA cluster) must have the DB IDO feature enabled. Example DB IDO MySQL: ```bash icinga2 feature enable ido-mysql ``` By default the DB IDO feature only runs on one node. All other nodes in the same zone disable the active IDO database connection at runtime. The node with the active DB IDO connection is not necessarily the zone master. **Note**: The DB IDO HA feature can be disabled by setting the `enable_ha` attribute to `false` for the [IdoMysqlConnection](09-object-types.md#objecttype-idomysqlconnection) or [IdoPgsqlConnection](09-object-types.md#objecttype-idopgsqlconnection) object on **all** nodes in the **same** zone. All endpoints will enable the DB IDO feature and connect to the configured database and dump configuration, status and historical data on their own. If the instance with the active DB IDO connection dies, the HA functionality will automatically elect a new DB IDO master. The DB IDO feature will try to determine which cluster endpoint is currently writing to the database and bail out if another endpoint is active. You can manually verify that by running the following query command: ``` icinga=> SELECT status_update_time, endpoint_name FROM icinga_programstatus; status_update_time | endpoint_name ------------------------+--------------- 2016-08-15 15:52:26+02 | icinga2-master1.localdomain (1 Zeile) ``` This is useful when the cluster connection between endpoints breaks, and prevents data duplication in split-brain-scenarios. The failover timeout can be set for the `failover_timeout` attribute, but not lower than 60 seconds. ### Endpoint Connection Direction Endpoints attempt to connect to another endpoint when its local [Endpoint](09-object-types.md#objecttype-endpoint) object configuration specifies a valid `host` attribute (FQDN or IP address). Example for the master node `icinga2-master1.localdomain` actively connecting to the agent node `icinga2-agent1.localdomain`: ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.conf //... object Endpoint "icinga2-agent1.localdomain" { host = "192.168.56.111" // The master actively tries to connect to the agent log_duration = 0 // Disable the replay log for command endpoint agents } ``` Example for the agent node `icinga2-agent1.localdomain` not actively connecting to the master node `icinga2-master1.localdomain`: ``` [root@icinga2-agent1.localdomain /]# vim /etc/icinga2/zones.conf //... object Endpoint "icinga2-master1.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute log_duration = 0 // Disable the replay log for command endpoint agents } ``` It is not necessary that both the master and the agent node establish two connections to each other. Icinga 2 will only use one connection and close the second connection if established. This generates useless CPU cycles and leads to blocking resources when the connection times out. **Tip**: Choose either to let master/satellite nodes connect to agent nodes or vice versa. ### Disable Log Duration for Command Endpoints The replay log is a built-in mechanism to ensure that nodes in a distributed setup keep the same history (check results, notifications, etc.) when nodes are temporarily disconnected and then reconnect. This functionality is not needed when a master/satellite node is sending check execution events to an agent which is configured as [command endpoint](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) for check execution. The [Endpoint](09-object-types.md#objecttype-endpoint) object attribute `log_duration` can be lower or set to 0 to fully disable any log replay updates when the agent is not connected. Configuration on the master node `icinga2-master1.localdomain`: ``` [root@icinga2-master1.localdomain /]# vim /etc/icinga2/zones.conf //... object Endpoint "icinga2-agent1.localdomain" { host = "192.168.56.111" // The master actively tries to connect to the agent log_duration = 0 } object Endpoint "icinga2-agent2.localdomain" { host = "192.168.56.112" // The master actively tries to connect to the agent log_duration = 0 } ``` Configuration on the agent `icinga2-agent1.localdomain`: ``` [root@icinga2-agent1.localdomain /]# vim /etc/icinga2/zones.conf //... object Endpoint "icinga2-master1.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute log_duration = 0 } object Endpoint "icinga2-master2.localdomain" { // Do not actively connect to the master by leaving out the 'host' attribute log_duration = 0 } ``` ### Initial Sync for new Endpoints in a Zone > **Note** > > This is required if you decide to change an already running single endpoint production > environment into an HA-enabled cluster zone with two endpoints. > The [initial setup](06-distributed-monitoring.md#distributed-monitoring-scenarios-ha-master-clients) > with 2 HA masters doesn't require this step. In order to make sure that all of your zone endpoints have the same state you need to pick the authoritative running one and copy the following content: * State file from `/var/lib/icinga2/icinga2.state` * Internal config package for runtime created objects (downtimes, comments, hosts, etc.) at `/var/lib/icinga2/api/packages/_api` If you need already deployed config packages from the Director, or synced cluster zones, you can also sync the entire `/var/lib/icinga2/api/packages` directory. This directory should also be included in your backup strategy. Do **not** sync `/var/lib/icinga2/api/zones*` manually - this is an internal directory and handled by the Icinga cluster config sync itself. > **Note** > > Ensure that all endpoints are shut down during this procedure. Once you have > synced the cached files, proceed with configuring the remaining endpoints > to let them know about the new master/satellite node (zones.conf). ### Manual Certificate Creation #### Create CA on the Master Choose the host which should store the certificate authority (one of the master nodes). The first step is the creation of the certificate authority (CA) by running the following command as root user: ``` [root@icinga2-master1.localdomain /root]# icinga2 pki new-ca ``` #### Create CSR and Certificate Create a certificate signing request (CSR) for the local instance: ``` [root@icinga2-master1.localdomain /root]# icinga2 pki new-cert --cn icinga2-master1.localdomain \ --key icinga2-master1.localdomain.key \ --csr icinga2-master1.localdomain.csr ``` Sign the CSR with the previously created CA: ``` [root@icinga2-master1.localdomain /root]# icinga2 pki sign-csr --csr icinga2-master1.localdomain.csr --cert icinga2-master1.localdomain.crt ``` Repeat the steps for all instances in your setup. #### Copy Certificates Copy the host's certificate files and the public CA certificate to `/var/lib/icinga2/certs`: ``` [root@icinga2-master1.localdomain /root]# mkdir -p /var/lib/icinga2/certs [root@icinga2-master1.localdomain /root]# cp icinga2-master1.localdomain.{crt,key} /var/lib/icinga2/certs [root@icinga2-master1.localdomain /root]# cp /var/lib/icinga2/ca/ca.crt /var/lib/icinga2/certs ``` Ensure that proper permissions are set (replace `icinga` with the Icinga 2 daemon user): ``` [root@icinga2-master1.localdomain /root]# chown -R icinga:icinga /var/lib/icinga2/certs [root@icinga2-master1.localdomain /root]# chmod 600 /var/lib/icinga2/certs/*.key [root@icinga2-master1.localdomain /root]# chmod 644 /var/lib/icinga2/certs/*.crt ``` The CA public and private key are stored in the `/var/lib/icinga2/ca` directory. Keep this path secure and include it in your backups. #### Create Multiple Certificates Use your preferred method to automate the certificate generation process. ``` [root@icinga2-master1.localdomain /var/lib/icinga2/certs]# for node in icinga2-master1.localdomain icinga2-master2.localdomain icinga2-satellite1.localdomain; do icinga2 pki new-cert --cn $node --csr $node.csr --key $node.key; done information/base: Writing private key to 'icinga2-master1.localdomain.key'. information/base: Writing certificate signing request to 'icinga2-master1.localdomain.csr'. information/base: Writing private key to 'icinga2-master2.localdomain.key'. information/base: Writing certificate signing request to 'icinga2-master2.localdomain.csr'. information/base: Writing private key to 'icinga2-satellite1.localdomain.key'. information/base: Writing certificate signing request to 'icinga2-satellite1.localdomain.csr'. [root@icinga2-master1.localdomain /var/lib/icinga2/certs]# for node in icinga2-master1.localdomain icinga2-master2.localdomain icinga2-satellite1.localdomain; do sudo icinga2 pki sign-csr --csr $node.csr --cert $node.crt; done information/pki: Writing certificate to file 'icinga2-master1.localdomain.crt'. information/pki: Writing certificate to file 'icinga2-master2.localdomain.crt'. information/pki: Writing certificate to file 'icinga2-satellite1.localdomain.crt'. ``` Copy and move these certificates to the respective instances e.g. with SSH/SCP. #### External CA/PKI Icinga works best with its own certificates. The commands described above take care of the optimal certificate properties. Also, Icinga renews them periodically at runtime to avoid expiry. But you can also provide your own certificates, just like to any other application which uses TLS. !!! warning The only serious reasons to generate own certificates are company policies. You are responsible for making Icinga working with your certificates, as well as for [expiry monitoring](10-icinga-template-library.md#plugin-check-command-ssl_cert) and renewal. Especially `icinga2 pki` CLI commands do not expect such certificates. Also, do not provide your custom CA private key to Icinga 2! Otherwise, it will automatically renew leaf certificates with our hardcoded properties, not your custom ones. The CA certificate must be located in `/var/lib/icinga2/certs/ca.crt`. The basic requirements for all leaf certificates are: * Located in `/var/lib/icinga2/certs/NODENAME.crt` and `/var/lib/icinga2/certs/NODENAME.key` * Subject with CN matching the endpoint name * A DNS SAN matching the endpoint name Pretty much everything else is limited only by your company policy and the OpenSSL versions your Icinga nodes use. E.g. the following works: * Custom key sizes, e.g. 2048 bits * Custom key types, e.g. ECC * Any number of intermediate CAs (but see limitations below) * Multiple trusted root CAs in `/var/lib/icinga2/certs/ca.crt` * Different root CAs per cluster subtree, as long as each node trusts the certificate issuers of all nodes it's directly connected to Intermediate CA restrictions: * Each side has to provide its intermediate CAs along with the leaf certificate in `/var/lib/icinga2/certs/NODENAME.crt`, ordered from leaf to root. * Intermediate CAs may not be used directly as root CAs. To trust only specific intermediate CAs, cross-sign them with themselves, so that you get equal certificates except that they're self-signed. Use them as root CAs in Icinga. ## Automation These hints should get you started with your own automation tools (Puppet, Ansible, Chef, Salt, etc.) or custom scripts for automated setup. These are collected best practices from various community channels. * [Silent Windows setup](06-distributed-monitoring.md#distributed-monitoring-automation-windows-silent) * [Node Setup CLI command](06-distributed-monitoring.md#distributed-monitoring-automation-cli-node-setup) with parameters If you prefer an alternate method, we still recommend leaving all the Icinga 2 features intact (e.g. `icinga2 feature enable api`). You should also use well known and documented default configuration file locations (e.g. `zones.conf`). This will tremendously help when someone is trying to help in the [community channels](https://icinga.com/community/). ### Silent Windows Setup If you want to install the agent silently/unattended, use the `/qn` modifier. The installation should not trigger a restart, but if you want to be completely sure, you can use the `/norestart` modifier. ``` C:> msiexec /i C:\Icinga2-v2.5.0-x86.msi /qn /norestart ``` Once the setup is completed you can use the `node setup` cli command too. ### Node Setup using CLI Parameters Instead of using the `node wizard` CLI command, there is an alternative `node setup` command available which has some prerequisites. **Note**: The CLI command can be used on Linux/Unix and Windows operating systems. The graphical Windows setup wizard actively uses these CLI commands. #### Node Setup on the Master Node In case you want to setup a master node you must add the `--master` parameter to the `node setup` CLI command. In addition to that the `--cn` can optionally be passed (defaults to the FQDN). Parameter | Description --------------------|-------------------- `--cn` | **Optional.** Common name (CN). By convention this should be the host's FQDN. Defaults to the FQDN. `--zone` | **Optional.** Zone name. Defaults to `master`. `--listen` | **Optional.** Address to listen on. Syntax is `host,port`. `--disable-confd` | **Optional.** If provided, this disables the `include_recursive "conf.d"` directive and adds the `api-users.conf` file inclusion to `icinga2.conf`. Available since v2.9+. Not set by default for compatibility reasons with Puppet, Ansible, Chef, etc. Example: ``` [root@icinga2-master1.localdomain /]# icinga2 node setup --master ``` In case you want to bind the `ApiListener` object to a specific host/port you can specify it like this: ``` --listen 192.68.56.101,5665 ``` In case you don't need anything in `conf.d`, use the following command line: ``` [root@icinga2-master1.localdomain /]# icinga2 node setup --master --disable-confd ``` #### Node Setup with Agents/Satellites ##### Preparations Make sure that the `/var/lib/icinga2/certs` directory exists and is owned by the `icinga` user (or the user Icinga 2 is running as). ``` [root@icinga2-agent1.localdomain /]# mkdir -p /var/lib/icinga2/certs [root@icinga2-agent1.localdomain /]# chown -R icinga:icinga /var/lib/icinga2/certs ``` First you'll need to generate a new local self-signed certificate. Pass the following details to the `pki new-cert` CLI command: Parameter | Description --------------------|-------------------- `--cn` | **Required.** Common name (CN). By convention this should be the host's FQDN. `--key`, `--file` | **Required.** Client certificate files. These generated files will be put into the specified location. By convention this should be using `/var/lib/icinga2/certs` as directory. Example: ``` [root@icinga2-agent1.localdomain /]# icinga2 pki new-cert --cn icinga2-agent1.localdomain \ --key /var/lib/icinga2/certs/icinga2-agent1.localdomain.key \ --cert /var/lib/icinga2/certs/icinga2-agent1.localdomain.crt ``` ##### Verify Parent Connection In order to verify the parent connection and avoid man-in-the-middle attacks, fetch the parent instance's certificate and verify that it matches the connection. The `trusted-parent.crt` file is a temporary file passed to `node setup` in the next step and does not need to be stored for later usage. Pass the following details to the `pki save-cert` CLI command: Parameter | Description --------------------|-------------------- `--trustedcert` | **Required.** Store the parent's certificate file. Manually verify that you're trusting it. `--host` | **Required.** FQDN or IP address of the parent host. Request the master certificate from the master host (`icinga2-master1.localdomain`) and store it as `trusted-parent.crt`. Review it and continue. ``` [root@icinga2-agent1.localdomain /]# icinga2 pki save-cert \ --trustedcert /var/lib/icinga2/certs/trusted-parent.crt \ --host icinga2-master1.localdomain information/cli: Retrieving TLS certificate for 'icinga2-master1.localdomain:5665'. Subject: CN = icinga2-master1.localdomain Issuer: CN = icinga2-master1.localdomain Valid From: Feb 4 08:59:05 2020 GMT Valid Until: Jan 31 08:59:05 2035 GMT Fingerprint: B4 90 DE 46 81 DD 2E BF EE 9D D5 47 61 43 EF C6 6D 86 A6 CC *** *** You have to ensure that this certificate actually matches the parent *** instance's certificate in order to avoid man-in-the-middle attacks. *** information/pki: Writing certificate to file '/var/lib/icinga2/certs/trusted-parent.crt'. ``` ##### Node Setup Continue with the additional `node setup` step. Specify a local endpoint and zone name (`icinga2-agent1.localdomain`) and set the master host (`icinga2-master1.localdomain`) as parent zone configuration. Specify the path to the previously stored trusted parent certificate (`trusted-parent.crt`). Pass the following details to the `node setup` CLI command: Parameter | Description --------------------|-------------------- `--cn` | **Optional.** Common name (CN). By convention this should be the host's FQDN. `--ticket` | **Required.** Request ticket. Add the previously generated [ticket number](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing). `--trustedcert` | **Required.** Trusted parent certificate file as connection verification (received via 'pki save-cert'). `--parent_host` | **Optional.** FQDN or IP address of the parent host. This is where the command connects for CSR signing. If not specified, you need to manually copy the parent's public CA certificate file into `/var/lib/icinga2/certs/ca.crt` in order to start Icinga 2. `--endpoint` | **Required.** Specifies the parent's endpoint name. `--zone` | **Required.** Specifies the agent/satellite zone name. `--parent_zone` | **Optional.** Specifies the parent's zone name. `--accept-config` | **Optional.** Whether this node accepts configuration sync from the master node (required for [config sync mode](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync)). `--accept-commands` | **Optional.** Whether this node accepts command execution messages from the master node (required for [command endpoint mode](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint)). `--global_zones` | **Optional.** Allows to specify more global zones in addition to `global-templates` and `director-global`. `--disable-confd` | **Optional.** If provided, this disables the `include_recursive "conf.d"` directive in `icinga2.conf`. Available since v2.9+. Not set by default for compatibility reasons with Puppet, Ansible, Chef, etc. > **Note** > > The `master_host` parameter is deprecated and will be removed. Please use `--parent_host` instead. Example: ``` [root@icinga2-agent1.localdomain /]# icinga2 node setup --ticket ead2d570e18c78abf285d6b85524970a0f69c22d \ --cn icinga2-agent1.localdomain \ --endpoint icinga2-master1.localdomain \ --zone icinga2-agent1.localdomain \ --parent_zone master \ --parent_host icinga2-master1.localdomain \ --trustedcert /var/lib/icinga2/certs/trusted-parent.crt \ --accept-commands --accept-config \ --disable-confd ``` In case the agent/satellite should connect to the master node, you'll need to modify the `--endpoint` parameter using the format `cn,host,port`: ``` --endpoint icinga2-master1.localdomain,192.168.56.101,5665 ``` Specify the parent zone using the `--parent_zone` parameter. This is useful if the agent connects to a satellite, not the master instance. ``` --parent_zone satellite ``` In case the agent should know the additional global zone `linux-templates`, you'll need to set the `--global-zones` parameter. ``` --global_zones linux-templates ``` The `--parent-host` parameter is optional since v2.9 and allows you to perform a connection-less setup. You cannot restart Icinga 2 yet, the CLI command asked to to manually copy the parent's public CA certificate file in `/var/lib/icinga2/certs/ca.crt`. Once Icinga 2 is started, it sends a ticket signing request to the parent node. If you have provided a ticket, the master node signs the request and sends it back to the agent/satellite which performs a certificate update in-memory. In case you did not provide a ticket, you need to [manually sign the CSR on the master node](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing-master) which holds the CA's key pair. **You can find additional best practices below.** If this agent node is configured as [remote command endpoint execution](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) you can safely disable the `checker` feature. The `node setup` CLI command already disabled the `notification` feature. ``` [root@icinga2-agent1.localdomain /]# icinga2 feature disable checker ``` **Optional**: Add an ApiUser object configuration for remote troubleshooting. ``` [root@icinga2-agent1.localdomain /]# cat </etc/icinga2/conf.d/api-users.conf object ApiUser "root" { password = "agentsupersecretpassword" permissions = ["*"] } EOF ``` Finally restart Icinga 2. ``` [root@icinga2-agent1.localdomain /]# systemctl restart icinga2 ``` Your automation tool must then configure master node in the meantime. ``` # cat <>/etc/icinga2/zones.conf object Endpoint "icinga2-agent1.localdomain" { // Agent connects itself } object Zone "icinga2-agent1.localdomain" { endpoints = [ "icinga2-agent1.localdomain" ] parent = "master" } EOF ``` ## Using Multiple Environments > **Note** > > This documentation only covers the basics. Full functionality requires a not yet released addon. In some cases it can be desired to run multiple Icinga instances on the same host. Two potential scenarios include: * Different versions of the same monitoring configuration (e.g. production and testing) * Disparate sets of checks for entirely unrelated monitoring environments (e.g. infrastructure and applications) The configuration is done with the global constants `ApiBindHost` and `ApiBindPort` or the `bind_host` and `bind_port` attributes of the [ApiListener](09-object-types.md#objecttype-apilistener) object. The environment must be set with the global constant `Environment` or as object attribute of the [IcingaApplication](09-object-types.md#objecttype-icingaapplication) object. In any case the constant is default value for the attribute and the direct configuration in the objects have more precedence. The constants have been added to allow the values being set from the CLI on startup. When Icinga establishes a TLS connection to another cluster instance it automatically uses the [SNI extension](https://en.wikipedia.org/wiki/Server_Name_Indication) to signal which endpoint it is attempting to connect to. On its own this can already be used to position multiple Icinga instances behind a load balancer. SNI example: `icinga2-agent1.localdomain` However, if the environment is configured to `production`, Icinga appends the environment name to the SNI hostname like this: SNI example with environment: `icinga2-agent1.localdomain:production` Middleware like loadbalancers or TLS proxies can read the SNI header and route the connection to the appropriate target. I.e., it uses a single externally-visible TCP port (usually 5665) and forwards connections to one or more Icinga instances which are bound to a local TCP port. It does so by inspecting the environment name that is sent as part of the SNI extension. icinga2-2.14.6/doc/07-agent-based-monitoring.md000066400000000000000000000401341501332562400207730ustar00rootroot00000000000000# Agent-based Checks If the remote services are not directly accessible through the network, a local agent installation exposing the results to check queries can become handy. Prior to installing and configuration an agent service, evaluate possible options based on these requirements: * Security (authentication, TLS certificates, secure connection handling, etc.) * Connection direction * Master/satellite can execute commands directly or * Agent sends back passive/external check results * Availability on specific OS types and versions * Packages available * Configuration and initial setup * Updates and maintenance, compatibility Available agent types: * [Icinga Agent](07-agent-based-monitoring.md#agent-based-checks-icinga) on Linux/Unix and Windows * [SSH](07-agent-based-monitoring.md#agent-based-checks-ssh) on Linux/Unix * [SNMP](07-agent-based-monitoring.md#agent-based-checks-snmp) on Linux/Unix and hardware * [SNMP Traps](07-agent-based-monitoring.md#agent-based-checks-snmp-traps) as passive check results * [REST API](07-agent-based-monitoring.md#agent-based-checks-rest-api) for passive external check results * [NSClient++](07-agent-based-monitoring.md#agent-based-checks-nsclient) and [WMI](07-agent-based-monitoring.md#agent-based-checks-wmi) on Windows ## Icinga Agent For the most common setups on Linux/Unix and Windows, we recommend to setup the Icinga agent in a [distributed environment](06-distributed-monitoring.md#distributed-monitoring). ![Icinga 2 Distributed Master with Agents](images/distributed-monitoring/icinga2_distributed_monitoring_scenarios_master_with_agents.png) Key benefits: * Directly integrated into the distributed monitoring stack of Icinga * Works on Linux/Unix and Windows * Secure communication with TLS * Connection can be established from both sides. Once connected, command execution and check results are exchanged. * Master/satellite connects to agent * Agent connects to parent satellite/master * Same configuration language and binaries * Troubleshooting docs and community best practices Follow the setup and configuration instructions [here](06-distributed-monitoring.md#distributed-monitoring-setup-agent-satellite). On Windows hosts, the Icinga agent can query a local NSClient++ service for additional checks in case there are no plugins available. ![Icinga 2 Windows Setup](images/distributed-monitoring/icinga2_windows_setup_wizard_01.png) ## SSH > **Tip** > > This is the recommended way for systems where the Icinga agent is not available > Be it specific hardware architectures, old systems or forbidden to install an additional software. This method uses the SSH service on the remote host to execute an arbitrary plugin command line. The output and exit code is returned and used by the core. The `check_by_ssh` plugin takes care of this. It is available in the [Monitoring Plugins](https://www.monitoring-plugins.org/) package. For your convenience, the Icinga template library provides the [by_ssh](10-icinga-template-library.md#plugin-check-command-by-ssh) CheckCommand already. ### SSH: Preparations SSH key pair for the Icinga daemon user. In case the user has no shell, temporarily enable this. When asked for a passphrase, **do not set it** and press enter. ```bash sudo su - icinga ssh-keygen -b 4096 -t rsa -C "icinga@$(hostname) user for check_by_ssh" -f $HOME/.ssh/id_rsa ``` On the remote agent, create the icinga user and generate a temporary password. ```bash useradd -m icinga passwd icinga ``` Copy the public key from the Icinga server to the remote agent, e.g. with `ssh-copy-id` or manually into `/home/icinga/.ssh/authorized_keys`. This will ask for the password once. ```bash sudo su - icinga ssh-copy-id -i $HOME/.ssh/id_rsa icinga@ssh-agent1.localdomain ``` After the SSH key is copied, test at the connection **at least once** and accept the host key verification. If you forget about this step, checks will become UNKNOWN later. ```bash ssh -i $HOME/.ssh/id_rsa icinga@ssh-agent1.localdomain ``` After the SSH key login works, disable the previously enabled logins. * Remote agent user's password with `passwd -l icinga` * Local icinga user terminal Also, ensure that the permissions are correct for the `.ssh` directory as otherwise logins will fail. * `.ssh` directory: 700 * `.ssh/id_rsa.pub` public key file: 644 * `.ssh/id_rsa` private key file: 600 ### SSH: Configuration First, create a host object which has SSH configured and enabled. Mark this e.g. with the custom variable `agent_type` to later use this for service apply rule matches. Best practice is to store that in a specific template, either in the static configuration or inside the Director. ``` template Host "ssh-agent" { check_command = "hostalive" vars.agent_type = "ssh" vars.os_type = "linux" } object Host "ssh-agent1.localdomain" { import "ssh-agent" address = "192.168.56.115" } ``` Example for monitoring the remote users: ``` apply Service "users" { check_command = "by_ssh" vars.by_ssh_command = [ "/usr/lib/nagios/plugins/check_users" ] // Follows the same principle as with command arguments, e.g. for ordering vars.by_ssh_arguments = { "-w" = { value = "$users_wgreater$" // Can reference an existing custom variable defined on the host or service, evaluated at runtime } "-c" = { value = "$users_cgreater$" } } vars.users_wgreater = 3 vars.users_cgreater = 5 assign where host.vars.os_type == "linux" && host.vars.agent_type == "ssh" } ``` A more advanced example with better arguments is shown in [this blogpost](https://www.netways.de/blog/2016/03/21/check_by_ssh-mit-icinga-2/). ## SNMP The SNMP daemon runs on the remote system and answers SNMP queries by plugin scripts. The [Monitoring Plugins](https://www.monitoring-plugins.org/) package provides the `check_snmp` plugin binary, but there are plenty of [existing plugins](05-service-monitoring.md#service-monitoring-plugins) for specific use cases already around, for example monitoring Cisco routers. The following example uses the [SNMP ITL](10-icinga-template-library.md#plugin-check-command-snmp) CheckCommand and sets the `snmp_oid` custom variable. A service is created for all hosts which have the `snmp-community` custom variable. ``` template Host "snmp-agent" { check_command = "hostalive" vars.agent_type = "snmp" vars.snmp_community = "public-icinga" } object Host "snmp-agent1.localdomain" { import "snmp-agent" } ``` ``` apply Service "uptime" { import "generic-service" check_command = "snmp" vars.snmp_oid = "1.3.6.1.2.1.1.3.0" vars.snmp_miblist = "DISMAN-EVENT-MIB" assign where host.vars.agent_type == "snmp" && host.vars.snmp_community != "" } ``` If no `snmp_miblist` is specified, the plugin will default to `ALL`. As the number of available MIB files on the system increases so will the load generated by this plugin if no `MIB` is specified. As such, it is recommended to always specify at least one `MIB`. Additional SNMP plugins are available using the [Manubulon SNMP Plugins](10-icinga-template-library.md#snmp-manubulon-plugin-check-commands). For network monitoring, community members advise to use [nwc_health](05-service-monitoring.md#service-monitoring-network) for example. ## SNMP Traps and Passive Check Results SNMP Traps can be received and filtered by using [SNMPTT](http://snmptt.sourceforge.net/) and specific trap handlers passing the check results to Icinga 2. Following the SNMPTT [Format](http://snmptt.sourceforge.net/docs/snmptt.shtml#SNMPTT.CONF-FORMAT) documentation and the Icinga external command syntax found [here](24-appendix.md#external-commands-list-detail) we can create generic services that can accommodate any number of hosts for a given scenario. ### Simple SNMP Traps A simple example might be monitoring host reboots indicated by an SNMP agent reset. Building the event to auto reset after dispatching a notification is important. Setup the manual check parameters to reset the event from an initial unhandled state or from a missed reset event. Add a directive in `snmptt.conf` ``` EVENT coldStart .1.3.6.1.6.3.1.1.5.1 "Status Events" Normal FORMAT Device reinitialized (coldStart) EXEC echo "[$@] PROCESS_SERVICE_CHECK_RESULT;$A;Coldstart;2;The snmp agent has reinitialized." >> /var/run/icinga2/cmd/icinga2.cmd SDESC A coldStart trap signifies that the SNMPv2 entity, acting in an agent role, is reinitializing itself and that its configuration may have been altered. EDESC ``` 1. Define the `EVENT` as per your need. 2. Construct the `EXEC` statement with the service name matching your template applied to your _n_ hosts. The host address inferred by SNMPTT will be the correlating factor. You can have snmptt provide host names or ip addresses to match your Icinga convention. > **Note** > > Replace the deprecated command pipe EXEC statement with a curl call > to the REST API action [process-check-result](12-icinga2-api.md#icinga2-api-actions-process-check-result). Add an `EventCommand` configuration object for the passive service auto reset event. ``` object EventCommand "coldstart-reset-event" { command = [ ConfigDir + "/conf.d/custom/scripts/coldstart_reset_event.sh" ] arguments = { "-i" = "$service.state_id$" "-n" = "$host.name$" "-s" = "$service.name$" } } ``` Create the `coldstart_reset_event.sh` shell script to pass the expanded variable data in. The `$service.state_id$` is important in order to prevent an endless loop of event firing after the service has been reset. ```bash #!/bin/bash SERVICE_STATE_ID="" HOST_NAME="" SERVICE_NAME="" show_help() { cat <<-EOF Usage: ${0##*/} [-h] -n HOST_NAME -s SERVICE_NAME Writes a coldstart reset event to the Icinga command pipe. -h Display this help and exit. -i SERVICE_STATE_ID The associated service state id. -n HOST_NAME The associated host name. -s SERVICE_NAME The associated service name. EOF } while getopts "hi:n:s:" opt; do case "$opt" in h) show_help exit 0 ;; i) SERVICE_STATE_ID=$OPTARG ;; n) HOST_NAME=$OPTARG ;; s) SERVICE_NAME=$OPTARG ;; '?') show_help exit 0 ;; esac done if [ -z "$SERVICE_STATE_ID" ]; then show_help printf "\n Error: -i required.\n" exit 1 fi if [ -z "$HOST_NAME" ]; then show_help printf "\n Error: -n required.\n" exit 1 fi if [ -z "$SERVICE_NAME" ]; then show_help printf "\n Error: -s required.\n" exit 1 fi if [ "$SERVICE_STATE_ID" -gt 0 ]; then echo "[`date +%s`] PROCESS_SERVICE_CHECK_RESULT;$HOST_NAME;$SERVICE_NAME;0;Auto-reset (`date +"%m-%d-%Y %T"`)." >> /var/run/icinga2/cmd/icinga2.cmd fi ``` > **Note** > > Replace the deprecated command pipe EXEC statement with a curl call > to the REST API action [process-check-result](12-icinga2-api.md#icinga2-api-actions-process-check-result). Finally create the `Service` and assign it: ``` apply Service "Coldstart" { import "generic-service-custom" check_command = "dummy" event_command = "coldstart-reset-event" enable_notifications = 1 enable_active_checks = 0 enable_passive_checks = 1 enable_flapping = 0 volatile = 1 enable_perfdata = 0 vars.dummy_state = 0 vars.dummy_text = "Manual reset." vars.sla = "24x7" assign where (host.vars.os == "Linux" || host.vars.os == "Windows") } ``` ### Complex SNMP Traps A more complex example might be passing dynamic data from a traps varbind list for a backup scenario where the backup software dispatches status updates. By utilizing active and passive checks, the older freshness concept can be leveraged. By defining the active check as a hard failed state, a missed backup can be reported. As long as the most recent passive update has occurred, the active check is bypassed. Add a directive in `snmptt.conf` ``` EVENT enterpriseSpecific "Status Events" Normal FORMAT Enterprise specific trap EXEC echo "[$@] PROCESS_SERVICE_CHECK_RESULT;$A;$1;$2;$3" >> /var/run/icinga2/cmd/icinga2.cmd SDESC An enterprise specific trap. The varbinds in order denote the Icinga service name, state and text. EDESC ``` 1. Define the `EVENT` as per your need using your actual oid. 2. The service name, state and text are extracted from the first three varbinds. This has the advantage of accommodating an unlimited set of use cases. > **Note** > > Replace the deprecated command pipe EXEC statement with a curl call > to the REST API action [process-check-result](12-icinga2-api.md#icinga2-api-actions-process-check-result). Create a `Service` for the specific use case associated to the host. If the host matches and the first varbind value is `Backup`, SNMPTT will submit the corresponding passive update with the state and text from the second and third varbind: ``` object Service "Backup" { import "generic-service-custom" host_name = "host.domain.com" check_command = "dummy" enable_notifications = 1 enable_active_checks = 1 enable_passive_checks = 1 enable_flapping = 0 volatile = 1 max_check_attempts = 1 check_interval = 87000 enable_perfdata = 0 vars.sla = "24x7" vars.dummy_state = 2 vars.dummy_text = "No passive check result received." } ``` ## Agents sending Check Results via REST API Whenever the remote agent cannot run the Icinga agent, or a backup script should just send its current state after finishing, you can use the [REST API](12-icinga2-api.md#icinga2-api) as secure transport and send [passive external check results](08-advanced-topics.md#external-check-results). Use the [process-check-result](12-icinga2-api.md#icinga2-api-actions-process-check-result) API action to send the external passive check result. You can either use `curl` or implement the HTTP requests in your preferred programming language. Examples for API clients are available in [this chapter](12-icinga2-api.md#icinga2-api-clients). Feeding check results from remote hosts requires the host/service objects configured on the master/satellite instance. ## NSClient++ on Windows [NSClient++](https://nsclient.org/) works on both Windows and Linux platforms and is well known for its magnificent Windows support. There are alternatives like the WMI interface, but using `NSClient++` will allow you to run local scripts similar to check plugins fetching the required output and performance counters. > **Tip** > > Best practice is to use the Icinga agent as secure execution > bridge (`check_nt` and `check_nrpe` are considered insecure) > and query the NSClient++ service [locally](06-distributed-monitoring.md#distributed-monitoring-windows-nscp). You can use the `check_nt` plugin from the Monitoring Plugins project to query NSClient++. Icinga 2 provides the [nscp check command](10-icinga-template-library.md#plugin-check-command-nscp) for this: Example: ``` object Service "disk" { import "generic-service" host_name = "remote-windows-host" check_command = "nscp" vars.nscp_variable = "USEDDISKSPACE" vars.nscp_params = "c" vars.nscp_warn = 70 vars.nscp_crit = 80 } ``` For details on the `NSClient++` configuration please refer to the [official documentation](https://docs.nsclient.org/). ## WMI on Windows The most popular plugin is [check_wmi_plus](https://edcint.co.nz/checkwmiplus/). > Check WMI Plus uses the Windows Management Interface (WMI) to check for common services (cpu, disk, sevices, eventlog…) on Windows machines. It requires the open source wmi client for Linux. Community examples: * [Icinga 2 check_wmi_plus example by 18pct](https://18pct.com/icinga2-check_wmi_plus-example/) * [Agent-less monitoring with WMI](https://www.devlink.de/linux/icinga2-nagios-agentless-monitoring-von-windows/) icinga2-2.14.6/doc/08-advanced-topics.md000066400000000000000000001351241501332562400175070ustar00rootroot00000000000000# Advanced Topics This chapter covers a number of advanced topics. If you're new to Icinga, you can safely skip over things you're not interested in. ## Downtimes Downtimes can be scheduled for planned server maintenance or any other targeted service outage you are aware of in advance. Downtimes suppress notifications and can trigger other downtimes too. If the downtime was set by accident, or the duration exceeds the maintenance windows, you can manually cancel the downtime. ### Scheduling a downtime The most convenient way to schedule planned downtimes is to create them in Icinga Web 2 inside the host/service detail view. Select multiple hosts/services from the listing with the shift key to schedule multiple downtimes. ![Downtime in Icinga Web 2](images/advanced-topics/icingaweb2_downtime_handled.png) In addition to that you can schedule a downtime by using the Icinga 2 API action [schedule-downtime](12-icinga2-api.md#icinga2-api-actions-schedule-downtime). This is especially useful to schedule a downtime on-demand inside a (remote) backup script, or create maintenance downtimes from a cron job for specific dates and intervals. Multiple downtimes for a single object may overlap. This is useful when you want to extend your maintenance window taking longer than expected. If there are multiple downtimes triggered for one object, the overall downtime depth will be greater than `1`. If the downtime was scheduled after the problem changed to a critical hard state triggering a problem notification, and the service recovers during the downtime window, the recovery notification won't be suppressed. Planned downtimes are also taken into account for SLA reporting tools calculating the SLAs based on the state and downtime history. ### Fixed and Flexible Downtimes A `fixed` downtime will be activated at the defined start time, and removed at the end time. During this time window the service state will change to `NOT-OK` and then actually trigger the downtime. Notifications are suppressed and the downtime depth is incremented. Common scenarios are a planned distribution upgrade on your linux servers, or database updates in your warehouse. The customer knows about a fixed downtime window between 23:00 and 24:00. After 24:00 all problems should be alerted again. Solution is simple - schedule a `fixed` downtime starting at 23:00 and ending at 24:00. Unlike a `fixed` downtime, a `flexible` downtime will be triggered by the state change in the time span defined by start and end time, and then last for the specified duration in minutes. Imagine the following scenario: Your service is frequently polled by users trying to grab free deleted domains for immediate registration. Between 07:30 and 08:00 the impact will hit for 15 minutes and generate a network outage visible to the monitoring. The service is still alive, but answering too slow to Icinga 2 service checks. For that reason, you may want to schedule a downtime between 07:30 and 08:00 with a duration of 15 minutes. The downtime will then last from its trigger time until the duration is over. After that, the downtime is removed (may happen before or after the actual end time!). #### Fixed Downtime If the host/service changes into a NOT-OK state between the start and end time window, the downtime will be marked as `in effect` and increases the downtime depth counter. ``` | | | start | end trigger time ``` #### Flexible Downtime A flexible downtime defines a time window where the downtime may be triggered from a host/service NOT-OK state change. It will then last until the specified time duration is reached. That way it can happen that the downtime end time is already gone, but the downtime ends at `trigger time + duration`. ``` | | | start | end actual end time |--------------duration--------| trigger time ``` ### Triggered Downtimes This is optional when scheduling a downtime. If there is already a downtime scheduled for a future maintenance, the current downtime can be triggered by that downtime. This renders useful if you have scheduled a host downtime and are now scheduling a child host's downtime getting triggered by the parent downtime on `NOT-OK` state change. ### Recurring Downtimes [ScheduledDowntime objects](09-object-types.md#objecttype-scheduleddowntime) can be used to set up recurring downtimes for services. Example: ``` apply ScheduledDowntime "backup-downtime" to Service { author = "icingaadmin" comment = "Scheduled downtime for backup" ranges = { monday = "02:00-03:00" tuesday = "02:00-03:00" wednesday = "02:00-03:00" thursday = "02:00-03:00" friday = "02:00-03:00" saturday = "02:00-03:00" sunday = "02:00-03:00" } assign where "backup" in service.groups } ``` Icinga 2 attempts to find the next possible segment from a ScheduledDowntime object's `ranges` attribute, and wont create multiple downtimes in the future. In case you need all these downtimes planned and visible for the next days, weeks or months, schedule them manually via the [REST API](12-icinga2-api.md#icinga2-api-actions-schedule-downtime) using a script or cron job. > **Note** > > If ScheduledDowntime objects are synced in a distributed high-availability setup, > both will create the next possible downtime on their own. These runtime generated > downtimes are synced among both zone instances, and you may see sort-of duplicate downtimes > in Icinga Web 2. ## Comments Comments can be added at runtime and are persistent over restarts. You can add useful information for others on repeating incidents (for example "last time syslog at 100% cpu on 17.10.2013 due to stale nfs mount") which is primarily accessible using web interfaces. You can add a comment either by using the Icinga 2 API action [add-comment](12-icinga2-api.md#icinga2-api-actions-add-comment) or by sending an [external command](14-features.md#external-commands). ## Acknowledgements If a problem persists and notifications have been sent, you can acknowledge the problem. That way other users will get a notification that you're aware of the issue and probably are already working on a fix. Note: Acknowledgements also add a new [comment](08-advanced-topics.md#comments-intro) which contains the author and text fields. You can send an acknowledgement either by using the Icinga 2 API action [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) or by sending an [external command](14-features.md#external-commands). ### Sticky Acknowledgements The acknowledgement is removed if a state change occurs or if the host/service recovers (OK/Up state). If you acknowledge a problem once you've received a `Critical` notification, the acknowledgement will be removed if there is a state transition to `Warning`. ``` OK -> WARNING -> CRITICAL -> WARNING -> OK ``` If you prefer to keep the acknowledgement until the problem is resolved (`OK` recovery) you need to enable the `sticky` parameter. ### Expiring Acknowledgements Once a problem is acknowledged it may disappear from your `handled problems` dashboard and no-one ever looks at it again since it will suppress notifications too. This `fire-and-forget` action is quite common. If you're sure that a current problem should be resolved in the future at a defined time, you can define an expiration time when acknowledging the problem. Icinga 2 will clear the acknowledgement when expired and start to re-notify, if the problem persists. ## Time Periods [Time Periods](09-object-types.md#objecttype-timeperiod) define time ranges in Icinga where event actions are triggered, for example whether a service check is executed or not within the `check_period` attribute. Or a notification should be sent to users or not, filtered by the `period` and `notification_period` configuration attributes for `Notification` and `User` objects. The `TimePeriod` attribute `ranges` may contain multiple directives, including weekdays, days of the month, and calendar dates. These types may overlap/override other types in your ranges dictionary. The descending order of precedence is as follows: * Calendar date (2008-01-01) * Specific month date (January 1st) * Generic month date (Day 15) * Offset weekday of specific month (2nd Tuesday in December) * Offset weekday (3rd Monday) * Normal weekday (Tuesday) If you don't set any `check_period` or `notification_period` attribute on your configuration objects, Icinga 2 assumes `24x7` as time period as shown below. ``` object TimePeriod "24x7" { display_name = "Icinga 2 24x7 TimePeriod" ranges = { "monday" = "00:00-24:00" "tuesday" = "00:00-24:00" "wednesday" = "00:00-24:00" "thursday" = "00:00-24:00" "friday" = "00:00-24:00" "saturday" = "00:00-24:00" "sunday" = "00:00-24:00" } } ``` If your operation staff should only be notified during workhours, create a new timeperiod named `workhours` defining a work day from 09:00 to 17:00. ``` object TimePeriod "workhours" { display_name = "Icinga 2 8x5 TimePeriod" ranges = { "monday" = "09:00-17:00" "tuesday" = "09:00-17:00" "wednesday" = "09:00-17:00" "thursday" = "09:00-17:00" "friday" = "09:00-17:00" } } ``` ### Across midnight If you want to specify a notification period across midnight, you can define it the following way: ``` object TimePeriod "across-midnight" { display_name = "Nightly Notification" ranges = { "saturday" = "22:00-24:00" "sunday" = "00:00-03:00" } } ``` Starting with v2.11 this can be shortened to using the first day as start with an overlapping range into the next day: ``` object TimePeriod "do-not-disturb" { display_name = "Weekend DND" ranges = { "saturday" = "22:00-06:00" } } ``` ### Across several days, weeks or months Below you can see another example for configuring timeperiods across several days, weeks or months. This can be useful when taking components offline for a distinct period of time. ``` object TimePeriod "standby" { display_name = "Standby" ranges = { "2016-09-30 - 2016-10-30" = "00:00-24:00" } } ``` Please note that the spaces before and after the dash are mandatory. Once your time period is configured you can Use the `period` attribute to assign time periods to `Notification` and `Dependency` objects: ``` apply Notification "mail-icingaadmin" to Service { import "mail-service-notification" user_groups = host.vars.notification.mail.groups users = host.vars.notification.mail.users period = "workhours" assign where host.vars.notification.mail } ``` ### Time Periods Inclusion and Exclusion Sometimes it is necessary to exclude certain time ranges from your default time period definitions, for example, if you don't want to send out any notification during the holiday season, or if you only want to allow small time windows for executed checks. The [TimePeriod object](09-object-types.md#objecttype-timeperiod) provides the `includes` and `excludes` attributes to solve this issue. `prefer_includes` defines whether included or excluded time periods are preferred. The following example defines a time period called `holidays` where notifications should be suppressed: ``` object TimePeriod "holidays" { ranges = { "january 1" = "00:00-24:00" //new year's day "july 4" = "00:00-24:00" //independence day "december 25" = "00:00-24:00" //christmas "december 31" = "18:00-24:00" //new year's eve (6pm+) "2017-04-16" = "00:00-24:00" //easter 2017 "monday -1 may" = "00:00-24:00" //memorial day (last monday in may) "monday 1 september" = "00:00-24:00" //labor day (1st monday in september) "thursday 4 november" = "00:00-24:00" //thanksgiving (4th thursday in november) } } ``` In addition to that the time period `weekends` defines an additional time window which should be excluded from notifications: ``` object TimePeriod "weekends-excluded" { ranges = { "saturday" = "00:00-09:00,18:00-24:00" "sunday" = "00:00-09:00,18:00-24:00" } } ``` The time period `prod-notification` defines the default time ranges and adds the excluded time period names as an array. ``` object TimePeriod "prod-notification" { excludes = [ "holidays", "weekends-excluded" ] ranges = { "monday" = "00:00-24:00" "tuesday" = "00:00-24:00" "wednesday" = "00:00-24:00" "thursday" = "00:00-24:00" "friday" = "00:00-24:00" "saturday" = "00:00-24:00" "sunday" = "00:00-24:00" } } ``` ### Time zone handling Icinga 2 takes the OS' time zone including DST changes into account. Times inside DST changes are interpreted as before the DST changes. I.e. for the time zone Europe/Berlin: * On 2020-10-25 03:00 CEST the time jumps back to 02:00 CET. For Icinga 02:30 means 02:30 CEST. * On 2021-02-28 02:00 CET the time jumps forward to 03:00 CEST. For Icinga (the actually not existing) 02:30 refers to CET and effectively means 03:30 CEST. ## External Passive Check Results Hosts or services which do not actively execute a check plugin to receive the state and output are called "passive checks" or "external check results". In this scenario an external client or script is sending in check results. You can feed check results into Icinga 2 with the following transport methods: * [process-check-result action](12-icinga2-api.md#icinga2-api-actions-process-check-result) available with the [REST API](12-icinga2-api.md#icinga2-api) (remote and local) * External command sent via command pipe (local only) Each time a new check result is received, the next expected check time is updated. This means that if there are no check result received from the external source, Icinga 2 will execute [freshness checks](08-advanced-topics.md#check-result-freshness). > **Note** > > The REST API action allows to specify the `check_source` attribute > which helps identifying the external sender. This is also visible > in Icinga Web 2 and the REST API queries. ## Check Result Freshness In Icinga 2 active check freshness is enabled by default. It is determined by the `check_interval` attribute and no incoming check results in that period of time. The threshold is calculated based on the last check execution time for actively executed checks: ``` (last check execution time + check interval) > current time ``` If this host/service receives check results from an [external source](08-advanced-topics.md#external-check-results), the threshold is based on the last time a check result was received: ``` (last check result time + check interval) > current time ``` > **Tip** > > The [process-check-result](12-icinga2-api.md#icinga2-api-actions-process-check-result) REST API > action allows to overrule the pre-defined check interval with a specified TTL in Icinga 2 v2.9+. If the freshness checks fail, Icinga 2 will execute the defined check command unless active checks are disabled. Best practice is to define a [dummy](10-icinga-template-library.md#itl-dummy) `check_command` which gets executed when freshness checks fail. ``` apply Service "external-check" { check_command = "dummy" check_interval = 1m /* Set the state to UNKNOWN (3) if freshness checks fail. */ vars.dummy_state = 3 /* Use a runtime function to retrieve the last check time and more details. */ vars.dummy_text = {{ var service = get_service(macro("$host.name$"), macro("$service.name$")) var lastCheck = DateTime(service.last_check).to_string() return "No check results received. Last result time: " + lastCheck }} assign where "external" in host.vars.services } ``` References: [get_service](18-library-reference.md#objref-get_service), [macro](18-library-reference.md#scoped-functions-macro), [DateTime](18-library-reference.md#datetime-type). Example output in Icinga Web 2: ![Icinga 2 Freshness Checks](images/advanced-topics/icinga2_external_checks_freshness_icingaweb2.png) ## Check Flapping Icinga 2 supports optional detection of hosts and services that are "flapping". Flapping occurs when a service or host changes state too frequently, which would result in a storm of problem and recovery notifications. With flapping detection enabled a flapping notification will be sent while other notifications are suppressed until it calms down after receiving the same status from checks a few times. Flapping detection can help detect configuration problems (wrong thresholds), troublesome services or network problems. Flapping detection can be enabled or disabled using the `enable_flapping` attribute. The `flapping_threshold_high` and `flapping_threshold_low` attributes allows to specify the thresholds that control when a [host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) is considered to be flapping. The default thresholds are 30% for high and 25% for low. If the computed flapping value exceeds the high threshold a host or service is considered flapping until it drops below the low flapping threshold. The attribute `flapping_ignore_states` allows to ignore state changes to specified states during the flapping calculation. `FlappingStart` and `FlappingEnd` notifications will be sent out accordingly, if configured. See the chapter on [notifications](03-monitoring-basics.md#notifications) for details > Note: There is no distinctions between hard and soft states with flapping. All state changes count and notifications > will be sent out regardless of the objects state. ### How it works Icinga 2 saves the last 20 state changes for every host and service. See the graphic below: ![Icinga 2 Flapping State Timeline](images/advanced-topics/flapping-state-graph.png) All the states are weighted, with the most recent one being worth the most (1.15) and the 20th the least (0.8). The states in between are fairly distributed. The final flapping value are the weighted state changes divided by the total count of 20. In the example above, the added states would have a total value of 7.82 (`0.84 + 0.86 + 0.88 + 0.9 + 0.98 + 1.06 + 1.12 + 1.18`). This yields a flapping percentage of 39.1% (`7.82 / 20 * 100`). As the default upper flapping threshold is 30%, it would be considered flapping. If the next seven check results then would not be state changes, the flapping percentage would fall below the lower threshold of 25% and therefore the host or service would recover from flapping. ## Volatile Services and Hosts The `volatile` option, if enabled for a host or service, makes it treat every [state change](03-monitoring-basics.md#hard-soft-states) as a `HARD` state change. It is comparable to `max_check_attempts = 1`. With this any `NOT-OK` result will ignore `max_check_attempts` and trigger notifications etc. It will further cause any additional `NOT-OK` result to re-send notifications. It may be reasonable to have a volatile service which stays in a `HARD` state if the service stays in a `NOT-OK` state. That way each service recheck will automatically trigger a notification unless the service is acknowledged or in a scheduled downtime. A common example are security checks where each `NOT-OK` check result should immediately trigger a notification. The default for this option is `false` and should only be enabled when required. ## Monitoring Icinga 2 Why should you do that? Icinga and its components run like any other service application on your server. There are predictable issues such as "disk space is running low" and your monitoring suffers from just that. You would also like to ensure that features and backends are running and storing required data. Be it the database backend where Icinga Web 2 presents fancy dashboards, forwarded metrics to Graphite or InfluxDB or the entire distributed setup. This list isn't complete but should help with your own setup. Windows client specific checks are highlighted. Type | Description | Plugins and CheckCommands ----------------|-------------------------------|----------------------------------------------------- System | Filesystem | [disk](10-icinga-template-library.md#plugin-check-command-disk), [disk-windows](10-icinga-template-library.md#windows-plugins) (Windows Client) System | Memory, Swap | [mem](10-icinga-template-library.md#plugin-contrib-command-mem), [swap](10-icinga-template-library.md#plugin-check-command-swap), [memory](10-icinga-template-library.md#windows-plugins) (Windows Client) System | Hardware | [hpasm](10-icinga-template-library.md#plugin-contrib-command-hpasm), [ipmi-sensor](10-icinga-template-library.md#plugin-contrib-command-ipmi-sensor) System | Virtualization | [VMware](10-icinga-template-library.md#plugin-contrib-vmware), [esxi_hardware](10-icinga-template-library.md#plugin-contrib-command-esxi-hardware) System | Processes | [procs](10-icinga-template-library.md#plugin-check-command-processes), [service-windows](10-icinga-template-library.md#windows-plugins) (Windows Client) System | System Activity Reports | [sar-perf](10-icinga-template-library.md#plugin-contrib-command-sar-perf) System | I/O | [iostat](10-icinga-template-library.md#plugin-contrib-command-iostat) System | Network interfaces | [nwc_health](10-icinga-template-library.md#plugin-contrib-command-nwc_health), [interfaces](10-icinga-template-library.md#plugin-contrib-command-interfaces) System | Users | [users](10-icinga-template-library.md#plugin-check-command-users), [users-windows](10-icinga-template-library.md#windows-plugins) (Windows Client) System | Logs | Forward them to [Elastic Stack](14-features.md#elastic-stack-integration) or [Graylog](14-features.md#graylog-integration) and add your own alerts. System | NTP | [ntp_time](10-icinga-template-library.md#plugin-check-command-ntp-time) System | Updates | [apt](10-icinga-template-library.md#plugin-check-command-apt), [yum](10-icinga-template-library.md#plugin-contrib-command-yum) Icinga | Status & Stats | [icinga](10-icinga-template-library.md#itl-icinga) (more below) Icinga | Cluster & Clients | [health checks](06-distributed-monitoring.md#distributed-monitoring-health-checks) Database | MySQL | [mysql_health](10-icinga-template-library.md#plugin-contrib-command-mysql_health) Database | PostgreSQL | [postgres](10-icinga-template-library.md#plugin-contrib-command-postgres) Database | Housekeeping | Check the database size and growth and analyse metrics to examine trends. Database | DB IDO | [ido](10-icinga-template-library.md#itl-icinga-ido) (more below) Webserver | Apache2, Nginx, etc. | [http](10-icinga-template-library.md#plugin-check-command-http), [apache-status](10-icinga-template-library.md#plugin-contrib-command-apache-status), [nginx_status](10-icinga-template-library.md#plugin-contrib-command-nginx_status) Webserver | Certificates | [http](10-icinga-template-library.md#plugin-check-command-http), [Icinga certificate monitoring](https://icinga.com/products/icinga-certificate-monitoring/) Webserver | Authorization | [http](10-icinga-template-library.md#plugin-check-command-http) Notifications | Mail (queue) | [smtp](10-icinga-template-library.md#plugin-check-command-smtp), [mailq](10-icinga-template-library.md#plugin-check-command-mailq) Notifications | SMS (GSM modem) | [check_sms3_status](https://exchange.icinga.com/netways/check_sms3status) Notifications | Messengers, Cloud services | XMPP, Twitter, IRC, Telegram, PagerDuty, VictorOps, etc. Metrics | PNP, RRDTool | [check_pnp_rrds](https://github.com/lingej/pnp4nagios/tree/master/scripts) checks for stale RRD files. Metrics | Graphite | [graphite](10-icinga-template-library.md#plugin-contrib-command-graphite) Metrics | InfluxDB | [check_influxdb](https://exchange.icinga.com/Mikanoshi/InfluxDB+data+monitoring+plugin) Metrics | Elastic Stack | [elasticsearch](10-icinga-template-library.md#plugin-contrib-command-elasticsearch), [Elastic Stack integration](14-features.md#elastic-stack-integration) Metrics | Graylog | [Graylog integration](14-features.md#graylog-integration) The [icinga](10-icinga-template-library.md#itl-icinga) CheckCommand provides metrics for the runtime stats of Icinga 2. You can forward them to your preferred graphing solution. If you require more metrics you can also query the [REST API](12-icinga2-api.md#icinga2-api) and write your own custom check plugin. Or you keep using the built-in [object accessor functions](08-advanced-topics.md#access-object-attributes-at-runtime) to calculate stats in-memory. There is a built-in [ido](10-icinga-template-library.md#itl-icinga-ido) check available for DB IDO MySQL/PostgreSQL which provides additional metrics for the IDO database. ``` apply Service "ido-mysql" { check_command = "ido" vars.ido_type = "IdoMysqlConnection" vars.ido_name = "ido-mysql" //the name defined in /etc/icinga2/features-enabled/ido-mysql.conf assign where match("master*.localdomain", host.name) } ``` More specific database queries can be found in the [DB IDO](14-features.md#db-ido) chapter. Distributed setups should include specific [health checks](06-distributed-monitoring.md#distributed-monitoring-health-checks). You might also want to add additional checks for TLS certificate expiration. This can be done using the [Icinga certificate monitoring](https://icinga.com/products/icinga-certificate-monitoring/) module. ## Advanced Configuration Hints ### Advanced Use of Apply Rules [Apply rules](03-monitoring-basics.md#using-apply) can be used to create a rule set which is entirely based on host objects and their attributes. In addition to that [apply for and custom variable override](03-monitoring-basics.md#using-apply-for) extend the possibilities. The following example defines a dictionary on the host object which contains configuration attributes for multiple web servers. This then used to add three checks: * A `ping4` check using the local IP `address` of the web server. * A `tcp` check querying the TCP port where the HTTP service is running on. * If the `url` key is defined, the third apply for rule will create service objects using the `http` CheckCommand. In addition to that you can optionally define the `ssl` attribute which enables HTTPS checks. Host definition: ``` object Host "webserver01" { import "generic-host" address = "192.168.56.200" vars.os = "Linux" vars.webserver = { instance["status"] = { address = "192.168.56.201" port = "80" url = "/status" } instance["tomcat"] = { address = "192.168.56.202" port = "8080" } instance["icingaweb2"] = { address = "192.168.56.210" port = "443" url = "/icingaweb2" ssl = true } } } ``` Service apply for definitions: ``` apply Service "webserver_ping" for (instance => config in host.vars.webserver.instance) { display_name = "webserver_" + instance check_command = "ping4" vars.ping_address = config.address assign where host.vars.webserver.instance } apply Service "webserver_port" for (instance => config in host.vars.webserver.instance) { display_name = "webserver_" + instance + "_" + config.port check_command = "tcp" vars.tcp_address = config.address vars.tcp_port = config.port assign where host.vars.webserver.instance } apply Service "webserver_url" for (instance => config in host.vars.webserver.instance) { display_name = "webserver_" + instance + "_" + config.url check_command = "http" vars.http_address = config.address vars.http_port = config.port vars.http_uri = config.url if (config.ssl) { vars.http_ssl = config.ssl } assign where config.url != "" } ``` The variables defined in the host dictionary are not using the typical custom variable prefix recommended for CheckCommand parameters. Instead they are re-used for multiple service checks in this example. In addition to defining check parameters this way, you can also enrich the `display_name` attribute with more details. This will be shown in in Icinga Web 2 for example. ### Use Functions in Object Configuration There is a limited scope where functions can be used as object attributes such as: * As value for [Custom Variables](03-monitoring-basics.md#custom-variables-functions) * Returning boolean expressions for [set_if](08-advanced-topics.md#use-functions-command-arguments-setif) inside command arguments * Returning a [command](08-advanced-topics.md#use-functions-command-attribute) array inside command objects The other way around you can create objects dynamically using your own global functions. > **Note** > > Functions called inside command objects share the same global scope as runtime macros. > Therefore you can access host custom variables like `host.vars.os`, or any other > object attribute from inside the function definition used for [set_if](08-advanced-topics.md#use-functions-command-arguments-setif) or [command](08-advanced-topics.md#use-functions-command-attribute). Tips when implementing functions: * Use [log()](18-library-reference.md#global-functions-log) to dump variables. You can see the output inside the `icinga2.log` file depending in your log severity * Use the `icinga2 console` to test basic functionality (e.g. iterating over a dictionary) * Build them step-by-step. You can always refactor your code later on. #### Register and Use Global Functions [Functions](17-language-reference.md#functions) can be registered into the global scope. This allows custom functions being available in objects and other functions. Keep in mind that these functions are not marked as side-effect-free and as such are not available via the REST API. Add a new configuration file `functions.conf` and include it into the [icinga2.conf](04-configuration.md#icinga2-conf) configuration file in the very beginning, e.g. after `constants.conf`. You can also manage global functions inside `constants.conf` if you prefer. The following function converts a given state parameter into a returned string value. The important bits for registering it into the global scope are: * `globals.` adds a new globals entry. * `function()` specifies that a call to `state_to_string()` executes a function. * Function parameters are defined inside the `function()` definition. ``` globals.state_to_string = function(state) { if (state == 2) { return "Critical" } else if (state == 1) { return "Warning" } else if (state == 0) { return "OK" } else if (state == 3) { return "Unknown" } else { log(LogWarning, "state_to_string", "Unknown state " + state + " provided.") } } ``` The else-condition allows for better error handling. This warning will be shown in the Icinga 2 log file once the function is called. > **Note** > > If these functions are used in a distributed environment, you must ensure to deploy them > everywhere needed. In order to test-drive the newly created function, restart Icinga 2 and use the [debug console](11-cli-commands.md#cli-command-console) to connect to the REST API. ``` $ ICINGA2_API_PASSWORD=icinga icinga2 console --connect 'https://root@localhost:5665/' Icinga 2 (version: v2.11.0) <1> => globals.state_to_string(1) "Warning" <2> => state_to_string(2) "Critical" ``` You can see that this function is now registered into the [global scope](17-language-reference.md#variable-scopes). The function call `state_to_string()` can be used in any object at static config compile time or inside runtime lambda functions. The following service object example uses the service state and converts it to string output. The function definition is not optimized and is enrolled for better readability including a log message. ``` object Service "state-test" { check_command = "dummy" host_name = NodeName vars.dummy_state = 2 vars.dummy_text = {{ var h = macro("$host.name$") var s = macro("$service.name$") var state = get_service(h, s).state log(LogInformation, "dummy_state", "Host: " + h + " Service: " + s + " State: " + state) return state_to_string(state) }} } ``` #### Use Custom Functions as Attribute To use custom functions as attributes, the function must be defined in a slightly unexpected way. The following example shows how to assign values depending on group membership. All hosts in the `slow-lan` host group use 300 as value for `ping_wrta`, all other hosts use 100. ``` globals.group_specific_value = function(group, group_value, non_group_value) { return function() use (group, group_value, non_group_value) { if (group in host.groups) { return group_value } else { return non_group_value } } } apply Service "ping4" { import "generic-service" check_command = "ping4" vars.ping_wrta = group_specific_value("slow-lan", 300, 100) vars.ping_crta = group_specific_value("slow-lan", 500, 200) assign where true } ``` #### Use Functions in Assign Where Expressions If a simple expression for matching a name or checking if an item exists in an array or dictionary does not fit, you should consider writing your own global [functions](17-language-reference.md#functions). You can call them inside `assign where` and `ignore where` expressions for [apply rules](03-monitoring-basics.md#using-apply-expressions) or [group assignments](03-monitoring-basics.md#group-assign-intro) just like any other global functions for example [match](18-library-reference.md#global-functions-match). The following example requires the host `myprinter` being added to the host group `printers-lexmark` but only if the host uses a template matching the name `lexmark*`. ``` template Host "lexmark-printer-host" { vars.printer_type = "Lexmark" } object Host "myprinter" { import "generic-host" import "lexmark-printer-host" address = "192.168.1.1" } /* register a global function for the assign where call */ globals.check_host_templates = function(host, search) { /* iterate over all host templates and check if the search matches */ for (tmpl in host.templates) { if (match(search, tmpl)) { return true } } /* nothing matched */ return false } object HostGroup "printers-lexmark" { display_name = "Lexmark Printers" /* call the global function and pass the arguments */ assign where check_host_templates(host, "lexmark*") } ``` Take a different more complex example: All hosts with the custom variable `vars_app` as nested dictionary should be added to the host group `ABAP-app-server`. But only if the `app_type` for all entries is set to `ABAP`. It could read as wildcard match for nested dictionaries: ``` where host.vars.vars_app["*"].app_type == "ABAP" ``` The solution for this problem is to register a global function which checks the `app_type` for all hosts with the `vars_app` dictionary. ``` object Host "appserver01" { check_command = "dummy" vars.vars_app["ABC"] = { app_type = "ABAP" } } object Host "appserver02" { check_command = "dummy" vars.vars_app["DEF"] = { app_type = "ABAP" } } globals.check_app_type = function(host, type) { /* ensure that other hosts without the custom variable do not match */ if (typeof(host.vars.vars_app) != Dictionary) { return false } /* iterate over the vars_app dictionary */ for (key => val in host.vars.vars_app) { /* if the value is a dictionary and if contains the app_type being the requested type */ if (typeof(val) == Dictionary && val.app_type == type) { return true } } /* nothing matched */ return false } object HostGroup "ABAP-app-server" { assign where check_app_type(host, "ABAP") } ``` #### Use Functions in Command Arguments set_if The `set_if` attribute inside the command arguments definition in the [CheckCommand object definition](09-object-types.md#objecttype-checkcommand) is primarily used to evaluate whether the command parameter should be set or not. By default you can evaluate runtime macros for their existence. If the result is not an empty string, the command parameter is passed. This becomes fairly complicated when want to evaluate multiple conditions and attributes. The following example was found on the community support channels. The user had defined a host dictionary named `compellent` with the key `disks`. This was then used inside service apply for rules. ``` object Host "dict-host" { check_command = "check_compellent" vars.compellent["disks"] = { file = "/var/lib/check_compellent/san_disks.0.json", checks = ["disks"] } } ``` The more significant problem was to only add the command parameter `--disk` to the plugin call when the dictionary `compellent` contains the key `disks`, and omit it if not found. By defining `set_if` as [abbreviated lambda function](17-language-reference.md#nullary-lambdas) and evaluating the host custom variable `compellent` containing the `disks` this problem was solved like this: ``` object CheckCommand "check_compellent" { command = [ "/usr/bin/check_compellent" ] arguments = { "--disks" = { set_if = {{ var host_vars = host.vars log(host_vars) var compel = host_vars.compellent log(compel) compel.contains("disks") }} } } } ``` This implementation uses the dictionary type method [contains](18-library-reference.md#dictionary-contains) and will fail if `host.vars.compellent` is not of the type `Dictionary`. Therefore you can extend the checks using the [typeof](17-language-reference.md#types) function. You can test the types using the `icinga2 console`: ``` # icinga2 console Icinga (version: v2.3.0-193-g3eb55ad) <1> => srv_vars.compellent["check_a"] = { file="outfile_a.json", checks = [ "disks", "fans" ] } null <2> => srv_vars.compellent["check_b"] = { file="outfile_b.json", checks = [ "power", "voltages" ] } null <3> => typeof(srv_vars.compellent) type 'Dictionary' <4> => ``` The more programmatic approach for `set_if` could look like this: ``` "--disks" = { set_if = {{ var srv_vars = service.vars if(len(srv_vars) > 0) { if (typeof(srv_vars.compellent) == Dictionary) { return srv_vars.compellent.contains("disks") } else { log(LogInformation, "checkcommand set_if", "custom variable compellent_checks is not a dictionary, ignoring it.") return false } } else { log(LogWarning, "checkcommand set_if", "empty custom variables") return false } }} } ``` #### Use Functions as Command Attribute This comes in handy for [NotificationCommands](09-object-types.md#objecttype-notificationcommand) or [EventCommands](09-object-types.md#objecttype-eventcommand) which does not require a returned checkresult including state/output. The following example was taken from the community support channels. The requirement was to specify a custom variable inside the notification apply rule and decide which notification script to call based on that. ``` object User "short-dummy" { } object UserGroup "short-dummy-group" { assign where user.name == "short-dummy" } apply Notification "mail-admins-short" to Host { import "mail-host-notification" command = "mail-host-notification-test" user_groups = [ "short-dummy-group" ] vars.short = true assign where host.vars.notification.mail } ``` The solution is fairly simple: The `command` attribute is implemented as function returning an array required by the caller Icinga 2. The local variable `mailscript` sets the default value for the notification scrip location. If the notification custom variable `short` is set, it will override the local variable `mailscript` with a new value. The `mailscript` variable is then used to compute the final notification command array being returned. You can omit the `log()` calls, they only help debugging. ``` object NotificationCommand "mail-host-notification-test" { command = {{ log("command as function") var mailscript = "mail-host-notification-long.sh" if (notification.vars.short) { mailscript = "mail-host-notification-short.sh" } log("Running command") log(mailscript) var cmd = [ ConfigDir + "/scripts/" + mailscript ] log(LogCritical, "me", cmd) return cmd }} env = { } } ``` ### Access Object Attributes at Runtime The [Object Accessor Functions](18-library-reference.md#object-accessor-functions) can be used to retrieve references to other objects by name. This allows you to access configuration and runtime object attributes. A detailed list can be found [here](09-object-types.md#object-types). #### Access Object Attributes at Runtime: Cluster Check This is a simple cluster example for accessing two host object states and calculating a virtual cluster state and output: ``` object Host "cluster-host-01" { check_command = "dummy" vars.dummy_state = 2 vars.dummy_text = "This host is down." } object Host "cluster-host-02" { check_command = "dummy" vars.dummy_state = 0 vars.dummy_text = "This host is up." } object Host "cluster" { check_command = "dummy" vars.cluster_nodes = [ "cluster-host-01", "cluster-host-02" ] vars.dummy_state = {{ var up_count = 0 var down_count = 0 var cluster_nodes = macro("$cluster_nodes$") for (node in cluster_nodes) { if (get_host(node).state > 0) { down_count += 1 } else { up_count += 1 } } if (up_count >= down_count) { return 0 //same up as down -> UP } else { return 2 //something is broken } }} vars.dummy_text = {{ var output = "Cluster hosts:\n" var cluster_nodes = macro("$cluster_nodes$") for (node in cluster_nodes) { output += node + ": " + get_host(node).last_check_result.output + "\n" } return output }} } ``` #### Time Dependent Thresholds The following example sets time dependent thresholds for the load check based on the current time of the day compared to the defined time period. ``` object TimePeriod "backup" { ranges = { monday = "02:00-03:00" tuesday = "02:00-03:00" wednesday = "02:00-03:00" thursday = "02:00-03:00" friday = "02:00-03:00" saturday = "02:00-03:00" sunday = "02:00-03:00" } } object Host "webserver-with-backup" { check_command = "hostalive" address = "127.0.0.1" } object Service "webserver-backup-load" { check_command = "load" host_name = "webserver-with-backup" vars.load_wload1 = {{ if (get_time_period("backup").is_inside) { return 20 } else { return 5 } }} vars.load_cload1 = {{ if (get_time_period("backup").is_inside) { return 40 } else { return 10 } }} } ``` ## Advanced Value Types In addition to the default value types Icinga 2 also uses a few other types to represent its internal state. The following types are exposed via the [API](12-icinga2-api.md#icinga2-api). ### CheckResult Name | Type | Description --------------------------|-----------------------|---------------------------------- exit\_status | Number | The exit status returned by the check execution. output | String | The check output. performance\_data | Array | Array of [performance data values](08-advanced-topics.md#advanced-value-types-perfdatavalue). check\_source | String | Name of the node executing the check. scheduling\_source | String | Name of the node scheduling the check. state | Number | The current state (0 = OK, 1 = WARNING, 2 = CRITICAL, 3 = UNKNOWN). command | Value | Array of command with shell-escaped arguments or command line string. execution\_start | Timestamp | Check execution start time (as a UNIX timestamp). execution\_end | Timestamp | Check execution end time (as a UNIX timestamp). schedule\_start | Timestamp | Scheduled check execution start time (as a UNIX timestamp). schedule\_end | Timestamp | Scheduled check execution end time (as a UNIX timestamp). active | Boolean | Whether the result is from an active or passive check. vars\_before | Dictionary | Internal attribute used for calculations. vars\_after | Dictionary | Internal attribute used for calculations. ttl | Number | Time-to-live duration in seconds for this check result. The next expected check result is `now + ttl` where freshness checks are executed. ### PerfdataValue Icinga 2 parses performance data strings returned by check plugins and makes the information available to external interfaces (e.g. [GraphiteWriter](09-object-types.md#objecttype-graphitewriter) or the [Icinga 2 API](12-icinga2-api.md#icinga2-api)). Name | Type | Description --------------------------|-----------------------|---------------------------------- label | String | Performance data label. value | Number | Normalized performance data value without unit. counter | Boolean | Enabled if the original value contains `c` as unit. Defaults to `false`. unit | String | Unit of measurement (`seconds`, `bytes`. `percent`) according to the [plugin API](05-service-monitoring.md#service-monitoring-plugin-api). crit | Value | Critical threshold value. warn | Value | Warning threshold value. min | Value | Minimum value returned by the check. max | Value | Maximum value returned by the check. icinga2-2.14.6/doc/09-object-types.md000066400000000000000000003303701501332562400170540ustar00rootroot00000000000000# Object Types This chapter provides an overview of all available config object types which can be instantiated using the `object` keyword. Additional details on configuration and runtime attributes and their description are explained here too. The attributes need to have a specific type value. Many of them are explained in [this chapter](03-monitoring-basics.md#attribute-value-types) already. You should note that the `Timestamp` type is a `Number`. In addition to that `Object name` is an object reference to an existing object name as `String` type. ## Overview * [Monitoring Objects](09-object-types.md#object-types-monitoring) such as host, service, etc. * [Runtime Objects](09-object-types.md#object-types-runtime) generated by Icinga itself. * [Features](09-object-types.md#object-types-features) available via `icinga2 feature` CLI command. ## Common Runtime Attributes Configuration objects share these runtime attributes which cannot be modified by the user. You can access these attributes using the [Icinga 2 API](12-icinga2-api.md#icinga2-api-config-objects). Name | Type | Description --------------------------|-----------------------|---------------------------------- version | Number | Timestamp when the object was created or modified. Synced throughout cluster nodes. type | String | Object type. original\_attributes | Dictionary | Original values of object attributes modified at runtime. active | Boolean | Object is active (e.g. a service being checked). paused | Boolean | Object has been paused at runtime (e.g. [IdoMysqlConnection](09-object-types.md#objecttype-idomysqlconnection). Defaults to `false`. templates | Array | Templates imported on object compilation. package | String | [Configuration package name](12-icinga2-api.md#icinga2-api-config-management) this object belongs to. Local configuration is set to `_etc`, runtime created objects use `_api`. source\_location | Dictionary | Location information where the configuration files are stored. name | String | Object name. Might be used in [apply rules](03-monitoring-basics.md#using-apply). ## Monitoring Objects ### ApiUser ApiUser objects are used for authentication against the [Icinga 2 API](12-icinga2-api.md#icinga2-api-authentication). Example: ``` object ApiUser "root" { password = "mysecretapipassword" permissions = [ "*" ] } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- password | String | **Optional.** Password string. Note: This attribute is hidden in API responses. client\_cn | String | **Optional.** Client Common Name (CN). permissions | Array | **Required.** Array of permissions. Either as string or dictionary with the keys `permission` and `filter`. The latter must be specified as function. Available permissions are explained in the [API permissions](12-icinga2-api.md#icinga2-api-permissions) chapter. ### CheckCommand A check command definition. Additional default command custom variables can be defined here. Example: ``` object CheckCommand "http" { command = [ PluginDir + "/check_http" ] arguments = { "-H" = "$http_vhost$" "-I" = "$http_address$" "-u" = "$http_uri$" "-p" = "$http_port$" "-S" = { set_if = "$http_ssl$" } "--sni" = { set_if = "$http_sni$" } "-a" = { value = "$http_auth_pair$" description = "Username:password on sites with basic authentication" } "--no-body" = { set_if = "$http_ignore_body$" } "-r" = "$http_expect_body_regex$" "-w" = "$http_warn_time$" "-c" = "$http_critical_time$" "-e" = "$http_expect$" } vars.http_address = "$address$" vars.http_ssl = false vars.http_sni = false } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- command | Array | **Required.** The command. This can either be an array of individual command arguments. Alternatively a string can be specified in which case the shell interpreter (usually /bin/sh) takes care of parsing the command. When using the "arguments" attribute this must be an array. Can be specified as function for advanced implementations. env | Dictionary | **Optional.** A dictionary of macros which should be exported as environment variables prior to executing the command. vars | Dictionary | **Optional.** A dictionary containing custom variables that are specific to this command. timeout | Duration | **Optional.** The command timeout in seconds. Defaults to `1m`. arguments | Dictionary | **Optional.** A dictionary of command arguments. #### CheckCommand Arguments Command arguments can be defined as key-value-pairs in the `arguments` dictionary. Best practice is to assign a dictionary as value which provides additional details such as the `description` next to the `value`. ``` arguments = { "--parameter" = { description = "..." value = "..." } } ``` All available argument value entries are shown below: Name | Type | Description --------------------------|-----------------------|---------------------------------- value | String/Function | Optional argument value set by a [runtime macro string](03-monitoring-basics.md#runtime-macros) or a [function call](17-language-reference.md#functions). [More details](03-monitoring-basics.md#command-arguments-value). description | String | Optional argument description. [More details](03-monitoring-basics.md#command-arguments-description). required | Boolean | Required argument. Execution error if not set. Defaults to false (optional). [More details](03-monitoring-basics.md#command-arguments-required). skip\_key | Boolean | Use the value as argument and skip the key. [More details](03-monitoring-basics.md#command-arguments-skip-key). set\_if | String/Function | Argument is added if the [runtime macro string](03-monitoring-basics.md#runtime-macros) resolves to a defined numeric or boolean value. String values are not supported. [Function calls](17-language-reference.md#functions) returning a value are supported too. [More details](03-monitoring-basics.md#command-arguments-set-if). order | Number | Set if multiple arguments require a defined argument order. The syntax is `..., -3, -2, -1, , 1, 2, 3, ...`. [More details](03-monitoring-basics.md#command-arguments-order). repeat\_key | Boolean | If the argument value is an array, repeat the argument key, or not. Defaults to true (repeat). [More details](03-monitoring-basics.md#command-arguments-repeat-key). key | String | Optional argument key overriding the key identifier. [More details](03-monitoring-basics.md#command-arguments-key). separator | String | Key-value separator. If given, e.g. `=`, appears between key and value like `--key=value` instead of the regular `--key` `value`. `value` and `description` are commonly used, the other entries allow to build more advanced CheckCommand objects and arguments. Please continue reading [here](03-monitoring-basics.md#command-arguments) for advanced usage and examples for command arguments. ### Dependency Dependency objects are used to specify dependencies between hosts and services. Dependencies can be defined as Host-to-Host, Service-to-Service, Service-to-Host, or Host-to-Service relations. > **Best Practice** > > Rather than creating a `Dependency` object for a specific host or service it is usually easier > to just create a `Dependency` template and use the `apply` keyword to assign the > dependency to a number of hosts or services. Use the `to` keyword to set the specific target > type for `Host` or `Service`. > Check the [dependencies](03-monitoring-basics.md#dependencies) chapter for detailed examples. Service-to-Service Example: ``` object Dependency "webserver-internet" { parent_host_name = "internet" parent_service_name = "ping4" child_host_name = "webserver" child_service_name = "ping4" states = [ OK, Warning ] disable_checks = true } ``` Host-to-Host Example: ``` object Dependency "webserver-internet" { parent_host_name = "internet" child_host_name = "webserver" states = [ Up ] disable_checks = true } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- parent\_host\_name | Object name | **Required.** The parent host. parent\_service\_name | Object name | **Optional.** The parent service. If omitted, this dependency object is treated as host dependency. child\_host\_name | Object name | **Required.** The child host. child\_service\_name | Object name | **Optional.** The child service. If omitted, this dependency object is treated as host dependency. redundancy\_group | String | **Optional.** Puts the dependency into a group of [mutually redundant ones](03-monitoring-basics.md#dependencies-redundancy-groups). disable\_checks | Boolean | **Optional.** Whether to disable checks (i.e., don't schedule active checks and drop passive results) when this dependency fails. Defaults to false. disable\_notifications | Boolean | **Optional.** Whether to disable notifications when this dependency fails. Defaults to true. ignore\_soft\_states | Boolean | **Optional.** Whether to ignore soft states for the reachability calculation. Defaults to true. period | Object name | **Optional.** Time period object during which this dependency is enabled. states | Array | **Optional.** A list of state filters when this dependency should be OK. Defaults to [ OK, Warning ] for services and [ Up ] for hosts. Available state filters: ``` OK Warning Critical Unknown Up Down ``` When using [apply rules](03-monitoring-basics.md#using-apply) for dependencies, you can leave out certain attributes which will be automatically determined by Icinga 2. Service-to-Host Dependency Example: ``` apply Dependency "internet" to Service { parent_host_name = "dsl-router" disable_checks = true assign where host.name != "dsl-router" } ``` This example sets all service objects matching the assign condition into a dependency relation to the parent host object `dsl-router` as implicit child services. Service-to-Service-on-the-same-Host Dependency Example: ``` apply Dependency "disable-agent-checks" to Service { parent_service_name = "agent-health" assign where service.check_command == "ssh" ignore where service.name == "agent-health" } ``` This example omits the `parent_host_name` attribute and Icinga 2 automatically sets its value to the name of the host object matched by the apply rule condition. All services where apply matches are made implicit child services in this dependency relation. Dependency objects have composite names, i.e. their names are based on the `child_host_name` and `child_service_name` attributes and the name you specified. This means you can define more than one object with the same (short) name as long as one of the `child_host_name` and `child_service_name` attributes has a different value. ### Endpoint Endpoint objects are used to specify connection information for remote Icinga 2 instances. More details can be found in the [distributed monitoring chapter](06-distributed-monitoring.md#distributed-monitoring). Example: ``` object Endpoint "icinga2-agent1.localdomain" { host = "192.168.56.111" port = 5665 log_duration = 1d } ``` Example (disable replay log): ``` object Endpoint "icinga2-agent1.localdomain" { host = "192.168.5.111" port = 5665 log_duration = 0 } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Optional.** The hostname/IP address of the remote Icinga 2 instance. port | Number | **Optional.** The service name/port of the remote Icinga 2 instance. Defaults to `5665`. log\_duration | Duration | **Optional.** Duration for keeping replay logs on connection loss. Defaults to `1d` (86400 seconds). Attribute is specified in seconds. If log_duration is set to 0, replaying logs is disabled. You could also specify the value in human readable format like `10m` for 10 minutes or `1h` for one hour. Endpoint objects cannot currently be created with the API. ### EventCommand An event command definition. Example: ``` object EventCommand "restart-httpd-event" { command = "/opt/bin/restart-httpd.sh" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- command | Array | **Required.** The command. This can either be an array of individual command arguments. Alternatively a string can be specified in which case the shell interpreter (usually /bin/sh) takes care of parsing the command. When using the "arguments" attribute this must be an array. Can be specified as function for advanced implementations. env | Dictionary | **Optional.** A dictionary of macros which should be exported as environment variables prior to executing the command. vars | Dictionary | **Optional.** A dictionary containing custom variables that are specific to this command. timeout | Duration | **Optional.** The command timeout in seconds. Defaults to `1m`. arguments | Dictionary | **Optional.** A dictionary of command arguments. Command arguments can be used the same way as for [CheckCommand objects](09-object-types.md#objecttype-checkcommand-arguments). More advanced examples for event command usage can be found [here](03-monitoring-basics.md#event-commands). ### Host A host. Example: ``` object Host "icinga2-agent1.localdomain" { display_name = "Linux Client 1" address = "192.168.56.111" address6 = "2a00:1450:4001:815::2003" groups = [ "linux-servers" ] check_command = "hostalive" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- display\_name | String | **Optional.** A short description of the host (e.g. displayed by external interfaces instead of the name if set). address | String | **Optional.** The host's IPv4 address. Available as command runtime macro `$address$` if set. address6 | String | **Optional.** The host's IPv6 address. Available as command runtime macro `$address6$` if set. groups | Array of object names | **Optional.** A list of host groups this host belongs to. vars | Dictionary | **Optional.** A dictionary containing custom variables that are specific to this host. check\_command | Object name | **Required.** The name of the check command. max\_check\_attempts | Number | **Optional.** The number of times a host is re-checked before changing into a hard state. Defaults to 3. check\_period | Object name | **Optional.** The name of a time period which determines when this host should be checked. Not set by default (effectively 24x7). check\_timeout | Duration | **Optional.** Check command timeout in seconds. Overrides the CheckCommand's `timeout` attribute. check\_interval | Duration | **Optional.** The check interval (in seconds). This interval is used for checks when the host is in a `HARD` state. Defaults to `5m`. retry\_interval | Duration | **Optional.** The retry interval (in seconds). This interval is used for checks when the host is in a `SOFT` state. Defaults to `1m`. Note: This does not affect the scheduling [after a passive check result](08-advanced-topics.md#check-result-freshness). enable\_notifications | Boolean | **Optional.** Whether notifications are enabled. Defaults to true. enable\_active\_checks | Boolean | **Optional.** Whether active checks are enabled. Defaults to true. enable\_passive\_checks | Boolean | **Optional.** Whether passive checks are enabled. Defaults to true. enable\_event\_handler | Boolean | **Optional.** Enables event handlers for this host. Defaults to true. enable\_flapping | Boolean | **Optional.** Whether flap detection is enabled. Defaults to false. enable\_perfdata | Boolean | **Optional.** Whether performance data processing is enabled. Defaults to true. event\_command | Object name | **Optional.** The name of an event command that should be executed every time the host's state changes or the host is in a `SOFT` state. flapping\_threshold\_high | Number | **Optional.** Flapping upper bound in percent for a host to be considered flapping. Default `30.0` flapping\_threshold\_low | Number | **Optional.** Flapping lower bound in percent for a host to be considered not flapping. Default `25.0` flapping\_ignore\_states | Array | **Optional.** A list of states that should be ignored during flapping calculation. By default no state is ignored. volatile | Boolean | **Optional.** Treat all state changes as HARD changes. See [here](08-advanced-topics.md#volatile-services-hosts) for details. Defaults to `false`. zone | Object name | **Optional.** The zone this object is a member of. Please read the [distributed monitoring](06-distributed-monitoring.md#distributed-monitoring) chapter for details. command\_endpoint | Object name | **Optional.** The endpoint where commands are executed on. notes | String | **Optional.** Notes for the host. notes\_url | String | **Optional.** URL for notes for the host (for example, in notification commands). action\_url | String | **Optional.** URL for actions for the host (for example, an external graphing tool). icon\_image | String | **Optional.** Icon image for the host. Used by external interfaces only. icon\_image\_alt | String | **Optional.** Icon image description for the host. Used by external interface only. The actual check interval might deviate slightly from the configured values due to the fact that Icinga tries to evenly distribute all checks over a certain period of time, i.e. to avoid load spikes. > **Best Practice** > > The `address` and `address6` attributes are required for running commands using > the `$address$` and `$address6$` runtime macros. Runtime Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- next\_check | Timestamp | When the next check occurs (as a UNIX timestamp). last\_check | Timestamp | When the last check occurred (as a UNIX timestamp). check\_attempt | Number | The current check attempt number. state\_type | Number | The current state type (0 = SOFT, 1 = HARD). last\_state\_type | Number | The previous state type (0 = SOFT, 1 = HARD). last\_reachable | Boolean | Whether the host was reachable when the last check occurred. last\_check\_result | CheckResult | The current [check result](08-advanced-topics.md#advanced-value-types-checkresult). last\_state\_change | Timestamp | When the last state change occurred (as a UNIX timestamp). last\_hard\_state\_change | Timestamp | When the last hard state change occurred (as a UNIX timestamp). acknowledgement | Number | The acknowledgement type (0 = NONE, 1 = NORMAL, 2 = STICKY). acknowledgement\_expiry | Timestamp | When the acknowledgement expires (as a UNIX timestamp; 0 = no expiry). downtime\_depth | Number | Whether the host has one or more active downtimes. flapping\_last\_change | Timestamp | When the last flapping change occurred (as a UNIX timestamp). flapping | Boolean | Whether the host is flapping between states. flapping\_current | Number | Current flapping value in percent (see flapping\_thresholds) state | Number | The current state (0 = UP, 1 = DOWN). last\_state | Number | The previous state (0 = UP, 1 = DOWN). last\_hard\_state | Number | The last hard state (0 = UP, 1 = DOWN). last\_state\_up | Timestamp | When the last UP state occurred (as a UNIX timestamp). last\_state\_down | Timestamp | When the last DOWN state occurred (as a UNIX timestamp). last\_state\_unreachable | Timestamp | When the host was unreachable the last time (as a UNIX timestamp). previous\_state\_change | Timestamp | Previous timestamp of `last_state_change` before processing a new check result. severity | Number | [Severity](19-technical-concepts.md#technical-concepts-checks-severity) calculated value. problem | Boolean | Whether the host is considered in a problem state type (NOT-UP). handled | Boolean | Whether the host problem is handled (downtime or acknowledgement). next\_update | Timestamp | When the next check update is to be expected. ### HostGroup A group of hosts. > **Best Practice** > > Assign host group members using the [group assign](17-language-reference.md#group-assign) rules. Example: ``` object HostGroup "linux-servers" { display_name = "Linux Servers" assign where host.vars.os == "Linux" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- display\_name | String | **Optional.** A short description of the host group. groups | Array of object names | **Optional.** An array of nested group names. ### Notification Notification objects are used to specify how users should be notified in case of host and service state changes and other events. > **Best Practice** > > Rather than creating a `Notification` object for a specific host or service it is > usually easier to just create a `Notification` template and use the `apply` keyword > to assign the notification to a number of hosts or services. Use the `to` keyword > to set the specific target type for `Host` or `Service`. > Check the [notifications](03-monitoring-basics.md#alert-notifications) chapter for detailed examples. Example: ``` object Notification "localhost-ping-notification" { host_name = "localhost" service_name = "ping4" command = "mail-notification" users = [ "user1", "user2" ] // reference to User objects types = [ Problem, Recovery ] states = [ Critical, Warning, OK ] } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host\_name | Object name | **Required.** The name of the host this notification belongs to. service\_name | Object name | **Optional.** The short name of the service this notification belongs to. If omitted, this notification object is treated as host notification. vars | Dictionary | **Optional.** A dictionary containing custom variables that are specific to this notification object. users | Array of object names | **Required.** A list of user names who should be notified. **Optional.** if the `user_groups` attribute is set. user\_groups | Array of object names | **Required.** A list of user group names who should be notified. **Optional.** if the `users` attribute is set. times | Dictionary | **Optional.** A dictionary containing `begin` and `end` attributes for the notification. If `end` is set to 0, `Notifications` are disabled permanently. Please read the [notification delay](03-monitoring-basics.md#notification-delay) chapter for details. command | Object name | **Required.** The name of the notification command which should be executed when the notification is triggered. interval | Duration | **Optional.** The notification interval (in seconds). This interval is used for active notifications. Defaults to 30 minutes. If set to 0, [re-notifications](03-monitoring-basics.md#disable-renotification) are disabled. period | Object name | **Optional.** The name of a time period which determines when this notification should be triggered. Not set by default (effectively 24x7). zone | Object name | **Optional.** The zone this object is a member of. Please read the [distributed monitoring](06-distributed-monitoring.md#distributed-monitoring) chapter for details. types | Array | **Optional.** A list of type filters when this notification should be triggered. By default everything is matched. states | Array | **Optional.** A list of state filters when this notification should be triggered. By default everything is matched. Note that the states filter is ignored for notifications of type Acknowledgement! Available notification state filters for Service: ``` OK Warning Critical Unknown ``` Available notification state filters for Host: ``` Up Down ``` Available notification type filters: ``` DowntimeStart DowntimeEnd DowntimeRemoved Custom Acknowledgement Problem Recovery FlappingStart FlappingEnd ``` Runtime Attributes: Name | Type | Description ----------------------------|-----------------------|----------------- last\_notification | Timestamp | When the last notification was sent for this Notification object (as a UNIX timestamp). next\_notification | Timestamp | When the next notification is going to be sent for this assuming the associated host/service is still in a non-OK state (as a UNIX timestamp). notification\_number | Number | The notification number. last\_problem\_notification | Timestamp | When the last notification was sent for a problem (as a UNIX timestamp). ### NotificationCommand A notification command definition. Example: ``` object NotificationCommand "mail-service-notification" { command = [ ConfigDir + "/scripts/mail-service-notification.sh" ] arguments += { "-4" = { required = true value = "$notification_address$" } "-6" = "$notification_address6$" "-b" = "$notification_author$" "-c" = "$notification_comment$" "-d" = { required = true value = "$notification_date$" } "-e" = { required = true value = "$notification_servicename$" } "-f" = { value = "$notification_from$" description = "Set from address. Requires GNU mailutils (Debian/Ubuntu) or mailx (RHEL/SUSE)" } "-i" = "$notification_icingaweb2url$" "-l" = { required = true value = "$notification_hostname$" } "-n" = { required = true value = "$notification_hostdisplayname$" } "-o" = { required = true value = "$notification_serviceoutput$" } "-r" = { required = true value = "$notification_useremail$" } "-s" = { required = true value = "$notification_servicestate$" } "-t" = { required = true value = "$notification_type$" } "-u" = { required = true value = "$notification_servicedisplayname$" } "-v" = "$notification_logtosyslog$" } vars += { notification_address = "$address$" notification_address6 = "$address6$" notification_author = "$notification.author$" notification_comment = "$notification.comment$" notification_type = "$notification.type$" notification_date = "$icinga.long_date_time$" notification_hostname = "$host.name$" notification_hostdisplayname = "$host.display_name$" notification_servicename = "$service.name$" notification_serviceoutput = "$service.output$" notification_servicestate = "$service.state$" notification_useremail = "$user.email$" notification_servicedisplayname = "$service.display_name$" } } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- command | Array | **Required.** The command. This can either be an array of individual command arguments. Alternatively a string can be specified in which case the shell interpreter (usually /bin/sh) takes care of parsing the command. When using the "arguments" attribute this must be an array. Can be specified as function for advanced implementations. env | Dictionary | **Optional.** A dictionary of macros which should be exported as environment variables prior to executing the command. vars | Dictionary | **Optional.** A dictionary containing custom variables that are specific to this command. timeout | Duration | **Optional.** The command timeout in seconds. Defaults to `1m`. arguments | Dictionary | **Optional.** A dictionary of command arguments. Command arguments can be used the same way as for [CheckCommand objects](09-object-types.md#objecttype-checkcommand-arguments). More details on specific attributes can be found in [this chapter](03-monitoring-basics.md#notification-commands). ### ScheduledDowntime ScheduledDowntime objects can be used to set up recurring downtimes for hosts/services. > **Best Practice** > > Rather than creating a `ScheduledDowntime` object for a specific host or service it is usually easier > to just create a `ScheduledDowntime` template and use the `apply` keyword to assign the > scheduled downtime to a number of hosts or services. Use the `to` keyword to set the specific target > type for `Host` or `Service`. > Check the [recurring downtimes](08-advanced-topics.md#recurring-downtimes) example for details. Example: ``` object ScheduledDowntime "some-downtime" { host_name = "localhost" service_name = "ping4" author = "icingaadmin" comment = "Some comment" fixed = false duration = 30m ranges = { "sunday" = "02:00-03:00" } } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host\_name | Object name | **Required.** The name of the host this scheduled downtime belongs to. service\_name | Object name | **Optional.** The short name of the service this scheduled downtime belongs to. If omitted, this downtime object is treated as host downtime. author | String | **Required.** The author of the downtime. comment | String | **Required.** A comment for the downtime. fixed | Boolean | **Optional.** Whether this is a fixed downtime. Defaults to `true`. duration | Duration | **Optional.** How long the downtime lasts. Only has an effect for flexible (non-fixed) downtimes. ranges | Dictionary | **Required.** A dictionary containing information which days and durations apply to this timeperiod. child\_options | String | **Optional.** Schedule child downtimes. `DowntimeNoChildren` does not do anything, `DowntimeTriggeredChildren` schedules child downtimes triggered by this downtime, `DowntimeNonTriggeredChildren` schedules non-triggered downtimes. Defaults to `DowntimeNoChildren`. ScheduledDowntime objects have composite names, i.e. their names are based on the `host_name` and `service_name` attributes and the name you specified. This means you can define more than one object with the same (short) name as long as one of the `host_name` and `service_name` attributes has a different value. See also [time zone handling](08-advanced-topics.md#timeperiods-timezones). ### Service Service objects describe network services and how they should be checked by Icinga 2. > **Best Practice** > > Rather than creating a `Service` object for a specific host it is usually easier > to just create a `Service` template and use the `apply` keyword to assign the > service to a number of hosts. > Check the [apply](03-monitoring-basics.md#using-apply) chapter for details. Example: ``` object Service "uptime" { host_name = "localhost" display_name = "localhost Uptime" check_command = "snmp" vars.snmp_community = "public" vars.snmp_oid = "DISMAN-EVENT-MIB::sysUpTimeInstance" check_interval = 60s retry_interval = 15s groups = [ "all-services", "snmp" ] } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- display\_name | String | **Optional.** A short description of the service. host\_name | Object name | **Required.** The host this service belongs to. There must be a `Host` object with that name. groups | Array of object names | **Optional.** The service groups this service belongs to. vars | Dictionary | **Optional.** A dictionary containing custom variables that are specific to this service. check\_command | Object name | **Required.** The name of the check command. max\_check\_attempts | Number | **Optional.** The number of times a service is re-checked before changing into a hard state. Defaults to 3. check\_period | Object name | **Optional.** The name of a time period which determines when this service should be checked. Not set by default (effectively 24x7). check\_timeout | Duration | **Optional.** Check command timeout in seconds. Overrides the CheckCommand's `timeout` attribute. check\_interval | Duration | **Optional.** The check interval (in seconds). This interval is used for checks when the service is in a `HARD` state. Defaults to `5m`. retry\_interval | Duration | **Optional.** The retry interval (in seconds). This interval is used for checks when the service is in a `SOFT` state. Defaults to `1m`. Note: This does not affect the scheduling [after a passive check result](08-advanced-topics.md#check-result-freshness). enable\_notifications | Boolean | **Optional.** Whether notifications are enabled. Defaults to `true`. enable\_active\_checks | Boolean | **Optional.** Whether active checks are enabled. Defaults to `true`. enable\_passive\_checks | Boolean | **Optional.** Whether passive checks are enabled. Defaults to `true`. enable\_event\_handler | Boolean | **Optional.** Enables event handlers for this host. Defaults to `true`. enable\_flapping | Boolean | **Optional.** Whether flap detection is enabled. Defaults to `false`. flapping\_threshold\_high | Number | **Optional.** Flapping upper bound in percent for a service to be considered flapping. `30.0` flapping\_threshold\_low | Number | **Optional.** Flapping lower bound in percent for a service to be considered not flapping. `25.0` flapping\_ignore\_states | Array | **Optional.** A list of states that should be ignored during flapping calculation. By default no state is ignored. enable\_perfdata | Boolean | **Optional.** Whether performance data processing is enabled. Defaults to `true`. event\_command | Object name | **Optional.** The name of an event command that should be executed every time the service's state changes or the service is in a `SOFT` state. volatile | Boolean | **Optional.** Treat all state changes as HARD changes. See [here](08-advanced-topics.md#volatile-services-hosts) for details. Defaults to `false`. zone | Object name | **Optional.** The zone this object is a member of. Please read the [distributed monitoring](06-distributed-monitoring.md#distributed-monitoring) chapter for details. command\_endpoint | Object name | **Optional.** The endpoint where commands are executed on. notes | String | **Optional.** Notes for the service. notes\_url | String | **Optional.** URL for notes for the service (for example, in notification commands). action\_url | String | **Optional.** URL for actions for the service (for example, an external graphing tool). icon\_image | String | **Optional.** Icon image for the service. Used by external interfaces only. icon\_image\_alt | String | **Optional.** Icon image description for the service. Used by external interface only. Service objects have composite names, i.e. their names are based on the host\_name attribute and the name you specified. This means you can define more than one object with the same (short) name as long as the `host_name` attribute has a different value. The actual check interval might deviate slightly from the configured values due to the fact that Icinga tries to evenly distribute all checks over a certain period of time, i.e. to avoid load spikes. Runtime Attributes: Name | Type | Description ------------------------------|-------------------|---------------------------------- next\_check | Timestamp | When the next check occurs (as a UNIX timestamp). last\_check | Timestamp | When the last check occurred (as a UNIX timestamp). check\_attempt | Number | The current check attempt number. state\_type | Number | The current state type (0 = SOFT, 1 = HARD). last\_state\_type | Number | The previous state type (0 = SOFT, 1 = HARD). last\_reachable | Boolean | Whether the service was reachable when the last check occurred. last\_check\_result | CheckResult | The current [check result](08-advanced-topics.md#advanced-value-types-checkresult). last\_state\_change | Timestamp | When the last state change occurred (as a UNIX timestamp). last\_hard\_state\_change | Timestamp | When the last hard state change occurred (as a UNIX timestamp). acknowledgement | Number | The acknowledgement type (0 = NONE, 1 = NORMAL, 2 = STICKY). acknowledgement\_expiry | Timestamp | When the acknowledgement expires (as a UNIX timestamp; 0 = no expiry). acknowledgement\_last\_change | Timestamp | When the acknowledgement has been set/cleared downtime\_depth | Number | Whether the service has one or more active downtimes. flapping\_last\_change | Timestamp | When the last flapping change occurred (as a UNIX timestamp). flapping\_current | Number | Current flapping value in percent (see flapping\_thresholds) flapping | Boolean | Whether the service is flapping between states. state | Number | The current state (0 = OK, 1 = WARNING, 2 = CRITICAL, 3 = UNKNOWN). last\_state | Number | The previous state (0 = OK, 1 = WARNING, 2 = CRITICAL, 3 = UNKNOWN). last\_hard\_state | Number | The last hard state (0 = OK, 1 = WARNING, 2 = CRITICAL, 3 = UNKNOWN). last\_state\_ok | Timestamp | When the last OK state occurred (as a UNIX timestamp). last\_state\_warning | Timestamp | When the last WARNING state occurred (as a UNIX timestamp). last\_state\_critical | Timestamp | When the last CRITICAL state occurred (as a UNIX timestamp). last\_state\_unknown | Timestamp | When the last UNKNOWN state occurred (as a UNIX timestamp). last\_state\_unreachable | Timestamp | When the service was unreachable the last time (as a UNIX timestamp). previous\_state\_change | Timestamp | Previous timestamp of `last_state_change` before processing a new check result. severity | Number | [Severity](19-technical-concepts.md#technical-concepts-checks-severity) calculated value. problem | Boolean | Whether the service is considered in a problem state type (NOT-OK). handled | Boolean | Whether the service problem is handled (downtime or acknowledgement). next\_update | Timestamp | When the next check update is to be expected. ### ServiceGroup A group of services. > **Best Practice** > > Assign service group members using the [group assign](17-language-reference.md#group-assign) rules. Example: ``` object ServiceGroup "snmp" { display_name = "SNMP services" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- display\_name | String | **Optional.** A short description of the service group. groups | Array of object names | **Optional.** An array of nested group names. ### TimePeriod Time periods can be used to specify when hosts/services should be checked or to limit when notifications should be sent out. Examples: ``` object TimePeriod "nonworkhours" { display_name = "Icinga 2 TimePeriod for non working hours" ranges = { monday = "00:00-8:00,17:00-24:00" tuesday = "00:00-8:00,17:00-24:00" wednesday = "00:00-8:00,17:00-24:00" thursday = "00:00-8:00,17:00-24:00" friday = "00:00-8:00,16:00-24:00" saturday = "00:00-24:00" sunday = "00:00-24:00" } } object TimePeriod "exampledays" { display_name = "Icinga 2 TimePeriod for random example days" ranges = { //We still believe in Santa, no peeking! //Applies every 25th of December every year "december 25" = "00:00-24:00" //Any point in time can be specified, //but you still have to use a range "2038-01-19" = "03:13-03:15" //Evey 3rd day from the second monday of February //to 8th of November "monday 2 february - november 8 / 3" = "00:00-24:00" } } ``` Additional examples can be found [here](08-advanced-topics.md#timeperiods). Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- display\_name | String | **Optional.** A short description of the time period. ranges | Dictionary | **Required.** A dictionary containing information which days and durations apply to this timeperiod. prefer\_includes | Boolean | **Optional.** Whether to prefer timeperiods `includes` or `excludes`. Default to true. excludes | Array of object names | **Optional.** An array of timeperiods, which should exclude from your timerange. includes | Array of object names | **Optional.** An array of timeperiods, which should include into your timerange Runtime Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- is\_inside | Boolean | Whether we're currently inside this timeperiod. See also [time zone handling](08-advanced-topics.md#timeperiods-timezones). ### User A user. Example: ``` object User "icingaadmin" { display_name = "Icinga 2 Admin" groups = [ "icingaadmins" ] email = "icinga@localhost" pager = "icingaadmin@localhost.localdomain" period = "24x7" states = [ OK, Warning, Critical, Unknown ] types = [ Problem, Recovery ] vars.additional_notes = "This is the Icinga 2 Admin account." } ``` Available notification state filters: ``` OK Warning Critical Unknown Up Down ``` Available notification type filters: ``` DowntimeStart DowntimeEnd DowntimeRemoved Custom Acknowledgement Problem Recovery FlappingStart FlappingEnd ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- display\_name | String | **Optional.** A short description of the user. email | String | **Optional.** An email string for this user. Useful for notification commands. pager | String | **Optional.** A pager string for this user. Useful for notification commands. vars | Dictionary | **Optional.** A dictionary containing custom variables that are specific to this user. groups | Array of object names | **Optional.** An array of group names. enable\_notifications | Boolean | **Optional.** Whether notifications are enabled for this user. Defaults to true. period | Object name | **Optional.** The name of a time period which determines when a notification for this user should be triggered. Not set by default (effectively 24x7). types | Array | **Optional.** A set of type filters when a notification for this user should be triggered. By default everything is matched. states | Array | **Optional.** A set of state filters when a notification for this should be triggered. By default everything is matched. Runtime Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- last\_notification | Timestamp | When the last notification was sent for this user (as a UNIX timestamp). ### UserGroup A user group. > **Best Practice** > > Assign user group members using the [group assign](17-language-reference.md#group-assign) rules. Example: ``` object UserGroup "icingaadmins" { display_name = "Icinga 2 Admin Group" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- display\_name | String | **Optional.** A short description of the user group. groups | Array of object names | **Optional.** An array of nested group names. ### Zone Zone objects are used to specify which Icinga 2 instances are located in a zone. Please read the [distributed monitoring chapter](06-distributed-monitoring.md#distributed-monitoring) for additional details. Example: ``` object Zone "master" { endpoints = [ "icinga2-master1.localdomain", "icinga2-master2.localdomain" ] } object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain" ] parent = "master" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- endpoints | Array of object names | **Optional.** Array of endpoint names located in this zone. parent | Object name | **Optional.** The name of the parent zone. (Do not specify a global zone) global | Boolean | **Optional.** Whether configuration files for this zone should be [synced](06-distributed-monitoring.md#distributed-monitoring-global-zone-config-sync) to all endpoints. Defaults to `false`. Zone objects cannot currently be created with the API. ## Runtime Objects These objects are generated at runtime by the daemon from API actions. Downtime objects are also created by ScheduledDowntime objects. ### Comment Comments created at runtime are represented as objects. Note: This is for reference only. You can create comments with the [add-comment](12-icinga2-api.md#icinga2-api-actions-add-comment) API action. Example: ``` object Comment "my-comment" { host_name = "localhost" author = "icingaadmin" text = "This is a comment." entry_time = 1234567890 } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host\_name | Object name | **Required.** The name of the host this comment belongs to. service\_name | Object name | **Optional.** The short name of the service this comment belongs to. If omitted, this comment object is treated as host comment. author | String | **Required.** The author's name. text | String | **Required.** The comment text. entry\_time | Timestamp | **Optional.** The UNIX timestamp when this comment was added. If omitted, the entry time is volatile! entry\_type | Number | **Optional.** The comment type (`User` = 1, `Downtime` = 2, `Flapping` = 3, `Acknowledgement` = 4). expire\_time | Timestamp | **Optional.** The comment's expire time as UNIX timestamp. persistent | Boolean | **Optional.** Only evaluated for `entry_type` Acknowledgement. `true` does not remove the comment when the acknowledgement is removed. ### Downtime Downtimes created at runtime are represented as objects. You can create downtimes with the [schedule-downtime](12-icinga2-api.md#icinga2-api-actions-schedule-downtime) API action. Example: ``` object Downtime "my-downtime" { host_name = "localhost" author = "icingaadmin" comment = "This is a downtime." start_time = 1505312869 end_time = 1505312924 } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host\_name | Object name | **Required.** The name of the host this downtime belongs to. service\_name | Object name | **Optional.** The short name of the service this downtime belongs to. If omitted, this downtime object is treated as host downtime. author | String | **Required.** The author's name. comment | String | **Required.** The comment text. start\_time | Timestamp | **Required.** The start time as UNIX timestamp. end\_time | Timestamp | **Required.** The end time as UNIX timestamp. duration | Number | **Optional.** The duration as number. entry\_time | Timestamp | **Optional.** The UNIX timestamp when this downtime was added. fixed | Boolean | **Optional.** Whether the downtime is fixed (true) or flexible (false). Defaults to flexible. Details in the [advanced topics chapter](08-advanced-topics.md#fixed-flexible-downtimes). triggers | Array of object names | **Optional.** List of downtimes which should be triggered by this downtime. Runtime Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- trigger\_time | Timestamp | The UNIX timestamp when this downtime was triggered. triggered\_by | Object name | The name of the downtime this downtime was triggered by. ## Features ### ApiListener ApiListener objects are used for distributed monitoring setups and API usage specifying the certificate files used for ssl authorization and additional restrictions. This configuration object is available as [api feature](11-cli-commands.md#cli-command-feature). The `TicketSalt` constant must be defined in [constants.conf](04-configuration.md#constants-conf). Example: ``` object ApiListener "api" { accept_commands = true accept_config = true ticket_salt = TicketSalt } ``` Configuration Attributes: Name | Type | Description --------------------------------------|-----------------------|---------------------------------- cert\_path | String | **Deprecated.** Path to the public key. key\_path | String | **Deprecated.** Path to the private key. ca\_path | String | **Deprecated.** Path to the CA certificate file. ticket\_salt | String | **Optional.** Private key for [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing). **Required** for a signing master instance. crl\_path | String | **Optional.** Path to the CRL file. bind\_host | String | **Optional.** The IP address the api listener should be bound to. If not specified, the ApiListener is bound to `::` and listens for both IPv4 and IPv6 connections or to `0.0.0.0` if IPv6 is not supported by the operating system. bind\_port | Number | **Optional.** The port the api listener should be bound to. Defaults to `5665`. accept\_config | Boolean | **Optional.** Accept zone configuration. Defaults to `false`. accept\_commands | Boolean | **Optional.** Accept remote commands. Defaults to `false`. max\_anonymous\_clients | Number | **Optional.** Limit the number of anonymous client connections (not configured endpoints and signing requests). cipher\_list | String | **Optional.** Cipher list that is allowed. For a list of available ciphers run `openssl ciphers`. Defaults to `ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256`. tls\_protocolmin | String | **Optional.** Minimum TLS protocol version. Since v2.11, only `TLSv1.2` is supported. Defaults to `TLSv1.2`. tls\_handshake\_timeout | Number | **Deprecated.** TLS Handshake timeout. Defaults to `10s`. connect\_timeout | Number | **Optional.** Timeout for establishing new connections. Affects both incoming and outgoing connections. Within this time, the TCP and TLS handshakes must complete and either a HTTP request or an Icinga cluster connection must be initiated. Defaults to `15s`. access\_control\_allow\_origin | Array | **Optional.** Specifies an array of origin URLs that may access the API. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Origin) access\_control\_allow\_credentials | Boolean | **Deprecated.** Indicates whether or not the actual request can be made using credentials. Defaults to `true`. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Credentials) access\_control\_allow\_headers | String | **Deprecated.** Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. Defaults to `Authorization`. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Headers) access\_control\_allow\_methods | String | **Deprecated.** Used in response to a preflight request to indicate which HTTP methods can be used when making the actual request. Defaults to `GET, POST, PUT, DELETE`. [(MDN docs)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Methods) environment | String | **Optional.** Used as suffix in TLS SNI extension name; default from constant `ApiEnvironment`, which is empty. The attributes `access_control_allow_credentials`, `access_control_allow_headers` and `access_control_allow_methods` are controlled by Icinga 2 and are not changeable by config any more. The ApiListener type expects its certificate files to be in the following locations: Type | Location ---------------------|------------------------------------- Private key | `DataDir + "/certs/" + NodeName + ".key"` Certificate file | `DataDir + "/certs/" + NodeName + ".crt"` CA certificate file | `DataDir + "/certs/ca.crt"` If the deprecated attributes `cert_path`, `key_path` and/or `ca_path` are specified Icinga 2 copies those files to the new location in `DataDir + "/certs"` unless the file(s) there are newer. Please check the [upgrading chapter](16-upgrading-icinga-2.md#upgrading-to-2-8-certificate-paths) for more details. While Icinga 2 and the underlying OpenSSL library use sane and secure defaults, the attributes `cipher_list` and `tls_protocolmin` can be used to increase communication security. A good source for a more secure configuration is provided by the [Mozilla Wiki](https://wiki.mozilla.org/Security/Server_Side_TLS). Ensure to use the same configuration for both attributes on **all** endpoints to avoid communication problems which requires to use `cipher_list` compatible with the endpoint using the oldest version of the OpenSSL library. If using other tools to connect to the API ensure also compatibility with them as this setting affects not only inter-cluster communcation but also the REST API. ### CheckerComponent The checker component is responsible for scheduling active checks. This configuration object is available as [checker feature](11-cli-commands.md#cli-command-feature). Example: ``` object CheckerComponent "checker" { } ``` In order to limit the concurrent checks on a master/satellite endpoint, use [MaxConcurrentChecks](17-language-reference.md#icinga-constants-global-config) constant. This also applies to an agent as command endpoint where the checker feature is disabled. ### CompatLogger Writes log files in a format that's compatible with Icinga 1.x. This configuration object is available as [compatlog feature](14-features.md#compat-logging). > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). Example: ``` object CompatLogger "compatlog" { log_dir = "/var/log/icinga2/compat" rotation_method = "DAILY" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- log\_dir | String | **Optional.** Path to the compat log directory. Defaults to LogDir + "/compat". rotation\_method | String | **Optional.** Specifies when to rotate log files. Can be one of "HOURLY", "DAILY", "WEEKLY" or "MONTHLY". Defaults to "HOURLY". ### ElasticsearchWriter Writes check result metrics and performance data to an Elasticsearch instance. This configuration object is available as [elasticsearch feature](14-features.md#elasticsearch-writer). Example: ``` object ElasticsearchWriter "elasticsearch" { host = "127.0.0.1" port = 9200 index = "icinga2" enable_send_perfdata = true flush_threshold = 1024 flush_interval = 10 } ``` The index is rotated daily, as is recommended by Elastic, meaning the index will be renamed to `$index-$d.$M.$y`. Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Required.** Elasticsearch host address. Defaults to `127.0.0.1`. port | Number | **Required.** Elasticsearch port. Defaults to `9200`. index | String | **Required.** Elasticsearch index name. Defaults to `icinga2`. enable\_send\_perfdata | Boolean | **Optional.** Send parsed performance data metrics for check results. Defaults to `false`. flush\_interval | Duration | **Optional.** How long to buffer data points before transferring to Elasticsearch. Defaults to `10s`. flush\_threshold | Number | **Optional.** How many data points to buffer before forcing a transfer to Elasticsearch. Defaults to `1024`. username | String | **Optional.** Basic auth username if Elasticsearch is hidden behind an HTTP proxy. password | String | **Optional.** Basic auth password if Elasticsearch is hidden behind an HTTP proxy. enable\_tls | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`. Requires an HTTP proxy. insecure\_noverify | Boolean | **Optional.** Disable TLS peer verification. ca\_path | String | **Optional.** Path to CA certificate to validate the remote host. Requires `enable_tls` set to `true`. cert\_path | String | **Optional.** Path to host certificate to present to the remote host for mutual verification. Requires `enable_tls` set to `true`. key\_path | String | **Optional.** Path to host key to accompany the cert\_path. Requires `enable_tls` set to `true`. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`. Note: If `flush_threshold` is set too low, this will force the feature to flush all data to Elasticsearch too often. Experiment with the setting, if you are processing more than 1024 metrics per second or similar. Basic auth is supported with the `username` and `password` attributes. This requires an HTTP proxy (Nginx, etc.) in front of the Elasticsearch instance. Check [this blogpost](https://blog.netways.de/2017/09/14/secure-elasticsearch-and-kibana-with-an-nginx-http-proxy/) for an example. TLS for the HTTP proxy can be enabled with `enable_tls`. In addition to that you can specify the certificates with the `ca_path`, `cert_path` and `cert_key` attributes. ### ExternalCommandListener Implements the Icinga 1.x command pipe which can be used to send commands to Icinga. This configuration object is available as [command feature](14-features.md#external-commands). > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). Example: ``` object ExternalCommandListener "command" { command_path = "/var/run/icinga2/cmd/icinga2.cmd" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- command\_path | String | **Optional.** Path to the command pipe. Defaults to RunDir + "/icinga2/cmd/icinga2.cmd". ### FileLogger Specifies Icinga 2 logging to a file. This configuration object is available as `mainlog` and `debuglog` [logging feature](14-features.md#logging). Example: ``` object FileLogger "debug-file" { severity = "debug" path = "/var/log/icinga2/debug.log" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- path | String | **Required.** The log path. severity | String | **Optional.** The minimum severity for this log. Can be "debug", "notice", "information", "warning" or "critical". Defaults to "information". ### GelfWriter Writes event log entries to a defined GELF receiver host (Graylog, Logstash). This configuration object is available as [gelf feature](14-features.md#gelfwriter). Example: ``` object GelfWriter "gelf" { host = "127.0.0.1" port = 12201 } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Optional.** GELF receiver host address. Defaults to `127.0.0.1`. port | Number | **Optional.** GELF receiver port. Defaults to `12201`. source | String | **Optional.** Source name for this instance. Defaults to `icinga2`. enable\_send\_perfdata | Boolean | **Optional.** Enable performance data for 'CHECK RESULT' events. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`. enable\_tls | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`. insecure\_noverify | Boolean | **Optional.** Disable TLS peer verification. ca\_path | String | **Optional.** Path to CA certificate to validate the remote host. Requires `enable_tls` set to `true`. cert\_path | String | **Optional.** Path to host certificate to present to the remote host for mutual verification. Requires `enable_tls` set to `true`. key\_path | String | **Optional.** Path to host key to accompany the cert\_path. Requires `enable_tls` set to `true`. ### GraphiteWriter Writes check result metrics and performance data to a defined Graphite Carbon host. This configuration object is available as [graphite feature](14-features.md#graphite-carbon-cache-writer). Example: ``` object GraphiteWriter "graphite" { host = "127.0.0.1" port = 2003 } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Optional.** Graphite Carbon host address. Defaults to `127.0.0.1`. port | Number | **Optional.** Graphite Carbon port. Defaults to `2003`. host\_name\_template | String | **Optional.** Metric prefix for host name. Defaults to `icinga2.$host.name$.host.$host.check_command$`. service\_name\_template | String | **Optional.** Metric prefix for service name. Defaults to `icinga2.$host.name$.services.$service.name$.$service.check_command$`. enable\_send\_thresholds | Boolean | **Optional.** Send additional threshold metrics. Defaults to `false`. enable\_send\_metadata | Boolean | **Optional.** Send additional metadata metrics. Defaults to `false`. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`. Additional usage examples can be found [here](14-features.md#graphite-carbon-cache-writer). ### IcingaApplication The IcingaApplication object is required to start Icinga 2. The object name must be `app`. If the object configuration is missing, Icinga 2 will automatically create an IcingaApplication object. Example: ``` object IcingaApplication "app" { enable_perfdata = false } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- enable\_notifications | Boolean | **Optional.** Whether notifications are globally enabled. Defaults to true. enable\_event\_handlers | Boolean | **Optional.** Whether event handlers are globally enabled. Defaults to true. enable\_flapping | Boolean | **Optional.** Whether flap detection is globally enabled. Defaults to true. enable\_host\_checks | Boolean | **Optional.** Whether active host checks are globally enabled. Defaults to true. enable\_service\_checks | Boolean | **Optional.** Whether active service checks are globally enabled. Defaults to true. enable\_perfdata | Boolean | **Optional.** Whether performance data processing is globally enabled. Defaults to true. vars | Dictionary | **Optional.** A dictionary containing custom variables that are available globally. environment | String | **Optional.** Specify the Icinga environment. This overrides the `Environment` constant specified in the configuration or on the CLI with `--define`. Defaults to empty. ### IcingaDB The `IcingaDB` object implements the [Icinga DB feature](14-features.md#icinga-db). Example: ``` object IcingaDB "icingadb" { //host = "127.0.0.1" //port = 6380 //password = "xxx" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Optional.** Redis host. Defaults to `127.0.0.1`. port | Number | **Optional.** Redis port. Defaults to `6380` since the Redis server provided by the `icingadb-redis` package listens on that port. path | String | **Optional.** Redis unix socket path. Can be used instead of `host` and `port` attributes. password | String | **Optional.** Redis auth password. enable\_tls | Boolean | **Optional.** Whether to use TLS. cert\_path | String | **Optional.** Path to the certificate. key\_path | String | **Optional.** Path to the private key. ca\_path | String | **Optional.** Path to the CA certificate to use instead of the system's root CAs. crl\_path | String | **Optional.** Path to the CRL file. cipher\_list | String | **Optional.** Cipher list that is allowed. For a list of available ciphers run `openssl ciphers`. Defaults to `ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256`. tls\_protocolmin | String | **Optional.** Minimum TLS protocol version. Defaults to `TLSv1.2`. insecure\_noverify | Boolean | **Optional.** Whether not to verify the peer. connect\_timeout | Number | **Optional.** Timeout for establishing new connections. Within this time, the TCP, TLS (if enabled) and Redis handshakes must complete. Defaults to `15s`. ### IdoMySqlConnection > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). IDO database adapter for MySQL. This configuration object is available as [ido-mysql feature](14-features.md#db-ido). Example: ``` object IdoMysqlConnection "mysql-ido" { host = "127.0.0.1" port = 3306 user = "icinga" password = "icinga" database = "icinga" cleanup = { downtimehistory_age = 48h contactnotifications_age = 31d } } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Optional.** MySQL database host address. Defaults to `localhost`. port | Number | **Optional.** MySQL database port. Defaults to `3306`. socket\_path | String | **Optional.** MySQL socket path. user | String | **Optional.** MySQL database user with read/write permission to the icinga database. Defaults to `icinga`. password | String | **Optional.** MySQL database user's password. Defaults to `icinga`. database | String | **Optional.** MySQL database name. Defaults to `icinga`. enable\_ssl | Boolean | **Optional.** Use SSL. Defaults to false. Change to `true` in case you want to use any of the SSL options. ssl\_key | String | **Optional.** MySQL SSL client key file path. ssl\_cert | String | **Optional.** MySQL SSL certificate file path. ssl\_ca | String | **Optional.** MySQL SSL certificate authority certificate file path. ssl\_capath | String | **Optional.** MySQL SSL trusted SSL CA certificates in PEM format directory path. ssl\_cipher | String | **Optional.** MySQL SSL list of allowed ciphers. table\_prefix | String | **Optional.** MySQL database table prefix. Defaults to `icinga_`. instance\_name | String | **Optional.** Unique identifier for the local Icinga 2 instance, used for multiple Icinga 2 clusters writing to the same database. Defaults to `default`. instance\_description | String | **Optional.** Description for the Icinga 2 instance. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-db-ido). Defaults to `true`. failover\_timeout | Duration | **Optional.** Set the failover timeout in a [HA cluster](06-distributed-monitoring.md#distributed-monitoring-high-availability-db-ido). Must not be lower than 30s. Defaults to `30s`. cleanup | Dictionary | **Optional.** Dictionary with items for historical table cleanup. categories | Array | **Optional.** Array of information types that should be written to the database. Cleanup Items: Name | Type | Description --------------------------------|-----------------------|---------------------------------- acknowledgements\_age | Duration | **Optional.** Max age for acknowledgements table rows (entry\_time). Defaults to 0 (never). commenthistory\_age | Duration | **Optional.** Max age for commenthistory table rows (entry\_time). Defaults to 0 (never). contactnotifications\_age | Duration | **Optional.** Max age for contactnotifications table rows (start\_time). Defaults to 0 (never). contactnotificationmethods\_age | Duration | **Optional.** Max age for contactnotificationmethods table rows (start\_time). Defaults to 0 (never). downtimehistory\_age | Duration | **Optional.** Max age for downtimehistory table rows (entry\_time). Defaults to 0 (never). eventhandlers\_age | Duration | **Optional.** Max age for eventhandlers table rows (start\_time). Defaults to 0 (never). externalcommands\_age | Duration | **Optional.** Max age for externalcommands table rows (entry\_time). Defaults to 0 (never). flappinghistory\_age | Duration | **Optional.** Max age for flappinghistory table rows (event\_time). Defaults to 0 (never). hostchecks\_age | Duration | **Optional.** Max age for hostchecks table rows (start\_time). Defaults to 0 (never). logentries\_age | Duration | **Optional.** Max age for logentries table rows (logentry\_time). Defaults to 0 (never). notifications\_age | Duration | **Optional.** Max age for notifications table rows (start\_time). Defaults to 0 (never). processevents\_age | Duration | **Optional.** Max age for processevents table rows (event\_time). Defaults to 0 (never). statehistory\_age | Duration | **Optional.** Max age for statehistory table rows (state\_time). Defaults to 0 (never). servicechecks\_age | Duration | **Optional.** Max age for servicechecks table rows (start\_time). Defaults to 0 (never). systemcommands\_age | Duration | **Optional.** Max age for systemcommands table rows (start\_time). Defaults to 0 (never). > **Supported units** > > Supported suffixes include ms (milliseconds), s (seconds), m (minutes), h (hours) and d (days). > Check the [language reference](17-language-reference.md#duration-literals). Data Categories: Name | Description | Required by ---------------------|------------------------|-------------------- DbCatConfig | Configuration data | Icinga Web 2 DbCatState | Current state data | Icinga Web 2 DbCatAcknowledgement | Acknowledgements | Icinga Web 2 DbCatComment | Comments | Icinga Web 2 DbCatDowntime | Downtimes | Icinga Web 2 DbCatEventHandler | Event handler data | Icinga Web 2 DbCatExternalCommand | External commands | -- DbCatFlapping | Flap detection data | Icinga Web 2 DbCatCheck | Check results | -- DbCatLog | Log messages | -- DbCatNotification | Notifications | Icinga Web 2 DbCatProgramStatus | Program status data | Icinga Web 2 DbCatRetention | Retention data | Icinga Web 2 DbCatStateHistory | Historical state data | Icinga Web 2 The default value for `categories` includes everything required by Icinga Web 2 in the table above. In addition to the category flags listed above the `DbCatEverything` flag may be used as a shortcut for listing all flags. Runtime Attributes: Name | Type | Description ----------------------------|-----------------------|----------------- last\_failover | Timestamp | When the last failover happened for this connection (only available with `enable_ha = true`. ### IdoPgsqlConnection > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). IDO database adapter for PostgreSQL. This configuration object is available as [ido-pgsql feature](14-features.md#db-ido). Example: ``` object IdoPgsqlConnection "pgsql-ido" { host = "127.0.0.1" port = 5432 user = "icinga" password = "icinga" database = "icinga" cleanup = { downtimehistory_age = 48h contactnotifications_age = 31d } } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Optional.** PostgreSQL database host address. Defaults to `localhost`. port | Number | **Optional.** PostgreSQL database port. Defaults to `5432`. user | String | **Optional.** PostgreSQL database user with read/write permission to the icinga database. Defaults to `icinga`. password | String | **Optional.** PostgreSQL database user's password. Defaults to `icinga`. database | String | **Optional.** PostgreSQL database name. Defaults to `icinga`. ssl\_mode | String | **Optional.** Enable SSL connection mode. Value must be set according to the [sslmode setting](https://www.postgresql.org/docs/9.3/static/libpq-connect.html#LIBPQ-CONNSTRING): `prefer`, `require`, `verify-ca`, `verify-full`, `allow`, `disable`. ssl\_key | String | **Optional.** PostgreSQL SSL client key file path. ssl\_cert | String | **Optional.** PostgreSQL SSL certificate file path. ssl\_ca | String | **Optional.** PostgreSQL SSL certificate authority certificate file path. table\_prefix | String | **Optional.** PostgreSQL database table prefix. Defaults to `icinga_`. instance\_name | String | **Optional.** Unique identifier for the local Icinga 2 instance, used for multiple Icinga 2 clusters writing to the same database. Defaults to `default`. instance\_description | String | **Optional.** Description for the Icinga 2 instance. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-db-ido). Defaults to `true`. failover\_timeout | Duration | **Optional.** Set the failover timeout in a [HA cluster](06-distributed-monitoring.md#distributed-monitoring-high-availability-db-ido). Must not be lower than 30s. Defaults to `30s`. cleanup | Dictionary | **Optional.** Dictionary with items for historical table cleanup. categories | Array | **Optional.** Array of information types that should be written to the database. Cleanup Items: Name | Type | Description --------------------------------|-----------------------|---------------------------------- acknowledgements\_age | Duration | **Optional.** Max age for acknowledgements table rows (entry\_time). Defaults to 0 (never). commenthistory\_age | Duration | **Optional.** Max age for commenthistory table rows (entry\_time). Defaults to 0 (never). contactnotifications\_age | Duration | **Optional.** Max age for contactnotifications table rows (start\_time). Defaults to 0 (never). contactnotificationmethods\_age | Duration | **Optional.** Max age for contactnotificationmethods table rows (start\_time). Defaults to 0 (never). downtimehistory\_age | Duration | **Optional.** Max age for downtimehistory table rows (entry\_time). Defaults to 0 (never). eventhandlers\_age | Duration | **Optional.** Max age for eventhandlers table rows (start\_time). Defaults to 0 (never). externalcommands\_age | Duration | **Optional.** Max age for externalcommands table rows (entry\_time). Defaults to 0 (never). flappinghistory\_age | Duration | **Optional.** Max age for flappinghistory table rows (event\_time). Defaults to 0 (never). hostchecks\_age | Duration | **Optional.** Max age for hostchecks table rows (start\_time). Defaults to 0 (never). logentries\_age | Duration | **Optional.** Max age for logentries table rows (logentry\_time). Defaults to 0 (never). notifications\_age | Duration | **Optional.** Max age for notifications table rows (start\_time). Defaults to 0 (never). processevents\_age | Duration | **Optional.** Max age for processevents table rows (event\_time). Defaults to 0 (never). statehistory\_age | Duration | **Optional.** Max age for statehistory table rows (state\_time). Defaults to 0 (never). servicechecks\_age | Duration | **Optional.** Max age for servicechecks table rows (start\_time). Defaults to 0 (never). systemcommands\_age | Duration | **Optional.** Max age for systemcommands table rows (start\_time). Defaults to 0 (never). > **Supported units** > > Supported suffixes include ms (milliseconds), s (seconds), m (minutes), h (hours) and d (days). > Check the [language reference](17-language-reference.md#duration-literals). Data Categories: Name | Description | Required by ---------------------|------------------------|-------------------- DbCatConfig | Configuration data | Icinga Web 2 DbCatState | Current state data | Icinga Web 2 DbCatAcknowledgement | Acknowledgements | Icinga Web 2 DbCatComment | Comments | Icinga Web 2 DbCatDowntime | Downtimes | Icinga Web 2 DbCatEventHandler | Event handler data | Icinga Web 2 DbCatExternalCommand | External commands | -- DbCatFlapping | Flap detection data | Icinga Web 2 DbCatCheck | Check results | -- DbCatLog | Log messages | -- DbCatNotification | Notifications | Icinga Web 2 DbCatProgramStatus | Program status data | Icinga Web 2 DbCatRetention | Retention data | Icinga Web 2 DbCatStateHistory | Historical state data | Icinga Web 2 The default value for `categories` includes everything required by Icinga Web 2 in the table above. In addition to the category flags listed above the `DbCatEverything` flag may be used as a shortcut for listing all flags. Runtime Attributes: Name | Type | Description ----------------------------|-----------------------|----------------- last\_failover | Timestamp | When the last failover happened for this connection (only available with `enable_ha = true`. ### InfluxdbWriter Writes check result metrics and performance data to a defined InfluxDB v1 host. This configuration object is available as [influxdb feature](14-features.md#influxdb-writer). For InfluxDB v2 support see the [Influxdb2Writer](#objecttype-influxdb2writer) below. Example: ``` object InfluxdbWriter "influxdb" { host = "127.0.0.1" port = 8086 database = "icinga2" username = "icinga2" password = "icinga2" basic_auth = { username = "icinga" password = "icinga" } flush_threshold = 1024 flush_interval = 10s host_template = { measurement = "$host.check_command$" tags = { hostname = "$host.name$" } } service_template = { measurement = "$service.check_command$" tags = { hostname = "$host.name$" service = "$service.name$" } } } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Required.** InfluxDB host address. Defaults to `127.0.0.1`. port | Number | **Required.** InfluxDB HTTP port. Defaults to `8086`. database | String | **Required.** InfluxDB database name. Defaults to `icinga2`. username | String | **Optional.** InfluxDB user name. Defaults to `none`. password | String | **Optional.** InfluxDB user password. Defaults to `none`. basic\_auth | Dictionary | **Optional.** Username and password for HTTP basic authentication. ssl\_enable | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`. ssl\_insecure\_noverify | Boolean | **Optional.** Disable TLS peer verification. ssl\_ca\_cert | String | **Optional.** Path to CA certificate to validate the remote host. ssl\_cert | String | **Optional.** Path to host certificate to present to the remote host for mutual verification. ssl\_key | String | **Optional.** Path to host key to accompany the ssl\_cert. host\_template | Dictionary | **Required.** Host template to define the InfluxDB line protocol. service\_template | Dictionary | **Required.** Service template to define the influxDB line protocol. enable\_send\_thresholds | Boolean | **Optional.** Whether to send warn, crit, min & max tagged data. enable\_send\_metadata | Boolean | **Optional.** Whether to send check metadata e.g. states, execution time, latency etc. flush\_interval | Duration | **Optional.** How long to buffer data points before transferring to InfluxDB. Defaults to `10s`. flush\_threshold | Number | **Optional.** How many data points to buffer before forcing a transfer to InfluxDB. Defaults to `1024`. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`. Note: If `flush_threshold` is set too low, this will always force the feature to flush all data to InfluxDB. Experiment with the setting, if you are processing more than 1024 metrics per second or similar. ### Influxdb2Writer Writes check result metrics and performance data to a defined InfluxDB v2 host. This configuration object is available as [influxdb feature](14-features.md#influxdb-writer). For InfluxDB v1 support see the [InfluxdbWriter](#objecttype-influxdbwriter) above. Example: ``` object Influxdb2Writer "influxdb2" { host = "127.0.0.1" port = 8086 organization = "monitoring" bucket = "icinga2" auth_token = "ABCDEvwxyz0189-_" flush_threshold = 1024 flush_interval = 10s host_template = { measurement = "$host.check_command$" tags = { hostname = "$host.name$" } } service_template = { measurement = "$service.check_command$" tags = { hostname = "$host.name$" service = "$service.name$" } } } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Required.** InfluxDB host address. Defaults to `127.0.0.1`. port | Number | **Required.** InfluxDB HTTP port. Defaults to `8086`. organization | String | **Required.** InfluxDB organization name. bucket | String | **Required.** InfluxDB bucket name. auth\_token | String | **Required.** InfluxDB authentication token. ssl\_enable | Boolean | **Optional.** Whether to use a TLS stream. Defaults to `false`. ssl\_insecure\_noverify | Boolean | **Optional.** Disable TLS peer verification. ssl\_ca\_cert | String | **Optional.** Path to CA certificate to validate the remote host. ssl\_cert | String | **Optional.** Path to host certificate to present to the remote host for mutual verification. ssl\_key | String | **Optional.** Path to host key to accompany the ssl\_cert. host\_template | Dictionary | **Required.** Host template to define the InfluxDB line protocol. service\_template | Dictionary | **Required.** Service template to define the influxDB line protocol. enable\_send\_thresholds | Boolean | **Optional.** Whether to send warn, crit, min & max tagged data. enable\_send\_metadata | Boolean | **Optional.** Whether to send check metadata e.g. states, execution time, latency etc. flush\_interval | Duration | **Optional.** How long to buffer data points before transferring to InfluxDB. Defaults to `10s`. flush\_threshold | Number | **Optional.** How many data points to buffer before forcing a transfer to InfluxDB. Defaults to `1024`. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`. Note: If `flush_threshold` is set too low, this will always force the feature to flush all data to InfluxDB. Experiment with the setting, if you are processing more than 1024 metrics per second or similar. ### JournaldLogger Specifies Icinga 2 logging to the systemd journal using its native interface. This configuration object is available as `journald` [logging feature](14-features.md#logging). Resulting journal records have fields as described in [journal fields](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html), and an additional custom field `ICINGA2_FACILITY` with the detailed message origin (e.g. "ApiListener"). Example: ``` object JournaldLogger "journald" { severity = "warning" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- severity | String | **Optional.** The minimum syslog compatible severity for this log. Can be "debug", "notice", "information", "warning" or "critical". Defaults to "information". facility | String | **Optional.** Defines the syslog compatible facility to use for journal entries. This can be a facility constant like `FacilityDaemon`. Defaults to `FacilityUser`. identifier | String | **Optional.** Defines the syslog compatible identifier (also known as "tag") to use for journal entries. If not given, systemd's default behavior is used and usually results in "icinga2". Facility Constants are the same as for [SyslogLogger](09-object-types.md#objecttype-sysloglogger). ### LiveStatusListener Livestatus API interface available as TCP or UNIX socket. Historical table queries require the [CompatLogger](09-object-types.md#objecttype-compatlogger) feature enabled pointing to the log files using the `compat_log_path` configuration attribute. This configuration object is available as [livestatus feature](14-features.md#setting-up-livestatus). > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). Examples: ``` object LivestatusListener "livestatus-tcp" { socket_type = "tcp" bind_host = "127.0.0.1" bind_port = "6558" } object LivestatusListener "livestatus-unix" { socket_type = "unix" socket_path = "/var/run/icinga2/cmd/livestatus" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- socket\_type | String | **Optional.** Specifies the socket type. Can be either `tcp` or `unix`. Defaults to `unix`. bind\_host | String | **Optional.** Only valid when `socket_type` is set to `tcp`. Host address to listen on for connections. Defaults to `127.0.0.1`. bind\_port | Number | **Optional.** Only valid when `socket_type` is set to `tcp`. Port to listen on for connections. Defaults to `6558`. socket\_path | String | **Optional.** Only valid when `socket_type` is set to `unix`. Specifies the path to the UNIX socket file. Defaults to RunDir + "/icinga2/cmd/livestatus". compat\_log\_path | String | **Optional.** Path to Icinga 1.x log files. Required for historical table queries. Requires `CompatLogger` feature enabled. Defaults to LogDir + "/compat" > **Note** > > UNIX sockets are not supported on Windows. ### NotificationComponent The notification component is responsible for sending notifications. This configuration object is available as [notification feature](11-cli-commands.md#cli-command-feature). Example: ``` object NotificationComponent "notification" { } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-notifications). Disabling this currently only affects reminder notifications. Defaults to "true". ### OpenTsdbWriter Writes check result metrics and performance data to [OpenTSDB](http://opentsdb.net). This configuration object is available as [opentsdb feature](14-features.md#opentsdb-writer). Example: ``` object OpenTsdbWriter "opentsdb" { host = "127.0.0.1" port = 4242 } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host | String | **Optional.** OpenTSDB host address. Defaults to `127.0.0.1`. port | Number | **Optional.** OpenTSDB port. Defaults to `4242`. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`. enable_generic_metrics | Boolean | **Optional.** Re-use metric names to store different perfdata values for a particular check. Use tags to distinguish perfdata instead of metric name. Defaults to `false`. host_template | Dictionary | **Optional.** Specify additional tags to be included with host metrics. This requires a sub-dictionary named `tags`. Also specify a naming prefix by setting `metric`. More information can be found in [OpenTSDB custom tags](14-features.md#opentsdb-custom-tags) and [OpenTSDB Metric Prefix](14-features.md#opentsdb-metric-prefix). More information can be found in [OpenTSDB custom tags](14-features.md#opentsdb-custom-tags). Defaults to an `empty Dictionary`. service_template | Dictionary | **Optional.** Specify additional tags to be included with service metrics. This requires a sub-dictionary named `tags`. Also specify a naming prefix by setting `metric`. More information can be found in [OpenTSDB custom tags](14-features.md#opentsdb-custom-tags) and [OpenTSDB Metric Prefix](14-features.md#opentsdb-metric-prefix). Defaults to an `empty Dictionary`. ### PerfdataWriter Writes check result performance data to a defined path using macro pattern consisting of custom variables and runtime macros. This configuration object is available as [perfdata feature](14-features.md#writing-performance-data-files). Example: ``` object PerfdataWriter "perfdata" { host_perfdata_path = "/var/spool/icinga2/perfdata/host-perfdata" service_perfdata_path = "/var/spool/icinga2/perfdata/service-perfdata" host_format_template = "DATATYPE::HOSTPERFDATA\tTIMET::$icinga.timet$\tHOSTNAME::$host.name$\tHOSTPERFDATA::$host.perfdata$\tHOSTCHECKCOMMAND::$host.check_command$\tHOSTSTATE::$host.state$\tHOSTSTATETYPE::$host.state_type$" service_format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$icinga.timet$\tHOSTNAME::$host.name$\tSERVICEDESC::$service.name$\tSERVICEPERFDATA::$service.perfdata$\tSERVICECHECKCOMMAND::$service.check_command$\tHOSTSTATE::$host.state$\tHOSTSTATETYPE::$host.state_type$\tSERVICESTATE::$service.state$\tSERVICESTATETYPE::$service.state_type$" rotation_interval = 15s } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- host\_perfdata\_path | String | **Optional.** Path to the host performance data file. Defaults to SpoolDir + "/perfdata/host-perfdata". service\_perfdata\_path | String | **Optional.** Path to the service performance data file. Defaults to SpoolDir + "/perfdata/service-perfdata". host\_temp\_path | String | **Optional.** Path to the temporary host file. Defaults to SpoolDir + "/tmp/host-perfdata". service\_temp\_path | String | **Optional.** Path to the temporary service file. Defaults to SpoolDir + "/tmp/service-perfdata". host\_format\_template | String | **Optional.** Host Format template for the performance data file. Defaults to a template that's suitable for use with PNP4Nagios. service\_format\_template | String | **Optional.** Service Format template for the performance data file. Defaults to a template that's suitable for use with PNP4Nagios. rotation\_interval | Duration | **Optional.** Rotation interval for the files specified in `{host,service}_perfdata_path`. Defaults to `30s`. enable\_ha | Boolean | **Optional.** Enable the high availability functionality. Only valid in a [cluster setup](06-distributed-monitoring.md#distributed-monitoring-high-availability-features). Defaults to `false`. When rotating the performance data file the current UNIX timestamp is appended to the path specified in `host_perfdata_path` and `service_perfdata_path` to generate a unique filename. ### SyslogLogger Specifies Icinga 2 logging to syslog. This configuration object is available as `syslog` [logging feature](14-features.md#logging). Example: ``` object SyslogLogger "syslog" { severity = "warning" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- severity | String | **Optional.** The minimum severity for this log. Can be "debug", "notice", "information", "warning" or "critical". Defaults to "information". facility | String | **Optional.** Defines the facility to use for syslog entries. This can be a facility constant like `FacilityDaemon`. Defaults to `FacilityUser`. Facility Constants: Name | Facility | Description ---------------------|---------------|---------------- FacilityAuth | LOG\_AUTH | The authorization system. FacilityAuthPriv | LOG\_AUTHPRIV | The same as `FacilityAuth`, but logged to a file readable only by selected individuals. FacilityCron | LOG\_CRON | The cron daemon. FacilityDaemon | LOG\_DAEMON | System daemons that are not provided for explicitly by other facilities. FacilityFtp | LOG\_FTP | The file transfer protocol daemons. FacilityKern | LOG\_KERN | Messages generated by the kernel. These cannot be generated by any user processes. FacilityLocal0 | LOG\_LOCAL0 | Reserved for local use. FacilityLocal1 | LOG\_LOCAL1 | Reserved for local use. FacilityLocal2 | LOG\_LOCAL2 | Reserved for local use. FacilityLocal3 | LOG\_LOCAL3 | Reserved for local use. FacilityLocal4 | LOG\_LOCAL4 | Reserved for local use. FacilityLocal5 | LOG\_LOCAL5 | Reserved for local use. FacilityLocal6 | LOG\_LOCAL6 | Reserved for local use. FacilityLocal7 | LOG\_LOCAL7 | Reserved for local use. FacilityLpr | LOG\_LPR | The line printer spooling system. FacilityMail | LOG\_MAIL | The mail system. FacilityNews | LOG\_NEWS | The network news system. FacilitySyslog | LOG\_SYSLOG | Messages generated internally by syslogd. FacilityUser | LOG\_USER | Messages generated by user processes. This is the default facility identifier if none is specified. FacilityUucp | LOG\_UUCP | The UUCP system. ### WindowsEventLogLogger Specifies Icinga 2 logging to the Windows Event Log. This configuration object is available as `windowseventlog` [logging feature](14-features.md#logging). Example: ``` object WindowsEventLogLogger "windowseventlog" { severity = "information" } ``` Configuration Attributes: Name | Type | Description --------------------------|-----------------------|---------------------------------- severity | String | **Optional.** The minimum severity for this log. Can be "debug", "notice", "information", "warning" or "critical". Defaults to "information". icinga2-2.14.6/doc/10-icinga-template-library.md000066400000000000000000016424071501332562400211510ustar00rootroot00000000000000# Icinga Template Library The Icinga Template Library (ITL) implements standard templates and object definitions. There is a subset of templates and object definitions available: * [Generic ITL templates](10-icinga-template-library.md#itl-generic-templates) * [CheckCommand definitions for Icinga 2](10-icinga-template-library.md#itl-check-commands) (this includes [icinga](10-icinga-template-library.md#itl-icinga), [cluster](10-icinga-template-library.md#itl-icinga-cluster), [cluster-zone](10-icinga-template-library.md#itl-icinga-cluster-zone), [ido](10-icinga-template-library.md#itl-icinga-ido), etc.) * [CheckCommand definitions for Monitoring Plugins](10-icinga-template-library.md#plugin-check-commands-monitoring-plugins) * [CheckCommand definitions for Icinga 2 Windows Plugins](10-icinga-template-library.md#windows-plugins) * [CheckCommand definitions for NSClient++](10-icinga-template-library.md#nscp-plugin-check-commands) * [CheckCommand definitions for Manubulon SNMP](10-icinga-template-library.md#snmp-manubulon-plugin-check-commands) * [Contributed CheckCommand definitions](10-icinga-template-library.md#plugin-contrib) The ITL content is updated with new releases. Please do not modify templates and/or objects as changes will be overridden without further notice. You are advised to create your own CheckCommand definitions in `/etc/icinga2`. ## Generic Templates By default the generic templates are included in the [icinga2.conf](04-configuration.md#icinga2-conf) configuration file: ``` include ``` These templates are imported by the provided example configuration. > **Note**: > > These templates are built into the binaries. By convention > all command and timeperiod objects should import these templates. ### plugin-check-command Command template for check plugins executed by Icinga 2. The `plugin-check-command` command does not support any vars. By default this template is automatically imported into all [CheckCommand](09-object-types.md#objecttype-checkcommand) definitions. ### plugin-notification-command Command template for notification scripts executed by Icinga 2. The `plugin-notification-command` command does not support any vars. By default this template is automatically imported into all [NotificationCommand](09-object-types.md#objecttype-notificationcommand) definitions. ### plugin-event-command Command template for event handler scripts executed by Icinga 2. The `plugin-event-command` command does not support any vars. By default this template is automatically imported into all [EventCommand](09-object-types.md#objecttype-eventcommand) definitions. ### legacy-timeperiod Timeperiod template for [TimePeriod objects](09-object-types.md#objecttype-timeperiod). The `legacy-timeperiod` timeperiod does not support any vars. By default this template is automatically imported into all [TimePeriod](09-object-types.md#objecttype-timeperiod) definitions. ## Check Commands These check commands are embedded into Icinga 2 and do not require any external plugin scripts. ### icinga Check command for the built-in `icinga` check. This check returns performance data for the current Icinga instance, reports as warning if the last reload or config sync failed and optionally allows for minimum version checks. For the config sync check to work, it must be run on the satellite or agent. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------|--------------- icinga\_min\_version | **Optional.** Required minimum Icinga 2 version, e.g. `2.8.0`. If not satisfied, the state changes to `Critical`. Release packages only. ### cluster Check command for the built-in `cluster` check. This check returns performance data for the current Icinga instance and connected endpoints. The `cluster` check command does not support any vars. ### cluster-zone Check command for the built-in `cluster-zone` check. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------|--------------- cluster\_zone | **Required.** The zone name. Defaults to `$host.name$`. cluster\_lag\_warning | **Optional.** Warning threshold for log lag in seconds. Applies if the log lag is greater than the threshold. cluster\_lag\_critical | **Optional.** Critical threshold for log lag in seconds. Applies if the log lag is greater than the threshold. ### icingadb Check command for the built-in `icingadb` check. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------------------------|----------------------------- icingadb\_name | **Required.** The name of the Icinga DB connection object. Defaults to `icingadb`. icingadb\_full\_dump\_duration\_warning | **Optional.** Warning threshold for ongoing Redis dump duration. Applies if the value is higher than the threshold. Defaults to 5 minutes. icingadb\_full\_dump\_duration\_critical | **Optional.** Critical threshold for ongoing Redis dump duration. Applies if the value is higher than the threshold. Defaults to 10 minutes. icingadb\_full\_sync\_duration\_warning | **Optional.** Warning threshold for ongoing database sync duration. Applies if the value is higher than the threshold. Defaults to 5 minutes. icingadb\_full\_sync\_duration\_critical | **Optional.** Critical threshold for ongoing database sync duration. Applies if the value is higher than the threshold. Defaults to 10 minutes. icingadb\_redis\_backlog\_warning | **Optional.** Warning threshold for Redis write backlog. Applies if the value is higher than the threshold. Defaults to 5 minutes. icingadb\_redis\_backlog\_critical | **Optional.** Critical threshold for Redis write backlog. Applies if the value is higher than the threshold. Defaults to 15 minutes. icingadb\_database\_backlog\_warning | **Optional.** Warning threshold for database sync backlog. Applies if the value is higher than the threshold. Defaults to 5 minutes. icingadb\_database\_backlog\_critical | **Optional.** Critical threshold for database sync backlog. Applies if the value is higher than the threshold. Defaults to 15 minutes. ### ido Check command for the built-in `ido` check. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|----------------------------- ido\_type | **Required.** The type of the IDO connection object. Can be either "IdoMysqlConnection" or "IdoPgsqlConnection". ido\_name | **Required.** The name of the IDO connection object. ido\_queries\_warning | **Optional.** Warning threshold for queries/s. Applies if the rate is lower than the threshold. ido\_queries\_critical | **Optional.** Critical threshold for queries/s. Applies if the rate is lower than the threshold. ido\_pending\_queries\_warning | **Optional.** Warning threshold for pending queries. Applies if pending queries are higher than the threshold. Supersedes the `ido_queries` thresholds above. ido\_pending\_queries\_critical | **Optional.** Critical threshold for pending queries. Applies if pending queries are higher than the threshold. Supersedes the `ido_queries` thresholds above. ### dummy Check command for the built-in `dummy` check. This allows to set a check result state and output and can be used in [freshness checks](08-advanced-topics.md#check-result-freshness) or [runtime object checks](08-advanced-topics.md#access-object-attributes-at-runtime). In contrast to the [check_dummy](https://www.monitoring-plugins.org/doc/man/check_dummy.html) plugin, Icinga 2 implements a light-weight in memory check with 2.9+. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- dummy\_state | **Optional.** The state. Can be one of 0 (ok), 1 (warning), 2 (critical) and 3 (unknown). Defaults to 0. dummy\_text | **Optional.** Plugin output. Defaults to "Check was successful.". ### passive Specialised check command object for passive checks which uses the functionality of the "dummy" check command with appropriate default values. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- dummy_state | **Optional.** The state. Can be one of 0 (ok), 1 (warning), 2 (critical) and 3 (unknown). Defaults to 3. dummy_text | **Optional.** Plugin output. Defaults to "No Passive Check Result Received.". ### random Check command for the built-in `random` check. This check returns random states and adds the check source to the check output. For test and demo purposes only. The `random` check command does not support any vars. ### exception Check command for the built-in `exception` check. This check throws an exception. For test and demo purposes only. The `exception` check command does not support any vars. ### sleep Check command for the built-in `sleep` check. This allows to use sleep for testing and debugging only. Name | Description ----------------|-------------- sleep\_time | **Optional.** The duration of the sleep in seconds. Defaults to 1s. ### ifw-api Built-in check command for executing arbitrary PowerShell check commands via the [Icinga for Windows REST API](https://icinga.com/docs/icinga-for-windows/latest/doc/110-Installation/30-API-Check-Forwarder/). Consult that documentation for why and how to optimally use the `ifw-api` command as an addon for existing Icinga clusters with Icinga for Windows. In short, that feature lets the PowerShell processes spawned by Icinga just talk to the pre-loaded IfW API instead of loading all PowerShell check commands by itself on every check. In contrast, the `ifw-api` command doesn't even spawn any process, but communicates directly with the IfW API. It may be also used like e.g. [check_by_ssh](#plugin-check-command-by-ssh). Its custom variables provide high flexibility. From using a custom CA to controlling the IfW API directly from a Linux satellite. Optional custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): | Name | Default | Description | |-------------------------|-------------------|-------------------------------------------------------------------------------------------------------------| | ifw\_api\_command | `$command.name$` | Command to run. | | ifw\_api\_arguments | {} (none) | Arguments for the command, similar to [CheckCommand](09-object-types.md#objecttype-checkcommand)#arguments. | | ifw\_api\_host | null (localhost) | IfW API host. | | ifw\_api\_port | 5668 | IfW API port. | | ifw\_api\_expected\_san | `$ifw_api_host$` | Peer TLS certificate SAN (and SNI). null means agent NodeName. | | ifw\_api\_cert | null (Icinga PKI) | TLS client certificate path. | | ifw\_api\_key | null (Icinga PKI) | TLS client private key path. | | ifw\_api\_ca | null (Icinga PKI) | Peer TLS CA certificate path. | | ifw\_api\_crl | null (none) | Path to TLS CRL to check peer against. | | ifw\_api\_username | null (none) | Basic auth username. | | ifw\_api\_password | null (none) | Basic auth password. | !!! info Due to how Icinga 2 resolves macros and serializes the resolved values for sending to a command endpoint (if any), ifw\_api\_arguments may not directly contain functions for the case `ifw-api` is used with command endpoints. Only macro strings referring to custom variables which are set to functions work. #### Remarks * `$command.name$` is resolved at runtime to the name of the specific check command being run and not any of the templates it imports, i.e. it becomes e.g. "Invoke-IcingaCheckCPU" if "ifw-api" is imported there * `ifw-api` connects to localhost (if ifw\_api\_host is null), but expects the peer to identify itself via TLS with the NodeName of the endpoint actually running the command (if ifw\_api\_expected\_san is null) * The actual values of ifw\_api\_cert, ifw\_api\_key, ifw\_api\_ca and ifw\_api\_crl are also resolved to the Icinga PKI on the command endpoint if null ## Plugin Check Commands for Monitoring Plugins The Plugin Check Commands provides example configuration for plugin check commands provided by the [Monitoring Plugins](https://www.monitoring-plugins.org) project. By default the Plugin Check Commands are included in the [icinga2.conf](04-configuration.md#icinga2-conf) configuration file: include The plugin check commands assume that there's a global constant named `PluginDir` which contains the path of the plugins from the Monitoring Plugins project. > **Note**: > > Please be aware that the CheckCommand definitions are based on the [Monitoring Plugins](https://www.monitoring-plugins.org), other Plugin collections might not support > all parameters. If there are command parameters missing for the provided CheckCommand definitions please kindly send a patch upstream. > This should include an update for the ITL CheckCommand itself and this documentation section. ### apt The plugin [apt](https://www.monitoring-plugins.org/doc/man/check_apt.html) checks for software updates on systems that use package management systems based on the apt-get(8) command found in Debian based systems. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- apt_extra_opts | **Optional.** Read options from an ini file. apt_upgrade | **Optional.** [Default] Perform an upgrade. If an optional OPTS argument is provided, apt-get will be run with these command line options instead of the default. apt_dist_upgrade | **Optional.** Perform a dist-upgrade instead of normal upgrade. Like with -U OPTS can be provided to override the default options. apt_include | **Optional.** Include only packages matching REGEXP. Can be specified multiple times the values will be combined together. apt_exclude | **Optional.** Exclude packages matching REGEXP from the list of packages that would otherwise be included. Can be specified multiple times. apt_critical | **Optional.** If the full package information of any of the upgradable packages match this REGEXP, the plugin will return CRITICAL status. Can be specified multiple times. apt_timeout | **Optional.** Seconds before plugin times out (default: 10). apt_only_critical | **Optional.** Only warn about critical upgrades. apt_list | **Optional.** List packages available for upgrade. ### breeze The [check_breeze](https://www.monitoring-plugins.org/doc/man/check_breeze.html) plugin reports the signal strength of a Breezecom wireless equipment. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------|--------------------------------- breeze_hostname | **Required.** Name or IP address of host to check. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. breeze_community | **Optional.** SNMPv1 community. Defaults to "public". breeze_warning | **Required.** Percentage strength below which a WARNING status will result. Defaults to 50. breeze_critical | **Required.** Percentage strength below which a WARNING status will result. Defaults to 20. ### by_ssh The [check_by_ssh](https://www.monitoring-plugins.org/doc/man/check_by_ssh.html) plugin uses SSH to execute commands on a remote host. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------- | -------------- by_ssh_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. by_ssh_port | **Optional.** The SSH port. Defaults to 22. by_ssh_command | **Required.** The command that should be executed. Can be an array if multiple arguments should be passed to `check_by_ssh`. by_ssh_arguments | **Optional.** A dictionary with arguments for the command. This works exactly like the 'arguments' dictionary for ordinary CheckCommands. by_ssh_logname | **Optional.** The SSH username. by_ssh_identity | **Optional.** The SSH identity. by_ssh_quiet | **Optional.** Whether to suppress SSH warnings. Defaults to false. by_ssh_warn | **Optional.** The warning threshold. by_ssh_crit | **Optional.** The critical threshold. by_ssh_timeout | **Optional.** The timeout in seconds. by_ssh_options | **Optional.** Call ssh with '-o OPTION' (multiple options may be specified as an array). by_ssh_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. by_ssh_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. by_ssh_skip_stderr | **Optional.** Ignore all or (if specified) first n lines on STDERR. ### clamd The [check_clamd](https://www.monitoring-plugins.org/doc/man/check_clamd.html) plugin tests CLAMD connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -------------------|-------------- clamd_address | **Required.** The host's address or unix socket (must be an absolute path). clamd_port | **Optional.** Port number (default: none). clamd_expect | **Optional.** String to expect in server response. Multiple strings must be defined as array. clamd_all | **Optional.** All expect strings need to occur in server response. Defaults to false. clamd_escape_send | **Optional.** Enable usage of \\n, \\r, \\t or \\\\ in send string. clamd_send | **Optional.** String to send to the server. clamd_escape_quit | **Optional.** Enable usage of \\n, \\r, \\t or \\\\ in quit string. clamd_quit | **Optional.** String to send server to initiate a clean close of the connection. clamd_refuse | **Optional.** Accept TCP refusals with states ok, warn, crit. Defaults to crit. clamd_mismatch | **Optional.** Accept expected string mismatches with states ok, warn, crit. Defaults to warn. clamd_jail | **Optional.** Hide output from TCP socket. clamd_maxbytes | **Optional.** Close connection once more than this number of bytes are received. clamd_delay | **Optional.** Seconds to wait between sending string and polling for response. clamd_certificate | **Optional.** Minimum number of days a certificate has to be valid. 1st value is number of days for warning, 2nd is critical (if not specified: 0) -- separated by comma. clamd_ssl | **Optional.** Use SSL for the connection. Defaults to false. clamd_wtime | **Optional.** Response time to result in warning status (seconds). clamd_ctime | **Optional.** Response time to result in critical status (seconds). clamd_timeout | **Optional.** Seconds before connection times out. Defaults to 10. clamd_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. clamd_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### dhcp The [check_dhcp](https://www.monitoring-plugins.org/doc/man/check_dhcp.html) plugin tests the availability of DHCP servers on a network. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- dhcp_serverip | **Optional.** The IP address of the DHCP server which we should get a response from. dhcp_requestedip| **Optional.** The IP address which we should be offered by a DHCP server. dhcp_timeout | **Optional.** The timeout in seconds. dhcp_interface | **Optional.** The interface to use. dhcp_mac | **Optional.** The MAC address to use in the DHCP request. dhcp_unicast | **Optional.** Whether to use unicast requests. Defaults to false. ### dig The [check_dig](https://www.monitoring-plugins.org/doc/man/check_dig.html) plugin test the DNS service on the specified host using dig. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------|-------------- dig_server | **Optional.** The DNS server to query. Defaults to "127.0.0.1". dig_port | **Optional.** Port number (default: 53). dig_lookup | **Required.** The address that should be looked up. dig_record_type | **Optional.** Record type to lookup (default: A). dig_expected_address | **Optional.** An address expected to be in the answer section. If not set, uses whatever was in -l. dig_arguments | **Optional.** Pass STRING as argument(s) to dig. dig_retries | **Optional.** Number of retries passed to dig, timeout is divided by this value (Default: 3). dig_warning | **Optional.** Response time to result in warning status (seconds). dig_critical | **Optional.** Response time to result in critical status (seconds). dig_timeout | **Optional.** Seconds before connection times out (default: 10). dig_ipv4 | **Optional.** Force dig to only use IPv4 query transport. Defaults to false. dig_ipv6 | **Optional.** Force dig to only use IPv6 query transport. Defaults to false. ### disk The [check_disk](https://www.monitoring-plugins.org/doc/man/check_disk.html) plugin checks the amount of used disk space on a mounted file system and generates an alert if free space is less than one of the threshold values. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------|------------------------ disk\_wfree | **Optional.** The free space warning threshold. Defaults to "20%". If the percent sign is omitted, units from `disk_units` are used. disk\_cfree | **Optional.** The free space critical threshold. Defaults to "10%". If the percent sign is omitted, units from `disk_units` are used. disk\_inode\_wfree | **Optional.** The free inode warning threshold. disk\_inode\_cfree | **Optional.** The free inode critical threshold. disk\_partition | **Optional.** The partition. **Deprecated in 2.3.** disk\_partition\_excluded | **Optional.** The excluded partition. **Deprecated in 2.3.** disk\_partitions | **Optional.** The partition(s). Multiple partitions must be defined as array. disk\_partitions\_excluded | **Optional.** The excluded partition(s). Multiple partitions must be defined as array. disk\_clear | **Optional.** Clear thresholds. May be true or false. disk\_exact\_match | **Optional.** For paths or partitions specified with -p, only check for exact paths. May be true or false. disk\_errors\_only | **Optional.** Display only devices/mountpoints with errors. May be true or false. disk\_ignore\_reserved | **Optional.** If set, account root-reserved blocks are not accounted for freespace in perfdata. May be true or false. disk\_group | **Optional.** Group paths. Thresholds apply to (free-)space of all partitions together. disk\_kilobytes | **Optional.** Same as --units kB. May be true or false. disk\_local | **Optional.** Only check local filesystems. May be true or false. disk\_stat\_remote\_fs | **Optional.** Only check local filesystems against thresholds. Yet call stat on remote filesystems to test if they are accessible (e.g. to detect Stale NFS Handles). May be true or false. disk\_mountpoint | **Optional.** Display the mountpoint instead of the partition. May be true or false. disk\_megabytes | **Optional.** Same as --units MB. May be true or false. disk\_all | **Optional.** Explicitly select all paths. This is equivalent to -R '.\*'. May be true or false. disk\_eregi\_path | **Optional.** Case insensitive regular expression for path/partition. Multiple regular expression strings must be defined as array. disk\_ereg\_path | **Optional.** Regular expression for path or partition. Multiple regular expression strings must be defined as array. disk\_ignore\_eregi\_path | **Optional.** Regular expression to ignore selected path/partition (case insensitive). Multiple regular expression strings must be defined as array. disk\_ignore\_ereg\_path | **Optional.** Regular expression to ignore selected path or partition. Multiple regular expression strings must be defined as array. disk\_timeout | **Optional.** Seconds before connection times out (default: 10). disk\_units | **Optional.** Choose bytes, kB, MB, GB, TB. disk\_exclude\_type | **Optional.** Ignore all filesystems of indicated type. Multiple regular expression strings must be defined as array. Defaults to "none", "tmpfs", "sysfs", "proc", "configfs", "devtmpfs", "devfs", "mtmfs", "tracefs", "cgroup", "fuse.gvfsd-fuse", "fuse.gvfs-fuse-daemon", "fdescfs", "overlay", "nsfs", "squashfs". disk\_include\_type | **Optional.** Check only filesystems of indicated type. Multiple regular expression strings must be defined as array. disk\_inode\_perfdata | **Optional.** Display inode usage in perfdata ### disk_smb The [check_disk_smb](https://www.monitoring-plugins.org/doc/man/check_disk_smb.html) plugin uses the `smbclient` binary to check SMB shares. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|------------------------ disk_smb_hostname | **Required.** NetBIOS name of the server. disk_smb_share | **Required.** Share name being queried. disk_smb_workgroup | **Optional.** Workgroup or Domain used (defaults to 'WORKGROUP' if omitted). disk_smb_address | **Optional.** IP address of the host (only necessary if host belongs to another network). disk_smb_username | **Optional.** Username for server log-in (defaults to 'guest' if omitted). disk_smb_password | **Optional.** Password for server log-in (defaults to an empty password if omitted). disk_smb_wused | **Optional.** The used space warning threshold. Defaults to "85%". If the percent sign is omitted, use optional disk units. disk_smb_cused | **Optional.** The used space critical threshold. Defaults to "95%". If the percent sign is omitted, use optional disk units. disk_smb_port | **Optional.** Connection port, e.g. `139` or `445`. Defaults to `smbclient` default if omitted. ### dns The [check_dns](https://www.monitoring-plugins.org/doc/man/check_dns.html) plugin uses the nslookup program to obtain the IP address for the given host/domain query. An optional DNS server to use may be specified. If no DNS server is specified, the default server(s) specified in `/etc/resolv.conf` will be used. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------|-------------- dns_lookup | **Optional.** The hostname or IP to query the DNS for. Defaults to "$host_name$". dns_server | **Optional.** The DNS server to query. Defaults to the server configured in the OS. dns_query_type | **Optional.** The DNS record query type where TYPE =(A, AAAA, SRV, TXT, MX, ANY). The default query type is 'A' (IPv4 host entry). **Only supported by the Nagios plugins version of check\_dns, not by the monitoring plugins one.** dns_expected_answers | **Optional.** The answer(s) to look for. A hostname must end with a dot. Format depends on the monitoring-plugins version: In version 2.2 and before, a single string with the values alphabetically ordered and joined by commas. In version 2.3 and later, multiple answers must be defined as array. dns_all_expected | **Optional.** Denotes whether to require all values passed in `dns_expected_answers` to pass, or at least one. Only supported in newer versions of monitoring-plugins (2.3 and later), and is needed in such versions to replicate behaviour of previous versions of the plugins. dns_authoritative | **Optional.** Expect the server to send an authoritative answer. dns_accept_cname | **Optional.** Accept cname responses as a valid result to a query. dns_wtime | **Optional.** Return warning if elapsed time exceeds value. dns_ctime | **Optional.** Return critical if elapsed time exceeds value. dns_timeout | **Optional.** Seconds before connection times out. Defaults to 10. ### file_age The [check_file_age](https://www.monitoring-plugins.org/doc/man/check_file_age.html) plugin checks a file's size and modification time to make sure it's not empty and that it's sufficiently recent. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------|-------------------------------------------------------------------------------------------------------- file_age_file | **Required.** File to monitor. file_age_warning_time | **Optional.** File must be no more than this many seconds old as warning threshold. Defaults to "240s". file_age_critical_time | **Optional.** File must be no more than this many seconds old as critical threshold. Defaults to "600s". file_age_warning_size | **Optional.** File must be at least this many bytes long as warning threshold. No default given. file_age_critical_size | **Optional.** File must be at least this many bytes long as critical threshold. Defaults to "0B". file_age_ignoremissing | **Optional.** Return OK if the file does not exist. Defaults to false. ### flexlm The [check_flexlm](https://www.monitoring-plugins.org/doc/man/check_flexlm.html) plugin checks available flexlm license managers. Requires the `lmstat` command. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -------------------|---------------------------------------------------------- flexlm_licensefile | **Required.** Name of license file (usually license.dat). flexlm_timeout | **Optional.** Plugin time out in seconds. Defaults to 15. ### fping4 The [check_fping](https://www.monitoring-plugins.org/doc/man/check_fping.html) plugin uses the `fping` command to ping the specified host for a fast check. Note that it is necessary to set the `suid` flag on `fping`. This CheckCommand expects an IPv4 address. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- fping_address | **Optional.** The host's IPv4 address. Defaults to "$address$". fping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. fping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. fping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. fping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. fping_number | **Optional.** The number of packets to send. Defaults to 5. fping_interval | **Optional.** The interval between packets in milli-seconds. Defaults to 500. fping_bytes | **Optional.** The size of ICMP packet. fping_target_timeout | **Optional.** The target timeout in milli-seconds. fping_source_ip | **Optional.** The name or ip address of the source ip. fping_source_interface | **Optional.** The source interface name. ### fping6 The [check_fping](https://www.monitoring-plugins.org/doc/man/check_fping.html) plugin will use the `fping` command to ping the specified host for a fast check. Note that it is necessary to set the `suid` flag on `fping`. This CheckCommand expects an IPv6 address. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- fping_address | **Optional.** The host's IPv6 address. Defaults to "$address6$". fping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. fping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. fping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. fping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. fping_number | **Optional.** The number of packets to send. Defaults to 5. fping_interval | **Optional.** The interval between packets in milli-seconds. Defaults to 500. fping_bytes | **Optional.** The size of ICMP packet. fping_target_timeout | **Optional.** The target timeout in milli-seconds. fping_source_ip | **Optional.** The name or ip address of the source ip. fping_source_interface | **Optional.** The source interface name. ### ftp The [check_ftp](https://www.monitoring-plugins.org/doc/man/check_ftp.html) plugin tests FTP connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -------------------|-------------- ftp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ftp_port | **Optional.** The FTP port number. ftp_expect | **Optional.** String to expect in server response. Multiple strings must be defined as array. ftp_all | **Optional.** All expect strings need to occur in server response. Defaults to false. ftp_escape_send | **Optional.** Enable usage of \\n, \\r, \\t or \\\\ in send string. ftp_send | **Optional.** String to send to the server. ftp_escape_quit | **Optional.** Enable usage of \\n, \\r, \\t or \\\\ in quit string. ftp_quit | **Optional.** String to send server to initiate a clean close of the connection. ftp_refuse | **Optional.** Accept TCP refusals with states ok, warn, crit. Defaults to crit. ftp_mismatch | **Optional.** Accept expected string mismatches with states ok, warn, crit. Defaults to warn. ftp_jail | **Optional.** Hide output from TCP socket. ftp_maxbytes | **Optional.** Close connection once more than this number of bytes are received. ftp_delay | **Optional.** Seconds to wait between sending string and polling for response. ftp_certificate | **Optional.** Minimum number of days a certificate has to be valid. 1st value is number of days for warning, 2nd is critical (if not specified: 0) -- separated by comma. ftp_ssl | **Optional.** Use SSL for the connection. Defaults to false. ftp_wtime | **Optional.** Response time to result in warning status (seconds). ftp_ctime | **Optional.** Response time to result in critical status (seconds). ftp_timeout | **Optional.** Seconds before connection times out. Defaults to 10. ftp_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. ftp_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### game The [check_game](https://www.monitoring-plugins.org/doc/man/check_game.html) plugin tests game server connections with the specified host. This plugin uses the 'qstat' command, the popular game server status query tool. If you don't have the package installed, you will need to [download](http://www.activesw.com/people/steve/qstat.html) or install the package `quakestat` before you can use this plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -------------------|------------------- game_game | **Required.** Name of the game. game_ipaddress | **Required.** Ipaddress of the game server to query. game_timeout | **Optional.** Seconds before connection times out. Defaults to 10. game_port | **Optional.** Port to connect to. game_gamefield | **Optional.** Field number in raw qstat output that contains game name. game_mapfield | **Optional.** Field number in raw qstat output that contains map name. game_pingfield | **Optional.** Field number in raw qstat output that contains ping time. game_gametime | **Optional.** Field number in raw qstat output that contains game time. game_hostname | **Optional.** Name of the host running the game. ### hostalive Check command object for the [check_ping](https://www.monitoring-plugins.org/doc/man/check_ping.html) plugin with host check default values. This variant uses the host's `address` attribute if available and falls back to using the `address6` attribute if the `address` attribute is not set. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ping_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 3000. ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 80. ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 5000. ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 100. ping_packets | **Optional.** The number of packets to send. Defaults to 5. ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### hostalive4 Check command object for the [check_ping](https://www.monitoring-plugins.org/doc/man/check_ping.html) plugin with host check default values. This variant uses the host's `address` attribute. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ping_address | **Optional.** The host's IPv4 address. Defaults to "$address$". ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 3000. ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 80. ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 5000. ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 100. ping_packets | **Optional.** The number of packets to send. Defaults to 5. ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### hostalive6 Check command object for the [check_ping](https://www.monitoring-plugins.org/doc/man/check_ping.html) plugin with host check default values. This variant uses the host's `address6` attribute. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ping_address | **Optional.** The host's IPv6 address. Defaults to "$address6$". ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 3000. ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 80. ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 5000. ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 100. ping_packets | **Optional.** The number of packets to send. Defaults to 5. ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### hpjd The [check_hpjd](https://www.monitoring-plugins.org/doc/man/check_hpjd.html) plugin tests the state of an HP printer with a JetDirect card. Net-snmp must be installed on the computer running the plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- hpjd_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. hpjd_port | **Optional.** The host's SNMP port. Defaults to 161. hpjd_community | **Optional.** The SNMP community. Defaults to "public". ### http The [check_http](https://www.monitoring-plugins.org/doc/man/check_http.html) plugin tests the HTTP service on the specified host. It can test normal (http) and secure (https) servers, follow redirects, search for strings and regular expressions, check connection times, and report on certificate expiration times. The plugin can either test the HTTP response of a server, or if `http_certificate` is set to a non-empty value, the TLS certificate age for a HTTPS host. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|--------------------------------- http_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. http_vhost | **Optional.** The virtual host that should be sent in the "Host" header. http_uri | **Optional.** The request URI for GET or POST. Defaults to `/`. http_port | **Optional.** The TCP port. Defaults to 80 when not using SSL, 443 otherwise. http_ssl | **Optional.** Whether to use SSL. Defaults to false. http_ssl_force_tlsv1 | **Optional.** Whether to force TLSv1. http_ssl_force_tlsv1_1 | **Optional.** Whether to force TLSv1.1. http_ssl_force_tlsv1_2 | **Optional.** Whether to force TLSv1.2. http_ssl_force_sslv2 | **Optional.** Whether to force SSLv2. http_ssl_force_sslv3 | **Optional.** Whether to force SSLv3. http_ssl_force_tlsv1_or_higher | **Optional.** Whether to force TLSv1 or higher. http_ssl_force_tlsv1_1_or_higher | **Optional.** Whether to force TLSv1.1 or higher. http_ssl_force_tlsv1_2_or_higher | **Optional.** Whether to force TLSv1.2 or higher. http_ssl_force_sslv2_or_higher | **Optional.** Whether to force SSLv2 or higher. http_ssl_force_sslv3_or_higher | **Optional.** Whether to force SSLv3 or higher. http_sni | **Optional.** Whether to use SNI. Defaults to false. http_auth_pair | **Optional.** Add 'username:password' authorization pair. http_proxy_auth_pair | **Optional.** Add 'username:password' authorization pair for proxy. http_ignore_body | **Optional.** Don't download the body, just the headers. http_linespan | **Optional.** Allow regex to span newline. http_expect_body_regex | **Optional.** A regular expression which the body must match against. Incompatible with http_ignore_body. http_expect_body_eregi | **Optional.** A case-insensitive expression which the body must match against. Incompatible with http_ignore_body. http_invertregex | **Optional.** Changes behavior of http_expect_body_regex and http_expect_body_eregi to return CRITICAL if found, OK if not. http_warn_time | **Optional.** The warning threshold. http_critical_time | **Optional.** The critical threshold. http_expect | **Optional.** Comma-delimited list of strings, at least one of them is expected in the first (status) line of the server response. Default: HTTP/1. http_certificate | **Optional.** Minimum number of days a certificate has to be valid. Port defaults to 443. When this option is used the URL is not checked. The first parameter defines the warning threshold (in days), the second parameter the critical threshold (in days). (Example `http_certificate = "30,20"`). http_clientcert | **Optional.** Name of file contains the client certificate (PEM format). http_privatekey | **Optional.** Name of file contains the private key (PEM format). http_headerstring | **Optional.** String to expect in the response headers. http_string | **Optional.** String to expect in the content. http_post | **Optional.** URL encoded http POST data. http_method | **Optional.** Set http method (for example: HEAD, OPTIONS, TRACE, PUT, DELETE). http_maxage | **Optional.** Warn if document is more than seconds old. http_contenttype | **Optional.** Specify Content-Type header when POSTing. http_useragent | **Optional.** String to be sent in http header as User Agent. http_header | **Optional.** Any other tags to be sent in http header. Can be an array if multiple headers should be passed to `check_http`. http_extendedperfdata | **Optional.** Print additional perfdata. Defaults to false. http_onredirect | **Optional.** How to handle redirect pages. Possible values: "ok" (default), "warning", "critical", "follow", "sticky" (like follow but stick to address), "stickyport" (like sticky but also to port) http_pagesize | **Optional.** Minimum page size required:Maximum page size required. http_timeout | **Optional.** Seconds before connection times out. http_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. http_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. http_link | **Optional.** Wrap output in HTML link. Defaults to false. http_verbose | **Optional.** Show details for command-line debugging. Defaults to false. http_verify_host | **Optional.** Verify SSL certificate is for the -H hostname (with --sni and -S). Defaults to false. **Only supported by the Nagios plugins version of check\_http, not by the monitoring plugins one.** ### icmp The [check_icmp](https://www.monitoring-plugins.org/doc/man/check_icmp.html) plugin check_icmp allows for checking multiple hosts at once compared to `check_ping`. The main difference is that check_ping executes the system's ping(1) command and parses its output while `check_icmp` talks ICMP itself. `check_icmp` must be installed with `setuid` root. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- icmp_address | **Optional.** The host's address. This can either be a single address or an array of addresses. Defaults to "$address$". icmp_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. icmp_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 10. icmp_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. icmp_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 30. icmp_source | **Optional.** The source IP address to send packets from. icmp_packets | **Optional.** The number of packets to send. Defaults to 5. icmp_packet_interval | **Optional** The maximum packet interval. Defaults to 80 (milliseconds). icmp_target_interval | **Optional.** The maximum target interval. icmp_hosts_alive | **Optional.** The number of hosts which have to be alive for the check to succeed. icmp_data_bytes | **Optional.** Payload size for each ICMP request. Defaults to 8. icmp_timeout | **Optional.** The plugin timeout in seconds. Defaults to 10 (seconds). icmp_ttl | **Optional.** The TTL on outgoing packets. ### imap The [check_imap](https://www.monitoring-plugins.org/doc/man/check_imap.html) plugin tests IMAP connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------------|-------------- imap_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. imap_port | **Optional.** The port that should be checked. Defaults to 143. imap_escape | **Optional.** Can use \\n, \\r, \\t or \\ in send or quit string. Must come before send or quit option. Default: nothing added to send, \\r\\n added to end of quit. imap_send | **Optional.** String to send to the server. imap_expect | **Optional.** String to expect in server response. Multiple strings must be defined as array. imap_all | **Optional.** All expect strings need to occur in server response. Default is any. imap_quit | **Optional.** String to send server to initiate a clean close of the connection. imap_refuse | **Optional.** Accept TCP refusals with states ok, warn, crit (default: crit). imap_mismatch | **Optional.** Accept expected string mismatches with states ok, warn, crit (default: warn). imap_jail | **Optional.** Hide output from TCP socket. imap_maxbytes | **Optional.** Close connection once more than this number of bytes are received. imap_delay | **Optional.** Seconds to wait between sending string and polling for response. imap_certificate_age | **Optional.** Minimum number of days a certificate has to be valid. imap_ssl | **Optional.** Use SSL for the connection. imap_warning | **Optional.** Response time to result in warning status (seconds). imap_critical | **Optional.** Response time to result in critical status (seconds). imap_timeout | **Optional.** Seconds before connection times out (default: 10). imap_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. imap_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### ldap The [check_ldap](https://www.monitoring-plugins.org/doc/man/check_ldap.html) plugin can be used to check LDAP servers. The plugin can also be used for monitoring ldaps connections instead of the deprecated `check_ldaps`. This can be ensured by enabling `ldap_starttls` or `ldap_ssl`. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- ldap_address | **Optional.** Host name, IP Address, or unix socket (must be an absolute path). Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ldap_port | **Optional.** Port number. Defaults to 389. ldap_attr | **Optional.** LDAP attribute to search for (default: "(objectclass=*)") ldap_base | **Required.** LDAP base (eg. ou=myunit,o=myorg,c=at). ldap_bind | **Optional.** LDAP bind DN (if required). ldap_pass | **Optional.** LDAP password (if required). ldap_starttls | **Optional.** Use STARTSSL mechanism introduced in protocol version 3. ldap_ssl | **Optional.** Use LDAPS (LDAP v2 SSL method). This also sets the default port to 636. ldap_v2 | **Optional.** Use LDAP protocol version 2 (enabled by default). ldap_v3 | **Optional.** Use LDAP protocol version 3 (disabled by default) ldap_warning | **Optional.** Response time to result in warning status (seconds). ldap_critical | **Optional.** Response time to result in critical status (seconds). ldap_warning_entries | **Optional.** Number of found entries to result in warning status. ldap_critical_entries | **Optional.** Number of found entries to result in critical status. ldap_timeout | **Optional.** Seconds before connection times out (default: 10). ldap_verbose | **Optional.** Show details for command-line debugging (disabled by default) ### load The [check_load](https://www.monitoring-plugins.org/doc/man/check_load.html) plugin tests the current system load average. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- load_wload1 | **Optional.** The 1-minute warning threshold. Defaults to 5. load_wload5 | **Optional.** The 5-minute warning threshold. Defaults to 4. load_wload15 | **Optional.** The 15-minute warning threshold. Defaults to 3. load_cload1 | **Optional.** The 1-minute critical threshold. Defaults to 10. load_cload5 | **Optional.** The 5-minute critical threshold. Defaults to 6. load_cload15 | **Optional.** The 15-minute critical threshold. Defaults to 4. load_percpu | **Optional.** Divide the load averages by the number of CPUs (when possible). Defaults to false. ### mailq The [check_mailq](https://www.monitoring-plugins.org/doc/man/check_mailq.html) plugin checks the number of messages in the mail queue (supports multiple sendmail queues, qmail). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- mailq_warning | **Required.** Min. number of messages in queue to generate warning. mailq_critical | **Required.** Min. number of messages in queue to generate critical alert ( w < c ). mailq_domain_warning | **Optional.** Min. number of messages for same domain in queue to generate warning mailq_domain_critical | **Optional.** Min. number of messages for same domain in queue to generate critical alert ( W < C ). mailq_timeout | **Optional.** Plugin timeout in seconds (default = 15). mailq_servertype | **Optional.** [ sendmail \| qmail \| postfix \| exim \| nullmailer ] (default = autodetect). mailq_sudo | **Optional.** Use sudo to execute the mailq command. ### mysql The [check_mysql](https://www.monitoring-plugins.org/doc/man/check_mysql.html) plugin tests connections to a MySQL server. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|--------------------------------------------------------------- mysql_extra_opts | **Optional.** Read options from an ini file. mysql_hostname | **Optional.** Host name, IP Address, or unix socket (must be an absolute path). mysql_port | **Optional.** Port number (default: 3306). mysql_socket | **Optional.** Use the specified socket (has no effect if `mysql_hostname` is used). mysql_ignore_auth | **Optional.** Ignore authentication failure and check for mysql connectivity only. mysql_database | **Optional.** Check database with indicated name. mysql_file | **Optional.** Read from the specified client options file. mysql_group | **Optional.** Use a client options group. mysql_username | **Optional.** Connect using the indicated username. mysql_password | **Optional.** Use the indicated password to authenticate the connection. mysql_check_slave | **Optional.** Check if the slave thread is running properly. mysql_warning | **Optional.** Exit with WARNING status if slave server is more than INTEGER seconds behind master. mysql_critical | **Optional.** Exit with CRITICAL status if slave server is more then INTEGER seconds behind master. mysql_ssl | **Optional.** Use ssl encryption. mysql_cacert | **Optional.** Path to CA signing the cert. mysql_cert | **Optional.** Path to SSL certificate. mysql_key | **Optional.** Path to private SSL key. mysql_cadir | **Optional.** Path to CA directory. mysql_ciphers | **Optional.** List of valid SSL ciphers. ### mysql_query The [check_mysql_query](https://www.monitoring-plugins.org/doc/man/check_mysql_query.html) plugin checks a query result against threshold levels. The result from the query should be numeric. For extra security, create a user with minimal access. **Note**: You must specify `mysql_query_password` with an empty string to force an empty password, overriding any my.cnf settings. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|--------------------------------------------------------------- mysql_query_hostname | **Optional.** Host name, IP Address, or unix socket (must be an absolute path). mysql_query_port | **Optional.** Port number (default: 3306). mysql_query_database | **Optional.** Check database with indicated name. mysql_query_file | **Optional.** Read from the specified client options file. mysql_query_group | **Optional.** Use a client options group. mysql_query_username | **Optional.** Connect using the indicated username. mysql_query_password | **Optional.** Use the indicated password to authenticate the connection. mysql_query_execute | **Required.** SQL Query to run on the MySQL Server. mysql_query_warning | **Optional.** Exit with WARNING status if query is outside of the range (format: start:end). mysql_query_critical | **Optional.** Exit with CRITICAL status if query is outside of the range. ### negate The [negate](https://www.monitoring-plugins.org/doc/man/negate.html) plugin negates the status of a plugin (returns OK for CRITICAL and vice-versa). Additional switches can be used to control which state becomes what. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------------|--------------------------------------------------------------- negate_timeout | **Optional.** Seconds before plugin times out (default: 11). negate_timeout_result | **Optional.** Custom result on Negate timeouts, default to UNKNOWN. negate_ok | **Optional.** OK, WARNING, CRITICAL or UNKNOWN. negate_warning | Numeric values are accepted. negate_critical | If nothing is specified, negate_unknown | permutes OK and CRITICAL. negate_substitute | **Optional.** Substitute output text as well. Will only substitute text in CAPITALS. negate_command | **Required.** Command to be negated. negate_arguments | **Optional.** Arguments for the negated command. ### nrpe The `check_nrpe` plugin can be used to query an [NRPE](https://icinga.com/docs/icinga1/latest/en/nrpe.html) server or [NSClient++](https://www.nsclient.org). **Note**: This plugin is considered insecure/deprecated. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- nrpe_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. nrpe_port | **Optional.** The NRPE port. Defaults to 5666. nrpe_command | **Optional.** The command that should be executed. nrpe_no_ssl | **Optional.** Whether to disable SSL or not. Defaults to `false`. nrpe_timeout_unknown | **Optional.** Whether to set timeouts to unknown instead of critical state. Defaults to `false`. nrpe_timeout | **Optional.** The timeout in seconds. nrpe_arguments | **Optional.** Arguments that should be passed to the command. Multiple arguments must be defined as array. nrpe_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. nrpe_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. nrpe_version_2 | **Optional.** Use this if you want to connect using NRPE v2 protocol (needed for NSClient++). Defaults to false. nrpe_version_3 | **Optional.** Use this if you want to connect using NRPE v3 protocol. Defaults to false. nrpe_payload_size | **Optional.** Specify non-default payload size for NSClient++. Default is 1024. nrpe_ca | **Optional.** The CA file to use for PKI. Defaults to none. nrpe_cert | **Optional.** The client cert file to use for PKI. Defaults to none. nrpe_key | **Optional.** The client key file to use for PKI. Defaults to none. nrpe_ssl_version | **Optional.** The SSL/TLS version to use. Defaults to TLSv1+. nrpe_cipher_list | **Optional.** The list of SSL ciphers to use. Default depends on check_nrpe version. nrpe_dh_opt | **Optional.** Anonymous Diffie Hellman use: 0 = deny, 1 = allow, 2 = force. Default depends on check_nrpe version. nrpe_no_logging | **Optional.** Disable logging of check_nrpe to syslog facilities (requires check_nrpe >= 4.0). ### nscp The [check_nt](https://www.monitoring-plugins.org/doc/man/check_nt.html) plugin collects data from the [NSClient++](https://www.nsclient.org) service. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- nscp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. nscp_port | **Optional.** The NSClient++ port. Defaults to 12489. nscp_password | **Optional.** The NSClient++ password. nscp_variable | **Required.** The variable that should be checked. nscp_params | **Optional.** Parameters for the query. Multiple parameters must be defined as array. nscp_warn | **Optional.** The warning threshold. nscp_crit | **Optional.** The critical threshold. nscp_timeout | **Optional.** The query timeout in seconds. nscp_showall | **Optional.** Use with SERVICESTATE to see working services or PROCSTATE for running processes. Defaults to false. ### ntp_time The [check_ntp_time](https://www.monitoring-plugins.org/doc/man/check_ntp_time.html) plugin checks the clock offset between the local host and a remote NTP server. **Note**: If you want to monitor an NTP server, please use `ntp_peer`. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ntp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ntp_port | **Optional.** Port number (default: 123). ntp_quiet | **Optional.** Returns UNKNOWN instead of CRITICAL if offset cannot be found. ntp_warning | **Optional.** Offset to result in warning status (seconds). ntp_critical | **Optional.** Offset to result in critical status (seconds). ntp_timeoffset | **Optional.** Expected offset of the ntp server relative to local server (seconds). ntp_timeout | **Optional.** Seconds before connection times out (default: 10). ntp_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. ntp_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### ntp_peer The [check_ntp_peer](https://www.monitoring-plugins.org/doc/man/check_ntp_peer.html) plugin checks the health of an NTP server. It supports checking the offset with the sync peer, the jitter and stratum. This plugin will not check the clock offset between the local host and NTP server; please use `ntp_time` for that purpose. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ntp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ntp_port | **Optional.** The port to use. Default to 123. ntp_quiet | **Optional.** Returns UNKNOWN instead of CRITICAL or WARNING if server isn't synchronized. ntp_warning | **Optional.** Offset to result in warning status (seconds). ntp_critical | **Optional.** Offset to result in critical status (seconds). ntp_wstratum | **Optional.** Warning threshold for stratum of server's synchronization peer. ntp_cstratum | **Optional.** Critical threshold for stratum of server's synchronization peer. ntp_wjitter | **Optional.** Warning threshold for jitter. ntp_cjitter | **Optional.** Critical threshold for jitter. ntp_wsource | **Optional.** Warning threshold for number of usable time sources. ntp_csource | **Optional.** Critical threshold for number of usable time sources. ntp_timeout | **Optional.** Seconds before connection times out (default: 10). ntp_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. ntp_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### pgsql The [check_pgsql](https://www.monitoring-plugins.org/doc/man/check_pgsql.html) plugin tests a PostgreSQL DBMS to determine whether it is active and accepting queries. If a query is specified using the `pgsql_query` attribute, it will be executed after connecting to the server. The result from the query has to be numeric in order to compare it against the query thresholds if set. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|--------------------------------------------------------------- pgsql_extra_opts | **Optional.** Read options from an ini file. pgsql_hostname | **Optional.** Host name, IP Address, or unix socket (must be an absolute path). pgsql_port | **Optional.** Port number (default: 5432). pgsql_database | **Optional.** Database to check (default: template1). pgsql_username | **Optional.** Login name of user. pgsql_password | **Optional.** Password (BIG SECURITY ISSUE). pgsql_options | **Optional.** Connection parameters (keyword = value), see below. pgsql_warning | **Optional.** Response time to result in warning status (seconds). pgsql_critical | **Optional.** Response time to result in critical status (seconds). pgsql_timeout | **Optional.** Seconds before connection times out (default: 10). pgsql_query | **Optional.** SQL query to run. Only first column in first row will be read. pgsql_query_warning | **Optional.** SQL query value to result in warning status (double). pgsql_query_critical | **Optional.** SQL query value to result in critical status (double). ### ping The [check_ping](https://www.monitoring-plugins.org/doc/man/check_ping.html) plugin uses the ping command to probe the specified host for packet loss (percentage) and round trip average (milliseconds). This command uses the host's `address` attribute if available and falls back to using the `address6` attribute if the `address` attribute is not set. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ping_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. ping_packets | **Optional.** The number of packets to send. Defaults to 5. ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### ping4 The [check_ping](https://www.monitoring-plugins.org/doc/man/check_ping.html) plugin uses the ping command to probe the specified host for packet loss (percentage) and round trip average (milliseconds). This command uses the host's `address` attribute if not explicitly specified using the `ping_address` attribute. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ping_address | **Optional.** The host's IPv4 address. Defaults to "$address$". ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. ping_packets | **Optional.** The number of packets to send. Defaults to 5. ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### ping6 The [check_ping](https://www.monitoring-plugins.org/doc/man/check_ping.html) plugin uses the ping command to probe the specified host for packet loss (percentage) and round trip average (milliseconds). This command uses the host's `address6` attribute if not explicitly specified using the `ping_address` attribute. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ping_address | **Optional.** The host's IPv6 address. Defaults to "$address6$". ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 100. ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 5. ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 200. ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 15. ping_packets | **Optional.** The number of packets to send. Defaults to 5. ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### pop The [check_pop](https://www.monitoring-plugins.org/doc/man/check_pop.html) plugin tests POP connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------|-------------- pop_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. pop_port | **Optional.** The port that should be checked. Defaults to 110. pop_escape | **Optional.** Can use \\n, \\r, \\t or \\ in send or quit string. Must come before send or quit option. Default: nothing added to send, \\r\\n added to end of quit. pop_send | **Optional.** String to send to the server. pop_expect | **Optional.** String to expect in server response. Multiple strings must be defined as array. pop_all | **Optional.** All expect strings need to occur in server response. Default is any. pop_quit | **Optional.** String to send server to initiate a clean close of the connection. pop_refuse | **Optional.** Accept TCP refusals with states ok, warn, crit (default: crit). pop_mismatch | **Optional.** Accept expected string mismatches with states ok, warn, crit (default: warn). pop_jail | **Optional.** Hide output from TCP socket. pop_maxbytes | **Optional.** Close connection once more than this number of bytes are received. pop_delay | **Optional.** Seconds to wait between sending string and polling for response. pop_certificate_age | **Optional.** Minimum number of days a certificate has to be valid. pop_ssl | **Optional.** Use SSL for the connection. pop_warning | **Optional.** Response time to result in warning status (seconds). pop_critical | **Optional.** Response time to result in critical status (seconds). pop_timeout | **Optional.** Seconds before connection times out (default: 10). pop_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. pop_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### procs The [check_procs](https://www.monitoring-plugins.org/doc/man/check_procs.html) plugin checks all processes and generates WARNING or CRITICAL states if the specified metric is outside the required threshold ranges. The metric defaults to number of processes. Search filters can be applied to limit the processes to check. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------|-------------- procs_warning | **Optional.** The process count warning threshold. Defaults to 250. procs_critical | **Optional.** The process count critical threshold. Defaults to 400. procs_metric | **Optional.** Check thresholds against metric. procs_timeout | **Optional.** Seconds before plugin times out. procs_traditional | **Optional.** Filter own process the traditional way by PID instead of /proc/pid/exe. Defaults to false. procs_state | **Optional.** Only scan for processes that have one or more of the status flags you specify. procs_ppid | **Optional.** Only scan for children of the parent process ID indicated. procs_vsz | **Optional.** Only scan for processes with VSZ higher than indicated. procs_rss | **Optional.** Only scan for processes with RSS higher than indicated. procs_pcpu | **Optional.** Only scan for processes with PCPU higher than indicated. procs_user | **Optional.** Only scan for processes with user name or ID indicated. procs_argument | **Optional.** Only scan for processes with args that contain STRING. procs_argument_regex | **Optional.** Only scan for processes with args that contain the regex STRING. procs_command | **Optional.** Only scan for exact matches of COMMAND (without path). procs_nokthreads | **Optional.** Only scan for non kernel threads. Defaults to false. ### radius The [check_radius](https://www.monitoring-plugins.org/doc/man/check_radius.html) plugin checks a RADIUS server to see if it is accepting connections. The server to test must be specified in the invocation, as well as a user name and password. A configuration file may also be present. The format of the configuration file is described in the radiusclient library sources. The password option presents a substantial security issue because the password can possibly be determined by careful watching of the command line in a process listing. This risk is exacerbated because the plugin will typically be executed at regular predictable intervals. Please be sure that the password used does not allow access to sensitive system resources. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -------------------|-------------- radius_address | **Optional.** The radius server's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. radius_config_file | **Required.** The radius configuration file. radius_username | **Required.** The radius username to test. radius_password | **Required.** The radius password to test. radius_port | **Optional.** The radius port number (default 1645). radius_nas_id | **Optional.** The NAS identifier. radius_nas_address | **Optional.** The NAS IP address. radius_expect | **Optional.** The response string to expect from the server. radius_retries | **Optional.** The number of times to retry a failed connection. radius_timeout | **Optional.** The number of seconds before connection times out (default: 10). ### rpc The [check_rpc](https://www.monitoring-plugins.org/doc/man/check_rpc.html) plugin tests if a service is registered and running using `rpcinfo -H host -C rpc_command`. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --- | --- rpc_address | **Optional.** The rpc host address. Defaults to "$address$ if the host `address` attribute is set, "$address6$" otherwise. rpc_command | **Required.** The programm name (or number). rpc_port | **Optional.** The port that should be checked. rpc_version | **Optional.** The version you want to check for (one or more). rpc_udp | **Optional.** Use UDP test. Defaults to false. rpc_tcp | **Optional.** Use TCP test. Defaults to false. rpc_verbose | **Optional.** Show verbose output. Defaults to false. ### simap The [check_simap](https://www.monitoring-plugins.org/doc/man/check_simap.html) plugin tests SIMAP connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------|-------------- simap_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. simap_port | **Optional.** The port that should be checked. Defaults to 993. simap_escape | **Optional.** Can use \\n, \\r, \\t or \\ in send or quit string. Must come before send or quit option. Default: nothing added to send, \\r\\n added to end of quit. simap_send | **Optional.** String to send to the server. simap_expect | **Optional.** String to expect in server response. Multiple strings must be defined as array. simap_all | **Optional.** All expect strings need to occur in server response. Default is any. simap_quit | **Optional.** String to send server to initiate a clean close of the connection. simap_refuse | **Optional.** Accept TCP refusals with states ok, warn, crit (default: crit). simap_mismatch | **Optional.** Accept expected string mismatches with states ok, warn, crit (default: warn). simap_jail | **Optional.** Hide output from TCP socket. simap_maxbytes | **Optional.** Close connection once more than this number of bytes are received. simap_delay | **Optional.** Seconds to wait between sending string and polling for response. simap_certificate_age | **Optional.** Minimum number of days a certificate has to be valid. simap_ssl | **Optional.** Use SSL for the connection. simap_warning | **Optional.** Response time to result in warning status (seconds). simap_critical | **Optional.** Response time to result in critical status (seconds). simap_timeout | **Optional.** Seconds before connection times out (default: 10). simap_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. simap_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### smart The [check_ide_smart](https://www.monitoring-plugins.org/doc/man/check_ide_smart.html) plugin checks a local hard drive with the (Linux specific) SMART interface. Requires installation of `smartctl`. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- smart_device | **Required.** The name of a local hard drive to monitor. ### smtp The [check_smtp](https://www.monitoring-plugins.org/doc/man/check_smtp.html) plugin will attempt to open an SMTP connection with the host. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------------|-------------- smtp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. smtp_port | **Optional.** The port that should be checked. Defaults to 25. smtp_mail_from | **Optional.** Test a MAIL FROM command with the given email address. smtp_expect | **Optional.** String to expect in first line of server response (default: '220'). smtp_command | **Optional.** SMTP command (may be used repeatedly). smtp_response | **Optional.** Expected response to command (may be used repeatedly). smtp_helo_fqdn | **Optional.** FQDN used for HELO smtp_certificate_age | **Optional.** Minimum number of days a certificate has to be valid. smtp_starttls | **Optional.** Use STARTTLS for the connection. smtp_authtype | **Optional.** SMTP AUTH type to check (default none, only LOGIN supported). smtp_authuser | **Optional.** SMTP AUTH username. smtp_authpass | **Optional.** SMTP AUTH password. smtp_ignore_quit | **Optional.** Ignore failure when sending QUIT command to server. smtp_warning | **Optional.** Response time to result in warning status (seconds). smtp_critical | **Optional.** Response time to result in critical status (seconds). smtp_timeout | **Optional.** Seconds before connection times out (default: 10). smtp_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. smtp_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### snmp The [check_snmp](https://www.monitoring-plugins.org/doc/man/check_snmp.html) plugin checks the status of remote machines and obtains system information via SNMP. **Note**: This plugin uses the `snmpget` command included with the NET-SNMP package. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_oid | **Required.** The SNMP OID. snmp_community | **Optional.** The SNMP community. Defaults to "public". snmp_port | **Optional.** The SNMP port. Defaults to "161". snmp_retries | **Optional.** Number of retries to be used in the SNMP requests. snmp_warn | **Optional.** The warning threshold. snmp_crit | **Optional.** The critical threshold. snmp_string | **Optional.** Return OK state if the string matches exactly with the output value snmp_ereg | **Optional.** Return OK state if extended regular expression REGEX matches with the output value snmp_eregi | **Optional.** Return OK state if case-insensitive extended REGEX matches with the output value snmp_label | **Optional.** Prefix label for output value snmp_invert_search | **Optional.** Invert search result and return CRITICAL state if found snmp_units | **Optional.** Units label(s) for output value (e.g., 'sec.'). snmp_version | **Optional.** Version to use. E.g. 1, 2, 2c or 3. snmp_miblist | **Optional.** MIB's to use, comma separated. Defaults to "ALL". snmp_rate_multiplier | **Optional.** Converts rate per second. For example, set to 60 to convert to per minute. snmp_rate | **Optional.** Boolean. Enable rate calculation. snmp_getnext | **Optional.** Boolean. Use SNMP GETNEXT. Defaults to false. snmp_timeout | **Optional.** The command timeout in seconds. Defaults to 10 seconds. snmp_offset | **Optional.** Add/subtract the specified OFFSET to numeric sensor data. snmp_output_delimiter | **Optional.** Separates output on multiple OID requests. snmp_perf_oids | **Optional.** Label performance data with OIDs instead of --label's. ### snmpv3 Check command object for the [check_snmp](https://www.monitoring-plugins.org/doc/man/check_snmp.html) plugin, using SNMPv3 authentication and encryption options. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------|-------------- snmpv3_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmpv3_getnext | **Optional.** Use SNMP GETNEXT instead of SNMP GET. snmpv3_seclevel | **Optional.** The security level. Defaults to authPriv. snmpv3_auth_alg | **Optional.** The authentication algorithm. Defaults to SHA. snmpv3_user | **Required.** The username to log in with. snmpv3_context | **Optional.** The SNMPv3 context. snmpv3_auth_key | **Required,** The authentication key. Required if `snmpv3_seclevel` is set to `authPriv` otherwise optional. snmpv3_priv_key | **Required.** The encryption key. snmpv3_oid | **Required.** The SNMP OID. snmpv3_priv_alg | **Optional.** The encryption algorithm. Defaults to AES. snmpv3_warn | **Optional.** The warning threshold. snmpv3_crit | **Optional.** The critical threshold. snmpv3_string | **Optional.** Return OK state (for that OID) if STRING is an exact match. snmpv3_ereg | **Optional.** Return OK state (for that OID) if extended regular expression REGEX matches. snmpv3_eregi | **Optional.** Return OK state (for that OID) if case-insensitive extended REGEX matches. snmpv3_invert_search | **Optional.** Invert search result and return CRITICAL if found snmpv3_label | **Optional.** Prefix label for output value. snmpv3_units | **Optional.** Units label(s) for output value (e.g., 'sec.'). snmpv3_rate_multiplier | **Optional.** Converts rate per second. For example, set to 60 to convert to per minute. snmpv3_rate | **Optional.** Boolean. Enable rate calculation. snmpv3_timeout | **Optional.** The command timeout in seconds. Defaults to 10 seconds. ### snmp-uptime Check command object for the [check_snmp](https://www.monitoring-plugins.org/doc/man/check_snmp.html) plugin, using the uptime OID by default. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_oid | **Optional.** The SNMP OID. Defaults to "1.3.6.1.2.1.1.3.0". snmp_community | **Optional.** The SNMP community. Defaults to "public". ### spop The [check_spop](https://www.monitoring-plugins.org/doc/man/check_spop.html) plugin tests SPOP connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------------|-------------- spop_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. spop_port | **Optional.** The port that should be checked. Defaults to 995. spop_escape | **Optional.** Can use \\n, \\r, \\t or \\ in send or quit string. Must come before send or quit option. Default: nothing added to send, \\r\\n added to end of quit. spop_send | **Optional.** String to send to the server. spop_expect | **Optional.** String to expect in server response. Multiple strings must be defined as array. spop_all | **Optional.** All expect strings need to occur in server response. Default is any. spop_quit | **Optional.** String to send server to initiate a clean close of the connection. spop_refuse | **Optional.** Accept TCP refusals with states ok, warn, crit (default: crit). spop_mismatch | **Optional.** Accept expected string mismatches with states ok, warn, crit (default: warn). spop_jail | **Optional.** Hide output from TCP socket. spop_maxbytes | **Optional.** Close connection once more than this number of bytes are received. spop_delay | **Optional.** Seconds to wait between sending string and polling for response. spop_certificate_age | **Optional.** Minimum number of days a certificate has to be valid. spop_ssl | **Optional.** Use SSL for the connection. spop_warning | **Optional.** Response time to result in warning status (seconds). spop_critical | **Optional.** Response time to result in critical status (seconds). spop_timeout | **Optional.** Seconds before connection times out (default: 10). spop_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. spop_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### ssh The [check_ssh](https://www.monitoring-plugins.org/doc/man/check_ssh.html) plugin connects to an SSH server at a specified host and port. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ssh_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ssh_port | **Optional.** The port that should be checked. Defaults to 22. ssh_timeout | **Optional.** Seconds before connection times out. Defaults to 10. ssh_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. ssh_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### ssl Check command object for the [check_tcp](https://www.monitoring-plugins.org/doc/man/check_tcp.html) plugin, using ssl-related options. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------------|-------------- ssl_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ssl_port | **Optional.** The port that should be checked. Defaults to 443. ssl_timeout | **Optional.** Timeout in seconds for the connect and handshake. The plugin default is 10 seconds. ssl_cert_valid_days_warn | **Optional.** Warning threshold for days before the certificate will expire. When used, the default for ssl_cert_valid_days_critical is 0. ssl_cert_valid_days_critical | **Optional.** Critical threshold for days before the certificate will expire. When used, ssl_cert_valid_days_warn must also be set. ssl_sni | **Optional.** The `server_name` that is sent to select the SSL certificate to check. Important if SNI is used. ### ssmtp The [check_ssmtp](https://www.monitoring-plugins.org/doc/man/check_ssmtp.html) plugin tests SSMTP connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------|-------------- ssmtp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ssmtp_port | **Optional.** The port that should be checked. Defaults to 465. ssmtp_escape | **Optional.** Can use \\n, \\r, \\t or \\ in send or quit string. Must come before send or quit option. Default: nothing added to send, \\r\\n added to end of quit. ssmtp_send | **Optional.** String to send to the server. ssmtp_expect | **Optional.** String to expect in server response. Multiple strings must be defined as array. ssmtp_all | **Optional.** All expect strings need to occur in server response. Default is any. ssmtp_quit | **Optional.** String to send server to initiate a clean close of the connection. ssmtp_refuse | **Optional.** Accept TCP refusals with states ok, warn, crit (default: crit). ssmtp_mismatch | **Optional.** Accept expected string mismatches with states ok, warn, crit (default: warn). ssmtp_jail | **Optional.** Hide output from TCP socket. ssmtp_maxbytes | **Optional.** Close connection once more than this number of bytes are received. ssmtp_delay | **Optional.** Seconds to wait between sending string and polling for response. ssmtp_certificate_age | **Optional.** Minimum number of days a certificate has to be valid. ssmtp_ssl | **Optional.** Use SSL for the connection. ssmtp_warning | **Optional.** Response time to result in warning status (seconds). ssmtp_critical | **Optional.** Response time to result in critical status (seconds). ssmtp_timeout | **Optional.** Seconds before connection times out (default: 10). ssmtp_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. ssmtp_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### swap The [check_swap](https://www.monitoring-plugins.org/doc/man/check_swap.html) plugin checks the swap space on a local machine. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- swap_wfree | **Optional.** The free swap space warning threshold in % (enable `swap_integer` for number values). Defaults to `50%`. swap_cfree | **Optional.** The free swap space critical threshold in % (enable `swap_integer` for number values). Defaults to `25%`. swap_integer | **Optional.** Specifies whether the thresholds are passed as number or percent value. Defaults to false (percent values). swap_allswaps | **Optional.** Conduct comparisons for all swap partitions, one by one. Defaults to false. swap_noswap | **Optional.** Resulting state when there is no swap regardless of thresholds. Possible values are "ok", "warning", "critical", "unknown". Defaults to "critical". ### tcp The [check_tcp](https://www.monitoring-plugins.org/doc/man/check_tcp.html) plugin tests TCP connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- tcp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. tcp_port | **Required.** The port that should be checked. tcp_expect | **Optional.** String to expect in server response. Multiple strings must be defined as array. tcp_all | **Optional.** All expect strings need to occur in server response. Defaults to false. tcp_escape_send | **Optional.** Enable usage of \\n, \\r, \\t or \\\\ in send string. tcp_send | **Optional.** String to send to the server. tcp_escape_quit | **Optional.** Enable usage of \\n, \\r, \\t or \\\\ in quit string. tcp_quit | **Optional.** String to send server to initiate a clean close of the connection. tcp_refuse | **Optional.** Accept TCP refusals with states ok, warn, crit. Defaults to crit. tcp_mismatch | **Optional.** Accept expected string mismatches with states ok, warn, crit. Defaults to warn. tcp_jail | **Optional.** Hide output from TCP socket. tcp_maxbytes | **Optional.** Close connection once more than this number of bytes are received. tcp_delay | **Optional.** Seconds to wait between sending string and polling for response. tcp_certificate | **Optional.** Minimum number of days a certificate has to be valid. 1st value is number of days for warning, 2nd is critical (if not specified: 0) -- separated by comma. tcp_ssl | **Optional.** Use SSL for the connection. Defaults to false. tcp_sni | **Optional.** Hostname to send in the `server_name` (SNI) SSL/TLS extension. tcp_wtime | **Optional.** Response time to result in warning status (seconds). tcp_ctime | **Optional.** Response time to result in critical status (seconds). tcp_timeout | **Optional.** Seconds before connection times out. Defaults to 10. tcp_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. tcp_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### udp The [check_udp](https://www.monitoring-plugins.org/doc/man/check_udp.html) plugin tests UDP connections with the specified host (or unix socket). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- udp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. udp_port | **Required.** The port that should be checked. udp_send | **Required.** The payload to send in the UDP datagram. udp_expect | **Required.** The payload to expect in the response datagram. udp_quit | **Optional.** The payload to send to 'close' the session. udp_ipv4 | **Optional.** Use IPv4 connection. Defaults to false. udp_ipv6 | **Optional.** Use IPv6 connection. Defaults to false. ### ups The [check_ups](https://www.monitoring-plugins.org/doc/man/check_ups.html) plugin tests the UPS service on the specified host. [Network UPS Tools](http://www.networkupstools.org) must be running for this plugin to work. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- ups_address | **Required.** The address of the host running upsd. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ups_name | **Required.** The UPS name. Defaults to `ups`. ups_port | **Optional.** The port to which to connect. Defaults to 3493. ups_variable | **Optional.** The variable to monitor. Must be one of LINE, TEMP, BATTPCT or LOADPCT. If this is not set, the check only relies on the value of `ups.status`. ups_warning | **Optional.** The warning threshold for the selected variable. ups_critical | **Optional.** The critical threshold for the selected variable. ups_celsius | **Optional.** Display the temperature in degrees Celsius instead of Fahrenheit. Defaults to `false`. ups_timeout | **Optional.** The number of seconds before the connection times out. Defaults to 10. ### users The [check_users](https://www.monitoring-plugins.org/doc/man/check_users.html) plugin checks the number of users currently logged in on the local system and generates an error if the number exceeds the thresholds specified. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- users_wgreater | **Optional.** The user count warning threshold. Defaults to 20. users_cgreater | **Optional.** The user count critical threshold. Defaults to 50. ### uptime The [check_uptime](https://www.monitoring-plugins.org/doc/man/check_uptime.html) plugin checks the uptime of the system using /proc/uptime. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- uptime_warning | **Required.** Min. number of uptime to generate warning (-w 30m). Defaults to 30m. uptime_critical | **Required.** Min. number of uptime to generate critical alert (-c 15m). Defaults to 15m. uptime_for | **Optional.** Show uptime in a pretty format (Running for x weeks, x days, ...). Defaults to false. uptime_since | **Optional.** Show last boot in yyyy-mm-dd HH:MM:SS format (output from 'uptime -s'). Defaults to false. ## Windows Plugins for Icinga 2 > **Note** > > These plugins are DEPRECATED in favor of our > [PowerShell Plugins](https://github.com/Icinga/icinga-powershell-plugins) > and may be removed in a future release. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). To allow a basic monitoring of Windows clients Icinga 2 comes with a set of Windows only plugins. While trying to mirror the functionalities of their linux cousins from the monitoring-plugins package, the differences between Windows and Linux are too big to be able use the same CheckCommands for both systems. A check-commands-windows.conf comes with Icinga 2, it assumes that the Windows Plugins are installed in the PluginDir set in your constants.conf. To enable them the following include directive is needed in you icinga2.conf: include One of the differences between the Windows plugins and their linux counterparts is that they consistently do not require thresholds to run, functioning like dummies without. ### Threshold syntax So not specified differently the thresholds for the plugins all follow the same pattern Threshold | Meaning :------------|:---------- "29" | The threshold is 29. "!29" | The threshold is 29, but the negative of the result is returned. "[10-40]" | The threshold is a range from (including) 10 to 40, a value inside means the threshold has been exceeded. "![10-40]" | Same as above, but the result is inverted. ### disk-windows Check command object for the `check_disk.exe` plugin. Aggregates the disk space of all volumes and mount points it can find, or the ones defined in `disk_win_path`. Ignores removable storage like flash drives and discs (CD, DVD etc.). The data collection is instant and free disk space (default, see `disk_win_show_used`) is used for threshold computation. > **Note** > > Percentage based thresholds can be used by adding a '%' to the threshold > value. Custom variables: Name | Description :---------------------|:------------ disk\_win\_warn | **Optional**. The warning threshold. Defaults to "20%". disk\_win\_crit | **Optional**. The critical threshold. Defaults to "10%". disk\_win\_path | **Optional**. Check only these paths, default checks all. disk\_win\_unit | **Optional**. Use this unit to display disk space, thresholds are interpreted in this unit. Defaults to "mb", possible values are: b, kb, mb, gb and tb. disk\_win\_exclude | **Optional**. Exclude these drives from check. disk\_win\_show\_used | **Optional**. Use used instead of free space. ### load-windows Check command object for the `check_load.exe` plugin. This plugin collects the inverse of the performance counter `\Processor(_Total)\% Idle Time` two times, with a wait time of one second between the collection. To change this wait time use [`perfmon-windows`](10-icinga-template-library.md#windows-plugins-load-windows). Custom variables: Name | Description :---------------|:------------ load\_win\_warn | **Optional**. The warning threshold. load\_win\_crit | **Optional**. The critical threshold. ### memory-windows Check command object for the `check_memory.exe` plugin. The memory collection is instant and free memory is used for threshold computation. > **Note** > > Percentage based thresholds can be used by adding a '%' to the threshold > value. Keep in mind that memory\_win\_unit is applied before the > value is calculated. Custom variables: Name | Description :-----------------|:------------ memory\_win\_warn | **Optional**. The warning threshold. Defaults to "10%". memory\_win\_crit | **Optional**. The critical threshold. Defaults to "5%". memory\_win\_unit | **Optional**. The unit to display the received value in, thresholds are interpreted in this unit. Defaults to "mb" (megabyte), possible values are: b, kb, mb, gb and tb. memory\_win\_show\_used | **Optional**. Show used memory instead of the free memory. ### network-windows Check command object for the `check_network.exe` plugin. Collects the total Bytes inbound and outbound for all interfaces in one second, to itemise interfaces or use a different collection interval use [`perfmon-windows`](10-icinga-template-library.md#windows-plugins-load-windows). Custom variables: Name | Description :-------------------|:------------ network\_win\_warn | **Optional**. The warning threshold. network\_win\_crit | **Optional**. The critical threshold. network\_no\_isatap | **Optional**. Do not print ISATAP interfaces. ### perfmon-windows Check command object for the `check_perfmon.exe` plugin. This plugins allows to collect data from a Performance Counter. After the first data collection a second one is done after `perfmon_win_wait` milliseconds. When you know `perfmon_win_counter` only requires one set of data to provide valid data you can set `perfmon_win_wait` to `0`. To receive a list of possible Performance Counter Objects run `check_perfmon.exe --print-objects` and to view an objects instances and counters run `check_perfmon.exe --print-object-info -P "name of object"` Custom variables: Name | Description :---------------------|:------------ perfmon\_win\_warn | **Optional**. The warning threshold. perfmon\_win\_crit | **Optional**. The critical threshold. perfmon\_win\_counter | **Required**. The Performance Counter to use. Ex. `\Processor(_Total)\% Idle Time`. perfmon\_win\_wait | **Optional**. Time in milliseconds to wait between data collection (default: 1000). perfmon\_win\_type | **Optional**. Format in which to expect performance values. Possible are: long, int64 and double (default). perfmon\_win\_syntax | **Optional**. Use this in the performance output instead of `perfmon\_win\_counter`. Exists for graphics compatibility reasons. ### ping-windows Check command object for the `check_ping.exe` plugin. ping-windows should automatically detect whether `ping_win_address` is an IPv4 or IPv6 address. If not, use ping4-windows and ping6-windows. Also note that check\_ping.exe waits at least `ping_win_timeout` milliseconds between the pings. Custom variables: Name | Description :------------------|:------------ ping\_win\_warn | **Optional**. The warning threshold. RTA and package loss separated by comma. ping\_win\_crit | **Optional**. The critical threshold. RTA and package loss separated by comma. ping\_win\_address | **Required**. An IPv4 or IPv6 address. ping\_win\_packets | **Optional**. Number of packages to send. Default: 5. ping\_win\_timeout | **Optional**. The timeout in milliseconds. Default: 1000 ### procs-windows Check command object for `check_procs.exe` plugin. When using `procs_win_user` this plugins needs administrative privileges to access the processes of other users, to just enumerate them no additional privileges are required. Custom variables: Name | Description :----------------|:------------ procs\_win\_warn | **Optional**. The warning threshold. procs\_win\_crit | **Optional**. The critical threshold. procs\_win\_user | **Optional**. Count this users processes. ### service-windows Check command object for `check_service.exe` plugin. This checks thresholds work different since the binary decision whether a service is running or not does not allow for three states. As a default `check_service.exe` will return CRITICAL when `service_win_service` is not running, the `service_win_warn` flag changes this to WARNING. Custom variables: Name | Description :-------------------------|:------------ service\_win\_warn | **Optional**. Warn when service is not running. service\_win\_description | **Optional**. If this is set, `service\_win\_service` looks at the service description. service\_win\_service | **Required**. Name of the service to check. ### swap-windows Check command object for `check_swap.exe` plugin. The data collection is instant. Custom variables: Name | Description :--------------- | :------------ swap\_win\_warn | **Optional**. The warning threshold. Defaults to "10%". swap\_win\_crit | **Optional**. The critical threshold. Defaults to "5%". swap\_win\_unit | **Optional**. The unit to display the received value in, thresholds are interpreted in this unit. Defaults to "mb" (megabyte). swap\_win\_show\_used | **Optional**. Show used swap instead of the free swap. ### update-windows Check command object for `check_update.exe` plugin. Querying Microsoft for Windows updates can take multiple seconds to minutes. An update is treated as important when it has the WSUS flag for SecurityUpdates or CriticalUpdates. > **Note** > > The Network Services Account which runs Icinga 2 by default does not have the required > permissions to run this check. Custom variables: Name | Description :-------------------|:------------ update\_win\_warn | **Optional**. The warning threshold. update\_win\_crit | **Optional**. The critical threshold. update\_win\_reboot | **Optional**. Set to treat 'may need update' as 'definitely needs update'. Please Note that this is true for almost every update and is therefore not recommended. ignore\_reboot | **Optional**. Set to disable behavior of returning critical if any updates require a reboot. If a warning threshold is set but not a critical threshold, the critical threshold will be set to one greater than the set warning threshold. Unless the `ignore_reboot` flag is set, if any updates require a reboot the plugin will return critical. > **Note** > > If they are enabled, performance data will be shown in the web interface. > If run without the optional parameters, the plugin will output critical if any important updates are available. ### uptime-windows Check command object for `check_uptime.exe` plugin. Uses GetTickCount64 to get the uptime, so boot time is not included. Custom variables: Name | Description :-----------------|:------------ uptime\_win\_warn | **Optional**. The warning threshold. uptime\_win\_crit | **Optional**. The critical threshold. uptime\_win\_unit | **Optional**. The unit to display the received value in, thresholds are interpreted in this unit. Defaults to "s"(seconds), possible values are ms (milliseconds), s, m (minutes), h (hours). ### users-windows Check command object for `check_users.exe` plugin. Custom variables: Name | Description :----------------|:------------ users\_win\_warn | **Optional**. The warning threshold. users\_win\_crit | **Optional**. The critical threshold. ### file-age-windows Check command object for `check_file_age.cmd` command file and `check_file_age.cmd.ps1` plugin. Custom variables: Name | Description :---------------------|:------------ file_age_win_file | **Required**. File name and location file_age_win_warning | **Required**. The warning threshold of file age in seconds. file_age_win_critical | **Required**. The critical threshold of file age in seconds. All variables are required and all variables are positional. The variable order is: file warning critical. The check_file_age.cmd and the check_file_age.cmd.ps1 files are available for [download](https://github.com/KAMI911/icinga2-basic/tree/master/plugins). ## Plugin Check Commands for NSClient++ There are two methods available for querying NSClient++: * Query the [HTTP API](06-distributed-monitoring.md#distributed-monitoring-windows-nscp-check-api) locally from an Icinga 2 client (requires a running NSClient++ service) * Run a [local CLI check](10-icinga-template-library.md#nscp-check-local) (does not require NSClient++ as a service) Both methods have their advantages and disadvantages. One thing to note: If you rely on performance counter delta calculations such as CPU utilization, please use the HTTP API instead of the CLI sample call. For security reasons, it is advised to enable the NSClient++ HTTP API for local connection from the Icinga 2 client only. Remote connections to the HTTP API are not recommended with using the legacy HTTP API. ### nscp_api `check_nscp_api` is part of the Icinga 2 plugins. This plugin is available for both, Windows and Linux/Unix. Verify that the ITL CheckCommand is included in the [icinga2.conf](04-configuration.md#icinga2-conf) configuration file: vim /etc/icinga2/icinga2.conf include `check_nscp_api` runs queries against the NSClient++ API. Therefore NSClient++ needs to have the `webserver` module enabled, configured and loaded. You can install the webserver using the following CLI commands: ./nscp.exe web install ./nscp.exe web password — –set icinga Now you can define specific [queries](https://docs.nsclient.org/reference/check/CheckHelpers.html#queries) and integrate them into Icinga 2. The check plugin `check_nscp_api` can be integrated with the `nscp_api` CheckCommand object: Custom variables: Name | Description :----------------------|:---------------------- nscp\_api\_host | **Required**. NSCP API host address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. nscp\_api\_port | **Optional**. NSCP API port. Defaults to `8443`. nscp\_api\_password | **Required**. NSCP API password. Please check the NSCP documentation for setup details. nscp\_api\_query | **Required**. NSCP API query endpoint. Refer to the NSCP documentation for possible values. nscp\_api\_arguments | **Optional**. NSCP API arguments dictionary either as single strings or key-value pairs using `=`. Refer to the NSCP documentation. `nscp_api_arguments` can be used to pass required thresholds to the executed check. The example below checks the CPU utilization and specifies warning and critical thresholds. ``` check_nscp_api --host 10.0.10.148 --password icinga --query check_cpu --arguments show-all warning='load>40' critical='load>30' check_cpu CRITICAL: critical(5m: 48%, 1m: 36%), 5s: 0% | 'total 5m'=48%;40;30 'total 1m'=36%;40;30 'total 5s'=0%;40;30 ``` ### nscp-local Icinga 2 can use the `nscp client` command to run arbitrary NSClient++ checks locally on the client. You can enable these check commands by adding the following the include directive in your [icinga2.conf](04-configuration.md#icinga2-conf) configuration file: include You can also optionally specify an alternative installation directory for NSClient++ by adding the NscpPath constant in your [constants.conf](04-configuration.md#constants-conf) configuration file: const NscpPath = "C:\\Program Files (x86)\\NSClient++" By default Icinga 2 uses the Microsoft Installer API to determine where NSClient++ is installed. It should not be necessary to manually set this constant. Note that it is not necessary to run NSClient++ as a Windows service for these commands to work. The check command object for NSClient++ is available as `nscp-local`. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------- nscp_log_level | **Optional.** The log level. Defaults to "critical". nscp_load_all | **Optional.** Whether to load all modules. Defaults to false. nscp_modules | **Optional.** An array of NSClient++ modules to load. Defaults to `[ "CheckSystem" ]`. nscp_boot | **Optional.** Whether to use the --boot option. Defaults to true. nscp_query | **Required.** The NSClient++ query. Try `nscp client -q x` for a list. nscp_arguments | **Optional.** An array of query arguments. nscp_showall | **Optional.** Shows more details in plugin output, default to false. > **Tip** > > In order to measure CPU load, you'll need a running NSClient++ service. > Therefore it is advised to use a local [nscp-api](06-distributed-monitoring.md#distributed-monitoring-windows-nscp-check-api) > check against its REST API. ### nscp-local-cpu Check command object for the `check_cpu` NSClient++ plugin. Name | Description --------------------|------------------ nscp_cpu_time | **Optional.** Calculate average usage for the given time intervals. Value has to be an array, default to [ "1m", "5m", "15m" ]. nscp_cpu_warning | **Optional.** Threshold for WARNING state in percent, default to 80. nscp_cpu_critical | **Optional.** Threshold for CRITICAL state in percent, default to 90. nscp_cpu_arguments | **Optional.** Additional arguments. nscp_cpu_showall | **Optional.** Shows more details in plugin output, default to false. ### nscp-local-memory Check command object for the `check_memory` NSClient++ plugin. Name | Description ----------------------|------------------ nscp_memory_committed | **Optional.** Check for committed memory, default to false. nscp_memory_physical | **Optional.** Check for physical memory, default to true. nscp_memory_free | **Optional.** Switch between checking free (true) or used memory (false), default to false. nscp_memory_warning | **Optional.** Threshold for WARNING state in percent or absolute (use MB, GB, ...), default to 80 (free=false) or 20 (free=true). nscp_memory_critical | **Optional.** Threshold for CRITICAL state in percent or absolute (use MB, GB, ...), default to 90 (free=false) or 10 (free=true). nscp_memory_arguments | **Optional.** Additional arguments. nscp_memory_showall | **Optional.** Shows more details in plugin output, default to false. ### nscp-local-os-version Check command object for the `check_os_version` NSClient++ plugin. This command has the same custom variables like the `nscp-local` check command. ### nscp-local-pagefile Check command object for the `check_pagefile` NSClient++ plugin. This command has the same custom variables like the `nscp-local` check command. ### nscp-local-process Check command object for the `check_process` NSClient++ plugin. This command has the same custom variables like the `nscp-local` check command. ### nscp-local-service Check command object for the `check_service` NSClient++ plugin. Name | Description -----------------------|------------------ nscp_service_name | **Required.** Name of service to check. nscp_service_type | **Optional.** Type to check, default to state. nscp_service_ok | **Optional.** State for return an OK, i.e. for type=state running, stopped, ... nscp_service_otype | **Optional.** Dedicate type for nscp_service_ok, default to nscp_service_state. nscp_service_warning | **Optional.** State for return an WARNING. nscp_service_wtype | **Optional.** Dedicate type for nscp_service_warning, default to nscp_service_state. nscp_service_critical | **Optional.** State for return an CRITICAL. nscp_service_ctype | **Optional.** Dedicate type for nscp_service_critical, default to nscp_service_state. nscp_service_arguments | **Optional.** Additional arguments. nscp_service_showall | **Optional.** Shows more details in plugin output, default to true. ### nscp-local-uptime Check command object for the `check_uptime` NSClient++ plugin. This command has the same custom variables like the `nscp-local` check command. ### nscp-local-version Check command object for the `check_version` NSClient++ plugin. This command has the same custom variables like the `nscp-local` check command. In addition to that the default value for `nscp_modules` is set to `[ "CheckHelpers" ]`. ### nscp-local-disk Check command object for the `check_drivesize` NSClient++ plugin. Name | Description -----------------------|------------------ nscp_disk_drive | **Optional.** Drive character, default to all drives. Can be an array if multiple drives should be monitored. nscp_disk_exclude | **Optional.** Drive character, default to none. Can be an array of drive characters if multiple drives should be excluded. nscp_disk_free | **Optional.** Switch between checking free space (free=true) or used space (free=false), default to false. nscp_disk_warning | **Optional.** Threshold for WARNING in percent or absolute (use MB, GB, ...), default to 80 (used) or 20 percent (free). nscp_disk_critical | **Optional.** Threshold for CRITICAL in percent or absolute (use MB, GB, ...), default to 90 (used) or 10 percent (free). nscp_disk_arguments | **Optional.** Additional arguments. nscp_disk_showall | **Optional.** Shows more details in plugin output, default to true. nscp_modules | **Optional.** An array of NSClient++ modules to load. Defaults to `[ "CheckDisk" ]`. ### nscp-local-counter Check command object for the `check_pdh` NSClient++ plugin. Name | Description -----------------------|------------------ nscp_counter_name | **Required.** Performance counter name. nscp_counter_warning | **Optional.** WARNING Threshold. nscp_counter_critical | **Optional.** CRITICAL Threshold. nscp_counter_arguments | **Optional.** Additional arguments. nscp_counter_showall | **Optional.** Shows more details in plugin output, default to false. nscp_counter_perfsyntax | **Optional.** Apply performance data label, e.g. `Total Processor Time` to avoid special character problems. Defaults to `nscp_counter_name`. ### nscp-local-tasksched Check Command object for the `check_tasksched` NSClient++ plugin. You can check for a single task or for a complete folder (and sub folders) of tasks. Name | Description -----------------------|------------------ nscp_tasksched_name | **Optional.** Name of the task to check. nscp_tasksched_folder | **Optional.** The folder in which the tasks to check reside. nscp_tasksched_recursive | **Optional.** Recurse sub folder, defaults to true. nscp_tasksched_hidden | **Optional.** Look for hidden tasks, defaults to false. nscp_tasksched_warning | **Optional.** Filter which marks items which generates a warning state, defaults to `exit_code != 0`. nscp_tasksched_critical | **Optional.** Filter which marks items which generates a critical state, defaults to `exit_code < 0`. nscp_tasksched_emptystate | **Optional.** Return status to use when nothing matched filter, defaults to warning. nscp_tasksched_perfsyntax | **Optional.** Performance alias syntax., defaults to `%(title)` nscp_tasksched_detailsyntax | **Optional.** Detail level syntax, defaults to `%(folder)/%(title): %(exit_code) != 0` nscp_tasksched_arguments | **Optional.** Additional arguments. nscp_tasksched_showall | **Optional.** Shows more details in plugin output, default to false. nscp_modules | **Optional.** An array of NSClient++ modules to load. Defaults to `[ "CheckTaskSched" ]`. ## Plugin Check Commands for Manubulon SNMP The `SNMP Manubulon Plugin Check Commands` provide configuration for plugin check commands provided by the [SNMP Manubulon project](http://nagios.manubulon.com/index_snmp.html). **Note:** Some plugin parameters are only available in Debian packages or in a [forked repository](https://github.com/dnsmichi/manubulon-snmp) with patches applied. The SNMP manubulon plugin check commands assume that the global constant named `ManubulonPluginDir` is set to the path where the Manubublon SNMP plugins are installed. You can enable these plugin check commands by adding the following the include directive in your [icinga2.conf](04-configuration.md#icinga2-conf) configuration file: include ### Checks by Host Type **N/A** : Not available for this type. **SNMP** : Available for simple SNMP query. **??** : Untested. **Specific** : Script name for platform specific checks. Host type | Interface | storage | load/cpu | mem | process | env | specific ------------------------|------------|----------|-----------|-----|----------|-----|------------------------- Linux | Yes | Yes | Yes | Yes | Yes | No | Windows | Yes | Yes | Yes | Yes | Yes | No | check_snmp_win.pl Cisco router/switch | Yes | N/A | Yes | Yes | N/A | Yes | HP router/switch | Yes | N/A | Yes | Yes | N/A | No | Bluecoat proxy | Yes | SNMP | Yes | SNMP| No | Yes | CheckPoint on SPLAT | Yes | Yes | Yes | Yes | Yes | No | check_snmp_cpfw.pl CheckPoint on Nokia IP | Yes | Yes | Yes | No | ?? | No | check_snmp_vrrp.pl Boostedge | Yes | Yes | Yes | Yes | ?? | No | check_snmp_boostedge.pl AS400 | Yes | Yes | Yes | Yes | No | No | NetsecureOne Netbox | Yes | Yes | Yes | ?? | Yes | No | Radware Linkproof | Yes | N/A | SNMP | SNMP| No | No | check_snmp_linkproof_nhr
check_snmp_vrrp.pl IronPort | Yes | SNMP | SNMP | SNMP| No | Yes | Cisco CSS | Yes | ?? | Yes | Yes | No | ?? | check_snmp_css.pl ### snmp-env Check command object for the [check_snmp_env.pl](http://nagios.manubulon.com/snmp_env.html) plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_nocrypt | **Optional.** Define SNMP encryption. If set to `false`, `snmp_v3` needs to be enabled. Defaults to `true` (no encryption). snmp_community | **Optional.** The SNMP community. Defaults to "public". snmp_port | **Optional.** The SNMP port connection. snmp_v2 | **Optional.** SNMP version to 2c. Defaults to false. snmp_v3 | **Optional.** SNMP version to 3. Defaults to false. snmp_login | **Optional.** SNMP version 3 username. Defaults to "snmpuser". snmp_password | **Required.** SNMP version 3 password. No value defined as default. snmp_v3_use_privpass | **Optional.** Define to use SNMP version 3 priv password. Defaults to false. snmp_v3_use_authprotocol| **Optional.** Define to use SNMP version 3 authentication protocol. Defaults to false. snmp_authprotocol | **Optional.** SNMP version 3 authentication protocol. Defaults to "md5,des". snmp_privpass | **Required.** SNMP version 3 priv password. No value defined as default. snmp_env_type | **Optional.** Environment Type [cisco|nokia|bc|iron|foundry|linux]. Defaults to "cisco". snmp_env_fan | **Optional.** Minimum fan rpm value (only needed for 'iron' & 'linux') snmp_env_celsius | **Optional.** Maximum temp in degrees celsius (only needed for 'iron' & 'linux') snmp_perf | **Optional.** Enable perfdata values. Defaults to true. snmp_timeout | **Optional.** The command timeout in seconds. Defaults to 5 seconds. ### snmp-load Check command object for the [check_snmp_load.pl](http://nagios.manubulon.com/snmp_load.html) plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_nocrypt | **Optional.** Define SNMP encryption. If set to `false`, `snmp_v3` needs to be enabled. Defaults to `true` (no encryption). snmp_community | **Optional.** The SNMP community. Defaults to "public". snmp_port | **Optional.** The SNMP port connection. snmp_v2 | **Optional.** SNMP version to 2c. Defaults to false. snmp_v3 | **Optional.** SNMP version to 3. Defaults to false. snmp_login | **Optional.** SNMP version 3 username. Defaults to "snmpuser". snmp_password | **Required.** SNMP version 3 password. No value defined as default. snmp_v3_use_privpass | **Optional.** Define to use SNMP version 3 priv password. Defaults to false. snmp_v3_use_authprotocol| **Optional.** Define to use SNMP version 3 authentication protocol. Defaults to false. snmp_authprotocol | **Optional.** SNMP version 3 authentication protocol. Defaults to "md5,des". snmp_privpass | **Required.** SNMP version 3 priv password. No value defined as default. snmp_warn | **Optional.** The warning threshold. Change the `snmp_load_type` var to "netsl" for using 3 values. snmp_crit | **Optional.** The critical threshold. Change the `snmp_load_type` var to "netsl" for using 3 values. snmp_load_type | **Optional.** Load type. Defaults to "stand". Check all available types in the [snmp load](http://nagios.manubulon.com/snmp_load.html) documentation. snmp_perf | **Optional.** Enable perfdata values. Defaults to true. snmp_timeout | **Optional.** The command timeout in seconds. Defaults to 5 seconds. ### snmp-memory Check command object for the [check_snmp_mem.pl](http://nagios.manubulon.com/snmp_mem.html) plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_nocrypt | **Optional.** Define SNMP encryption. If set to `false`, `snmp_v3` needs to be enabled. Defaults to `true` (no encryption). snmp_community | **Optional.** The SNMP community. Defaults to "public". snmp_port | **Optional.** The SNMP port connection. snmp_v2 | **Optional.** SNMP version to 2c. Defaults to false. snmp_v3 | **Optional.** SNMP version to 3. Defaults to false. snmp_login | **Optional.** SNMP version 3 username. Defaults to "snmpuser". snmp_password | **Required.** SNMP version 3 password. No value defined as default. snmp_v3_use_privpass | **Optional.** Define to use SNMP version 3 priv password. Defaults to false. snmp_v3_use_authprotocol| **Optional.** Define to use SNMP version 3 authentication protocol. Defaults to false. snmp_authprotocol | **Optional.** SNMP version 3 authentication protocol. Defaults to "md5,des". snmp_privpass | **Required.** SNMP version 3 priv password. No value defined as default. snmp_warn | **Optional.** The warning threshold. snmp_crit | **Optional.** The critical threshold. snmp_is_cisco | **Optional.** Change OIDs for Cisco switches. Defaults to false. snmp_is_hp | **Optional.** Change OIDs for HP/Procurve switches. Defaults to false. snmp_perf | **Optional.** Enable perfdata values. Defaults to true. snmp_memcached | **Optional.** Include cached memory in used memory, Defaults to false. snmp_membuffer | **Optional.** Exclude buffered memory in used memory, Defaults to false. snmp_timeout | **Optional.** The command timeout in seconds. Defaults to 5 seconds. ### snmp-storage Check command object for the [check_snmp_storage.pl](http://nagios.manubulon.com/snmp_storage.html) plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_nocrypt | **Optional.** Define SNMP encryption. If set to `false`, `snmp_v3` needs to be enabled. Defaults to `true` (no encryption). snmp_community | **Optional.** The SNMP community. Defaults to "public". snmp_port | **Optional.** The SNMP port connection. snmp_v2 | **Optional.** SNMP version to 2c. Defaults to false. snmp_v3 | **Optional.** SNMP version to 3. Defaults to false. snmp_login | **Optional.** SNMP version 3 username. Defaults to "snmpuser". snmp_password | **Required.** SNMP version 3 password. No value defined as default. snmp_v3_use_privpass | **Optional.** Define to use SNMP version 3 priv password. Defaults to false. snmp_v3_use_authprotocol| **Optional.** Define to use SNMP version 3 authentication protocol. Defaults to false. snmp_authprotocol | **Optional.** SNMP version 3 authentication protocol. Defaults to "md5,des". snmp_privpass | **Required.** SNMP version 3 priv password. No value defined as default. snmp_warn | **Optional.** The warning threshold. snmp_crit | **Optional.** The critical threshold. snmp_storage_name | **Optional.** Storage name. Default to regex "^/$$". More options available in the [snmp storage](http://nagios.manubulon.com/snmp_storage.html) documentation. snmp_storage_type | **Optional.** Filter by storage type. Valid options are Other, Ram, VirtualMemory, FixedDisk, RemovableDisk, FloppyDisk, CompactDisk, RamDisk, FlashMemory, or NetworkDisk. No value defined as default. snmp_perf | **Optional.** Enable perfdata values. Defaults to true. snmp_exclude | **Optional.** Select all storages except the one(s) selected by -m. No action on storage type selection. snmp_timeout | **Optional.** The command timeout in seconds. Defaults to 5 seconds. snmp_storage_olength | **Optional.** Max-size of the SNMP message, usefull in case of Too Long responses. ### snmp-interface Check command object for the [check_snmp_int.pl](http://nagios.manubulon.com/snmp_int.html) plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_nocrypt | **Optional.** Define SNMP encryption. If set to `false`, `snmp_v3` needs to be enabled. Defaults to `true` (no encryption). snmp_community | **Optional.** The SNMP community. Defaults to "public". snmp_port | **Optional.** The SNMP port connection. snmp_v2 | **Optional.** SNMP version to 2c. Defaults to false. snmp_v3 | **Optional.** SNMP version to 3. Defaults to false. snmp_login | **Optional.** SNMP version 3 username. Defaults to "snmpuser". snmp_password | **Required.** SNMP version 3 password. No value defined as default. snmp_v3_use_privpass | **Optional.** Define to use SNMP version 3 priv password. Defaults to false. snmp_v3_use_authprotocol | **Optional.** Define to use SNMP version 3 authentication protocol. Defaults to false. snmp_authprotocol | **Optional.** SNMP version 3 authentication protocol. Defaults to "md5,des". snmp_privpass | **Required.** SNMP version 3 priv password. No value defined as default. snmp_warn | **Optional.** The warning threshold. snmp_crit | **Optional.** The critical threshold. snmp_interface | **Optional.** Network interface name. Default to regex "eth0". snmp_interface_inverse | **Optional.** Inverse Interface check, down is ok. Defaults to false as it is missing. snmp_interface_perf | **Optional.** Check the input/output bandwidth of the interface. Defaults to true. snmp_interface_label | **Optional.** Add label before speed in output: in=, out=, errors-out=, etc. snmp_interface_bits_bytes | **Optional.** Output performance data in bits/s or Bytes/s. **Depends** on snmp_interface_kbits set to true. Defaults to true. snmp_interface_percent | **Optional.** Output performance data in % of max speed. Defaults to false. snmp_interface_kbits | **Optional.** Make the warning and critical levels in KBits/s. Defaults to true. snmp_interface_megabytes | **Optional.** Make the warning and critical levels in Mbps or MBps. **Depends** on snmp_interface_kbits set to true. Defaults to true. snmp_interface_64bit | **Optional.** Use 64 bits counters instead of the standard counters when checking bandwidth & performance data for interface >= 1Gbps. Defaults to false. snmp_interface_errors | **Optional.** Add error & discard to Perfparse output. Defaults to true. snmp_interface_extended_checks | **Optional.** Also check the error and discard input/output. When enabled format of `snmp_warn` and `snmp_crit` changes to ,,,,,. More options available in the [snmp interface](http://nagios.manubulon.com/snmp_int.html) documentation. Defaults to false. snmp_interface_noregexp | **Optional.** Do not use regexp to match interface name in description OID. Defaults to false. snmp_interface_delta | **Optional.** Delta time of perfcheck. Defaults to "300" (5 min). snmp_interface_warncrit_percent | **Optional.** Make the warning and critical levels in % of reported interface speed. If set, **snmp_interface_megabytes** needs to be set to false. Defaults to false. snmp_interface_ifname | **Optional.** Switch from IF-MIB::ifDescr to IF-MIB::ifName when looking up the interface's name. snmp_interface_ifalias | **Optional.** Switch from IF-MIB::ifDescr to IF-MIB::ifAlias when looking up the interface's name. snmp_interface_weathermap | **Optional.** Output data for ["weathermap" lines](http://docs.nagvis.org/1.9/en_US/lines_weathermap_style.html) in NagVis. **Depends** on `snmp_interface_perf` set to true. Defaults to `false`. **Note**: Available in `check_snmp_int.pl v2.1.0`. snmp_perf | **Optional.** Enable perfdata values. Defaults to true. snmp_timeout | **Optional.** The command timeout in seconds. Defaults to 5 seconds. snmp_interface_admin | **Optional.** Use administrative status instead of operational. Defaults to false. ### snmp-process Check command object for the [check_snmp_process.pl](http://nagios.manubulon.com/snmp_process.html) plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_nocrypt | **Optional.** Define SNMP encryption. If set to `false`, `snmp_v3` needs to be enabled. Defaults to `true` (no encryption). snmp_community | **Optional.** The SNMP community. Defaults to "public". snmp_port | **Optional.** The SNMP port connection. snmp_v2 | **Optional.** SNMP version to 2c. Defaults to false. snmp_v3 | **Optional.** SNMP version to 3. Defaults to false. snmp_login | **Optional.** SNMP version 3 username. Defaults to "snmpuser". snmp_password | **Required.** SNMP version 3 password. No value defined as default. snmp_v3_use_privpass | **Optional.** Define to use SNMP version 3 priv password. Defaults to false. snmp_v3_use_authprotocol | **Optional.** Define to use SNMP version 3 authentication protocol. Defaults to false. snmp_authprotocol | **Optional.** SNMP version 3 authentication protocol. Defaults to "md5,des". snmp_privpass | **Required.** SNMP version 3 priv password. No value defined as default.. snmp_warn | **Optional.** The warning threshold. snmp_crit | **Optional.** The critical threshold. snmp_process_name | **Optional.** Name of the process (regexp). No trailing slash!. Defaults to ".*". snmp_perf | **Optional.** Enable perfdata values. Defaults to true. snmp_timeout | **Optional.** The command timeout in seconds. Defaults to 5 seconds. snmp_process_use_params | **Optional.** Add process parameters to process name for regexp matching. Example: "named.*-t /var/named/chroot" will only select named process with this parameter. Defaults to false. snmp_process_use_fullpath | **Optional.** Use full path name instead of process name to select processes. Example: "/opt/app1/app1bin" will only select named process with this full path. Defaults to false. snmp_process_mem_usage | **Optional.** Define to check memory usage for the process. Defaults to false. snmp_process_mem_threshold | **Optional.** Defines the warning and critical thresholds in Mb when snmp_process_mem_usage set to true. Example "512,1024". Defaults to "0,0". snmp_process_cpu_usage | **Optional.** Define to check CPU usage for the process. Defaults to false. snmp_process_cpu_threshold | **Optional.** Defines the warning and critical thresholds in % when snmp_process_cpu_usage set to true. If more than one CPU, value can be > 100% : 100%=1 CPU. Example "15,50". Defaults to "0,0". ### snmp-service Check command object for the [check_snmp_win.pl](http://nagios.manubulon.com/snmp_windows.html) plugin. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------|-------------- snmp_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. snmp_nocrypt | **Optional.** Define SNMP encryption. If set to `false`, `snmp_v3` needs to be enabled. Defaults to `true` (no encryption). snmp_community | **Optional.** The SNMP community. Defaults to "public". snmp_port | **Optional.** The SNMP port connection. snmp_v2 | **Optional.** SNMP version to 2c. Defaults to false. snmp_v3 | **Optional.** SNMP version to 3. Defaults to false. snmp_login | **Optional.** SNMP version 3 username. Defaults to "snmpuser". snmp_password | **Required.** SNMP version 3 password. No value defined as default. snmp_v3_use_privpass | **Optional.** Define to use SNMP version 3 priv password. Defaults to false. snmp_v3_use_authprotocol | **Optional.** Define to use SNMP version 3 authentication protocol. Defaults to false. snmp_authprotocol | **Optional.** SNMP version 3 authentication protocol. Defaults to "md5,des". snmp_privpass | **Required.** SNMP version 3 priv password. No value defined as default. snmp_timeout | **Optional.** The command timeout in seconds. Defaults to 5 seconds. snmp_service_name | **Optional.** Comma separated names of services (perl regular expressions can be used for every one). By default, it is not case sensitive. eg. ^dns$. Defaults to ".*". snmp_service_count | **Optional.** Compare matching services with a specified number instead of the number of names provided. snmp_service_showall | **Optional.** Show all services in the output, instead of only the non-active ones. Defaults to false. snmp_service_noregexp | **Optional.** Do not use regexp to match NAME in service description. Defaults to false. ## Contributed Plugin Check Commands The contributed Plugin Check Commands provides various additional command definitions contributed by community members. These check commands assume that the global constant named `PluginContribDir` is set to the path where the user installs custom plugins and can be enabled by uncommenting the corresponding line in [icinga2.conf](04-configuration.md#icinga2-conf): ``` vim /etc/icinga2/icinga2.conf include ``` This is enabled by default since Icinga 2 2.5.0. ### Big Data This category contains plugins for various Big Data systems. #### cloudera_service_status The [cloudera_service_status](https://github.com/miso231/icinga2-cloudera-plugin) plugin uses Cloudera Manager API to monitor cluster services Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------------|----------------------------------------------------------------- cloudera_host | **Required.** Hostname of cloudera server. cloudera_port | **Optional.** Port where cloudera is listening. Defaults to 443. cloudera_user | **Required.** The username for the API connection. cloudera_pass | **Required.** The password for the API connection. cloudera_api_version | **Required.** API version of cloudera. cloudera_cluster | **Required.** The cluster name in cloudera manager. cloudera_service | **Required.** Name of cluster service to be checked. cloudera_verify_ssl | **Optional.** Verify SSL. Defaults to true. #### cloudera_hdfs_space The [cloudera_hdfs_space](https://github.com/miso231/icinga2-cloudera-plugin) plugin connects to Hadoop Namenode and gets used capacity of selected disk Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------|----------------------------------------------------------------- cloudera_hdfs_space_host | **Required.** Namenode host to connect to. cloudera_hdfs_space_port | **Optional.** Namenode port (default 50070). cloudera_hdfs_space_disk | **Required.** HDFS disk to check. cloudera_hdfs_space_warn | **Required.** Warning threshold in percent. cloudera_hdfs_space_crit | **Required.** Critical threshold in percent. #### cloudera_hdfs_files The [cloudera_hdfs_files](https://github.com/miso231/icinga2-cloudera-plugin) plugin connects to Hadoop Namenode and gets total number of files on HDFS Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------|----------------------------------------------------------------- cloudera_hdfs_files_host | **Required.** Namenode host to connect to. cloudera_hdfs_files_port | **Optional.** Namenode port (default 50070). cloudera_hdfs_files_warn | **Required.** Warning threshold. cloudera_hdfs_files_crit | **Required.** Critical threshold. cloudera_hdfs_files_max | **Required.** Max files count that causes problems (default 140,000,000). ### Databases This category contains plugins for various database servers. #### db2_health The [check_db2_health](https://labs.consol.de/nagios/check_db2_health/) plugin uses the `DBD::DB2` Perl library to monitor a [DB2](https://www.ibm.com/support/knowledgecenter/SSEPGG_11.1.0/) database. The Git repository is located on [GitHub](https://github.com/lausser/check_db2_health). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|------------------------------------------------------------------------------------------------------------------------------ db2_health_database | **Required.** The name of the database. (If it was catalogued locally, this parameter and `db2_health_not_catalogued = false` are the only you need. Otherwise you must specify database, hostname and port) db2_health_username | **Optional.** The username for the database connection. db2_health_password | **Optional.** The password for the database connection. db2_health_port | **Optional.** The port where DB2 is listening. db2_health_warning | **Optional.** The warning threshold depending on the mode. db2_health_critical | **Optional.** The critical threshold depending on the mode. db2_health_mode | **Required.** The mode uses predefined keywords for the different checks. For example "connection-time", "database-usage" or "sql". db2_health_method | **Optional.** This tells the plugin how to connect to the database. The only method implemented yet is “dbi” which is the default. (It means, the plugin uses the perl module DBD::DB2). db2_health_name | **Optional.** The tablespace, datafile, wait event, latch, enqueue depending on the mode or SQL statement to be executed with "db2_health_mode" sql. db2_health_name2 | **Optional.** If "db2_health_name" is a sql statement, "db2_health_name2" can be used to appear in the output and the performance data. db2_health_regexp | **Optional.** If set to true, "db2_health_name" will be interpreted as a regular expression. Defaults to false. db2_health_units | **Optional.** This is used for a better output of mode=sql and for specifying thresholds for mode=tablespace-free. Possible values are "%", "KB", "MB" and "GB". db2_health_maxinactivity | **Optional.** Used for the maximum amount of time a certain event has not happened. db2_health_mitigation | **Optional.** Classifies the severity of an offline tablespace. db2_health_lookback | **Optional.** How many days in the past db2_health check should look back to calculate exitcode. db2_health_report | **Optional.** Report can be used to output only the bad news. Possible values are "short", "long", "html". Defaults to `short`. db2_health_not_catalogued | **Optional.** Set this variable to false if you want to use a catalogued locally database. Defaults to `true`. db2_health_env_db2_home | **Required.** Specifies the location of the db2 client libraries as environment variable `DB2_HOME`. Defaults to "/opt/ibm/db2/V10.5". db2_health_env_db2_version | **Optional.** Specifies the DB2 version as environment variable `DB2_VERSION`. #### mssql_health The [check_mssql_health](https://labs.consol.de/nagios/check_mssql_health/index.html) plugin uses the `DBD::Sybase` Perl library based on [FreeTDS](https://www.freetds.org/) to monitor a [MS SQL](https://www.microsoft.com/en-us/sql-server/) server. The Git repository is located on [GitHub](https://github.com/lausser/check_mssql_health). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|------------------------------------------------------------------------------------------------------------------------------ mssql_health_hostname | **Optional.** Specifies the database hostname or address. No default because you typically use "mssql_health_server". mssql_health_username | **Optional.** The username for the database connection. mssql_health_password | **Optional.** The password for the database connection. mssql_health_port | **Optional.** Specifies the database port. No default because you typically use "mssql_health_server". mssql_health_server | **Optional.** The name of a predefined connection (in freetds.conf). mssql_health_currentdb | **Optional.** The name of a database which is used as the current database for the connection. mssql_health_offlineok | **Optional.** Set this to true if offline databases are perfectly ok for you. Defaults to false. mssql_health_nooffline | **Optional.** Set this to true to ignore offline databases. Defaults to false. mssql_health_dbthresholds | **Optional.** With this parameter thresholds are read from the database table check_mssql_health_thresholds. mssql_health_notemp | **Optional.** Set this to true to ignore temporary databases/tablespaces. Defaults to false. mssql_health_commit | **Optional.** Set this to true to turn on autocommit for the dbd::sybase module. Defaults to false. mssql_health_method | **Optional.** How the plugin should connect to the database (dbi for the perl module `DBD::Sybase` (default) and `sqlrelay` for the SQLRelay proxy). mssql_health_mode | **Required.** The mode uses predefined keywords for the different checks. For example "connection-time", "database-free" or "sql". mssql_health_regexp | **Optional.** If set to true, "mssql_health_name" will be interpreted as a regular expression. Defaults to false. mssql_health_warning | **Optional.** The warning threshold depending on the mode. mssql_health_critical | **Optional.** The critical threshold depending on the mode. mssql_health_warningx | **Optional.** A possible override for the warning threshold. mssql_health_criticalx | **Optional.** A possible override for the critical threshold. mssql_health_units | **Optional.** This is used for a better output of mode=sql and for specifying thresholds for mode=tablespace-free. Possible values are "%", "KB", "MB" and "GB". mssql_health_name | **Optional.** Depending on the mode this could be the database name or a SQL statement. mssql_health_name2 | **Optional.** If "mssql_health_name" is a sql statement, "mssql_health_name2" can be used to appear in the output and the performance data. mssql_health_name3 | **Optional.** Additional argument used for 'database-file-free' mode for example. mssql_health_extraopts | **Optional.** Read command line arguments from an external file. mssql_health_blacklist | **Optional.** Blacklist some (missing/failed) components mssql_health_mitigation | **Optional.** The parameter allows you to change a critical error to a warning. mssql_health_lookback | **Optional.** The amount of time you want to look back when calculating average rates. mssql_health_environment | **Optional.** Add a variable to the plugin's environment. mssql_health_negate | **Optional.** Emulate the negate plugin. --negate warning=critical --negate unknown=critical. mssql_health_morphmessage | **Optional.** Modify the final output message. mssql_health_morphperfdata | **Optional.** The parameter allows you to change performance data labels. mssql_health_selectedperfdata | **Optional.** The parameter allows you to limit the list of performance data. mssql_health_report | **Optional.** Report can be used to output only the bad news. Possible values are "short", "long", "html". Defaults to `short`. mssql_health_multiline | **Optional.** Multiline output. mssql_health_withmymodulesdyndir | **Optional.** Add-on modules for the my-modes will be searched in this directory. mssql_health_statefilesdir | **Optional.** An alternate directory where the plugin can save files. mssql_health_isvalidtime | **Optional.** Signals the plugin to return OK if now is not a valid check time. mssql_health_timeout | **Optional.** Plugin timeout. Defaults to 15s. #### mysql_health The [check_mysql_health](https://labs.consol.de/nagios/check_mysql_health/index.html) plugin uses the `DBD::MySQL` Perl library to monitor a [MySQL](https://dev.mysql.com/downloads/mysql/) or [MariaDB](https://mariadb.org/about/) database. The Git repository is located on [GitHub](https://github.com/lausser/check_mysql_health). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|------------------------------------------------------------------------------------------------------------------------------ mysql_health_hostname | **Required.** Specifies the database hostname or address. Defaults to "$address$" or "$address6$" if the `address` attribute is not set. mysql_health_port | **Optional.** Specifies the database port. Defaults to 3306 (or 1186 for "mysql_health_mode" cluster). mysql_health_socket | **Optional.** Specifies the database unix socket. No default. mysql_health_username | **Optional.** The username for the database connection. mysql_health_password | **Optional.** The password for the database connection. mysql_health_database | **Optional.** The database to connect to. Defaults to information_schema. mysql_health_warning | **Optional.** The warning threshold depending on the mode. mysql_health_critical | **Optional.** The critical threshold depending on the mode. mysql_health_warningx | **Optional.** The extended warning thresholds depending on the mode. mysql_health_criticalx | **Optional.** The extended critical thresholds depending on the mode. mysql_health_mode | **Required.** The mode uses predefined keywords for the different checks. For example "connection-time", "slave-lag" or "sql". mysql_health_method | **Optional.** How the plugin should connect to the database (`dbi` for using DBD::Mysql (default), `mysql` for using the mysql-Tool). mysql_health_commit | **Optional.** Turns on autocommit for the dbd::\* module. mysql_health_notemp | **Optional.** Ignore temporary databases/tablespaces. mysql_health_nooffline | **Optional.** Skip the offline databases. mysql_health_regexp | **Optional.** Parameter name/name2/name3 will be interpreted as (perl) regular expression. mysql_health_name | **Optional.** The name of a specific component to check. mysql_health_name2 | **Optional.** The secondary name of a component. mysql_health_name3 | **Optional.** The tertiary name of a component. mysql_health_units | **Optional.** This is used for a better output of mode=sql and for specifying thresholds for mode=tablespace-free. Possible values are "%", "KB", "MB" and "GB". mysql_health_labelformat | **Optional.** One of those formats pnp4nagios or groundwork. Defaults to pnp4nagios. mysql_health_extraopts | **Optional.** Read command line arguments from an external file. mysql_health_blacklist | **Optional.** Blacklist some (missing/failed) components mysql_health_mitigation | **Optional.** The parameter allows you to change a critical error to a warning. mysql_health_lookback | **Optional.** The amount of time you want to look back when calculating average rates. mysql_health_environment | **Optional.** Add a variable to the plugin's environment. mysql_health_morphmessage | **Optional.** Modify the final output message. mysql_health_morphperfdata | **Optional.** The parameter allows you to change performance data labels. mysql_health_selectedperfdata | **Optional.** The parameter allows you to limit the list of performance data. mysql_health_report | **Optional.** Can be used to shorten the output. mysql_health_multiline | **Optional.** Multiline output. mysql_health_negate | **Optional.** Emulate the negate plugin. --negate warning=critical --negate unknown=critical. mysql_health_withmymodulesdyndir | **Optional.** Add-on modules for the my-modes will be searched in this directory. mysql_health_statefilesdir | **Optional.** An alternate directory where the plugin can save files. mysql_health_isvalidtime | **Optional.** Signals the plugin to return OK if now is not a valid check time. mysql_health_timeout | **Optional.** Plugin timeout. Defaults to 60s. #### oracle_health The [check_oracle_health](https://labs.consol.de/nagios/check_oracle_health/index.html) plugin uses the `DBD::Oracle` Perl library to monitor an [Oracle](https://www.oracle.com/database/) database. The Git repository is located on [GitHub](https://github.com/lausser/check_oracle_health). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|------------------------------------------------------------------------------------------------------------------------------ oracle_health_connect | **Required.** Specifies the database connection string (from tnsnames.ora). oracle_health_username | **Optional.** The username for the database connection. oracle_health_password | **Optional.** The password for the database connection. oracle_health_warning | **Optional.** The warning threshold depending on the mode. oracle_health_critical | **Optional.** The critical threshold depending on the mode. oracle_health_mode | **Required.** The mode uses predefined keywords for the different checks. For example "connection-time", "flash-recovery-area-usage" or "sql". oracle_health_method | **Optional.** How the plugin should connect to the database (`dbi` for using DBD::Oracle (default), `sqlplus` for using the sqlplus-Tool). oracle_health_name | **Optional.** The tablespace, datafile, wait event, latch, enqueue depending on the mode or SQL statement to be executed with "oracle_health_mode" sql. oracle_health_name2 | **Optional.** If "oracle_health_name" is a sql statement, "oracle_health_name2" can be used to appear in the output and the performance data. oracle_health_regexp | **Optional.** If set to true, "oracle_health_name" will be interpreted as a regular expression. Defaults to false. oracle_health_units | **Optional.** This is used for a better output of mode=sql and for specifying thresholds for mode=tablespace-free. Possible values are "%", "KB", "MB" and "GB". oracle_health_ident | **Optional.** If set to true, outputs instance and database names. Defaults to false. oracle_health_commit | **Optional.** Set this to true to turn on autocommit for the dbd::oracle module. Defaults to false. oracle_health_noperfdata | **Optional.** Set this to true if you want to disable perfdata. Defaults to false. oracle_health_timeout | **Optional.** Plugin timeout. Defaults to 60s. oracle_health_report | **Optional.** Select the plugin output format. Can be short or long. Defaults to long. oracle_health_notemp | **Optional.** Set this to true to hide temporary and system tablespaces. Defaults to false. Environment Macros: Name | Description --------------------|------------------------------------------------------------------------------------------------------------------------------------------ ORACLE\_HOME | **Required.** Specifies the location of the oracle instant client libraries. Defaults to "/usr/lib/oracle/11.2/client64/lib". Can be overridden by setting the custom variable `oracle_home`. LD\_LIBRARY\_PATH | **Required.** Specifies the location of the oracle instant client libraries for the run-time shared library loader. Defaults to "/usr/lib/oracle/11.2/client64/lib". Can be overridden by setting the custom variable `oracle_ld_library_path`. TNS\_ADMIN | **Required.** Specifies the location of the tnsnames.ora including the database connection strings. Defaults to "/etc/icinga2/plugin-configs". Can be overridden by setting the custom variable `oracle_tns_admin`. #### postgres The [check_postgres](https://bucardo.org/wiki/Check_postgres) plugin uses the `psql` binary to monitor a [PostgreSQL](https://www.postgresql.org/about/) database. The Git repository is located on [GitHub](https://github.com/bucardo/check_postgres). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|------------------------------------------------------------------------------------------------------------------------------ postgres_host | **Optional.** Specifies the database hostname or address. Defaults to "$address$" or "$address6$" if the `address` attribute is not set. If "postgres_unixsocket" is set to true, falls back to unix socket. postgres_port | **Optional.** Specifies the database port. Defaults to 5432. postgres_dbname | **Optional.** Specifies the database name to connect to. Defaults to "postgres" or "template1". postgres_dbuser | **Optional.** The username for the database connection. Defaults to "postgres". postgres_dbpass | **Optional.** The password for the database connection. You can use a .pgpass file instead. postgres_dbservice | **Optional.** Specifies the service name to use inside of pg_service.conf. postgres_warning | **Optional.** Specifies the warning threshold, range depends on the action. postgres_critical | **Optional.** Specifies the critical threshold, range depends on the action. postgres_include | **Optional.** Specifies name(s) items to specifically include (e.g. tables), depends on the action. postgres_exclude | **Optional.** Specifies name(s) items to specifically exclude (e.g. tables), depends on the action. postgres_includeuser | **Optional.** Include objects owned by certain users. postgres_excludeuser | **Optional.** Exclude objects owned by certain users. postgres_standby | **Optional.** Assume that the server is in continuous WAL recovery mode if set to true. Defaults to false. postgres_production | **Optional.** Assume that the server is in production mode if set to true. Defaults to false. postgres_action | **Required.** Determines the test executed. postgres_unixsocket | **Optional.** If "postgres_unixsocket" is set to true, the unix socket is used instead of an address. Defaults to false. postgres_query | **Optional.** Query for "custom_query" action. postgres_valtype | **Optional.** Value type of query result for "custom_query". postgres_reverse | **Optional.** If "postgres_reverse" is set, warning and critical values are reversed for "custom_query" action. postgres_tempdir | **Optional.** Specify directory for temporary files. The default directory is dependent on the OS. More details [here](https://perldoc.perl.org/File/Spec.html). postgres_datadir | **Optional.** Specifies the database directory (PGDATA). This information is required for some actions, such as "bloat", "locks" and "prepared_txns". postgres_language | **Optional.** Specifies the language for messages issued by the plugin. The default language depends on the system configuration. postgres_perflimit | **Optional.** Specifies the maximum number of performance data values returned by the plugin. The default is to return all performance data. postgres_pgcontroldata | **Optional.** Full path to the pg_controldata command line utility, e.g. "/usr/pgsql-12/bin/pg_controldata". #### mongodb The [check_mongodb.py](https://github.com/mzupan/nagios-plugin-mongodb) plugin uses the `pymongo` Python library to monitor a [MongoDB](https://docs.mongodb.com/manual/) instance. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|------------------------------------------------------------------------------------------------------------------------------ mongodb_host | **Required.** Specifies the hostname or address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. mongodb_port | **Required.** The port mongodb is running on. mongodb_user | **Optional.** The username you want to login as. mongodb_passwd | **Optional.** The password you want to use for that user. mongodb_authdb | **Optional.** The database you want to authenticate against. mongodb_warning | **Optional.** The warning threshold we want to set. mongodb_critical | **Optional.** The critical threshold we want to set. mongodb_action | **Required.** The action you want to take. mongodb_maxlag | **Optional.** Get max replication lag (for replication_lag action only). mongodb_mappedmemory | **Optional.** Get mapped memory instead of resident (if resident memory can not be read). mongodb_perfdata | **Optional.** Enable output of Nagios performance data. mongodb_database | **Optional.** Specify the database to check. mongodb_alldatabases | **Optional.** Check all databases (action database_size). mongodb_ssl | **Optional.** Connect using SSL. mongodb_ssl_ca_cert_file | **Optional.** Path to certificate authority file for SSL. mongodb_replicaset | **Optional.** Connect to replicaset. mongodb_replcheck | **Optional.** If set to true, will enable the mongodb_replicaset value needed for "replica_primary" check. mongodb_querytype | **Optional.** The query type to check [query\|insert\|update\|delete\|getmore\|command] from queries_per_second. mongodb_collection | **Optional.** Specify the collection to check. mongodb_sampletime | **Optional.** Time used to sample number of pages faults. mongodb_disableretrywrites | **Optional.** If set to true, will disable Retry Writes, to allow counting the QPS. #### elasticsearch The [check_elasticsearch](https://github.com/anchor/nagios-plugin-elasticsearch) plugin uses the HTTP API to monitor an [Elasticsearch](https://www.elastic.co/products/elasticsearch) node. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------------|------------------------------------------------------------------------------------------------------- elasticsearch_host | **Optional.** Hostname or network address to probe. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. elasticsearch_failuredomain | **Optional.** A comma-separated list of ElasticSearch attributes that make up your cluster's failure domain. elasticsearch_masternodes | **Optional.** Issue a warning if the number of master-eligible nodes in the cluster drops below this number. By default, do not monitor the number of nodes in the cluster. elasticsearch_port | **Optional.** TCP port to probe. The ElasticSearch API should be listening here. Defaults to 9200. elasticsearch_prefix | **Optional.** Optional prefix (e.g. 'es') for the ElasticSearch API. Defaults to ''. elasticsearch_yellowcritical | **Optional.** Instead of issuing a 'warning' for a yellow cluster state, issue a 'critical' alert. Defaults to false. #### redis The [check_redis.pl](https://github.com/willixix/naglio-plugins/blob/master/check_redis.pl) plugin uses the `Redis` Perl library to monitor a [Redis](https://redis.io/) instance. The plugin can measure response time, hitrate, memory utilization, check replication synchronization, etc. It is also possible to test data in a specified key and calculate averages or summaries on ranges. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -------------------------|-------------------------------------------------------------------------------------------------------------- redis_hostname | **Required.** Hostname or IP Address to check. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. redis_port | **Optional.** Port number to query. Default to "6379". redis_database | **Optional.** Database name (usually a number) to query, needed for **redis_query**. redis_password | **Optional.** Password for Redis authentication. Safer alternative is to put them in a file and use **redis_credentials**. redis_credentials | **Optional.** Credentials file to read for Redis authentication. redis_timeout | **Optional.** Allows to set timeout for execution of this plugin. redis_variables | **Optional.** List of variables from info data to do threshold checks on. redis_warn | **Optional.** This option can only be used if **redis_variables** is used and the number of values listed here must exactly match number of variables specified. redis_crit | **Optional.** This option can only be used if **redis_variables** is used and the number of values listed here must exactly match number of variables specified. redis_perfparse | **Optional.** This should only be used with variables and causes variable data not only to be printed as part of main status line but also as perfparse compatible output. Defaults to false. redis_perfvars | **Optional.** This allows to list variables which values will go only into perfparse output (and not for threshold checking). redis_prev_perfdata | **Optional.** If set to true, previous performance data are used to calculate rate of change for counter statistics variables and for proper calculation of hitrate. Defaults to false. redis_rate_label | **Optional.** Prefix or Suffix label used to create a new variable which has rate of change of another base variable. You can specify PREFIX or SUFFIX or both as one string separated by ",". Default if not specified is suffix "_rate". redis_query | **Optional.** Option specifies key to query and optional variable name to assign the results to after. redis_option | **Optional.** Specifiers are separated by "," and must include NAME or PATTERN. redis_response_time | **Optional.** If this is used, plugin will measure and output connection response time in seconds. With **redis_perfparse** this would also be provided on perf variables. redis_hitrate | **Optional.** Calculates Hitrate and specify values are interpreted as WARNING and CRITICAL thresholds. redis_memory_utilization | **Optional.** This calculates percent of total memory on system used by redis. Total_memory on server must be specified with **redis_total_memory**. If you specify by itself, the plugin will just output this info. Parameter values are interpreted as WARNING and CRITICAL thresholds. redis_total_memory | **Optional.** Amount of memory on a system for memory utilization calculation. Use system memory or max_memory setting of redis. redis_replication_delay | **Optional.** Allows to set threshold on replication delay info. #### proxysql The [check_proxysql](https://github.com/sysown/proxysql-nagios) plugin, uses the `proxysql` binary to monitor [proxysql](https://proxysql.com/). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------------|---------------------------------------------------------------------------------- proxysql_user | **Optional.** ProxySQL admin username (default=admin) proxysql_password | **Optional.** ProxySQL admin password (default=admin) proxysql_host | **Optional.** ProxySQL hostname / IP (default=127.0.0.1) proxysql_port | **Optional.** ProxySQL admin port (default=6032) proxysql_defaultfile | **Optional.** ProxySQL defaults file proxysql_type | **Required.** ProxySQL check type (one of conns,hg,rules,status,var) proxysql_name | **Optional.** ProxySQL variable name to check proxysql_lower | **Optional.** Alert if ProxySQL value are LOWER than defined WARN / CRIT thresholds (only applies to 'var' check type) proxysql_runtime | **Optional.** Force ProxySQL Nagios check to query the runtime_mysql_XXX tables rather than the mysql_XXX tables proxysql_warning | **Optional.** Warning threshold proxysql_critical | **Optional.** Critical threshold proxysql\_include\_hostgroup | **Optional.** ProxySQL hostgroup(s) to include (only applies to '--type hg' checks, accepts comma-separated list) proxysql\_ignore\_hostgroup | **Optional.** ProxySQL hostgroup(s) to ignore (only applies to '--type hg' checks, accepts comma-separated list) #### memcached The [check_memcached](https://exchange.icinga.com/exchange/check_memcached) plugin checks the health of a running [memcached](https://memcached.org/) service. On Debian/Ubuntu, it is provided with the `nagios-plugin-contrib` package. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|---------------------------------------------------------------------------------- memcached_hostname | **Required.** Hostname or IP address (required) optional ':port' overrides -p memcached_port | **Optional.** Port number (default: 11211) memcached_verbose | **Optional.** verbose messages memcached_keep | **Optional.** Keep up to this many items in the history object in memcached (default: 30) memcached_minimum_stat_interval | **Optional.** Minimum time interval (in minutes) to use to analyse stats. (default: 30) memcached_warning_hits_misses | **Optional.** Generate warning if quotient of hits/misses falls below this value (default: 2.0) memcached_warning_evictions | **Optional.** Generate warning if number of evictions exceeds this threshold. 0=disable. (default: 10) memcached_timeout | **Optional.** timeout in seconds (default: 1.0) memcached_key | **Optional.** key name for history object (default: check_memcached) memcached_expiry | **Optional.** expiry time in seconds for history object (default: 7200) memcached_performance_output | **Optional.** output performance statistics as rate-per-minute figures (better suited to pnp4nagios) ### Hardware This category includes all plugin check commands for various hardware checks. #### hpasm The [check_hpasm](https://labs.consol.de/de/nagios/check_hpasm/index.html) plugin monitors the hardware health of HP Proliant Servers, provided that the `hpasm` (HP Advanced Server Management) software is installed. It is also able to monitor the system health of HP Bladesystems and storage systems. The plugin can run in two different ways: 1. Local execution using the `hpasmcli` command line tool. 2. Remote SNMP query which invokes the HP Insight Tools on the remote node. You can either set or omit `hpasm_hostname` custom variable and select the corresponding node. The `hpasm_remote` attribute enables the plugin to execute remote SNMP queries if set to `true`. For compatibility reasons this attribute uses `true` as default value, and ensures that specifying the `hpasm_hostname` always enables remote checks. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|----------------------------------------------------------------------- hpasm_hostname | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. hpasm_community | **Optional.** SNMP community of the server (SNMP v1/2 only). hpasm_protocol | **Optional.** The SNMP protocol to use (default: 2c, other possibilities: 1,3). hpasm_port | **Optional.** The SNMP port to use (default: 161). hpasm_blacklist | **Optional.** Blacklist some (missing/failed) components. hpasm_ignore-dimms | **Optional.** Ignore "N/A"-DIMM status on misc. servers (e.g. older DL320). hpasm_ignore-fan-redundancy | **Optional.** Ignore missing redundancy partners. hpasm_customthresholds | **Optional.** Use custom thresholds for certain temperatures. hpasm_eventrange | **Optional.** Period of time before critical IML events respectively become warnings or vanish. A range is described as a number and a unit (s, m, h, d), e.g. --eventrange 1h/20m. hpasm_perfdata | **Optional.** Output performance data. If your performance data string becomes too long and is truncated by Nagios, then you can use --perfdata=short instead. This will output temperature tags without location information. hpasm_username | **Optional.** The securityName for the USM security model (SNMPv3 only). hpasm_authpassword | **Optional.** The authentication password for SNMPv3. hpasm_authprotocol | **Optional.** The authentication protocol for SNMPv3 (md5\|sha). hpasm_privpassword | **Optional.** The password for authPriv security level. hpasm_privprotocol | **Optional.** The private protocol for SNMPv3 (des\|aes\|aes128\|3des\|3desde). hpasm_servertype | **Optional.** The type of the server: proliant (default) or bladesystem. hpasm_eval-nics | **Optional.** Check network interfaces (and groups). Try it and report me whyt you think about it. I need to build up some know how on this subject. If you get an error and think, it is not justified for your configuration, please tell me about it. (always send the output of "snmpwalk -On .... 1.3.6.1.4.1.232" and a description how you setup your nics and why it is correct opposed to the plugins error message. hpasm_remote | **Optional.** Run remote SNMP checks if enabled. Otherwise checks are executed locally using the `hpasmcli` binary. Defaults to `true`. #### openmanage The [check_openmanage](http://folk.uio.no/trondham/software/check_openmanage.html) plugin checks the hardware health of Dell PowerEdge (and some PowerVault) servers. It uses the Dell OpenManage Server Administrator (OMSA) software, which must be running on the monitored system. check_openmanage can be used remotely with SNMP or locally with icinga2 agent, check_by_ssh or similar, whichever suits your needs and particular taste. The plugin checks the health of the storage subsystem, power supplies, memory modules, temperature probes etc., and gives an alert if any of the components are faulty or operate outside normal parameters. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|----------------------------------------------------------------------- openmanage_all | **Optional.** Check everything, even log content openmanage_blacklist | **Optional.** Blacklist missing and/or failed components openmanage_check | **Optional.** Fine-tune which components are checked openmanage_community | **Optional.** SNMP community string [default=public] openmanage_config | **Optional.** Specify configuration file openmanage_critical | **Optional.** Custom temperature critical limits openmanage_extinfo | **Optional.** Append system info to alerts openmanage_fahrenheit | **Optional.** Use Fahrenheit as temperature unit openmanage_hostname | **Optional.** Hostname or IP (required for SNMP) openmanage_htmlinfo | **Optional.** HTML output with clickable links openmanage_info | **Optional.** Prefix any alerts with the service tag openmanage_ipv6 | **Optional.** Use IPv6 instead of IPv4 [default=no] openmanage_legacy_perfdata | **Optional.** Legacy performance data output openmanage_no_storage | **Optional.** Don't check storage openmanage_only | **Optional.** Only check a certain component or alert type openmanage_perfdata | **Optional.** Output performance data [default=no] openmanage_port | **Optional.** SNMP port number [default=161] openmanage_protocol | **Optional.** SNMP protocol version [default=2c] openmanage_short_state | **Optional.** Prefix alerts with alert state abbreviated openmanage_show_blacklist | **Optional.** Show blacklistings in OK output openmanage_state | **Optional.** Prefix alerts with alert state openmanage_tcp | **Optional.** Use TCP instead of UDP [default=no] openmanage_timeout | **Optional.** Plugin timeout in seconds [default=30] openmanage_vdisk_critical | **Optional.** Make any alerts on virtual disks critical openmanage_warning | **Optional.** Custom temperature warning limits #### lmsensors The [check_lmsensors](https://github.com/jackbenny/check_temp) plugin, uses the `lm-sensors` binary to monitor temperature sensors. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|---------------------------------------------------------------------------------- lmsensors_warning | **Required.** Exit with WARNING status if above INTEGER degrees lmsensors_critical | **Required.** Exit with CRITICAL status if above INTEGER degrees lmsensors_sensor | **Optional.** Set what to monitor, for example CPU or MB (or M/B). Check sensors for the correct word. Default is CPU. #### hddtemp The [check_hddtemp](https://github.com/vint21h/nagios-check-hddtemp) plugin, uses the `hddtemp` binary to monitor hard drive temperature. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|---------------------------------------------------------------------------------- hddtemp_server | **Required.** server name or address hddtemp_port | **Optional.** port number hddtemp_devices | **Optional.** comma separated devices list, or empty for all devices in hddtemp response hddtemp_separator | **Optional.** hddtemp separator hddtemp_warning | **Required.** warning temperature hddtemp_critical | **Required.** critical temperature hddtemp_timeout | **Optional.** receiving data from hddtemp operation network timeout hddtemp_performance | **Optional.** If set, return performance data hddtemp_quiet | **Optional.** If set, be quiet The following sane default value are specified: ``` vars.hddtemp_server = "127.0.0.1" vars.hddtemp_warning = 55 vars.hddtemp_critical = 60 vars.hddtemp_performance = true vars.hddtemp_timeout = 5 ``` #### adaptec-raid The [check_adaptec_raid](https://github.com/thomas-krenn/check_adaptec_raid) plugin uses the `arcconf` binary to monitor Adaptec RAID controllers. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|----------------------------------------------------------------------- adaptec_controller_number | **Required.** Controller number to monitor. arcconf_path | **Required.** Path to the `arcconf` binary, e.g. "/sbin/arcconf". #### lsi-raid The [check_lsi_raid](https://github.com/thomas-krenn/check_lsi_raid) plugin uses the `storcli` binary to monitor MegaRAID RAID controllers. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|----------------------------------------------------------------------- lsi_controller_number | **Optional.** Controller number to monitor. storcli_path | **Optional.** Path to the `storcli` binary, e.g. "/usr/sbin/storcli". lsi_enclosure_id | **Optional.** Enclosure numbers to be checked, comma-separated. lsi_ld_id | **Optional.** Logical devices to be checked, comma-separated. lsi_pd_id | **Optional.** Physical devices to be checked, comma-separated. lsi_temp_warning | **Optional.** RAID controller warning temperature. lsi_temp_critical | **Optional.** RAID controller critical temperature. lsi_pd_temp_warning | **Optional.** Disk warning temperature. lsi_pd_temp_critical | **Optional.** Disk critical temperature. lsi_bbu_temp_warning | **Optional.** Battery warning temperature. lsi_bbu_temp_critical | **Optional.** Battery critical temperature. lsi_cv_temp_warning | **Optional.** CacheVault warning temperature. lsi_cv_temp_critical | **Optional.** CacheVault critical temperature. lsi_ignored_media_errors | **Optional.** Warning threshold for media errors. lsi_ignored_other_errors | **Optional.** Warning threshold for other errors. lsi_ignored_predictive_fails | **Optional.** Warning threshold for predictive failures. lsi_ignored_shield_counters | **Optional.** Warning threshold for shield counter. lsi_ignored_bbm_counters | **Optional.** Warning threshold for BBM counter. lsi_bbu | **Optional.** Define if BBU is present and it's state should be checked. lsi_noenclosures | **Optional.** If set to true, does not check enclosures. lsi_nosudo | **Optional.** If set to true, does not use sudo when running storcli. lsi_nocleanlogs | **Optional.** If set to true, does not clean up the log files after executing storcli checks. #### smart-attributes The [check_smart_attributes](https://github.com/thomas-krenn/check_smart_attributes) plugin uses the `smartctl` binary to monitor SMART values of SSDs and HDDs. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|----------------------------------------------------------------------- smart_attributes_config_path | **Required.** Path to the smart attributes config file (e.g. check_smartdb.json). smart_attributes_device | **Required.** Device name (e.g. /dev/sda) to monitor. ### IcingaCLI This category includes all plugins using the icingacli provided by Icinga Web 2. The user running Icinga 2 needs sufficient permissions to read the Icinga Web 2 configuration directory. e.g. `usermod -a -G icingaweb2 icinga`. You need to restart, not reload Icinga 2 for the new group membership to work. #### Business Process This subcommand is provided by the [business process module](https://exchange.icinga.com/icinga/Business+Process) and executed as `icingacli businessprocess` CLI command. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------------------------|----------------------------------------------------------------------------------------- icingacli_businessprocess_process | **Required.** Business process to monitor. icingacli_businessprocess_config | **Optional.** Configuration file containing your business process without file extension. icingacli_businessprocess_details | **Optional.** Get details for root cause analysis. Defaults to false. icingacli_businessprocess_statetype | **Optional.** Define which state type to look at, `soft` or `hard`. Overrides the default value inside the businessprocess module, if configured. icingacli_businessprocess_ackisok | **Optional.** Treat acknowledged hosts/services always as UP/OK. icingacli_businessprocess_blame | **Optional.** Show problem details as a tree reduced to the nodes which have the same state as the business process. icingacli_businessprocess_colors | **Optional.** Show colored output. icingacli_businessprocess_downtimeisok | **Optional.** Treat hosts/services in downtime always as UP/OK. icingacli_businessprocess_rootcause | **Optional.** Used in combination with *icingacli_businessprocess_blame*. Only shows the paths of the nodes which are responsible for the state of the business process. #### Director This subcommand is provided by the [director module](https://github.com/Icinga/icingaweb2-module-director) > 1.4.2 and executed as `icingacli director health check`. Please refer to the [documentation](https://github.com/Icinga/icingaweb2-module-director/blob/master/doc/60-CLI.md#health-check-plugin) for all available sub-checks. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------------------------|----------------------------------------------------------------------------------------- icingacli_director_check | **Optional.** Run only a specific test suite. icingacli_director_db | **Optional.** Use a specific Icinga Web DB resource. #### Elasticsearch This subcommand is provided by the [elasticsearch_module](https://github.com/Icinga/icingaweb2-module-elasticsearch) and executed as `icingacli elasticsearch check`. * The value of `icingacli_elasticsearch_instance` is the same like in the configuration of the module. * The value of `icingacli_elasticsearch_filter` are filters for events in Icinga Web 2 syntax. e.g. `"beat.hostname=www.example.com" AND severity=critical` * The thresholds are just numerical values. They get checked against how many events match the filter within the given timeframe. * The value of `icingacli_elasticsearch_index` is an index pattern. e.g. `logstash*` Name | Description ------------------------------------------|----------------------------------------------------------------------------------------- icingacli_elasticsearch_instance | **Required.** The Elasticsearch to connect to icingacli_elasticsearch_index | **Required.** Index pattern to use when searching icingacli_elasticsearch_critical | **Required.** Critical threshold icingacli_elasticsearch_warning | **Required.** Warning threshold icingacli_elasticsearch_filter | **Required.** Filter for events icingacli_elasticsearch_from | **Optional.** Negative value of time to search from now (Default: -5m) #### x509 This subcommand is provided by the [x509 module](https://github.com/Icinga/icingaweb2-module-x509) and executed as `icingacli x509 check host`. Please refer to the [documentation](https://github.com/Icinga/icingaweb2-module-x509/blob/master/doc/10-Monitoring.md#host-check-command) for more information. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------------------------|----------------------------------------------------------------------------------------- icingacli_x509_ip | **Required.** A hosts IP address [or] icingacli_x509_host | **Required.** A hosts name icingacli_x509_port | **Optional.** The port to check in particular icingacli_x509_warning | **Optional.** Less remaining time results in state WARNING (Default: 25%) icingacli_x509_critical | **Optional.** Less remaining time results in state CRITICAL (Default: 10%) icingacli_x509_allow_self_signed | **Optional.** Ignore if a certificate or its issuer has been self-signed (Default: false) ### IPMI Devices This category includes all plugins for IPMI devices. #### ipmi-sensor The [check_ipmi_sensor](https://github.com/thomas-krenn/check_ipmi_sensor_v3) plugin uses the `ipmimonitoring` binary to monitor sensor data for IPMI devices. Please read the [documentation](https://www.thomas-krenn.com/en/wiki/IPMI_Sensor_Monitoring_Plugin) for installation and configuration details. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|----------------------------------------------------------------------------------------------------- ipmi_address | **Required.** Specifies the remote host (IPMI device) to check. Defaults to "$address$". ipmi_config_file | **Optional.** Path to the FreeIPMI configuration file. It should contain IPMI username, IPMI password, and IPMI privilege-level. ipmi_username | **Optional.** The IPMI username. ipmi_password | **Optional.** The IPMI password. ipmi_privilege_level | **Optional.** The IPMI privilege level of the IPMI user. ipmi_backward_compatibility_mode | **Optional.** Enable backward compatibility mode, useful for FreeIPMI 0.5.\* (this omits FreeIPMI options "--quiet-cache" and "--sdr-cache-recreate"). ipmi_sensor_type | **Optional.** Limit sensors to query based on IPMI sensor type. Examples for IPMI sensor types are 'Fan', 'Temperature' and 'Voltage'. ipmi_sel_type | **Optional.** Limit SEL entries to specific types, run 'ipmi-sel -L' for a list of types. All sensors are populated to the SEL and per default all sensor types are monitored. ipmi_exclude_sensor_id | **Optional.** Exclude sensor matching ipmi_sensor_id. ipmi_exclude_sensor | **Optional.** Exclude sensor based on IPMI sensor type. (Comma-separated) ipmi_exclude_sel | **Optional.** Exclude SEL entries of specific sensor types. (comma-separated list). ipmi_sensor_id | **Optional.** Include sensor matching ipmi_sensor_id. ipmi_protocol_lan_version | **Optional.** Change the protocol LAN version. Defaults to "LAN_2_0". ipmi_number_of_active_fans | **Optional.** Number of fans that should be active. Otherwise a WARNING state is returned. ipmi_show_fru | **Optional.** Print the product serial number if it is available in the IPMI FRU data. ipmi_show_assettag | **Optional.** Print the assettag if it is available in the IPMI FRU data. (--fru is mandatory) ipmi_show_board | **Optional.** Print additional motherboard informations if it is available in the IPMI FRU data. (--fru is mandatory) ipmi_no_sel_checking | **Optional.** Turn off system event log checking via ipmi-sel. ipmi_no_thresholds | **Optional.** Turn off performance data thresholds from output-sensor-thresholds. ipmi_verbose | **Optional.** Be Verbose multi line output, also with additional details for warnings. ipmi_debug | **Optional.** Be Verbose debugging output, followed by normal multi line output. ipmi_unify_file | **Optional.** Path to the unify file to unify sensor names. #### ipmi-alive The `ipmi-alive` check commands allows you to create a ping check for the IPMI Interface. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------------|----------------------------------------------------------------------------------------------------- ping_address | **Optional.** The address of the IPMI interface. Defaults to "$address$" if the IPMI interface's `address` attribute is set, "$address6$" otherwise. ping_wrta | **Optional.** The RTA warning threshold in milliseconds. Defaults to 5000. ping_wpl | **Optional.** The packet loss warning threshold in %. Defaults to 100. ping_crta | **Optional.** The RTA critical threshold in milliseconds. Defaults to 5000. ping_cpl | **Optional.** The packet loss critical threshold in %. Defaults to 100. ping_packets | **Optional.** The number of packets to send. Defaults to 1. ping_timeout | **Optional.** The plugin timeout in seconds. Defaults to 0 (no timeout). ### Log Management This category includes all plugins for log management, for example [Logstash](https://www.elastic.co/products/logstash). #### logstash The [logstash](https://github.com/NETWAYS/check_logstash) plugin connects to the Node API of Logstash. This plugin requires at least Logstash version 5.0.x. The Node API is not activated by default. You have to configure your Logstash installation in order to allow plugin connections. Name | Description ---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ logstash_hostname | **Optional.** Hostname where Logstash is running. Defaults to `check_address` logstash_port | **Optional.** Port where Logstash is listening for API requests. Defaults to 9600 logstash_filedesc_warn | **Optional.** Warning threshold of file descriptor usage in percent. Defaults to 85 (percent). logstash_filedesc_crit | **Optional.** Critical threshold of file descriptor usage in percent. Defaults to 95 (percent). logstash_heap_warn | **Optional.** Warning threshold of heap usage in percent. Defaults to 70 (percent). logstash_heap_crit | **Optional.** Critical threshold of heap usage in percent Defaults to 80 (percent). logstash_inflight_warn | **Optional.** Warning threshold of inflight events. logstash_inflight_crit | **Optional.** Critical threshold of inflight events. logstash_cpu_warn | **Optional.** Warning threshold for cpu usage in percent. logstash_cpu_crit | **Optional.** Critical threshold for cpu usage in percent. #### logfiles The [logfiles](https://labs.consol.de/nagios/check_logfiles/) plugin finds specified patterns in log files. Name | Description ----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ logfiles_tag | **Optional.** A short unique descriptor for this search. It will appear in the output of the plugin and is used to separare the different services. logfiles_logfile | **Optional.** This is the name of the log file you want to scan. logfiles_rotation | **Optional.** This is the method how log files are rotated. One of the predefined methods or a regular expression, which helps identify the rotated archives. If this key is missing, check_logfiles assumes that the log file will be simply overwritten instead of rotated. logfiles_critical_pattern | **Optional.** A regular expression which will trigger a critical error. logfiles_warning_pattern | **Optional.** A regular expression which will trigger a warning error. logfiles_critical_exception | **Optional.** A regular expression, the exceptions which are not counted as critical errors. logfiles_warning_exception | **Optional.** A regular expression, the exceptions which are not counted as warning errors. logfiles_ok_pattern | **Optional.** A regular expression which resets the error counters. logfiles_no_protocol | **Optional.** Normally all the matched lines are written into a protocol file with this file’s name appearing in the plugin’s output. This option switches this off. logfiles_syslog_server | **Optional.** With this option you limit the pattern matching to lines originating from the host check_logfiles is running on. logfiles_syslog_client | **Optional.** With this option you limit the pattern matching to lines originating from the host named in this option. logfiles_sticky | **Optional.** Errors are propagated through successive runs. logfiles_unstick | **Optional.** Resets sticky errors. logfiles_config | **Optional.** The name of a configuration file. logfiles_configdir | **Optional.** The name of a configuration directory. Configfiles ending in .cfg or .conf are (recursively) imported. logfiles_searches | **Optional.** A list of tags of those searches which are to be run. Using this parameter, not all searches listed in the config file are run, but only those selected. logfiles_selectedsearches | **Optional.** A list of tags of those searches which are to be run. Using this parameter, not all searches listed in the config file are run, but only those selected. logfiles_report | **Optional.** This option turns on multiline output (Default: off). The setting html generates a table which display the last hits in the service details view. Possible values are: short, long, html or off. logfiles_max_length | **Optional.** With this parameter long lines are truncated (Default: off). Some programs (e.g. TrueScan) generate entries in the eventlog of such a length, that the output of the plugin becomes longer than 1024 characters. NSClient++ discards these. logfiles_winwarncrit | **Optional.** With this parameter messages in the eventlog are classified by the type WARNING/ERROR (Default: off). Replaces or complements warning/criticalpattern. logfiles_run_unique | **Optional.** This parameter prevents check_logfiles from starting when there’s already another instance using the same config file. (exits with UNKNOWN). logfiles_timeout | **Optional.** This parameter causes an abort of a running search after a defined number of seconds. It is an aborted in a controlled manner, so that the lines which have been read so far, are used for the computation of the final result. logfiles_warning | **Optional.** Complex handler-scripts can be provided with a warning-parameter this way. Inside the scripts the value is accessible as the macro CL_WARNING. logfiles_critical | **Optional.** Complex handler-scripts can be provided with a critical-parameter this way. Inside the scripts the value is accessible as the macro CL_CRITICAL. ### Metrics This category includes all plugins for metric-based checks. #### graphite The [check_graphite](https://github.com/obfuscurity/nagios-scripts) plugin uses the `rest-client` Ruby library to monitor a [Graphite](https://graphiteapp.org) instance. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------------------|----------------------------------------------------------------------------------------------------- graphite_url | **Required.** Target url. graphite_metric | **Required.** Metric path string. graphite_shortname | **Optional.** Metric short name (used for performance data). graphite_duration | **Optional.** Length, in minute of data to parse (default: 5). graphite_function | **Optional.** Function applied to metrics for thresholds (default: average). graphite_warning | **Required.** Warning threshold. graphite_critical | **Required.** Critical threshold. graphite_units | **Optional.** Adds a text tag to the metric count in the plugin output. Useful to identify the metric units. Doesn't affect data queries. graphite_message | **Optional.** Text message to output (default: "metric count:"). graphite_zero_on_error | **Optional.** Return 0 on a graphite 500 error. graphite_link_graph | **Optional.** Add a link in the plugin output, showing a 24h graph for this metric in graphite. ### Network Components This category includes all plugins for various network components like routers, switches and firewalls. #### interfacetable The [check_interfacetable_v3t](http://www.tontonitch.com/tiki/tiki-index.php?page=Nagios+plugins+-+interfacetable_v3t) plugin generates a html page containing information about the monitored node and all of its interfaces. The Git repository is located on [GitHub](https://github.com/Tontonitch/interfacetable_v3t). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------------------|----------------------------------------------------------------------------------------------------- interfacetable_hostquery | **Required.** Specifies the remote host to poll. Defaults to "$address$". interfacetable_hostdisplay | **Optional.** Specifies the hostname to display in the HTML link. Defaults to "$host.display_name$". interfacetable_regex | **Optional.** Interface names and property names for some other options will be interpreted as regular expressions. Defaults to false. interfacetable_outputshort | **Optional.** Reduce the verbosity of the plugin output. Defaults to false. interfacetable_exclude | **Optional.** Comma separated list of interfaces globally excluded from the monitoring. interfacetable_include | **Optional.** Comma separated list of interfaces globally included in the monitoring. interfacetable_aliasmatching | **Optional.** Allow you to specify alias in addition to interface names. Defaults to false. interfacetable_excludetraffic | **Optional.** Comma separated list of interfaces excluded from traffic checks. interfacetable_includetraffic | **Optional.** Comma separated list of interfaces included for traffic checks. interfacetable_warningtraffic | **Optional.** Interface traffic load percentage leading to a warning alert. interfacetable_criticaltraffic | **Optional.** Interface traffic load percentage leading to a critical alert. interfacetable_pkt | **Optional.** Add unicast/non-unicast pkt stats for each interface. interfacetable_trafficwithpkt | **Optional.** Enable traffic calculation using pkt counters instead of octet counters. Useful when using 32-bit counters to track the load on > 1GbE interfaces. Defaults to false. interfacetable_trackproperty | **Optional.** List of tracked properties. interfacetable_excludeproperty | **Optional.** Comma separated list of interfaces excluded from the property tracking. interfacetable_includeproperty | **Optional.** Comma separated list of interfaces included in the property tracking. interfacetable_community | **Optional.** Specifies the snmp v1/v2c community string. Defaults to "public" if using snmp v1/v2c, ignored using v3. interfacetable_snmpv2 | **Optional.** Use snmp v2c. Defaults to false. interfacetable_login | **Optional.** Login for snmpv3 authentication. interfacetable_passwd | **Optional.** Auth password for snmpv3 authentication. interfacetable_privpass | **Optional.** Priv password for snmpv3 authentication. interfacetable_protocols | **Optional.** Authentication protocol,Priv protocol for snmpv3 authentication. interfacetable_domain | **Optional.** SNMP transport domain. interfacetable_contextname | **Optional.** Context name for the snmp requests. interfacetable_port | **Optional.** SNMP port. Defaults to standard port. interfacetable_64bits | **Optional.** Use SNMP 64-bits counters. Defaults to false. interfacetable_maxrepetitions | **Optional.** Increasing this value may enhance snmp query performances by gathering more results at one time. interfacetable_snmptimeout | **Optional.** Define the Transport Layer timeout for the snmp queries. interfacetable_snmpretries | **Optional.** Define the number of times to retry sending a SNMP message. interfacetable_snmpmaxmsgsize | **Optional.** Size of the SNMP message in octets, useful in case of too long responses. Be careful with network filters. Range 484 - 65535. Apply only to netsnmp perl bindings. The default is 1472 octets for UDP/IPv4, 1452 octets for UDP/IPv6, 1460 octets for TCP/IPv4, and 1440 octets for TCP/IPv6. interfacetable_unixsnmp | **Optional.** Use unix snmp utilities for snmp requests. Defaults to false, which means use the perl bindings. interfacetable_enableperfdata | **Optional.** Enable port performance data. Defaults to false. interfacetable_perfdataformat | **Optional.** Define which performance data will be generated. Possible values are "full" (default), "loadonly", "globalonly". interfacetable_perfdatathreshold | **Optional.** Define which thresholds are printed in the generated performance data. Possible values are "full" (default), "loadonly", "globalonly". interfacetable_perfdatadir | **Optional.** When specified, the performance data are also written directly to a file, in the specified location. interfacetable_perfdataservicedesc | **Optional.** Specify additional parameters for output performance data to PNP. Defaults to "$service.name$", only affects **interfacetable_perfdatadir**. interfacetable_grapher | **Optional.** Specify the used graphing solution. Possible values are "pnp4nagios" (default), "nagiosgrapher", "netwaysgrapherv2" and "ingraph". interfacetable_grapherurl | **Optional.** Graphing system url. Default depends on **interfacetable_grapher**. interfacetable_portperfunit | **Optional.** Traffic could be reported in bits (counters) or in bps (calculated value). interfacetable_nodetype | **Optional.** Specify the node type, for specific information to be printed / specific oids to be used. Possible values: "standard" (default), "cisco", "hp", "netscreen", "netapp", "bigip", "bluecoat", "brocade", "brocade-nos", "nortel", "hpux". interfacetable_duplex | **Optional.** Add the duplex mode property for each interface in the interface table. Defaults to false. interfacetable_stp | **Optional.** Add the stp state property for each interface in the interface table. Defaults to false. interfacetable_vlan | **Optional.** Add the vlan attribution property for each interface in the interface table. Defaults to false. This option is available only for the following nodetypes: "cisco", "hp", "nortel" interfacetable_noipinfo | **Optional.** Remove the ip information for each interface from the interface table. Defaults to false. interfacetable_alias | **Optional.** Add the alias information for each interface in the interface table. Defaults to false. interfacetable_accessmethod | **Optional.** Access method for a shortcut to the host in the HTML page. Format is : [:] Where method can be: ssh, telnet, http or https. interfacetable_htmltablelinktarget | **Optional.** Specifies the windows or the frame where the [details] link will load the generated html page. Possible values are: "_blank", "_self" (default), "_parent", "_top", or a frame name. interfacetable_delta | **Optional.** Set the delta used for interface throughput calculation in seconds. interfacetable_ifs | **Optional.** Input field separator. Defaults to ",". interfacetable_cache | **Optional.** Define the retention time of the cached data in seconds. interfacetable_noifloadgradient | **Optional.** Disable color gradient from green over yellow to red for the load percentage. Defaults to false. interfacetable_nohuman | **Optional.** Do not translate bandwidth usage in human readable format. Defaults to false. interfacetable_snapshot | **Optional.** Force the plugin to run like if it was the first launch. Defaults to false. interfacetable_timeout | **Optional.** Define the global timeout limit of the plugin in seconds. Defaults to "15s". interfacetable_css | **Optional.** Define the css stylesheet used by the generated html files. Possible values are "classic", "icinga" or "icinga-alternate1". interfacetable_config | **Optional.** Specify a config file to load. interfacetable_noconfigtable | **Optional.** Disable configuration table on the generated HTML page. Defaults to false. interfacetable_notips | **Optional.** Disable the tips in the generated html tables. Defaults to false. interfacetable_defaulttablesorting | **Optional.** Default table sorting can be "index" (default) or "name". interfacetable_tablesplit | **Optional.** Generate multiple interface tables, one per interface type. Defaults to false. interfacetable_notype | **Optional.** Remove the interface type for each interface. Defaults to false. #### iftraffic The [check_iftraffic](https://exchange.icinga.com/exchange/iftraffic) plugin checks the utilization of a given interface name using the SNMP protocol. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|--------------------------------------------------------- iftraffic_address | **Required.** Specifies the remote host. Defaults to "$address$". iftraffic_community | **Optional.** SNMP community. Defaults to "public'" if omitted. iftraffic_version | **Optional.** SNMP version to use. Defaults to "1" if omitted. Requires v1.0.2+. iftraffic_interface | **Required.** Queried interface name. iftraffic_bandwidth | **Required.** Interface maximum speed in kilo/mega/giga/bits per second. iftraffic_units | **Optional.** Interface units can be one of these values: `g` (gigabits/s),`m` (megabits/s), `k` (kilobits/s),`b` (bits/s) iftraffic_warn | **Optional.** Percent of bandwidth usage necessary to result in warning status (defaults to `85`). iftraffic_crit | **Optional.** Percent of bandwidth usage necessary to result in critical status (defaults to `98`). iftraffic_max_counter | **Optional.** Maximum counter value of net devices in kilo/mega/giga/bytes. #### iftraffic64 The [check_iftraffic64](https://exchange.icinga.com/exchange/check_iftraffic64) plugin checks the utilization of a given interface name using the SNMP protocol. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|--------------------------------------------------------- iftraffic64_address | **Required.** Specifies the remote host. Defaults to "$address$". iftraffic64_community | **Optional.** SNMP community. Defaults to "public'" if omitted. iftraffic64_interface | **Required.** Queried interface name. iftraffic64_bandwidth | **Required.** Interface maximum speed in kilo/mega/giga/bits per second. iftraffic64_units | **Optional.** Interface units can be one of these values: `g` (gigabits/s),`m` (megabits/s), `k` (kilobits/s),`b` (bits/s) iftraffic64_warn | **Optional.** Percent of bandwidth usage necessary to result in warning status (defaults to `85`). iftraffic64_crit | **Optional.** Percent of bandwidth usage necessary to result in critical status (defaults to `98`). iftraffic64_max_counter | **Optional.** Maximum counter value of net devices in kilo/mega/giga/bytes. #### interfaces The [check_interfaces](https://git.netways.org/plugins/check_interfaces) plugin uses SNMP to monitor network interfaces and their utilization. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------|--------------------------------------------------------- interfaces_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. interfaces_regex | **Optional.** Interface list regexp. interfaces_exclude_regex | **Optional.** Interface list negative regexp. interfaces_errors | **Optional.** Number of in errors (CRC errors for cisco) to consider a warning (default 50). interface_out_errors | **Optional.** Number of out errors (collisions for cisco) to consider a warning (default same as in errors). interfaces_perfdata | **Optional.** perfdata from last check result. interfaces_prefix | **Optional.** Prefix interface names with this label. interfaces_lastcheck | **Optional.** Last checktime (unixtime). interfaces_bandwidth | **Optional.** Bandwidth warn level in percent. interfaces_speed | **Optional.** Override speed detection with this value (bits per sec). interfaces_trim | **Optional.** Cut this number of characters from the start of interface descriptions. interfaces_mode | **Optional.** Special operating mode (default,cisco,nonbulk,bintec). interfaces_auth_proto | **Optional.** SNMPv3 Auth Protocol (SHA\|MD5) interfaces_auth_phrase | **Optional.** SNMPv3 Auth Phrase interfaces_priv_proto | **Optional.** SNMPv3 Privacy Protocol (AES\|DES) interfaces_priv_phrase | **Optional.** SNMPv3 Privacy Phrase interfaces_user | **Optional.** SNMPv3 User interfaces_down_is_ok | **Optional.** Disables critical alerts for down interfaces. interfaces_aliases | **Optional.** Retrieves the interface description. interfaces_match_aliases | **Optional.** Also match against aliases (Option --aliases automatically enabled). interfaces_timeout | **Optional.** Sets the SNMP timeout (in ms). interfaces_sleep | **Optional.** Sleep between every SNMP query (in ms). interfaces_names | **Optional.** If set to true, use ifName instead of ifDescr. #### linux\_netdev The [check\_linux\_netdev](https://github.com/Al2Klimov/check_linux_netdev) plugin monitors a Linux system's network device statistics via `/proc/net/dev`. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------|--------------------------------------------------------- linux\_netdev\_duration | **Optional.** For how long to run. E.g. "10s" or "2m". Default: "1m" linux\_netdev\_exclude | **Optional.** Which NICs to exclude. E.g. `eth0` or `eth?*`, may be an array. Default: none linux\_netdev\_thresholds | **Optional.** Warning and critical thresholds. E.g. `eth?*:tx:bytes:persec:w=1000000000` (see [plugin documentation](https://github.com/Al2Klimov/check_linux_netdev#usage)), may be an array. Default: none #### nwc_health The [check_nwc_health](https://labs.consol.de/de/nagios/check_nwc_health/index.html) plugin uses SNMP to monitor network components. The plugin is able to generate interface statistics, check hardware (CPU, memory, fan, power, etc.), monitor firewall policies, HRSP, load-balancer pools, processor and memory usage. Currently the following network components are supported: Cisco IOS, Cisco Nexus, Cisco ASA, Cisco PIX, F5 BIG-IP, CheckPoint Firewall1, Juniper NetScreen, HP Procurve, Nortel, Brocade 4100/4900, EMC DS 4700, EMC DS 24, Allied Telesyn. Blue Coat SG600, Cisco Wireless Lan Controller 5500, Brocade ICX6610-24-HPOE, Cisco UC Telefonzeugs, FOUNDRY-SN-AGENT-MIB, FRITZ!BOX 7390, FRITZ!DECT 200, Juniper IVE, Pulse-Gateway MAG4610, Cisco IronPort AsyncOS, Foundry, etc. A complete list can be found in the plugin [documentation](https://labs.consol.de/nagios/check_nwc_health/index.html). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|--------------------------------------------------------- nwc_health_hostname | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. nwc_health_mode | **Optional.** The plugin mode. A list of all available modes can be found in the [plugin documentation](https://labs.consol.de/nagios/check_nwc_health/index.html). nwc_health_timeout | **Optional.** Seconds before plugin times out (default: 15) nwc_health_blacklist | **Optional.** Blacklist some (missing/failed) components. nwc_health_port | **Optional.** The SNMP port to use (default: 161). nwc_health_domain | **Optional.** The transport domain to use (default: udp/ipv4, other possible values: udp6, udp/ipv6, tcp, tcp4, tcp/ipv4, tcp6, tcp/ipv6). nwc_health_protocol | **Optional.** The SNMP protocol to use (default: 2c, other possibilities: 1,3). nwc_health_community | **Optional.** SNMP community of the server (SNMP v1/2 only). nwc_health_username | **Optional.** The securityName for the USM security model (SNMPv3 only). nwc_health_authpassword | **Optional.** The authentication password for SNMPv3. nwc_health_authprotocol | **Optional.** The authentication protocol for SNMPv3 (md5\|sha). nwc_health_privpassword | **Optional.** The password for authPriv security level. nwc_health_privprotocol | **Optional.** The private protocol for SNMPv3 (des\|aes\|aes128\|3des\|3desde). nwc_health_contextengineid | **Optional.** The context engine id for SNMPv3 (10 to 64 hex characters). nwc_health_contextname | **Optional.** The context name for SNMPv3 (empty represents the default context). nwc_health_community2 | **Optional.** SNMP community which can be used to switch the context during runtime. nwc_health_name | **Optional.** The name of an interface (ifDescr). nwc_health_drecksptkdb | **Optional.** This parameter must be used instead of --name, because Devel::ptkdb is stealing the latter from the command line. nwc_health_alias | **Optional.** The alias name of a 64bit-interface (ifAlias) nwc_health_regexp | **Optional.** A flag indicating that --name is a regular expression nwc_health_ifspeedin | **Optional.** Override the ifspeed oid of an interface (only inbound) nwc_health_ifspeedout | **Optional.** Override the ifspeed oid of an interface (only outbound) nwc_health_ifspeed | **Optional.** Override the ifspeed oid of an interface nwc_health_units | **Optional.** One of %, B, KB, MB, GB, Bit, KBi, MBi, GBi. (used for e.g. mode interface-usage) nwc_health_name2 | **Optional.** The secondary name of a component. nwc_health_name3 | **Optional.** The tertiary name of a component. nwc_health_role | **Optional.** The role of this device in a hsrp group (active/standby/listen). nwc_health_report | **Optional.** Can be used to shorten the output. Possible values are: 'long' (default), 'short' (to shorten if available), or 'html' (to produce some html outputs if available) nwc_health_lookback | **Optional.** The amount of time you want to look back when calculating average rates. Use it for mode interface-errors or interface-usage. Without --lookback the time between two runs of check_nwc_health is the base for calculations. If you want your checkresult to be based for example on the past hour, use --lookback 3600. nwc_health_warning | **Optional.** The warning threshold nwc_health_critical | **Optional.** The critical threshold nwc_health_warningx | **Optional.** The extended warning thresholds nwc_health_criticalx | **Optional.** The extended critical thresholds nwc_health_mitigation | **Optional.** The parameter allows you to change a critical error to a warning (1) or ok (0). nwc_health_selectedperfdata | **Optional.** The parameter allows you to limit the list of performance data. It's a perl regexp. Only matching perfdata show up in the output. nwc_health_morphperfdata | **Optional.** The parameter allows you to change performance data labels. It's a perl regexp and a substitution. --morphperfdata '(.*)ISATAP(.*)'='$1patasi$2' nwc_health_negate | **Optional.** The parameter allows you to map exit levels, such as warning=critical. nwc_health_mymodules-dyn-dir | **Optional.** A directory where own extensions can be found. nwc_health_servertype | **Optional.** The type of the network device: cisco (default). Use it if auto-detection is not possible. nwc_health_statefilesdir | **Optional.** An alternate directory where the plugin can save files. nwc_health_oids | **Optional.** A list of oids which are downloaded and written to a cache file. Use it together with --mode oidcache. nwc_health_offline | **Optional.** The maximum number of seconds since the last update of cache file before it is considered too old. nwc_health_multiline | **Optional.** Multiline output #### printer_health The [check_printer_health](https://labs.consol.de/nagios/check_printer_health/index.html) plugin uses SNMP to monitor printer. The plugin is able to generate supply statistics and check hardware. A complete list can be found in the plugin [documentation](https://labs.consol.de/nagios/check_printer_health/index.html). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|--------------------------------------------------------- printer_health_hostname | **Required.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. printer_health_mode | **Required.** The plugin mode. A list of all available modes can be found in the [plugin documentation](https://labs.consol.de/nagios/check_printer_health/index.html). printer_health_timeout | **Optional.** Seconds before plugin times out (default: 15) printer_health_blacklist | **Optional.** Blacklist some (missing/failed) components. printer_health_port | **Optional.** The SNMP port to use (default: 161). printer_health_domain | **Optional.** The transport domain to use (default: udp/ipv4, other possible values: udp6, udp/ipv6, tcp, tcp4, tcp/ipv4, tcp6, tcp/ipv6). printer_health_protocol | **Optional.** The SNMP protocol to use (default: 2c, other possibilities: 1,3). printer_health_community | **Optional.** SNMP community of the server (SNMP v1/2 only). printer_health_username | **Optional.** The securityName for the USM security model (SNMPv3 only). printer_health_authpassword | **Optional.** The authentication password for SNMPv3. printer_health_authprotocol | **Optional.** The authentication protocol for SNMPv3 (md5\|sha). printer_health_privpassword | **Optional.** The password for authPriv security level. printer_health_privprotocol | **Optional.** The private protocol for SNMPv3 (des\|aes\|aes128\|3des\|3desde). printer_health_contextengineid | **Optional.** The context engine id for SNMPv3 (10 to 64 hex characters). printer_health_contextname | **Optional.** The context name for SNMPv3 (empty represents the default context). printer_health_community2 | **Optional.** SNMP community which can be used to switch the context during runtime. printer_health_name | **Optional.** The name of an interface (ifDescr). printer_health_regexp | **Optional.** A flag indicating that --name is a regular expression printer_health_ifspeedin | **Optional.** Override the ifspeed oid of an interface (only inbound) printer_health_ifspeedout | **Optional.** Override the ifspeed oid of an interface (only outbound) printer_health_ifspeed | **Optional.** Override the ifspeed oid of an interface printer_health_units | **Optional.** One of %, B, KB, MB, GB, Bit, KBi, MBi, GBi. (used for e.g. mode interface-usage) printer_health_name2 | **Optional.** The secondary name of a component. printer_health_name3 | **Optional.** The teritary name of a component. printer_health_role | **Optional.** The role of this device in a hsrp group (active/standby/listen). printer_health_report | **Optional.** Can be used to shorten the output. Possible values are: 'long' (default), 'short' (to shorten if available), or 'html' (to produce some html outputs if available) printer_health_lookback | **Optional.** The amount of time you want to look back when calculating average rates. Use it for mode interface-errors or interface-usage. Without --lookback the time between two runs of `check_printer_health` is the base for calculations. If you want your checkresult to be based for example on the past hour, use --lookback 3600. printer_health_warning | **Optional.** The warning threshold printer_health_critical | **Optional.** The critical threshold printer_health_warningx | **Optional.** The extended warning thresholds printer_health_criticalx | **Optional.** The extended critical thresholds printer_health_mitigation | **Optional.** The parameter allows you to change a critical error to a warning (1) or ok (0). printer_health_selectedperfdata | **Optional.** The parameter allows you to limit the list of performance data. It's a perl regexp. Only matching perfdata show up in the output. printer_health_morphperfdata | **Optional.** The parameter allows you to change performance data labels. It's a perl regexp and a substitution. --morphperfdata '(.*)ISATAP(.*)'='$1patasi$2' printer_health_negate | **Optional.** The parameter allows you to map exit levels, such as warning=critical. printer_health_mymodules-dyn-dir | **Optional.** A directory where own extensions can be found. printer_health_servertype | **Optional.** The type of the network device: cisco (default). Use it if auto-detection is not possible. printer_health_statefilesdir | **Optional.** An alternate directory where the plugin can save files. printer_health_oids | **Optional.** A list of oids which are downloaded and written to a cache file. Use it together with --mode oidcache. printer_health_offline | **Optional.** The maximum number of seconds since the last update of cache file before it is considered too old. printer_health_multiline | **Optional.** Multiline output #### Thola The [Thola](https://thola.io) plugin is a tool for monitoring network devices, that mainly uses SNMP. To run these commands you need a server that is running the Thola API. If you don't know how to do this, you can have a look at the plugin's [documentation](https://docs.thola.io). Also, you have to put the Thola-client binary into the `PluginContribDir`. ##### thola-cpu-load Checks the CPU load of a network device. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -------------------------------|-------------------------------------------------------- thola_api_address | **Required.** Address of the Thola API to connect to thola_device_address | **Required.** The host's address. Defaults to "$address$" if the host's address attribute is set, “$address6$” otherwise. thola_device_snmp_community | **Optional.** SNMP community of the device thola_device_snmp_protocol | **Optional.** SNMP version to use thola_cpu_load_critical | **Optional.** Critical threshold for the CPU load in % thola_cpu_load_warning | **Optional.** Warning threshold for the CPU load in % ##### thola-interface-metrics Checks the interface metrics of a network device. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|----------------------------------------------------- thola_api_address | **Required.** Address of the Thola API to connect to thola_device_address | **Required.** The host's address. Defaults to "$address$" if the host's address attribute is set, “$address6$” otherwise thola_device_snmp_community | **Optional.** SNMP community of the device ##### thola-hardware-health Checks the hardware health of a network device. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------------|----------------------------------------------------- thola_api_address | **Required.** Address of the Thola API to connect to thola_device_address | **Required.** The host's address. Defaults to "$address$" if the host's address attribute is set, “$address6$” otherwise thola_device_snmp_community | **Optional.** SNMP community of the device ##### thola-identify Checks if a device can be identified by the given properties. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------------------|-------------------------------------------------------------------------------- thola_api_address | **Required.** Address of the Thola API to connect to thola_device_address | **Required.** The host's address. Defaults to "$address$" if the host's address attribute is set, “$address6$” otherwise thola_device_snmp_community | **Optional.** SNMP community of the device thola_identify_model | **Optional.** Model that is compared to the actual model of the device thola_identify_os_version | **Optional.** OS-version that is compared to the actual OS-version of the device thola_identify_vendor | **Optional.** Vendor that is compared to the actual vendor of the device thola_identify_serial_number | **Optional.** Serial number that is compared to the actual serial number of the device thola_identify_discover_retries | **Optional.** The number of discover retries before aborting thola_identify_discover_timeouts | **Optional.** The number of discover timeouts before aborting > **Note**: > > One of the variables `thola_identify_model`, `thola_identify_os_version`, > `thola_identify_vendor` or `thola_identify_serial_number` must be set ##### thola-memory-usage Checks the memory usage of a device. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -------------------------------|----------------------------------------------------- thola_api_address | **Required.** Address of the Thola API to connect to thola_device_address | **Required.** The host's address. Defaults to "$address$" if the host's address attribute is set, “$address6$” otherwise thola_device_snmp_community | **Optional.** SNMP community of the device thola_memory_usage_critical | **Optional.** Critical threshold for the memory usage in % thola_memory_usage_warning | **Optional.** Warning threshold for the memory usage in % ##### thola-sbc Checks special metrics from sbc network devices. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------------------------|----------------------------------------------------------- thola_api_address | **Required.** Address of the Thola API to connect to thola_device_address | **Required.** The host's address. Defaults to "$address$" if the host's address attribute is set, “$address6$” otherwise thola_device_snmp_community | **Optional.** SNMP community of the device thola_sbc_system_health_score_critical | **Optional.** Critical threshold for the health score in % thola_sbc_system_health_score_warning | **Optional.** Warning threshold for the health score in % ##### thola-thola-server Checks if a Thola API is running on a given server. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------|----------------------------------------------------- thola_api_address | **Required.** Address of the Thola API to connect to ##### thola-ups Checks whether a UPS device has its main voltage applied. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------------------|----------------------------------------------------------------- thola_api_address | **Required.** Address of the Thola API to connect to thola_device_address | **Required.** The host's address. Defaults to "$address$" if the host's address attribute is set, “$address6$” otherwise thola_device_snmp_community | **Optional.** SNMP community of the device thola_ups_batt_current_critical_max | **Optional.** High critical threshold for the battery current in Volt thola_ups_batt_current_critical_min | **Optional.** Low critical threshold for the battery current in Volt thola_ups_batt_current_warning_max | **Optional.** High warning threshold for the battery current in Volt thola_ups_batt_current_warning_min | **Optional.** Low warning threshold for the battery current in Volt thola_ups_batt_temperature_critical_max | **Optional.** High critical threshold for the battery temperature in degree celsius thola_ups_batt_temperature_critical_min | **Optional.** Low critical threshold for the battery temperature in degree celsius thola_ups_batt_temperature_warning_max | **Optional.** High warning threshold for the battery temperature in degree celsius thola_ups_batt_temperature_warning_min | **Optional.** Low warning threshold for the battery temperature in degree celsius thola_ups_current_load_critical_max | **Optional.** High critical threshold for the current load in percent thola_ups_current_load_critical_min | **Optional.** Low critical threshold for the current load in percent thola_ups_current_load_warning_max | **Optional.** High warning threshold for the current load in percent thola_ups_current_load_warning_min | **Optional.** Low warning threshold for the current load in percent thola_ups_rectifier_current_critical_max | **Optional.** High critical threshold for the current rectifier in Volt thola_ups_rectifier_current_critical_min | **Optional.** Low critical threshold for the current rectifier in Volt thola_ups_rectifier_current_warning_max | **Optional.** High warning threshold for the current rectifier in Volt thola_ups_rectifier_current_warning_min | **Optional.** Low warning threshold for the current rectifier in Volt thola_ups_system_voltage_critical_max | **Optional.** High critical threshold for the system voltage in Volt thola_ups_system_voltage_critical_min | **Optional.** Low critical threshold for the system voltage in Volt thola_ups_system_voltage_warning_max | **Optional.** High warning threshold for the system voltage in Volt thola_ups_system_voltage_warning_min | **Optional.** Low warning threshold for the system voltage in Volt ### Network Services This category contains plugins which receive details about network services #### lsyncd The [check_lsyncd](https://github.com/ohitz/check_lsyncd) plugin, uses the `lsyncd` status file to monitor [lsyncd](https://axkibe.github.io/lsyncd/). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|--------------------------------------------------------------------------- lsyncd_statfile | **Optional.** Set status file path (default: /var/run/lsyncd.status). lsyncd_warning | **Optional.** Warning if more than N delays (default: 10). lsyncd_critical | **Optional.** Critical if more then N delays (default: 100). #### fail2ban The [check_fail2ban](https://github.com/fail2ban/fail2ban/tree/master/files/nagios) plugin uses the `fail2ban-client` binary to monitor [fail2ban](https://www.fail2ban.org) jails. The plugin requires `sudo` permissions. You can add a sudoers file to allow your monitoring user to use the plugin, i.e. edit /etc/sudoers.d/icinga and add: ``` icinga ALL=(root) NOPASSWD:/usr/lib/nagios/plugins/check_fail2ban ``` and set the correct permissions: ```bash chown -c root: /etc/sudoers.d/icinga chmod -c 0440 /etc/sudoers.d/icinga ``` Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|--------------------------------------------------------------------------- fail2ban_display | **Optional.** To modify the output display, default is 'CHECK FAIL2BAN ACTIVITY' fail2ban_path | **Optional.** Specify the path to the tw_cli binary, default value is /usr/bin/fail2ban-client fail2ban_warning | **Optional.** Specify a warning threshold, default is 1 fail2ban_critical | **Optional.** Specify a critical threshold, default is 2 fail2ban_socket | **Optional.** Specify a socket path, default is unset fail2ban_perfdata | **Optional.** If set to true, activate the perfdata output, default value for the plugin is set to true fail2ban_jail | **Optional.** Specify the name of the specific jail to monitor; omitted by default, i.e. all jails are being monitored. ### Operating System This category contains plugins which receive details about your operating system or the guest system. #### mem The [check_mem.pl](https://github.com/justintime/nagios-plugins) plugin checks the memory usage on linux and unix hosts. It is able to count cache memory as free when compared to thresholds. More details can be found on [this blog entry](http://sysadminsjourney.com/content/2009/06/04/new-and-improved-checkmempl-nagios-plugin). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------|----------------------------------------------------------------------------------------------------------------------- mem_used | **Optional.** Tell the plugin to check for used memory to the exclusion of **mem_free** and **mem_available**. Must specify one of these as true. mem_free | **Optional.** Tell the plugin to check for free memory to the exclusion of **mem_used** and **mem_available**. Must specify one of these as true. mem_available | **Optional.** Tell the plugin to check available memory to the exclusion of **mem_free** and **mem_used**. Must specify one of these as true. mem_cache | **Optional.** If set to true, plugin will count cache as free memory. Defaults to false. mem_warning | **Required.** Specify the warning threshold as number interpreted as percent. mem_critical | **Required.** Specify the critical threshold as number interpreted as percent. #### sar-perf The [check_sar_perf.py](https://github.com/NETWAYS/check-sar-perf) plugin collects performance metrics from Linux hosts using the `sar` binary available in the `sysstat` package. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------|----------------------------------------------------------------------------------------------------------------------- sar_perf_profile | **Required.** Define the run profile: `pagestat`, `cpu`, `memory_util`, `memory_stat`, `io_transfer`, `queueln_load`, `swap_util`, `swap_stat`, `task`, `kernel`, `disk `. Can be a string or an array of multiple profiles. sar_perf_disk | **Optional.** Disk name for the 'disk' profile. #### running_kernel The [check_running_kernel](https://packages.debian.org/stretch/nagios-plugins-contrib) plugin is provided by the `nagios-plugin-contrib` package on Debian/Ubuntu. Custom variables: Name | Description ---------------------------|------------- running\_kernel\_use\_sudo | Whether to run the plugin with `sudo`. Defaults to false except on Ubuntu where it defaults to true. #### iostats The [check_iostats](https://github.com/dnsmichi/icinga-plugins/blob/master/scripts/check_iostats) plugin uses the `iostat` binary to monitor I/O on a Linux host. The default thresholds are rather high so you can use a grapher for baselining before setting your own. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------|----------------------------------------------------------------------------------------------------------------------- iostats\_disk | **Required.** The device to monitor without path. e.g. sda or vda. (default: sda). iostats\_warning\_tps | **Required.** Warning threshold for tps (default: 3000). iostats\_warning\_read | **Required.** Warning threshold for KB/s reads (default: 50000). iostats\_warning\_write | **Required.** Warning threshold for KB/s writes (default: 10000). iostats\_warning\_wait | **Required.** Warning threshold for % iowait (default: 50). iostats\_critical\_tps | **Required.** Critical threshold for tps (default: 5000). iostats\_critical\_read | **Required.** Critical threshold for KB/s reads (default: 80000). iostats\_critical\_write | **Required.** Critical threshold for KB/s writes (default: 25000). iostats\_critical\_wait | **Required.** Critical threshold for % iowait (default: 80). #### iostat The [check_iostat](https://github.com/dnsmichi/icinga-plugins/blob/master/scripts/check_iostat) plugin uses the `iostat` binary to monitor disk I/O on a Linux host. The default thresholds are rather high so you can use a grapher for baselining before setting your own. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------|----------------------------------------------------------------------------------------------------------------------- iostat\_disk | **Required.** The device to monitor without path. e.g. sda or vda. (default: sda). iostat\_wtps | **Required.** Warning threshold for tps (default: 100). iostat\_wread | **Required.** Warning threshold for KB/s reads (default: 100). iostat\_wwrite | **Required.** Warning threshold for KB/s writes (default: 100). iostat\_ctps | **Required.** Critical threshold for tps (default: 200). iostat\_cread | **Required.** Critical threshold for KB/s reads (default: 200). iostat\_cwrite | **Required.** Critical threshold for KB/s writes (default: 200). #### systemd The [check_systemd.py](https://github.com/Josef-Friedrich/check_systemd) plugin will report a degraded system to your monitoring solution. It requires only the [nagiosplugin](https://nagiosplugin.readthedocs.io/en/stable) library. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------- systemd\_unit | **Optional.** Name of the systemd unit that is being tested. systemd\_exclude\_unit | **Optional.** Exclude a systemd unit from the checks. This option can be applied multiple times. Also supports regular expressions. systemd\_no\_startup\_time | **Optional.** Don’t check the startup time. Using this option the options `systemd_warning` and `systemd_critical` have no effect. (Default: `false`) systemd\_warning | **Optional.** Startup time in seconds to result in a warning status. (Default: `60s`) systemd\_critical | **Optional.** Startup time in seconds to result in a critical status. (Default: `120s`) systemd\_dead\_timers | **Optional.** Detect dead / inactive timers. (Default: `false`) systemd\_dead\_timers\_warning | **Optional.** Time ago in seconds for dead / inactive timers to trigger a warning state (by default 6 days). systemd\_dead\_timers\_critical | **Optional.** Time ago in seconds for dead / inactive timers to trigger a critical state (by default 7 days). systemd\_verbose\_level | **Optional.** Increase verbosity level (Accepted values: `1`, `2` or `3`). (Defaults to none) #### yum The [check_yum](https://github.com/calestyo/check_yum) plugin checks the YUM package management system for package updates. The plugin requires the `yum-plugin-security` package to differentiate between security and normal updates. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yum_all_updates | **Optional.** Set to true to not distinguish between security and non-security updates, but returns critical for any available update. This may be used if the YUM security plugin is absent or you want to maintain every single package at the latest version. You may want to use **yum_warn_on_any_update** instead of this option. Defaults to false. yum_warn_on_any_update | **Optional.** Set to true to warn if there are any (non-security) package updates available. Defaults to false. yum_cache_only | **Optional.** If set to true, plugin runs entirely from cache and does not update the cache when running YUM. Useful if you have `yum makecache` cronned. Defaults to false. yum_no_warn_on_lock | **Optional.** If set to true, returns OK instead of WARNING when YUM is locked and fails to check for updates due to another instance running. Defaults to false. yum_no_warn_on_updates | **Optional.** If set to true, returns OK instead of WARNING even when updates are available. The plugin output still shows the number of available updates. Defaults to false. yum_enablerepo | **Optional.** Explicitly enables a repository when calling YUM. Can take a comma separated list of repositories. Note that enabling repositories can lead to unexpected results, for example when protected repositories are enabled. yum_disablerepo | **Optional.** Explicitly disables a repository when calling YUM. Can take a comma separated list of repositories. Note that enabling repositories can lead to unexpected results, for example when protected repositories are enabled. yum_installroot | **Optional.** Specifies another installation root directory (for example a chroot). yum_timeout | **Optional.** Set a timeout in seconds after which the plugin will exit (defaults to 55 seconds). ### Storage This category includes all plugins for various storage and object storage technologies. #### glusterfs The [glusterfs](https://www.unixadm.org/software/nagios-stuff/checks/check_glusterfs) plugin is used to check the GlusterFS storage health on the server. The plugin requires `sudo` permissions. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ glusterfs_perfdata | **Optional.** Print perfdata of all or the specified volume. glusterfs_warnonfailedheal | **Optional.** Warn if the *heal-failed* log contains entries. The log can be cleared by restarting glusterd. glusterfs_volume | **Optional.** Only check the specified *VOLUME*. If --volume is not set, all volumes are checked. glusterfs_disk_warning | **Optional.** Warn if disk usage is above *DISKWARN*. Defaults to 90 (percent). glusterfs_disk_critical | **Optional.** Return a critical error if disk usage is above *DISKCRIT*. Defaults to 95 (percent). glusterfs_inode_warning | **Optional.** Warn if inode usage is above *DISKWARN*. Defaults to 90 (percent). glusterfs_inode_critical | **Optional.** Return a critical error if inode usage is above *DISKCRIT*. Defaults to 95 (percent). #### ceph The [ceph plugin](https://github.com/ceph/ceph-nagios-plugins) is used to check the Ceph storage health on the server. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------|--------------------------------------------------------- ceph_exec_dir | **Optional.** Ceph executable. Default /usr/bin/ceph. ceph_conf_file | **Optional.** Alternative ceph conf file. ceph_mon_address | **Optional.** Ceph monitor address[:port]. ceph_client_id | **Optional.** Ceph client id. ceph_client_name | **Optional.** Ceph client name. ceph_client_key | **Optional.** Ceph client keyring file. ceph_whitelist | **Optional.** Whitelist regexp for ceph health warnings. ceph_details | **Optional.** Run 'ceph health detail'. #### btrfs The [btrfs plugin](https://github.com/knorrie/python-btrfs/) is used to check the btrfs storage health on the server. The plugin requires `sudo` permissions. You can add a sudoers file to allow your monitoring user to use the plugin, i.e. edit /etc/sudoers.d/icinga and add: ``` icinga ALL=(root) NOPASSWD:/usr/lib/nagios/plugins/check_btrfs ``` and set the correct permissions: ```bash chown -c root: /etc/sudoers.d/icinga chmod -c 0440 /etc/sudoers.d/icinga ``` [monitoring-plugins-btrfs](https://packages.debian.org/monitoring-plugins-btrfs) provide the necessary binary on debian/ubuntu. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------|--------------------------------------------------------- btrfs_awg | **Optional.** Exit with WARNING status if less than the specified amount of disk space (in GiB) is unallocated btrfs_acg | **Optional.** Exit with CRITICAL status if less than the specified amount of disk space (in GiB) is unallocated btrfs_awp | **Optional.** Exit with WARNING status if more than the specified percent of disk space is allocated btrfs_acp | **Optional.** Exit with CRITICAL status if more than the specified percent of disk space is allocated btrfs_mountpoint | **Required.** Path to the BTRFS mountpoint ### Virtualization This category includes all plugins for various virtualization technologies. #### esxi_hardware The [check_esxi_hardware.py](https://www.claudiokuenzler.com/monitoring-plugins/check_esxi_hardware.php) plugin uses the [pywbem](https://pywbem.github.io/pywbem/) Python library to monitor the hardware of ESXi servers through the [VMWare CIM API](https://developer.vmware.com/apis/207/cim). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ esxi_hardware_host | **Required.** Specifies the host to monitor. Defaults to "$address$". esxi_hardware_user | **Required.** Specifies the user for polling. Must be a local user of the root group on the system. Can also be provided as a file path file:/path/to/.passwdfile, then first string of file is used. esxi_hardware_pass | **Required.** Password of the user. Can also be provided as a file path file:/path/to/.passwdfile, then second string of file is used. esxi_hardware_port | **Optional.** Specifies the CIM port to connect to. Defaults to 5989. esxi_hardware_sslproto | **Optional.** Specifies the SSL/TLS protocol to use. Defaults to local openssl config. esxi_hardware_vendor | **Optional.** Defines the vendor of the server: "auto", "dell", "hp", "ibm", "intel", "unknown" (default). esxi_hardware_html | **Optional.** Add web-links to hardware manuals for Dell servers (use your country extension). Only useful with **esxi_hardware_vendor** = dell. esxi_hardware_ignore | **Optional.** Comma separated list of CIM elements to ignore. esxi_hardware_regex | **Optional.** Allow regular expression lookups of elements in ignore list. Defaults to false. esxi_hardware_perfdata | **Optional.** Add performcedata for graphers like PNP4Nagios to the output. Defaults to false. esxi_hardware_format | **Optional.** Set output format to string or json. Defaults to string. esxi_hardware_pretty | **Optional.** Show plugin output in a human readable format. Only useful with **esxi_hardware_format** = json. esxi_hardware_nopower | **Optional.** Do not collect power performance data, when **esxi_hardware_perfdata** is set to true. Defaults to false. esxi_hardware_novolts | **Optional.** Do not collect voltage performance data, when **esxi_hardware_perfdata** is set to true. Defaults to false. esxi_hardware_nocurrent | **Optional.** Do not collect current performance data, when **esxi_hardware_perfdata** is set to true. Defaults to false. esxi_hardware_notemp | **Optional.** Do not collect temperature performance data, when **esxi_hardware_perfdata** is set to true. Defaults to false. esxi_hardware_nofan | **Optional.** Do not collect fan performance data, when **esxi_hardware_perfdata** is set to true. Defaults to false. esxi_hardware_nolcd | **Optional.** Do not collect lcd/display status data. Defaults to false. #### VMware Check commands for the [check_vmware_esx](https://github.com/BaldMansMojo/check_vmware_esx) plugin. **vmware-esx-dc-volumes** Check command object for the `check_vmware_esx` plugin. Shows all datastore volumes info. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Required.** Datacenter/vCenter hostname. vmware_cluster | **Optional.** ESX or ESXi clustername. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_subselect | **Optional.** Volume name to be checked the free space. vmware_gigabyte | **Optional.** Output in GB instead of MB. vmware_usedspace | **Optional.** Output used space instead of free. Defaults to "false". vmware_alertonly | **Optional.** List only alerting volumes. Defaults to "false". vmware_exclude | **Optional.** Blacklist volumes name. No value defined as default. vmware_include | **Optional.** Whitelist volumes name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_dc_volume_used | **Optional.** Output used space instead of free. Defaults to "true". vmware_warn | **Optional.** The warning threshold for volumes. Defaults to "80%". vmware_crit | **Optional.** The critical threshold for volumes. Defaults to "90%". **vmware-esx-dc-runtime-info** Check command object for the `check_vmware_esx` plugin. Shows all runtime info for the datacenter/Vcenter. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Required.** Datacenter/vCenter hostname. vmware_cluster | **Optional.** ESX or ESXi clustername. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-dc-runtime-listvms** Check command object for the `check_vmware_esx` plugin. List of vmware machines and their power state. BEWARE!! In larger environments systems can cause trouble displaying the informations needed due to the mass of data. Use **vmware_alertonly** to avoid this. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Required.** Datacenter/vCenter hostname. vmware_cluster | **Optional.** ESX or ESXi clustername. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_alertonly | **Optional.** List only alerting VMs. Important here to avoid masses of data. vmware_exclude | **Optional.** Blacklist VMs name. No value defined as default. vmware_include | **Optional.** Whitelist VMs name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-dc-runtime-listhost** Check command object for the `check_vmware_esx` plugin. List of VMware ESX hosts and their power state. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Required.** Datacenter/vCenter hostname. vmware_cluster | **Optional.** ESX or ESXi clustername. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_alertonly | **Optional.** List only alerting hosts. Important here to avoid masses of data. vmware_exclude | **Optional.** Blacklist VMware ESX hosts. No value defined as default. vmware_include | **Optional.** Whitelist VMware ESX hosts. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-dc-runtime-listcluster** Check command object for the `check_vmware_esx` plugin. List of VMware clusters and their states. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Required.** Datacenter/vCenter hostname. vmware_cluster | **Optional.** ESX or ESXi clustername. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_alertonly | **Optional.** List only alerting hosts. Important here to avoid masses of data. vmware_exclude | **Optional.** Blacklist VMware cluster. No value defined as default. vmware_include | **Optional.** Whitelist VMware cluster. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-dc-runtime-issues** Check command object for the `check_vmware_esx` plugin. All issues for the host. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Required.** Datacenter/vCenter hostname. vmware_cluster | **Optional.** ESX or ESXi clustername. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist issues. No value defined as default. vmware_include | **Optional.** Whitelist issues. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-dc-runtime-status** Check command object for the `check_vmware_esx` plugin. Overall object status (gray/green/red/yellow). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Required.** Datacenter/vCenter hostname. vmware_cluster | **Optional.** ESX or ESXi clustername. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-dc-runtime-tools** Check command object for the `check_vmware_esx` plugin. Vmware Tools status. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Required.** Datacenter/vCenter hostname. vmware_cluster | **Optional.** ESX or ESXi clustername. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_poweredonly | **Optional.** List only VMs which are powered on. No value defined as default. vmware_alertonly | **Optional.** List only alerting VMs. Important here to avoid masses of data. vmware_exclude | **Optional.** Blacklist VMs. No value defined as default. vmware_include | **Optional.** Whitelist VMs. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. vmware_openvmtools | **Optional** Prevent CRITICAL state for installed and running Open VM Tools. vmware_novmtools | **Optional** Prevent CRITICAL state for missing VMware tools. **vmware-esx-soap-host-check** Check command object for the `check_vmware_esx` plugin. Simple check to verify a successful connection to VMware SOAP API. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-host-uptime** Check command object for the `check_vmware_esx` plugin. Displays uptime of the VMware host. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-host-cpu** Check command object for the `check_vmware_esx` plugin. CPU usage in percentage. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in percent. Defaults to "80%". vmware_crit | **Optional.** The critical threshold in percent. Defaults to "90%". **vmware-esx-soap-host-cpu-ready** Check command object for the `check_vmware_esx` plugin. Percentage of time that the virtual machine was ready, but could not get scheduled to run on the physical CPU. CPU ready time is dependent on the number of virtual machines on the host and their CPU loads. High or growing ready time can be a hint CPU bottlenecks. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-host-cpu-wait** Check command object for the `check_vmware_esx` plugin. CPU time spent in wait state. The wait total includes time spent the CPU idle, CPU swap wait, and CPU I/O wait states. High or growing wait time can be a hint I/O bottlenecks. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-host-cpu-usage** Check command object for the `check_vmware_esx` plugin. Actively used CPU of the host, as a percentage of the total available CPU. Active CPU is approximately equal to the ratio of the used CPU to the available CPU. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in percent. Defaults to "80%". vmware_crit | **Optional.** The critical threshold in percent. Defaults to "90%". **vmware-esx-soap-host-mem** Check command object for the `check_vmware_esx` plugin. All mem info(except overall and no thresholds). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-host-mem-usage** Check command object for the `check_vmware_esx` plugin. Average mem usage in percentage. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in percent. Defaults to "80%". vmware_crit | **Optional.** The critical threshold in percent. Defaults to "90%". **vmware-esx-soap-host-mem-consumed** Check command object for the `check_vmware_esx` plugin. Amount of machine memory used on the host. Consumed memory includes Includes memory used by the Service Console, the VMkernel vSphere services, plus the total consumed metrics for all running virtual machines in MB. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in percent. No value defined as default. vmware_crit | **Optional.** The critical threshold in percent. No value defined as default. **vmware-esx-soap-host-mem-swapused** Check command object for the `check_vmware_esx` plugin. Amount of memory that is used by swap. Sum of memory swapped of all powered on VMs and vSphere services on the host in MB. In case of an error all VMs with their swap used will be displayed. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in percent. No value defined as default. vmware_crit | **Optional.** The critical threshold in percent. No value defined as default. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-mem-overhead** Check command object for the `check_vmware_esx` plugin. Additional mem used by VM Server in MB. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Auhentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in percent. No value defined as default. vmware_crit | **Optional.** The critical threshold in percent. No value defined as default. **vmware-esx-soap-host-mem-memctl** Check command object for the `check_vmware_esx` plugin. The sum of all vmmemctl values in MB for all powered-on virtual machines, plus vSphere services on the host. If the balloon target value is greater than the balloon value, the VMkernel inflates the balloon, causing more virtual machine memory to be reclaimed. If the balloon target value is less than the balloon value, the VMkernel deflates the balloon, which allows the virtual machine to consume additional memory if needed (used by VM memory control driver). In case of an error all VMs with their vmmemctl values will be displayed. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in percent. No value defined as default. vmware_crit | **Optional.** The critical threshold in percent. No value defined as default. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-net** Check command object for the `check_vmware_esx` plugin. Shows net info. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist NICs. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist expression as regexp. **vmware-esx-soap-host-net-usage** Check command object for the `check_vmware_esx` plugin. Overall network usage in KBps(Kilobytes per Second). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in KBps(Kilobytes per Second). No value defined as default. vmware_crit | **Optional.** The critical threshold in KBps(Kilobytes per Second). No value defined as default. **vmware-esx-soap-host-net-receive** Check command object for the `check_vmware_esx` plugin. Data receive in KBps(Kilobytes per Second). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in KBps(Kilobytes per Second). No value defined as default. vmware_crit | **Optional.** The critical threshold in KBps(Kilobytes per Second). No value defined as default. **vmware-esx-soap-host-net-send** Check command object for the `check_vmware_esx` plugin. Data send in KBps(Kilobytes per Second). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold in KBps(Kilobytes per Second). No value defined as default. vmware_crit | **Optional.** The critical threshold in KBps(Kilobytes per Second). No value defined as default. **vmware-esx-soap-host-net-nic** Check command object for the `check_vmware_esx` plugin. Check all active NICs. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist NICs. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist expression as regexp. **vmware-esx-soap-host-volumes** Check command object for the `check_vmware_esx` plugin. Shows all datastore volumes info. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_subselect | **Optional.** Volume name to be checked the free space. vmware_gigabyte | **Optional.** Output in GB instead of MB. vmware_usedspace | **Optional.** Output used space instead of free. Defaults to "false". vmware_alertonly | **Optional.** List only alerting volumes. Defaults to "false". vmware_exclude | **Optional.** Blacklist volumes name. No value defined as default. vmware_include | **Optional.** Whitelist volumes name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_warn | **Optional.** The warning threshold for volumes. Defaults to "80%". vmware_crit | **Optional.** The critical threshold for volumes. Defaults to "90%". vmware_spaceleft | **Optional.** This has to be used in conjunction with thresholds as mentioned above. **vmware-esx-soap-host-io** Check command object for the `check_vmware_esx` plugin. Shows all disk io info. Without subselect no thresholds can be given. All I/O values are aggregated from historical intervals over the past 24 hours with a 5 minute sample rate. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-host-io-aborted** Check command object for the `check_vmware_esx` plugin. Number of aborted SCSI commands. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-resets** Check command object for the `check_vmware_esx` plugin. Number of SCSI bus resets. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-read** Check command object for the `check_vmware_esx` plugin. Average number of kilobytes read from the disk each second. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-read-latency** Check command object for the `check_vmware_esx` plugin. Average amount of time (ms) to process a SCSI read command issued from the Guest OS to the virtual machine. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-write** Check command object for the `check_vmware_esx` plugin. Average number of kilobytes written to disk each second. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-write-latency** Check command object for the `check_vmware_esx` plugin. Average amount of time (ms) taken to process a SCSI write command issued by the Guest OS to the virtual machine. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-usage** Check command object for the `check_vmware_esx` plugin. Aggregated disk I/O rate. For hosts, this metric includes the rates for all virtual machines running on the host. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-kernel-latency** Check command object for the `check_vmware_esx` plugin. Average amount of time (ms) spent by VMkernel processing each SCSI command. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-device-latency** Check command object for the `check_vmware_esx` plugin. Average amount of time (ms) to complete a SCSI command from the physical device. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-queue-latency** Check command object for the `check_vmware_esx` plugin. Average amount of time (ms) spent in the VMkernel queue. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-io-total-latency** Check command object for the `check_vmware_esx` plugin. Average amount of time (ms) taken during the collection interval to process a SCSI command issued by the guest OS to the virtual machine. The sum of kernelWriteLatency and deviceWriteLatency. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-host-media** Check command object for the `check_vmware_esx` plugin. List vm's with attached host mounted media like cd,dvd or floppy drives. This is important for monitoring because a virtual machine with a mount cd or dvd drive can not be moved to another host. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist VMs name. No value defined as default. vmware_include | **Optional.** Whitelist VMs name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-service** Check command object for the `check_vmware_esx` plugin. Shows host service info. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist services name. No value defined as default. vmware_include | **Optional.** Whitelist services name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-runtime** Check command object for the `check_vmware_esx` plugin. Shows runtime info: VMs, overall status, connection state, health, storagehealth, temperature and sensor are represented as one value and without thresholds. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist VMs name. No value defined as default. vmware_include | **Optional.** Whitelist VMs name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. **vmware-esx-soap-host-runtime-con** Check command object for the `check_vmware_esx` plugin. Shows connection state. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-host-runtime-listvms** Check command object for the `check_vmware_esx` plugin. List of VMware machines and their status. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist VMs name. No value defined as default. vmware_include | **Optional.** Whitelist VMs name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-runtime-status** Check command object for the `check_vmware_esx` plugin. Overall object status (gray/green/red/yellow). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-host-runtime-health** Check command object for the `check_vmware_esx` plugin. Checks cpu/storage/memory/sensor status. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist status name. No value defined as default. vmware_include | **Optional.** Whitelist status name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. **vmware-esx-soap-host-runtime-health-listsensors** Check command object for the `check_vmware_esx` plugin. List all available sensors(use for listing purpose only). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist status name. No value defined as default. vmware_include | **Optional.** Whitelist status name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. **vmware-esx-soap-host-runtime-health-nostoragestatus** Check command object for the `check_vmware_esx` plugin. This is to avoid a double alarm if you use **vmware-esx-soap-host-runtime-health** and **vmware-esx-soap-host-runtime-storagehealth**. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist status name. No value defined as default. vmware_include | **Optional.** Whitelist status name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. **vmware-esx-soap-host-runtime-storagehealth** Check command object for the `check_vmware_esx` plugin. Local storage status check. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist storage name. No value defined as default. vmware_include | **Optional.** Whitelist storage name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-runtime-temp** Check command object for the `check_vmware_esx` plugin. Lists all temperature sensors. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist sensor name. No value defined as default. vmware_include | **Optional.** Whitelist sensor name. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-runtime-issues** Check command object for the `check_vmware_esx` plugin. Lists all configuration issues for the host. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist configuration issues. No value defined as default. vmware_include | **Optional.** Whitelist configuration issues. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-storage** Check command object for the `check_vmware_esx` plugin. Shows Host storage info. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist adapters, luns and paths. No value defined as default. vmware_include | **Optional.** Whitelist adapters, luns and paths. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. **vmware-esx-soap-host-storage-adapter** Check command object for the `check_vmware_esx` plugin. List host bus adapters. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist adapters. No value defined as default. vmware_include | **Optional.** Whitelist adapters. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-storage-lun** Check command object for the `check_vmware_esx` plugin. List SCSI logical units. The listing will include: LUN, canonical name of the disc, all of displayed name which is not part of the canonical name and status. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_exclude | **Optional.** Blacklist luns. No value defined as default. vmware_include | **Optional.** Whitelist luns. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. **vmware-esx-soap-host-storage-path** Check command object for the `check_vmware_esx` plugin. List multipaths and the associated paths. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_host | **Required.** ESX or ESXi hostname. vmware_datacenter | **Optional.** Datacenter/vCenter hostname. In case the check is done through a Datacenter/vCenter host. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_alertonly | **Optional.** List only alerting units. Important here to avoid masses of data. Defaults to "false". vmware_exclude | **Optional.** Blacklist paths. No value defined as default. vmware_include | **Optional.** Whitelist paths. No value defined as default. vmware_isregexp | **Optional.** Treat blacklist and whitelist expressions as regexp. vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. vmware_standbyok | **Optional.** For storage systems where a standby multipath is ok and not a warning. Defaults to false. **vmware-esx-soap-vm-cpu** Check command object for the `check_vmware_esx` plugin. Shows all CPU usage info. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-cpu-ready** Check command object for the `check_vmware_esx` plugin. Percentage of time that the virtual machine was ready, but could not get scheduled to run on the physical CPU. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-cpu-wait** Check command object for the `check_vmware_esx` plugin. CPU time spent in wait state. The wait total includes time spent the CPU idle, CPU swap wait, and CPU I/O wait states. High or growing wait time can be a hint I/O bottlenecks. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-cpu-usage** Check command object for the `check_vmware_esx` plugin. Amount of actively used virtual CPU, as a percentage of total available CPU. This is the host's view of the CPU usage, not the guest operating system view. It is the average CPU utilization over all available virtual CPUs in the virtual machine. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** Warning threshold in percent. Defaults to "80%". vmware_crit | **Optional.** Critical threshold in percent. Defaults to "90%". **vmware-esx-soap-vm-mem** Check command object for the `check_vmware_esx` plugin. Shows all memory info, except overall. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-mem-usage** Check command object for the `check_vmware_esx` plugin. Average mem usage in percentage of configured virtual machine "physical" memory. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** Warning threshold in percent. Defaults to "80%". vmware_crit | **Optional.** Critical threshold in percent. Defaults to "90%". **vmware-esx-soap-vm-mem-consumed** Check command object for the `check_vmware_esx` plugin. Amount of guest physical memory in MB consumed by the virtual machine for guest memory. Consumed memory does not include overhead memory. It includes shared memory and memory that might be reserved, but not actually used. Use this metric for charge-back purposes.
**vm consumed memory = memory granted -- memory saved** Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-mem-memctl** Check command object for the `check_vmware_esx` plugin. Amount of guest physical memory that is currently reclaimed from the virtual machine through ballooning. This is the amount of guest physical memory that has been allocated and pinned by the balloon driver. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-net** Check command object for the `check_vmware_esx` plugin. Shows net info. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-net-usage** Check command object for the `check_vmware_esx` plugin. Overall network usage in KBps(Kilobytes per Second). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-net-receive** Check command object for the `check_vmware_esx` plugin. Receive in KBps(Kilobytes per Second). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-net-send** Check command object for the `check_vmware_esx` plugin. Send in KBps(Kilobytes per Second). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-io** Check command object for the `check_vmware_esx` plugin. Shows all disk io info. Without subselect no thresholds can be given. All I/O values are aggregated from historical intervals over the past 24 hours with a 5 minute sample rate. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-io-read** Check command object for the `check_vmware_esx` plugin. Average number of kilobytes read from the disk each second. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session - IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-io-write** Check command object for the `check_vmware_esx` plugin. Average number of kilobytes written to disk each second. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-io-usage** Check command object for the `check_vmware_esx` plugin. Aggregated disk I/O rate. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-runtime** Check command object for the `check_vmware_esx` plugin. Shows virtual machine runtime info. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-runtime-con** Check command object for the `check_vmware_esx` plugin. Shows the connection state. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-runtime-powerstate** Check command object for the `check_vmware_esx` plugin. Shows virtual machine power state: poweredOn, poweredOff or suspended. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-runtime-status** Check command object for the `check_vmware_esx` plugin. Overall object status (gray/green/red/yellow). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-runtime-consoleconnections** Check command object for the `check_vmware_esx` plugin. Console connections to virtual machine. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_warn | **Optional.** The warning threshold. No value defined as default. vmware_crit | **Optional.** The critical threshold. No value defined as default. **vmware-esx-soap-vm-runtime-gueststate** Check command object for the `check_vmware_esx` plugin. Guest OS status. Needs VMware Tools installed and running. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd **vmware-esx-soap-vm-runtime-tools** Check command object for the `check_vmware_esx` plugin. Guest OS status. VMware tools status. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_openvmtools | **Optional** Prevent CRITICAL state for installed and running Open VM Tools. vmware_novmtools | **Optional** Prevent CRITICAL state for missing VMware tools. **vmware-esx-soap-vm-runtime-issues** Check command object for the `check_vmware_esx` plugin. All issues for the virtual machine. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- vmware_datacenter | **Optional.** Datacenter/vCenter hostname. Conflicts with **vmware_host**. vmware_host | **Optional.** ESX or ESXi hostname. Conflicts with **vmware_datacenter**. vmware_vmname | **Required.** Virtual machine name. vmware_sslport | **Optional.** SSL port connection. Defaults to "443". vmware_ignoreunknown | **Optional.** Sometimes 3 (unknown) is returned from a component. But the check itself is ok. With this option the plugin will return OK (0) instead of UNKNOWN (3). Defaults to "false". vmware_ignorewarning | **Optional.** Sometimes 2 (warning) is returned from a component. But the check itself is ok (from an operator view). With this option the plugin will return OK (0) instead of WARNING (1). Defaults to "false". vmware_timeout | **Optional.** Seconds before plugin times out. Defaults to "90". vmware_trace | **Optional.** Set verbosity level of vSphere API request/respond trace. vmware_sessionfile | **Optional.** Session file name enhancement. vmware_sessionfiledir | **Optional.** Path to store the **vmware_sessionfile** file. Defaults to "/var/spool/icinga2/tmp". vmware_nosession | **Optional.** No auth session -- IT SHOULD BE USED FOR TESTING PURPOSES ONLY!. Defaults to "false". vmware_username | **Optional.** The username to connect to Host or vCenter server. No value defined as default. vmware_password | **Optional.** The username's password. No value defined as default. vmware_authfile | **Optional.** Use auth file instead username/password to session connect. No effect if **vmware_username** and **vmware_password** are defined
**Authentication file content:**
username=vmuser
password=p@ssw0rd vmware_multiline | **Optional.** Multiline output in overview. This mean technically that a multiline output uses a HTML **\** for the GUI. No value defined as default. ### Web This category includes all plugins for web-based checks. #### apache-status The [check_apache_status.pl](https://github.com/lbetz/check_apache_status) plugin uses the [/server-status](https://httpd.apache.org/docs/current/mod/mod_status.html) HTTP endpoint to monitor status metrics for the Apache webserver. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|---------------------------------------------------------------------------------- apache_status_address | **Optional.** Host address. Defaults to "$address$" if the host's `address` attribute is set, `address6` otherwise. apache_status_port | **Optional.** HTTP port. apache_status_uri | **Optional.** URL to use, instead of the default (http://`apache_status_address`/server-status). apache_status_ssl | **Optional.** Set to use SSL connection. apache_status_no_validate | **Optional.** Skip SSL certificate validation. apache_status_username | **Optional.** Username for basic auth. apache_status_password | **Optional.** Password for basic auth. apache_status_timeout | **Optional.** Timeout in seconds. apache_status_unreachable | **Optional.** Return CRITICAL if socket timed out or http code >= 500. apache_status_warning | **Optional.** Warning threshold (number of open slots, busy workers and idle workers that will cause a WARNING) like ':20,50,:50'. apache_status_critical | **Optional.** Critical threshold (number of open slots, busy workers and idle workers that will cause a CRITICAL) like ':10,25,:20'. #### ssl_cert The [check_ssl_cert](https://github.com/matteocorti/check_ssl_cert) plugin uses the openssl binary (and optional curl) to check a X.509 certificate. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------|-------------- ssl_cert_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. ssl_cert_port | **Optional.** TCP port number (default: 443). ssl_cert_proxy | **Optional.** Proxy server to use for connecting to the host. Sets http_proxy and the s_client -proxy option. ssl_cert_file | **Optional.** Local file path. Works only if `ssl_cert_address` is set to "localhost". ssl_cert_warn | **Optional.** Minimum number of days a certificate has to be valid. ssl_cert_critical | **Optional.** Minimum number of days a certificate has to be valid to issue a critical status. ssl_cert_cn | **Optional.** Pattern to match the CN of the certificate. ssl_cert_altnames | **Optional.** Matches the pattern specified in -n with alternate ssl_cert_issuer | **Optional.** Pattern to match the issuer of the certificate. ssl_cert_org | **Optional.** Pattern to match the organization of the certificate. ssl_cert_email | **Optional.** Pattern to match the email address contained in the certificate. ssl_cert_serial | **Optional.** Pattern to match the serial number. ssl_cert_noauth | **Optional.** Ignore authority warnings (expiration only) ssl_cert_match_host | **Optional.** Match CN with the host name. ssl_cert_selfsigned | **Optional.** Allow self-signed certificate. ssl_cert_sni | **Optional.** Sets the TLS SNI (Server Name Indication) extension. ssl_cert_timeout | **Optional.** Seconds before connection times out (default: 15) ssl_cert_protocol | **Optional.** Use the specific protocol {http,smtp,pop3,imap,ftp,xmpp,irc,ldap} (default: http). ssl_cert_clientcert | **Optional.** Use client certificate to authenticate. ssl_cert_clientpass | **Optional.** Set passphrase for client certificate. ssl_cert_ssllabs | **Optional.** SSL Labs assessment ssl_cert_ssllabs_nocache | **Optional.** Forces a new check by SSL Labs ssl_cert_rootcert | **Optional.** Root certificate or directory to be used for certificate validation. ssl_cert_ignore_signature | **Optional.** Do not check if the certificate was signed with SHA1 od MD5. ssl_cert_ssl_version | **Optional.** Force specific SSL version out of {ssl2,ssl3,tls1,tls1_1,tls1_2}. ssl_cert_disable_ssl_versions | **Optional.** Disable specific SSL versions out of {ssl2,ssl3,tls1,tls1_1,tls1_2}. Multiple versions can be given as array. ssl_cert_cipher | **Optional.** Cipher selection: force {ecdsa,rsa} authentication. ssl_cert_ignore_expiration | **Optional.** Ignore expiration date. ssl_cert_ignore_host_cn | **Optional.** Do not complain if the CN does not match. ssl_cert_ignore_ocsp | **Optional.** Do not check revocation with OCSP. ssl_cert_ignore_ocsp_errors | **Optional.** Continue if the OCSP status cannot be checked. ssl_cert_ignore_ocsp_timeout | **Optional.** Ignore OCSP result when timeout occurs while checking. ssl_cert_ignore_sct | **Optional.** Do not check for signed certificate timestamps. ssl_cert_ignore_tls_renegotiation | **Optional.** Do not check for renegotiation. #### jmx4perl The [check_jmx4perl](https://metacpan.org/pod/distribution/jmx4perl/scripts/check_jmx4perl) plugin uses the HTTP API exposed by the [Jolokia](https://jolokia.org) web application and queries Java message beans on an application server. It is part of the `JMX::Jmx4Perl` Perl module which includes detailed [documentation](https://metacpan.org/pod/distribution/jmx4perl/scripts/check_jmx4perl). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description -----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------- jmx4perl_url | **Required.** URL to agent web application. Defaults to "http://$address$:8080/jolokia". jmx4perl_product | **Optional.** Name of app server product (e.g. jboss), by default is uses an auto detection facility. jmx4perl_alias | **Optional.** Alias name for attribute (e.g. MEMORY_HEAP_USED). All available aliases can be viewed by executing `jmx4perl aliases` on the command line. jmx4perl_mbean | **Optional.** MBean name (e.g. java.lang:type=Memory). jmx4perl_attribute | **Optional.** Attribute name (e.g. HeapMemoryUsage). jmx4perl_operation | **Optional.** Operation to execute. jmx4perl_value | **Optional.** Shortcut for specifying mbean/attribute/path. Slashes within names must be escaped with backslash. jmx4perl_delta | **Optional.** Switches on incremental mode. Optional argument are seconds used for normalizing. jmx4perl_path | **Optional.** Inner path for extracting a single value from a complex attribute or return value (e.g. used). jmx4perl_target | **Optional.** JSR-160 Service URL specifing the target server. jmx4perl_target_user | **Optional.** Username to use for JSR-160 connection. jmx4perl_target_password | **Optional.** Password to use for JSR-160 connection. jmx4perl_proxy | **Optional.** Proxy to use. jmx4perl_user | **Optional.** User for HTTP authentication. jmx4perl_password | **Optional.** Password for HTTP authentication. jmx4perl_name | **Optional.** Name to use for output, by default a standard value based on the MBean and attribute will be used. jmx4perl_method | **Optional.** HTTP method to use, either get or post. By default a method is determined automatically based on the request type. jmx4perl_base | **Optional.** Base name, which when given, interprets critical and warning values as relative in the range 0 .. 100%. Must be given in the form mbean/attribute/path. jmx4perl_base_mbean | **Optional.** Base MBean name, interprets critical and warning values as relative in the range 0 .. 100%. Requires "jmx4perl_base_attribute". jmx4perl_base_attribute | **Optional.** Base attribute for a relative check. Requires "jmx4perl_base_mbean". jmx4perl_base_path | **Optional.** Base path for relative checks, where this path is used on the base attribute's value. jmx4perl_unit | **Optional.** Unit of measurement of the data retrieved. Recognized values are [B\|KB\|MN\|GB\|TB] for memory values and [us\|ms\|s\|m\|h\|d] for time values. jmx4perl_null | **Optional.** Value which should be used in case of a null return value of an operation or attribute. Defaults to null. jmx4perl_string | **Optional.** Force string comparison for critical and warning checks. Defaults to false. jmx4perl_numeric | **Optional.** Force numeric comparison for critical and warning checks. Defaults to false. jmx4perl_critical | **Optional.** Critical threshold for value. jmx4perl_warning | **Optional.** Warning threshold for value. jmx4perl_label | **Optional.** Label to be used for printing out the result of the check. For placeholders which can be used see the documentation. jmx4perl_perfdata | **Optional.** Whether performance data should be omitted, which are included by default. Defaults to "on" for numeric values, to "off" for strings. jmx4perl_unknown_is_critical | **Optional.** Map UNKNOWN errors to errors with a CRITICAL status. Defaults to false. jmx4perl_timeout | **Optional.** Seconds before plugin times out. Defaults to "15". jmx4perl_config | **Optional.** Path to configuration file. jmx4perl_server | **Optional.** Symbolic name of server url to use, which needs to be configured in the configuration file. jmx4perl_check | **Optional.** Name of a check configuration as defined in the configuration file, use array if you need arguments. #### kdc The [check_kdc](https://exchange.nagios.org/directory/Plugins/Security/check_kdc/details) plugin uses the Kerberos `kinit` binary to monitor Kerberos 5 KDC by acquiring a ticket. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------------------------------------------------------------------- kdc_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, `address6` otherwise. kdc_port | **Optional** Port on which KDC runs (default 88). kdc_principal | **Required** Principal name to authenticate as (including realm). kdc_keytab | **Required** Keytab file containing principal's key. #### nginx_status The [check_nginx_status.pl](https://github.com/regilero/check_nginx_status) plugin uses the [/nginx_status](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html) HTTP endpoint which provides metrics for monitoring Nginx. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------------|---------------------------------------------------------------------------------- nginx_status_host_address | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, `address6` otherwise. nginx_status_port | **Optional.** the http port. nginx_status_url | **Optional.** URL to use, instead of the default (http://`nginx_status_hostname`/nginx_status). nginx_status_servername | **Optional.** ServerName to use if you specified an IP to match the good Virtualhost in your target. nginx_status_ssl | **Optional.** set to use ssl connection. nginx_status_disable_sslverify | **Optional.** set to disable SSL hostname verification. nginx_status_user | **Optional.** Username for basic auth. nginx_status_pass | **Optional.** Password for basic auth. nginx_status_realm | **Optional.** Realm for basic auth. nginx_status_maxreach | **Optional.** Number of max processes reached (since last check) that should trigger an alert. nginx_status_timeout | **Optional.** timeout in seconds. nginx_status_warn | **Optional.** Warning threshold (number of active connections, ReqPerSec or ConnPerSec that will cause a WARNING) like '10000,100,200'. nginx_status_critical | **Optional.** Critical threshold (number of active connections, ReqPerSec or ConnPerSec that will cause a CRITICAL) like '20000,200,300'. #### rbl The [check_rbl](https://github.com/matteocorti/check_rbl) plugin uses the `Net::DNS` Perl library to check whether your SMTP server is blacklisted. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------|-------------------------------------------------------------------------- rbl_hostname | **Optional.** The address or name of the SMTP server to check. Defaults to "$address$" if the host's `address` attribute is set, `address6` otherwise. rbl_server | **Required** List of RBL servers as an array. rbl_warning | **Optional** Number of blacklisting servers for a warning. rbl_critical | **Optional** Number of blacklisting servers for a critical. rbl_timeout | **Optional** Seconds before plugin times out (default: 15). #### squid The [check_squid](https://exchange.icinga.com/exchange/check_squid) plugin uses the `squidclient` binary to monitor a [Squid proxy](http://www.squid-cache.org). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|---------------------------------------------------------------------------------- squid_hostname | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise. squid_data | **Optional.** Data to fetch (default: Connections) available data: Connections Cache Resources Memory FileDescriptors. squid_port | **Optional.** Port number (default: 3128). squid_user | **Optional.** WWW user. squid_password | **Optional.** WWW password. squid_warning | **Optional.** Warning threshold. See http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT for the threshold format. squid_critical | **Optional.** Critical threshold. See http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT for the threshold format. squid_client | **Optional.** Path of squidclient (default: /usr/bin/squidclient). squid_timeout | **Optional.** Seconds before plugin times out (default: 15). #### webinject The [check_webinject](https://labs.consol.de/de/nagios/check_webinject/index.html) plugin uses [WebInject](http://www.webinject.org/manual.html) to test web applications and web services in an automated fashion. It can be used to test individual system components that have HTTP interfaces (JSP, ASP, CGI, PHP, AJAX, Servlets, HTML Forms, XML/SOAP Web Services, REST, etc), and can be used as a test harness to create a suite of HTTP level automated functional, acceptance, and regression tests. A test harness allows you to run many test cases and collect/report your results. WebInject offers real-time results display and may also be used for monitoring system response times. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|-------------- webinject_config_file | **Optional.** There is a configuration file named 'config.xml' that is used to store configuration settings for your project. You can use this to specify which test case files to run and to set some constants and settings to be used by WebInject. webinject_output | **Optional.** This option is followed by a directory name or a prefix to prepended to the output files. This is used to specify the location for writing output files (http.log, results.html, and results.xml). If a directory name is supplied (use either an absolute or relative path and make sure to add the trailing slash), all output files are written to this directory. If the trailing slash is omitted, it is assumed to a prefix and this will be prepended to the output files. You may also use a combination of a directory and prefix. webinject_no_output | **Optional.** Suppresses all output to STDOUT except the results summary. webinject_timeout | **Optional.** The value [given in seconds] will be compared to the global time elapsed to run all the tests. If the tests have all been successful, but have taken more time than the 'globaltimeout' value, a warning message is sent back to Icinga. webinject_report_type | **Optional.** This setting is used to enable output formatting that is compatible for use with specific external programs. The available values you can set this to are: nagios, mrtg, external and standard. webinject_testcase_file | **Optional.** When you launch WebInject in console mode, you can optionally supply an argument for a testcase file to run. It will look for this file in the directory that webinject.pl resides in. If no filename is passed from the command line, it will look in config.xml for testcasefile declarations. If no files are specified, it will look for a default file named 'testcases.xml' in the current [webinject] directory. If none of these are found, the engine will stop and give you an error. #### varnish The [check_varnish](https://github.com/varnish/varnish-nagios) plugin, also available in the [monitoring-plugins-contrib](https://packages.debian.org/sid/nagios-plugins-contrib) on debian, uses the `varnishstat` binary to monitor [varnish](https://varnish-cache.org/). Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|---------------------------------------------------------------------------------- varnish_name | **Optional.** Specify the Varnish instance name varnish_param | **Optional.** Specify the parameter to check (see below). The default is 'ratio'. varnish_critical | **Optional.** Set critical threshold: [@][lo:]hi varnish_warning | **Optional.** Set warning threshold: [@][lo:]hi For *varnish_param*, all items reported by varnishstat(1) are available - use the identifier listed in the left column by `varnishstat -l`. In addition, the following parameters are available: Name | Description ------------------------|---------------------------------------------------------------------------------- uptime | How long the cache has been running (in seconds) ratio | The cache hit ratio expressed as a percentage of hits to hits + misses. Default thresholds are 95 and 90. usage | Cache file usage as a percentage of the total cache space. #### haproxy The [check_haproxy](https://salsa.debian.org/nagios-team/pkg-nagios-plugins-contrib/blob/master/check_haproxy/check_haproxy) plugin, also available in the [monitoring-plugins-contrib](https://packages.debian.org/nagios-plugins-contrib) on debian, uses the `haproxy` csv statistics page to monitor [haproxy](https://www.haproxy.org/) response time. The plugin output performance data for backends sessions and statistics response time. This plugin need to access the csv statistics page. You can configure it in haproxy by adding a new frontend: ``` frontend stats bind 127.0.0.1:80 stats enablestats stats uri /stats ``` The statistics page will be available at `http://127.0.0.1/stats;csv;norefresh`. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ------------------------|---------------------------------------------------------------------------------- haproxy_username | **Optional.** Username for HTTP Auth haproxy_password | **Optional.** Password for HTTP Auth haproxy_url | **Required.** URL of the HAProxy csv statistics page. haproxy_timeout | **Optional.** Seconds before plugin times out (default: 10) haproxy_warning | **Optional.** Warning request time threshold (in seconds) haproxy_critical | **Optional.** Critical request time threshold (in seconds) #### haproxy_status The [check_haproxy_status](https://github.com/jonathanio/monitoring-nagios-haproxy) plugin, uses the `haproxy` statistics socket to monitor [haproxy](https://www.haproxy.org/) frontends/backends. This plugin need read/write access to the statistics socket with an operator level. You can configure it in the global section of haproxy to allow icinga user to use it: ``` stats socket /run/haproxy/admin.sock user haproxy group icinga mode 660 level operator ``` Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description ----------------------------|---------------------------------------------------------------------------------- haproxy\_status\_default | **Optional.** Set/Override the defaults which will be applied to all checks (unless specifically set by --overrides). haproxy\_status\_frontends | **Optional.** Enable checks for the frontends in HAProxy (that they're marked as OPEN and the session limits haven't been reached). haproxy\_status\_nofrontends| **Optional.** Disable checks for the frontends in HAProxy (that they're marked as OPEN and the session limits haven't been reached). haproxy\_status\_backends | **Optional.** Enable checks for the backends in HAProxy (that they have the required quorum of servers, and that the session limits haven't been reached). haproxy\_status\_nobackends | **Optional.** Disable checks for the backends in HAProxy (that they have the required quorum of servers, and that the session limits haven't been reached). haproxy\_status\_servers | **Optional.** Enable checks for the servers in HAProxy (that they haven't reached the limits for the sessions or for queues). haproxy\_status\_noservers | **Optional.** Disable checks for the servers in HAProxy (that they haven't reached the limits for the sessions or for queues). haproxy\_status\_overrides | **Optional.** Override the defaults for a particular frontend or backend, in the form {name}:{override}, where {override} is the same format as --defaults above. haproxy\_status\_socket | **Required.** Path to the socket check_haproxy should connect to #### phpfpm_status The [check_phpfpm_status](https://github.com/regilero/check_phpfpm_status) plugin, uses the `php-fpm` status page to monitor php-fpm. Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters): Name | Description --------------------------|---------------------------------------------------------------------------------- phpfpm\_status\_hostname | **Required.** name or IP address of host to check phpfpm\_status\_port | **Optional.** Http port, or Fastcgi port when using --fastcgi phpfpm\_status\_url | **Optional.** Specific URL (only the path part of it in fact) to use, instead of the default /fpm-status phpfpm\_status\_servername| **Optional.** ServerName, (host header of HTTP request) use it if you specified an IP in -H to match the good Virtualhost in your target phpfpm\_status\_fastcgi | **Optional.** If set, connect directly to php-fpm via network or local socket, using fastcgi protocol instead of HTTP. phpfpm\_status\_user | **Optional.** Username for basic auth phpfpm\_status\_pass | **Optional.** Password for basic auth phpfpm\_status\_realm | **Optional.** Realm for basic auth phpfpm\_status\_debug | **Optional.** If set, debug mode (show http request response) phpfpm\_status\_timeout | **Optional.** timeout in seconds (Default: 15) phpfpm\_status\_ssl | **Optional.** Wether we should use HTTPS instead of HTTP. Note that you can give some extra parameters to this settings. Default value is 'TLSv1' but you could use things like 'TLSv1_1' or 'TLSV1_2' (or even 'SSLv23:!SSLv2:!SSLv3' for old stuff). phpfpm\_status\_verifyssl | **Optional.** If set, verify certificate and hostname from ssl cert, default is 0 (no security), set it to 1 to really make SSL peer name and certificater checks. phpfpm\_status\_cacert | **Optional.** Full path to the cacert.pem certificate authority used to verify ssl certificates (use with --verifyssl). if not given the cacert from Mozilla::CA cpan plugin will be used. phpfpm\_status\_warn | **Optional.** MIN_AVAILABLE_PROCESSES,PROC_MAX_REACHED,QUEUE_MAX_REACHED number of available workers, or max states reached that will cause a warning. -1 for no warning phpfpm\_status\_critical | **Optional.** MIN_AVAILABLE_PROCESSES,PROC_MAX_REACHED,QUEUE_MAX_REACHED number of available workers, or max states reached that will cause an error, -1 for no CRITICAL icinga2-2.14.6/doc/11-cli-commands.md000066400000000000000000000656321501332562400170110ustar00rootroot00000000000000# Icinga 2 CLI Commands Icinga 2 comes with a number of CLI commands which support bash autocompletion. These CLI commands will allow you to use certain functionality provided by and around Icinga 2. Each CLI command provides its own help and usage information, so please make sure to always run them with the `--help` parameter. Run `icinga2` without any arguments to get a list of all available global options. ``` # icinga2 icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 [] Supported commands: * api setup (setup for API) * ca list (lists all certificate signing requests) * ca restore (restores a removed certificate request) * ca remove (removes an outstanding certificate request) * ca sign (signs an outstanding certificate request) * console (Icinga debug console) * daemon (starts Icinga 2) * feature disable (disables specified feature) * feature enable (enables specified feature) * feature list (lists all available features) * node setup (set up node) * node wizard (wizard for node setup) * object list (lists all objects) * pki new-ca (sets up a new CA) * pki new-cert (creates a new CSR) * pki request (requests a certificate) * pki save-cert (saves another Icinga 2 instance's certificate) * pki sign-csr (signs a CSR) * pki ticket (generates a ticket) * pki verify (verify TLS certificates: CN, signed by CA, is CA; Print certificate) * variable get (gets a variable) * variable list (lists all variables) Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -a [ --app ] arg application library name (default: icinga) -l [ --library ] arg load a library -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Report bugs at Icinga home page: ``` ## Icinga 2 CLI Bash Autocompletion Bash Auto-Completion (pressing ``) is provided only for the corresponding context. While `--config` suggests and auto-completes files and directories on disk, `feature enable` only suggests disabled features. RPM and Debian packages install the bash completion files into `/etc/bash_completion.d/icinga2`. You need to install the `bash-completion` package if not already installed. RHEL/Fedora: ```bash yum install bash-completion ``` SUSE: ```bash zypper install bash-completion ``` Debian/Ubuntu: ```bash apt-get install bash-completion ``` Ensure that the `bash-completion.d` directory is added to your shell environment. You can manually source the icinga2 bash-completion file into your current session and test it: ```bash source /etc/bash-completion.d/icinga2 ``` ## Icinga 2 CLI Global Options ### Application Type By default the `icinga2` binary loads the `icinga` library. A different application type can be specified with the `--app` command-line option. Note: This is not needed by the average Icinga user, only developers. ### Libraries Instead of loading libraries using the [`library` config directive](17-language-reference.md#library) you can also use the `--library` command-line option. Note: This is not needed by the average Icinga user, only developers. ### Constants [Global constants](17-language-reference.md#constants) can be set using the `--define` command-line option. ### Config Include Path When including files you can specify that the include search path should be checked. You can do this by putting your configuration file name in angle brackets like this: ``` include ``` This causes Icinga 2 to search its include path for the configuration file `test.conf`. By default the installation path for the [Icinga Template Library](10-icinga-template-library.md#icinga-template-library) is the only search directory. Using the `--include` command-line option additional search directories can be added. ## CLI command: Api Provides helper functions to enable and setup the [Icinga 2 API](12-icinga2-api.md#icinga2-api-setup). ### CLI command: Api Setup ``` # icinga2 api setup --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 api setup [] Setup for Icinga 2 API. Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Command options: --cn arg The certificate's common name Report bugs at Get support: Documentation: Icinga home page: ``` ## CLI command: Ca List and manage incoming certificate signing requests. More details can be found in the [signing methods](06-distributed-monitoring.md#distributed-monitoring-setup-sign-certificates-master) chapter. This CLI command is available since v2.8. ``` # icinga2 ca --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 [] Supported commands: * ca list (lists all certificate signing requests) * ca sign (signs an outstanding certificate request) * ca restore (restores a removed certificate request) * ca remove (removes an outstanding certificate request) Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -a [ --app ] arg application library name (default: icinga) -l [ --library ] arg load a library -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Report bugs at Icinga home page: ``` ### CLI command: Ca List ``` icinga2 ca list --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 ca list [] Lists pending certificate signing requests. Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Command options: --all List all certificate signing requests, including signed. Note: Old requests are automatically cleaned by Icinga after 1 week. --removed List all removed CSRs (for use with 'ca restore') --json encode output as JSON Report bugs at Get support: Documentation: Icinga home page: ``` ## CLI command: Console The CLI command `console` can be used to debug and evaluate Icinga 2 config expressions, e.g. to test [functions](17-language-reference.md#functions) in your local sandbox. ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => function test(name) { <1> .. log("Hello " + name) <1> .. } null <2> => test("World") information/config: Hello World null <3> => ``` Further usage examples can be found in the [library reference](18-library-reference.md#library-reference) chapter. ``` # icinga2 console --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 console [] Interprets Icinga script expressions. Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -a [ --app ] arg application library name (default: icinga) -l [ --library ] arg load a library -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Command options: -c [ --connect ] arg connect to an Icinga 2 instance -e [ --eval ] arg evaluate expression and terminate -r [ --file ] arg evaluate a file and terminate --syntax-only only validate syntax (requires --eval or --file) --sandbox enable sandbox mode Report bugs at Icinga home page: ``` On operating systems without the `libedit` library installed there is no support for line-editing or a command history. However you can use the `rlwrap` program if you require those features: ```bash rlwrap icinga2 console ``` The debug console can be used to connect to a running Icinga 2 instance using the [REST API](12-icinga2-api.md#icinga2-api). [API permissions](12-icinga2-api.md#icinga2-api-permissions) are required for executing config expressions and auto-completion. > **Note** > > The debug console does not currently support TLS certificate verification. > > Runtime modifications are not validated and might cause the Icinga 2 > daemon to crash or behave in an unexpected way. Use these runtime changes > at your own risk and rather *inspect and debug objects read-only*. You can specify the API URL using the `--connect` parameter. Although the password can be specified there process arguments on UNIX platforms are usually visible to other users (e.g. through `ps`). In order to securely specify the user credentials the debug console supports two environment variables: Environment variable | Description ---------------------|------------- ICINGA2_API_USERNAME | The API username. ICINGA2_API_PASSWORD | The API password. Here's an example: ``` $ ICINGA2_API_PASSWORD=icinga icinga2 console --connect 'https://root@localhost:5665/' Icinga 2 (version: v2.11.0) <1> => ``` Once connected you can inspect variables and execute other expressions by entering them at the prompt: ``` <1> => var h = get_host("icinga2-agent1.localdomain") null <2> => h.last_check_result { active = true check_source = "icinga2-agent1.localdomain" command = [ "/usr/local/sbin/check_ping", "-H", "127.0.0.1", "-c", "5000,100%", "-w", "3000,80%" ] execution_end = 1446653527.174983 execution_start = 1446653523.152673 exit_status = 0.000000 output = "PING OK - Packet loss = 0%, RTA = 0.11 ms" performance_data = [ "rta=0.114000ms;3000.000000;5000.000000;0.000000", "pl=0%;80;100;0" ] schedule_end = 1446653527.175133 schedule_start = 1446653583.150000 state = 0.000000 type = "CheckResult" vars_after = { attempt = 1.000000 reachable = true state = 0.000000 state_type = 1.000000 } vars_before = { attempt = 1.000000 reachable = true state = 0.000000 state_type = 1.000000 } } <3> => ``` You can use the `--eval` parameter to evaluate a single expression in batch mode. Using the `--file` option you can specify a file which should be evaluated. The output format for batch mode is JSON. The `--syntax-only` option can be used in combination with `--eval` or `--file` to check a script for syntax errors. In this mode the script is parsed to identify syntax errors but not evaluated. Here's an example that retrieves the command that was used by Icinga to check the `icinga2-agent1.localdomain` host: ``` $ ICINGA2_API_PASSWORD=icinga icinga2 console --connect 'https://root@localhost:5665/' --eval 'get_host("icinga2-agent1.localdomain").last_check_result.command' | python -m json.tool [ "/usr/local/sbin/check_ping", "-H", "127.0.0.1", "-c", "5000,100%", "-w", "3000,80%" ] ``` ## CLI command: Daemon The CLI command `daemon` provides the functionality to start/stop Icinga 2. Furthermore it allows to run the [configuration validation](11-cli-commands.md#config-validation). ``` # icinga2 daemon --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 daemon [] Starts Icinga 2. Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -a [ --app ] arg application library name (default: icinga) -l [ --library ] arg load a library -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Command options: -c [ --config ] arg parse a configuration file -z [ --no-config ] start without a configuration file -C [ --validate ] exit after validating the configuration --dump-objects write icinga2.debug cache file for icinga2 object list -e [ --errorlog ] arg log fatal errors to the specified log file (only works in combination with --daemonize or --close-stdio) -d [ --daemonize ] detach from the controlling terminal --close-stdio do not log to stdout (or stderr) after startup Report bugs at Icinga home page: ``` ### Config Files You can specify one or more configuration files with the `--config` option. Configuration files are processed in the order they're specified on the command-line. When no configuration file is specified and the `--no-config` is not used Icinga 2 automatically falls back to using the configuration file `ConfigDir + "/icinga2.conf"` (where ConfigDir is usually `/etc/icinga2`). ### Validation The `--validate` option can be used to check if configuration files contain errors. If any errors are found, the exit status is 1, otherwise 0 is returned. More details in the [configuration validation](11-cli-commands.md#config-validation) chapter. ## CLI command: Feature The `feature enable` and `feature disable` commands can be used to enable and disable features: ``` # icinga2 feature disable --app --define --include --log-level --version checker graphite mainlog --color --help --library --script-debugger api command ido-mysql notification ``` ``` # icinga2 feature enable --app --define --include --log-level --version debuglog ido-pgsql livestatus perfdata syslog --color --help --library --script-debugger compatlog gelf influxdb opentsdb statusdata ``` The `feature list` command shows which features are currently enabled: ``` # icinga2 feature list Disabled features: compatlog debuglog gelf ido-pgsql influxdb livestatus opentsdb perfdata statusdata syslog Enabled features: api checker command graphite ido-mysql mainlog notification ``` ## CLI command: Node Provides the functionality to setup master and client nodes in a [distributed monitoring](06-distributed-monitoring.md#distributed-monitoring) scenario. ``` # icinga2 node --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 [] Supported commands: * node setup (set up node) * node wizard (wizard for node setup) Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -a [ --app ] arg application library name (default: icinga) -l [ --library ] arg load a library -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Report bugs at Icinga home page: ``` ## CLI command: Object The `object` CLI command can be used to list all configuration objects and their attributes. The command also shows where each of the attributes was modified and as such provides debug information for further configuration problem analysis. That way you can also identify which objects have been created from your [apply rules](17-language-reference.md#apply). Configuration modifications are not immediately updated. Furthermore there is a known issue with [group assign expressions](17-language-reference.md#group-assign) which are not reflected in the host object output. You need to run `icinga2 daemon -C --dump-objects` in order to update the `icinga2.debug` cache file. More information can be found in the [troubleshooting](15-troubleshooting.md#troubleshooting-list-configuration-objects) section. ``` # icinga2 object --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 [] Supported commands: * object list (lists all objects) Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -a [ --app ] arg application library name (default: icinga) -l [ --library ] arg load a library -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Report bugs at Icinga home page: ``` ## CLI command: Pki Provides the CLI commands to * generate a new certificate authority (CA) * generate a new CSR or self-signed certificate * sign a CSR and return a certificate * save a master certificate manually * request a signed certificate from the master * generate a new ticket for the client setup This functionality is used by the [node setup/wizard](11-cli-commands.md#cli-command-node) CLI commands. You will need them in the [distributed monitoring chapter](06-distributed-monitoring.md#distributed-monitoring). ``` # icinga2 pki --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.12.0) Usage: icinga2 [] Supported commands: * pki new-ca (sets up a new CA) * pki new-cert (creates a new CSR) * pki request (requests a certificate) * pki save-cert (saves another Icinga 2 instance's certificate) * pki sign-csr (signs a CSR) * pki ticket (generates a ticket) * pki verify (verify TLS certificates: CN, signed by CA, is CA; Print certificate) Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -a [ --app ] arg application library name (default: icinga) -l [ --library ] arg load a library -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Report bugs at Icinga home page: ``` ## CLI command: Variable Lists all configured variables (constants) in a similar fashion like [object list](11-cli-commands.md#cli-command-object). ``` # icinga2 variable --help icinga2 - The Icinga 2 network monitoring daemon (version: v2.11.0) Usage: icinga2 [] Supported commands: * variable get (gets a variable) * variable list (lists all variables) Global options: -h [ --help ] show this help message -V [ --version ] show version information --color use VT100 color codes even when stdout is not a terminal -D [ --define ] arg define a constant -a [ --app ] arg application library name (default: icinga) -l [ --library ] arg load a library -I [ --include ] arg add include search directory -x [ --log-level ] arg specify the log level for the console log. The valid value is either debug, notice, information (default), warning, or critical -X [ --script-debugger ] whether to enable the script debugger Report bugs at Icinga home page: ``` ## Enabling/Disabling Features Icinga 2 provides configuration files for some commonly used features. These are installed in the `/etc/icinga2/features-available` directory and can be enabled and disabled using the `icinga2 feature enable` and `icinga2 feature disable` [CLI commands](11-cli-commands.md#cli-command-feature), respectively. The `icinga2 feature enable` CLI command creates symlinks in the `/etc/icinga2/features-enabled` directory which is included by default in the example configuration file. You can view a list of enabled and disabled features: ``` # icinga2 feature list Disabled features: api command compatlog debuglog graphite icingastatus ido-mysql ido-pgsql livestatus notification perfdata statusdata syslog Enabled features: checker mainlog notification ``` Using the `icinga2 feature enable` command you can enable features: ``` # icinga2 feature enable graphite Enabling feature graphite. Make sure to restart Icinga 2 for these changes to take effect. ``` You can disable features using the `icinga2 feature disable` command: ``` # icinga2 feature disable ido-mysql livestatus Disabling feature ido-mysql. Make sure to restart Icinga 2 for these changes to take effect. Disabling feature livestatus. Make sure to restart Icinga 2 for these changes to take effect. ``` The `icinga2 feature enable` and `icinga2 feature disable` commands do not restart Icinga 2. You will need to restart Icinga 2 using the init script after enabling or disabling features. ## Configuration Validation Once you've edited the configuration files make sure to tell Icinga 2 to validate the configuration changes. Icinga 2 will log any configuration error including a hint on the file, the line number and the affected configuration line itself. The following example creates an apply rule without any `assign` condition. ``` apply Service "my-ping4" { import "generic-service" check_command = "ping4" //assign where host.address } ``` Validate the configuration: ``` # icinga2 daemon -C [2014-05-22 17:07:25 +0200] critical/ConfigItem: Location: /etc/icinga2/conf.d/tests/my.conf(5): } /etc/icinga2/conf.d/tests/my.conf(6): /etc/icinga2/conf.d/tests/my.conf(7): apply Service "my-ping4" { ^^^^^^^^^^^^^ /etc/icinga2/conf.d/tests/my.conf(8): import "test-generic-service" /etc/icinga2/conf.d/tests/my.conf(9): check_command = "ping4" Config error: 'apply' is missing 'assign' [2014-05-22 17:07:25 +0200] critical/ConfigItem: 1 errors, 0 warnings. Icinga 2 detected configuration errors. ``` If you encounter errors during configuration validation, please make sure to read the [troubleshooting](15-troubleshooting.md#troubleshooting) chapter. You can also use the [CLI command](11-cli-commands.md#cli-command-object) `icinga2 object list` after validation passes to analyze object attributes, inheritance or created objects by apply rules. Find more on troubleshooting with `object list` in [this chapter](15-troubleshooting.md#troubleshooting-list-configuration-objects). ## Reload on Configuration Changes Every time you have changed your configuration you should first tell Icinga 2 to [validate](11-cli-commands.md#config-validation). If there are no validation errors, you can safely reload the Icinga 2 daemon. ```bash systemctl reload icinga2 ``` The `reload` action will send the `SIGHUP` signal to the Icinga 2 daemon which will validate the configuration in a separate process and not stop the other events like check execution, notifications, etc. icinga2-2.14.6/doc/12-icinga2-api.md000066400000000000000000003722331501332562400165250ustar00rootroot00000000000000# REST API * [Setup](12-icinga2-api.md#icinga2-api-setup) * [Introduction](12-icinga2-api.md#icinga2-api-introduction) * Endpoints * [Config Objects](12-icinga2-api.md#icinga2-api-config-objects) * [Actions](12-icinga2-api.md#icinga2-api-actions) * [Event Streams](12-icinga2-api.md#icinga2-api-event-streams) * [Status and Statistics](12-icinga2-api.md#icinga2-api-status) * [Config Management](12-icinga2-api.md#icinga2-api-config-management) * [Types](12-icinga2-api.md#icinga2-api-types) * [Templates](12-icinga2-api.md#icinga2-api-config-templates) * [Variables](12-icinga2-api.md#icinga2-api-variables) * [Debug Console](12-icinga2-api.md#icinga2-api-console) * [API Clients](12-icinga2-api.md#icinga2-api-clients) * [Programmatic Examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples) ## Setting up the API You can run the CLI command `icinga2 api setup` to enable the `api` [feature](11-cli-commands.md#enable-features) and set up certificates as well as a new API user `root` with an auto-generated password in the `/etc/icinga2/conf.d/api-users.conf` configuration file: ```bash icinga2 api setup ``` Make sure to restart Icinga 2 to enable the changes you just made: ```bash systemctl restart icinga2 ``` If you prefer to set up the API manually, you will have to perform the following steps: * Set up X.509 TLS certificates for Icinga 2 * Enable the `api` feature (`icinga2 feature enable api`) * Create an `ApiUser` object for authentication The next chapter provides a quick overview of how you can use the API. ## Introduction The Icinga 2 API allows you to manage configuration objects and resources in a simple, programmatic way using HTTP requests. The URL endpoints are logically separated allowing you to easily make calls to * query, create, modify and delete [config objects](12-icinga2-api.md#icinga2-api-config-objects) * perform [actions](12-icinga2-api.md#icinga2-api-actions) (reschedule checks, etc.) * subscribe to [event streams](12-icinga2-api.md#icinga2-api-event-streams) * [manage configuration packages](12-icinga2-api.md#icinga2-api-config-management) * evaluate [script expressions](12-icinga2-api.md#icinga2-api-console) ### Requests Any tool capable of making HTTP requests can communicate with the API, for example [curl](https://curl.haxx.se/). Requests are only allowed to use the HTTPS protocol so that traffic remains encrypted. By default the Icinga 2 API listens on port `5665` which is shared with the cluster stack. The port can be changed by setting the `bind_port` attribute for the [ApiListener](09-object-types.md#objecttype-apilistener) object in the `/etc/icinga2/features-available/api.conf` configuration file. Supported request methods: Method | Usage -------|-------- GET | Retrieve information about configuration objects. Any request using the GET method is read-only and does not affect any objects. POST | Update attributes of a specified configuration object. PUT | Create a new object. The PUT request must include all attributes required to create a new object. DELETE | Remove an object created by the API. The DELETE method is idempotent and does not require any check if the object actually exists. All requests except `GET` require the following `Accept` header: ``` Accept: application/json ``` Each URL is prefixed with the API version (currently "/v1"). HTTP header size is limited to 8KB per request. ### Responses Successful requests will send back a response body containing a `results` list. Depending on the number of affected objects in your request, the `results` list may contain more than one entry. The output will be sent back as a JSON object: ```json { "results": [ { "code": 200.0, "status": "Object was created." } ] } ``` > **Tip** > > You can use the [pretty](12-icinga2-api.md#icinga2-api-parameters-global) parameter to beautify the JSON response. You can also use [jq](https://stedolan.github.io/jq/) or `python -m json.tool` in combination with curl on the CLI. ```bash curl ... | jq curl ... | python -m json.tool ``` jq also has additional filter capabilities, as shown in [this blogpost](https://www.netways.de/blog/2018/08/24/json-in-bequem/). ```bash curl ... |jq '{name: .results[].name}' ``` For programmatic examples in various languages, check the chapter [below](12-icinga2-api.md#icinga2-api-clients). > **Note** > > Future versions of Icinga 2 might set additional fields. Your application > should gracefully handle fields it is not familiar with, for example by > ignoring them. ### HTTP Statuses The API will return standard [HTTP statuses](https://www.ietf.org/rfc/rfc2616.txt) including error codes. When an error occurs, the response body will contain additional information about the problem and its source. Set `verbose` to true to retrieve more insights into what may be causing the error. A status code between 200 and 299 generally means that the request was successful. Return codes within the 400 range indicate that there was a problem with the request. Either you did not authenticate correctly, you are missing the authorization for your requested action, the requested object does not exist or the request was malformed. A status in the range of 500 generally means that there was a server-side problem and Icinga 2 is unable to process your request. ### Security * HTTPS only. * TLS v1.2+ is required. * TLS cipher lists are hardened [by default](09-object-types.md#objecttype-apilistener). * Authentication is [required](12-icinga2-api.md#icinga2-api-authentication). ### Authentication There are two different ways for authenticating against the Icinga 2 API: * Username and password using HTTP basic auth * X.509 client certificate In order to configure a new API user you'll need to add a new [ApiUser](09-object-types.md#objecttype-apiuser) configuration object. In this example `root` will be the basic auth username and the `password` attribute contains the basic auth password. ``` # vim /etc/icinga2/conf.d/api-users.conf object ApiUser "root" { password = "icinga" } ``` Alternatively you can use X.509 client certificates by specifying the `client_cn` the API should trust. The X.509 certificate has to be signed by the CA certificate that is configured in the [ApiListener](09-object-types.md#objecttype-apilistener) object. ``` # vim /etc/icinga2/conf.d/api-users.conf object ApiUser "root" { client_cn = "CertificateCommonName" } ``` An `ApiUser` object can have both authentication methods configured. #### Authentication Test You can test authentication by sending a GET request to the API: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1' ``` In case you get an error message make sure to check the API user credentials. When using client certificates for authentication you'll need to pass your client certificate and private key to the curl call: ```bash curl -k --cert example.localdomain.crt --key example.localdomain.key 'https://example.localdomain:5665/v1/status' ``` In case of an error make sure to verify the client certificate and CA. The curl parameter `-k` disables certificate verification and should therefore only be used for testing. In order to securely check each connection you'll need to specify the trusted CA certificate using the curl parameter`--cacert`: ```bash curl -u root:icinga --cacert ca.crt 'icinga2.node1.localdomain:5665/v1' ``` Read the next chapter on [API permissions](12-icinga2-api.md#icinga2-api-permissions) in order to configure authorization settings for your newly created API user. ### Permissions By default an API user does not have any permissions to perform actions on the URL endpoints. Permissions for API users must be specified in the `permissions` attribute as array. The array items can be a list of permission strings with wildcard matches. Please notice, that the permission system that is used by the API differs from the permission system used by the Icinga Web 2 frontend or other parts of Icinga 2. The permission system mainly relies on the url scheme of the API endpoints (See listing below). Example for an API user with all permissions: ``` permissions = [ "*" ] ``` Note that you can use wildcards to include all possible hierarchically lower items. Here's another example that only allows the user to perform read-only object queries for hosts and services: ``` permissions = [ "objects/query/Host", "objects/query/Service" ] ``` You can also further restrict permissions by specifying a filter expression. The filter expression has to be a [lambda function](17-language-reference.md#nullary-lambdas) which must return a boolean value. The following example allows the API user to query all hosts and services which have a custom variable `os` that matches the regular expression `^Linux`. The [regex function](18-library-reference.md#global-functions-regex) is available as global function. ``` permissions = [ { permission = "objects/query/Host" filter = {{ regex("^Linux", host.vars.os) }} }, { permission = "objects/query/Service" filter = {{ regex("^Linux", service.vars.os) }} } ] ``` More information about filters can be found in the [filters](12-icinga2-api.md#icinga2-api-filters) chapter. Prior to setting complex permissions, ensure to always [test](12-icinga2-api.md#icinga2-api-authentication-test) them step by step. #### Overview Permissions are tied to a maximum HTTP request size to prevent abuse, responses sent by Icinga are not limited. An API user with all permissions ("\*") may send up to 512 MB regardless of the endpoint. Available permissions for specific URL endpoints: Permissions | URL Endpoint | Supports filters | Max body size in MB ------------------------------|---------------|-------------------|--------------------- actions/<action> | /v1/actions | Yes | 1 config/query | /v1/config | No | 1 config/modify | /v1/config | No | 512 console | /v1/console | No | 1 debug | /v1/debug | No | 1 events/<type> | /v1/events | No | 1 objects/query/<type> | /v1/objects | Yes | 1 objects/create/<type> | /v1/objects | No | 1 objects/modify/<type> | /v1/objects | Yes | 1 objects/delete/<type> | /v1/objects | Yes | 1 status/query | /v1/status | Yes | 1 templates/<type> | /v1/templates | Yes | 1 types | /v1/types | Yes | 1 variables | /v1/variables | Yes | 1 The required actions or types can be replaced by using a wildcard match ("\*"). ### Parameters Depending on the request method there are two ways of passing parameters to the request: * JSON object as request body (all request methods other than `GET`) * Query string as URL parameter (all request methods) Reserved characters by the HTTP protocol must be [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding) as query string, e.g. a space character becomes `%20`. Example for a URL-encoded query string: ``` /v1/objects/hosts?filter=match(%22example.localdomain*%22,host.name)&attrs=name&attrs=state ``` Here are the exact same query parameters as a JSON object: ```json { "filter": "match(\"example.localdomain*\",host.name)", "attrs": [ "host.name", "host.state" ] } ``` The [match function](18-library-reference.md#global-functions-match) is available as global function in Icinga 2. Whenever filters and other URL parameters don't work due to encoding issues, consider passing them in the request body. For GET requests, this method is explained [here](12-icinga2-api.md#icinga2-api-requests-method-override). You can use [jo](https://github.com/jpmens/jo) to format JSON strings on the shell. An example for API actions shown [here](12-icinga2-api.md#icinga2-api-actions-unix-timestamps). ### Global Parameters Name | Description ----------------|-------------------- pretty | Pretty-print the JSON response. verbose | Add verbose debug information inside the `diagnostic_information` key into the response if available. This helps with troubleshooting failing requests. Example as URL parameter: ``` /v1/objects/hosts?pretty=1 ``` Example as JSON object: ```json { "pretty": true } ``` ### Request Method Override `GET` requests do not allow you to send a request body. In case you cannot pass everything as URL parameters (e.g. complex filters or JSON-encoded dictionaries) you can use the `X-HTTP-Method-Override` header. This comes in handy when you are using HTTP proxies disallowing `PUT` or `DELETE` requests too. Query an existing object by sending a `POST` request with `X-HTTP-Method-Override: GET` as request header: ```bash curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://localhost:5665/v1/objects/hosts' ``` Delete an existing object by sending a `POST` request with `X-HTTP-Method-Override: DELETE` as request header: ```bash curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: DELETE' -X POST \ 'https://localhost:5665/v1/objects/hosts/example.localdomain' ``` Query objects with complex filters. For a detailed introduction into filter, please read the [following chapter](12-icinga2-api.md#icinga2-api-filters). ```bash curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://localhost:5665/v1/objects/services' \ -d '{ "filter": "service.state==2 && match(\"ping*\",service.name)" }' ``` ### Filters #### Simple Filters By default actions and queries operate on all objects unless further restricted by the user. For example, the following query returns all `Host` objects: ``` https://localhost:5665/v1/objects/hosts ``` If you're only interested in a single object, you can limit the output to that object by specifying its name: ``` https://localhost:5665/v1/objects/hosts?host=localhost ``` **The name of the URL parameter is the lower-case version of the type the query applies to.** For example, for `Host` objects the URL parameter therefore is `host`, for `Service` objects it is `service` and so on. You can also specify multiple objects: ``` https://localhost:5665/v1/objects/hosts?hosts=first-host&hosts=second-host ``` Again -- like in the previous example -- the name of the URL parameter is the lower-case version of the type. However, because we're specifying multiple objects here the **plural form** of the type is used. When specifying names for objects which have composite names like for example services the full name has to be used: ``` https://localhost:5665/v1/objects/services?service=localhost!ping6 ``` The full name of an object can be obtained by looking at the `__name` attribute. #### Advanced Filters Most of the information provided in this chapter applies to both permission filters (as used when configuring `ApiUser` objects) and filters specified in queries. Advanced filters allow users to filter objects using lambda expressions. The syntax for these filters is the same like for [apply rule expressions](03-monitoring-basics.md#using-apply-expressions). The `filter` parameter can only be specified once, complex filters must be defined once in the provided string value. > **Note** > > Filters used as URL parameter must be URL-encoded. The following examples > are **not URL-encoded** for better readability. Example matching all services in NOT-OK state: ``` https://localhost:5665/v1/objects/services?filter=service.state!=ServiceOK ``` Example [matching](18-library-reference.md#global-functions-match) all hosts by a name string pattern: ``` https://localhost:5665/v1/objects/hosts?filter=match("example.localdomain*",host.name) ``` Example for all hosts which are in the host group `linux-servers`: ``` https://localhost:5665/v1/objects/hosts?filter="linux-servers" in host.groups ``` > **Tip** > > Best practice for filters is to use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) > for GET requests and always pass them in the request body. User-specified filters are run in a sandbox environment which ensures that filters cannot modify Icinga's state, for example object attributes or global variables. When querying objects of a specific type the filter expression is evaluated for each object of that type. The object is made available to the filter expression as a variable whose name is the lower-case version of the object's type name. For example when querying objects of type `Host` the variable in the filter expression is named `host`. Additionally related objects such as the host's check command are also made available (e.g., via the `check_command` variable). The variable names are the exact same as for the `joins` query parameter; see [object query joins](12-icinga2-api.md#icinga2-api-config-objects-query-joins) for details. The object is also made available via the `obj` variable. This makes it easier to build filters which can be used for more than one object type (e.g., for permissions). Some queries can be performed for more than just one object type. One example is the 'reschedule-check' action which can be used for both hosts and services. When using advanced filters you will also have to specify the type using the `type` parameter: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X POST \ 'https://localhost:5665/v1/actions/reschedule-check' \ -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "pretty": true }' ``` ##### Filter Variables Filter values need to be escaped in the same way as in the Icinga 2 DSL. The example below is not valid: ``` -d '{ "type": "Host", "filter": ""linux-servers" in host.groups" }' ``` The double quotes need to be escaped with a preceeding backslash: ``` -d '{ "type": "Host", "filter": "\"linux-servers\" in host.groups" }' ``` You can use the `filter_vars` attribute to avoid additional escaping. This follows the same principle as with parameter binding known from RDBMS. Specify a placeholder variable inside the `filter` string, and actually assign its value inside the `filter_vars` dictionary. That way you can also keep the `filter` string the same for different requests with only changing the `filter_vars`. ```bash curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://localhost:5665/v1/objects/hosts' \ -d '{ "filter": "group in host.groups", "filter_vars": { "group": "linux-servers" }, "pretty": true }' ``` We're using [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) here because the HTTP specification does not allow message bodies for GET requests. The `filters_vars` attribute can only be used inside the request body, but not as a URL parameter because there is no way to specify a dictionary in a URL. The example from [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) can be enhanced to avoid additional parameter value escaping. ```bash curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://localhost:5665/v1/objects/services' \ -d '{ "filter": "service.state==state && match(pattern,service.name)", "filter_vars": { "state": 2, "pattern": "ping*" } }' ``` ## Config Objects Provides methods to manage configuration objects: * [creating objects](12-icinga2-api.md#icinga2-api-config-objects-create) * [querying objects](12-icinga2-api.md#icinga2-api-config-objects-query) * [modifying objects](12-icinga2-api.md#icinga2-api-config-objects-modify) * [deleting objects](12-icinga2-api.md#icinga2-api-config-objects-delete) ### API Objects and Cluster Config Sync Newly created or updated objects can be synced throughout your Icinga 2 cluster. Set the `zone` attribute to the zone this object belongs to and let the API and cluster handle the rest. Objects without a zone attribute are only synced in the same zone the Icinga instance belongs to. > **Note** > > Cluster nodes must accept configuration for creating, modifying > and deleting objects. Ensure that `accept_config` is set to `true` > in the [ApiListener](09-object-types.md#objecttype-apilistener) object > on each node. If you add a new cluster instance, or reconnect an instance which has been offline for a while, Icinga 2 takes care of the initial object sync for all objects created by the API. ### Querying Objects You can request information about configuration objects by sending a `GET` query to the `/v1/objects/` URL endpoint. `` has to be replaced with the plural name of the object type you are interested in: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/objects/hosts' ``` A list of all available configuration types is available in the [object types](09-object-types.md#object-types) chapter. The following URL parameters are available: Parameters | Type | Description -----------|--------------|---------------------------- attrs | Array | **Optional.** Limited attribute list in the output. joins | Array | **Optional.** Join related object types and their attributes specified as list (`?joins=host` for the entire set, or selectively by `?joins=host.name`). meta | Array | **Optional.** Enable meta information using `?meta=used_by` (references from other objects) and/or `?meta=location` (location information) specified as list. Defaults to disabled. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) may be provided. Instead of using a filter you can optionally specify the object name in the URL path when querying a single object. For objects with composite names (e.g. services) the full name (e.g. `example.localdomain!http`) must be specified: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/objects/services/example.localdomain!http' ``` You can limit the output to specific attributes using the `attrs` URL parameter: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/objects/hosts/example.localdomain?attrs=name&attrs=address&pretty=1' ``` ```json { "results": [ { "attrs": { "name": "example.localdomain", "address": "192.168.1.1" }, "joins": {}, "meta": {}, "name": "example.localdomain", "type": "Host" } ] } ``` #### Object Queries Result Each response entry in the results array contains the following attributes: Attribute | Type | Description -----------|------------|-------------- name | String | Full object name. type | String | Object type. attrs | Dictionary | Object attributes (can be filtered using the URL parameter `attrs`). joins | Dictionary | [Joined object types](12-icinga2-api.md#icinga2-api-config-objects-query-joins) as key, attributes as nested dictionary. Disabled by default. meta | Dictionary | Contains `used_by` object references. Disabled by default, enable it using `?meta=used_by` as URL parameter. #### Object Query Joins Icinga 2 knows about object relations. For example it can optionally return information about the host when querying service objects. The following query retrieves all host attributes: ``` https://localhost:5665/v1/objects/services?joins=host ``` Instead of requesting all host attributes you can also limit the output to specific attributes: ``` https://localhost:5665/v1/objects/services?joins=host.name&joins=host.address ``` You can request that all available joins are returned in the result set by using the `all_joins` query parameter. ``` https://localhost:5665/v1/objects/services?all_joins=1 ``` > **Note** > > For performance reasons you should only request attributes which your application > requires. Please note that the object type refers to the URL endpoint with `/v1/objects/` where the following joins are available: Object Type | Object Relations (`joins` prefix name) -------------|------------------------------------------ Service | host, check\_command, check\_period, event\_command, command\_endpoint Host | check\_command, check\_period, event\_command, command\_endpoint Notification | host, service, command, period Dependency | child\_host, child\_service, parent\_host, parent\_service, period User | period Zones | parent Here's an example that retrieves all service objects for hosts which have had their `os` custom variable set to `Linux`. The result set contains the `display_name` and `check_command` attributes for the service. The query also returns the host's `name` and `address` attribute via a join: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/objects/services?attrs=display_name&attrs=check_command&joins=host.name&joins=host.address&filter=host.vars.os==%22Linux%22&pretty=1' ``` ```json { "results": [ { "attrs": { "check_command": "ping4", "display_name": "ping4" }, "joins": { "host": { "address": "192.168.1.1", "name": "example.localdomain" } }, "meta": {}, "name": "example.localdomain!ping4", "type": "Service" }, { "attrs": { "check_command": "ssh", "display_name": "ssh" }, "joins": { "host": { "address": "192.168.1.1", "name": "example.localdomain" } }, "meta": {}, "name": "example.localdomain!ssh", "type": "Service" } ] } ``` > **Tip** > > Use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) > and pass everything in the request body like this: ```bash curl -k -s -S -i -u 'root:icinga' -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://localhost:5665/v1/objects/services' \ -d '{ "attrs": [ "display_name", "check_command" ], "joins": [ "host.name", "host.address" ], "filter": "host.vars.os==\"Linux\"", "pretty": true }' ``` In case you want to fetch all [comments](09-object-types.md#objecttype-comment) for hosts and services, you can use the following query URL (similar example for downtimes): ``` https://localhost:5665/v1/objects/comments?joins=host&joins=service ``` This is another example for listing all service objects which are unhandled problems (state is not OK and no downtime or acknowledgement set). We're using [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) here because we want to pass all query attributes in the request body. ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://127.0.0.1:5665/v1/objects/services' \ -d '{ "joins": [ "host.name", "host.address" ], "attrs": [ "name", "state", "downtime_depth", "acknowledgement" ], "filter": "service.state != ServiceOK && service.downtime_depth == 0.0 && service.acknowledgement == 0.0", "pretty": true }' ``` ```json { "results": [ { "attrs": { "acknowledgement": 0.0, "downtime_depth": 0.0, "name": "10807-service", "state": 3.0 }, "joins": { "host": { "address": "", "name": "10807-host" } }, "meta": {}, "name": "10807-host!10807-service", "type": "Service" } ] } ``` In order to list all acknowledgements without expire time, you query the `/v1/objects/comments` URL endpoint with `joins` and `filter` request parameters using the [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) method: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://localhost:5665/v1/objects/comments' \ -d '{ "joins": [ "service.name", "service.acknowledgement", "service.acknowledgement_expiry" ], "attrs": [ "author", "text" ], "filter": "service.acknowledgement!=0 && service.acknowledgement_expiry==0", "pretty": true }' ``` ```json { "results": [ { "attrs": { "author": "icingaadmin", "text": "maintenance work" }, "joins": { "service": { "__name": "example.localdomain!disk /", "acknowledgement": 1.0, "acknowledgement_expiry": 0.0 } }, "meta": {}, "name": "example.localdomain!disk /!example.localdomain-1495457222-0", "type": "Comment" } ] } ``` ### Creating Config Objects New objects must be created by sending a PUT request. The following parameters need to be passed inside the JSON body: Parameters | Type | Description ------------------|--------------|-------------------------- templates | Array | **Optional.** Import existing configuration templates for this object type. Note: These templates must either be statically configured or provided in [config packages](12-icinga2-api.md#icinga2-api-config-management). attrs | Dictionary | **Required.** Set specific object attributes for this [object type](09-object-types.md#object-types). ignore\_on\_error | Boolean | **Optional.** Ignore object creation errors and return an HTTP 200 status instead. The object name must be specified as part of the URL path. For objects with composite names (e.g. services) the full name (e.g. `example.localdomain!http`) must be specified. If attributes are of the Dictionary type, you can also use the indexer format. This might be necessary to only override specific custom variables and keep all other existing custom variables (e.g. from templates): ``` "attrs": { "vars.os": "Linux" } ``` Example for creating the new host object `example.localdomain`: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \ -d '{ "templates": [ "generic-host" ], "attrs": { "address": "192.168.1.1", "check_command": "hostalive", "vars.os" : "Linux" }, "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Object was created." } ] } ``` If the configuration validation fails, the new object will not be created and the response body contains a detailed error message. The following example is missing the `check_command` attribute which is required for host objects: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \ -d '{ "attrs": { "address": "192.168.1.1", "vars.os" : "Linux" }, "pretty": true }' ``` ```json { "results": [ { "code": 500.0, "errors": [ "Error: Validation failed for object 'example.localdomain' of type 'Host'; Attribute 'check_command': Attribute must not be empty." ], "status": "Object could not be created." } ] } ``` Service objects must be created using their full name ("hostname!servicename") referencing an existing host object: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X PUT 'https://localhost:5665/v1/objects/services/example.localdomain!realtime-load' \ -d '{ "templates": [ "generic-service" ], "attrs": { "check_command": "load", "check_interval": 1,"retry_interval": 1 } }' ``` Example for a new CheckCommand object: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X PUT 'https://localhost:5665/v1/objects/checkcommands/mytest' \ -d '{ "templates": [ "plugin-check-command" ], "attrs": { "command": [ "/usr/local/sbin/check_http" ], "arguments": { "-I": "$mytest_iparam$" } } }' ``` ### Modifying Objects Existing objects must be modified by sending a `POST` request. The following parameters need to be passed inside the JSON body: | Parameters | Type | Description | |----------------|------------|----------------------------------------------------------------------------------------------------------------------------| | attrs | Dictionary | **Optional.** Set specific object attributes for this [object type](09-object-types.md#object-types). | | restore\_attrs | Array | **Optional.** Discard modifications of specific object attributes for this [object type](09-object-types.md#object-types). | One of the above is required. !!! info If a particular attribute is given in both sets, it's first restored and then set to the desired new value. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) parameter should be provided. > **Note**: > > Modified attributes do not trigger a re-evaluation of existing > static [apply rules](03-monitoring-basics.md#using-apply) and [group assignments](03-monitoring-basics.md#group-assign-intro). > Delete and re-create the objects if you require such changes or > consider funding [this feature request](https://github.com/Icinga/icinga2/issues/4084). > > Furthermore you cannot modify templates which have already been resolved > during [object creation](12-icinga2-api.md#icinga2-api-config-objects-create). > There are attributes which can only be set for [PUT requests](12-icinga2-api.md#icinga2-api-config-objects-create) such as `groups` > or `zone`. A complete list of `no_user_modify` attributes can be fetched from the [types](12-icinga2-api.md#icinga2-api-types) URL endpoint. If attributes are of the [Dictionary](17-language-reference.md#dictionary) type, you can also use the indexer format: ``` "attrs": { "vars.os": "Linux" } ``` The following example updates the `address` attribute and the custom variable `os` for the `example.localdomain` host: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/objects/hosts/example.localdomain' \ -d '{ "attrs": { "address": "192.168.1.2", "vars.os" : "Windows" }, "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "name": "example.localdomain", "status": "Attributes updated.", "type": "Host" } ] } ``` To undo such modifications to specific object attributes, list the latter in the `restore_attrs` parameter. E.g.: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/objects/hosts/example.localdomain' \ -d '{ "restore_attrs": [ "address", "vars.os" ], "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "name": "example.localdomain", "status": "Attributes updated.", "type": "Host" } ] } ``` Giving `attrs` with the original value would have almost the same effect. But in this case Icinga would still store that value as a modified attribute, overriding DSL/Director config (changes). In contrast, `restore_attrs` tells Icinga to actually forget particular modified attributes, so that changes to them via Director or plain config are effective again. ### Deleting Objects You can delete objects created using the API by sending a `DELETE` request. Parameters | Type | Description -----------|---------|--------------- cascade | Boolean | **Optional.** Delete objects depending on the deleted objects (e.g. services on a host). In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) should be provided. Example for deleting the host object `example.localdomain`: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X DELETE 'https://localhost:5665/v1/objects/hosts/example.localdomain?cascade=1&pretty=1' ``` ```json { "results": [ { "code": 200.0, "name": "example.localdomain", "status": "Object was deleted.", "type": "Host" } ] } ``` ## Actions There are several actions available for Icinga 2 provided by the `/v1/actions` URL endpoint. You can run actions by sending a `POST` request. The following actions are also used by [Icinga Web 2](https://icinga.com/docs/icinga-web/latest/): * sending check results to Icinga from scripts, remote agents, etc. * scheduling downtimes from external scripts or cronjobs * acknowledging problems * adding comments All actions return a 200 `OK` or an appropriate error code for each action performed on each object matching the supplied filter. Actions which affect the Icinga Application itself such as disabling notification on a program-wide basis must be applied by updating the [IcingaApplication object](12-icinga2-api.md#icinga2-api-config-objects) called `app`. ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/objects/icingaapplications/app' \ -d '{ "attrs": { "enable_notifications": false } }' ``` ### Unix Timestamp Handling If you don't want to write JSON manually, especially for adding the `start_time` and `end_time` parameters, you can use [jo](https://github.com/jpmens/jo) to format this. ```bash jo -p pretty=true type=Service filter="service.name==\"ping4\"" author=icingaadmin comment="IPv4 network maintenance" fixed=true start_time=$(date +%s -d "+0 hour") end_time=$(date +%s -d "+1 hour") ``` ```json { "pretty": true, "type": "Service", "filter": "service.name==\"ping4\"", "author": "icingaadmin", "comment": "IPv4 network maintenance", "fixed": true, "start_time": 1557414097, "end_time": 1557417697 } ``` Now wrap this into the actual curl command: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/schedule-downtime' \ -d "$(jo -p pretty=true type=Service filter="service.name==\"ping4\"" author=icingaadmin comment="IPv4 network maintanence" fixed=true start_time=$(date +%s -d "+0 hour") end_time=$(date +%s -d "+1 hour"))" ``` Note: This requires GNU date. On macOS, install `coreutils` from Homebrew and use `gdate`. ### process-check-result Process a check result for a host or a service. Send a `POST` request to the URL endpoint `/v1/actions/process-check-result`. Parameter | Type | Description ------------------ | -------------- | -------------- exit\_status | Number | **Required.** For services: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN, for hosts: 0=UP, 1=DOWN. plugin\_output | String | **Required.** One or more lines of the plugin main output. Does **not** contain the performance data. performance\_data | Array|String | **Optional.** The performance data as array of strings. The raw performance data string can be used too. check\_command | Array|String | **Optional.** The first entry should be the check commands path, then one entry for each command line option followed by an entry for each of its argument. Alternativly a single string can be used. check\_source | String | **Optional.** Usually the name of the `command_endpoint` execution\_start | Timestamp | **Optional.** The timestamp where a script/process started its execution. execution\_end | Timestamp | **Optional.** The timestamp where a script/process ended its execution. This timestamp is used in features to determine e.g. the metric timestamp. ttl | Number | **Optional.** Time-to-live duration in seconds for this check result. The next expected check result is `now + ttl` where freshness checks are executed. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. Example for the service `passive-ping`: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/process-check-result' \ -d '{ "type": "Service", "filter": "host.name==\"icinga2-master1.localdomain\" && service.name==\"passive-ping\"", "exit_status": 2, "plugin_output": "PING CRITICAL - Packet loss = 100%", "performance_data": [ "rta=5000.000000ms;3000.000000;5000.000000;0.000000", "pl=100%;80;100;0" ], "check_source": "example.localdomain", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully processed check result for object 'icinga2-master1.localdomain!passive-ping'." } ] } ``` You can avoid URL encoding of white spaces in object names by using the `filter` attribute in the request body. Example for using the `Host` type and filter by the host name: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/process-check-result' \ -d '{ "filter": "host.name==\"example.localdomain\"", "type": "Host", "exit_status": 1, "plugin_output": "Host is not available." }' ``` > **Note** > > Multi-line plugin output requires the following format: The first line is treated as `short` plugin output corresponding > to the first line of the plugin output. Subsequent lines are treated as `long` plugin output. Please note that the > performance data is separated from the plugin output and has to be passed as `performance_data` attribute. ### reschedule-check Reschedule a check for hosts and services. The check can be forced if required. Send a `POST` request to the URL endpoint `/v1/actions/reschedule-check`. Parameter | Type | Description -------------|-----------|-------------- next\_check | Timestamp | **Optional.** The next check will be run at this time. If omitted, the current time is used. force | Boolean | **Optional.** Defaults to `false`. If enabled, the checks are executed regardless of time period restrictions and checks being disabled per object or on a global basis. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. The example reschedules all services with the name "ping6" to immediately perform a check (`next_check` default), ignoring any time periods or whether active checks are allowed for the service (`force=true`). ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/reschedule-check' \ -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "force": true, "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully rescheduled check for object 'icinga2-master1.localdomain!ping6'." } ] } ``` ### send-custom-notification Send a custom notification for hosts and services. This notification type can be forced being sent to all users. Send a `POST` request to the URL endpoint `/v1/actions/send-custom-notification`. Parameter | Type | Description ----------|---------|-------------- author | String | **Required.** Name of the author, may be empty. comment | String | **Required.** Comment text, may be empty. force | Boolean | **Optional.** Default: false. If true, the notification is sent regardless of downtimes or whether notifications are enabled or not. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. Example for a custom host notification announcing a global maintenance to host owners: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/send-custom-notification' \ -d '{ "type": "Host", "author": "icingaadmin", "comment": "System is going down for maintenance", "force": true, "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully sent custom notification for object 'host0'." }, { "code": 200.0, "status": "Successfully sent custom notification for object 'host1'." } ] } ``` ### delay-notification Delay notifications for a host or a service. Note that this will only have an effect if the service stays in the same problem state that it is currently in. If the service changes to another state, a new notification may go out before the time you specify in the `timestamp` argument. Send a `POST` request to the URL endpoint `/v1/actions/delay-notification`. Parameter | Type | Description ----------|-----------|-------------- timestamp | Timestamp | **Required.** Delay notifications until this timestamp. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. Example: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/delay-notification' \ -d '{ "type": "Service", "timestamp": 1446389894, "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully delayed notifications for object 'host0!service0'." }, { "code": 200.0, "status": "Successfully delayed notifications for object 'host1!service1'." } ] } ``` ### acknowledge-problem Allows you to acknowledge the current problem for hosts or services. By acknowledging the current problem, future notifications (for the same state if `sticky` is set to `false`) are disabled. Send a `POST` request to the URL endpoint `/v1/actions/acknowledge-problem`. Parameter | Type | Description ---------------------|-----------|-------------- author | String | **Required.** Name of the author, may be empty. comment | String | **Required.** Comment text, may be empty. expiry | Timestamp | **Optional.** Whether the acknowledgement will be removed at the timestamp. sticky | Boolean | **Optional.** Whether the acknowledgement will be set until the service or host fully recovers. Defaults to `false`. notify | Boolean | **Optional.** Whether a notification of the `Acknowledgement` type will be sent. Defaults to `false`. persistent | Boolean | **Optional.** When the comment is of type `Acknowledgement` and this is set to `true`, the comment will remain after the acknowledgement recovers or expires. Defaults to `false`. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. The following example acknowledges all services which are in a hard critical state and sends out a notification for them: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/acknowledge-problem' \ -d '{ "type": "Service", "filter": "service.state==2 && service.state_type==1", "author": "icingaadmin", "comment": "Global outage. Working on it.", "notify": true, "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully acknowledged problem for object 'icinga2-satellite1.localdomain!ping4'." }, { "code": 200.0, "status": "Successfully acknowledged problem for object 'icinga2-satellite2.localdomain!ping4'." } ] } ``` ### remove-acknowledgement Removes the acknowledgements for services or hosts. Once the acknowledgement has been removed the next notification will be sent again. Send a `POST` request to the URL endpoint `/v1/actions/remove-acknowledgement`. Parameter | Type | Description ----------|--------|-------------- author | String | **Optional.** Name of the removal requestor. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. The example removes all service acknowledgements: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/remove-acknowledgement' \ -d '{ "type": "Service", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully removed acknowledgement for object 'host0!service0'." }, { "code": 200.0, "status": "Successfully removed acknowledgement for object 'example2.localdomain!aws-health'." } ] } ``` ### add-comment Adds a `comment` from an `author` to services or hosts. Send a `POST` request to the URL endpoint `/v1/actions/add-comment`. Parameter | Type | Description ----------|-----------|-------------- author | string | **Required.** Name of the author, may be empty. comment | string | **Required.** Comment text, may be empty. expiry | Timestamp | **Optional.** Comment expiry time. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. The following example adds a comment for all `ping4` services: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/add-comment' \ -d '{ "type": "Service", "filter": "service.name==\"ping4\"", "author": "icingaadmin", "comment": "Troubleticket #123456789 opened.", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "legacy_id": 26.0, "name": "icinga2-satellite1.localdomain!ping4!7e7861c8-8008-4e8d-9910-2a0bb26921bd", "status": "Successfully added comment 'icinga2-satellite1.localdomain!ping4!7e7861c8-8008-4e8d-9910-2a0bb26921bd' for object 'icinga2-satellite1.localdomain!ping4'." }, { "code": 200.0, "legacy_id": 27.0, "name": "icinga2-satellite2.localdomain!ping4!9a4c43f5-9407-a536-18bf-4a6cc4b73a9f", "status": "Successfully added comment 'icinga2-satellite2.localdomain!ping4!9a4c43f5-9407-a536-18bf-4a6cc4b73a9f' for object 'icinga2-satellite2.localdomain!ping4'." } ] } ``` ### remove-comment Remove the comment using its `name` attribute , returns `OK` if the comment did not exist. **Note**: This is **not** the legacy ID but the comment name returned by Icinga 2 when [adding a comment](12-icinga2-api.md#icinga2-api-actions-add-comment). Send a `POST` request to the URL endpoint `/v1/actions/remove-comment`. Parameter | Type | Description ----------|--------|-------------- author | String | **Optional.** Name of the removal requestor. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Comment`. Example for a simple filter using the `comment` URL parameter: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/remove-comment' \ -d '{ "comment": "icinga2-satellite2.localdomain!ping4!9a4c43f5-9407-a536-18bf-4a6cc4b73a9f", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully removed comment 'icinga2-satellite2.localdomain!ping4!9a4c43f5-9407-a536-18bf-4a6cc4b73a9f'." } ] } ``` Example for removing all service comments using a service name filter for `ping4`: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/remove-comment' -d '{ "type": "Service", "filter": "service.name==\"ping4\"", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully removed all comments for object 'icinga2-satellite1.localdomain!ping4'." }, { "code": 200.0, "status": "Successfully removed all comments for object 'icinga2-satellite2.localdomain!ping4'." } ] } ``` ### schedule-downtime Schedule a downtime for hosts and services. Send a `POST` request to the URL endpoint `/v1/actions/schedule-downtime`. Parameter | Type | Description --------------|-----------|-------------- author | String | **Required.** Name of the author. comment | String | **Required.** Comment text. start\_time | Timestamp | **Required.** Timestamp marking the beginning of the downtime. end\_time | Timestamp | **Required.** Timestamp marking the end of the downtime. fixed | Boolean | **Optional.** Defaults to `true`. If true, the downtime is `fixed` otherwise `flexible`. See [downtimes](08-advanced-topics.md#downtimes) for more information. duration | Number | **Required for flexible downtimes.** Duration of the downtime in seconds if `fixed` is set to false. all\_services | Boolean | **Optional for host downtimes.** Sets downtime for [all services](12-icinga2-api.md#icinga2-api-actions-schedule-downtime-host-all-services) for the matched host objects. If `child_options` are set, all child hosts and their services will schedule a downtime too. Defaults to `false`. trigger\_name | String | **Optional.** Sets the trigger for a triggered downtime. See [downtimes](08-advanced-topics.md#downtimes) for more information on triggered downtimes. child\_options| String | **Optional.** Schedule child downtimes. `DowntimeNoChildren` does not do anything, `DowntimeTriggeredChildren` schedules child downtimes triggered by this downtime, `DowntimeNonTriggeredChildren` schedules non-triggered downtimes. Defaults to `DowntimeNoChildren`. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`. Example for scheduling a downtime for all `ping4` services: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/schedule-downtime' \ -d '{ "type": "Service", "filter": "service.name==\"ping4\"", "start_time": 1446388806, "end_time": 1446389806, "author": "icingaadmin", "comment": "IPv4 network maintenance", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "legacy_id": 2.0, "name": "icinga2-satellite1.localdomain!ping4!ecc5fa55-a5b8-4189-a013-a5d4bb47af34", "status": "Successfully scheduled downtime 'icinga2-satellite1.localdomain!ping4!ecc5fa55-a5b8-4189-a013-a5d4bb47af34' for object 'icinga2-satellite1.localdomain!ping4'." }, { "code": 200.0, "legacy_id": 3.0, "name": "icinga2-satellite2.localdomain!ping4!abc59032-4589-abcd-4567-ecf67856c347", "status": "Successfully scheduled downtime 'icinga2-satellite2.localdomain!ping4!abc59032-4589-abcd-4567-ecf67856c347' for object 'icinga2-satellite2.localdomain!ping4'." } ] } ``` In case you want to target just a single service on a host, modify the filter like this: ``` "filter": "host.name==\"icinga2-satellite1.localdomain\" && service.name==\"ping4\"" ``` #### Schedule Host Downtime(s) with all Services Schedule a downtime for one (or multiple) hosts and all of their services. Note the `all_services` attribute. ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/schedule-downtime' \ -d "$(jo -p pretty=true type=Host filter="match(\"*satellite*\", host.name)" all_services=true author=icingaadmin comment="Cluster upgrade maintenance" fixed=true start_time=$(date +%s -d "+0 hour") end_time=$(date +%s -d "+1 hour"))" ``` ### remove-downtime Remove the downtime using its `name` attribute , returns `OK` if the downtime did not exist. **Note**: This is **not** the legacy ID but the downtime name returned by Icinga 2 when [scheduling a downtime](12-icinga2-api.md#icinga2-api-actions-schedule-downtime). Send a `POST` request to the URL endpoint `/v1/actions/remove-downtime`. Parameter | Type | Description ----------|--------|-------------- author | String | **Optional.** Name of the removal requestor. In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Downtime`. When removing a host downtime, service downtimes on this host are automatically deleted if they were created using the `all_services` option. Other downtimes created using the `child_options` option are not affected. Example for a simple filter using the `downtime` URL parameter: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/remove-downtime' \ -d '{ "downtime": "icinga2-satellite2.localdomain!ping4!abc59032-4589-abcd-4567-ecf67856c347", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully removed downtime 'icinga2-satellite2.localdomain!ping4!abc59032-4589-abcd-4567-ecf67856c347'." } ] } ``` Example for removing all host downtimes using a host name filter for `icinga2-satellite2.localdomain`: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/remove-downtime' \ -d '{ "type": "Host", "filter": "host.name==\"icinga2-satellite2.localdomain\"", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully removed all downtimes for object 'icinga2-satellite2.localdomain'." } ] } ``` Example for removing a downtime from a host but not the services filtered by the author name. This example uses filter variables explained in the [advanced filters](12-icinga2-api.md#icinga2-api-advanced-filters) chapter. ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/remove-downtime' \ -d $'{ "type": "Downtime", "filter": "host.name == filterHost && !service && downtime.author == filterAuthor", "filter_vars": { "filterHost": "icinga2-satellite1.localdomain", "filterAuthor": "icingaadmin" }, "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Successfully removed downtime 'icinga2-satellite1.localdomain!ecc5fa55-a5b8-ef34-abcd-a5d41234af34'." } ] } ``` ### shutdown-process Shuts down Icinga. May or may not return. Send a `POST` request to the URL endpoint `/v1/actions/shutdown-process`. This action does not support a target type or filter. Example: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/shutdown-process?pretty=1' ``` ```json { "results": [ { "code": 200.0, "status": "Shutting down Icinga 2." } ] } ``` ### restart-process Restarts Icinga. May or may not return. Send a `POST` request to the URL endpoint `/v1/actions/restart-process`. This action does not support a target type or filter. Example: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/restart-process?pretty=1' ``` ```json { "results": [ { "code": 200.0, "status": "Restarting Icinga 2." } ] } ``` ### generate-ticket Generates a PKI ticket for [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing). This can be used in combination with satellite/client setups requesting this ticket number. > **Note** > > This must be used on the local host, or e.g. by a Puppet master. > Doing so remotely may result in security issues with cluster > trust relationships. Send a `POST` request to the URL endpoint `/v1/actions/generate-ticket`. Parameter | Type | Description --------------|-----------|-------------- cn | String | **Required.** The host's common name for which the ticket should be generated. Example: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/generate-ticket' \ -d '{ "cn": "icinga2-agent1.localdomain", "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Generated PKI ticket '4f75d2ecd253575fe9180938ebff7cbca262f96e' for common name 'icinga2-agent1.localdomain'.", "ticket": "4f75d2ecd253575fe9180938ebff7cbca262f96e" } ] } ``` ### execute-command Executes a particular check/notification/event-command on a particular endpoint in the context of a particular checkable. Example use cases: * Test a check command without actually triggering notifications * Reboot a node via an event command * Test a notification command without actually reproducing the notification reason Send a `POST` request to the URL endpoint `/v1/actions/execute-command`. Parameter | Type | Description --------------|------------|-------------- ttl | Number | **Required.** The time to live of the execution expressed in seconds. command_type | String | **Optional.** The command type: `CheckCommand` or `EventCommand` or `NotificationCommand`. Default: `EventCommand` command | String | **Optional.** The command to execute. Its type must the same as `command_type`. It can be a macro string. Default: depending on the `command_type` it's either `$check_command$`, `$event_command$` or `$notification_command$` endpoint | String | **Optional.** The endpoint to execute the command on. It can be a macro string. Default: `$command_endpoint$`. macros | Dictionary | **Optional.** Macro overrides. Default: `{}` user | String | **Optional.** The user used for the notification command. notification | String | **Optional.** The notification used for the notification command. Example: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/actions/execute-command' \ -d '{"type": "Service", "service": "agent!custom_service", "ttl": 15, "macros": { "command_endpoint": "master", "ls_dir": "/tmp/foo" }, "command": "custom_command", "command_type": "CheckCommand" }' ``` ```json { "results": [ { "checkable": "agent!custom_service", "code": 202.0, "execution": "3541d906-9afe-4c0e-ae6d-f549ee9bb3e7", "status": "Accepted" } ] } ``` You may poll the state of the execution by [querying](#icinga2-api-config-objects-query) the checkable's attribute `executions`. ## Event Streams Event streams can be used to receive check results, downtimes, comments, acknowledgements, etc. as a "live stream" from Icinga. You can for example forward these types into your own backend. Process the metrics and correlate them with notifications and state changes e.g. in Elasticsearch with the help of [Icingabeat](https://icinga.com/docs/icingabeat/latest/). Another use case are aligned events and creating/resolving tickets automatically in your ticket system. You can subscribe to event streams by sending a `POST` request to the URL endpoint `/v1/events`. The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body): Parameter | Type | Description -----------|--------------|------------- types | Array | **Required.** Event type(s). Multiple types as URL parameters are supported. queue | String | **Required.** Unique queue name. Multiple HTTP clients can use the same queue as long as they use the same event types and filter. filter | String | **Optional.** Filter for specific event attributes using [filter expressions](12-icinga2-api.md#icinga2-api-filters). ### Event Stream Types The following event stream types are available: Type | Description -----------------------|-------------- CheckResult | Check results for hosts and services. StateChange | Host/service state changes. Notification | Notification events including notified users for hosts and services. AcknowledgementSet | Acknowledgement set on hosts and services. AcknowledgementCleared | Acknowledgement cleared on hosts and services. CommentAdded | Comment added for hosts and services. CommentRemoved | Comment removed for hosts and services. DowntimeAdded | Downtime added for hosts and services. DowntimeRemoved | Downtime removed for hosts and services. DowntimeStarted | Downtime started for hosts and services. DowntimeTriggered | Downtime triggered for hosts and services. ObjectCreated | Object created for all Icinga 2 objects. ObjectDeleted | Object deleted for all Icinga 2 objects. ObjectModified | Object modified for all Icinga 2 objects. Note: Each type requires [API permissions](12-icinga2-api.md#icinga2-api-permissions) being set. Example for all downtime events: ``` &types=DowntimeAdded&types=DowntimeRemoved&types=DowntimeTriggered -d '{ "types": ["DowntimeAdded", "DowntimeRemoved", "DowntimeTriggered"] }' ``` Example for all object events: ``` &types=ObjectCreated&types=ObjectDeleted&types=ObjectModified -d '{ "types": ["ObjectCreated", "ObjectDeleted", "ObjectModified"] }' ``` #### Event Stream Type: CheckResult Name | Type | Description -----------------|---------------|-------------------------- type | String | Event type `CheckResult`. timestamp | Timestamp | Unix timestamp when the event happened. host | String | [Host](09-object-types.md#objecttype-host) name. service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host check result. check\_result | CheckResult | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type. downtime\_depth | Number | Amount of active downtimes on the checkable. acknowledgement | Boolean | Whether the object is acknowledged. #### Event Stream Type: StateChange Name | Type | Description -----------------|---------------|-------------------------- type | String | Event type `StateChange`. timestamp | Timestamp | Unix timestamp when the event happened. host | String | [Host](09-object-types.md#objecttype-host) name. service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host state change. state | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state. state\_type | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type. check\_result | CheckResult | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type. downtime\_depth | Number | Amount of active downtimes on the checkable. acknowledgement | Boolean | Whether the object is acknowledged. #### Event Stream Type: Notification Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `Notification`. timestamp | Timestamp | Unix timestamp when the event happened. host | String | [Host](09-object-types.md#objecttype-host) name. service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host notification. command | String | [NotificationCommand](09-object-types.md#objecttype-notificationcommand) name. users | Array | List of notified [user](09-object-types.md#objecttype-user) names. notification\_type | String | [$notification.type$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value. author | String | [$notification.author$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value. text | String | [$notification.comment$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value. check\_result | CheckResult | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type. #### Event Stream Type: Flapping Name | Type | Description ------------------|---------------|-------------------------- type | String | Event type `Flapping`. timestamp | Timestamp | Unix timestamp when the event happened. host | String | [Host](09-object-types.md#objecttype-host) name. service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host flapping event. state | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state. state\_type | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type. is\_flapping | Boolean | Whether this object is flapping. current\_flapping | Number | Current flapping value in percent (added in 2.8). threshold\_low | Number | Low threshold in percent (added in 2.8). threshold\_high | Number | High threshold in percent (added in 2.8). #### Event Stream Type: AcknowledgementSet Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `AcknowledgementSet`. timestamp | Timestamp | Unix timestamp when the event happened. host | String | [Host](09-object-types.md#objecttype-host) name. service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host acknowledgement. state | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state. state\_type | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type. author | String | Acknowledgement author set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action. comment | String | Acknowledgement comment set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action. acknowledgement\_type | Number | 0 = None, 1 = Normal, 2 = Sticky. `sticky` can be set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action. notify | Boolean | Notifications were enabled via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action. expiry | Timestamp | Acknowledgement expire time set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action. #### Event Stream Type: AcknowledgementCleared Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `AcknowledgementCleared`. timestamp | Timestamp | Unix timestamp when the event happened. host | String | [Host](09-object-types.md#objecttype-host) name. service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host acknowledgement. state | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state. state\_type | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type. #### Event Stream Type: CommentAdded Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `CommentAdded`. timestamp | Timestamp | Unix timestamp when the event happened. comment | Dictionary | Serialized [Comment](09-object-types.md#objecttype-comment) object. #### Event Stream Type: CommentRemoved Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `CommentRemoved`. timestamp | Timestamp | Unix timestamp when the event happened. comment | Dictionary | Serialized [Comment](09-object-types.md#objecttype-comment) object. #### Event Stream Type: DowntimeAdded Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `DowntimeAdded`. timestamp | Timestamp | Unix timestamp when the event happened. downtime | Dictionary | Serialized [Downtime](09-object-types.md#objecttype-downtime) object. #### Event Stream Type: DowntimeRemoved Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `DowntimeRemoved`. timestamp | Timestamp | Unix timestamp when the event happened. downtime | Dictionary | Serialized [Downtime](09-object-types.md#objecttype-downtime) object. #### Event Stream Type: DowntimeStarted Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `DowntimeStarted`. timestamp | Timestamp | Unix timestamp when the event happened. downtime | Dictionary | Serialized [Downtime](09-object-types.md#objecttype-downtime) object. #### Event Stream Type: DowntimeTriggered Name | Type | Description --------------|---------------|-------------------------- type | String | Event type `DowntimeTriggered`. timestamp | Timestamp | Unix timestamp when the event happened. downtime | Dictionary | Serialized [Downtime](09-object-types.md#objecttype-downtime) object. #### Event Stream Type: ObjectCreated | Name | Type | Description | |--------------|-----------|----------------------------------------------------------------| | type | String | Event type `ObjectCreated`. | | timestamp | Timestamp | Unix timestamp when the event happened. | | object\_type | String | Type of the newly created object, such as `Host` or `Service`. | | object\_name | String | The full name of the object. | #### Event Stream Type: ObjectModified | Name | Type | Description | |--------------|-----------|-----------------------------------------------------------| | type | String | Event type `ObjectModified`. | | timestamp | Timestamp | Unix timestamp when the event happened. | | object\_type | String | Type of the modified object, such as `Host` or `Service`. | | object\_name | String | The full name of the object. | #### Event Stream Type: ObjectDeleted | Name | Type | Description | |--------------|-----------|----------------------------------------------------------| | type | String | Event type `ObjectDeleted`. | | timestamp | Timestamp | Unix timestamp when the event happened. | | object\_type | String | Type of the deleted object, such as `Host` or `Service`. | | object\_name | String | The full name of the object. | ### Event Stream Filter Event streams can be filtered by attributes using the prefix `event.`. Example for the `CheckResult` type with the `exit_code` set to `2`: ``` &types=CheckResult&filter=event.check_result.exit_status==2 -d '{ "types": [ "CheckResult" ], "filter": "event.check_result.exit_status==2" }' ``` Example for the `CheckResult` type with the service [matching](18-library-reference.md#global-functions-match) the string pattern "random\*": ``` &types=CheckResult&filter=match%28%22random*%22,event.service%29 -d { "types": [ "CheckResult" ], "filter": "match(\"random*\", event.service)" } ``` ### Event Stream Response The event stream response is separated with new lines. The HTTP client must support long-polling and HTTP/1.1. HTTP/1.0 is not supported. Example: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/events' \ -d '{ "queue": "myqueue", "types": [ "CheckResult" ], "filter": "event.check_result.exit_status==2" }' ``` ``` {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421319.7226390839,"type":"CheckResult"} {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421324.7226390839,"type":"CheckResult"} {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421329.7226390839,"type":"CheckResult"} ``` ## Status and Statistics Send a `GET` request to the URL endpoint `/v1/status` to retrieve status information and statistics for Icinga 2. Example: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/status?pretty=1' ``` ``` { "results": [ { "name": "ApiListener", "perfdata": [ ... ], "status": [ ... ] }, ... { "name": "IcingaAplication", "perfdata": [ ... ], "status": [ ... ] }, ... ] } ``` You can limit the output by specifying a status type in the URL, e.g. `IcingaApplication`: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/status/IcingaApplication?pretty=1' ``` ```json { "results": [ { "perfdata": [], "status": { "icingaapplication": { "app": { "enable_event_handlers": true, "enable_flapping": true, "enable_host_checks": true, "enable_notifications": true, "enable_perfdata": true, "enable_service_checks": true, "node_name": "example.localdomain", "pid": 59819.0, "program_start": 1443019345.093372, "version": "v2.3.0-573-g380a131" } } } } ] } ``` ## Configuration Management The main idea behind configuration management is that external applications can create configuration packages and stages based on configuration files and directory trees. This replaces any additional SSH connection and whatnot to dump configuration files to Icinga 2 directly. In case you are pushing a new configuration stage to a package, Icinga 2 will validate the configuration asynchronously and populate a status log which can be fetched in a separated request. Once the validation succeeds, a reload is triggered by default. This functionality was primarly developed for the [Icinga Director](https://icinga.com/docs/director/latest/) but can be used with your own deployments too. It also solves the problem with certain runtime objects (zones, endpoints) and can be used to deploy global templates in [global cluster zones](06-distributed-monitoring.md#distributed-monitoring-global-zone-config-sync). ### Create a Config Package Send a `POST` request to a new config package called `example-cmdb` in this example. This creates a new empty configuration package. ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/config/packages/example-cmdb?pretty=1' ``` ```json { "results": [ { "code": 200.0, "package": "example-cmdb", "status": "Created package." } ] } ``` Package names with the `_` prefix are reserved for internal packages and must not be used. You can recognize `_api`, `_etc` and `_cluster` when querying specific objects and packages. Each configuration object stores the package source in the `package` attribute. ### Create a Stage: Upload Configuration Configuration files in packages are managed in stages. Stages provide a way to maintain multiple configuration versions for a package. Once a new stage is deployed, the content is validated and set as active stage on success. On failure, the older stage remains active, and the caller can fetch the `startup.log` from this stage deployment attempt to see what exactly failed. You can see that in the Director's deployment log. Send a `POST` request to the URL endpoint `/v1/config/stages` and add the name of an existing configuration package to the URL path (e.g. `example-cmdb`). The request body must contain the `files` attribute with the value being a dictionary of file targets and their content. Optional attributes include `reload` (defaults to `true`) and `activate` (defaults to `true`). The `reload` attribute will tell icinga2 to reload after stage config validation. The `activate` attribute will tell icinga2 to activate the stage if it validates. If `activate` is set to `false`, `reload` must also be `false`. The file path requires one of these two directories inside its path: Directory | Description ------------|------------------------------------ conf.d | Local configuration directory. zones.d | Configuration directory for cluster zones, each zone must be put into its own zone directory underneath. Supports the [cluster config sync](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync). Example for a local configuration in the `conf.d` directory: ``` "files": { "conf.d/host1.conf": "object Host \"local-host\" { address = \"127.0.0.1\", check_command = \"hostalive\" }" } ``` Example for a host configuration inside the `satellite` zone in the `zones.d` directory: ``` "files": { "zones.d/satellite/host2.conf": "object Host \"satellite-host\" { address = \"192.168.1.100\", check_command = \"hostalive\" }" } ``` The example below will create a new file called `test.conf` in the `conf.d` directory. Note: This example contains an error (`chec_command`). This is intentional. ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X POST \ -d '{ "files": { "conf.d/test.conf": "object Host \"cmdb-host\" { chec_command = \"dummy\" }" }, "pretty": true }' \ 'https://localhost:5665/v1/config/stages/example-cmdb' ``` ```json { "results": [ { "code": 200.0, "package": "example-cmdb", "stage": "7e7861c8-8008-4e8d-9910-2a0bb26921bd", "status": "Created stage. Reload triggered." } ] } ``` The Icinga 2 API returns the `package` name this stage was created for, and also generates a unique name for the `stage` attribute you'll need for later requests. Icinga 2 automatically restarts the daemon in order to activate the new config stage. This can be disabled by setting `reload` to `false` in the request. If the validation for the new config stage failed, the old stage and its configuration objects will remain active. Activation may be inhibited even for stages that validate correctly by setting `activate` to `false`. This may be useful for validating the contents of a stage without making it active, for example in a CI (continuous integration) system. > **Note** > > Old stages are not purged automatically. You can [remove stages](12-icinga2-api.md#icinga2-api-config-management-delete-config-stage) that are no longer in use. Icinga 2 creates the following files in the configuration package stage after configuration validation: File | Description ------------|-------------- status | Contains the [configuration validation](11-cli-commands.md#config-validation) exit code (everything else than 0 indicates an error). startup.log | Contains the [configuration validation](11-cli-commands.md#config-validation) output. You can [fetch these files](12-icinga2-api.md#icinga2-api-config-management-fetch-config-package-stage-files) in order to verify that the new configuration was deployed successfully. Please follow the chapter below to learn more about this. ### List Configuration Packages and their Stages A list of packages and their stages can be retrieved by sending a `GET` request to the URL endpoint `/v1/config/packages`. The following example contains one configuration package `example-cmdb`. The package does not currently have an active stage. ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/config/packages?pretty=1' ``` ```json { "results": [ { "active-stage": "", "name": "example-cmdb", "stages": [ "7e7861c8-8008-4e8d-9910-2a0bb26921bd" ] } ] } ``` ### List Configuration Package Stage Files In order to retrieve a list of files for a stage you can send a `GET` request to the URL endpoint `/v1/config/stages`. You need to include the package name (`example-cmdb`) and stage name (`7e7861c8-8008-4e8d-9910-2a0bb26921bd`) in the URL: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/config/stages/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd?pretty=1' ``` ``` { "results": [ ... { "name": "startup.log", "type": "file" }, { "name": "status", "type": "file" }, { "name": "conf.d", "type": "directory" }, { "name": "zones.d", "type": "directory" }, { "name": "conf.d/test.conf", "type": "file" } ] } ``` ### Fetch Configuration Package Stage Files Send a `GET` request to the URL endpoint `/v1/config/files` and add the package name, the stage name and the relative path to the file to the URL path. > **Note** > > The returned files are plain-text instead of JSON-encoded. The following example fetches the configuration file `conf.d/test.conf`: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd/conf.d/test.conf' ``` ``` object Host "cmdb-host" { chec_command = "dummy" } ``` You can fetch a [list of existing files](12-icinga2-api.md#icinga2-api-config-management-list-config-package-stage-files) in a configuration stage and then specifically request their content. ### Configuration Package Stage Errors Now that we don't have an active stage for `example-cmdb` yet seen [here](12-icinga2-api.md#icinga2-api-config-management-list-config-packages), there must have been an error. In order to check for validation errors you can fetch the `startup.log` file by sending a `GET` request to the URL endpoint `/v1/config/files`. You must include the package name, stage name and the `startup.log` in the URL path. ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd/startup.log' ``` ``` [...] critical/config: Error: Attribute 'chec_command' does not exist. Location: /var/lib/icinga2/api/packages/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd/conf.d/test.conf(1): object Host "cmdb-host" { chec_command = "dummy" } ^^^^^^^^^^^^^^^^^^^^^^ critical/config: 1 error ``` The output is the exact as known from [configuration validation](11-cli-commands.md#config-validation). > **Note** > > The returned output is plain-text instead of JSON-encoded. ### Deleting Configuration Package Stage You can send a `DELETE` request to the URL endpoint `/v1/config/stages` in order to purge a configuration stage. You must include the package and stage name inside the URL path. The following example removes the failed configuration stage `7e7861c8-8008-4e8d-9910-2a0bb26921bd` in the `example-cmdb` configuration package: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X DELETE 'https://localhost:5665/v1/config/stages/example-cmdb/7e7861c8-8008-4e8d-9910-2a0bb26921bd?pretty=1' ``` ```json { "results": [ { "code": 200.0, "status": "Stage deleted." } ] } ``` ### Deleting Configuration Package In order to completely purge a configuration package and its stages you can send a `DELETE` request to the URL endpoint `/v1/config/packages` with the package name in the URL path. This example entirely deletes the configuration package `example-cmdb`: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' -X DELETE \ 'https://localhost:5665/v1/config/packages/example-cmdb?pretty=1' ``` ```json { "results": [ { "code": 200.0, "package": "example-cmdb", "status": "Deleted package." } ] } ``` ## Types You can retrieve the configuration object types by sending a `GET` request to URL endpoint `/v1/types`. Each response entry in the results array contains the following attributes: Attribute | Type | Description ----------------|--------------|--------------------- name | String | The type name. plural\_name | String | The plural type name. fields | Dictionary | Available fields including details on e.g. the type and attribute accessibility. abstract | Boolean | Whether objects can be instantiated for this type. base | Boolean | The base type (e.g. `Service` inherits fields and prototype methods from `Checkable`). prototype\_keys | Array | Available prototype methods. In order to view a specific configuration object type specify its name inside the URL path: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/types/Object?pretty=1' ``` ```json { "results": [ { "abstract": false, "fields": { "type": { "array_rank": 0.0, "attributes": { "config": false, "navigation": false, "no_user_modify": false, "no_user_view": false, "required": false, "state": false }, "id": 0.0, "type": "String" } }, "name": "Object", "plural_name": "Objects", "prototype_keys": [ "clone", "notify_attribute", "to_string" ] } ] } ``` ## Config Templates Provides methods to manage configuration templates: * [querying templates](12-icinga2-api.md#icinga2-api-config-templates-query) Creation, modification and deletion of templates at runtime is not supported. ### Querying Templates You can request information about configuration templates by sending a `GET` query to the `/v1/templates/` URL endpoint. `` has to be replaced with the plural name of the object type you are interested in: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/templates/hosts' ``` A list of all available configuration types is available in the [object types](09-object-types.md#object-types) chapter. A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The template object can be accessed in the filter using the `tmpl` variable. In this example the [match function](18-library-reference.md#global-functions-match) is used to check a wildcard string pattern against `tmpl.name`. The `filter` attribute is passed inside the request body thus requiring to use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) here. ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://localhost:5661/v1/templates/hosts' \ -d '{ "filter": "match(\"g*\", tmpl.name)" }' ``` Instead of using a filter you can optionally specify the template name in the URL path when querying a single object: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/templates/hosts/generic-host' ``` The result set contains the type, name as well as the location of the template. ## Variables Provides methods to manage global variables: * [querying variables](12-icinga2-api.md#icinga2-api-variables-query) ### Querying Variables You can request information about global variables by sending a `GET` query to the `/v1/variables/` URL endpoint: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/variables' ``` A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The variable information object can be accessed in the filter using the `variable` variable. The `filter` attribute is passed inside the request body thus requiring to use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) here. ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -H 'X-HTTP-Method-Override: GET' -X POST \ 'https://localhost:5661/v1/variables' \ -d '{ "filter": "variable.type in [ \"String\", \"Number\" ]" }' ``` Instead of using a filter you can optionally specify the variable name in the URL path when querying a single variable: ```bash curl -k -s -S -i -u root:icinga 'https://localhost:5665/v1/variables/PrefixDir' ``` The result set contains the type, name and value of the global variable. ## Debug Console You can inspect variables and execute other expressions by sending a `POST` request to the URL endpoint `/v1/console/execute-script`. In order to receive auto-completion suggestions, send a `POST` request to the URL endpoint `/v1/console/auto-complete-script`. > **Note** > > This functionality is used by the [debug console](11-cli-commands.md#cli-command-console). Do not use this in production, unless > you are aware of the fact that expressions and commands may crash the daemon, or lead into > unwanted behaviour. Use this URL endpoint **read-only** when needed. The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body): Parameter | Type | Description -----------|--------------|------------- session | String | **Optional.** The session ID. Ideally this should be a GUID or some other unique identifier. command | String | **Required.** Command expression for execution or auto-completion. sandboxed | Number | **Optional.** Whether runtime changes are allowed or forbidden. Defaults to disabled. The [API permission](12-icinga2-api.md#icinga2-api-permissions) `console` is required for executing expressions. > **Note** > > Runtime modifications via `execute-script` calls are not validated and might cause the Icinga 2 > daemon to crash or behave in an unexpected way. Use these runtime changes at your own risk. If you specify a session identifier, the same script context can be reused for multiple requests. This allows you to, for example, set a local variable in a request and use that local variable in another request. Sessions automatically expire after a set period of inactivity (currently 30 minutes). Example for fetching the command line from the local host's last check result: ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/console/execute-script?command=get_host(NodeName).last_check_result.command&sandboxed=0&session=bb75fd7c-c686-407d-9688-582c04227756&pretty=1' ``` ```json { "results": [ { "code": 200.0, "result": [ "/usr/local/sbin/check_ping", "-H", "127.0.0.1", "-c", "5000,100%", "-w", "3000,80%" ], "status": "Executed successfully." } ] } ``` Example for fetching auto-completion suggestions for the `Host.` type. This works in a similar fashion when pressing TAB inside the [console CLI command](11-cli-commands.md#cli-command-console): ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X POST 'https://localhost:5665/v1/console/auto-complete-script?command=Host.&sandboxed=0&session=bb75fd7c-c686-407d-9688-582c04227756&pretty=1' ``` ```json { "results": [ { "code": 200.0, "status": "Auto-completed successfully.", "suggestions": [ "Host.type", "Host.name", "Host.prototype", "Host.base", "Host.register_attribute_handler", "Host.clone", "Host.notify_attribute", "Host.to_string" ] } ] } ``` ## Memory Usage Analysis The GNU libc function `malloc_info(3)` provides memory allocation and usage statistics of Icinga 2 itself. You can call it directly by sending a `GET` request to the URL endpoint `/v1/debug/malloc_info`. The [API permission](12-icinga2-api.md#icinga2-api-permissions) `debug` is required. Example: ```bash curl -k -s -S -i -u root:icinga https://localhost:5665/v1/debug/malloc_info ``` In contrast to other API endpoints, the response is not JSON, but the raw XML output from `malloc_info(3)`. See also the [glibc malloc(3) internals](https://sourceware.org/glibc/wiki/MallocInternals). ```xml ``` ## API Clients After its initial release in 2015, community members and developers have been working hard to add more REST API clients and integrations into DevOps tools. * [Libraries](12-icinga2-api.md#icinga2-api-clients-libraries) * [Status](12-icinga2-api.md#icinga2-api-clients-status) * [Management](12-icinga2-api.md#icinga2-api-clients-management) * [Event Streams](12-icinga2-api.md#icinga2-api-clients-event-streams) * [Actions](12-icinga2-api.md#icinga2-api-clients-actions) * [REST API Apps](12-icinga2-api.md#icinga2-api-clients-apps) Additional [programmatic examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples) will help you getting started using the Icinga 2 API in your environment. ### Libraries Name | Language | Description ------------------------------------------------------------------------------------------------|---------------|-------------------------------------------------------- [ruby-icinga2](https://github.com/bodsch/ruby-icinga2) | Ruby | Ruby library [python-icinga2_api](https://github.com/KevinHonka/Icinga2_Python_API) | Python | Python library [python-icinga2-api](https://github.com/fmnisme/python-icinga2api) | Python | Python bindings for Icinga 2 interaction [python-icinga2-api-continued](https://github.com/joni1993/icinga2apic) | Python | Python bindings for Icinga 2 interaction forked and continued from fmnisme's python binding [go-icinga2](https://github.com/xert/go-icinga2) | Golang | Golang functions and type definitions [go-icinga2-api](https://github.com/lrsmith/go-icinga2-api/) | Golang | Golang implementation used inside the Terraform provider [go-icinga2-client](https://github.com/Nexinto/go-icinga2-client) | Golang | Golang implementation for the Rancher integration. [Monitoring::Icinga2::Client::REST](https://metacpan.org/release/THESEAL/Monitoring-Icinga2-Client-REST-2.0.0) | Perl | Perl bindings. [Icinga 2 API in PHP](https://github.com/uniwue-rz/icinga2-api) | PHP | PHP implementation. For other examples, look into Icinga Web 2 and Director. ### Status Name | Language | Description ------------------------------------------------------------------------------------------------|---------------|-------------------------------------------------------- [Dashing](https://github.com/dnsmichi/dashing-icinga2) | Ruby, HTML | Dashboard for Dashing querying the REST API for current host/service/global status [InfluxDB Telegraf Input](https://github.com/influxdata/telegraf/blob/master/plugins/inputs/icinga2/README.md) | Golang | [Telegraf](https://github.com/influxdata/telegraf) is an agent written in Go for collecting, processing, aggregating, and writing metrics. [Icinga Slack Bot](https://github.com/bb-Ricardo/icinga-slack-bot) | Python | It can be used to interact with Icinga2 from your Slack client. It uses the Icinga2 API to get Host/Service status details. Simple status filters can be used to narrow down the returned status list. [Icinga 2 Slack Bot](https://github.com/mlabouardy/icinga2-slack-bot) | Golang | Query host/service details from a [Slack](https://slack.com/) channel [icinga2bot](https://github.com/reikoNeko/icinga2bot) | Python | [Errbot](https://errbot.io/en/latest/user_guide/setup.html) plugin to fetch status and event stream information and forward to XMPP, IRC, etc. [IcingaBusyLightAgent](https://github.com/stdevel/IcingaBusylightAgent) | C# | Notification Agent in Systray [BitBar for OSX](https://getbitbar.com/plugins/Dev/Icinga2/icinga2.24m.py) | Python | macOS tray app for highlighting the host/service status [Icinga 2 Multistatus](https://chrome.google.com/webstore/detail/icinga-multi-status/khabbhcojgkibdeipanmiphceeoiijal/related) | - | Chrome Extension [Naglite4](https://github.com/wftech/icinga2-naglite4) | Python | Naglite3 rewrite using the Icinga 2 REST API. [icinga-telegram-bot](https://github.com/joni1993/icinga-telegram-bot) | Python | Telegram Bot using the Icinga 2 REST API ### Manage Objects Name | Language | Description ------------------------------------------------------------------------------------------------|---------------|-------------------------------------------------------- [Icinga Director](https://icinga.com/docs/director/latest) | PHP, JS | Icinga 2 configuration interface with a nice frontend, and automated imports for nearly any source. [Terraform Provider](https://github.com/terraform-providers/terraform-provider-icinga2) | Golang | Register hosts from Terraform in Icinga 2. [Official docs](https://www.terraform.io/docs/providers/icinga2/index.html). [Kube Icinga](https://github.com/gyselroth/kube-icinga) | Typescript | Monitor Kubernetes services / resources using icinga2 (including autodiscovery support) [Logstash output for Icinga](https://www.icinga.com/products/integrations/elastic/) | Ruby | Forward check results and create objects from log events [Foreman Smart Proxy Monitoring](https://github.com/theforeman/smart_proxy_monitoring) | Ruby | Smart Proxy extension for Foreman creating and deleting hosts and services in Icinga 2 [Rancher integration](https://github.com/Nexinto/rancher-icinga) | Golang | Registers [Rancher](https://rancher.com) resources in Icinga 2 for monitoring. [AWS/EC2](https://github.com/Icinga/icinga2-api-examples/tree/master/aws-ec2) | Ruby | Example script for creating and deleting AWS instances in Icinga 2 [Ansible Host Module](https://docs.ansible.com/ansible/latest/modules/icinga2_host_module.html) | Python | In progress, [Ansible Feature](https://docs.ansible.com/ansible/latest/modules/icinga2_feature_module.html#icinga2-feature-module) is also there. [gocinga](https://gitlab.com/sambadevi/gocinga) | Golang | CLI Tool for Icinga, written in go ### Event Streams Name | Language | Description ------------------------------------------------------------------------------------------------|---------------|-------------------------------------------------------- [Elastic Icingabeat](https://icinga.com/docs/icingabeat/latest/) | Golang | Process events and send to Elasticsearch/Logstash outputs [Request Tracker ticket integration](https://github.com/bytemine/icinga2rt) | Golang | Create and update RT tickets [Logstash input event stream](https://github.com/bobapple/logstash-input-icinga_eventstream) | Ruby | Forward events as Logstash input [Flapjack events](https://github.com/sol1/flapjack-icinga2) | Golang | Dumping events into Redis for Flapjack processing [Stackstorm integration](https://github.com/StackStorm-Exchange/stackstorm-icinga2) | Python | Processing events and fetching status information [NodeJS consumer](https://community.icinga.com/t/consume-api-event-stream/1010/6) | NodeJS | Example from our community :) ### Actions Name | Language | Description ------------------------------------------------------------------------------------------------|---------------|-------------------------------------------------------- [Icinga Web 2](https://icinga.com/docs/icingaweb2/latest/) | PHP | Trigger actions via command transport [Logstash output for Icinga](https://www.icinga.com/products/integrations/elastic/) | Ruby | Forward check results and create objects from log events [OTRS SystemMonitoring](https://github.com/OTRS/SystemMonitoring) | Perl | Acknowledge problems in Icinga 2 from OTRS tickets [mqttwarn](https://github.com/jpmens/mqttwarn#icinga2) | Python | Forward check results from mqttwarn to Icinga 2 [Lita handler](https://github.com/tuxmea/lita-icinga2) | Ruby | List, recheck and acknowledge through a #chatops bot called [Lita](https://github.com/litaio/lita) [Sakuli forwarder](http://sakuli.readthedocs.io/en/latest/forwarder-icinga2api/) | Java | Forward check results from tests from [Sakuli](https://github.com/ConSol/sakuli) to Icinga 2 [OpsGenie actions](https://www.opsgenie.com/docs/integrations/icinga2-integration) | Golang, Java | Integrate Icinga 2 into OpsGenie ### REST API Apps Name | Language | Description ------------------------------------------------------------------------------------------------|---------------|-------------------------------------------------------- Browser plugins | - | [Postman for Chrome](https://www.getpostman.com), [RESTED for Firefox](https://addons.mozilla.org/en-US/firefox/addon/rested/) [Postman](https://www.getpostman.com/) | - | App instead of browser plugin [Cocoa Rest Client](https://mmattozzi.github.io/cocoa-rest-client/) | - | macOS app [Paw for MacOS](https://paw.cloud) | (exported) | Paw is a full-featured HTTP client that lets you test and describe the APIs you build or consume. It has a beautiful native macOS interface to compose requests, inspect server responses, generate client code and export API definitions. ### Programmatic Examples The following languages are covered: * [Python](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-python) * [Ruby](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-ruby) * [PHP](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-php) * [Perl](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-perl) * [Golang](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-golang) * [Powershell](12-icinga2-api.md#icinga2-api-clients-programmatic-examples-powershell) The [request method](#icinga2-api-requests) is `POST` using [X-HTTP-Method-Override: GET](12-icinga2-api.md#icinga2-api-requests-method-override) which allows you to send a JSON request body. The examples request specific service attributes joined with host attributes. `attrs` and `joins` are therefore specified as array. The `filter` attribute [matches](18-library-reference.md#global-functions-match) on all services with `ping` in their name. #### Example API Client in Python The following example uses **Python** and the `requests` and `json` module: ``` # pip install requests # pip install json $ vim icinga.py #!/usr/bin/env python import requests, json # Replace 'localhost' with your FQDN and certificate CN # for TLS verification request_url = "https://localhost:5665/v1/objects/services" headers = { 'Accept': 'application/json', 'X-HTTP-Method-Override': 'GET' } data = { "attrs": [ "name", "state", "last_check_result" ], "joins": [ "host.name", "host.state", "host.last_check_result" ], "filter": "match(\"ping*\", service.name)", } r = requests.post(request_url, headers=headers, auth=('root', 'icinga'), data=json.dumps(data), verify="pki/icinga2-ca.crt") print "Request URL: " + str(r.url) print "Status code: " + str(r.status_code) if (r.status_code == 200): print "Result: " + json.dumps(r.json()) else: print r.text r.raise_for_status() $ python icinga.py ``` #### Example API Client in Ruby The following example uses **Ruby** and the `rest_client` gem: ``` # gem install rest_client $ vim icinga.rb #!/usr/bin/ruby require 'rest_client' # Replace 'localhost' with your FQDN and certificate CN # for TLS verification request_url = "https://localhost:5665/v1/objects/services" headers = { "Accept" => "application/json", "X-HTTP-Method-Override" => "GET" } data = { "attrs" => [ "name", "state", "last_check_result" ], "joins" => [ "host.name", "host.state", "host.last_check_result" ], "filter" => "match(\"ping*\", service.name)", } r = RestClient::Resource.new( URI.encode(request_url), :headers => headers, :user => "root", :password => "icinga", :ssl_ca_file => "pki/icinga2-ca.crt") begin response = r.post(data.to_json) rescue => e response = e.response end puts "Status: " + response.code.to_s if response.code == 200 puts "Result: " + (JSON.pretty_generate JSON.parse(response.body)) else puts "Error: " + response end $ ruby icinga.rb ``` A more detailed example can be found in the [Dashing demo](https://github.com/Icinga/dashing-icinga2). #### Example API Client in PHP The following example uses **PHP** and its `curl` library: ``` $ vim icinga.php #!/usr/bin/env php array('name', 'state', 'last_check_result'), joins => array('host.name', 'host.state', 'host.last_check_result'), filter => 'match("ping*", service.name)', ); $ch = curl_init(); curl_setopt_array($ch, array( CURLOPT_URL => $request_url, CURLOPT_HTTPHEADER => $headers, CURLOPT_USERPWD => $username . ":" . $password, CURLOPT_RETURNTRANSFER => true, CURLOPT_CAINFO => "pki/icinga2-ca.crt", CURLOPT_POST => count($data), CURLOPT_POSTFIELDS => json_encode($data) )); $response = curl_exec($ch); if ($response === false) { print "Error: " . curl_error($ch) . "(" . $response . ")\n"; } $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); print "Status: " . $code . "\n"; if ($code == 200) { $response = json_decode($response, true); print_r($response); } ?> $ php icinga.php ``` #### Example API Client in Perl The following example uses **Perl** and the `Rest::Client` module: ``` # perl -MCPAN -e 'install REST::Client' # perl -MCPAN -e 'install JSON' # perl -MCPAN -e 'install MIME::Base64' # perl -MCPAN -e 'install Data::Dumper' $ vim icinga.pl #!/usr/bin/env perl use strict; use warnings; use REST::Client; use MIME::Base64; use JSON; use Data::Dumper; # Replace 'localhost' with your FQDN and certificate CN # for TLS verification my $request_host = "https://localhost:5665"; my $userpass = "root:icinga"; my $client = REST::Client->new(); $client->setHost($request_host); $client->setCa("pki/icinga2-ca.crt"); $client->addHeader("Accept", "application/json"); $client->addHeader("X-HTTP-Method-Override", "GET"); $client->addHeader("Authorization", "Basic " . encode_base64($userpass)); my %json_data = ( attrs => ['name', 'state', 'last_check_result'], joins => ['host.name', 'host.state', 'host.last_check_result'], filter => 'match("ping*", service.name)', ); my $data = encode_json(\%json_data); $client->POST("/v1/objects/services", $data); my $status = $client->responseCode(); print "Status: " . $status . "\n"; my $response = $client->responseContent(); if ($status == 200) { print "Result: " . Dumper(decode_json($response)) . "\n"; } else { print "Error: " . $response . "\n"; } $ perl icinga.pl ``` #### Example API Client in Golang Requires the Golang build chain. ``` $ vim icinga.go package main import ( "bytes" "crypto/tls" "log" "io/ioutil" "net/http" ) func main() { var urlBase= "https://localhost:5665" var apiUser= "root" var apiPass= "icinga" urlEndpoint := urlBase + "/v1/objects/services" tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } httpClient := &http.Client{Transport: tr} var requestBody = []byte(`{ "attrs": [ "name", "state", "last_check_result" ], "joins": [ "host.name", "host.state", "host.last_check_result" ], "filter": "match(\"ping*\", service.name)" }`) req, err := http.NewRequest("POST", urlEndpoint, bytes.NewBuffer(requestBody)) req.Header.Set("Accept", "application/json") req.Header.Set("X-HTTP-Method-Override", "GET") req.SetBasicAuth(apiUser, apiPass) resp, err := httpClient.Do(req) if err != nil { log.Fatal("Server error:", err) return } defer resp.Body.Close() log.Print("Response status:", resp.Status) bodyBytes, _ := ioutil.ReadAll(resp.Body) bodyString := string(bodyBytes) if resp.StatusCode == http.StatusOK { log.Print("Result: " + bodyString) } else { log.Fatal(bodyString) } } ``` Build the binary: ```bash go build icinga.go ./icinga ``` #### Example API Client in Powershell This example compares the given certificate with the certificate from icinga2 for a trusted connection. More info: https://stackoverflow.com/a/58494718/9397788 Invoke-RestMethod with PUT is buggy with Powershell 3.0. So we need at least Powershell 4.0. https://stackoverflow.com/questions/18278977/powershell-v3-invoke-restmethod-headers ``` $icingaApiHost = "icinga.master.local" $IcingaApiPort = 5665 $icingaApiUser = "root" $icingaApiPassword = "icinga" $requestUrl = "https://{0}:{1}/v1/objects/services" -f $icingaApiHost,$IcingaApiPort # Put the certificate from your master (/etc/icinga2/pki/*.crt) here. # You will get it with "openssl s_client -connect :5665" too. $cert64=@" -----BEGIN CERTIFICATE----- MIIE5TCCAs2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlJY2lu Z2EgQ0EwHhcNMTYwNzA3MDYxOTM4WhcNMzEwNzA0MDYxOTM4WjAiMSAwHgYDVQQD DBdpY2luZ2EuZXh0ZXJuMS56bXQuaW5mbzCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAJ2/ufxCb1m8PbUCxLkZqZNLxZ/vpulOcKmOGYm6VBWbOXQA50on IewnMRUDGF9DHajLk1nyUu1TyKxGzBbja+06/kVd/8Muv0MUNF6iC1U3F3h0W9da kk5rK1L+A534csHCFcG3dZkbdOMrh5hy4kMf9c2FEpviL54Fo4e+b3ZJFA6rv5D9 7LzaxfLcsMwXIZ/WRnxjjfnA+RenHeYLlNM8Uk3vqI6tBc1qpFzFeRWMbclFzSLN 5x+J6cuyFjVi+Vv8c6SU6W3ykw8Vvq1QQUixl9lwxqNJNsWWfGR8ycmFiv1ZYxiu HpmuLslExZ2qxdGe/raMBEOGgVsUTDZNyTm/9TxgOa3m9cv3R0YIFUmfoBQ3d51S wburJG2eC0ETpnt0TptwMdTfL+HYVWB71djg2Pb8R3vldnhFVpy9vyx3FyHoN7ZQ h7+r6HK2jpwWo7/jK9ExpglVoV8vUbNYqXiA/lZGEkT3YLwTyUhqXKei3Xu2CGGR UId6fAj6OWk9TLW+OaR9BcS74mpiTWNDlbEP+/LQnUhte8scX5cSqBzy4vpuG1G+ NGDbYcG4xn6Pc6qt/QddKU/pB/GbJv9SlHU8SjSt09oG9GtuXVjPoZX5msi3NmMy DpAcab5Lx4MgOS/GwRLRI3IjZ3ZK+UkLvRgesSH5/JPUIgfTdr/Eg5dVAgMBAAGj NDAyMAwGA1UdEwEB/wQCMAAwIgYDVR0RBBswGYIXaWNpbmdhLmV4dGVybjEuem10 LmluZm8wDQYJKoZIhvcNAQELBQADggIBAEpEJt35KZuvDzU/xrVaVC3ct6CHmXOh DDj5PdwkYtO0vw9WE7aVc88Fs6uhW2BxFkLvm7TpJ6g05egtBozHYrhTEir/fPna rVAD9wEQU6KuSayeToXlgWhKDRAAv1lrQwU4xAAdJP8faxQGc7nAwN/h0g14UTmU LSkyJU4a+1SkEUOs2YCq9vChS3MowO+6I35e98dIA1swHLeQ/QJowspODQvi6pGX VH8FaaqfGwhv+gMwDoAW9hB74VZXO8I3mueZUccPiJXlaojx5hpaHRNRvpdBPclA HHLRQniEOkai2Wg2cft/wq6/fYLE/yv5ej15MNyt3Wjj41DEK5B/bvmN/chOrZlv 8rh3ek12ngVtXF+Jcmfsij8+hj/IOM6SeELtW+c0KRaPoVR7oR9o6ce/dyfiw6Hv iQsAV6x//kytpRnUY3VAH4QTJzQ5bgz1Cwr6H+cWE2ca4MHCtPYaZnDiOv4b/Yz7 97Nrc7QPGewMl0hYeykpLP2hBJldw01NXhztuq1j38vYY38lKCN6v1INUujEUZg7 NwgfHUvJmGIE/fwLAvP7do8gf+1MGPEimsgvias5YtDtrEOz7K/oF3Qgk3sepwAz XXlNLnJAY4p0d/sgCCFQnstQMM95X0Y6cfITzkz3HIUcNF2sbvVnn8xHi0TSH/8J tPLHO1xOLz7N -----END CERTIFICATE----- "@ # register callback for comparing the certificate function set-SSLCertificate { param( $Cert ) if (-not("validateCert" -as [type])) { add-type -TypeDefinition @" using System.Net.Security; using System.Security.Cryptography.X509Certificates; public static class ValidateCert { static X509Certificate2 MyCert; public static bool Validate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (MyCert.Equals(cert)) { return true; } else { return false; } } public static RemoteCertificateValidationCallback GetDelegate(X509Certificate2 Cert) { MyCert = Cert; return new RemoteCertificateValidationCallback(ValidateCert.Validate); } } "@ } [System.Net.ServicePointManager]::ServerCertificateValidationCallback = [validateCert]::GetDelegate($Cert) } # convert base64 based certificate to X509 certificate function get-x509 { param( [string] $Cert64 ) $CertBin=[System.Convert]::FromBase64String(($Cert64.Trim(" ") -replace "-.*-","")) Write-Host ($Cert64.Trim(" ") -replace "-.*-","") [System.Security.Cryptography.X509Certificates.X509Certificate2]$CertBin } # Allow TLS 1.2. Old powershell (.net) uses TLS 1.0 only. Icinga2 >2.10 needs TLS 1.2 [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' $SecPass = ConvertTo-SecureString $icingaApiPassword -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential($icingaApiUser, $SecPass) $Cert = get-x509 $Cert64 set-SSLCertificate $Cert $httpHeaders = @{ "X-HTTP-Method-Override" = "GET" "accept" = "application/json" } $attrs = @( "name", "state", "last_check_result" ) $joins = @( "host.name", "host.state", "host.last_check_result") $filter = 'match("ping*", service.name)' $data = @{ "attrs" = $attrs "joins" = $joins "filter" = $filter } $result = Invoke-RestMethod -Uri $requestUrl -Method "POST" -Body (ConvertTo-Json -InputObject $data) -Credential $Cred -ContentType "application/json" -Headers $httpHeaders foreach ($s in $result.results) { Write-Host "Service " $s.attrs.name " on Host " $s.joins.host.name "State " $s.attrs.state " Output: " $s.attrs.last_check_result.output # Debug Write-Host "Debug: Attributes " $s.attrs | ConvertTo-Json Write-Host "Debug: Joins Host" $s.joins.host | ConvertTo-Json Write-Host "`n" } ``` Run the Powershell ISE as administrator, and execute the script as you change it. ![Icinga 2 API Windows Powershell ISE Script](images/api/icinga2_api_powershell_ise.png) Alternatively, save the code and run it in Powershell: ``` .\icinga.ps1 ``` icinga2-2.14.6/doc/13-addons.md000066400000000000000000000217161501332562400157100ustar00rootroot00000000000000# Icinga 2 Addons and Integrations For an uptodate overview of all integrations and modules, please visit [https://icinga.com/products/](https://icinga.com/products/). ## Syntax Highlighting Icinga 2 provides configuration examples for syntax highlighting using the `vim` and `nano` editors. ### Using Vim Install the package `vim-icinga2` with your distribution's package manager. Ensure that syntax highlighting is enabled e.g. by editing the user's `vimrc` configuration file: ``` # vim ~/.vimrc syntax on ``` Test it: ```bash vim /etc/icinga2/conf.d/templates.conf ``` ![Vim with syntax highlighting](images/addons/vim-syntax.png "Vim with Icinga 2 syntax highlighting") ### Using Nano Install the package `nano-icinga2` with your distribution's package manager. **Note:** On Debian, Ubuntu and Raspberry Pi OS, the syntax files are installed with the `icinga2-common` package already. Copy the `/etc/nanorc` sample file to your home directory. ```bash cp /etc/nanorc ~/.nanorc ``` Include the `icinga2.nanorc` file. ``` $ vim ~/.nanorc ## Icinga 2 include "/usr/share/nano/icinga2.nanorc" ``` Test it: ```bash nano /etc/icinga2/conf.d/templates.conf ``` ![Nano with syntax highlighting](images/addons/nano-syntax.png "Nano with Icinga 2 syntax highlighting") ## Icinga Reporting The [Icinga Reporting Module](https://icinga.com/docs/reporting/latest/) is the framework and foundation we created to handle data collected by Icinga 2 and other data providers. By definition Icinga Reporting does not collect or calculate any data. The framework processes usable data from data providers such as Icinga’s IDO or Icinga Web 2 modules and makes them available in different formats. It can display the data directly within the Icinga web interface or export it to PDF, JSON or CSV format. With scheduled reports you can receive the prepared data periodically via email. ![Icinga Reporting](images/addons/icinga_reporting.png) ## Graphs and Metrics ### Graphite [Graphite](https://graphite.readthedocs.org/en/latest/) is a time-series database storing collected metrics and making them available through restful apis and web interfaces. Graphite consists of 3 software components: * carbon -- a Twisted daemon that listens for time-series data * whisper -- a simple database library for storing time-series data (similar in design to RRD) * graphite webapp -- a Django webapp that renders graphs on-demand using Cairo You need to install Graphite first, then proceed with configuring it in Icinga 2. Use the [GraphiteWriter](14-features.md#graphite-carbon-cache-writer) feature for sending real-time metrics from Icinga 2 to Graphite. ```bash icinga2 feature enable graphite ``` A popular alternative frontend for Graphite is for example [Grafana](https://grafana.org). Integration in Icinga Web 2 is possible by installing the official [graphite module](https://icinga.com/docs/graphite/latest/). ![Icinga Web 2 Detail View with Graphite](images/addons/icingaweb2_graphite.png) ### InfluxDB [InfluxDB](https://influxdb.com) is a time series, metrics, and analytics database. It’s written in Go and has no external dependencies. Use the [InfluxdbWriter](14-features.md#influxdb-writer) feature for sending real-time metrics from Icinga 2 to InfluxDB v1. ```bash icinga2 feature enable influxdb ``` Use the [Influxdb2Writer](14-features.md#influxdb-writer) feature for sending real-time metrics from Icinga 2 to InfluxDB v2. ```bash icinga2 feature enable influxdb2 ``` A popular frontend for InfluxDB is for example [Grafana](https://grafana.org). Integration in Icinga Web 2 is possible by installing the community [Grafana module](https://github.com/Mikesch-mp/icingaweb2-module-grafana). ![Icinga Web 2 Detail View with Grafana](images/addons/icingaweb2_grafana.png) ### PNP [PNP](https://www.pnp4nagios.org) is a graphing addon. [PNP](https://www.pnp4nagios.org) is an addon which adds a graphical representation of the performance data collected by the monitoring plugins. The data is stored as rrd (round robin database) files. Use your distribution's package manager to install the `pnp4nagios` package. If you're planning to use it, configure it to use the [bulk mode with npcd and npcdmod](https://docs.pnp4nagios.org/pnp-0.6/modes#bulk_mode_with_npcd_and_npcdmod) in combination with Icinga 2's [PerfdataWriter](14-features.md#writing-performance-data-files). NPCD collects the performance data files which Icinga 2 generates. Enable performance data writer in icinga 2 ```bash icinga2 feature enable perfdata ``` Configure npcd to use the performance data created by Icinga 2: ```bash vim /etc/pnp4nagios/npcd.cfg ``` Set `perfdata_spool_dir = /var/spool/icinga2/perfdata` and restart the `npcd` daemon. There's also an Icinga Web 2 module for direct PNP graph integration available at [Icinga Exchange](https://exchange.icinga.com/icinga/PNP). ## Visualization ### Maps This community module displays host objects as markers on openstreetmap in Icinga Web 2. It uses the data provided by the monitoring module and as such the [DB IDO](14-features.md#db-ido) from Icinga 2. If you configure multiple hosts with the same coordinates, i.e. servers in a datacenter, a clustered view is rendered. Check the [Map module docs](https://github.com/nbuchwitz/icingaweb2-module-map) for more details on installation, configuration and integration. ![Icinga Web 2 Maps](images/addons/icingaweb2_maps.png) ### Business Process Create top-level views of your applications in a graphical editor. Rules express dependencies between existing hosts and services and let you alert on application level. Business processes are displayed in a tree or list overview and can be added to any dashboard. ![Icinga Web 2 Business Process](images/addons/icingaweb2_businessprocess.png) Read more [here](https://icinga.com/docs/icinga-business-process-modeling/latest/). ### Certificate Monitoring Monitor your certificates in an efficient and comfortable way. Be aware of required actions and view all details at a glance. ![Icinga Certificate Monitoring](images/addons/icinga_certificate_monitoring.png) Read more [here](https://icinga.com/products/icinga-certificate-monitoring/). ### Dashing Dashboard The [Icinga 2 dashboard](https://github.com/dnsmichi/dashing-icinga2) is built on top of Dashing and uses the [REST API](12-icinga2-api.md#icinga2-api) to visualize what's going on with your monitoring. It combines several popular widgets and provides development instructions for your own implementation. The dashboard also allows to embed the [Icinga Web 2](https://icinga.com/docs/icinga-web/latest/) host and service problem lists as Iframe. ![Dashing dashboard](images/addons/dashing_icinga2.png) ## Log Monitoring Using [Logstash](https://www.elastic.co/guide/en/logstash/current/introduction.html) or [Graylog](https://www.graylog.org) in your infrastructure and correlate events with your monitoring is even simpler these days. * Use the `GelfWriter` feature to write Icinga 2's check and notification events to Graylog or Logstash. * Configure the logstash `nagios` output to send passive traps to Icinga 2 using the external command pipe. * Execute a plugin to check Graylog alert streams. More details can be found in [this blog post](https://icinga.com/2014/12/02/team-icinga-at-osmc-2014/). ## Notification Scripts and Interfaces There's a variety of resources available, for example different notification scripts such as: * E-Mail ([examples](03-monitoring-basics.md#alert-notifications) provided) * SMS * Pager (XMPP, etc.) * Twitter * IRC * Ticket systems * etc. Additionally external services can be [integrated with Icinga 2](https://icinga.com/products/integrations/): * [Pagerduty](https://icinga.com/products/integrations/pagerduty/) * [VictorOps](https://icinga.com/products/integrations/victorops/) * [StackStorm](https://icinga.com/products/integrations/stackstorm/) More information can be found on the [Icinga Website](https://icinga.com/). ## Configuration Management Tools Checkout these specific integrations: * [Ansible Roles](https://icinga.com/products/integrations/) * [Puppet Module](https://icinga.com/products/integrations/puppet/) * [Chef Cookbook](https://icinga.com/products/integrations/chef/) If you're looking for different config management integrations -- we're happy to add them upstream, so please get in touch with the [Icinga team](https://icinga.com/community/). icinga2-2.14.6/doc/14-features.md000066400000000000000000001363161501332562400162620ustar00rootroot00000000000000# Icinga 2 Features ## Logging Icinga 2 supports three different types of logging: * File logging * Syslog (on Linux/UNIX) * Console logging (`STDOUT` on tty) You can enable additional loggers using the `icinga2 feature enable` and `icinga2 feature disable` commands to configure loggers: Feature | Description ----------------|------------ debuglog | Debug log (path: `/var/log/icinga2/debug.log`, severity: `debug` or higher) journald | Systemd Journal (severity: `warning` or higher) mainlog | Main log (path: `/var/log/icinga2/icinga2.log`, severity: `information` or higher) syslog | Syslog (severity: `warning` or higher) windowseventlog | Windows Event Log (severity: `information` or higher) By default file the `mainlog` feature is enabled. When running Icinga 2 on a terminal log messages with severity `information` or higher are written to the console. ### Log Rotation Packages provide a configuration file for [logrotate](https://linux.die.net/man/8/logrotate) on Linux/Unix. Typically this is installed into `/etc/logrotate.d/icinga2` and modifications won't be overridden on upgrade. Instead of sending the reload HUP signal, logrotate sends the USR1 signal to notify the Icinga daemon that it has rotate the log file. Icinga reopens the log files then: * `/var/log/icinga2/icinga2.log` (requires `mainlog` enabled) * `/var/log/icinga2/debug.log` (requires `debuglog` enabled) * `/var/log/icinga2/error.log` By default, log files will be rotated daily. ## Core Backends ### REST API The REST API is documented [here](12-icinga2-api.md#icinga2-api) as a core feature. ### Icinga DB Icinga DB is a set of components for publishing, synchronizing and visualizing monitoring data in the Icinga ecosystem, consisting of: * Icinga 2 with its `icingadb` feature enabled, responsible for publishing monitoring data to a Redis server, i.e. configuration and its runtime updates, check results, state changes, downtimes, acknowledgements, notifications, and other events such as flapping * The [Icinga DB daemon](https://icinga.com/docs/icinga-db), which synchronizes the data between the Redis server and a database * And Icinga Web with the [Icinga DB Web](https://icinga.com/docs/icinga-db-web) module enabled, which connects to both Redis and the database to display and work with the most up-to-date data ![Icinga DB Architecture](images/icingadb/icingadb-architecture.png) To set up a Redis server and the Icinga DB feature, please follow the steps from the Icinga 2 [Installation](02-installation.md) guide. For the feature configuration options, see its [Icinga DB object type](09-object-types.md#icingadb) documentation. ## Metrics Whenever a host or service check is executed, or received via the REST API, best practice is to provide performance data. This data is parsed by features sending metrics to time series databases (TSDB): * [Graphite](14-features.md#graphite-carbon-cache-writer) * [InfluxDB](14-features.md#influxdb-writer) * [OpenTSDB](14-features.md#opentsdb-writer) Metrics, state changes and notifications can be managed with the following integrations: * [Elastic Stack](14-features.md#elastic-stack-integration) * [Graylog](14-features.md#graylog-integration) ### Graphite Writer [Graphite](13-addons.md#addons-graphing-graphite) is a tool stack for storing metrics and needs to be running prior to enabling the `graphite` feature. Icinga 2 writes parsed metrics directly to Graphite's Carbon Cache TCP port, defaulting to `2003`. You can enable the feature using ```bash icinga2 feature enable graphite ``` By default the [GraphiteWriter](09-object-types.md#objecttype-graphitewriter) feature expects the Graphite Carbon Cache to listen at `127.0.0.1` on TCP port `2003`. #### Graphite Schema The current naming schema is defined as follows. The [Icinga Web 2 Graphite module](https://icinga.com/products/integrations/graphite/) depends on this schema. The default prefix for hosts and services is configured using [runtime macros](03-monitoring-basics.md#runtime-macros) like this: ``` icinga2.$host.name$.host.$host.check_command$ icinga2.$host.name$.services.$service.name$.$service.check_command$ ``` You can customize the prefix name by using the `host_name_template` and `service_name_template` configuration attributes. The additional levels will allow fine granular filters and also template capabilities, e.g. by using the check command `disk` for specific graph templates in web applications rendering the Graphite data. The following characters are escaped in prefix labels: Character | Escaped character --------------|-------------------------- whitespace | _ . | _ \ | _ / | _ Metric values are stored like this: ``` .perfdata..value ``` The following characters are escaped in performance labels parsed from plugin output: Character | Escaped character --------------|-------------------------- whitespace | _ \ | _ / | _ :: | . Note that labels may contain dots (`.`) allowing to add more subsequent levels inside the Graphite tree. `::` adds support for [multi performance labels](http://my-plugin.de/wiki/projects/check_multi/configuration/performance) and is therefore replaced by `.`. By enabling `enable_send_thresholds` Icinga 2 automatically adds the following threshold metrics: ``` .perfdata..min .perfdata..max .perfdata..warn .perfdata..crit ``` By enabling `enable_send_metadata` Icinga 2 automatically adds the following metadata metrics: ``` .metadata.current_attempt .metadata.downtime_depth .metadata.acknowledgement .metadata.execution_time .metadata.latency .metadata.max_check_attempts .metadata.reachable .metadata.state .metadata.state_type ``` Metadata metric overview: metric | description -------------------|------------------------------------------ current_attempt | current check attempt max_check_attempts | maximum check attempts until the hard state is reached reachable | checked object is reachable downtime_depth | number of downtimes this object is in acknowledgement | whether the object is acknowledged or not execution_time | check execution time latency | check latency state | current state of the checked object state_type | 0=SOFT, 1=HARD state The following example illustrates how to configure the storage schemas for Graphite Carbon Cache. ``` [icinga2_default] # intervals like PNP4Nagios uses them per default pattern = ^icinga2\. retentions = 1m:2d,5m:10d,30m:90d,360m:4y ``` #### Graphite in Cluster HA Zones The Graphite feature supports [high availability](06-distributed-monitoring.md#distributed-monitoring-high-availability-features) in cluster zones since 2.11. By default, all endpoints in a zone will activate the feature and start writing metrics to a Carbon Cache socket. In HA enabled scenarios, it is possible to set `enable_ha = true` in all feature configuration files. This allows each endpoint to calculate the feature authority, and only one endpoint actively writes metrics, the other endpoints pause the feature. When the cluster connection breaks at some point, the remaining endpoint(s) in that zone will automatically resume the feature. This built-in failover mechanism ensures that metrics are written even if the cluster fails. The recommended way of running Graphite in this scenario is a dedicated server where Carbon Cache/Relay is running as receiver. ### InfluxDB Writer Once there are new metrics available, Icinga 2 will directly write them to the defined InfluxDB v1/v2 HTTP API. You can enable the feature using ```bash icinga2 feature enable influxdb ``` or ```bash icinga2 feature enable influxdb2 ``` By default the [InfluxdbWriter](09-object-types.md#objecttype-influxdbwriter)/[Influxdb2Writer](09-object-types.md#objecttype-influxdb2writer) features expect the InfluxDB daemon to listen at `127.0.0.1` on port `8086`. Measurement names and tags are fully configurable by the end user. The Influxdb(2)Writer object will automatically add a `metric` tag to each data point. This correlates to the perfdata label. Fields (value, warn, crit, min, max, unit) are created from data if available and the configuration allows it. If a value associated with a tag is not able to be resolved, it will be dropped and not sent to the target host. Backslashes are allowed in tag keys, tag values and field keys, however they are also escape characters when followed by a space or comma, but cannot be escaped themselves. As a result all trailling slashes in these fields are replaced with an underscore. This predominantly affects Windows paths e.g. `C:\` becomes `C:_`. The database/bucket is assumed to exist so this object will make no attempt to create it currently. If [SELinux](22-selinux.md#selinux) is enabled, it will not allow access for Icinga 2 to InfluxDB until the [boolean](22-selinux.md#selinux-policy-booleans) `icinga2_can_connect_all` is set to true as InfluxDB is not providing its own policy. More configuration details can be found [here for v1](09-object-types.md#objecttype-influxdbwriter) and [here for v2](09-object-types.md#objecttype-influxdb2writer). #### Instance Tagging Consider the following service check: ``` apply Service "disk" for (disk => attributes in host.vars.disks) { import "generic-service" check_command = "disk" display_name = "Disk " + disk vars.disk_partitions = disk assign where host.vars.disks } ``` This is a typical pattern for checking individual disks, NICs, TLS certificates etc associated with a host. What would be useful is to have the data points tagged with the specific instance for that check. This would allow you to query time series data for a check on a host and for a specific instance e.g. /dev/sda. To do this quite simply add the instance to the service variables: ``` apply Service "disk" for (disk => attributes in host.vars.disks) { ... vars.instance = disk ... } ``` Then modify your writer configuration to add this tag to your data points if the instance variable is associated with the service: ``` object InfluxdbWriter "influxdb" { ... service_template = { measurement = "$service.check_command$" tags = { hostname = "$host.name$" service = "$service.name$" instance = "$service.vars.instance$" } } ... } ``` #### InfluxDB in Cluster HA Zones The InfluxDB feature supports [high availability](06-distributed-monitoring.md#distributed-monitoring-high-availability-features) in cluster zones since 2.11. By default, all endpoints in a zone will activate the feature and start writing metrics to the InfluxDB HTTP API. In HA enabled scenarios, it is possible to set `enable_ha = true` in all feature configuration files. This allows each endpoint to calculate the feature authority, and only one endpoint actively writes metrics, the other endpoints pause the feature. When the cluster connection breaks at some point, the remaining endpoint(s) in that zone will automatically resume the feature. This built-in failover mechanism ensures that metrics are written even if the cluster fails. The recommended way of running InfluxDB in this scenario is a dedicated server where the InfluxDB HTTP API or Telegraf as Proxy are running. ### Elastic Stack Integration [Icingabeat](https://icinga.com/products/integrations/elastic/) is an Elastic Beat that fetches data from the Icinga 2 API and sends it either directly to [Elasticsearch](https://www.elastic.co/products/elasticsearch) or [Logstash](https://www.elastic.co/products/logstash). More integrations: * [Logstash output](https://icinga.com/products/integrations/elastic/) for the Icinga 2 API. * [Logstash Grok Pattern](https://icinga.com/products/integrations/elastic/) for Icinga 2 logs. #### Elasticsearch Writer This feature forwards check results, state changes and notification events to an [Elasticsearch](https://www.elastic.co/products/elasticsearch) installation over its HTTP API. The check results include parsed performance data metrics if enabled. > **Note** > > Elasticsearch 5.x or 6.x are required. This feature has been successfully tested with > Elasticsearch 5.6.7 and 6.3.1. Enable the feature and restart Icinga 2. ```bash icinga2 feature enable elasticsearch ``` The default configuration expects an Elasticsearch instance running on `localhost` on port `9200` and writes to an index called `icinga2`. More configuration details can be found [here](09-object-types.md#objecttype-elasticsearchwriter). #### Current Elasticsearch Schema The following event types are written to Elasticsearch: * icinga2.event.checkresult * icinga2.event.statechange * icinga2.event.notification Performance data metrics must be explicitly enabled with the `enable_send_perfdata` attribute. Metric values are stored like this: ``` check_result.perfdata..value ``` The following characters are escaped in perfdata labels: Character | Escaped character ------------|-------------------------- whitespace | _ \ | _ / | _ :: | . Note that perfdata labels may contain dots (`.`) allowing to add more subsequent levels inside the tree. `::` adds support for [multi performance labels](http://my-plugin.de/wiki/projects/check_multi/configuration/performance) and is therefore replaced by `.`. Icinga 2 automatically adds the following threshold metrics if existing: ``` check_result.perfdata..min check_result.perfdata..max check_result.perfdata..warn check_result.perfdata..crit ``` #### Elasticsearch in Cluster HA Zones The Elasticsearch feature supports [high availability](06-distributed-monitoring.md#distributed-monitoring-high-availability-features) in cluster zones since 2.11. By default, all endpoints in a zone will activate the feature and start writing events to the Elasticsearch HTTP API. In HA enabled scenarios, it is possible to set `enable_ha = true` in all feature configuration files. This allows each endpoint to calculate the feature authority, and only one endpoint actively writes events, the other endpoints pause the feature. When the cluster connection breaks at some point, the remaining endpoint(s) in that zone will automatically resume the feature. This built-in failover mechanism ensures that events are written even if the cluster fails. The recommended way of running Elasticsearch in this scenario is a dedicated server where you either have the Elasticsearch HTTP API, or a TLS secured HTTP proxy, or Logstash for additional filtering. ### Graylog Integration #### GELF Writer The `Graylog Extended Log Format` (short: [GELF](https://docs.graylog.org/en/latest/pages/gelf.html)) can be used to send application logs directly to a TCP socket. While it has been specified by the [Graylog](https://www.graylog.org) project as their [input resource standard](https://docs.graylog.org/en/latest/pages/sending_data.html), other tools such as [Logstash](https://www.elastic.co/products/logstash) also support `GELF` as [input type](https://www.elastic.co/guide/en/logstash/current/plugins-inputs-gelf.html). You can enable the feature using ```bash icinga2 feature enable gelf ``` By default the `GelfWriter` object expects the GELF receiver to listen at `127.0.0.1` on TCP port `12201`. The default `source` attribute is set to `icinga2`. You can customize that for your needs if required. Currently these events are processed: * Check results * State changes * Notifications #### Graylog/GELF in Cluster HA Zones The Gelf feature supports [high availability](06-distributed-monitoring.md#distributed-monitoring-high-availability-features) in cluster zones since 2.11. By default, all endpoints in a zone will activate the feature and start writing events to the Graylog HTTP API. In HA enabled scenarios, it is possible to set `enable_ha = true` in all feature configuration files. This allows each endpoint to calculate the feature authority, and only one endpoint actively writes events, the other endpoints pause the feature. When the cluster connection breaks at some point, the remaining endpoint(s) in that zone will automatically resume the feature. This built-in failover mechanism ensures that events are written even if the cluster fails. The recommended way of running Graylog in this scenario is a dedicated server where you have the Graylog HTTP API listening. ### OpenTSDB Writer While there are some OpenTSDB collector scripts and daemons like tcollector available for Icinga 1.x it's more reasonable to directly process the check and plugin performance in memory in Icinga 2. Once there are new metrics available, Icinga 2 will directly write them to the defined TSDB TCP socket. You can enable the feature using ```bash icinga2 feature enable opentsdb ``` By default the `OpenTsdbWriter` object expects the TSD to listen at `127.0.0.1` on port `4242`. The current default naming schema is: ``` icinga.host. icinga.service.. ``` for host and service checks. The tag `host` is always applied. Icinga also sends perfdata warning, critical, minimum and maximum threshold values to OpenTSDB. These are stored as new OpenTSDB metric names appended with `_warn`, `_crit`, `_min`, `_max`. Values are only stored when the corresponding threshold exists in Icinga's perfdata. Example: ``` icinga.service.. icinga.service..._warn icinga.service..._crit icinga.service..._min icinga.service..._max ``` To make sure Icinga 2 writes a valid metric into OpenTSDB some characters are replaced with `_` in the target name: ``` \ : (and space) ``` The resulting name in OpenTSDB might look like: ``` www-01 / http-cert / response time icinga.http_cert.response_time ``` In addition to the performance data retrieved from the check plugin, Icinga 2 sends internal check statistic data to OpenTSDB: metric | description -------------------|------------------------------------------ current_attempt | current check attempt max_check_attempts | maximum check attempts until the hard state is reached reachable | checked object is reachable downtime_depth | number of downtimes this object is in acknowledgement | whether the object is acknowledged or not execution_time | check execution time latency | check latency state | current state of the checked object state_type | 0=SOFT, 1=HARD state While reachable, state and state_type are metrics for the host or service the other metrics follow the current naming schema ``` icinga.check. ``` with the following tags tag | description --------|------------------------------------------ type | the check type, one of [host, service] host | hostname, the check ran on service | the service name (if type=service) > **Note** > > You might want to set the tsd.core.auto_create_metrics setting to `true` > in your opentsdb.conf configuration file. #### OpenTSDB Metric Prefix Functionality exists to modify the built in OpenTSDB metric names that the plugin writes to. By default this is `icinga.host` and `icinga.service.`. These prefixes can be modified as necessary to any arbitary string. The prefix configuration also supports Icinga macros, so if you rather use `` or any other variable instead of `` you may do so. To configure OpenTSDB metric name prefixes, create or modify the `host_template` and/or `service_template` blocks in the `opentsdb.conf` file, to add a `metric` definition. These modifications go hand in hand with the **OpenTSDB Custom Tag Support** detailed below, and more information around macro use can be found there. Additionally, using custom Metric Prefixes or your own macros in the prefix may be helpful if you are using the **OpenTSDB Generic Metric** functionality detailed below. An example configuration which includes prefix name modification: ``` object OpenTsdbWriter "opentsdb" { host = "127.0.0.1" port = 4242 host_template = { metric = "icinga.myhost" tags = { location = "$host.vars.location$" checkcommand = "$host.check_command$" } } service_template = { metric = "icinga.service.$service.check_command$" } } ``` The above configuration will output the following naming schema: ``` icinga.myhost. icinga.service.. ``` Note how `` is always appended in the default naming schema mode. #### OpenTSDB Generic Metric Naming Schema An alternate naming schema (`Generic Metrics`) is available where OpenTSDB metric names are more generic and do not include the Icinga perfdata label in the metric name. Instead, perfdata labels are stored in a tag `label` which is stored along with each perfdata value. This ultimately reduces the number of unique OpenTSDB metric names which may make querying aggregate data easier. This also allows you to store all perfdata values for a particular check inside one OpenTSDB metric name for each check. This alternate naming schema can be enabled by setting the following in the OpenTSDBWriter config: `enable_generic_metrics = true` > **Tip** > Consider using `Generic Metrics` along with the **OpenTSDB Metric Prefix** naming options > described above An example of this naming schema when compared to the default is: ``` icinga.host icinga.service. ``` > **Note** > Note how `` does not appear in the OpenTSDB metric name > when using `Generic Metrics`. Instead, a new tag `label` appears on each value written > to OpenTSDB which contains the perfdata label. #### Custom Tags In addition to the default tags listed above, it is possible to send your own custom tags with your data to OpenTSDB. Note that custom tags are sent **in addition** to the default hostname, type and service name tags. If you do not include this section in the config file, no custom tags will be included. Custom tags can be custom attributes or built in attributes. Consider a host object: ``` object Host "my-server1" { address = "10.0.0.1" check_command = "hostalive" vars.location = "Australia" } ``` and a service object: ``` object Service "ping" { host_name = "localhost" check_command = "my-ping" vars.ping_packets = 10 } ``` It is possible to send `vars.location` and `vars.ping_packets` along with performance data. Additionally, any other attribute can be sent as a tag, such as `check_command`. You can make use of the `host_template` and `service_template` blocks in the `opentsdb.conf` configuration file. An example OpenTSDB configuration file which makes use of custom tags: ``` object OpenTsdbWriter "opentsdb" { host = "127.0.0.1" port = 4242 host_template = { tags = { location = "$host.vars.location$" checkcommand = "$host.check_command$" } } service_template = { tags = { location = "$host.vars.location$" pingpackets = "$service.vars.ping_packets$" checkcommand = "$service.check_command$" } } } ``` Depending on what keyword the macro begins with, will determine what attributes are available in the macro context. The below table explains what attributes are available with links to each object type. start of macro | description ---------------|------------------------------------------ \$host...$ | Attributes available on a [Host object](09-object-types.md#objecttype-host) \$service...$ | Attributes available on a [Service object](09-object-types.md#objecttype-service) \$icinga...$ | Attributes available on the [IcingaApplication object](09-object-types.md#objecttype-icingaapplication) > **Note** > > Ensure you do not name your custom attributes with a dot in the name. > Dots located inside a macro tell the interpreter to expand a > dictionary. > > Do not do this in your object configuration: > > `vars["my.attribute"]` > > as you will be unable to reference `my.attribute` because it is not a > dictionary. > > Instead, use underscores or another character: > > `vars.my_attribute` or `vars["my_attribute"]` #### OpenTSDB in Cluster HA Zones The OpenTSDB feature supports [high availability](06-distributed-monitoring.md#distributed-monitoring-high-availability-features) in cluster zones since 2.11. By default, all endpoints in a zone will activate the feature and start writing events to the OpenTSDB listener. In HA enabled scenarios, it is possible to set `enable_ha = true` in all feature configuration files. This allows each endpoint to calculate the feature authority, and only one endpoint actively writes metrics, the other endpoints pause the feature. When the cluster connection breaks at some point, the remaining endpoint(s) in that zone will automatically resume the feature. This built-in failover mechanism ensures that metrics are written even if the cluster fails. The recommended way of running OpenTSDB in this scenario is a dedicated server where you have OpenTSDB running. ### Writing Performance Data Files PNP and Graphios use performance data collector daemons to fetch the current performance files for their backend updates. Therefore the Icinga 2 [PerfdataWriter](09-object-types.md#objecttype-perfdatawriter) feature allows you to define the output template format for host and services helped with Icinga 2 runtime vars. ``` host_format_template = "DATATYPE::HOSTPERFDATA\tTIMET::$icinga.timet$\tHOSTNAME::$host.name$\tHOSTPERFDATA::$host.perfdata$\tHOSTCHECKCOMMAND::$host.check_command$\tHOSTSTATE::$host.state$\tHOSTSTATETYPE::$host.state_type$" service_format_template = "DATATYPE::SERVICEPERFDATA\tTIMET::$icinga.timet$\tHOSTNAME::$host.name$\tSERVICEDESC::$service.name$\tSERVICEPERFDATA::$service.perfdata$\tSERVICECHECKCOMMAND::$service.check_command$\tHOSTSTATE::$host.state$\tHOSTSTATETYPE::$host.state_type$\tSERVICESTATE::$service.state$\tSERVICESTATETYPE::$service.state_type$" ``` The default templates are already provided with the Icinga 2 feature configuration which can be enabled using ```bash icinga2 feature enable perfdata ``` By default all performance data files are rotated in a 15 seconds interval into the `/var/spool/icinga2/perfdata/` directory as `host-perfdata.` and `service-perfdata.`. External collectors need to parse the rotated performance data files and then remove the processed files. #### Perfdata Files in Cluster HA Zones The Perfdata feature supports [high availability](06-distributed-monitoring.md#distributed-monitoring-high-availability-features) in cluster zones since 2.11. By default, all endpoints in a zone will activate the feature and start writing metrics to the local spool directory. In HA enabled scenarios, it is possible to set `enable_ha = true` in all feature configuration files. This allows each endpoint to calculate the feature authority, and only one endpoint actively writes metrics, the other endpoints pause the feature. When the cluster connection breaks at some point, the remaining endpoint(s) in that zone will automatically resume the feature. This built-in failover mechanism ensures that metrics are written even if the cluster fails. The recommended way of running Perfdata is to mount the perfdata spool directory via NFS on a central server where PNP with the NPCD collector is running on. ## Deprecated Features ### IDO Database (DB IDO) > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). The IDO (Icinga Data Output) feature for Icinga 2 takes care of exporting all configuration and status information into a database. The IDO database is used by Icinga Web 2 as data backend. You can either use a [MySQL](#ido-with-mysql) or [PostgreSQL](#ido-with-postgresql) database. #### IDO with MySQL ##### Install IDO Feature The next step is to install the `icinga2-ido-mysql` package using your distribution's package manager. ###### Debian / Ubuntu ```bash apt-get install icinga2-ido-mysql ``` !!! note The packages provide a database configuration wizard by default. You can skip the automated setup and install/upgrade the database manually if you prefer. ###### RHEL 8 ```bash dnf install icinga2-ido-mysql ``` ###### RHEL 7 ```bash yum install icinga2-ido-mysql ``` ###### SLES ```bash zypper install icinga2-ido-mysql ``` ###### Amazon Linux ```bash yum install icinga2-ido-mysql ``` ##### Set up MySQL database Set up a MySQL database for Icinga 2: ```bash # mysql -u root -p CREATE DATABASE icinga; GRANT ALTER, CREATE, SELECT, INSERT, UPDATE, DELETE, DROP, CREATE VIEW, INDEX, EXECUTE ON icinga.* TO 'icinga'@'localhost' IDENTIFIED BY 'icinga'; quit ``` Please note that the example above uses the very simple password 'icinga' (in `IDENTIFIED BY 'icinga'`). Please choose a better password for your installation. After creating the database you can import the Icinga 2 IDO schema using the following command. Enter the icinga password into the prompt when asked. ```bash mysql -u icinga -p icinga < /usr/share/icinga2-ido-mysql/schema/mysql.sql ``` ##### Enable the IDO MySQL feature The package provides a new configuration file that is installed in `/etc/icinga2/features-available/ido-mysql.conf`. You can update the database credentials in this file. All available attributes are explained in the [IdoMysqlConnection object](09-object-types.md#objecttype-idomysqlconnection) chapter. Enable the `ido-mysql` feature configuration file using the `icinga2` command: ```bash # icinga2 feature enable ido-mysql Module 'ido-mysql' was enabled. Make sure to restart Icinga 2 for these changes to take effect. ``` Restart Icinga 2. ```bash systemctl restart icinga2 ``` #### IDO with PostgreSQL ##### Install IDO Feature The next step is to install the `icinga2-ido-pgsql` package using your distribution's package manager. ###### Debian / Ubuntu ```bash apt-get install icinga2-ido-pgsql ``` !!! note Upstream Debian packages provide a database configuration wizard by default. You can skip the automated setup and install/upgrade the database manually if you prefer that. ###### RHEL 8 ```bash dnf install icinga2-ido-pgsql ``` ###### RHEL 7 ```bash yum install icinga2-ido-pgsql ``` ###### SLES ```bash zypper install icinga2-ido-pgsql ``` ###### Amazon Linux ```bash yum install icinga2-ido-pgsql ``` ##### Set up PostgreSQL database Set up a PostgreSQL database for Icinga 2: ```bash cd /tmp sudo -u postgres psql -c "CREATE ROLE icinga WITH LOGIN PASSWORD 'icinga'" sudo -u postgres createdb -O icinga -E UTF8 icinga ``` !!! note It is assumed here that your locale is set to utf-8, you may run into problems otherwise. Locate your `pg_hba.conf` configuration file and add the icinga user with `md5` as authentication method and restart the postgresql server. Common locations for `pg_hba.conf` are either `/etc/postgresql/*/main/pg_hba.conf` or `/var/lib/pgsql/data/pg_hba.conf`. ``` # icinga local icinga icinga md5 host icinga icinga 127.0.0.1/32 md5 host icinga icinga ::1/128 md5 # "local" is for Unix domain socket connections only local all all ident # IPv4 local connections: host all all 127.0.0.1/32 ident # IPv6 local connections: host all all ::1/128 ident ``` Restart PostgreSQL: ```bash systemctl restart postgresql ``` After creating the database and permissions you need to import the IDO database schema using the following command: ```bash export PGPASSWORD=icinga psql -U icinga -d icinga < /usr/share/icinga2-ido-pgsql/schema/pgsql.sql ``` ##### Enable the IDO PostgreSQL feature The package provides a new configuration file that is installed in `/etc/icinga2/features-available/ido-pgsql.conf`. You can update the database credentials in this file. All available attributes are explained in the [IdoPgsqlConnection object](09-object-types.md#objecttype-idopgsqlconnection) chapter. Enable the `ido-pgsql` feature configuration file using the `icinga2` command: ``` # icinga2 feature enable ido-pgsql Module 'ido-pgsql' was enabled. Make sure to restart Icinga 2 for these changes to take effect. ``` Restart Icinga 2. ```bash systemctl restart icinga2 ``` #### Configuration Details on the configuration can be found in the [IdoMysqlConnection](09-object-types.md#objecttype-idomysqlconnection) and [IdoPgsqlConnection](09-object-types.md#objecttype-idopgsqlconnection) object configuration documentation. #### DB IDO Health If the monitoring health indicator is critical in Icinga Web 2, you can use the following queries to manually check whether Icinga 2 is actually updating the IDO database. Icinga 2 writes its current status to the `icinga_programstatus` table every 10 seconds. The query below checks 60 seconds into the past which is a reasonable amount of time -- adjust it for your requirements. If the condition is not met, the query returns an empty result. > **Tip** > > Use [check plugins](05-service-monitoring.md#service-monitoring-plugins) to monitor the backend. Replace the `default` string with your instance name if different. Example for MySQL: ``` # mysql -u root -p icinga -e "SELECT status_update_time FROM icinga_programstatus ps JOIN icinga_instances i ON ps.instance_id=i.instance_id WHERE (UNIX_TIMESTAMP(ps.status_update_time) > UNIX_TIMESTAMP(NOW())-60) AND i.instance_name='default';" +---------------------+ | status_update_time | +---------------------+ | 2014-05-29 14:29:56 | +---------------------+ ``` Example for PostgreSQL: ``` # export PGPASSWORD=icinga; psql -U icinga -d icinga -c "SELECT ps.status_update_time FROM icinga_programstatus AS ps JOIN icinga_instances AS i ON ps.instance_id=i.instance_id WHERE ((SELECT extract(epoch from status_update_time) FROM icinga_programstatus) > (SELECT extract(epoch from now())-60)) AND i.instance_name='default'"; status_update_time ------------------------ 2014-05-29 15:11:38+02 (1 Zeile) ``` A detailed list on the available table attributes can be found in the [DB IDO Schema documentation](24-appendix.md#schema-db-ido). #### DB IDO in Cluster HA Zones The DB IDO feature supports [High Availability](06-distributed-monitoring.md#distributed-monitoring-high-availability-db-ido) in the Icinga 2 cluster. By default, both endpoints in a zone calculate the endpoint which activates the feature, the other endpoint automatically pauses it. If the cluster connection breaks at some point, the paused IDO feature automatically does a failover. You can disable this behaviour by setting `enable_ha = false` in both feature configuration files. #### DB IDO Cleanup Objects get deactivated when they are deleted from the configuration. This is visible with the `is_active` column in the `icinga_objects` table. Therefore all queries need to join this table and add `WHERE is_active=1` as condition. Deleted objects preserve their history table entries for later SLA reporting. Historical data isn't purged by default. You can enable the least kept data age inside the `cleanup` configuration attribute for the IDO features [IdoMysqlConnection](09-object-types.md#objecttype-idomysqlconnection) and [IdoPgsqlConnection](09-object-types.md#objecttype-idopgsqlconnection). Example if you prefer to keep notification history for 30 days: ``` cleanup = { notifications_age = 30d contactnotifications_age = 30d } ``` The historical tables are populated depending on the data `categories` specified. Some tables are empty by default. #### DB IDO Tuning As with any application database, there are ways to optimize and tune the database performance. General tips for performance tuning: * [MariaDB KB](https://mariadb.com/kb/en/library/optimization-and-tuning/) * [PostgreSQL Wiki](https://wiki.postgresql.org/wiki/Performance_Optimization) Re-creation of indexes, changed column values, etc. will increase the database size. Ensure to add health checks for this, and monitor the trend in your Grafana dashboards. In order to optimize the tables, there are different approaches. Always keep in mind to have a current backup and schedule maintenance downtime for these kind of tasks! MySQL: ``` mariadb> OPTIMIZE TABLE icinga_statehistory; ``` > **Important** > > Tables might not support optimization at runtime. This can take a **long** time. > > `Table does not support optimize, doing recreate + analyze instead`. If you want to optimize all tables in a specified database, there is a script called `mysqlcheck`. This also allows to repair broken tables in the case of emergency. ```bash mysqlcheck --optimize icinga ``` PostgreSQL: ``` icinga=# vacuum; VACUUM ``` > **Note** > > Don't use `VACUUM FULL` as this has a severe impact on performance. ### Compat Log Files > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). The Icinga 1.x log format is considered being the `Compat Log` in Icinga 2 provided with the `CompatLogger` object. These logs are used for informational representation in external web interfaces parsing the logs, but also to generate SLA reports and trends. The [Livestatus](14-features.md#setting-up-livestatus) feature uses these logs for answering queries to historical tables. The `CompatLogger` object can be enabled with ```bash icinga2 feature enable compatlog ``` By default, the Icinga 1.x log file called `icinga.log` is located in `/var/log/icinga2/compat`. Rotated log files are moved into `var/log/icinga2/compat/archives`. ### External Command Pipe > **Note** > > Please use the [REST API](12-icinga2-api.md#icinga2-api) as modern and secure alternative > for external actions. > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). Icinga 2 provides an external command pipe for processing commands triggering specific actions (for example rescheduling a service check through the web interface). In order to enable the `ExternalCommandListener` configuration use the following command and restart Icinga 2 afterwards: ```bash icinga2 feature enable command ``` Icinga 2 creates the command pipe file as `/var/run/icinga2/cmd/icinga2.cmd` using the default configuration. Web interfaces and other Icinga addons are able to send commands to Icinga 2 through the external command pipe, for example for rescheduling a forced service check: ``` # /bin/echo "[`date +%s`] SCHEDULE_FORCED_SVC_CHECK;localhost;ping4;`date +%s`" >> /var/run/icinga2/cmd/icinga2.cmd # tail -f /var/log/messages Oct 17 15:01:25 icinga-server icinga2: Executing external command: [1382014885] SCHEDULE_FORCED_SVC_CHECK;localhost;ping4;1382014885 Oct 17 15:01:25 icinga-server icinga2: Rescheduling next check for service 'ping4' ``` A list of currently supported external commands can be found [here](24-appendix.md#external-commands-list-detail). Detailed information on the commands and their required parameters can be found on the [Icinga 1.x documentation](https://docs.icinga.com/latest/en/extcommands2.html). ### Livestatus > **Note** > > This feature is DEPRECATED and may be removed in future releases. > Check the [roadmap](https://github.com/Icinga/icinga2/milestones). The [MK Livestatus](https://mathias-kettner.de/checkmk_livestatus.html) project implements a query protocol that lets users query their Icinga instance for status information. It can also be used to send commands. The Livestatus component that is distributed as part of Icinga 2 is a re-implementation of the Livestatus protocol which is compatible with MK Livestatus. > **Tip** > > Only install the Livestatus feature if your web interface or addon requires > you to do so. > [Icinga Web 2](https://icinga.com/docs/icinga-web-2/latest/doc/02-Installation/) does not need > Livestatus. Details on the available tables and attributes with Icinga 2 can be found in the [Livestatus Schema](24-appendix.md#schema-livestatus) section. You can enable Livestatus using icinga2 feature enable: ```bash icinga2 feature enable livestatus ``` After that you will have to restart Icinga 2: ```bash systemctl restart icinga2 ``` By default the Livestatus socket is available in `/var/run/icinga2/cmd/livestatus`. In order for queries and commands to work you will need to add your query user (e.g. your web server) to the `icingacmd` group: ```bash usermod -a -G icingacmd www-data ``` The Debian packages use `nagios` as the user and group name. Make sure to change `icingacmd` to `nagios` if you're using Debian. Change `www-data` to the user you're using to run queries. In order to use the historical tables provided by the livestatus feature (for example, the `log` table) you need to have the `CompatLogger` feature enabled. By default these logs are expected to be in `/var/log/icinga2/compat`. A different path can be set using the `compat_log_path` configuration attribute. ```bash icinga2 feature enable compatlog ``` #### Livestatus Sockets Other to the Icinga 1.x Addon, Icinga 2 supports two socket types * Unix socket (default) * TCP socket Details on the configuration can be found in the [LivestatusListener](09-object-types.md#objecttype-livestatuslistener) object configuration. #### Livestatus GET Queries > **Note** > > All Livestatus queries require an additional empty line as query end identifier. > The `nc` tool (`netcat`) provides the `-U` parameter to communicate using > a unix socket. There also is a Perl module available in CPAN for accessing the Livestatus socket programmatically: [Monitoring::Livestatus](https://metacpan.org/release/NIERLEIN/Monitoring-Livestatus-0.74) Example using the unix socket: ``` # echo -e "GET services\n" | /usr/bin/nc -U /var/run/icinga2/cmd/livestatus Example using the tcp socket listening on port `6558`: # echo -e 'GET services\n' | netcat 127.0.0.1 6558 # cat servicegroups < A list of available external commands and their parameters can be found [here](24-appendix.md#external-commands-list-detail) ```bash echo -e 'COMMAND ' | netcat 127.0.0.1 6558 ``` #### Livestatus Filters and, or, negate Operator | Negate | Description ----------|----------|------------- = | != | Equality ~ | !~ | Regex match =~ | !=~ | Equality ignoring case ~~ | !~~ | Regex ignoring case < | | Less than > | | Greater than <= | | Less than or equal >= | | Greater than or equal #### Livestatus Stats Schema: "Stats: aggregatefunction aggregateattribute" Aggregate Function | Description -------------------|-------------- sum |   min |   max |   avg | sum / count std | standard deviation suminv | sum (1 / value) avginv | suminv / count count | ordinary default for any stats query if not aggregate function defined Example: ``` GET hosts Filter: has_been_checked = 1 Filter: check_type = 0 Stats: sum execution_time Stats: sum latency Stats: sum percent_state_change Stats: min execution_time Stats: min latency Stats: min percent_state_change Stats: max execution_time Stats: max latency Stats: max percent_state_change OutputFormat: json ResponseHeader: fixed16 ``` #### Livestatus Output * CSV CSV output uses two levels of array separators: The members array separator is a comma (1st level) while extra info and host|service relation separator is a pipe (2nd level). Separators can be set using ASCII codes like: ``` Separators: 10 59 44 124 ``` * JSON Default separators. #### Livestatus Error Codes Code | Description ----------|-------------- 200 | OK 404 | Table does not exist 452 | Exception on query #### Livestatus Tables Table | Join |Description --------------|-----------|---------------------------- hosts |   | host config and status attributes, services counter hostgroups |   | hostgroup config, status attributes and host/service counters services | hosts | service config and status attributes servicegroups |   | servicegroup config, status attributes and service counters contacts |   | contact config and status attributes contactgroups |   | contact config, members commands |   | command name and line status |   | programstatus, config and stats comments | services | status attributes downtimes | services | status attributes timeperiods |   | name and is inside flag endpoints |   | config and status attributes log | services, hosts, contacts, commands | parses [compatlog](09-object-types.md#objecttype-compatlogger) and shows log attributes statehist | hosts, services | parses [compatlog](09-object-types.md#objecttype-compatlogger) and aggregates state change attributes hostsbygroup | hostgroups | host attributes grouped by hostgroup and its attributes servicesbygroup | servicegroups | service attributes grouped by servicegroup and its attributes servicesbyhostgroup | hostgroups | service attributes grouped by hostgroup and its attributes The `commands` table is populated with `CheckCommand`, `EventCommand` and `NotificationCommand` objects. A detailed list on the available table attributes can be found in the [Livestatus Schema documentation](24-appendix.md#schema-livestatus). icinga2-2.14.6/doc/15-troubleshooting.md000066400000000000000000002466301501332562400176750ustar00rootroot00000000000000# Icinga 2 Troubleshooting ## Required Information Please ensure to provide any detail which may help reproduce and understand your issue. Whether you ask on the [community channels](https://community.icinga.com) or you create an issue at [GitHub](https://github.com/Icinga), make sure that others can follow your explanations. If necessary, draw a picture and attach it for better illustration. This is especially helpful if you are troubleshooting a distributed setup. We've come around many community questions and compiled this list. Add your own findings and details please. * Describe the expected behavior in your own words. * Describe the actual behavior in one or two sentences. * Ensure to provide general information such as: * How was Icinga 2 installed (and which repository in case) and which distribution are you using * `icinga2 --version` * `icinga2 feature list` * `icinga2 daemon -C` * [Icinga Web 2](https://icinga.com/docs/icinga-web/latest/) version (screenshot from System - About) * Icinga Web 2 modules e.g. the Icinga Director (optional) * Configuration insights: * Provide complete configuration snippets explaining your problem in detail * Your [icinga2.conf](04-configuration.md#icinga2-conf) file * If you run multiple Icinga 2 instances, the [zones.conf](04-configuration.md#zones-conf) file (or `icinga2 object list --type Endpoint` and `icinga2 object list --type Zone`) from all affected nodes. * Logs * Relevant output from your main and [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) in `/var/log/icinga2`. Please add step-by-step explanations with timestamps if required. * The newest Icinga 2 crash log if relevant, located in `/var/log/icinga2/crash` * Additional details * If the check command failed, what's the output of your manual plugin tests? * In case of [debugging](21-development.md#development) Icinga 2, the full back traces and outputs ## Analyze your Environment There are many components involved on a server running Icinga 2. When you analyze a problem, keep in mind that basic system administration knowledge is also key to identify bottlenecks and issues. > **Tip** > > [Monitor Icinga 2](08-advanced-topics.md#monitoring-icinga) and use the hints for further analysis. * Analyze the system's performance and dentify bottlenecks and issues. * Collect details about all applications (e.g. Icinga 2, MySQL, Apache, Graphite, Elastic, etc.). * If data is exchanged via network (e.g. central MySQL cluster) ensure to monitor the bandwidth capabilities too. * Add graphs from Grafana or Graphite as screenshots to your issue description Install tools which help you to do so. Opinions differ, let us know if you have any additions here! ### Analyse your Linux/Unix Environment [htop](https://hisham.hm/htop/) is a better replacement for `top` and helps to analyze processes interactively. ```bash yum install htop apt-get install htop ``` If you are for example experiencing performance issues, open `htop` and take a screenshot. Add it to your question and/or bug report. Analyse disk I/O performance in Grafana, take a screenshot and obfuscate any sensitive details. Attach it when posting a question to the community channels. The [sysstat](https://github.com/sysstat/sysstat) package provides a number of tools to analyze the performance on Linux. On FreeBSD you could use `systat` for example. ```bash yum install sysstat apt-get install sysstat ``` Example for `vmstat` (summary of memory, processes, etc.): ```bash # summary vmstat -s # print timestamps, format in MB, stats every 1 second, 5 times vmstat -t -S M 1 5 ``` Example for `iostat`: ```bash watch -n 1 iostat ``` Example for `sar`: ```bash sar # cpu sar -r # ram sar -q # load avg sar -b # I/O ``` `sysstat` also provides the `iostat` binary. On FreeBSD you could use `systat` for example. If you are missing checks and metrics found in your analysis, add them to your monitoring! ### Analyze your Windows Environment A good tip for Windows are the tools found inside the [Sysinternals Suite](https://technet.microsoft.com/en-us/sysinternals/bb842062.aspx). You can also start `perfmon` and analyze specific performance counters. Keep notes which could be important for your monitoring, and add service checks later on. > **Tip** > > Use an administrative Powershell to gain more insights. ``` cd C:\ProgramData\icinga2\var\log\icinga2 Get-Content .\icinga2.log -tail 10 -wait ``` ## Enable Debug Output ### Enable Debug Output on Linux/Unix Enable the `debuglog` feature: ```bash icinga2 feature enable debuglog service icinga2 restart ``` The debug log file can be found in `/var/log/icinga2/debug.log`. You can tail the log files with an administrative shell: ```bash cd /var/log/icinga2 tail -f debug.log ``` Alternatively you may run Icinga 2 in the foreground with debugging enabled. Specify the console log severity as an additional parameter argument to `-x`. ```bash /usr/sbin/icinga2 daemon -x notice ``` The [log severity](09-object-types.md#objecttype-filelogger) can be one of `critical`, `warning`, `information`, `notice` and `debug`. ### Enable Debug Output on Windows Open a Powershell with administrative privileges and enable the debug log feature. ``` C:\> cd C:\Program Files\ICINGA2\sbin C:\Program Files\ICINGA2\sbin> .\icinga2.exe feature enable debuglog ``` Ensure that the Icinga 2 service already writes the main log into `C:\ProgramData\icinga2\var\log\icinga2`. Restart the Icinga 2 service in an administrative Powershell and open the newly created `debug.log` file. ``` C:\> Restart-Service icinga2 C:\> Get-Service icinga2 ``` You can tail the log files with an administrative Powershell: ``` C:\> cd C:\ProgramData\icinga2\var\log\icinga2 C:\ProgramData\icinga2\var\log\icinga2> Get-Content .\debug.log -tail 10 -wait ``` ### Enable/Disable Debug Output on the fly The `debuglog` feature can also be created and deleted at runtime without having to restart Icinga 2. Technically, this is possible because this feature is a [FileLogger](09-object-types.md#objecttype-filelogger) that can be managed through the [API](12-icinga2-api.md#icinga2-api-config-objects). This is a good alternative to `icinga2 feature enable debuglog` as object creation/deletion via API happens immediately and requires no restart. The above matters in setups large enough for the reload to take a while. Especially these produce a lot of debug log output until disabled again. !!! info In case of [an HA zone](06-distributed-monitoring.md#distributed-monitoring-scenarios-ha-master-agents), the following API examples toggle the feature on both nodes. #### Enable Debug Output on the fly ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X PUT 'https://localhost:5665/v1/objects/fileloggers/on-the-fly-debug-file' \ -d '{ "attrs": { "severity": "debug", "path": "/var/log/icinga2/on-the-fly-debug.log" }, "pretty": true }' ``` ```json { "results": [ { "code": 200.0, "status": "Object was created." } ] } ``` #### Disable Debug Output on the fly This works only for debug loggers enabled on the fly as above! ```bash curl -k -s -S -i -u root:icinga -H 'Accept: application/json' \ -X DELETE 'https://localhost:5665/v1/objects/fileloggers/on-the-fly-debug-file?pretty=1' ``` ```json { "results": [ { "code": 200.0, "name": "on-the-fly-debug-file", "status": "Object was deleted.", "type": "FileLogger" } ] } ``` ## Icinga starts/restarts/reloads very slowly ### Try swapping out the allocator Icinga performs a lot of memory allocations, especially during startup. Swapping out the allocator may increase the startup performance. The following instructions assume you run Linux and systemd. On RHEL or derivates add the EPEL repository first (if not already done). Let your package manager search for package names containing "jemalloc". Pick preferably one named "libjemalloc" followed by a number, just "jemalloc" otherwise, and install it. Run `ldconfig -p |grep libjemalloc`. It should print something similar to: ``` libjemalloc.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libjemalloc.so.2 ``` I.e. a relative file name followed by an absolute one. Remember the latter. Measure how long Icinga needs to load its config without and with libjemalloc: ```bash time icinga2 daemon -C time env LD_PRELOAD=/lib/x86_64-linux-gnu/libjemalloc.so.2 icinga2 daemon -C ``` Replace `/lib/x86_64-linux-gnu/libjemalloc.so.2` with the absolute path you actually got from `ldconfig -p`! Please do us a favor and share your results [with us](https://community.icinga.com/t/icinga-reloads-config-slowly-try-jemalloc/11032). If it's faster with libjemalloc, do the following to persist the change. Run `systemctl edit icinga2.service`. This will open an editor. Add the following, save the file and close the editor. ``` [Service] Environment=LD_PRELOAD=/lib/x86_64-linux-gnu/libjemalloc.so.2 ``` Replace `/lib/x86_64-linux-gnu/libjemalloc.so.2` with the absolute path you actually got from `ldconfig -p`! Restart Icinga. Verify whether your changes took effect and enjoy the speed: ``` # lsof -p `cat /var/run/icinga2/icinga2.pid` |grep libjemalloc icinga2 7764 nagios mem REG 8,5 744776 2631636 /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 # ``` ### Optimise apply rules and group assign conditions #### Remove actually unused apply rules If `icinga2 daemon -C` warns you like shown below and the respective apply rule should indeed create no objects, consider removing it. At least comment it out. ``` [...] warning/ApplyRule: Apply rule '...' (...) for type '...' does not match anywhere! ``` In Director you can't comment out anything as in Icinga DSL, but you can disable apply rules (temporarily or permanently). Same for `assign where` conditions in groups. In this case removing just the `assign where` line(s) is enough if you'd like to keep the group itself. #### Avoid creating single objects via apply rules If possible, replace constructs like the immediately following with the below one. ``` apply Service "syspatch" { // ... assign where host.name == "firewall" } ``` ``` object Service "syspatch" { // ... host_name = "firewall" } ``` This way Icinga won't have to evaluate `host.name == "firewall"` for all of your hosts. At least upgrade to Icinga v2.13.6+ which optimizes apply rules as shown above. Group membership assign conditions aren't optimized by v2.13.6. But they can just be replaced with constructs like this one: ``` object Host "firewall" { // ... groups = [ "OpenBSD hosts" ] } ``` #### Reduce `assign where` filter complexity If neither removals, nor flat objects, nor Icinga v2.13.6+ are an option, at least keep the filter as simple as possible. The less complex an `assign where` filter is, the more time Icinga saves while loading its config. **I.e. the following is a bad example.** ``` assign where ( match("MySQL*", host.name) || match("Maria*", host.name) || match("Postgre*", host.name) || match("Redis*", host.name) || match("Elastic*", host.name) ) ``` Preferably only a single custom var is checked. Ideally just whether it's set. (`assign where host.vars.db` or "is true (or set)" operator in Director.) Otherwise, prefer `==` over `match()`. (In Director avoid `*` wildcards.) If you're using the Director, you can create such a custom var automatically and pattern-based via a _Sync rule_. Navigate to its _Properties_ and add a new property: * Destination Field: Custom variable (vars.) * Custom variable: e.g. `db` * Source Column: Custom expression * Source Expression: e.g. `true` * Set based on filter: Yes * Filter Expression: e.g. `host=MySQL*|host=Maria*|host=Postgre*|host=Redis*|host=Elastic*` * Merge Policy: replace At least reorder operands of an `&&` chain so that a mismatch terminates the whole chain as soon as possible. E.g. prefer `assign where host.vars.production && match("MySQL*", host.name)`, not `assign where match("MySQL*", host.name) && host.vars.production`. For all test hosts `host.vars.production` will be false and terminate the `&&` rather than also evaluating `match("MySQL*", host.name)`. ### Try reducing concurrency (threads) !!! note This section applies rather to systems with more than eight CPU cores. In case of less consider upgrading your hardware instead. Yes, reducing and not increasing. By default, Icinga 2 already starts as many threads as there are CPU cores according to the OS (unaware of SMT aka Hyper-Threading). So there's no point in increasing as Icinga would not gain additional CPU time. But more threads also require more synchronization between them. This may outweigh the CPU time gain and even worsen the performance. So reducing may indeed help or at least save CPU time and power at no cost. Start with benchmarking your Icinga 2 config with `time icinga2 daemon -C` on the node in question. The results will be most accurate during normal operation, i.e. while Icinga is running, but not reloading (e.g. due to config deployments). Icinga accepts the argument `-DConfiguration.Concurrency=` with the number (of threads) immediately after the "=". Start with 8 and finish with the number of CPU cores. Write down the times. I.e.: * `time icinga2 daemon -C -DConfiguration.Concurrency=8` * `time icinga2 daemon -C -DConfiguration.Concurrency=10` * `time icinga2 daemon -C -DConfiguration.Concurrency=12` * ... If significantly less threads than CPU cores significantly reduce the time (reported as "real") Icinga 2 needs to load its configuration, pick the number with the best time and persist it in your init daemon. In case of systemd copy the `ExecStart=` line from output of `systemctl cat icinga2.service` first. Next, run `systemctl edit icinga2.service`. This will open an editor. Add `[Service]` (if not already present) and the copied `ExecStart=` line. Append `-DConfiguration.Concurrency=` and the chosen number so that the result looks like this: ``` [Service] ExecStart=/usr/sbin/icinga2 daemon --close-stdio -e ${ICINGA2_ERROR_LOG} -DConfiguration.Concurrency=42 ``` Save the file and close the editor. Restart Icinga. Finally verify whether your changes took effect and enjoy the speed. ## Configuration Troubleshooting ### List Configuration Objects The `icinga2 object list` CLI command can be used to list all configuration objects and their attributes. The tool also shows where each of the attributes was modified. > **Tip** > > Use the Icinga 2 API to access [config objects at runtime](12-icinga2-api.md#icinga2-api-config-objects) directly. That way you can also identify which objects have been created from your [apply rules](17-language-reference.md#apply). ``` # icinga2 object list Object 'localhost!ssh' of type 'Service': * __name = 'localhost!ssh' * check_command = 'ssh' % = modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 5:3-5:23 * check_interval = 60 % = modified in '/etc/icinga2/conf.d/templates.conf', lines 24:3-24:21 * host_name = 'localhost' % = modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 4:3-4:25 * max_check_attempts = 3 % = modified in '/etc/icinga2/conf.d/templates.conf', lines 23:3-23:24 * name = 'ssh' * retry_interval = 30 % = modified in '/etc/icinga2/conf.d/templates.conf', lines 25:3-25:22 * templates = [ 'ssh', 'generic-service' ] % += modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 1:0-7:1 % += modified in '/etc/icinga2/conf.d/templates.conf', lines 22:1-26:1 * type = 'Service' * vars % += modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 6:3-6:19 * sla = '24x7' % = modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 6:3-6:19 [...] ``` On Windows, use an administrative Powershell: ``` C:\> cd C:\Program Files\ICINGA2\sbin C:\Program Files\ICINGA2\sbin> .\icinga2.exe object list ``` You can also filter by name and type: ``` # icinga2 object list --name *ssh* --type Service Object 'localhost!ssh' of type 'Service': * __name = 'localhost!ssh' * check_command = 'ssh' % = modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 5:3-5:23 * check_interval = 60 % = modified in '/etc/icinga2/conf.d/templates.conf', lines 24:3-24:21 * host_name = 'localhost' % = modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 4:3-4:25 * max_check_attempts = 3 % = modified in '/etc/icinga2/conf.d/templates.conf', lines 23:3-23:24 * name = 'ssh' * retry_interval = 30 % = modified in '/etc/icinga2/conf.d/templates.conf', lines 25:3-25:22 * templates = [ 'ssh', 'generic-service' ] % += modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 1:0-7:1 % += modified in '/etc/icinga2/conf.d/templates.conf', lines 22:1-26:1 * type = 'Service' * vars % += modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 6:3-6:19 * sla = '24x7' % = modified in '/etc/icinga2/conf.d/hosts/localhost/ssh.conf', lines 6:3-6:19 Found 1 Service objects. [2014-10-15 14:27:19 +0200] information/cli: Parsed 175 objects. ``` Configuration modifications are not immediately updated. Furthermore there is a known issue with [group assign expressions](17-language-reference.md#group-assign) which are not reflected in the host object output. You need to `icinga2 daemon -C --dump-objects` in order to update the `icinga2.debug` cache file. ### Apply rules do not match You can analyze apply rules and matching objects by using the [script debugger](20-script-debugger.md#script-debugger). ### Where are the check command definitions? Icinga 2 features a number of built-in [check command definitions](10-icinga-template-library.md#icinga-template-library) which are included with ``` include include ``` in the [icinga2.conf](04-configuration.md#icinga2-conf) configuration file. These files are not considered configuration files and will be overridden on upgrade, so please send modifications as proposed patches upstream. The default include path is set to `/usr/share/icinga2/includes` with the constant `IncludeConfDir`. You should add your own command definitions to a new file in `conf.d/` called `commands.conf` or similar. ### Configuration is ignored * Make sure that the line(s) are not [commented out](17-language-reference.md#comments) (starting with `//` or `#`, or encapsulated by `/* ... */`). * Is the configuration file included in [icinga2.conf](04-configuration.md#icinga2-conf)? Run the [configuration validation](11-cli-commands.md#config-validation) and add `notice` as log severity. Search for the file which should be included i.e. using the `grep` CLI command. ```bash icinga2 daemon -C -x notice | grep command ``` ### Configuration attributes are inherited from Icinga 2 allows you to import templates using the [import](17-language-reference.md#template-imports) keyword. If these templates contain additional attributes, your objects will automatically inherit them. You can override or modify these attributes in the current object. The [object list](15-troubleshooting.md#troubleshooting-list-configuration-objects) CLI command allows you to verify the attribute origin. ### Configuration Value with Single Dollar Sign In case your configuration validation fails with a missing closing dollar sign error message, you did not properly escape the single dollar sign preventing its usage as [runtime macro](03-monitoring-basics.md#runtime-macros). ``` critical/config: Error: Validation failed for Object 'ping4' (Type: 'Service') at /etc/icinga2/zones.d/global-templates/windows.conf:24: Closing $ not found in macro format string 'top-syntax=${list}'. ``` Correct the custom variable value to ``` "top-syntax=$${list}" ``` ## Checks Troubleshooting ### Executed Command for Checks * Use the Icinga 2 API to [query](12-icinga2-api.md#icinga2-api-config-objects-query) host/service objects for their check result containing the executed shell command. * Use the Icinga 2 [console cli command](11-cli-commands.md#cli-command-console) to fetch the checkable object, its check result and the executed shell command. * Alternatively enable the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) and look for the executed command. Example for a service object query using a [regex match](18-library-reference.md#global-functions-regex) on the name: ``` $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5665/v1/objects/services' \ -d '{ "filter": "regex(pattern, service.name)", "filter_vars": { "pattern": "^http" }, "attrs": [ "__name", "last_check_result" ], "pretty": true }' { "results": [ { "attrs": { "__name": "example.localdomain!http", "last_check_result": { "active": true, "check_source": "example.localdomain", "command": [ "/usr/local/sbin/check_http", "-I", "127.0.0.1", "-u", "/" ], ... } }, "joins": {}, "meta": {}, "name": "example.localdomain!http", "type": "Service" } ] } ``` Alternatively when using the Director, navigate into the Service Detail View in Icinga Web and pick `Inspect` to query the details. Example for using the `icinga2 console` CLI command evaluation functionality: ``` $ ICINGA2_API_PASSWORD=icinga icinga2 console --connect 'https://root@localhost:5665/' \ --eval 'get_service("example.localdomain", "http").last_check_result.command' | python -m json.tool [ "/usr/local/sbin/check_http", "-I", "127.0.0.1", "-u", "/" ] ``` Example for searching the debug log: ```bash icinga2 feature enable debuglog systemctl restart icinga2 tail -f /var/log/icinga2/debug.log | grep "notice/Process" ``` ### Checks are not executed * First off, decide whether the checks are executed locally, or remote in a distributed setup. If the master does not receive check results from the satellite, move your analysis to the satellite and verify why the checks are not executed there. * Check the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) to see if the check command gets executed. * Verify that failed dependencies do not prevent command execution. * Make sure that the plugin is executable by the Icinga 2 user (run a manual test). * Make sure the [checker](11-cli-commands.md#enable-features) feature is enabled. * Use the Icinga 2 API [event streams](12-icinga2-api.md#icinga2-api-event-streams) to receive live check result streams. Test a plugin as icinga user. ```bash sudo -u icinga /usr/lib/nagios/plugins/check_ping -4 -H 127.0.0.1 -c 5000,100% -w 3000,80% ``` > **Note** > > **Never test plugins as root, but the icinga daemon user.** The environment and permissions differ. > > Also, the daemon user **does not** spawn a terminal shell (Bash, etc.) so it won't read anything from .bashrc > and variants. The Icinga daemon only relies on sysconfig environment variables being set. Enable the checker feature. ``` # icinga2 feature enable checker The feature 'checker' is already enabled. ``` Fetch all check result events matching the `event.service` name `random`: ```bash curl -k -s -u root:icinga -H 'Accept: application/json' -X POST \ 'https://localhost:5665/v1/events?queue=debugchecks&types=CheckResult&filter=match%28%22random*%22,event.service%29' ``` ### Analyze Check Source Sometimes checks are not executed on the remote host, but on the master and so on. This could lead into unwanted results or NOT-OK states. The `check_source` attribute is the best indication where a check command was actually executed. This could be a satellite with synced configuration or a client as remote command bridge -- both will return the check source as where the plugin is called. Example for retrieving the check source from all `disk` services using a [regex match](18-library-reference.md#global-functions-regex) on the name: ``` $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5665/v1/objects/services' \ -d '{ "filter": "regex(pattern, service.name)", "filter_vars": { "pattern": "^disk" }, "attrs": [ "__name", "last_check_result" ], "pretty": true }' { "results": [ { "attrs": { "__name": "icinga2-agent1.localdomain!disk", "last_check_result": { "active": true, "check_source": "icinga2-agent1.localdomain", ... } }, "joins": {}, "meta": {}, "name": "icinga2-agent1.localdomain!disk", "type": "Service" } ] } ``` Alternatively when using the Director, navigate into the Service Detail View in Icinga Web and pick `Inspect` to query the details. Example with the debug console: ``` $ ICINGA2_API_PASSWORD=icinga icinga2 console --connect 'https://root@localhost:5665/' \ --eval 'get_service("icinga2-agent1.localdomain", "disk").last_check_result.check_source' | python -m json.tool "icinga2-agent1.localdomain" ``` ### NSClient++ Check Errors with nscp-local The [nscp-local](10-icinga-template-library.md#nscp-check-local) CheckCommand object definitions call the local `nscp.exe` command. If a Windows client service check fails to find the `nscp.exe` command, the log output would look like this: ``` Command ".\nscp.exe" "client" "-a" "drive=d" "-a" "show-all" "-b" "-q" "check_drivesize" failed to execute: 2, "The system cannot find the file specified." ``` or ``` Command ". scp.exe" "client" "-a" "drive=d" "-a" "show-all" "-b" "-q" "check_drivesize" failed to execute: 2, "The system cannot find the file specified." ``` The above actually prints `.\\nscp.exe` where the escaped `\n` character gets interpreted as new line. Both errors lead to the assumption that the `NscpPath` constant is empty or set to a `.` character. This could mean the following: * The command is **not executed on the Windows client**. Check the [check_source](15-troubleshooting.md#checks-check-source) attribute from the check result. * You are using an outdated NSClient++ version (0.3.x or 0.4.x) which is not compatible with Icinga 2. * You are using a custom NSClient++ installer which does not register the correct GUID for NSClient++ More troubleshooting: Retrieve the `NscpPath` constant on your Windows client: ``` C:\Program Files\ICINGA2\sbin\icinga2.exe variable get NscpPath ``` If the variable is returned empty, manually test how Icinga 2 would resolve its path (this can be found inside the ITL): ``` C:\Program Files\ICINGA2\sbin\icinga2.exe console --eval "dirname(msi_get_component_path(\"{5C45463A-4AE9-4325-96DB-6E239C034F93}\"))" ``` If this command does not return anything, NSClient++ is not properly installed. Verify that inside the `Programs and Features` (`appwiz.cpl`) control panel. ### Check Thresholds Not Applied This could happen with [clients as command endpoint execution](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint). If you have for example a client host `icinga2-agent1.localdomain` and a service `disk` check defined on the master, the warning and critical thresholds are sometimes to applied and unwanted notification alerts are raised. This happens because the client itself includes a host object with its `NodeName` and a basic set of checks in the [conf.d](04-configuration.md#conf-d) directory, i.e. `disk` with the default thresholds. Clients which have the `checker` feature enabled will attempt to execute checks for local services and send their results back to the master. If you now have the same host and service objects on the master you will receive wrong check results from the client. Solution: * Disable the `checker` feature on clients: `icinga2 feature disable checker`. * Remove the inclusion of [conf.d](04-configuration.md#conf-d) as suggested in the [client setup docs](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint). ### Check Fork Errors Newer versions of systemd on Linux limit spawned processes for services. * v227 introduces the `TasksMax` setting to units which allows to specify the spawned process limit. * v228 adds `DefaultTasksMax` in the global `systemd-system.conf` with a default setting of 512 processes. * v231 changes the default value to 15% This can cause problems with Icinga 2 in large environments with many commands executed in parallel starting with systemd v228. Some distributions also may have changed the defaults. The error message could look like this: ``` 2017-01-12T11:55:40.742685+01:00 icinga2-master1 kernel: [65567.582895] cgroup: fork rejected by pids controller in /system.slice/icinga2.service ``` In order to solve the problem, increase the value for `DefaultTasksMax` or set it to `infinity`. ```bash mkdir /etc/systemd/system/icinga2.service.d cat >/etc/systemd/system/icinga2.service.d/limits.conf < Usually Icinga 2 is a mission critical part of infrastructure and should be online at all times. In case of a recoverable crash (e.g. OOM) you may want to restart Icinga 2 automatically. With systemd it is as easy as overriding some settings of the Icinga 2 systemd service by creating `/etc/systemd/system/icinga2.service.d/override.conf` with the following content: ``` [Service] Restart=always RestartSec=1 StartLimitInterval=10 StartLimitBurst=3 ``` Using the watchdog can also help with monitoring Icinga 2, to activate and use it add the following to the override: ``` WatchdogSec=30s ``` This way systemd will kill Icinga 2 if it does not notify for over 30 seconds. A timeout of less than 10 seconds is not recommended. When the watchdog is activated, `Restart=` can be set to `watchdog` to restart Icinga 2 in the case of a watchdog timeout. Run `systemctl daemon-reload && systemctl restart icinga2` to apply the changes. Now systemd will always try to restart Icinga 2 (except if you run `systemctl stop icinga2`). After three failures in ten seconds it will stop trying because you probably have a problem that requires manual intervention. ### Late Check Results [Icinga Web 2](https://icinga.com/docs/icinga-web/latest/) provides a dashboard overview for `overdue checks`. The REST API provides the [status](12-icinga2-api.md#icinga2-api-status) URL endpoint with some generic metrics on Icinga and its features. ```bash curl -k -s -u root:icinga 'https://localhost:5665/v1/status?pretty=1' | less ``` You can also calculate late check results via the REST API: * Fetch the `last_check` timestamp from each object * Compare the timestamp with the current time and add `check_interval` multiple times (change it to see which results are really late, like five times check_interval) You can use the [icinga2 console](11-cli-commands.md#cli-command-console) to connect to the instance, fetch all data and calculate the differences. ``` # ICINGA2_API_USERNAME=root ICINGA2_API_PASSWORD=icinga icinga2 console --connect 'https://localhost:5665/' <1> => var res = []; for (s in get_objects(Service).filter(s => s.last_check < get_time() - 2 * s.check_interval)) { res.add([s.__name, DateTime(s.last_check).to_string()]) }; res [ [ "10807-host!10807-service", "2016-06-10 15:54:55 +0200" ], [ "mbmif.int.netways.de!disk /", "2016-01-26 16:32:29 +0100" ] ] ``` Or if you are just interested in numbers, call [len](18-library-reference.md#array-len) on the result array `res`: ``` <2> => var res = []; for (s in get_objects(Service).filter(s => s.last_check < get_time() - 2 * s.check_interval)) { res.add([s.__name, DateTime(s.last_check).to_string()]) }; res.len() 2.000000 ``` If you need to analyze that problem multiple times, just add the current formatted timestamp and repeat the commands. ``` <23> => DateTime(get_time()).to_string() "2017-04-04 16:09:39 +0200" <24> => var res = []; for (s in get_objects(Service).filter(s => s.last_check < get_time() - 2 * s.check_interval)) { res.add([s.__name, DateTime(s.last_check).to_string()]) }; res.len() 8287.000000 ``` More details about the Icinga 2 DSL and its possibilities can be found in the [language](17-language-reference.md#language-reference) and [library](18-library-reference.md#library-reference) reference chapters. ### Late Check Results in Distributed Environments When it comes to a distributed HA setup, each node is responsible for a load-balanced amount of checks. Host and Service objects provide the attribute `paused`. If this is set to `false`, the current node actively attempts to schedule and execute checks. Otherwise the node does not feel responsible. ``` <3> => var res = {}; for (s in get_objects(Service).filter(s => s.last_check < get_time() - 2 * s.check_interval)) { res[s.paused] += 1 }; res { @false = 2.000000 @true = 1.000000 } ``` You may ask why this analysis is important? Fair enough - if the numbers are not inverted in an HA zone with two members, this may give a hint that the cluster nodes are in a split-brain scenario, or you've found a bug in the cluster. If you are running a cluster setup where the master/satellite executes checks on the client via [top down command endpoint](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) mode, you might want to know which zones are affected. This analysis assumes that clients which are not connected, have the string `connected` in their service check result output and their state is `UNKNOWN`. ``` <4> => var res = {}; for (s in get_objects(Service)) { if (s.state==3) { if (match("*connected*", s.last_check_result.output)) { res[s.zone] += [s.host_name] } } }; for (k => v in res) { res[k] = len(v.unique()) }; res { Asia = 31.000000 Europe = 214.000000 USA = 207.000000 } ``` The result set shows the configured zones and their affected hosts in a unique list. The output also just prints the numbers but you can adjust this by omitting the `len()` call inside the for loop. ## Notifications Troubleshooting ### Notifications are not sent * Check the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) to see if a notification is triggered. * If yes, verify that all conditions are satisfied. * Are any errors on the notification command execution logged? Please ensure to add these details with your own description to any question or issue posted to the community channels. Verify the following configuration: * Is the host/service `enable_notifications` attribute set, and if so, to which value? * Do the [notification](09-object-types.md#objecttype-notification) attributes `states`, `types`, `period` match the notification conditions? * Do the [user](09-object-types.md#objecttype-user) attributes `states`, `types`, `period` match the notification conditions? * Are there any notification `begin` and `end` times configured? * Make sure the [notification](11-cli-commands.md#enable-features) feature is enabled. * Does the referenced NotificationCommand work when executed as Icinga user on the shell? If notifications are to be sent via mail, make sure that the mail program specified inside the [NotificationCommand object](09-object-types.md#objecttype-notificationcommand) exists. The name and location depends on the distribution so the preconfigured setting might have to be changed on your system. Examples: ``` # icinga2 feature enable notification The feature 'notification' is already enabled. ``` ```bash icinga2 feature enable debuglog systemctl restart icinga2 grep Notification /var/log/icinga2/debug.log > /root/analyze_notification_problem.log ``` You can use the Icinga 2 API [event streams](12-icinga2-api.md#icinga2-api-event-streams) to receive live notification streams: ```bash curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/events?queue=debugnotifications&types=Notification' ``` ## Feature Troubleshooting ### Feature is not working * Make sure that the feature configuration is enabled by symlinking from `features-available/` to `features-enabled` and that the latter is included in [icinga2.conf](04-configuration.md#icinga2-conf). * Are the feature attributes set correctly according to the documentation? * Any errors on the logs? Look up the [object type](09-object-types.md#object-types) for the required feature and verify it is enabled: ```bash icinga2 object list --type ``` Example for the `graphite` feature: ```bash icinga2 object list --type GraphiteWriter ``` Look into the log and check whether the feature logs anything specific for this matter. ```bash grep GraphiteWriter /var/log/icinga2/icinga2.log ``` ## REST API Troubleshooting In order to analyse errors on API requests, you can explicitly enable the [verbose parameter](12-icinga2-api.md#icinga2-api-parameters-global). ``` $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE 'https://localhost:5665/v1/objects/hosts/example-cmdb?pretty=1&verbose=1' { "diagnostic_information": "Error: Object does not exist.\n\n ....", "error": 404.0, "status": "No objects found." } ``` ### REST API Troubleshooting: No Objects Found Please note that the `404` status with no objects being found can also originate from missing or too strict object permissions for the authenticated user. This is a security feature to disable object name guessing. If this would not be the case, restricted users would be able to get a list of names of your objects just by trying every character combination. In order to analyse and fix the problem, please check the following: - use an administrative account with full permissions to check whether the objects are actually there. - verify the permissions on the affected ApiUser object and fix them. ### Missing Runtime Objects (Hosts, Downtimes, etc.) Runtime objects consume the internal config packages shared with the REST API config packages. Each host, downtime, comment, service, etc. created via the REST API is stored in the `_api` package. This includes downtimes and comments, which where sometimes stored in the wrong directory path, because the active-stage file was empty/truncated/unreadable at this point. Wrong: ``` /var/lib/icinga2/api/packages/_api//conf.d/downtimes/1234-5678-9012-3456.conf ``` Correct: ``` /var/lib/icinga2/api/packages/_api/dbe0bef8-c72c-4cc9-9779-da7c4527c5b2/conf.d/downtimes/1234-5678-9012-3456.conf ``` At creation time, the object lives in memory but its storage is broken. Upon restart, it is missing and e.g. a missing downtime will re-enable unwanted notifications. `abcd-ef12-3456-7890` is the active stage name which wasn't correctly read by the Icinga daemon. This information is stored in `/var/lib/icinga2/api/packages/_api/active-stage`. 2.11 now limits the direct active-stage file access (this is hidden from the user), and caches active stages for packages in-memory. It also tries to repair the broken package, and logs a new message: ``` systemctl restart icinga2 tail -f /var/log/icinga2/icinga2.log [2019-05-10 12:27:15 +0200] information/ConfigObjectUtility: Repairing config package '_api' with stage 'dbe0bef8-c72c-4cc9-9779-da7c4527c5b2'. ``` If this does not happen, you can manually fix the broken config package, and mark a deployed stage as active again, carefully do the following steps with creating a backup before: Navigate into the API package prefix. ```bash cd /var/lib/icinga2/api/packages ``` Change into the broken package directory and list all directories and files ordered by latest changes. ``` cd _api ls -lahtr drwx------ 4 michi wheel 128B Mar 27 14:39 .. -rw-r--r-- 1 michi wheel 25B Mar 27 14:39 include.conf -rw-r--r-- 1 michi wheel 405B Mar 27 14:39 active.conf drwx------ 7 michi wheel 224B Mar 27 15:01 dbe0bef8-c72c-4cc9-9779-da7c4527c5b2 drwx------ 5 michi wheel 160B Apr 26 12:47 . ``` As you can see, the `active-stage` file is missing. When it is there, verify that its content is set to the stage directory as follows. If you have more than one stage directory here, pick the latest modified directory. Copy the directory name `abcd-ef12-3456-7890` and add it into a new file `active-stage`. This can be done like this: ```bash echo "dbe0bef8-c72c-4cc9-9779-da7c4527c5b2" > active-stage ``` `active.conf` needs to have the correct active stage too, add it again like this. Note: This is deep down in the code, use with care! ```bash sed -i 's/ActiveStages\["_api"\] = .*/ActiveStages\["_api"\] = "dbe0bef8-c72c-4cc9-9779-da7c4527c5b2"/g' /var/lib/icinga2/api/packages/_api/active.conf ``` Restart Icinga 2. ```bash systemctl restart icinga2 ``` > **Note** > > The internal `_api` config package structure may change in the future. Do not modify > things in there manually or with scripts unless guided here or asked by a developer. ## Certificate Troubleshooting Tools for analysing certificates and TLS connections: - `openssl` binary on Linux/Unix, `openssl.exe` on Windows ([download](https://slproweb.com/products/Win32OpenSSL.html)) - `sslscan` tool, available [here](https://github.com/rbsec/sslscan) (Linux/Windows) Note: You can also execute sslscan on Windows using Powershell. ### Certificate Verification Whenever the TLS handshake fails when a client connects to the cluster or the REST API, ensure to verify the used certificates. Print the CA and client certificate and ensure that the following attributes are set: * Version must be 3. * Serial number is a hex-encoded string. * Issuer should be your certificate authority (defaults to `Icinga CA` for all certificates generated by CLI commands and automated signing requests). * Validity: The certificate must not be expired. * Subject with the common name (CN) matches the client endpoint name and its FQDN. * v3 extensions must set the basic constraint for `CA:TRUE` (ca.crt) or `CA:FALSE` (client certificate). * Subject Alternative Name is set to the resolvable DNS name (required for REST API and browsers). Navigate into the local certificate store: ```bash cd /var/lib/icinga2/certs/ ``` Make sure to verify the agents' certificate and its stored `ca.crt` in `/var/lib/icinga2/certs` and ensure that all instances (master, satellite, agent) are signed by the **same CA**. Compare the `ca.crt` file from the agent node and compare it to your master's `ca.crt` file. Since 2.12, you can use the built-in CLI command `pki verify` to perform TLS certificate validation tasks. > **Hint** > > The CLI command uses exit codes aligned to the [Plugin API specification](05-service-monitoring.md#service-monitoring-plugin-api). > Run the commands followed with `echo $?` to see the exit code. These CLI commands can be used on Windows agents too without requiring the OpenSSL binary. #### Print TLS Certificate Pass the certificate file to the `--cert` CLI command parameter to print its details. This prints a shorter version of `openssl x509 -in -text`. ``` $ icinga2 pki verify --cert icinga2-agent2.localdomain.crt information/cli: Printing certificate 'icinga2-agent2.localdomain.crt' Version: 3 Subject: CN = icinga2-agent2.localdomain Issuer: CN = Icinga CA Valid From: Feb 14 11:29:36 2020 GMT Valid Until: Feb 10 11:29:36 2035 GMT Serial: 12:fe:a6:22:f5:e3:db:a2:95:8e:92:b2:af:1a:e3:01:44:c4:70:e0 Signature Algorithm: sha256WithRSAEncryption Subject Alt Names: icinga2-agent2.localdomain Fingerprint: 40 98 A0 77 58 4F CA D1 05 AC 18 53 D7 52 8D D7 9C 7F 5A 23 B4 AF 63 A4 92 9D DC FF 89 EF F1 4C ``` You can also print the `ca.crt` certificate without any further checks using the `--cert` parameter. #### Print and Verify CA Certificate The `--cacert` CLI parameter allows to check whether the given certificate file is a public CA certificate. ``` $ icinga2 pki verify --cacert ca.crt information/cli: Checking whether certificate 'ca.crt' is a valid CA certificate. Version: 3 Subject: CN = Icinga CA Issuer: CN = Icinga CA Valid From: Jul 31 12:26:08 2019 GMT Valid Until: Jul 27 12:26:08 2034 GMT Serial: 89:fe:d6:12:66:25:3a:c5:07:c1:eb:d4:e6:f2:df:ca:13:6e:dc:e7 Signature Algorithm: sha256WithRSAEncryption Subject Alt Names: Fingerprint: 9A 11 29 A8 A3 89 F8 56 30 1A E4 0A B2 6B 28 46 07 F0 14 17 BD 19 A4 FC BD 41 40 B5 1A 8F BF 20 information/cli: OK: CA certificate file 'ca.crt' was verified successfully. ``` In case you pass a wrong certificate, an error is shown and the exit code is `2` (Critical). ``` $ icinga2 pki verify --cacert icinga2-agent2.localdomain.crt information/cli: Checking whether certificate 'icinga2-agent2.localdomain.crt' is a valid CA certificate. Version: 3 Subject: CN = icinga2-agent2.localdomain Issuer: CN = Icinga CA Valid From: Feb 14 11:29:36 2020 GMT Valid Until: Feb 10 11:29:36 2035 GMT Serial: 12:fe:a6:22:f5:e3:db:a2:95:8e:92:b2:af:1a:e3:01:44:c4:70:e0 Signature Algorithm: sha256WithRSAEncryption Subject Alt Names: icinga2-agent2.localdomain Fingerprint: 40 98 A0 77 58 4F CA D1 05 AC 18 53 D7 52 8D D7 9C 7F 5A 23 B4 AF 63 A4 92 9D DC FF 89 EF F1 4C critical/cli: CRITICAL: The file 'icinga2-agent2.localdomain.crt' does not seem to be a CA certificate file. ``` #### Verify Certificate is signed by CA Certificate Pass the certificate file to the `--cert` CLI parameter, and the `ca.crt` file to the `--cacert` parameter. Common troubleshooting scenarios involve self-signed certificates and untrusted agents resulting in disconnects. ``` $ icinga2 pki verify --cert icinga2-agent2.localdomain.crt --cacert ca.crt information/cli: Verifying certificate 'icinga2-agent2.localdomain.crt' Version: 3 Subject: CN = icinga2-agent2.localdomain Issuer: CN = Icinga CA Valid From: Feb 14 11:29:36 2020 GMT Valid Until: Feb 10 11:29:36 2035 GMT Serial: 12:fe:a6:22:f5:e3:db:a2:95:8e:92:b2:af:1a:e3:01:44:c4:70:e0 Signature Algorithm: sha256WithRSAEncryption Subject Alt Names: icinga2-agent2.localdomain Fingerprint: 40 98 A0 77 58 4F CA D1 05 AC 18 53 D7 52 8D D7 9C 7F 5A 23 B4 AF 63 A4 92 9D DC FF 89 EF F1 4C information/cli: with CA certificate 'ca.crt'. Version: 3 Subject: CN = Icinga CA Issuer: CN = Icinga CA Valid From: Jul 31 12:26:08 2019 GMT Valid Until: Jul 27 12:26:08 2034 GMT Serial: 89:fe:d6:12:66:25:3a:c5:07:c1:eb:d4:e6:f2:df:ca:13:6e:dc:e7 Signature Algorithm: sha256WithRSAEncryption Subject Alt Names: Fingerprint: 9A 11 29 A8 A3 89 F8 56 30 1A E4 0A B2 6B 28 46 07 F0 14 17 BD 19 A4 FC BD 41 40 B5 1A 8F BF 20 information/cli: OK: Certificate with CN 'icinga2-agent2.localdomain' is signed by CA. ``` #### Verify Certificate matches Common Name (CN) This allows to verify the common name inside the certificate with a given string parameter. Typical troubleshooting involve upper/lower case CNs (Windows). ``` $ icinga2 pki verify --cert icinga2-agent2.localdomain.crt --cn icinga2-agent2.localdomain information/cli: Verifying common name (CN) 'icinga2-agent2.localdomain in certificate 'icinga2-agent2.localdomain.crt'. Version: 3 Subject: CN = icinga2-agent2.localdomain Issuer: CN = Icinga CA Valid From: Feb 14 11:29:36 2020 GMT Valid Until: Feb 10 11:29:36 2035 GMT Serial: 12:fe:a6:22:f5:e3:db:a2:95:8e:92:b2:af:1a:e3:01:44:c4:70:e0 Signature Algorithm: sha256WithRSAEncryption Subject Alt Names: icinga2-agent2.localdomain Fingerprint: 40 98 A0 77 58 4F CA D1 05 AC 18 53 D7 52 8D D7 9C 7F 5A 23 B4 AF 63 A4 92 9D DC FF 89 EF F1 4C information/cli: OK: CN 'icinga2-agent2.localdomain' matches certificate CN 'icinga2-agent2.localdomain'. ``` In the example below, the certificate uses an upper case CN. ``` $ icinga2 pki verify --cert icinga2-agent2.localdomain.crt --cn icinga2-agent2.localdomain information/cli: Verifying common name (CN) 'icinga2-agent2.localdomain in certificate 'icinga2-agent2.localdomain.crt'. Version: 3 Subject: CN = ICINGA2-agent2.localdomain Issuer: CN = Icinga CA Valid From: Feb 14 11:29:36 2020 GMT Valid Until: Feb 10 11:29:36 2035 GMT Serial: 12:fe:a6:22:f5:e3:db:a2:95:8e:92:b2:af:1a:e3:01:44:c4:70:e0 Signature Algorithm: sha256WithRSAEncryption Subject Alt Names: ICINGA2-agent2.localdomain Fingerprint: 40 98 A0 77 58 4F CA D1 05 AC 18 53 D7 52 8D D7 9C 7F 5A 23 B4 AF 63 A4 92 9D DC FF 89 EF F1 4C critical/cli: CRITICAL: CN 'icinga2-agent2.localdomain' does NOT match certificate CN 'icinga2-agent2.localdomain'. ``` ### Certificate Signing Icinga offers two methods: * [CSR Auto-Signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing) which uses a client (an agent or a satellite) ticket generated on the master as trust identifier. * [On-Demand CSR Signing](06-distributed-monitoring.md#distributed-monitoring-setup-on-demand-csr-signing) which allows to sign pending certificate requests on the master. Whenever a signed certificate is not received on the requesting clients, ensure to check the following: * The ticket was valid and the master's log shows nothing different (CSR Auto-Signing only) * If the agent/satellite is directly connected to the CA master, check whether the master actually has performance problems to process the request. If the connection is closed without certificate response, analyse the master's health. It is also advised to upgrade to v2.11 where network stack problems have been fixed. * If you're using a 3+ level cluster, check whether the satellite really forwarded the CSR signing request and the master processed it. Other common errors: * The generated ticket is invalid. The client receives this error message, as well as the master logs a warning message. * The [api](09-object-types.md#objecttype-apilistener) feature does not have the `ticket_salt` attribute set to the generated `TicketSalt` constant by the CLI wizards. In case you are using On-Demand CSR Signing, `icinga2 ca list` on the master only lists pending requests since v2.11. Add `--all` to also see signed requests. Keep in mind that old requests are purged after 1 week automatically. ### TLS Handshake: Ciphers Starting with v2.11, the default configured ciphers have been hardened to modern standards. This includes TLS v1.2 as minimum protocol version too. In case the TLS handshake fails with `no shared cipher`, first analyse whether both instances support the same ciphers. #### Client connects to Server Connect using `openssl s_client` and try to reproduce the connection problem. > **Important** > > The endpoint with the server role **accepting** the connection picks the preferred > cipher. E.g. when a satellite connects to the master, the master chooses the cipher. > > Keep this in mind where to simulate the client role connecting to a server with > CLI tools such as `openssl s_client`. `openssl s_client` tells you about the supported and shared cipher suites on the remote server. `openssl ciphers` lists locally available ciphers. ``` $ openssl s_client -connect 192.168.33.5:5665 ... --- SSL handshake has read 2899 bytes and written 786 bytes --- New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384 Server public key is 4096 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : AES256-GCM-SHA384 ... ``` You can specifically use one cipher or a list with the `-cipher` parameter: ```bash openssl s_client -connect 192.168.33.5:5665 -cipher 'ECDHE-RSA-AES256-GCM-SHA384' ``` In order to fully simulate a connecting client, provide the certificates too: ```bash CERTPATH='/var/lib/icinga2/certs' HOSTNAME='icinga2.vagrant.demo.icinga.com' openssl s_client -connect 192.168.33.5:5665 -cert "${CERTPATH}/${HOSTNAME}.crt" -key "${CERTPATH}/${HOSTNAME}.key" -CAfile "${CERTPATH}/ca.crt" -cipher 'ECDHE-RSA-AES256-GCM-SHA384' ``` In case to need to change the default cipher list, set the [cipher_list](09-object-types.md#objecttype-apilistener) attribute in the `api` feature configuration accordingly. Beware of using insecure ciphers, this may become a security risk in your organisation. #### Server Accepts Client If the master node does not actively connect to the satellite/agent node(s), but instead the child node actively connectsm, you can still simulate a TLS handshake. Use `openssl s_server` instead of `openssl s_client` on the master during the connection attempt. ```bash openssl s_server -connect 192.168.56.101:5665 ``` Since the server role chooses the preferred cipher suite in Icinga, you can test-drive the "agent connects to master" mode here, granted that the TCP connection is not blocked by the firewall. #### Cipher Scan Tools You can also use different tools to test the available cipher suites, this is what SSL Labs, etc. provide for TLS enabled websites as well. [This post](https://superuser.com/questions/109213/how-do-i-list-the-ssl-tls-cipher-suites-a-particular-website-offers) highlights some tools and scripts such as [sslscan](https://github.com/rbsec/sslscan) or [testssl.sh](https://github.com/drwetter/testssl.sh/) Example for sslscan on macOS against a Debian 10 Buster instance running v2.11: ``` $ brew install sslscan $ sslscan 192.168.33.22:5665 Version: 1.11.13-static OpenSSL 1.0.2f 28 Jan 2016 Connected to 192.168.33.22 Testing SSL server 192.168.33.22 on port 5665 using SNI name 192.168.33.22 TLS Fallback SCSV: Server supports TLS Fallback SCSV TLS renegotiation: Session renegotiation not supported TLS Compression: Compression disabled Heartbleed: TLS 1.2 not vulnerable to heartbleed TLS 1.1 not vulnerable to heartbleed TLS 1.0 not vulnerable to heartbleed Supported Server Cipher(s): Preferred TLSv1.2 256 bits ECDHE-RSA-AES256-GCM-SHA384 Curve P-256 DHE 256 Accepted TLSv1.2 128 bits ECDHE-RSA-AES128-GCM-SHA256 Curve P-256 DHE 256 Accepted TLSv1.2 256 bits ECDHE-RSA-AES256-SHA384 Curve P-256 DHE 256 Accepted TLSv1.2 128 bits ECDHE-RSA-AES128-SHA256 Curve P-256 DHE 256 SSL Certificate: Signature Algorithm: sha256WithRSAEncryption RSA Key Strength: 4096 Subject: icinga2-debian10.vagrant.demo.icinga.com Altnames: DNS:icinga2-debian10.vagrant.demo.icinga.com Issuer: Icinga CA Not valid before: Jul 12 07:39:55 2019 GMT Not valid after: Jul 8 07:39:55 2034 GMT ``` ## Distributed Troubleshooting This applies to any Icinga 2 node in a [distributed monitoring setup](06-distributed-monitoring.md#distributed-monitoring-scenarios). You should configure the [cluster health checks](06-distributed-monitoring.md#distributed-monitoring-health-checks) if you haven't done so already. > **Note** > > Some problems just exist due to wrong file permissions or applied packet filters. Make > sure to check these in the first place. ### Cluster Troubleshooting Connection Errors General connection errors could be one of the following problems: * Incorrect network configuration * Packet loss * Firewall rules preventing traffic Use tools like `netstat`, `tcpdump`, `nmap`, etc. to make sure that the cluster communication works (default port is `5665`). ```bash tcpdump -n port 5665 -i any netstat -tulpen | grep icinga nmap icinga2-agent1.localdomain ``` ### Cluster Troubleshooting TLS Errors If the cluster communication fails with TLS/SSL error messages, make sure to check the following * File permissions on the TLS certificate files * Does the used CA match for all cluster endpoints? * Verify the `Issuer` being your trusted CA * Verify the `Subject` containing your endpoint's common name (CN) * Check the validity of the certificate itself Try to manually connect from `icinga2-agent1.localdomain` to the master node `icinga2-master1.localdomain`: ``` $ openssl s_client -CAfile /var/lib/icinga2/certs/ca.crt -cert /var/lib/icinga2/certs/icinga2-agent1.localdomain.crt -key /var/lib/icinga2/certs/icinga2-agent1.localdomain.key -connect icinga2-master1.localdomain:5665 CONNECTED(00000003) --- ... ``` If the connection attempt fails or your CA does not match, [verify the certificates](15-troubleshooting.md#troubleshooting-certificate-verification). #### Cluster Troubleshooting Unauthenticated Clients Unauthenticated nodes are able to connect. This is required for agent/satellite setups. Master: ``` [2015-07-13 18:29:25 +0200] information/ApiListener: New client connection for identity 'icinga2-agent1.localdomain' (unauthenticated) ``` Agent as command execution bridge: ``` [2015-07-13 18:29:26 +1000] notice/ClusterEvents: Discarding 'execute command' message from 'icinga2-master1.localdomain': Invalid endpoint origin (client not allowed). ``` If these messages do not go away, make sure to [verify the master and agent certificates](15-troubleshooting.md#troubleshooting-certificate-verification). ### Cluster Troubleshooting Message Errors When the network connection is broken or gone, the Icinga 2 instances will be disconnected. If the connection can't be re-established between endpoints in the same HA zone, they remain in a Split-Brain-mode and history may differ. Although the Icinga 2 cluster protocol stores historical events in a [replay log](15-troubleshooting.md#troubleshooting-cluster-replay-log) for later synchronisation, you should make sure to check why the network connection failed. Ensure to setup [cluster health checks](06-distributed-monitoring.md#distributed-monitoring-health-checks) to monitor all endpoints and zones connectivity. ### Cluster Troubleshooting Command Endpoint Errors Command endpoints can be used [for agents](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint) as well as inside an [High-Availability cluster](06-distributed-monitoring.md#distributed-monitoring-scenarios). There is no CLI command for manually executing the check, but you can verify the following (e.g. by invoking a forced check from the web interface): * `/var/log/icinga2/icinga2.log` shows connection and execution errors. * The ApiListener is not enabled to [accept commands](06-distributed-monitoring.md#distributed-monitoring-top-down-command-endpoint). This is visible as `UNKNOWN` check result output. * `CheckCommand` definition not found on the remote client. This is visible as `UNKNOWN` check result output. * Referenced check plugin not found on the remote agent. * Runtime warnings and errors, e.g. unresolved runtime macros or configuration problems. * Specific error messages are also populated into `UNKNOWN` check results including a detailed error message in their output. * Verify the [check source](15-troubleshooting.md#checks-check-source). This is populated by the node executing the check. You can see that in Icinga Web's detail view or by querying the REST API for this checkable object. Additional tasks: * More verbose logs are found inside the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output). * Use the Icinga 2 API [event streams](12-icinga2-api.md#icinga2-api-event-streams) to receive live check result streams. Fetch all check result events matching the `event.service` name `remote-client`: ```bash curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/events?queue=debugcommandendpoint&types=CheckResult&filter=match%28%22remote-client*%22,event.service%29' ``` #### Agent Hosts with Command Endpoint require a Zone 2.11 fixes bugs where agent host checks would never be scheduled on the master. One requirement is that the checkable host/service is put into a zone. By default, the Director puts the agent host in `zones.d/master` and you're good to go. If you manually manage the configuration, the config compiler now throws an error with `command_endpoint` being set but no `zone` defined. In case you previously managed the configuration outside of `zones.d`, follow along with the following instructions. The most convenient way with e.g. managing the objects in `conf.d` is to move them into the `master` zone. First, verify the name of your endpoint's zone. The CLI wizards use `master` by default. ``` vim /etc/icinga2/zones.conf object Zone "master" { ... } ``` Then create a new directory in `zones.d` called `master`, if not existing. ```bash mkdir -p /etc/icinga2/zones.d/master ``` Now move the directory tree from `conf.d` into the `master` zone. ```bash mv conf.d/* /etc/icinga2/zones.d/master/ ``` Validate the configuration and reload Icinga. ```bash icinga2 daemon -C systemctl restart icinga2 ``` Another method is to specify the `zone` attribute manually, but since this may lead into other unwanted "not checked" scenarios, we don't recommend this for your production environment. ### Cluster Troubleshooting Config Sync In order to troubleshoot this, remember the key things with the config sync: * Within a config master zone, only one configuration master is allowed to have its config in `/etc/icinga2/zones.d`. * The config master copies the zone configuration from `/etc/icinga2/zones.d` to `/var/lib/icinga2/api/zones`. This storage is the same for all cluster endpoints, and the source for all config syncs. * The config master puts the `.authoritative` marker on these zone files locally. This is to ensure that it doesn't receive config updates from other endpoints. If you have copied the content from `/var/lib/icinga2/api/zones` to another node, ensure to remove them. * During startup, the master validates the entire configuration and only syncs valid configuration to other zone endpoints. Satellites/Agents < 2.11 store the received configuration directly in `/var/lib/icinga2/api/zones`, validating it and reloading the daemon. Satellites/Agents >= 2.11 put the received configuration into the staging directory `/var/lib/icinga2/api/zones-stage` first, and will only copy this to the production directory `/var/lib/icinga2/api/zones` once the validation was successful. The configuration sync logs the operations during startup with the `information` severity level. Received zone configuration is also logged. Typical errors are: * The api feature doesn't [accept config](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync). This is logged into `/var/lib/icinga2/icinga2.log`. * The received configuration zone is not configured in [zones.conf](04-configuration.md#zones-conf) and Icinga denies it. This is logged into `/var/lib/icinga2/icinga2.log`. * The satellite/agent has local configuration in `/etc/icinga2/zones.d` and thinks it is authoritive for this zone. It then denies the received update. Purge the content from `/etc/icinga2/zones.d`, `/var/lib/icinga2/api/zones/*` and restart Icinga to fix this. * Configuration parts stored outside of `/etc/icinga2/zones.d` on the master, for example a constant in `/etc/icinga2/constants.conf`, are then missing on the satellite/agent. Note that if set up, the [built-in icinga CheckCommand](10-icinga-template-library.md#icinga) will notify you in case the config sync wasn't successful. #### New configuration does not trigger a reload The debug/notice log dumps the calculated checksums for all files and the comparison. Analyse this to troubleshoot further. A complete sync for the `director-global` global zone can look like this: ``` [2019-08-01 09:20:25 +0200] notice/JsonRpcConnection: Received 'config::Update' message from 'icinga2-master1.localdomain' [2019-08-01 09:20:25 +0200] information/ApiListener: Applying config update from endpoint 'icinga2-master1.localdomain' of zone 'master'. [2019-08-01 09:20:25 +0200] notice/ApiListener: Creating config update for file '/var/lib/icinga2/api/zones/director-global/.checksums'. [2019-08-01 09:20:25 +0200] notice/ApiListener: Creating config update for file '/var/lib/icinga2/api/zones/director-global/.timestamp'. [2019-08-01 09:20:25 +0200] notice/ApiListener: Creating config update for file '/var/lib/icinga2/api/zones/director-global/director/001-director-basics.conf'. [2019-08-01 09:20:25 +0200] notice/ApiListener: Creating config update for file '/var/lib/icinga2/api/zones/director-global/director/host_templates.conf'. [2019-08-01 09:20:25 +0200] information/ApiListener: Received configuration for zone 'director-global' from endpoint 'icinga2-master1.localdomain'. Comparing the checksums. [2019-08-01 09:20:25 +0200] debug/ApiListener: Checking for config change between stage and production. Old (4): '{"/.checksums":"c4dd1237e36dcad9142f4d9a81324a7cae7d01543a672299 b8c1bb08b629b7d1","/.timestamp":"f21c0e6551328812d9f5176e5e31f390de0d431d09800a85385630727b404d83","/director/001-director-basics.conf":"f86583eec81c9bf3a1823a761991fb53d640bd0dc 6cd12bf8c5e6a275359970f","/director/host_templates.conf":"831e9b7e3ec1e33288e56a51e63c688da1d6316155349382a101f7fce6229ecc"}' vs. new (4): '{"/.checksums":"c4dd1237e36dcad9142f4d 9a81324a7cae7d01543a672299b8c1bb08b629b7d1","/.timestamp":"f21c0e6551328812d9f5176e5e31f390de0d431d09800a85385630727b404d83","/director/001-director-basics.conf":"f86583eec81c9bf 3a1823a761991fb53d640bd0dc6cd12bf8c5e6a275359970f","/director/host_templates.conf":"831e9b7e3ec1e33288e56a51e63c688da1d6316155349382a101f7fce6229ecc"}'. [2019-08-01 09:20:25 +0200] debug/ApiListener: Ignoring old internal file '/.checksums'. [2019-08-01 09:20:25 +0200] debug/ApiListener: Ignoring old internal file '/.timestamp'. [2019-08-01 09:20:25 +0200] debug/ApiListener: Checking /director/001-director-basics.conf for old checksum: f86583eec81c9bf3a1823a761991fb53d640bd0dc6cd12bf8c5e6a275359970f. [2019-08-01 09:20:25 +0200] debug/ApiListener: Checking /director/host_templates.conf for old checksum: 831e9b7e3ec1e33288e56a51e63c688da1d6316155349382a101f7fce6229ecc. [2019-08-01 09:20:25 +0200] debug/ApiListener: Ignoring new internal file '/.checksums'. [2019-08-01 09:20:25 +0200] debug/ApiListener: Ignoring new internal file '/.timestamp'. [2019-08-01 09:20:25 +0200] debug/ApiListener: Checking /director/001-director-basics.conf for new checksum: f86583eec81c9bf3a1823a761991fb53d640bd0dc6cd12bf8c5e6a275359970f. [2019-08-01 09:20:25 +0200] debug/ApiListener: Checking /director/host_templates.conf for new checksum: 831e9b7e3ec1e33288e56a51e63c688da1d6316155349382a101f7fce6229ecc. [2019-08-01 09:20:25 +0200] information/ApiListener: Stage: Updating received configuration file '/var/lib/icinga2/api/zones-stage/director-global//director/001-director-basics.c onf' for zone 'director-global'. [2019-08-01 09:20:25 +0200] information/ApiListener: Stage: Updating received configuration file '/var/lib/icinga2/api/zones-stage/director-global//director/host_templates.conf' for zone 'director-global'. [2019-08-01 09:20:25 +0200] information/ApiListener: Applying configuration file update for path '/var/lib/icinga2/api/zones-stage/director-global' (2209 Bytes). ... [2019-08-01 09:20:25 +0200] information/ApiListener: Received configuration updates (4) from endpoint 'icinga2-master1.localdomain' are different to production, triggering validation and reload. [2019-08-01 09:20:25 +0200] notice/Process: Running command '/usr/lib/x86_64-linux-gnu/icinga2/sbin/icinga2' '--no-stack-rlimit' 'daemon' '--close-stdio' '-e' '/var/log/icinga2/e rror.log' '--validate' '--define' 'System.ZonesStageVarDir=/var/lib/icinga2/api/zones-stage/': PID 4532 [2019-08-01 09:20:25 +0200] notice/Process: PID 4532 ('/usr/lib/x86_64-linux-gnu/icinga2/sbin/icinga2' '--no-stack-rlimit' 'daemon' '--close-stdio' '-e' '/var/log/icinga2/error.l og' '--validate' '--define' 'System.ZonesStageVarDir=/var/lib/icinga2/api/zones-stage/') terminated with exit code 0 [2019-08-01 09:20:25 +0200] information/ApiListener: Config validation for stage '/var/lib/icinga2/api/zones-stage/' was OK, replacing into '/var/lib/icinga2/api/zones/' and trig gering reload. [2019-08-01 09:20:26 +0200] information/ApiListener: Copying file 'director-global//.checksums' from config sync staging to production zones directory. [2019-08-01 09:20:26 +0200] information/ApiListener: Copying file 'director-global//.timestamp' from config sync staging to production zones directory. [2019-08-01 09:20:26 +0200] information/ApiListener: Copying file 'director-global//director/001-director-basics.conf' from config sync staging to production zones directory. [2019-08-01 09:20:26 +0200] information/ApiListener: Copying file 'director-global//director/host_templates.conf' from config sync staging to production zones directory. ... [2019-08-01 09:20:26 +0200] notice/Application: Got reload command, forwarding to umbrella process (PID 4236) ``` In case the received configuration updates are equal to what is running in production, a different message is logged and the validation/reload is skipped. ``` [2020-02-05 15:18:19 +0200] information/ApiListener: Received configuration updates (4) from endpoint 'icinga2-master1.localdomain' are equal to production, skipping validation and reload. ``` #### Syncing Binary Files is Denied The config sync is built for syncing text configuration files, wrapped into JSON-RPC messages. Some users have started to use this as binary file sync instead of using tools built for this: rsync, git, Puppet, Ansible, etc. Starting with 2.11, this attempt is now prohibited and logged. ``` [2019-08-02 16:03:19 +0200] critical/ApiListener: Ignoring file '/etc/icinga2/zones.d/global-templates/forbidden.exe' for cluster config sync: Does not contain valid UTF8. Binary files are not supported. Context: (0) Creating config update for file '/etc/icinga2/zones.d/global-templates/forbidden.exe' (1) Activating object 'api' of type 'ApiListener' ``` In order to solve this problem, remove the mentioned files from `zones.d` and use an alternate way of syncing plugin binaries to your satellites and agents. #### Zones in Zones The cluster config sync works in a such manner that any `/etc/icinga2/zones.d/` subdirectory is included only when it is named after a known zone by the local `Endpoint`. If you for example add some configs in to `zones.d/satellite` and forgot to define the `satellite` zone in `zones.d/master` or outside in `/etc/icinga2/zones.conf`, the config compiler will not include this config from the `zones.d/satellite` zone directory. Since v2.11, the config compiler is only including directories where a zone has been configured. Otherwise, it would include renamed old zones, broken zones, etc. and those long-lasting bugs have been now fixed. Here are some working examples: **Example: Everything in `zones.conf`** Each instance needs to know the `Zone` and `Endpoint` definitions for itself and all directly connected instances in order to successfully establish a connection with each other. This can be achieved by placing all `Endpoint` and `Zone` definitions of all Icinga 2 instances known by the local endpoint in this single file. ``` vim /etc/icinga2/zones.conf object Endpoint "icinga2-master1.localdomain" { ... } object Endpoint "icinga2-master2.localdomain" { ... } object Zone "master" { endpoints = [ "icinga2-master1.localdomain", "icinga2-master2.localdomain" ] } object Endpoint "icinga2-satellite1.localdomain" { ... } object Endpoint "icinga2-satellite2.localdomain" { ... } object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain", "icinga2-satellite1.localdomain" ] parent = "master" } ``` **Example: Child zones in `zones.d/`** An additional option that Icinga 2 offers is the possibility to outsource all *child* `Endpoint` definitions of the local Icinga 2 instance to the `zones.d/` directory. As an example, we can place the satellite `Zone` and `Endpoint` definition from the above example into `zones.d/` underneath a directory named exactly like the local endpoint `Zone` name, which in our case is `master`. ``` mkdir /etc/icinga2/zones.d/master vim /etc/icinga2/zones.d/master/satellite.conf object Endpoint "icinga2-satellite1.localdomain" { ... } object Endpoint "icinga2-satellite2.localdomain" { ... } object Zone "satellite" { endpoints = [ "icinga2-satellite1.localdomain", "icinga2-satellite1.localdomain" ] parent = "master" } ... ``` Once done, you can start deploying actual monitoring objects into the satellite zone. ``` vim /etc/icinga2/zones.d/satellite/satellite-hosts.conf object Host "agent" { ... } ``` Keep in mind that the `agent` host object will never reach the satellite, when the master does not have the `satellite` zone configured either in `zones.d/master` nor outside the `zones.d` directory. That's also explained and described in the [documentation](06-distributed-monitoring.md#distributed-monitoring-scenarios-master-satellite-agents). The thing you can do: For `command_endpoint` agents like inside the Director: Host -> Agent -> yes, there is no config sync for this zone in place. Therefore, it is valid to just sync their zones via the config sync. #### Director Changes The following restores the Zone/Endpoint objects as config objects outside of `zones.d` in your master/satellite's zones.conf with rendering them as external objects in the Director. [Example](06-distributed-monitoring.md#distributed-monitoring-scenarios-master-satellite-agents) for a 3 level setup with the masters and satellites knowing about the zone hierarchy outside defined in [zones.conf](04-configuration.md#zones-conf): ``` object Endpoint "icinga-master1.localdomain" { //define 'host' attribute to control the connection direction on each instance } object Endpoint "icinga-master2.localdomain" { //... } object Endpoint "icinga-satellite1.localdomain" { //... } object Endpoint "icinga-satellite2.localdomain" { //... } //-------------- // Zone hierarchy with endpoints, required for the trust relationship and that the cluster config sync knows which zone directory defined in zones.d needs to be synced to which endpoint. // That's no different to what is explained in the docs as basic zone trust hierarchy, and is intentionally managed outside in zones.conf there. object Zone "master" { endpoints = [ "icinga-master1.localdomain", "icinga-master2.localdomain" ] } object Zone "satellite" { endpoints = [ "icinga-satellite1.localdomain", "icinga-satellite2.localdomain" ] parent = "master" // trust } ``` Prepare the above configuration on all affected nodes, satellites are likely uptodate already. Then continue with the steps below. > * backup your database, just to be on the safe side > * create all non-external Zone/Endpoint-Objects on all related Icinga Master/Satellite-Nodes (manually in your local zones.conf) > * while doing so please do NOT restart Icinga, no deployments > * change the type in the Director DB: > > ```sql > UPDATE icinga_zone SET object_type = 'external_object' WHERE object_type = 'object'; > UPDATE icinga_endpoint SET object_type = 'external_object' WHERE object_type = 'object'; > ``` > > * render and deploy a new configuration in the Director. It will state that there are no changes. Ignore it, deploy anyways > > That's it. All nodes should automatically restart, triggered by the deployed configuration via cluster protocol. ### Cluster Troubleshooting Overdue Check Results If your master does not receive check results (or any other events) from the child zones (satellite, clients, etc.), make sure to check whether the client sending in events is allowed to do so. > **Tip** > > General troubleshooting hints on late check results are documented [here](15-troubleshooting.md#late-check-results). The [distributed monitoring conventions](06-distributed-monitoring.md#distributed-monitoring-conventions) apply. So, if there's a mismatch between your client node's endpoint name and its provided certificate's CN, the master will deny all events. > **Tip** > > [Icinga Web 2](https://icinga.com/docs/icinga-web-2/latest/doc/01-About/) provides a dashboard view > for overdue check results. Enable the [debug log](15-troubleshooting.md#troubleshooting-enable-debug-output) on the master for more verbose insights. If the client cannot authenticate, it's a more general [problem](15-troubleshooting.md#troubleshooting-cluster-unauthenticated-clients). The client's endpoint is not configured on nor trusted by the master node: ``` Discarding 'check result' message from 'icinga2-agent1.localdomain': Invalid endpoint origin (client not allowed). ``` The check result message sent by the client does not belong to the zone the checkable object is in on the master: ``` Discarding 'check result' message from 'icinga2-agent1.localdomain': Unauthorized access. ``` ### Cluster Troubleshooting Replay Log If your `/var/lib/icinga2/api/log` directory grows, it generally means that your cluster cannot replay the log on connection loss and re-establishment. A master node for example will store all events for not connected endpoints in the same and child zones. Check the following: * All clients are connected? (e.g. [cluster health check](06-distributed-monitoring.md#distributed-monitoring-health-checks)). * Check your [connection](15-troubleshooting.md#troubleshooting-cluster-connection-errors) in general. * Does the log replay work, e.g. are all events processed and the directory gets cleared up over time? * Decrease the `log_duration` attribute value for that specific [endpoint](09-object-types.md#objecttype-endpoint). The cluster health checks also measure the `slave_lag` metric. Use this data to correlate graphs with other events (e.g. disk I/O, network problems, etc). ### Cluster Troubleshooting: Windows Agents #### Windows Service Exe Path Icinga agents can be installed either as x86 or x64 package. If you enable features, or wonder why logs are not written, the first step is to analyse which path the Windows service `icinga2` is using. Start a new administrative Powershell and ensure that the `icinga2` service is running. ``` C:\Program Files\ICINGA2\sbin> net start icinga2 ``` Use the `Get-WmiObject` function to extract the windows service and its path name. ``` C:\Program Files\ICINGA2\sbin> Get-WmiObject win32_service | ?{$_.Name -like '*icinga*'} | select Name, DisplayName, State, PathName Name DisplayName State PathName ---- ----------- ----- -------- icinga2 Icinga 2 Running "C:\Program Files\ICINGA2\sbin\icinga2.exe" --scm "daemon" ``` If you have used the `icinga2.exe` from a different path to enable e.g. the `debuglog` feature, navigate into `C:\Program Files\ICINGA2\sbin\` and use the correct exe to control the feature set. #### Windows Agents consuming 100% CPU > **Note** > > The network stack was rewritten in 2.11. This fixes several hanging connections and threads > on older Windows agents and master/satellite nodes. Prior to testing the below, plan an upgrade. Icinga 2 requires the `NodeName` [constant](17-language-reference.md#constants) in various places to run. This includes loading the TLS certificates, setting the proper check source, and so on. Typically the Windows setup wizard and also the CLI commands populate the [constants.conf](04-configuration.md#constants-conf) file with the auto-detected or user-provided FQDN/Common Name. If this constant is not set during startup, Icinga will try to resolve the FQDN, if that fails, fetch the hostname. If everything fails, it logs an error and sets this to `localhost`. This results in undefined behaviour if ignored by the admin. Querying the DNS when not reachable is CPU consuming, and may look like Icinga is doing lots of checks, etc. but actually really is just starting up. In order to fix this, edit the `constants.conf` file and populate the `NodeName` constant with the FQDN. Ensure this is the same value as the local endpoint object name. ``` const NodeName = "windows-agent1.domain.com" ``` #### Windows blocking Icinga 2 with ephemeral port range When you see a message like this in your Windows agent logs: ``` critical/TcpSocket: Invalid socket: 10055, "An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full." ``` Windows is blocking Icinga 2 and as such, no more TCP connection handling is possible. Depending on the version, patch level and installed applications, Windows is changing its range of [ephemeral ports](https://en.wikipedia.org/wiki/Ephemeral_port#Range). In order to solve this, raise the `MaxUserPort` value in the registry. ``` HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters Value Name: MaxUserPort Value Type: DWORD Value data: 65534 ``` More details in [this blogpost](https://www.netways.de/blog/2019/01/24/windows-blocking-icinga-2-with-ephemeral-port-range/) and this [MS help entry](https://support.microsoft.com/en-us/help/196271/when-you-try-to-connect-from-tcp-ports-greater-than-5000-you-receive-t). icinga2-2.14.6/doc/16-upgrading-icinga-2.md000066400000000000000000001303111501332562400200020ustar00rootroot00000000000000# Upgrading Icinga 2 Upgrading Icinga 2 is usually quite straightforward. Ordinarily the only manual steps involved are scheme updates for the IDO database. Specific version upgrades are described below. Please note that version updates are incremental. An upgrade from v2.6 to v2.8 requires to follow the instructions for v2.7 too. ## Upgrading to v2.14 ### Dependencies and Redundancy Groups Before Icinga v2.12 all dependencies were cumulative. I.e. the child was considered reachable only if no dependency was violated. In v2.12 and v2.13, all dependencies were redundant. I.e. the child was considered unreachable only if no dependency was fulfilled. v2.14 restores the pre-v2.12 behavior, but allows to override it. I.e. you can still make any number of your dependencies redundant, as you wish. For details read the docs' [redundancy groups section](03-monitoring-basics.md#dependencies-redundancy-groups). ### Email Notification Scripts The email notification scripts shipped with Icinga 2 (/etc/icinga2/scripts) now link to Icinga DB Web, not the monitoring module. Both new and existing installations are affected unless you've altered the scripts. In the latter case package managers won't upgrade those "config" files in-place, but just put files with similar names into the same directory. This allows you to patch them by yourself based on diff(1). On the other hand, if you want to stick to the monitoring module for now, add any comments to the notification scripts before upgrading. This way package managers won't touch those files. ## Upgrading to v2.13 ### DB IDO Schema Update There is an optional schema update on MySQL which increases the max length of object names from 128 to 255 characters. Please proceed here for the [MySQL upgrading docs](16-upgrading-icinga-2.md#upgrading-mysql-db). ### Behavior changes #### Deletion of child downtimes on services Service downtimes created while using the `all_services` flag on the [schedule-downtime](12-icinga2-api.md#schedule-downtime) API action will now automatically be deleted when deleting the hosts downtime. #### Windows Event Log Icinga 2.13 now supports logging to the Windows Event Log. Icinga will now also log messages from the early startup phase to the Windows Event Log. These were previously missing from the log file and you could only see them by manually starting Icinga in the foreground. This feature is now enabled and replaces the existing mainlog feature logging to a file. When upgrading, the installer will enable the windowseventlog feature and disable the mainlog feature. Logging to a file is still possible. If you don't want this configuration migration on upgrade, you can opt-out by installing the `%ProgramData%\icinga2\etc\icinga2\features-available\windowseventlog.conf` file before upgrading to Icinga 2.13. #### Broken API package name validation This version has replaced a broken regex in the API package validation code which results in package names now being validated correctly. Package names should now only consist of alphanumeric characters, dashes and underscores. This change only applies to newly created packages to support already existing ones. ## Upgrading to v2.12 * CLI * New `pki verify` CLI command for better [TLS certificate troubleshooting](15-troubleshooting.md#troubleshooting-certificate-verification) ### Behavior changes The behavior of multi parent [dependencies](03-monitoring-basics.md#dependencies) was fixed to e.g. render hosts unreachable when both router uplinks are down. Previous behaviour: 1) parentHost1 DOWN, parentHost2 UP => childHost **not reachable** 2) parentHost1 DOWN, parentHost2 DOWN => childHost **not reachable** New behavior: 1) parentHost1 DOWN, parentHost2 UP => childHost **reachable** 2) parentHost1 DOWN, parentHost2 DOWN => childHost **not reachable** Please review your [Dependency](09-object-types.md#objecttype-dependency) configuration as 1) may lead to different results for - `last_reachable` via REST API query - Notifications not suppressed by faulty reachability calculation anymore ### Breaking changes As of v2.12 our [API](12-icinga2-api.md) URL endpoint [`/v1/actions/acknowledge-problem`](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) refuses acknowledging an already acknowledged checkable by overwriting the acknowledgement. To replace an acknowledgement you have to remove the old one before adding the new one. The deprecated parameters `--cert` and `--key` for the `pki save-cert` CLI command have been removed from the command and documentation. ## Upgrading to v2.11 ### Bugfixes for 2.11 2.11.1 on agents/satellites fixes a problem where 2.10.x as config master would send out an unwanted config marker file, thus rendering the agent to think it is autoritative for the config, and never accepting any new config files for the zone(s). **If your config master is 2.11.x already, you are not affected by this problem.** In order to fix this, upgrade to at least 2.11.1, and purge away the local config sync storage once, then restart. ```bash yum install icinga2 rm -rf /var/lib/icinga2/api/zones/* rm -rf /var/lib/icinga2/api/zones-stage/* systemctl restart icinga2 ``` 2.11.2 fixes a problem where the newly introduced config sync "check-change-then-reload" functionality could cause endless reload loops with agents. The most visible parts are failing command endpoint checks with "not connected" UNKNOWN state. **Only applies to HA enabled zones with 2 masters and/or 2 satellites.** In order to fix this, upgrade all agents/satellites to at least 2.11.2 and restart them. ### Packages EOL distributions where no packages are available with this release: * SLES 11 * Ubuntu 14 LTS * RHEL/CentOS 6 x86 Raspbian Packages are available inside the `icinga-buster` repository on [https://packages.icinga.com](https://packages.icinga.com/raspbian/). Please note that Stretch is not supported suffering from compiler regressions. Upgrade to Raspbian Buster is highly recommended. #### Added: Boost 1.66+ The rewrite of our core network stack for cluster and REST API requires newer Boost versions, specifically >= 1.66. For technical details, please continue reading in [this issue](https://github.com/Icinga/icinga2/issues/7041). Distribution | Repository providing Boost Dependencies ---------------------|------------------------------------- CentOS 7 | [EPEL repository](02-installation.md#centos-repository) RHEL 7 | [EPEL repository](02-installation.md#rhel-repository) RHEL/CentOS 6 x64 | [packages.icinga.com](https://packages.icinga.com) Fedora | Fedora Upstream Debian 10 Buster | Debian Upstream Debian 9 Stretch | [Backports repository](02-installation.md#debian-backports-repository) **New since 2.11** Debian 8 Jessie | [packages.icinga.com](https://packages.icinga.com) Ubuntu 18 Bionic | [packages.icinga.com](https://packages.icinga.com) Ubuntu 16 Xenial | [packages.icinga.com](https://packages.icinga.com) SLES 15 | SUSE Upstream SLES 12 | [packages.icinga.com](https://packages.icinga.com) (replaces the SDK repository requirement) On platforms where EPEL or Backports cannot satisfy this dependency, we provide Boost as package on our [package repository](https://packages.icinga.com) for your convenience. After upgrade, you may remove the old Boost packages (1.53 or anything above) if you don't need them anymore. #### Added: .NET Framework 4.6 We modernized the graphical Windows wizard to use the more recent .NET Framework 4.6. This requires that Windows versions older than Windows 10/Windows Server 2016 installs at least [.NET Framework 4.6](https://www.microsoft.com/en-US/download/details.aspx?id=53344). Starting with Windows 10/Windows Server 2016 a .NET Framework 4.6 or higher is installed by default. The MSI-Installer package checks if the .NET Framework 4.6 or higher is present, if not the installation wizard will abort with an error message telling you to install at least .NET Framework 4.6. #### Removed: YAJL Our JSON library, namely [YAJL](https://github.com/lloyd/yajl), isn't maintained anymore and may cause [crashes](https://github.com/Icinga/icinga2/issues/6684). It is replaced by [JSON for Modern C++](https://github.com/nlohmann/json) by Niels Lohmann and compiled into the binary as header only include. It helps our way to C++11 and allows to fix additional UTF8 issues more easily. Read more about its [design goals](https://github.com/nlohmann/json#design-goals) and [benchmarks](https://github.com/miloyip/nativejson-benchmark#parsing-time). ### Core #### Reload Handling 2.11 provides fixes for unwanted notifications during restarts. The updated systemd service file now uses the `KillMode=mixed` setting. The reload handling was improved with an umbrella process, which means that normal runtime operations include **3 processes**. You may need to adjust the local instance monitoring of the [procs](08-advanced-topics.md#monitoring-icinga) check. More details can be found in the [technical concepts](19-technical-concepts.md#technical-concepts-core-reload) chapter. #### Downtime Notifications Imagine that a host/service changes to a HARD NOT-OK state, and its check interval is set to a high interval e.g. 1 hour. A maintenance downtime prevents the notification being sent, but once it ends and the host/service is still in a downtime, no immediate notification is re-sent but you'll have to wait for the next check. Another scenario is with one-shot notifications (interval=0) which would never notify again after the downtime ends and the problem state being intact. The state change logic requires to recover and become HARD NOT-OK to notify again. In order to solve these problems with filtered/suppressed notifications in downtimes, v2.11 changes the behaviour like this: - If there was a notification suppressed in a downtime, the core stores that information - Once the downtime ends and the problem state is still intact, Icinga checks whether a re-notification should be sent immediately A new cluster message was added to keep this in sync amongst HA masters. > **Important** > > In order to properly use this new feature, all involved endpoints > must be upgraded to v2.11. ### Network Stack The core network stack has been rewritten in 2.11 (some say this could be Icinga 3). You can read the full story [here](https://github.com/Icinga/icinga2/issues/7041). The only visible changes for users are: - No more dead-locks with hanging TLS connections (Cluster, REST API) - Better log messages in error cases - More robust and stable with using external libraries instead of self-written socket I/O Coming with this release, we've also updated TLS specific requirements explained below. #### TLS 1.2 v2.11 raises the minimum required TLS version to 1.2. This is available since OpenSSL 1.0.1 (EL6 & Debian Jessie). Older Icinga satellites/agents need to support TLS 1.2 during the TLS handshake. The `api` feature attribute `tls_protocolmin` now only supports the value `TLSv1.2` being the default. #### Hardened Cipher List The previous default cipher list allowed weak ciphers. There's no sane way other than explicitly setting the allowed ciphers. The new default sets this to: ``` ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384:AES128-GCM-SHA256 ``` You can override this setting in the [api](09-object-types.md#objecttype-apilistener) feature with the `cipher_list` attribute. In case that one of these ciphers is marked as insecure in the future, please let us know with an issue on GitHub. ### Cluster #### Agent Hosts with Command Endpoint require a Zone 2.11 fixes bugs where agent host checks would never be scheduled on the master. One definite requirement is that the checkable host/service is put into a zone. By default, the Director puts the agent host in `zones.d/master` and you're good to go. If you manually manage the configuration, the config compiler now throws an error with `command_endpoint` being set but no `zone` defined. The most convenient way with e.g. managing the objects in `conf.d` is to move them into the `master` zone. Please continue in the [troubleshooting docs](15-troubleshooting.md#troubleshooting-cluster-command-endpoint-errors-agent-hosts-command-endpoint-zone) for further instructions. #### Config Sync 2.11 overhauls the cluster config sync in many ways. This includes the following under the hood: - Synced configuration files are not immediately put into production, but left inside a stage. - Unsuccessful config validation never puts the config into production, additional logging and API states are available. - Zone directories which are not configured in zones.conf, are not included anymore on secondary master/satellites/clients. - Synced config change calculation use checksums instead of timestamps to trigger validation/reload. This is more safe, and the usage of timestamps is now deprecated. - Don't allow parallel cluster syncs to avoid race conditions with overridden files. - Deleted directories and files are now purged, previous versions had a bug. Whenever a newer child endpoint receives a configuration update without checksums, it will log a warning. ``` Received configuration update without checksums from parent endpoint satellite1. This behaviour is deprecated. Please upgrade the parent endpoint to 2.11+ ``` This is a gentle reminder to upgrade the master and satellites first, prior to installing new clients/agents. Technical details are available in the [technical concepts](19-technical-concepts.md#technical-concepts-cluster-config-sync) chapter. Since the config sync change detection now uses checksums, this may fail with anything else than syncing configuration text files. Syncing binary files were never supported, but rumors say that some users do so. This is now prohibited and logged. ``` [2019-08-02 16:03:19 +0200] critical/ApiListener: Ignoring file '/etc/icinga2/zones.d/global-templates/forbidden.exe' for cluster config sync: Does not contain valid UTF8. Binary files are not supported. Context: (0) Creating config update for file '/etc/icinga2/zones.d/global-templates/forbidden.exe' (1) Activating object 'api' of type 'ApiListener' ``` Such binaries wrapped into JSON-RPC cluster messages may always cause changes and trigger reload loops. In order to prevent such harm in production, use infrastructure tools such as Foreman, Puppet, Ansible, etc. to install plugins on the masters, satellites and agents. ##### Config Sync: Zones in Zones The cluster config sync works in the way that configuration put into `/etc/icinga2/zones.d` only is included when configured outside in `/etc/icinga2/zones.conf`. If you for example create a "Zone Inception" with defining the `satellite` zone in `zones.d/master`, the config compiler does not re-run and include this zone config recursively from `zones.d/satellite`. Since v2.11, the config compiler is only including directories where a zone has been configured. Otherwise it would include renamed old zones, broken zones, etc. and those long-lasting bugs have been now fixed. Please consult the [troubleshoot docs](15-troubleshooting.md#troubleshooting-cluster-config-zones-in-zones) for concrete examples and solutions. #### HA-aware Features v2.11 introduces additional HA functionality similar to the DB IDO feature. This enables the feature being active only on one endpoint while the other endpoint is paused. When one endpoint is shut down, automatic failover happens. This feature is turned off by default keeping the current behaviour. If you need it active on just one endpoint, set `enable_ha = true` on both endpoints in the feature configuration. This affects the following features: * [Elasticsearch](09-object-types.md#objecttype-elasticsearchwriter) * [Gelf](09-object-types.md#objecttype-gelfwriter) * [Graphite](09-object-types.md#objecttype-graphitewriter) * [InfluxDB](09-object-types.md#objecttype-influxdbwriter) * [OpenTsdb](09-object-types.md#objecttype-opentsdbwriter) * [Perfdata](09-object-types.md#objecttype-perfdatawriter) (for PNP) ### HA Failover The reconnect failover has been improved, and the default `failover_timeout` for the DB IDO features has been lowered from 60 to 30 seconds. Object authority updates (required for balancing in the cluster) happen more frequenty (was 30, is 10 seconds). Also the cold startup without object authority updates has been reduced from 60 to 30 seconds. This is to allow cluster reconnects (lowered from 60s to 10s in 2.10) before actually considering a failover/split brain scenario. The [IdoMysqlConnection](09-object-types.md#objecttype-idomysqlconnection) and [IdoPgsqlConnection](09-object-types.md#objecttype-idopgsqlconnection) objects provide a new attribute named `last_failover` which shows the last failover timestamp. This value also is available in the [ido](10-icinga-template-library.md#itl-icinga-ido) CheckCommand output. ### CLI Commands The `troubleshoot` CLI command has been removed. It was never completed, and turned out not to provide required details for GitHub issues anyways. We didn't ask nor endorse users on GitHub/Discourse in the past 2 years, so we're removing it without deprecation. Issue templates, the troubleshooting docs and support knowledge has proven to be better. #### Permissions CLI commands such as `api setup`, `node wizard/setup`, `feature enable/disable/list` required root permissions previously. Since the file permissions allow the Icinga user to change things already, and users kept asking to run Icinga on their own webspace without root permissions, this is now possible with 2.11. If you are running the commands with a different user than the compiled `ICINGA_USER` and `ICINGA_GROUP` CMake settings (`icinga` everywhere, except Debian with `nagios` for historical reasons), ensure that this user has the capabilities to change to a different user. If you still encounter problems, run the aforementioned CLI commands as root, or with sudo. #### CA List Behaviour Change `ca list` only shows the pending certificate signing requests by default. You can use the new `--all` parameter to show all signing requests. Note that Icinga automatically purges signed requests older than 1 week. #### New: CA Remove/Restore `ca remove` allows you to remove pending signing requests. Once the master receives a CSR, and it is marked as removed, the request is denied. `ca restore` allows you to restore a removed signing request. You can list removed signing requests with the new `--removed` parameter for `ca list`. ### Configuration The deprecated `concurrent_checks` attribute in the [checker feature](09-object-types.md#objecttype-checkercomponent) has no effect anymore if set. Please use the [MaxConcurrentChecks](17-language-reference.md#icinga-constants-global-config) constant in [constants.conf](04-configuration.md#constants-conf) instead. ### REST API #### Actions The [schedule-downtime](12-icinga2-api.md#icinga2-api-actions-schedule-downtime-host-all-services) action supports the `all_services` parameter for Host types. Defaults to false. #### Config Packages Deployed configuration packages require an active stage, with many previous allowed. This mechanism is used by the Icinga Director as external consumer, and Icinga itself for storing runtime created objects inside the `_api` package. This includes downtimes and comments, which where sometimes stored in the wrong directory path, because the active-stage file was empty/truncated/unreadable at this point. 2.11 makes this mechanism more stable and detects broken config packages. It will also attempt to fix them, the following log entry is perfectly fine. ``` [2019-05-10 12:12:09 +0200] information/ConfigObjectUtility: Repairing config package '_api' with stage 'dbe0bef8-c72c-4cc9-9779-da7c4527c5b2'. ``` If you still encounter problems, please follow [this troubleshooting entry](15-troubleshooting.md#troubleshooting-api-missing-runtime-objects). ### DB IDO MySQL Schema The schema for MySQL contains an optional update which drops unneeded indexes. You don't necessarily need to apply this update. ### Documentation * `Custom attributes` have been renamed to `Custom variables` following the name `vars` and their usage in backends and web interfaces. The term `custom attribute` still applies, but referring from the web to the core docs is easier. * The distributed environment term `client` has been refined into `agent`. Wordings and images have been adjusted, and a `client` only is used as general term when requesting something from a parent server role. * The images for basics, modes and scenarios in the distributed monitoring chapter have been re-created from scratch. * `02-getting-started.md` was renamed to `02-installation.md`, `04-configuring-icinga-2.md` into `04-configuration.md`. Apache redirects will be in place. ## Upgrading to v2.10 ### Path Constant Changes During package upgrades you may see a notice that the configuration content of features has changed. This is due to a more general approach with path constants in v2.10. The known constants `SysconfDir` and `LocalStateDir` stay intact and won't break on upgrade. If you are using these constants in your own custom command definitions or other objects, you are advised to revise them and update them according to the [documentation](17-language-reference.md#icinga-constants). Example diff: ``` object NotificationCommand "mail-service-notification" { - command = [ SysconfDir + "/icinga2/scripts/mail-service-notification.sh" ] + command = [ ConfigDir + "/scripts/mail-service-notification.sh" ] ``` If you have the `ICINGA2_RUN_DIR` environment variable configured in the sysconfig file, you need to rename it to `ICINGA2_INIT_RUN_DIR`. `ICINGA2_STATE_DIR` has been removed and this setting has no effect. > **Note** > > This is important if you rely on the sysconfig configuration in your own scripts. ### New Constants New [Icinga constants](17-language-reference.md#icinga-constants) have been added in this release. * `Environment` for specifying the Icinga environment. Defaults to not set. * `ApiBindHost` and `ApiBindPort` to allow overriding the default ApiListener values. This will be used for an Icinga addon only. ### Configuration: Namespaces The keywords `namespace` and `using` are now [reserved](17-language-reference.md#reserved-keywords) for the namespace functionality provided with v2.10. Read more about how it works [here](17-language-reference.md#namespaces). ### Configuration: ApiListener Anonymous JSON-RPC connections in the cluster can now be configured with `max_anonymous_clients` attribute. The corresponding REST API results from `/v1/status/ApiListener` in `json_rpc` have been renamed from `clients` to `anonymous_clients` to better reflect their purpose. Authenticated clients are counted as connected endpoints. A similar change is there for the performance data metrics. The TLS handshake timeout defaults to 10 seconds since v2.8.2. This can now be configured with the configuration attribute `tls_handshake_timeout`. Beware of performance issues with setting a too high value. ### API: schedule-downtime Action The attribute `child_options` was previously accepting 0,1,2 for specific child downtime settings. This behaviour stays intact, but the new proposed way are specific constants as values (`DowntimeNoChildren`, `DowntimeTriggeredChildren`, `DowntimeNonTriggeredChildren`). ### Notifications: Recovery and Acknowledgement When a user should be notified on `Problem` and `Acknowledgement`, v2.10 now checks during the `Acknowledgement` notification event whether this user has been notified about a problem before. ``` types = [ Problem, Acknowledgement, Recovery ] ``` If **no** `Problem` notification was sent, and the types filter includes problems for this user, the `Acknowledgement` notification is **not** sent. In contrast to that, the following configuration always sends `Acknowledgement` notifications. ``` types = [ Acknowledgement, Recovery ] ``` This change also restores the old behaviour for `Recovery` notifications. The above configuration leaving out the `Problem` type can be used to only receive recovery notifications. If `Problem` is added to the types again, Icinga 2 checks whether it has notified a user of a problem when sending the recovery notification. More details can be found in [this PR](https://github.com/Icinga/icinga2/pull/6527). ### Stricter configuration validation Some config errors are now fatal. While it never worked before, icinga2 refuses to start now! For example the following started to give a fatal error in 2.10: ``` object Zone "XXX" { endpoints = [ "master-server" ] parent = "global-templates" } ``` ```critical/config: Error: Zone 'XXX' can not have a global zone as parent.``` ### Package Changes Debian/Ubuntu drops the `libicinga2` package. `apt-get upgrade icinga2` won't remove such packages leaving the upgrade in an unsatisfied state. Please use `apt-get full-upgrade` or `apt-get dist-upgrade` instead, as explained [here](https://github.com/Icinga/icinga2/issues/6695#issuecomment-430585915). On RHEL/CentOS/Fedora, `icinga2-libs` has been obsoleted. Unfortunately yum's dependency resolver doesn't allow to install older versions than 2.10 then. Please read [here](https://github.com/Icinga/icinga-packaging/issues/114#issuecomment-429264827) for details. RPM packages dropped the [Classic UI](16-upgrading-icinga-2.md#upgrading-to-2-8-removed-classicui-config-package) package in v2.8, Debian/Ubuntu packages were forgotten. This is now the case with this release. Icinga 1.x is EOL by the end of 2018, plan your migration to [Icinga Web 2](https://icinga.com/docs/icingaweb2/latest/). ## Upgrading to v2.9 ### Deprecation and Removal Notes - Deprecation of 1.x compatibility features: `StatusDataWriter`, `CompatLogger`, `CheckResultReader`. Their removal is scheduled for 2.11. Icinga 1.x is EOL and will be out of support by the end of 2018. - Removal of Icinga Studio. It always has been experimental and did not satisfy our high quality standards. We've therefore removed it. ### Sysconfig Changes The security fixes in v2.8.2 required moving specific runtime settings into the Sysconfig file and environment. This included that Icinga 2 would itself parse this file and read the required variables. This has generated numerous false-positive log messages and led to many support questions. v2.9.0 changes this in the standard way to read these variables from the environment, and use sane compile-time defaults. > **Note** > > In order to upgrade, remove everything in the sysconfig file and re-apply > your changes. There is a bug with existing sysconfig files where path variables are not expanded because systemd [does not support](https://github.com/systemd/systemd/issues/2123) shell variable expansion. This worked with SysVInit though. Edit the sysconfig file and either remove everything, or edit this line on RHEL 7. Modify the path for other distributions. ``` vim /etc/sysconfig/icinga2 -ICINGA2_PID_FILE=$ICINGA2_RUN_DIR/icinga2/icinga2.pid +ICINGA2_PID_FILE=/run/icinga2/icinga2.pid ``` If you want to adjust the number of open files for the Icinga application for example, you would just add this setting like this on RHEL 7: ``` vim /etc/sysconfig/icinga2 ICINGA2_RLIMIT_FILES=50000 ``` Restart Icinga 2 afterwards, the systemd service file automatically puts the value into the application's environment where this is read on startup. ### Setup Wizard Changes Client and satellite setups previously had the example configuration in `conf.d` included by default. This caused trouble on config sync, or with locally executed checks generating wrong check results for command endpoint clients. In v2.9.0 `node wizard`, `node setup` and the graphical Windows wizard will disable the inclusion by default. You can opt-out and explicitly enable it again if needed. In addition to the default global zones `global-templates` and `director-global`, the setup wizards also offer to specify your own custom global zones and generate the required configuration automatically. The setup wizards also use full qualified names for Zone and Endpoint object generation, either the default values (FQDN for clients) or the user supplied input. This removes the dependency on the `NodeName` and `ZoneName` constant and helps to immediately see the parent-child relationship. Those doing support will also see the benefit in production. ### CLI Command Changes The [node setup](06-distributed-monitoring.md#distributed-monitoring-automation-cli-node-setup) parameter `--master_host` was deprecated and replaced with `--parent_host`. This parameter is now optional to allow connection-less client setups similar to the `node wizard` CLI command. The `parent_zone` parameter has been added to modify the parent zone name e.g. for client-to-satellite setups. The `api user` command which was released in v2.8.2 turned out to cause huge problems with configuration validation, windows restarts and OpenSSL versions. It is therefore removed in 2.9, the `password_hash` attribute for the ApiUser object stays intact but has no effect. This is to ensure that clients don't break on upgrade. We will revise this feature in future development iterations. ### Configuration Changes The CORS attributes `access_control_allow_credentials`, `access_control_allow_headers` and `access_control_allow_methods` are now controlled by Icinga 2 and cannot be changed anymore. ### Unique Generated Names With the removal of RHEL 5 as supported platform, we can finally use real unique IDs. This is reflected in generating names for e.g. API stage names. Previously it was a handcrafted mix of local FQDN, timestamps and random numbers. ### Custom Vars not updating A rare issue preventing the custom vars of objects created prior to 2.9.0 being updated when changed may occur. To remedy this, truncate the customvar tables and restart Icinga 2. The following is an example of how to do this with mysql: ``` $ mysql -uroot -picinga icinga MariaDB [icinga]> truncate icinga_customvariables; Query OK, 0 rows affected (0.05 sec) MariaDB [icinga]> truncate icinga_customvariablestatus; Query OK, 0 rows affected (0.03 sec) MariaDB [icinga]> exit Bye $ sudo systemctl restart icinga2 ``` Custom vars should now stay up to date. ## Upgrading to v2.8.2 With version 2.8.2 the location of settings formerly found in `/etc/icinga2/init.conf` has changed. They are now located in the sysconfig, `/etc/sysconfig/icinga2` (RPM) or `/etc/default/icinga2` (DPKG) on most systems. The `init.conf` file has been removed and its settings will be ignored. These changes are only relevant if you edited the `init.conf`. Below is a table displaying the new names for the affected settings. Old `init.conf` | New `sysconfig/icinga2` ----------------|------------------------ RunAsUser | ICINGA2\_USER RunAsGroup | ICINGA2\_GROUP RLimitFiles | ICINGA2\_RLIMIT\_FILES RLimitProcesses | ICINGA2\_RLIMIT\_PROCESSES RLimitStack | ICINGA2\_RLIMIT\_STACK ## Upgrading to v2.8 ### DB IDO Schema Update to 2.8.0 There are additional indexes and schema fixes which require an update. Please proceed here for [MySQL](16-upgrading-icinga-2.md#upgrading-mysql-db) or [PostgreSQL](16-upgrading-icinga-2.md#upgrading-postgresql-db). > **Note** > > `2.8.1.sql` fixes a unique constraint problem with fresh 2.8.0 installations. > You don't need this update if you are upgrading from an older version. ### Changed Certificate Paths The default certificate path was changed from `/etc/icinga2/pki` to `/var/lib/icinga2/certs`. Old Path | New Path ---------------------------------------------------|--------------------------------------------------- `/etc/icinga2/pki/icinga2-agent1.localdomain.crt` | `/var/lib/icinga2/certs/icinga2-agent1.localdomain.crt` `/etc/icinga2/pki/icinga2-agent1.localdomain.key` | `/var/lib/icinga2/certs/icinga2-agent1.localdomain.key` `/etc/icinga2/pki/ca.crt` | `/var/lib/icinga2/certs/ca.crt` This applies to Windows clients in the same way: `%ProgramData%\etc\icinga2\pki` was moved to `%ProgramData%\var\lib\icinga2\certs`. Old Path | New Path ----------------------------------------------------------------|---------------------------------------------------------------- `%ProgramData%\etc\icinga2\pki\icinga2-agent1.localdomain.crt` | `%ProgramData%\var\lib\icinga2\certs\icinga2-agent1.localdomain.crt` `%ProgramData%\etc\icinga2\pki\icinga2-agent1.localdomain.key` | `%ProgramData%\var\lib\icinga2\certs\icinga2-agent1.localdomain.key` `%ProgramData%\etc\icinga2\pki\ca.crt` | `%ProgramData%\var\lib\icinga2\certs\ca.crt` > **Note** > > The default expected path for client certificates is `/var/lib/icinga2/certs/ + NodeName + {.crt,.key}`. > The `NodeName` constant is usually the FQDN and certificate common name (CN). Check the [conventions](06-distributed-monitoring.md#distributed-monitoring-conventions) > section inside the Distributed Monitoring chapter. The [setup CLI commands](06-distributed-monitoring.md#distributed-monitoring-setup-master) and the default [ApiListener configuration](06-distributed-monitoring.md#distributed-monitoring-apilistener) have been adjusted to these paths too. The [ApiListener](09-object-types.md#objecttype-apilistener) object attributes `cert_path`, `key_path` and `ca_path` have been deprecated and removed from the example configuration. #### Migration Path > **Note** > > Icinga 2 automatically migrates the certificates to the new default location if they > are configured and detected in `/etc/icinga2/pki`. During startup, the migration kicks in and ensures to copy the certificates to the new location. This will also happen if someone updates the certificate files in `/etc/icinga2/pki` to ensure that the new certificate location always has the latest files. This has been implemented in the Icinga 2 binary to ensure it works on both Linux/Unix and the Windows platform. If you are not using the built-in CLI commands and setup wizards to deploy the client certificates, please ensure to update your deployment tools/scripts. This mainly affects * Puppet modules * Ansible playbooks * Chef cookbooks * Salt recipes * Custom scripts, e.g. Windows Powershell or self-made implementations In order to support a smooth migration between versions older than 2.8 and future releases, the built-in certificate migration path is planned to exist as long as the deprecated `ApiListener` object attributes exist. You are safe to use the existing configuration paths inside the `api` feature. **Example** Look at the following example taken from the Director Linux deployment script for clients. * Ensure that the default certificate path is changed from `/etc/icinga2/pki` to `/var/lib/icinga2/certs`. ``` -ICINGA2_SSL_DIR="${ICINGA2_CONF_DIR}/pki" +ICINGA2_SSL_DIR="${ICINGA2_STATE_DIR}/lib/icinga2/certs" ``` * Remove the ApiListener configuration attributes. ``` object ApiListener "api" { - cert_path = SysconfDir + "/icinga2/pki/${ICINGA2_NODENAME}.crt" - key_path = SysconfDir + "/icinga2/pki/${ICINGA2_NODENAME}.key" - ca_path = SysconfDir + "/icinga2/pki/ca.crt" accept_commands = true accept_config = true } ``` Test the script with a fresh client installation before putting it into production. > **Tip** > > Please support module and script developers in their migration. If you find > any project which would require these changes, create an issue or a patchset in a PR > and help them out. Thanks in advance! ### On-Demand Signing and CA Proxy Icinga 2 v2.8 supports the following features inside the cluster: * Forward signing requests from clients through a satellite instance to a signing master ("CA Proxy"). * Signing requests without a ticket. The master instance allows to list and sign CSRs ("On-Demand Signing"). In order to use these features, **all instances must be upgraded to v2.8**. More details in [this chapter](06-distributed-monitoring.md#distributed-monitoring-setup-sign-certificates-master). ### Windows Client Windows versions older than Windows 10/Server 2016 require the [Universal C Runtime for Windows](https://support.microsoft.com/en-us/help/2999226/update-for-universal-c-runtime-in-windows). ### Removed Bottom Up Client Mode This client mode was deprecated in 2.6 and was removed in 2.8. The node CLI command does not provide `list` or `update-config` anymore. > **Note** > > The old migration guide can be found on [GitHub](https://github.com/Icinga/icinga2/blob/v2.7.0/doc/06-distributed-monitoring.md#bottom-up-migration-to-top-down-). The clients don't need to have a local `conf.d` directory included. Icinga 2 continues to run with the generated and imported configuration. You are advised to [migrate](https://github.com/Icinga/icinga2/issues/4798) any existing configuration to the "top down" mode with the help of the Icinga Director or config management tools such as Puppet, Ansible, etc. ### Removed Classic UI Config Package The config meta package `classicui-config` and the configuration files have been removed. You need to manually configure this legacy interface. Create a backup of the configuration before upgrading and re-configure it afterwards. ### Flapping Configuration Icinga 2 v2.8 implements a new flapping detection algorithm which splits the threshold configuration into low and high settings. `flapping_threshold` is deprecated and does not have any effect when flapping is enabled. Please remove `flapping_threshold` from your configuration. This attribute will be removed in v2.9. Instead you need to use the `flapping_threshold_low` and `flapping_threshold_high` attributes. More details can be found [here](08-advanced-topics.md#check-flapping). ### Deprecated Configuration Attributes Object | Attribute --------------|------------------ ApiListener | cert\_path (migration happens) ApiListener | key\_path (migration happens) ApiListener | ca\_path (migration happens) Host, Service | flapping\_threshold (has no effect) ## Upgrading to v2.7 v2.7.0 provided new notification scripts and commands. Please ensure to update your configuration accordingly. An advisory has been published [here](https://icinga.com/2017/08/23/advisory-for-icinga-2-v2-7-update-and-mail-notification-scripts/). In case are having troubles with OpenSSL 1.1.0 and the public CA certificates, please read [this advisory](https://icinga.com/2017/08/30/advisory-for-ssl-problems-with-leading-zeros-on-openssl-1-1-0/) and check the [troubleshooting chapter](15-troubleshooting.md#troubleshooting). If Icinga 2 fails to start with an empty reference to `$ICINGA2_CACHE_DIR` ensure to set it inside `/etc/sysconfig/icinga2` (RHEL) or `/etc/default/icinga2` (Debian). RPM packages will put a file called `/etc/sysconfig/icinga2.rpmnew` if you have modified the original file. Example on CentOS 7: ``` vim /etc/sysconfig/icinga2 ICINGA2_CACHE_DIR=/var/cache/icinga2 systemctl restart icinga2 ``` ## Upgrading the MySQL database If you want to upgrade an existing Icinga 2 instance, check the `/usr/share/icinga2-ido-mysql/schema/upgrade` directory for incremental schema upgrade file(s). > **Note** > > If there isn't an upgrade file for your current version available, there's nothing to do. Apply all database schema upgrade files incrementally. ``` # mysql -u root -p icinga < /usr/share/icinga2-ido-mysql/schema/upgrade/.sql ``` The Icinga 2 DB IDO feature checks the required database schema version on startup and generates an log message if not satisfied. **Example:** You are upgrading Icinga 2 from version `2.4.0` to `2.8.0`. Look into the `upgrade` directory: ``` $ ls /usr/share/icinga2-ido-mysql/schema/upgrade/ 2.0.2.sql 2.1.0.sql 2.2.0.sql 2.3.0.sql 2.4.0.sql 2.5.0.sql 2.6.0.sql 2.8.0.sql ``` There are two new upgrade files called `2.5.0.sql`, `2.6.0.sql` and `2.8.0.sql` which must be applied incrementally to your IDO database. ```bash mysql -u root -p icinga < /usr/share/icinga2-ido-mysql/schema/upgrade/2.5.0.sql mysql -u root -p icinga < /usr/share/icinga2-ido-mysql/schema/upgrade/2.6.0.sql mysql -u root -p icinga < /usr/share/icinga2-ido-mysql/schema/upgrade/2.8.0.sql ``` ## Upgrading the PostgreSQL database If you want to upgrade an existing Icinga 2 instance, check the `/usr/share/icinga2-ido-pgsql/schema/upgrade` directory for incremental schema upgrade file(s). > **Note** > > If there isn't an upgrade file for your current version available, there's nothing to do. Apply all database schema upgrade files incrementally. ``` # export PGPASSWORD=icinga # psql -U icinga -d icinga < /usr/share/icinga2-ido-pgsql/schema/upgrade/.sql ``` The Icinga 2 DB IDO feature checks the required database schema version on startup and generates an log message if not satisfied. **Example:** You are upgrading Icinga 2 from version `2.4.0` to `2.8.0`. Look into the `upgrade` directory: ``` $ ls /usr/share/icinga2-ido-pgsql/schema/upgrade/ 2.0.2.sql 2.1.0.sql 2.2.0.sql 2.3.0.sql 2.4.0.sql 2.5.0.sql 2.6.0.sql 2.8.0.sql ``` There are two new upgrade files called `2.5.0.sql`, `2.6.0.sql` and `2.8.0.sql` which must be applied incrementally to your IDO database. ```bash export PGPASSWORD=icinga psql -U icinga -d icinga < /usr/share/icinga2-ido-pgsql/schema/upgrade/2.5.0.sql psql -U icinga -d icinga < /usr/share/icinga2-ido-pgsql/schema/upgrade/2.6.0.sql psql -U icinga -d icinga < /usr/share/icinga2-ido-pgsql/schema/upgrade/2.8.0.sql ``` icinga2-2.14.6/doc/17-language-reference.md000066400000000000000000001232521501332562400201610ustar00rootroot00000000000000# Language Reference ## Object Definition Icinga 2 features an object-based configuration format. You can define new objects using the `object` keyword: ``` object Host "host1.example.org" { display_name = "host1" address = "192.168.0.1" address6 = "2001:db8:1234::42" } ``` In general you need to write each statement on a new line. Expressions started with `{`, `(` and `[` extend until the matching closing character and can be broken up into multiple lines. Alternatively you can write multiple statements on a single line by separating them with a semicolon: ``` object Host "host1.example.org" { display_name = "host1" address = "192.168.0.1"; address6 = "2001:db8:1234::42" } ``` Each object is uniquely identified by its type (`Host`) and name (`host1.example.org`). Some types have composite names, e.g. the `Service` type which uses the `host_name` attribute and the name you specified to generate its object name. Exclamation marks (!) are not permitted in object names. Objects can contain a comma-separated list of property declarations. Instead of commas semicolons may also be used. The following data types are available for property values: All objects have at least the following attributes: Attribute | Description ---------------------|----------------------------- name | The name of the object. This attribute can be modified in the object definition to override the name specified with the `object` directive. type | The type of the object. ## Expressions The following expressions can be used on the right-hand side of assignments. ### Numeric Literals A floating-point number. Example: ``` 27.3 ``` ### Duration Literals Similar to floating-point numbers except for the fact that they support suffixes to help with specifying time durations. Example: ``` 2.5m ``` Supported suffixes include ms (milliseconds), s (seconds), m (minutes), h (hours) and d (days). Duration literals are converted to seconds by the config parser and are treated like numeric literals. ### String Literals A string. Example: ``` "Hello World!" ``` #### String Literals Escape Sequences Certain characters need to be escaped. The following escape sequences are supported: Character | Escape sequence --------------------------|------------------------------------ " | \\" \\ | \\\\ $ | $$ <TAB> | \\t <CARRIAGE-RETURN> | \\r <LINE-FEED> | \\n <BEL> | \\b <FORM-FEED> | \\f In addition to these pre-defined escape sequences you can specify arbitrary ASCII characters using the backslash character (\\) followed by an ASCII character in octal encoding. In Icinga 2, the `$` character is reserved for resolving [runtime macros](03-monitoring-basics.md#runtime-macros). However, in situations where a string that isn't intended to be used as a runtime macro contains the `$` character, it is necessary to escape it with another `$` character. ### Multi-line String Literals Strings spanning multiple lines can be specified by enclosing them in {{{ and }}}. Example: ``` {{{This is a multi-line string.}}} ``` Unlike in ordinary strings special characters do not have to be escaped in multi-line string literals. ### Boolean Literals The keywords `true` and `false` are used to denote truth values. ### Null Value The `null` keyword can be used to specify an empty value. ### Dictionary An unordered list of key-value pairs. Keys must be unique and are compared in a case-sensitive manner. Individual key-value pairs must either be comma-separated or on separate lines. The comma after the last key-value pair is optional. Example: ``` { address = "192.168.0.1" port = 443 } ``` Identifiers may not contain certain characters (e.g. space) or start with certain characters (e.g. digits). If you want to use a dictionary key that is not a valid identifier, you can enclose the key in double quotes. ### Array An ordered list of values. Individual array elements must be comma-separated. The comma after the last element is optional. Example: ``` [ "hello", 42 ] ``` An array may simultaneously contain values of different types, such as strings and numbers. ### Operators The following operators are supported in expressions. The operators are sorted by descending precedence. Operator | Precedence | Examples (Result) | Description ---------|------------|-----------------------------------------------|-------------------------------- `()` | 1 | (3 + 3) * 5 | Groups sub-expressions `()` | 1 | Math.random() | Calls a function `[]` | 1 | a[3] | Array subscript `.` | 1 | a.b | Element access `!` | 2 | !"Hello" (false), !false (true) | Logical negation of the operand `~` | 2 | ~true (false) | Bitwise negation of the operand `+` | 2 | +3 | Unary plus `-` | 2 | -3 | Unary minus `&` | 2 | &var (reference to 'var') | Reference operator `*` | 2 | *var | Indirection operator `*` | 3 | 5m * 10 (3000) | Multiplies two numbers `/` | 3 | 5m / 5 (60) | Divides two numbers `%` | 3 | 17 % 12 (5) | Remainder after division `+` | 4 | 1 + 3 (4), "hello " + "world" ("hello world") | Adds two numbers; concatenates strings `-` | 4 | 3 - 1 (2) | Subtracts two numbers `<<` | 5 | 4 << 8 (1024) | Left shift `>>` | 5 | 1024 >> 4 (64) | Right shift `<` | 6 | 3 < 5 (true) | Less than `>` | 6 | 3 > 5 (false) | Greater than `<=` | 6 | 3 <= 3 (true) | Less than or equal `>=` | 6 | 3 >= 3 (true) | Greater than or equal `in` | 7 | "foo" in [ "foo", "bar" ] (true) | Element contained in array `!in` | 7 | "foo" !in [ "bar", "baz" ] (true) | Element not contained in array `==` | 8 | "hello" == "hello" (true), 3 == 5 (false) | Equal to `!=` | 8 | "hello" != "world" (true), 3 != 3 (false) | Not equal to `&` | 9 | 7 & 3 (3) | Binary AND `^` | 10 | 17 ^ 12 (29) | Bitwise XOR | | 11 | 2 | 3 (3) | Binary OR `&&` | 12 | true && false (false), 3 && 7 (7), 0 && 7 (0) | Logical AND || | 13 | true || false (true), 0 || 7 (7)| Logical OR `=` | 14 | a = 3 | Assignment `=>` | 15 | x => x * x (function with arg x) | Lambda, for loop `?` | 16 | (2 * 3 > 5) ? 1 : 0 (1) | [Ternary operator](17-language-reference.md#conditional-statements-ternary) ### References A reference to a value can be obtained using the `&` operator. The `*` operator can be used to dereference a reference: ``` var value = "Hello!" var p = &value /* p refers to value */ *p = "Hi!" log(value) // Prints "Hi!" because the variable was changed ``` ### Namespaces Namespaces can be used to organize variables and functions. They are used to avoid name conflicts. The `namespace` keyword is used to create a new namespace: ``` namespace Utils { function calculate() { return 2 + 2 } } ``` The namespace is made available as a global variable which has the namespace's name (e.g. `Utils`): ``` Utils.calculate() ``` The `using` keyword can be used to make all attributes in a namespace available to a script without having to explicitly specify the namespace's name for each access: ``` using Utils calculate() ``` The `using` keyword only has an effect for the current file and only for code that follows the keyword: ``` calculate() // This will not work. using Utils ``` The following namespaces are automatically imported as if by using the `using` keyword: * System * System.Configuration * Types * Icinga ### Function Calls Functions can be called using the `()` operator: ``` const MyGroups = [ "test1", "test" ] { check_interval = len(MyGroups) * 1m } ``` A list of available functions is available in the [Library Reference](18-library-reference.md#library-reference) chapter. ## Assignments In addition to the `=` operator shown above a number of other operators to manipulate attributes are supported. Here's a list of all available operators (the outermost `{` `}` stand for a local variable scope): ### Operator = Sets an attribute to the specified value. Example: ``` { a = 5 a = 7 } ``` In this example `a` has the value `7` after both instructions are executed. ### Operator += The += operator is a shortcut. The following expression: ``` { a = [ "hello" ] a += [ "world" ] } ``` is equivalent to: ``` { a = [ "hello" ] a = a + [ "world" ] } ``` ### Operator -= The -= operator is a shortcut. The following expression: ``` { a = 10 a -= 5 } ``` is equivalent to: ``` { a = 10 a = a - 5 } ``` ### Operator \*= The *= operator is a shortcut. The following expression: ``` { a = 60 a *= 5 } ``` is equivalent to: ``` { a = 60 a = a * 5 } ``` ### Operator /= The /= operator is a shortcut. The following expression: ``` { a = 300 a /= 5 } ``` is equivalent to: ``` { a = 300 a = a / 5 } ``` ## Indexer The indexer syntax provides a convenient way to set dictionary elements. Example: ``` { hello.key = "world" } ``` Example (alternative syntax): ``` { hello["key"] = "world" } ``` This is equivalent to writing: ``` { hello += { key = "world" } } ``` If the `hello` attribute does not already have a value, it is automatically initialized to an empty dictionary. ## Template Imports Objects can import attributes from other objects. Example: ``` template Host "default-host" { vars.colour = "red" } template Host "test-host" { import "default-host" vars.colour = "blue" } object Host "localhost" { import "test-host" address = "127.0.0.1" address6 = "::1" } ``` The `default-host` and `test-host` objects are marked as templates using the `template` keyword. Unlike ordinary objects templates are not instantiated at run-time. Parent objects do not necessarily have to be templates, however in general they are. The `vars` dictionary for the `localhost` object contains all three custom variables and the custom variable `colour` has the value `"blue"`. Parent objects are resolved in the order they're specified using the `import` keyword. Default templates which are automatically imported into all object definitions can be specified using the `default` keyword: ``` template CheckCommand "plugin-check-command" default { // ... } ``` Default templates are imported before any other user-specified statement in an object definition is evaluated. If there are multiple default templates the order in which they are imported is unspecified. ## Constants Global constants can be set using the `const` keyword: ``` const VarName = "some value" ``` Once defined a constant can be accessed from any file. Constants cannot be changed once they are set. > **Tip** > > Best practice is to manage constants in the [constants.conf](04-configuration.md#constants-conf) file. ### Icinga 2 Specific Constants Icinga 2 provides a number of special global constants. These include directory paths, global configuration and runtime parameters for the application version and (build) platform. #### Directory Path Constants Constant | Description --------------------|------------------- ConfigDir |**Read-only.** Main configuration directory. Usually set to `/etc/icinga2`. DataDir |**Read-only.** Runtime data for the Icinga daemon. Usually set to `/var/lib/icinga2`. LogDir |**Read-only.** Logfiles from the daemon. Usually set to `/var/log/icinga2`. CacheDir |**Read-only.** Cached status information of the daemon. Usually set to `/var/cache/icinga2`. SpoolDir |**Read-only.** Spool directory for certain data outputs. Usually set to `/var/spool/icinga2`. InitRunDir |**Read-only.** Directory for PID files and sockets in daemon mode. Usually set to `/run/icinga2`. ZonesDir |**Read-only.** Contains the path of the zones.d directory. Defaults to `ConfigDir + "/zones.d"`. #### Global Configuration Constants Constant | Description --------------------|------------------- Vars |**Read-write.** Contains a dictionary with global custom variables. Not set by default. NodeName |**Read-write.** Contains the cluster node name. Set to the local hostname by default. ReloadTimeout |**Read-write.** Defines the reload timeout for child processes. Defaults to `300s`. Environment |**Read-write.** The name of the Icinga environment. Included in the SNI host name for outbound connections. Not set by default. RunAsUser |**Read-write.** Defines the user the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig. RunAsGroup |**Read-write.** Defines the group the Icinga 2 daemon is running as. Set in the Icinga 2 sysconfig. MaxConcurrentChecks |**Read-write.** The number of max checks run simultaneously. Defaults to `512`. ApiBindHost |**Read-write.** Overrides the default value for the ApiListener `bind_host` attribute. Defaults to `::` if IPv6 is supported by the operating system and to `0.0.0.0` otherwise. ApiBindPort |**Read-write.** Overrides the default value for the ApiListener `bind_port` attribute. Not set by default. #### Application Runtime Constants Constant | Description --------------------|------------------- PlatformName |**Read-only.** The name of the operating system, e.g. `Ubuntu`. PlatformVersion |**Read-only.** The version of the operating system, e.g. `14.04.3 LTS`. PlatformKernel |**Read-only.** The name of the operating system kernel, e.g. `Linux`. PlatformKernelVersion|**Read-only.** The version of the operating system kernel, e.g. `3.13.0-63-generic`. BuildCompilerName |**Read-only.** The name of the compiler Icinga was built with, e.g. `Clang`. BuildCompilerVersion|**Read-only.** The version of the compiler Icinga was built with, e.g. `7.3.0.7030031`. BuildHostName |**Read-only.** The name of the host Icinga was built on, e.g. `acheron`. ApplicationVersion |**Read-only.** The application version, e.g. `2.9.0`. #### Additional Constants Writable constants can be specified on the CLI using the `--define/-D` parameter. > **Note for v2.10+** > > Default paths which include `/etc` and `/var` as base directory continue to work > based on the `SysconfDir` and `LocalStateDir` constants respectively. In addition to that, the constants below are used to define specific file paths. You should never need to change them, as they are pre-compiled based on the constants above. Variable |Description --------------------|------------------- StatePath |**Read-write.** Contains the path of the Icinga 2 state file. Defaults to `DataDir + "/icinga2.state"`. ObjectsPath |**Read-write.** Contains the path of the Icinga 2 objects file. Defaults to `CacheDir + "/icinga2.debug"`. PidPath |**Read-write.** Contains the path of the Icinga 2 PID file. Defaults to `InitRunDir + "/icinga2.pid"`. PkgDataDir |**Read-only.** Contains the path of the package data directory. Defaults to `PrefixDir + "/share/icinga2"`. The constants below have been used until Icinga v2.10, and are still intact. You don't need them for future builds and configuration based on the newly available constants above. Variable |Description --------------------|------------------- PrefixDir |**Read-only.** Contains the installation prefix that was specified with `cmake -DCMAKE_INSTALL_PREFIX`. `Defaults to "/usr/local"`. SysconfDir |**Read-only.** Contains the path of the sysconf directory. Defaults to `PrefixDir + "/etc"`. LocalStateDir |**Read-only.** Contains the path of the local state directory. Defaults to `PrefixDir + "/var"`. RunDir |**Read-only.** Contains the path of the run directory. Defaults to `LocalStateDir + "/run"`. #### Advanced Constants and Variables Advanced runtime constants. Please only use them if advised by support or developers. Variable | Description ---------------------------|------------------- EventEngine |**Read-write.** The name of the socket event engine, can be `poll` or `epoll`. The epoll interface is only supported on Linux. AttachDebugger |**Read-write.** Whether to attach a debugger when Icinga 2 crashes. Defaults to `false`. Advanced sysconfig environment variables, defined in `/etc/sysconfig/icinga2` (RHEL/SLES) or `/etc/default/icinga2` (Debian/Ubuntu). Variable | Description ---------------------------|------------------- ICINGA2\_RLIMIT\_FILES |**Read-write.** Defines the resource limit for `RLIMIT_NOFILE` that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig. ICINGA2\_RLIMIT\_PROCESSES |**Read-write.** Defines the resource limit for `RLIMIT_NPROC` that should be set at start-up. Value cannot be set lower than the default `16 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig. ICINGA2\_RLIMIT\_STACK |**Read-write.** Defines the resource limit for `RLIMIT_STACK` that should be set at start-up. Value cannot be set lower than the default `256 * 1024`. 0 disables the setting. Set in Icinga 2 sysconfig. #### Debug Constants and Variables These constants are only available in debug builds for developers and help with tracing messages and attaching to debuggers. Variable | Description ---------------------------|------------------- Internal.DebugJsonRpc | **Read-write.** Setting this to `1` prints the raw JSON-RPC message to STDOUT. Internal.DebugWorkerDelay | **Read-write.** Delays the main worker process by X seconds after forked from the umbrella process. This helps with attaching LLDB which cannot follow child forks like GDB. Example: ``` $ icinga2 daemon -DInternal.DebugWorkerDelay=120 Closed FD 6 which we inherited from our parent process. [2020-01-29 12:22:33 +0100] information/cli: Icinga application loader (version: v2.11.0-477-gfe8701d77; debug) [2020-01-29 12:22:33 +0100] information/RunWorker: DEBUG: Current PID: 85253. Sleeping for 120 seconds to allow lldb/gdb -p attachment. $ lldb -p 85253 (lldb) b icinga::Checkable::ProcessCheckResult (lldb) c ``` ## Apply The `apply` keyword can be used to create new objects which are associated with another group of objects. ``` apply Service "ping" to Host { import "generic-service" check_command = "ping4" assign where host.name == "localhost" } ``` In this example the `assign where` condition is a boolean expression which is evaluated for all objects of type `Host` and a new service with name "ping" is created for each matching host. [Expression operators](17-language-reference.md#expression-operators) may be used in `assign where` conditions. The `to` keyword and the target type may be omitted if there is only one target type, e.g. for the `Service` type. Depending on the object type used in the `apply` expression additional local variables may be available for use in the `where` condition: Source Type | Target Type | Variables ------------------|-------------|-------------- Service | Host | host Dependency | Host | host Dependency | Service | host, service Notification | Host | host Notification | Service | host, service ScheduledDowntime | Host | host ScheduledDowntime | Service | host, service Any valid config attribute can be accessed using the `host` and `service` variables. For example, `host.address` would return the value of the host's "address" attribute -- or null if that attribute isn't set. More usage examples are documented in the [monitoring basics](03-monitoring-basics.md#using-apply-expressions) chapter. ## Apply For [Apply](17-language-reference.md#apply) rules can be extended with the [for loop](17-language-reference.md#for-loops) keyword. ``` apply Service "prefix-" for (key => value in host.vars.dictionary) to Host { import "generic-service" check_command = "ping4" vars.host_value = value } ``` Any valid config attribute can be accessed using the `host` and `service` variables. The attribute must be of the Array or Dictionary type. In this example `host.vars.dictionary` is of the Dictionary type which needs a key-value-pair as iterator. In this example all generated service object names consist of `prefix-` and the value of the `key` iterator. The prefix string can be omitted if not required. The `key` and `value` variables can be used for object attribute assignment, e.g. for setting the `check_command` attribute or custom variables as command parameters. `apply for` rules are first evaluated against all objects matching the `for loop` list and afterwards the `assign where` and `ignore where` conditions are evaluated. It is not necessary to check attributes referenced in the `for loop` expression for their existance using an additional `assign where` condition. More usage examples are documented in the [monitoring basics](03-monitoring-basics.md#using-apply-for) chapter. ## Group Assign Group objects can be assigned to specific member objects using the `assign where` and `ignore where` conditions. ``` object HostGroup "linux-servers" { display_name = "Linux Servers" assign where host.vars.os == "Linux" } ``` In this example the `assign where` condition is a boolean expression which is evaluated for all objects of the type `Host`. Each matching host is added as member to the host group with the name "linux-servers". Membership exclusion can be controlled using the `ignore where` condition. [Expression operators](17-language-reference.md#expression-operators) may be used in `assign where` and `ignore where` conditions. Source Type | Variables ------------------|-------------- HostGroup | host ServiceGroup | host, service UserGroup | user ## Boolean Values The `assign where`, `ignore where`, `if` and `while` statements, the `!` operator as well as the `bool()` function convert their arguments to a boolean value based on the following rules: Description | Example Value | Boolean Value ---------------------|-------------------|-------------- Empty value | null | false Zero | 0 | false Non-zero integer | -23945 | true Empty string | "" | false Non-empty string | "Hello" | true Empty array | [] | false Non-empty array | [ "Hello" ] | true Empty dictionary | {} | false Non-empty dictionary | { key = "value" } | true For a list of supported expression operators for `assign where` and `ignore where` statements, see [expression operators](17-language-reference.md#expression-operators). ## Comments The Icinga 2 configuration format supports C/C++-style and shell-style comments. Example: ``` /* This is a comment. */ object Host "localhost" { check_interval = 30 // this is also a comment. retry_interval = 15 # yet another comment } ``` ## Includes Other configuration files can be included using the `include` directive. Paths must be relative to the configuration file that contains the `include` directive. Example: ``` include "some/other/file.conf" include "conf.d/*.conf" ``` Wildcard includes are not recursive. Icinga also supports include search paths similar to how they work in a C/C++ compiler: ``` include ``` Note the use of angle brackets instead of double quotes. This causes the config compiler to search the include search paths for the specified file. By default $PREFIX/share/icinga2/include is included in the list of search paths. Additional include search paths can be added using [command-line options](11-cli-commands.md#config-include-path). Wildcards are not permitted when using angle brackets. ## Recursive Includes The `include_recursive` directive can be used to recursively include all files in a directory which match a certain pattern. Example: ``` include_recursive "conf.d", "*.conf" include_recursive "templates" ``` The first parameter specifies the directory from which files should be recursively included. The file names need to match the pattern given in the second parameter. When no pattern is specified the default pattern "*.conf" is used. ## Zone Includes > **Note** > > This is an internal functionality consumed by Icinga itself. > > The preferred way for users managing configuration files in > zones is to use the [cluster config sync](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync) > or [REST API config packages](12-icinga2-api.md#icinga2-api-config-management). The `include_zones` recursively includes all subdirectories for the given path. In addition to that it sets the `zone` attribute for all objects created in these subdirectories to the name of the subdirectory. Example: ``` include_zones "etc", "zones.d", "*.conf" include_zones "puppet", "puppet-zones" ``` The first parameter specifies a tag name for this directive. Each `include_zones` invocation should use a unique tag name. When copying the zones' configuration files Icinga uses the tag name as the name for the destination directory in `/var/lib/icinga2/api/config`. The second parameter specifies the directory which contains the subdirectories. The file names need to match the pattern given in the third parameter. When no pattern is specified the default pattern "*.conf" is used. ## Library directive The `library` directive was used to manually load additional libraries. Starting with version 2.9 it is no longer necessary to explicitly load libraries and this directive has no effect. ## Functions Functions can be defined using the `function` keyword. Example: ``` function multiply(a, b) { return a * b } ``` When encountering the `return` keyword further execution of the function is terminated and the specified value is supplied to the caller of the function: ``` log(multiply(3, 5)) ``` In this example the `multiply` function we declared earlier is invoked with two arguments (3 and 5). The function computes the product of those arguments and makes the result available to the function's caller. When no value is supplied for the `return` statement the function returns `null`. Functions which do not have a `return` statement have their return value set to the value of the last expression which was performed by the function. For example, we could have also written our `multiply` function like this: ``` function multiply(a, b) { a * b } ``` Anonymous functions can be created by omitting the name in the function definition. The resulting function object can be used like any other value: ``` var fn = function() { 3 } fn() /* Returns 3 */ ``` ## Lambda Expressions Functions can also be declared using the alternative lambda syntax. Example: ``` f = (x) => x * x ``` Multiple statements can be used by putting the function body into braces: ``` f = (x) => { log("Lambda called") x * x } ``` Just like with ordinary functions the return value is the value of the last statement. For lambdas which take exactly one argument the braces around the arguments can be omitted: ``` f = x => x * x ``` ### Lambda Expressions with Closures Lambda expressions which take a given number of arguments may need additional variable values from the outer scope. When the lambda expression does not allow to change the interface, [closures](17-language-reference.md#closures) come into play. ``` var y f = ((x) use(y) => x == y) ``` Note that the braces around arguments are always required when using closures. A more concrete example: Within the DSL, you want to [filter](18-library-reference.md#array-filter) an array of HostGroup objects by their name. The filter function takes one argument being a function callback which either returns `true` or `false`. Matching items are collected into the result set. ``` get_objects(HostGroup).filter((hg) => hg.name == "linux-servers") ``` Instead of hardcoding the matching hostgroup name into the lambda scope, you want to control the value from the outside configuration values, e.g. in a custom variable or global constant. ``` var hg_filter_name = "linux-servers" get_objects(HostGroup).filter((hg) use(hg_filter_name) => hg.name == hg_filter_name) ``` You can also use this example vice versa and extract host object matching a specific host group name. ``` var hg_filter_name = "linux-servers" get_objects(Host).filter((h) use (hg_search_name) => hg_search_name in h.groups).map(h => h.name) ``` Note that this example makes use of the [map](18-library-reference.md#array-map) method for the Array type which extracts the host name attribute from the full object into a new array. ## Abbreviated Lambda Syntax Lambdas which take no arguments can also be written using the abbreviated lambda syntax. Example: ``` f = {{ 3 }} ``` This creates a new function which returns the value 3. ## Variable Scopes When setting a variable Icinga checks the following scopes in this order whether the variable already exists there: * Local Scope * `this` Scope * Global Scope The local scope contains variables which only exist during the invocation of the current function, object or apply statement. Local variables can be declared using the `var` keyword: ``` function multiply(a, b) { var temp = a * b return temp } ``` Each time the `multiply` function is invoked a new `temp` variable is used which is in no way related to previous invocations of the function. When setting a variable which has not previously been declared as local using the `var` keyword the `this` scope is used. The `this` scope refers to the current object which the function or object/apply statement operates on. ``` object Host "localhost" { check_interval = 5m } ``` In this example the `this` scope refers to the "localhost" object. The `check_interval` attribute is set for this particular host. You can explicitly access the `this` scope using the `this` keyword: ``` object Host "localhost" { var check_interval = 5m /* This explicitly specifies that the attribute should be set * for the host, if we had omitted `this.` the (poorly named) * local variable `check_interval` would have been modified instead. */ this.check_interval = 1m } ``` Similarly the keywords `locals` and `globals` are available to access the local and global scope. Functions also have a `this` scope. However unlike for object/apply statements the `this` scope for a function is set to whichever object was used to invoke the function. Here's an example: ``` hm = { h_word = null function init(word) { h_word = word } } /* Let's invoke the init() function */ hm.init("hello") ``` We're using `hm.init` to invoke the function which causes the value of `hm` to become the `this` scope for this function call. ## Closures By default `function`s, `object`s and `apply` rules do not have access to variables declared outside of their scope (except for global variables). In order to access variables which are defined in the outer scope the `use` keyword can be used: ``` function MakeHelloFunction(name) { return function() use(name) { log("Hello, " + name) } } ``` In this case a new variable `name` is created inside the inner function's scope which has the value of the `name` function argument. Alternatively a different value for the inner variable can be specified: ``` function MakeHelloFunction(name) { return function() use (greeting = "Hello, " + name) { log(greeting) } } ``` ## Conditional Statements ### Conditional Statements: if/else Sometimes it can be desirable to only evaluate statements when certain conditions are met. The if/else construct can be used to accomplish this. Example: ``` a = 3 if (a < 5) { a *= 7 } else if (a > 10) { a *= 5 } else { a *= 2 } ``` An if/else construct can also be used in place of any other value. The value of an if/else statement is the value of the last statement which was evaluated for the branch which was taken: ``` a = if (true) { log("Taking the 'true' branch") 7 * 3 } else { log("Taking the 'false' branch") 9 } ``` This example prints the log message "Taking the 'true' branch" and the `a` variable is set to 21 (7 * 3). The value of an if/else construct is null if the condition evaluates to false and no else branch is given. ### Conditional Statements: Ternary Operator Instead of if/else condition chains, you can also use the ternary operator `?` with assignments. Values are separated with a colon `:` character. ``` cond ? cond_val_true : cond_val_false ``` Whether the first condition matches, the first value is returned, if not, the else and second branch value is returned. The following example evaluates a condition and either assigns `1` or `0` to the local variable. ``` <1> => var x = (2 * 3 > 5) ? 1 : 0 null <2> => x 1.000000 <3> => var x = (2 * 3 > 7) ? 1 : 0 null <4> => x 0.000000 ``` Additional examples with advanced condition chaining: ``` <1> => 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 2.000000 <2> => 0 ? 2 : 3 ? 4 : 5 ? 6 : 7 4.000000 <3> => 0 ? 2 : 0 ? 4 : 5 ? 6 : 7 6.000000 <4> => 0 ? 2 : 0 ? 4 : 0 ? 6 : 7 7.000000 <5> => 1 + 0 ? 2 : 3 + 4 2.000000 <6> => 0 + 0 ? 2 : 3 + 4 7.000000 <7> => (()=>{ return 1 ? 2 : 3 })() 2.000000 <8> => var x = 1 ? 2 : 3 null <9> => x 2.000000 ``` ## While Loops The `while` statement checks a condition and executes the loop body when the condition evaluates to `true`. This is repeated until the condition is no longer true. Example: ``` var num = 5 while (num > 5) { log("Test") num -= 1 } ``` The `continue` and `break` keywords can be used to control how the loop is executed: The `continue` keyword skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword breaks out of the loop. ## For Loops The `for` statement can be used to iterate over arrays and dictionaries. Example: ``` var list = [ "a", "b", "c" ] for (var item in list) { log("Item: " + item) } ``` The loop body is evaluated once for each item in the array. The variable `item` is declared as a local variable just as if the `var` keyword had been used. Iterating over dictionaries can be accomplished in a similar manner: ``` var dict = { a = 3, b = 7 } for (var key => var value in dict) { log("Key: " + key + ", Value: " + value) } ``` The `continue` and `break` keywords can be used to control how the loop is executed: The `continue` keyword skips over the remaining expressions for the loop body and begins the next loop evaluation. The `break` keyword breaks out of the loop. The `var` keyword is optional when declaring variables in the loop's header. Variables declared without the `var` keyword are nonetheless local to the function. ## Constructors In order to create a new value of a specific type constructor calls may be used. Example: ``` var pd = PerfdataValue() pd.label = "test" pd.value = 10 ``` You can also try to convert an existing value to another type by specifying it as an argument for the constructor call. Example: ``` var s = String(3) /* Sets s to "3". */ ``` ## Throwing Exceptions Built-in commands may throw exceptions to signal errors such as invalid arguments. User scripts can throw exceptions using the `throw` keyword. Example: ``` throw "An error occurred." ``` ## Handling Exceptions Exceptions can be handled using the `try` and `except` keywords. When an exception occurs while executing code in the `try` clause no further statements in the `try` clause are evaluated and the `except` clause is executed instead. Example: ``` try { throw "Test" log("This statement won't get executed.") } except { log("An error occurred in the try clause.") } ``` ## Breakpoints The `debugger` keyword can be used to insert a breakpoint. It may be used at any place where an assignment would also be a valid expression. By default breakpoints have no effect unless Icinga is started with the `--script-debugger` command-line option. When the script debugger is enabled Icinga stops execution of the script when it encounters a breakpoint and spawns a console which lets the user inspect the current state of the execution environment. ## Types All values have a static type. The `typeof` function can be used to determine the type of a value: ``` typeof(3) /* Returns an object which represents the type for numbers */ ``` The following built-in types are available: Type | Examples | Description -----------|-------------------|------------------------ Number | 3.7 | A numerical value. Boolean | true, false | A boolean value. String | "hello" | A string. Array | [ "a", "b" ] | An array. Dictionary | { a = 3 } | A dictionary. Depending on which libraries are loaded additional types may become available. The `icinga` library implements a whole bunch of other [object types](09-object-types.md#object-types), e.g. Host, Service, CheckCommand, etc. Each type has an associated type object which describes the type's semantics. These type objects are made available using global variables which match the type's name: ``` /* This logs 'true' */ log(typeof(3) == Number) ``` The type object's `prototype` property can be used to find out which methods a certain type supports: ``` /* This returns: ["contains","find","len","lower","replace","reverse","split","substr","to_string","trim","upper"] */ keys(String.prototype) ``` Additional documentation on type methods is available in the [library reference](18-library-reference.md#library-reference). ## Location Information The location of the currently executing script can be obtained using the `current_filename` and `current_line` keywords. Example: ``` log("Hello from '" + current_filename + "' in line " + current_line) ``` ## Reserved Keywords These keywords are reserved and must not be used as constants or custom variables. ``` object template include include_recursive include_zones library null true false const var this globals locals use default ignore_on_error current_filename current_line apply to where import assign ignore function return break continue for if else while throw try except in using namespace ``` You can escape reserved keywords using the `@` character. The following example tries to set `vars.include` which references a reserved keyword and generates an error: ``` [2014-09-15 17:24:00 +0200] critical/config: Location: /etc/icinga2/conf.d/hosts/localhost.conf(13): vars.sla = "24x7" /etc/icinga2/conf.d/hosts/localhost.conf(14): /etc/icinga2/conf.d/hosts/localhost.conf(15): vars.include = "some cmdb export field" ^^^^^^^ /etc/icinga2/conf.d/hosts/localhost.conf(16): } /etc/icinga2/conf.d/hosts/localhost.conf(17): Config error: in /etc/icinga2/conf.d/hosts/localhost.conf: 15:8-15:14: syntax error, unexpected include (T_INCLUDE), expecting T_IDENTIFIER [2014-09-15 17:24:00 +0200] critical/config: 1 errors, 0 warnings. ``` You can escape the `include` keyword by prefixing it with an additional `@` character: ``` object Host "localhost" { import "generic-host" address = "127.0.0.1" address6 = "::1" vars.os = "Linux" vars.sla = "24x7" vars.@include = "some cmdb export field" } ``` icinga2-2.14.6/doc/18-library-reference.md000066400000000000000000001142131501332562400200400ustar00rootroot00000000000000# Library Reference ## Global functions These functions are globally available in [assign/ignore where expressions](03-monitoring-basics.md#using-apply-expressions), [functions](17-language-reference.md#functions), [API filters](12-icinga2-api.md#icinga2-api-filters) and the [Icinga 2 debug console](11-cli-commands.md#cli-command-console). You can use the [Icinga 2 debug console](11-cli-commands.md#cli-command-console) as a sandbox to test these functions before implementing them in your scenarios. ### basename Signature: ``` function basename(path) ``` Returns the filename portion of the specified path. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var path = "/etc/icinga2/scripts/xmpp-notification.pl" null <2> => basename(path) "xmpp-notification.pl" ``` ### bool Signature: ``` function bool(value) ``` Converts the value to a bool. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => bool(1) true <2> => bool(0) false ``` ### cidr_match Signature: ``` function cidr_match(pattern, ip, mode) ``` Returns true if the CIDR pattern matches the IP address, false otherwise. IPv4 addresses are converted to IPv4-mapped IPv6 addresses before being matched against the pattern. The `mode` argument is optional and can be either `MatchAll` (in which case all elements for an array have to match) or `MatchAny` (in which case at least one element has to match). The default mode is `MatchAll`. Example for a single IP address: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => host.address = "192.168.56.101" null <2> => cidr_match("192.168.56.0/24", host.address) true <3> => cidr_match("192.168.56.0/26", host.address) false ``` Example for an array of IP addresses: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => host.vars.vhost_ips = [ "192.168.56.101", "192.168.56.102", "10.0.10.99" ] null <2> => cidr_match("192.168.56.0/24", host.vars.vhost_ips, MatchAll) false <3> => cidr_match("192.168.56.0/24", host.vars.vhost_ips, MatchAny) true ``` ### dirname Signature: ``` function dirname(path) ``` Returns the directory portion of the specified path. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var path = "/etc/icinga2/scripts/xmpp-notification.pl" null <2> => dirname(path) "/etc/icinga2/scripts" ``` ### escape_create_process_arg Signature: ``` function escape_create_process_arg(text) ``` Escapes a string for use as an argument for CreateProcess(). Windows only. ### escape_shell_arg Signature: ``` function escape_shell_arg(text) ``` Escapes a string for use as a single shell argument. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => escape_shell_arg("'$host.name$' '$service.name$'") "''\\''$host.name$'\\'' '\\''$service.name$'\\'''" ``` ### escape_shell_cmd Signature: ``` function escape_shell_cmd(text) ``` Escapes shell meta characters in a string. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => escape_shell_cmd("/bin/echo 'shell test' $ENV") "/bin/echo 'shell test' \\$ENV" ``` ### get_time Signature: ``` function get_time() ``` Returns the current UNIX timestamp as floating point number. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => get_time() 1480072135.633008 <2> => get_time() 1480072140.401207 ``` ### getenv Signature: ``` function getenv(key) ``` Returns the value from the specified environment variable key. Example: ``` $ MY_ENV_VAR=icinga2 icinga2 console Icinga 2 (version: v2.11.0) Type $help to view available commands. <1> => getenv("MY_ENV_VAR") "icinga2" ``` ### glob Signature: ``` function glob(pathSpec, type) ``` Returns an array containing all paths which match the `pathSpec` argument. The `type` argument is optional and specifies which types of paths are matched. This can be a combination of the `GlobFile` and `GlobDirectory` constants. The default value is `GlobFile | GlobDirectory`. ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var pathSpec = "/etc/icinga2/conf.d/*.conf" null <2> => glob(pathSpec) [ "/etc/icinga2/conf.d/app.conf", "/etc/icinga2/conf.d/commands.conf", ... ] ``` ### glob\_recursive Signature: ``` function glob_recursive(path, pattern, type) ``` Recursively descends into the specified directory and returns an array containing all paths which match the `pattern` argument. The `type` argument is optional and specifies which types of paths are matched. This can be a combination of the `GlobFile` and `GlobDirectory` constants. The default value is `GlobFile | GlobDirectory`. ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var path = "/etc/icinga2/zones.d/" null <2> => var pattern = "*.conf" null <3> => glob_recursive(path, pattern) [ "/etc/icinga2/zones.d/global-templates/templates.conf", "/etc/icinga2/zones.d/master/hosts.conf", ... ] ``` ### intersection Signature: ``` function intersection(array, array, ...) ``` Returns an array containing all unique elements which are common to all specified arrays. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var dev_notification_groups = [ "devs", "slack" ] null <2> => var host_notification_groups = [ "slack", "noc" ] null <3> => intersection(dev_notification_groups, host_notification_groups) [ "slack" ] ``` ### keys Signature: ``` function keys(dict) ``` Returns an array containing the dictionary's keys. **Note**: Instead of using this global function you are advised to use the type's prototype method: [Dictionary#keys](18-library-reference.md#dictionary-keys). Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => host.vars.disks["/"] = {} null <2> => host.vars.disks["/var"] = {} null <3> => host.vars.disks.keys() [ "/", "/var" ] ``` ### len Signature: ``` function len(value) ``` Returns the length of the value, i.e. the number of elements for an array or dictionary, or the length of the string in bytes. **Note**: Instead of using this global function you are advised to use the type's prototype method: [Array#len](18-library-reference.md#array-len), [Dictionary#len](18-library-reference.md#dictionary-len) and [String#len](18-library-reference.md#string-len). Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => host.groups = [ "linux-servers", "db-servers" ] null <2> => host.groups.len() 2.000000 <3> => host.vars.disks["/"] = {} null <4> => host.vars.disks["/var"] = {} null <5> => host.vars.disks.len() 2.000000 <6> => host.vars.os_type = "Linux/Unix" null <7> => host.vars.os_type.len() 10.000000 ``` ### log Signature: ``` function log(value) ``` Writes a message to the log. Non-string values are converted to a JSON string. Signature: ``` function log(severity, facility, value) ``` Writes a message to the log. `severity` can be one of `LogDebug`, `LogNotice`, `LogInformation`, `LogWarning`, and `LogCritical`. Non-string values are converted to a JSON string. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => log(LogCritical, "Console", "First line") critical/Console: First line null <2> => var groups = [ "devs", "slack" ] null <3> => log(LogCritical, "Console", groups) critical/Console: ["devs","slack"] null ``` ### match Signature: ``` function match(pattern, value, mode) ``` Returns true if the wildcard (`?*`) `pattern` matches the `value`, false otherwise. The `value` can be of the type [String](18-library-reference.md#string-type) or [Array](18-library-reference.md#array-type) (which contains string elements). The `mode` argument is optional and can be either `MatchAll` (in which case all elements for an array have to match) or `MatchAny` (in which case at least one element has to match). The default mode is `MatchAll`. Example for string values: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var name = "db-prod-sfo-657" null <2> => match("*prod-sfo*", name) true <3> => match("*-dev-*", name) false ``` Example for an array of string values: ``` $ icinga2 console Icinga 2 (version: v2.11.0-28) <1> => host.vars.application_types = [ "web-wp", "web-rt", "db-local" ] null <2> => match("web-*", host.vars.application_types, MatchAll) false <3> => match("web-*", host.vars.application_types, MatchAny) true ``` ### number Signature: ``` function number(value) ``` Converts the value to a number. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => number(false) 0.000000 <2> => number("78") 78.000000 ``` ### parse_performance_data Signature: ``` function parse_performance_data(pd) ``` Parses a single performance data value from a string and returns a [PerfdataValue](08-advanced-topics.md#advanced-value-types-perfdatavalue) object. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var pd = "'time'=1480074205.197363;;;" null <2> => parse_performance_data(pd) { counter = false crit = null label = "time" max = null min = null type = "PerfdataValue" unit = "" value = 1480074205.197363 warn = null } ``` ### path\_exists Signature: ``` function path_exists(path) ``` Returns true if the specified path exists, false otherwise. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var path = "/etc/icinga2/scripts/xmpp-notification.pl" null <2> => path_exists(path) true ``` ### random Signature: ``` function random() ``` Returns a random value between 0 and RAND\_MAX (as defined in stdlib.h). ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => random() 1263171996.000000 <2> => random() 108402530.000000 ``` ### range Signature: ``` function range(end) function range(start, end) function range(start, end, increment) ``` Returns an array of numbers in the specified range. If you specify one parameter, the first element starts at `0`. The following array numbers are incremented by `1` and stop before the specified end. If you specify the start and end numbers, the returned array number are incremented by `1`. They start at the specified start number and stop before the end number. Optionally you can specify the incremented step between numbers as third parameter. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => range(5) [ 0.000000, 1.000000, 2.000000, 3.000000, 4.000000 ] <2> => range(2,4) [ 2.000000, 3.000000 ] <3> => range(2,10,2) [ 2.000000, 4.000000, 6.000000, 8.000000 ] ``` ### regex Signature: ``` function regex(pattern, value, mode) ``` Returns true if the regular expression `pattern` matches the `value`, false otherwise. The `value` can be of the type [String](18-library-reference.md#string-type) or [Array](18-library-reference.md#array-type) (which contains string elements). The `mode` argument is optional and can be either `MatchAll` (in which case all elements for an array have to match) or `MatchAny` (in which case at least one element has to match). The default mode is `MatchAll`. **Tip**: In case you are looking for regular expression tests try [regex101](https://regex101.com). Example for string values: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => host.vars.os_type = "Linux/Unix" null <2> => regex("^Linux", host.vars.os_type) true <3> => regex("^Linux$", host.vars.os_type) false ``` Example for an array of string values: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => host.vars.databases = [ "db-prod1", "db-prod2", "db-dev" ] null <2> => regex("^db-prod\\d+", host.vars.databases, MatchAny) true <3> => regex("^db-prod\\d+", host.vars.databases, MatchAll) false ``` ### sleep Signature: ``` function sleep(interval) ``` Sleeps for the specified amount of time (in seconds). ### string Signature: ``` function string(value) ``` Converts the value to a string. **Note**: Instead of using this global function you are advised to use the type's prototype method: * [Number#to_string](18-library-reference.md#number-to_string) * [Boolean#to_string](18-library-reference.md#boolean-to_string) * [String#to_string](18-library-reference.md#string-to_string) * [Object#to_string](18-library-reference.md#object-to-string) for Array and Dictionary types * [DateTime#to_string](18-library-reference.md#datetime-tostring) Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => 5.to_string() "5" <2> => false.to_string() "false" <3> => "abc".to_string() "abc" <4> => [ "dev", "slack" ].to_string() "[ \"dev\", \"slack\" ]" <5> => { "/" = {}, "/var" = {} }.to_string() "{\n\t\"/\" = {\n\t}\n\t\"/var\" = {\n\t}\n}" <6> => DateTime(2016, 11, 25).to_string() "2016-11-25 00:00:00 +0100" ``` ### typeof Signature: ``` function typeof(value) ``` Returns the [Type](18-library-reference.md#type-type) object for a value. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => typeof(3) == Number true <2> => typeof("str") == String true <3> => typeof(true) == Boolean true <4> => typeof([ 1, 2, 3]) == Array true <5> => typeof({ a = 2, b = 3 }) == Dictionary true ``` ### union Signature: ``` function union(array, array, ...) ``` Returns an array containing all unique elements from the specified arrays. Example: ``` $ icinga2 console Icinga 2 (version: v2.11.0) <1> => var dev_notification_groups = [ "devs", "slack" ] null <2> => var host_notification_groups = [ "slack", "noc" ] null <3> => union(dev_notification_groups, host_notification_groups) [ "devs", "noc", "slack" ] ``` ## Scoped Functions This chapter describes functions which are only available in a specific scope. ### macro Signature: ``` function macro("$macro_name$") ``` The `macro` function can be used to resolve [runtime macro](03-monitoring-basics.md#runtime-macros) strings into their values. The returned value depends on the attribute value which is resolved from the specified runtime macro. This function is only available in runtime evaluated functions, e.g. for [custom variables](03-monitoring-basics.md#custom-variables-functions) which use the [abbreviated lambda syntax](17-language-reference.md#nullary-lambdas). This example sets the `snmp_address` custom variable based on `$address$` and `$address6$`. ``` vars.snmp_address = {{ var addr_v4 = macro("$address$") var addr_v6 = macro("$address6$") if (addr_v4) { return addr_v4 } else { return "udp6:[" + addr_v6 + "]" } }} ``` More reference examples are available inside the [Icinga Template Library](10-icinga-template-library.md#icinga-template-library) and the [object accessors chapter](08-advanced-topics.md#access-object-attributes-at-runtime). ## Object Accessor Functions These functions can be used to retrieve a reference to another object by name. ### get_check_command Signature: ``` function get_check_command(name); ``` Returns the CheckCommand object with the specified name, or `null` if no such CheckCommand object exists. ### get_event_command Signature: ``` function get_event_command(name); ``` Returns the EventCommand object with the specified name, or `null` if no such EventCommand object exists. ### get_host Signature: ``` function get_host(host_name); ``` Returns the Host object with the specified name, or `null` if no such Host object exists. ### get_host_group Signature: ``` function get_host_group(name); ``` Returns the HostGroup object with the specified name, or `null` if no such HostGroup object exists. ### get_notification_command Signature: ``` function get_notification_command(name); ``` Returns the NotificationCommand object with the specified name, or `null` if no such NotificationCommand object exists. ### get_object Signature: ``` function get_object(type, name); ``` Returns the object with the specified type and name, or `null` if no such object exists. `type` must refer to a type object. ### get_objects Signature: ``` function get_objects(type); ``` Returns an array of objects whose type matches the specified type. `type` must refer to a type object. ### get_service Signature: ``` function get_service(host_name, service_name); function get_service(host, service_name); ``` Returns the Service object with the specified host name or object and service name pair, or `null` if no such Service object exists. Example in the [debug console](11-cli-commands.md#cli-command-console) which fetches the `disk` service object from the current Icinga 2 node: ``` $ ICINGA2_API_PASSWORD=icinga icinga2 console --connect 'https://root@localhost:5665/' Icinga 2 (version: v2.11.0) <1> => get_service(NodeName, "disk") <2> => get_service(NodeName, "disk").__name "icinga2-master1.localdomain!disk" <3> => get_service(get_host(NodeName), "disk").__name "icinga2-master1.localdomain!disk" ``` ### get_service_group Signature: ``` function get_service_group(name); ``` Returns the ServiceGroup object with the specified name, or `null` if no such ServiceGroup object exists. ### get_services Signature: ``` function get_services(host_name); function get_services(host); ``` Returns an [array](17-language-reference.md#array) of service objects for the specified host name or object, or `null` if no such host object exists. Example in the [debug console](11-cli-commands.md#cli-command-console) which fetches all service objects from the current Icinga 2 node: ``` $ ICINGA2_API_PASSWORD=icinga icinga2 console --connect 'https://root@localhost:5665/' Icinga 2 (version: v2.11.0) <1> => get_services(NodeName).map(s => s.name) [ "disk", "disk /", "http", "icinga", "load", "ping4", "ping6", "procs", "ssh", "users" ] ``` Note: [map](18-library-reference.md#array-map) takes a [lambda function](17-language-reference.md#lambdas) as argument. In this example we only want to collect and print the `name` attribute with `s => s.name`. This works in a similar fashion for a host object where you can extract all service states in using the [map](18-library-reference.md#array-map) functionality: ``` <2> => get_services(get_host(NodeName)).map(s => s.state) [ 2.000000, 2.000000, 2.000000, 0.000000, 0.000000, 0.000000, 2.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000 ] ``` ### get_template Signature: ``` function get_template(type, name); ``` Returns the template with the specified type and name, or `null` if no such object exists. `type` must refer to a type object. > **Note** > > Only the name and debug info attributes are available for templates accessed in the DSL. > Object attributes are not available in this scope. You can use this functionality to check whether a template exists e.g. on a satellite endpoint and if not, import a different template. ``` object Host "icinga-agent47.localdomain" { if (get_template(Host, "master-host-tmpl")) { import "master-host-tmpl" } else { import "generic-host" } } ``` ### get_templates Signature: ``` function get_templates(type); ``` Returns an array of templates whose type matches the specified type. `type` must refer to a type object. > **Note** > > Only the name and debug info attributes are available for templates accessed in the DSL. > Object attributes are not available in this scope. You can use this function to iterate over all available template names, similar to what the [templates API URL endpoint](12-icinga2-api.md#icinga2-api-config-templates) provides. ``` <1> => get_templates(Host).map(n => n.name) [ "ssh-agent" ] ``` ### get_time_period Signature: ``` function get_time_period(name); ``` Returns the TimePeriod object with the specified name, or `null` if no such TimePeriod object exists. ### get_user Signature: ``` function get_user(name); ``` Returns the User object with the specified name, or `null` if no such User object exists. ### get_user_group Signature: ``` function get_user_group(name); ``` Returns the UserGroup object with the specified name, or `null` if no such UserGroup object exists. ## Json object The global `Json` object can be used to encode and decode JSON. ### Json.decode Signature: ``` function decode(x); ``` Decodes a JSON string. ### Json.encode Signature: ``` function encode(x); ``` Encodes an arbitrary value into JSON. ## Math object The global `Math` object can be used to access a number of mathematical constants and functions. ### Math.E Euler's constant. ### Math.LN2 Natural logarithm of 2. ### Math.LN10 Natural logarithm of 10. ### Math.LOG2E Base 2 logarithm of E. ### Math.PI The mathematical constant Pi. ### Math.SQRT1_2 Square root of 1/2. ### Math.SQRT2 Square root of 2. ### Math.abs Signature: ``` function abs(x); ``` Returns the absolute value of `x`. ### Math.acos Signature: ``` function acos(x); ``` Returns the arccosine of `x`. ### Math.asin Signature: ``` function asin(x); ``` Returns the arcsine of `x`. ### Math.atan Signature: ``` function atan(x); ``` Returns the arctangent of `x`. ### Math.atan2 Signature: ``` function atan2(y, x); ``` Returns the arctangent of the quotient of `y` and `x`. ### Math.ceil Signature: ``` function ceil(x); ``` Returns the smallest integer value not less than `x`. ### Math.cos Signature: ``` function cos(x); ``` Returns the cosine of `x`. ### Math.exp Signature: ``` function exp(x); ``` Returns E raised to the `x`th power. ### Math.floor Signature: ``` function floor(x); ``` Returns the largest integer value not greater than `x`. ### Math.isinf Signature: ``` function isinf(x); ``` Returns whether `x` is infinite. ### Math.isnan Signature: ``` function isnan(x); ``` Returns whether `x` is NaN (not-a-number). ### Math.log Signature: ``` function log(x); ``` Returns the natural logarithm of `x`. ### Math.max Signature: ``` function max(...); ``` Returns the largest argument. A variable number of arguments can be specified. If no arguments are given, -Infinity is returned. ### Math.min Signature: ``` function min(...); ``` Returns the smallest argument. A variable number of arguments can be specified. If no arguments are given, +Infinity is returned. ### Math.pow Signature: ``` function pow(x, y); ``` Returns `x` raised to the `y`th power. ### Math.random Signature: ``` function random(); ``` Returns a pseudo-random number between 0 and 1. ### Math.round Signature: ``` function round(x); ``` Returns `x` rounded to the nearest integer value. ### Math.sign Signature: ``` function sign(x); ``` Returns -1 if `x` is negative, 1 if `x` is positive and 0 if `x` is 0. ### Math.sin Signature: ``` function sin(x); ``` Returns the sine of `x`. ### Math.sqrt Signature: ``` function sqrt(x); ``` Returns the square root of `x`. ### Math.tan Signature: ``` function tan(x); ``` Returns the tangent of `x`. ## Array type Inherits methods from the [Object type](18-library-reference.md#object-type). ### Array#add Signature: ``` function add(value); ``` Adds a new value after the last element in the array. ### Array#all Signature: ``` function all(func); ``` Returns true if the array contains only elements for which `func(element)` is true, false otherwise. ### Array#any Signature: ``` function any(func); ``` Returns true if the array contains at least one element for which `func(element)` is true, false otherwise. ### Array#clear Signature: ``` function clear(); ``` Removes all elements from the array. ### Array#contains Signature: ``` function contains(value); ``` Returns true if the array contains the specified value, false otherwise. ### Array#filter Signature: ``` function filter(func); ``` Returns a copy of the array containing only the elements for which `func(element)` is true. ### Array#freeze Signature: ``` function freeze() ``` Disallows further modifications to this array. Trying to modify the array will result in an exception. ### Array#get Signature: ``` function get(index); ``` Retrieves the element at the specified zero-based index. ### Array#join Signature: ``` function join(separator); ``` Joins all elements of the array using the specified separator. ### Array#len Signature: ``` function len(); ``` Returns the number of elements contained in the array. ### Array#map Signature: ``` function map(func); ``` Calls `func(element)` for each of the elements in the array and returns a new array containing the return values of these function calls. ### Array#reduce Signature: ``` function reduce(func); ``` Reduces the elements of the array into a single value by calling the provided function `func` as `func(a, b)` repeatedly where `a` and `b` are elements of the array or results from previous function calls. ### Array#remove Signature: ``` function remove(index); ``` Removes the element at the specified zero-based index. ### Array#reverse Signature: ``` function reverse(); ``` Returns a new array with all elements of the current array in reverse order. ### Array#set Signature: ``` function set(index, value); ``` Sets the element at the zero-based index to the specified value. The `index` must refer to an element which already exists in the array. ### Array#shallow_clone ``` function shallow_clone(); ``` Returns a copy of the array. Note that for elements which are reference values (e.g. objects such as arrays and dictionaries) only the references are copied. ### Array#sort Signature: ``` function sort(less_cmp); ``` Returns a copy of the array where all items are sorted. The items are compared using the `<` (less-than) operator. A custom comparator function can be specified with the `less_cmp` argument. ### Array#unique Signature: ``` function unique(); ``` Returns a copy of the array with all duplicate elements removed. The original order of the array is not preserved. ## Boolean type ### Boolean#to_string Signature: ``` function to_string(); ``` The `to_string` method returns a string representation of the boolean value. Example: ``` var example = true example.to_string() /* Returns "true" */ ``` ## DateTime type Inherits methods from the [Object type](18-library-reference.md#object-type). ### DateTime constructor Signature: ``` function DateTime() function DateTime(unixTimestamp) function DateTime(year, month, day) function DateTime(year, month, day, hours, minutes, seconds) ``` Constructs a new DateTime object. When no arguments are specified for the constructor a new DateTime object representing the current time is created. Example: ``` var d1 = DateTime() /* current time */ var d2 = DateTime(2016, 5, 21) /* midnight April 21st, 2016 (local time) */ ``` ### DateTime arithmetic Subtracting two DateTime objects yields the interval between them, in seconds. Example: ``` var delta = DateTime() - DateTime(2016, 5, 21) /* seconds since midnight April 21st, 2016 */ ``` Subtracting a number from a DateTime object yields a new DateTime object that is further in the past: Example: ``` var dt = DateTime() - 2 * 60 * 60 /* Current time minus 2 hours */ ``` Adding a number to a DateTime object yields a new DateTime object that is in the future: Example: ``` var dt = DateTime() + 24 * 60 * 60 /* Current time plus 24 hours */ ``` ### DateTime#format Signature: ``` function format(fmt) ``` Returns a string representation for the DateTime object using the specified format string. The format string may contain format conversion placeholders as specified in strftime(3). Example: ``` var s = DateTime(2016, 4, 21).format("%A") /* Sets s to "Thursday". */ ``` ### DateTime#to_string Signature: ``` function to_string() ``` Returns a string representation for the DateTime object. Uses a suitable default format. Example: ``` var s = DateTime(2016, 4, 21).to_string() /* Sets s to "2016-04-21 00:00:00 +0200". */ ``` ## Dictionary type Inherits methods from the [Object type](18-library-reference.md#object-type). ### Dictionary#clear Signature: ``` function clear(); ``` Removes all items from the dictionary. ### Dictionary#contains Signature: ``` function contains(key); ``` Returns true if a dictionary item with the specified `key` exists, false otherwise. ### Dictionary#freeze Signature: ``` function freeze() ``` Disallows further modifications to this dictionary. Trying to modify the dictionary will result in an exception. ### Dictionary#get Signature: ``` function get(key); ``` Retrieves the value for the specified `key`. Returns `null` if they `key` does not exist in the dictionary. ### Dictionary#keys Signature: ``` function keys(); ``` Returns a list of keys for all items that are currently in the dictionary. ### Dictionary#len Signature: ``` function len(); ``` Returns the number of items contained in the dictionary. ### Dictionary#remove Signature: ``` function remove(key); ``` Removes the item with the specified `key`. Trying to remove an item which does not exist is a no-op. ### Dictionary#set Signature: ``` function set(key, value); ``` Creates or updates an item with the specified `key` and `value`. ### Dictionary#shallow_clone Signature: ``` function shallow_clone(); ``` Returns a copy of the dictionary. Note that for elements which are reference values (e.g. objects such as arrays and dictionaries) only the references are copied. ### Dictionary#values Signature: ``` function values(); ``` Returns a list of values for all items that are currently in the dictionary. ## Function type Inherits methods from the [Object type](18-library-reference.md#object-type). ### Function#call Signature: ``` function call(thisArg, ...); ``` Invokes the function using an alternative `this` scope. The `thisArg` argument specifies the `this` scope for the function. All other arguments are passed directly to the function. Example: ``` function set_x(val) { this.x = val } dict = {} set_x.call(dict, 7) /* Invokes set_x using `dict` as `this` */ ``` ### Function#callv Signature: ``` function callv(thisArg, args); ``` Invokes the function using an alternative `this` scope. The `thisArg` argument specifies the `this` scope for the function. The items in the `args` array are passed to the function as individual arguments. Example: ``` function set_x(val) { this.x = val } var dict = {} var args = [ 7 ] set_x.callv(dict, args) /* Invokes set_x using `dict` as `this` */ ``` ## Number type ### Number#to_string Signature: ``` function to_string(); ``` The `to_string` method returns a string representation of the number. Example: ``` var example = 7 example.to_string() /* Returns "7" */ ``` ## Object type This is the base type for all types in the Icinga application. ### Object#clone Signature: ``` function clone(); ``` Returns a copy of the object. Note that for object elements which are reference values (e.g. objects such as arrays or dictionaries) the entire object is recursively copied. ### Object#to_string Signature: ``` function to_string(); ``` Returns a string representation for the object. Unless overridden this returns a string of the format "Object of type ''" where is the name of the object's type. Example: ``` [ 3, true ].to_string() /* Returns "[ 3.000000, true ]" */ ``` ### Object#type Signature: String type; Returns the object's type name. This attribute is read-only. Example: ``` get_host("localhost").type /* Returns "Host" */ ``` ## String type ### String#contains Signature: ``` function contains(str); ``` Returns `true` if the string `str` was found in the string. If the string was not found, `false` is returned. Use [find](18-library-reference.md#string-find) for getting the index instead. Example: ``` "Hello World".contains("World") /* Returns true */ ``` ### String#find Signature: ``` function find(str, start); ``` Returns the zero-based index at which the string `str` was found in the string. If the string was not found, -1 is returned. `start` specifies the zero-based index at which `find` should start looking for the string (defaults to 0 when not specified). Example: ``` "Hello World".find("World") /* Returns 6 */ ``` ### String#len Signature ``` function len(); ``` Returns the length of the string in bytes. Note that depending on the encoding type of the string this is not necessarily the number of characters. Example: ``` "Hello World".len() /* Returns 11 */ ``` ### String#lower Signature: ``` function lower(); ``` Returns a copy of the string with all of its characters converted to lower-case. Example: ``` "Hello World".lower() /* Returns "hello world" */ ``` ### String#replace Signature: ``` function replace(search, replacement); ``` Returns a copy of the string with all occurences of the string specified in `search` replaced with the string specified in `replacement`. ### String#reverse Signature: ``` function reverse(); ``` Returns a copy of the string in reverse order. ### String#split Signature: ``` function split(delimiters); ``` Splits a string into individual parts and returns them as an array. The `delimiters` argument specifies the characters which should be used as delimiters between parts. Example: ``` "x-7,y".split("-,") /* Returns [ "x", "7", "y" ] */ ``` ### String#substr Signature: ``` function substr(start, len); ``` Returns a part of a string. The `start` argument specifies the zero-based index at which the part begins. The optional `len` argument specifies the length of the part ("until the end of the string" if omitted). Example: ``` "Hello World".substr(6) /* Returns "World" */ ``` ### String#to_string Signature: ``` function to_string(); ``` Returns a copy of the string. ### String#trim Signature: ``` function trim(); ``` Removes trailing whitespaces and returns the string. ### String#upper Signature: ``` function upper(); ``` Returns a copy of the string with all of its characters converted to upper-case. Example: ``` "Hello World".upper() /* Returns "HELLO WORLD" */ ``` ## Type type Inherits methods from the [Object type](18-library-reference.md#object-type). The `Type` type provides information about the underlying type of an object or scalar value. All types are registered as global variables. For example, in order to obtain a reference to the `String` type the global variable `String` can be used. ### Type#base Signature: ``` Type base; ``` Returns a reference to the type's base type. This attribute is read-only. Example: ``` Dictionary.base == Object /* Returns true, because the Dictionary type inherits directly from the Object type. */ ``` ### Type#name Signature: ``` String name; ``` Returns the name of the type. ### Type#prototype Signature: ``` Object prototype; ``` Returns the prototype object for the type. When an attribute is accessed on an object that doesn't exist the prototype object is checked to see if an attribute with the requested name exists. If it does, the attribute's value is returned. The prototype functionality is used to implement methods. Example: ``` 3.to_string() /* Even though '3' does not have a to_string property the Number type's prototype object does. */ ``` icinga2-2.14.6/doc/19-technical-concepts.md000066400000000000000000002551141501332562400202150ustar00rootroot00000000000000# Technical Concepts This chapter provides technical concepts and design insights into specific Icinga 2 components such as: * [Application](19-technical-concepts.md#technical-concepts-application) * [Configuration](19-technical-concepts.md#technical-concepts-configuration) * [Features](19-technical-concepts.md#technical-concepts-features) * [Check Scheduler](19-technical-concepts.md#technical-concepts-check-scheduler) * [Checks](19-technical-concepts.md#technical-concepts-checks) * [Cluster](19-technical-concepts.md#technical-concepts-cluster) * [TLS Network IO](19-technical-concepts.md#technical-concepts-tls-network-io) ## Application ### CLI Commands The Icinga 2 application is managed with different CLI sub commands. `daemon` takes care about loading the configuration files, running the application as daemon, etc. Other sub commands allow to enable features, generate and request TLS certificates or enter the debug console. The main entry point for each CLI command parses the command line parameters and then triggers the required actions. ### daemon CLI command This CLI command loads the configuration files, starting with `icinga2.conf`. The [configuration compiler](19-technical-concepts.md#technical-concepts-configuration) parses the file and detects additional file includes, constants, and any other DSL specific declaration. At this stage, the configuration will already be checked against the defined grammar in the scanner, and custom object validators will also be checked. If the user provided `-C/--validate`, the CLI command returns with the validation exit code. When running as daemon, additional parameters are checked, e.g. whether this application was triggered by a reload, needs to daemonize with fork() involved and update the object's authority. The latter is important for HA-enabled cluster zones. ## Configuration ### Lexer The lexer stage does not understand the DSL itself, it only maps specific character sequences into identifiers. This allows Icinga to detect the beginning of a string with `"`, reading the following characters and determining the end of the string with again `"`. Other parts covered by the lexer a escape sequences insides a string, e.g. `"\"abc"`. The lexer also identifiers logical operators, e.g. `&` or `in`, specific keywords like `object`, `import`, etc. and comment blocks. Please check `lib/config/config_lexer.ll` for details. Icinga uses [Flex](https://github.com/westes/flex) in the first stage. > Flex (The Fast Lexical Analyzer) > > Flex is a fast lexical analyser generator. It is a tool for generating programs > that perform pattern-matching on text. Flex is a free (but non-GNU) implementation > of the original Unix lex program. ### Parser The parser stage puts the identifiers from the lexer into more context with flow control and sequences. The following comparison is parsed into a left term, an operator and a right term. ``` x > 5 ``` The DSL contains many elements which require a specific order, and sometimes only a left term for example. The parser also takes care of parsing an object declaration for example. It already knows from the lexer that `object` marks the beginning of an object. It then expects a type string afterwards, and the object name - which can be either a string with double quotes or a previously defined constant. An opening bracket `{` in this specific context starts the object scope, which also is stored for later scope specific variable access. If there's an apply rule defined, this follows the same principle. The config parser detects the scope of an apply rule and generates Icinga 2 C++ code for the parsed string tokens. ``` assign where host.vars.sla == "24x7" ``` is parsed into an assign token identifier, and the string expression is compiled into a new `ApplyExpression` object. The flow control inside the parser ensures that for example `ignore where` can only be defined when a previous `assign where` was given - or when inside an apply for rule. Another example are specific object types which allow assign expression, specifically group objects. Others objects must throw a configuration error. Please check `lib/config/config_parser.yy` for more details, and the [language reference](17-language-reference.md#language-reference) chapter for documented DSL keywords and sequences. > Icinga uses [Bison](https://en.wikipedia.org/wiki/GNU_bison) as parser generator > which reads a specification of a context-free language, warns about any parsing > ambiguities, and generates a parser in C++ which reads sequences of tokens and > decides whether the sequence conforms to the syntax specified by the grammar. ### Compiler The config compiler initializes the scanner inside the [lexer](19-technical-concepts.md#technical-concepts-configuration-lexer) stage. The configuration files are parsed into memory from inside the [daemon CLI command](19-technical-concepts.md#technical-concepts-application-cli-commands-daemon) which invokes the config validation in `ValidateConfigFiles()`. This compiles the files into an AST expression which is executed. At this stage, the expressions generate so-called "config items" which are a pre-stage of the later compiled object. `ConfigItem::CommitItems` takes care of committing the items, and doing a rollback on failure. It also checks against matching apply rules from the previous run and generates statistics about the objects which can be seen by the config validation. `ConfigItem::CommitNewItems` collects the registered types and items, and checks for a specific required order, e.g. a service object needs a host object first. The following stages happen then: - **Commit**: A workqueue then commits the items in a parallel fashion for this specific type. The object gets its name, and the AST expression is executed. It is then registered into the item into `m_Object` as reference. - **OnAllConfigLoaded**: Special signal for each object to pre-load required object attributes, resolve group membership, initialize functions and timers. - **CreateChildObjects**: Run apply rules for this specific type. - **CommitNewItems**: Apply rules may generate new config items, this is to ensure that they again run through the stages. Note that the items are now committed and the configuration is validated and loaded into memory. The final config objects are not yet activated though. This only happens after the validation, when the application is about to be run with `ConfigItem::ActivateItems`. Each item has an object created in `m_Object` which is checked in a loop. Again, the dependency order of activated objects is important here, e.g. logger features come first, then config objects and last the checker, api, etc. features. This is done by sorting the objects based on their type specific activation priority. The following signals are triggered in the stages: - **PreActivate**: Setting the `active` flag for the config object. - **Activate**: Calls `Start()` on the object, sets the local HA authority and notifies subscribers that this object is now activated (e.g. for config updates in the DB backend). ### References * [The Icinga Config Compiler: An Overview](https://www.netways.de/blog/2018/07/12/the-icinga-config-compiler-an-overview/) * [A parser/lexer/compiler for the Leonardo language](https://github.com/EmilGedda/Leonardo) * [I wrote a programming language. Here’s how you can, too.](https://medium.freecodecamp.org/the-programming-language-pipeline-91d3f449c919) * [http://onoffswitch.net/building-a-custom-lexer/](http://onoffswitch.net/building-a-custom-lexer/) * [Writing an Interpreter with Lex, Yacc, and Memphis](http://memphis.compilertools.net/interpreter.html) * [Flex](https://github.com/westes/flex) * [GNU Bison](https://www.gnu.org/software/bison/) ## Core ### Core: Reload Handling The initial design of the reload state machine looks like this: * receive reload signal SIGHUP * fork a child process, start configuration validation in parallel work queues * parent process continues with old configuration objects and the event scheduling (doing checks, replicating cluster events, triggering alert notifications, etc.) * validation NOT ok: child process terminates, parent process continues with old configuration state * validation ok: child process signals parent process to terminate and save its current state (all events until now) into the icinga2 state file * parent process shuts down writing icinga2.state file * child process waits for parent process gone, reads the icinga2 state file and synchronizes all historical and status data * child becomes the new session leader Since Icinga 2.6, there are two processes when checked with `ps aux | grep icinga2` or `pidof icinga2`. This was to ensure that feature file descriptors don't leak into the plugin process (e.g. DB IDO MySQL sockets). Icinga 2.9 changed the reload handling a bit with SIGUSR2 signals and systemd notifies. With systemd, it could occur that the tree was broken thus resulting in killing all remaining processes on stop, instead of a clean exit. You can read the full story [here](https://github.com/Icinga/icinga2/issues/7309). With 2.11 you'll now see 3 processes: - The umbrella process which takes care about signal handling and process spawning/stopping - The main process with the check scheduler, notifications, etc. - The execution helper process During reload, the umbrella process spawns a new reload process which validates the configuration. Once successful, the new reload process signals the umbrella process that it is finished. The umbrella process forwards the signal and tells the old main process to shutdown. The old main process writes the icinga2.state file. The umbrella process signals the reload process that the main process terminated. The reload process was in idle wait before, and now continues to read the written state file and run the event loop (checks, notifications, "events", ...). The reload process itself also spawns the execution helper process again. ## Features Features are implemented in specific libraries and can be enabled using CLI commands. Features either write specific data or receive data. Examples for writing data: [DB IDO](14-features.md#db-ido), [Graphite](14-features.md#graphite-carbon-cache-writer), [InfluxDB](14-features.md#influxdb-writer). [GELF](14-features.md#gelfwriter), etc. Examples for receiving data: [REST API](12-icinga2-api.md#icinga2-api), etc. The implementation of features makes use of existing libraries and functionality. This makes the code more abstract, but shorter and easier to read. Features register callback functions on specific events they want to handle. For example the `GraphiteWriter` feature subscribes to new CheckResult events. Each time Icinga 2 receives and processes a new check result, this event is triggered and forwarded to all subscribers. The GraphiteWriter feature calls the registered function and processes the received data. Features which connect Icinga 2 to external interfaces normally parse and reformat the received data into an applicable format. Since this check result signal is blocking, many of the features include a work queue with asynchronous task handling. The GraphiteWriter uses a TCP socket to communicate with the carbon cache daemon of Graphite. The InfluxDBWriter is instead writing bulk metric messages to InfluxDB's HTTP API, similar to Elasticsearch. ## Check Scheduler The check scheduler starts a thread which loops forever. It waits for check events being inserted into `m_IdleCheckables`. If the current pending check event number is larger than the configured max concurrent checks, the thread waits up until it there's slots again. In addition, further checks on enabled checks, check periods, etc. are performed. Once all conditions have passed, the next check timestamp is calculated and updated. This also is the timestamp where Icinga expects a new check result ("freshness check"). The object is removed from idle checkables, and inserted into the pending checkables list. This can be seen via REST API metrics for the checker component feature as well. The actual check execution happens asynchronously using the application's thread pool. Once the check returns, it is removed from pending checkables and again inserted into idle checkables. This ensures that the scheduler takes this checkable event into account in the next iteration. ### Start When checkable objects get activated during the startup phase, the checker feature registers a handler for this event. This is due to the fact that the `checker` feature is fully optional, and e.g. not used on command endpoint clients. Whenever such an object activation signal is triggered, Icinga 2 checks whether it is [authoritative for this object](19-technical-concepts.md#technical-concepts-cluster-ha-object-authority). This means that inside an HA enabled zone with two endpoints, only non-paused checkable objects are actively inserted into the idle checkable list for the check scheduler. ### Initial Check When a new checkable object (host or service) is initially added to the configuration, Icinga 2 performs the following during startup: * `Checkable::Start()` is called and calculates the first check time * With a spread delta, the next check time is actually set. If the next check should happen within a time frame of 60 seconds, Icinga 2 calculates a delta from a random value. The minimum of `check_interval` and 60 seconds is used as basis, multiplied with a random value between 0 and 1. In the best case, this check gets immediately executed after application start. The worst case scenario is that the check is scheduled 60 seconds after start the latest. The reasons for delaying and spreading checks during startup is that the application typically needs more resources at this time (cluster connections, feature warmup, initial syncs, etc.). Immediate check execution with thousands of checks could lead into performance problems, and additional events for each received check results. Therefore the initial check window is 60 seconds on application startup, random seed for all checkables. This is not predictable over multiple restarts for specific checkable objects, the delta changes every time. ### Scheduling Offset There's a high chance that many checkable objects get executed at the same time and interval after startup. The initial scheduling spreads that a little, but Icinga 2 also attempts to ensure to keep fixed intervals, even with high check latency. During startup, Icinga 2 calculates the scheduling offset from a random number: * `Checkable::Checkable()` calls `SetSchedulingOffset()` with `Utility::Random()` * The offset is a pseudo-random integral value between `0` and `RAND_MAX`. Whenever the next check time is updated with `Checkable::UpdateNextCheck()`, the scheduling offset is taken into account. Depending on the state type (SOFT or HARD), either the `retry_interval` or `check_interval` is used. If the interval is greater than 1 second, the time adjustment is calculated in the following way: `now * 100 + offset` divided by `interval * 100`, using the remainder (that's what `fmod()` is for) and dividing this again onto base 100. Example: offset is 6500, interval 300, now is 1542190472. ``` 1542190472 * 100 + 6500 = 154219053714 300 * 100 = 30000 154219053714 / 30000 = 5140635.1238 (5140635.1238 - 5140635.0) * 30000 = 3714 3714 / 100 = 37.14 ``` 37.15 seconds as an offset would be far too much, so this is again used as a calculation divider for the real offset with the base of 5 times the actual interval. Again, the remainder is calculated from the offset and `interval * 5`. This is divided onto base 100 again, with an additional 0.5 seconds delay. Example: offset is 6500, interval 300. ``` 6500 / 300 = 21.666666666666667 (21.666666666666667 - 21.0) * 300 = 200 200 / 100 = 2 2 + 0.5 = 2.5 ``` The minimum value between the first adjustment and the second offset calculation based on the interval is taken, in the above example `2.5` wins. The actual next check time substracts the adjusted time from the future interval addition to provide a more widespread scheduling time among all checkable objects. `nextCheck = now - adj + interval` You may ask, what other values can happen with this offset calculation. Consider calculating more examples with different interval settings. Example: offset is 34567, interval 60, now is 1542190472. ``` 1542190472 * 100 + 34567 = 154219081767 60 * 100 = 6000 154219081767 / 6000 = 25703180.2945 (25703180.2945 - 25703180.0) * 6000 / 100 = 17.67 34567 / 60 = 576.116666666666667 (576.116666666666667 - 576.0) * 60 / 100 + 0.5 = 1.2 ``` `1m` interval starts at `now + 1.2s`. Example: offset is 12345, interval 86400, now is 1542190472. ``` 1542190472 * 100 + 12345 = 154219059545 86400 * 100 = 8640000 154219059545 / 8640000 = 17849.428188078703704 (17849.428188078703704 - 17849) * 8640000 = 3699545 3699545 / 100 = 36995.45 12345 / 86400 = 0.142881944444444 0.142881944444444 * 86400 / 100 + 0.5 = 123.95 ``` `1d` interval starts at `now + 2m4s`. > **Note** > > In case you have a better algorithm at hand, feel free to discuss this in a PR on GitHub. > It needs to fulfill two things: 1) spread and shuffle execution times on each `next_check` update > 2) not too narrowed window for both long and short intervals > Application startup and initial checks need to be handled with care in a slightly different > fashion. When `SetNextCheck()` is called, there are signals registered. One of them sits inside the `CheckerComponent` class whose handler `CheckerComponent::NextCheckChangedHandler()` deletes/inserts the next check event from the scheduling queue. This basically is a list with multiple indexes with the keys for scheduling info and the object. ## Checks ### Check Latency and Execution Time Each check command execution logs the start and end time where Icinga 2 (and the end user) is able to calculate the plugin execution time from it. ```cpp GetExecutionEnd() - GetExecutionStart() ``` The higher the execution time, the higher the command timeout must be set. Furthermore users and developers are encouraged to look into plugin optimizations to minimize the execution time. Sometimes it is better to let an external daemon/script do the checks and feed them back via REST API. Icinga 2 stores the scheduled start and end time for a check. If the actual check execution time differs from the scheduled time, e.g. due to performance problems or limited execution slots (concurrent checks), this value is stored and computed from inside the check result. The difference between the two deltas is called `check latency`. ```cpp (GetScheduleEnd() - GetScheduleStart()) - CalculateExecutionTime() ``` ### Severity The severity attribute is introduced with Icinga v2.11 and provides a bit mask calculated value from specific checkable object states. The severity value is pre-calculated for visualization interfaces such as Icinga Web which sorts the problem dashboard by severity by default. The higher the severity number is, the more important the problem is. However, the formula can change across Icinga 2 releases. ## Cluster This documentation refers to technical roles between cluster endpoints. - The `server` or `parent` role accepts incoming connection attempts and handles requests - The `client` role actively connects to remote endpoints receiving config/commands, requesting certificates, etc. A client role is not necessarily bound to the Icinga agent. It may also be a satellite which actively connects to the master. ### Communication Icinga 2 uses its own certificate authority (CA) by default. The public and private CA keys can be generated on the signing master. Each node certificate must be signed by the private CA key. Note: The following description uses `parent node` and `child node`. This also applies to nodes in the same cluster zone. During the connection attempt, a TLS handshake is performed. If the public certificate of a child node is not signed by the same CA, the child node is not trusted and the connection will be closed. If the TLS handshake succeeds, the parent node reads the certificate's common name (CN) of the child node and looks for a local Endpoint object name configuration. If there is no Endpoint object found, further communication (runtime and config sync, etc.) is terminated. The child node also checks the CN from the parent node's public certificate. If the child node does not find any local Endpoint object name configuration, it will not trust the parent node. Both checks prevent accepting cluster messages from an untrusted source endpoint. If an Endpoint match was found, there is one additional security mechanism in place: Endpoints belong to a Zone hierarchy. Several cluster messages can only be sent "top down", others like check results are allowed being sent from the child to the parent node. Once this check succeeds the cluster messages are exchanged and processed. ### CSR Signing In order to make things easier, Icinga 2 provides built-in methods to allow child nodes to request a signed certificate from the signing master. Icinga 2 v2.8 introduces the possibility to request certificates from indirectly connected nodes. This is required for multi level cluster environments with masters, satellites and agents. CSR Signing in general starts with the master setup. This step ensures that the master is in a working CSR signing state with: * public and private CA key in `/var/lib/icinga2/ca` * private `TicketSalt` constant defined inside the `api` feature * Cluster communication is ready and Icinga 2 listens on port 5665 The child node setup which is run with CLI commands will now attempt to connect to the parent node. This is not necessarily the signing master instance, but could also be a parent satellite node. During this process the child node asks the user to verify the parent node's public certificate to prevent MITM attacks. There are two methods to request signed certificates: * Add the ticket into the request. This ticket was generated on the master beforehand and contains hashed details for which client it has been created. The signing master uses this information to automatically sign the certificate request. * Do not add a ticket into the request. It will be sent to the signing master which stores the pending request. Manual user interaction with CLI commands is necessary to sign the request. The certificate request is sent as `pki::RequestCertificate` cluster message to the parent node. If the parent node is not the signing master, it stores the request in `/var/lib/icinga2/certificate-requests` and forwards the cluster message to its parent node. Once the message arrives on the signing master, it first verifies that the sent certificate request is valid. This is to prevent unwanted errors or modified requests from the "proxy" node. After verification, the signing master checks if the request contains a valid signing ticket. It hashes the certificate's common name and compares the value to the received ticket number. If the ticket is valid, the certificate request is immediately signed with CA key. The request is sent back to the client inside a `pki::UpdateCertificate` cluster message. If the child node was not the certificate request origin, it only updates the cached request for the child node and send another cluster message down to its child node (e.g. from a satellite to an agent). If no ticket was specified, the signing master waits until the `ca sign` CLI command manually signed the certificate. > **Note** > > Push notifications for manual request signing is not yet implemented (TODO). Once the child node reconnects it synchronizes all signed certificate requests. This takes some minutes and requires all nodes to reconnect to each other. #### CSR Signing: Clients without parent connection There is an additional scenario: The setup on a child node does not necessarily need a connection to the parent node. This mode leaves the node in a semi-configured state. You need to manually copy the master's public CA key into `/var/lib/icinga2/certs/ca.crt` on the client before starting Icinga 2. > **Note** > > The `client` in this case can be either a satellite or an agent. The parent node needs to actively connect to the child node. Once this connections succeeds, the child node will actively request a signed certificate. The update procedure works the same way as above. ### High Availability General high availability is automatically enabled between two endpoints in the same cluster zone. **This requires the same configuration and enabled features on both nodes.** HA zone members trust each other and share event updates as cluster messages. This includes for example check results, next check timestamp updates, acknowledgements or notifications. This ensures that both nodes are synchronized. If one node goes away, the remaining node takes over and continues as normal. #### High Availability: Object Authority Cluster nodes automatically determine the authority for configuration objects. By default, all config objects are set to `HARunEverywhere` and as such the object authority is true for any config object on any instance. Specific objects can override and influence this setting, e.g. with `HARunOnce` instead prior to config object activation. This is done when the daemon starts and in a regular interval inside the ApiListener class, specifically calling `ApiListener::UpdateObjectAuthority()`. The algorithm works like this: * Determine whether this instance is assigned to a local zone and endpoint. * Collects all endpoints in this zone if they are connected. * If there's two endpoints, but only us seeing ourselves and the application start is less than 60 seconds in the past, do nothing (wait for cluster reconnect to take place, grace period). * Sort the collected endpoints by name. * Iterate over all config types and their respective objects * Ignore !active objects * Ignore objects which are !HARunOnce. This means, they can run multiple times in a zone and don't need an authority update. * If this instance doesn't have a local zone, set authority to true. This is for non-clustered standalone environments where everything belongs to this instance. * Calculate the object authority based on the connected endpoint names. * Set the authority (true or false) The object authority calculation works "offline" without any message exchange. Each instance alculates the SDBM hash of the config object name, puts that in contrast modulo the connected endpoints size. This index is used to lookup the corresponding endpoint in the connected endpoints array, including the local endpoint. Whether the local endpoint is equal to the selected endpoint, or not, this sets the authority to `true` or `false`. ```cpp authority = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()] == my_endpoint; ``` `ConfigObject::SetAuthority(bool authority)` triggers the following events: * Authority is true and object now paused: Resume the object and set `paused` to `false`. * Authority is false, object not paused: Pause the object and set `paused` to true. **This results in activated but paused objects on one endpoint.** You can verify that by querying the `paused` attribute for all objects via REST API or debug console on both endpoints. Endpoints inside an HA zone calculate the object authority independent from each other. This object authority is important for selected features explained below. Since features are configuration objects too, you must ensure that all nodes inside the HA zone share the same enabled features. If configured otherwise, one might have a checker feature on the left node, nothing on the right node. This leads to late check results because one half is not executed by the right node which holds half of the object authorities. By default, features are enabled to "Run-Everywhere". Specific features which support HA awareness, provide the `enable_ha` configuration attribute. When `enable_ha` is set to `true` (usually the default), "Run-Once" is set and the feature pauses on one side. ``` vim /etc/icinga2/features-enabled/graphite.conf object GraphiteWriter "graphite" { ... enable_ha = true } ``` Once such a feature is paused, there won't be any more event handling, e.g. the Elasticsearch feature won't process any checkresults nor write to the Elasticsearch REST API. When the cluster connection drops, the feature configuration object is updated with the new object authority by the ApiListener timer and resumes its operation. You can see that by grepping the log file for `resumed` and `paused`. ``` [2018-10-24 13:28:28 +0200] information/GraphiteWriter: 'g-ha' paused. ``` ``` [2018-10-24 13:28:28 +0200] information/GraphiteWriter: 'g-ha' resumed. ``` Specific features with HA capabilities are explained below. #### High Availability: Checker The `checker` feature only executes checks for `Checkable` objects (Host, Service) where it is authoritative. That way each node only executes checks for a segment of the overall configuration objects. The cluster message routing ensures that all check results are synchronized to nodes which are not authoritative for this configuration object. #### High Availability: Notifications The `notification` feature only sends notifications for `Notification` objects where it is authoritative. That way each node only executes notifications for a segment of all notification objects. Notified users and other event details are synchronized throughout the cluster. This is required if for example the DB IDO feature is active on the other node. #### High Availability: DB IDO If you don't have HA enabled for the IDO feature, both nodes will write their status and historical data to their own separate database backends. In order to avoid data separation and a split view (each node would require its own Icinga Web 2 installation on top), the high availability option was added to the DB IDO feature. This is enabled by default with the `enable_ha` setting. This requires a central database backend. Best practice is to use a MySQL cluster with a virtual IP. Both Icinga 2 nodes require the connection and credential details configured in their DB IDO feature. During startup Icinga 2 calculates whether the feature configuration object is authoritative on this node or not. The order is an alpha-numeric comparison, e.g. if you have `master1` and `master2`, Icinga 2 will enable the DB IDO feature on `master2` by default. If the connection between endpoints drops, the object authority is re-calculated. In order to prevent data duplication in a split-brain scenario where both nodes would write into the same database, there is another safety mechanism in place. The split-brain decision which node will write to the database is calculated from a quorum inside the `programstatus` table. Each node verifies whether the `endpoint_name` column is not itself on database connect. In addition to that the DB IDO feature compares the `last_update_time` column against the current timestamp plus the configured `failover_timeout` offset. That way only one active DB IDO feature writes to the database, even if they are not currently connected in a cluster zone. This prevents data duplication in historical tables. ### Health Checks #### cluster-zone This built-in check provides the possibility to check for connectivity between zones. If you for example need to know whether the `master` zone is connected and processing messages with the child zone called `satellite` in this example, you can configure the [cluster-zone](10-icinga-template-library.md#itl-icinga-cluster-zone) check as new service on all `master` zone hosts. ``` vim /etc/zones.d/master/host1.conf object Service "cluster-zone-satellite" { check_command = "cluster-zone" host_name = "host1" vars.cluster_zone = "satellite" } ``` The check itself changes to NOT-OK if one or more child endpoints in the child zone are not connected to parent zone endpoints. In addition to the overall connectivity check, the log lag is calculated based on the to-be-sent replay log. Each instance stores that for its configured endpoint objects. This health check iterates over the target zone (`cluster_zone`) and their endpoints. The log lag is greater than zero if * the replay log synchronization is in progress and not yet finished or * the endpoint is not connected, and no replay log sync happened (obviously). The final log lag value is the worst value detected. If satellite1 has a log lag of `1.5` and satellite2 only has `0.5`, the computed value will be `1.5.`. You can control the check state by using optional warning and critical thresholds for the log lag value. If this service exists multiple times, e.g. for each master host object, the log lag may differ based on the execution time. This happens for example on restart of an instance when the log replay is in progress and a health check is executed at different times. If the endpoint is not connected, both master instances may have saved a different log replay position from the last synchronisation. The lag value is returned as performance metric key `slave_lag`. Icinga 2 v2.9+ adds more performance metrics for these values: * `last_messages_sent` and `last_messages_received` as UNIX timestamp * `sum_messages_sent_per_second` and `sum_messages_received_per_second` * `sum_bytes_sent_per_second` and `sum_bytes_received_per_second` ### Config Sync The visible feature for the user is to put configuration files in `/etc/icinga2/zones.d/` and have them synced automatically to all involved zones and endpoints. This not only includes host and service objects being checked in a satellite zone, but also additional config objects such as commands, groups, timeperiods and also templates. Additional thoughts and complexity added: - Putting files into zone directory names removes the burden to set the `zone` attribute on each object in this directory. This is done automatically by the config compiler. - Inclusion of `zones.d` happens automatically, the user shouldn't be bothered about this. - Before the REST API was created, only static configuration files in `/etc/icinga2/zones.d` existed. With the addition of config packages, additional `zones.d` targets must be registered (e.g. used by the Director) - Only one config master is allowed. This one identifies itself with configuration files in `/etc/icinga2/zones.d`. This is not necessarily the zone master seen in the debug logs, that one is important for message routing internally. - Objects and templates which cannot be bound into a specific zone (e.g. hosts in the satellite zone) must be made available "globally". - Users must be able to deny the synchronisation of specific zones, e.g. for security reasons. #### Config Sync: Config Master All zones must be configured and included in the `zones.conf` config file beforehand. The zone names are the identifier for the directories underneath the `/etc/icinga2/zones.d` directory. If a zone is not configured, it will not be included in the config sync - keep this in mind for troubleshooting. When the config master starts, the content of `/etc/icinga2/zones.d` is automatically included. There's no need for an additional entry in `icinga2.conf` like `conf.d`. You can verify this by running the config validation on debug level: ``` icinga2 daemon -C -x debug | grep 'zones.d' [2019-06-19 15:16:19 +0200] notice/ConfigCompiler: Compiling config file: /etc/icinga2/zones.d/global-templates/commands.conf ``` Once the config validation succeeds, the startup routine for the daemon copies the files into the "production" directory in `/var/lib/icinga2/api/zones`. This directory is used for all endpoints where Icinga stores the received configuration. With the exception of the config master retrieving this from `/etc/icinga2/zones.d` instead. These operations are logged for better visibility. ``` [2019-06-19 15:26:38 +0200] information/ApiListener: Copying 1 zone configuration files for zone 'global-templates' to '/var/lib/icinga2/api/zones/global-templates'. [2019-06-19 15:26:38 +0200] information/ApiListener: Updating configuration file: /var/lib/icinga2/api/zones/global-templates//_etc/commands.conf ``` The master is finished at this point. Depending on the cluster configuration, the next iteration is a connected endpoint after successful TLS handshake and certificate authentication. It calls `SendConfigUpdate(client)` which sends the [config::Update](19-technical-concepts.md#technical-concepts-json-rpc-messages-config-update) JSON-RPC message including all required zones and their configuration file content. #### Config Sync: Receive Config The secondary master endpoint and endpoints in a child zone will be connected to the config master. The endpoint receives the [config::Update](19-technical-concepts.md#technical-concepts-json-rpc-messages-config-update) JSON-RPC message and processes the content in `ConfigUpdateHandler()`. This method checks whether config should be accepted. In addition to that, it locks a local mutex to avoid race conditions with multiple syncs in parallel. After that, the received configuration content is analysed. > **Note** > > The cluster design allows that satellite endpoints may connect to the secondary master first. > There is no immediate need to always connect to the config master first, especially since > the satellite endpoints don't know that. > > The secondary master not only stores the master zone config files, but also all child zones. > This is also the case for any HA enabled zone with more than one endpoint. 2.11 puts the received configuration files into a staging directory in `/var/lib/icinga2/api/zones-stage`. Previous versions directly wrote the files into production which could have led to broken configuration on the next manual restart. ``` [2019-06-19 16:08:29 +0200] information/ApiListener: New client connection for identity 'master1' to [127.0.0.1]:5665 [2019-06-19 16:08:30 +0200] information/ApiListener: Applying config update from endpoint 'master1' of zone 'master'. [2019-06-19 16:08:30 +0200] information/ApiListener: Received configuration for zone 'agent' from endpoint 'master1'. Comparing the checksums. [2019-06-19 16:08:30 +0200] information/ApiListener: Stage: Updating received configuration file '/var/lib/icinga2/api/zones-stage/agent//_etc/host.conf' for zone 'agent'. [2019-06-19 16:08:30 +0200] information/ApiListener: Applying configuration file update for path '/var/lib/icinga2/api/zones-stage/agent' (176 Bytes). [2019-06-19 16:08:30 +0200] information/ApiListener: Received configuration for zone 'master' from endpoint 'master1'. Comparing the checksums. [2019-06-19 16:08:30 +0200] information/ApiListener: Applying configuration file update for path '/var/lib/icinga2/api/zones-stage/master' (17 Bytes). [2019-06-19 16:08:30 +0200] information/ApiListener: Received configuration from endpoint 'master1' is different to production, triggering validation and reload. ``` It then validates the received configuration in its own config stage. There is an parameter override in place which disables the automatic inclusion of the production config in `/var/lib/icinga2/api/zones`. Once completed, the reload is triggered. This follows the same configurable timeout as with the global reload. ``` [2019-06-19 16:52:26 +0200] information/ApiListener: Config validation for stage '/var/lib/icinga2/api/zones-stage/' was OK, replacing into '/var/lib/icinga2/api/zones/' and triggering reload. [2019-06-19 16:52:27 +0200] information/Application: Got reload command: Started new instance with PID '19945' (timeout is 300s). [2019-06-19 16:52:28 +0200] information/Application: Reload requested, letting new process take over. ``` Whenever the staged configuration validation fails, Icinga logs this including a reference to the startup log file which includes additional errors. ``` [2019-06-19 15:45:27 +0200] critical/ApiListener: Config validation failed for staged cluster config sync in '/var/lib/icinga2/api/zones-stage/'. Aborting. Logs: '/var/lib/icinga2/api/zones-stage//startup.log' ``` #### Config Sync: Changes and Reload Whenever a new configuration is received, it is validated and upon success, the daemon automatically reloads. While the daemon continues with checks, the reload cannot hand over open TCP connections. That being said, reloading the daemon everytime a configuration is synchronized would lead into many not connected endpoints. Therefore the cluster config sync checks whether the configuration files actually changed, and will only trigger a reload when such a change happened. 2.11 calculates a checksum from each file content and compares this to the production configuration. Previous versions used additional metadata with timestamps from files which sometimes led to problems with asynchronous dates. > **Note** > > For compatibility reasons, the timestamp metadata algorithm is still intact, e.g. > when the client is 2.11 already, but the parent endpoint is still on 2.10. Icinga logs a warning when this happens. ``` Received configuration update without checksums from parent endpoint satellite1. This behaviour is deprecated. Please upgrade the parent endpoint to 2.11+ ``` The debug log provides more details on the actual checksums and checks. Future output may change, use this solely for troubleshooting and debugging whenever the cluster config sync fails. ``` [2019-06-19 16:13:16 +0200] information/ApiListener: Received configuration for zone 'agent' from endpoint 'master1'. Comparing the checksums. [2019-06-19 16:13:16 +0200] debug/ApiListener: Checking for config change between stage and production. Old (3): '{"/.checksums":"7ede1276a9a32019c1412a52779804a976e163943e268ec4066e6b6ec4d15d73","/.timestamp":"ec4354b0eca455f7c2ca386fddf5b9ea810d826d402b3b6ac56ba63b55c2892c","/_etc/host.conf":"35d4823684d83a5ab0ca853c9a3aa8e592adfca66210762cdf2e54339ccf0a44"}' vs. new (3): '{"/.checksums":"84a586435d732327e2152e7c9b6d85a340cc917b89ae30972042f3dc344ea7cf","/.timestamp":"0fd6facf35e49ab1b2a161872fa7ad794564eba08624373d99d31c32a7a4c7d3","/_etc/host.conf":"0d62075e89be14088de1979644b40f33a8f185fcb4bb6ff1f7da2f63c7723fcb"}'. [2019-06-19 16:13:16 +0200] debug/ApiListener: Checking /_etc/host.conf for checksum: 35d4823684d83a5ab0ca853c9a3aa8e592adfca66210762cdf2e54339ccf0a44 [2019-06-19 16:13:16 +0200] debug/ApiListener: Path '/_etc/host.conf' doesn't match old checksum '0d62075e89be14088de1979644b40f33a8f185fcb4bb6ff1f7da2f63c7723fcb' with new checksum '35d4823684d83a5ab0ca853c9a3aa8e592adfca66210762cdf2e54339ccf0a44'. ``` #### Config Sync: Trust The config sync follows the "top down" approach, where the master endpoint in the master zone is allowed to synchronize configuration to the child zone, e.g. the satellite zone. Endpoints in the same zone, e.g. a secondary master, receive configuration for the same zone and all child zones. Endpoints in the satellite zone trust the parent zone, and will accept the pushed configuration via JSON-RPC cluster messages. By default, this is disabled and must be enabled with the `accept_config` attribute in the ApiListener feature (manually or with CLI helpers). The satellite zone will not only accept zone configuration for its own zone, but also all configured child zones. That is why it is important to configure the zone hierarchy on the satellite as well. Child zones are not allowed to sync configuration up to the parent zone. Each Icinga instance evaluates this in startup and knows on endpoint connect which config zones need to be synced. Global zones have a special trust relationship: They are synced to all child zones, be it a satellite zone or agent zone. Since checkable objects such as a Host or a Service object must have only one endpoint as authority, they cannot be put into a global zone (denied by the config compiler). Apply rules and templates are allowed, since they are evaluated in the endpoint which received the synced configuration. Keep in mind that there may be differences on the master and the satellite when e.g. hostgroup membership is used for assign where expressions, but the groups are only available on the master. ### Cluster: Message Routing One fundamental part of the cluster message routing is the MessageOrigin object. This is created when a new JSON-RPC message is received in `JsonRpcConnection::MessageHandler()`. It contains - FromZone being extracted from the endpoint object which owns the JsonRpcConnection - FromClient being the JsonRpcConnection bound to the endpoint object These attributes are checked in message receive api handlers for security access. E.g. whether a message origin is from a child zone which is not allowed, etc. This is explained in the [JSON-RPC messages](19-technical-concepts.md#technical-concepts-json-rpc-messages) chapter. Whenever such a message is processed on the client, it may trigger additional cluster events which are sent back to other endpoints. Therefore it is key to always pass the MessageOrigin `origin` when processing these messages locally. Example: - Client receives a CheckResult from another endpoint in the same zone, call it `sender` for now - Calls ProcessCheckResult() to store the CR and calculcate states, notifications, etc. - Calls the OnNewCheckResult() signal to trigger IDO updates OnNewCheckResult() also calls a registered cluster handler which forwards the CheckResult to other cluster members. Without any origin details, this CheckResult would be relayed to the `sender` endpoint again. Which processes the message, ProcessCheckResult(), OnNewCheckResult(), sends back and so on. That creates a loop which our cluster protocol needs to prevent at all cost. RelayMessageOne() takes care of the routing. This involves fetching the targetZone for this message and its endpoints. - Don't relay messages to ourselves. - Don't relay messages to disconnected endpoints. - Don't relay the message to the zone through more than one endpoint unless this is our own zone. - Don't relay messages back to the endpoint which we got the message from. **THIS** - Don't relay messages back to the zone which we got the message from. - Only relay message to the zone master if we're not currently the zone master. ``` e1 is zone master, e2 and e3 are zone members. Message is sent from e2 or e3: !isMaster == true targetEndpoint e1 is zone master -> send the message targetEndpoint e3 is not zone master -> skip it, avoid routing loops Message is sent from e1: !isMaster == false -> send the messages to e2 and e3 being the zone routing master. ``` With passing the `origin` the following condition prevents sending a message back to sender: ```cpp if (origin && origin->FromClient && targetEndpoint == origin->FromClient->GetEndpoint()) { ``` This message then simply gets skipped for this specific Endpoint and is never sent. This analysis originates from a long-lasting [downtime loop bug](https://github.com/Icinga/icinga2/issues/7198). ## TLS Network IO ### TLS Connection Handling Icinga supports two connection directions, controlled via the `host` attribute inside the Endpoint objects: * Outgoing connection attempts * Incoming connection handling Once the connection is established, higher layers can exchange JSON-RPC and HTTP messages. It doesn't matter which direction these message go. This offers a big advantage over single direction connections, just like polling via HTTP only. Also, connections are kept alive as long as data is transmitted. When the master connects to the child zone member(s), this requires more resources there. Keep this in mind when endpoints are not reachable, the TCP timeout blocks other resources. Moving a satellite zone in the middle between masters and agents helps to split the tasks - the master processes and stores data, deploys configuration and serves the API. The satellites schedule the checks, connect to the agents and receive check results. Agents/Clients can also connect to the parent endpoints - be it a master or a satellite. This is the preferred way out of a DMZ, and also reduces the overhead with connecting to e.g. 2000 agents on the master. You can benchmark this when TCP connections are broken and timeouts are encountered. #### Master Processes Incoming Connection * The node starts a new ApiListener, this invokes `AddListener()` * Setup TLS Context (SslContext) * Initialize global I/O engine and create a TCP acceptor * Resolve bind host/port (optional) * Listen on IPv4 and IPv6 * Re-use socket address and port * Listen on port 5665 with `INT_MAX` possible sockets * Spawn a new Coroutine which listens for new incoming connections as 'TCP server' pattern * Accept new connections asynchronously * Spawn a new Coroutine which handles the new client connection in a different context, Role: Server #### Master Connects Outgoing * The node starts a timer in a 10 seconds interval with `ApiReconnectTimerHandler()` as callback * Loop over all configured zones, exclude global zones and not direct parent/child zones * Get the endpoints configured in the zones, exclude: local endpoint, no 'host' attribute, already connected or in progress * Call `AddConnection()` * Spawn a new Coroutine after making the TLS context * Use the global I/O engine for socket I/O * Create TLS stream * Connect to endpoint host/port details * Handle the client connection, Role: Client #### TLS Handshake * Create a TLS connection in sslConn and perform an asynchronous TLS handshake * Get the peer certificate * Verify the presented certificate: `ssl::verify_peer` and `ssl::verify_client_once` * Get the certificate CN and compare it against the endpoint name - if not matching, return and close the connection #### Data Exchange Everything runs through TLS, we don't use any "raw" connections nor plain message handling. HTTP and JSON-RPC messages share the same port and API, so additional handling is required. On a new connection and successful TLS handshake, the first byte is read. This either is a JSON-RPC message in Netstring format starting with a number, or plain HTTP. ``` HTTP/1.1 2:{} ``` Depending on this, `ClientJsonRpc` or `ClientHttp` are assigned. JSON-RPC: * Create a new JsonRpcConnection object * When the endpoint object is configured, spawn a Coroutine which takes care of syncing the client (file and runtime config, replay log, etc.) * No endpoint treats this connection as anonymous client, with a configurable limit. This client may send a CSR signing request for example. * Start the JsonRpcConnection - this spawns Coroutines to HandleIncomingMessages, WriteOutgoingMessages, HandleAndWriteHeartbeats and CheckLiveness HTTP: * Create a new HttpServerConnection * Start the HttpServerConnection - this spawns Coroutines to ProcessMessages and CheckLiveness All the mentioned Coroutines run asynchronously using the global I/O engine's context. More details on this topic can be found in [this blogpost](https://www.netways.de/blog/2019/04/04/modern-c-programming-coroutines-with-boost/). The lower levels of context switching and sharing or event polling are hidden in Boost ASIO, Beast, Coroutine and Context libraries. #### Data Exchange: Coroutines and I/O Engine Light-weight and fast operations such as connection handling or TLS handshakes are performed in the default `IoBoundWorkSlot` pool inside the I/O engine. The I/O engine has another pool available: `CpuBoundWork`. This is used for processing CPU intensive tasks, such as handling a HTTP request. Depending on the available CPU cores, this is limited to `std::thread::hardware_concurrency() * 3u / 2u`. ``` 1 core * 3 / 2 = 1 2 cores * 3 / 2 = 3 8 cores * 3 / 2 = 12 16 cores * 3 / 2 = 24 ``` The I/O engine itself is used with all network I/O in Icinga, not only the cluster and the REST API. Features such as Graphite, InfluxDB, etc. also consume its functionality. There are 2 * CPU cores threads available which run the event loop in the I/O engine. This polls the I/O service with `m_IoService.run();` and triggers an asynchronous event progress for waiting coroutines. ## JSON-RPC Message API **The JSON-RPC message API is not a public API for end users.** In case you want to interact with Icinga, use the [REST API](12-icinga2-api.md#icinga2-api). This section describes the internal cluster messages exchanged between endpoints. > **Tip** > > Debug builds with `icinga2 daemon -DInternal.DebugJsonRpc=1` unveils the JSON-RPC messages. ### Registered Handler Functions Functions by example: Event Sender: `Checkable::OnNewCheckResult` ``` On.connect(&xyzHandler) ``` Event Receiver (Client): `CheckResultAPIHandler` in `REGISTER_APIFUNCTION` ``` APIHandler() ``` ### Messages #### icinga::Hello > Location: `apilistener.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | icinga::Hello params | Dictionary ##### Params Key | Type | Description ---------------------|-------------|------------------ capabilities | Number | Bitmask, see `lib/remote/apilistener.hpp`. version | Number | Icinga 2 version, e.g. 21300 for v2.13.0. ##### Functions Event Sender: When a new client connects in `NewClientHandlerInternal()`. Event Receiver: `HelloAPIHandler` ##### Permissions None, this is a required message. #### event::Heartbeat > Location: `jsonrpcconnection-heartbeat.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::Heartbeat params | Dictionary ##### Params Key | Type | Description ----------|---------------|------------------ timeout | Number | Heartbeat timeout, sender sets 120s. ##### Functions Event Sender: `JsonRpcConnection::HeartbeatTimerHandler` Event Receiver: `HeartbeatAPIHandler` Both sender and receiver exchange this heartbeat message. If the sender detects that a client endpoint hasn't sent anything in the updated timeout span, it disconnects the client. This is to avoid stale connections with no message processing. ##### Permissions None, this is a required message. #### event::CheckResult > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::CheckResult params | Dictionary ##### Params Key | Type | Description ----------|---------------|------------------ host | String | Host name service | String | Service name cr | Serialized CR | Check result ##### Functions Event Sender: `Checkable::OnNewCheckResult` Event Receiver: `CheckResultAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Hosts/services do not exist * Origin is a remote command endpoint different to the configured, and whose zone is not allowed to access this checkable. #### event::SetNextCheck > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetNextCheck params | Dictionary ##### Params Key | Type | Description ------------|---------------|------------------ host | String | Host name service | String | Service name next\_check | Timestamp | Next scheduled time as UNIX timestamp. ##### Functions Event Sender: `Checkable::OnNextCheckChanged` Event Receiver: `NextCheckChangedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::SetLastCheckStarted > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetLastCheckStarted params | Dictionary ##### Params Key | Type | Description ---------------------|-----------|------------------ host | String | Host name service | String | Service name last\_check\_started | Timestamp | Last check's start time as UNIX timestamp. ##### Functions Event Sender: `Checkable::OnLastCheckStartedChanged` Event Receiver: `LastCheckStartedChangedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::SetStateBeforeSuppression > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------------------------------- jsonrpc | 2.0 method | event::SetStateBeforeSuppression params | Dictionary ##### Params Key | Type | Description ---------------------------|--------|----------------------------------------------- host | String | Host name service | String | Service name state\_before\_suppression | Number | Checkable state before the current suppression ##### Functions Event Sender: `Checkable::OnStateBeforeSuppressionChanged` Event Receiver: `StateBeforeSuppressionChangedAPIHandler` Used to sync the checkable state from before a notification suppression (for example because the checkable is in a downtime) started within the same HA zone. ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint is not within the local zone. #### event::SetSuppressedNotifications > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetSuppressedNotifications params | Dictionary ##### Params Key | Type | Description -------------------------|---------------|------------------ host | String | Host name service | String | Service name supressed\_notifications | Number | Bitmask for suppressed notifications. ##### Functions Event Sender: `Checkable::OnSuppressedNotificationsChanged` Event Receiver: `SuppressedNotificationsChangedAPIHandler` Used to sync the notification state of a host or service object within the same HA zone. ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint is not within the local zone. #### event::SetSuppressedNotificationTypes > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetSuppressedNotificationTypes params | Dictionary ##### Params Key | Type | Description -------------------------|--------|------------------ notification | String | Notification name supressed\_notifications | Number | Bitmask for suppressed notifications. Used to sync the state of a notification object within the same HA zone. ##### Functions Event Sender: `Notification::OnSuppressedNotificationsChanged` Event Receiver: `SuppressedNotificationTypesChangedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Notification does not exist. * Origin endpoint is not within the local zone. #### event::SetNextNotification > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetNextNotification params | Dictionary ##### Params Key | Type | Description -------------------|---------------|------------------ host | String | Host name service | String | Service name notification | String | Notification name next\_notification | Timestamp | Next scheduled notification time as UNIX timestamp. ##### Functions Event Sender: `Notification::OnNextNotificationChanged` Event Receiver: `NextNotificationChangedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Notification does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::UpdateLastNotifiedStatePerUser > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::UpdateLastNotifiedStatePerUser params | Dictionary ##### Params Key | Type | Description -------------|--------|------------------ notification | String | Notification name user | String | User name state | Number | Checkable state the user just got a problem notification for Used to sync the state of a notification object within the same HA zone. ##### Functions Event Sender: `Notification::OnLastNotifiedStatePerUserUpdated` Event Receiver: `LastNotifiedStatePerUserUpdatedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Notification does not exist. * Origin endpoint is not within the local zone. #### event::ClearLastNotifiedStatePerUser > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::ClearLastNotifiedStatePerUser params | Dictionary ##### Params Key | Type | Description -------------|--------|------------------ notification | String | Notification name Used to sync the state of a notification object within the same HA zone. ##### Functions Event Sender: `Notification::OnLastNotifiedStatePerUserCleared` Event Receiver: `LastNotifiedStatePerUserClearedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Notification does not exist. * Origin endpoint is not within the local zone. #### event::SetForceNextCheck > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetForceNextCheck params | Dictionary ##### Params Key | Type | Description ----------|---------------|------------------ host | String | Host name service | String | Service name forced | Boolean | Forced next check (execute now) ##### Functions Event Sender: `Checkable::OnForceNextCheckChanged` Event Receiver: `ForceNextCheckChangedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::SetForceNextNotification > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetForceNextNotification params | Dictionary ##### Params Key | Type | Description ----------|---------------|------------------ host | String | Host name service | String | Service name forced | Boolean | Forced next check (execute now) ##### Functions Event Sender: `Checkable::SetForceNextNotification` Event Receiver: `ForceNextNotificationChangedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::SetAcknowledgement > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetAcknowledgement params | Dictionary ##### Params Key | Type | Description -----------|---------------|------------------ host | String | Host name service | String | Service name author | String | Acknowledgement author name. comment | String | Acknowledgement comment content. acktype | Number | Acknowledgement type (0=None, 1=Normal, 2=Sticky) notify | Boolean | Notification should be sent. persistent | Boolean | Whether the comment is persistent. expiry | Timestamp | Optional expire time as UNIX timestamp. ##### Functions Event Sender: `Checkable::OnForceNextCheckChanged` Event Receiver: `ForceNextCheckChangedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::ClearAcknowledgement > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::ClearAcknowledgement params | Dictionary ##### Params Key | Type | Description ----------|---------------|------------------ host | String | Host name service | String | Service name ##### Functions Event Sender: `Checkable::OnAcknowledgementCleared` Event Receiver: `AcknowledgementClearedAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::SendNotifications > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SendNotifications params | Dictionary ##### Params Key | Type | Description ----------|---------------|------------------ host | String | Host name service | String | Service name cr | Serialized CR | Check result type | Number | enum NotificationType, same as `types` for notification objects. author | String | Author name text | String | Notification text ##### Functions Event Sender: `Checkable::OnNotificationsRequested` Event Receiver: `SendNotificationsAPIHandler` Signals that notifications have to be sent within the same HA zone. This is relevant if the checkable and its notifications are active on different endpoints. ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint is not within the local zone. #### event::NotificationSentUser > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::NotificationSentUser params | Dictionary ##### Params Key | Type | Description --------------|-----------------|------------------ host | String | Host name service | String | Service name notification | String | Notification name. user | String | Notified user name. type | Number | enum NotificationType, same as `types` in Notification objects. cr | Serialized CR | Check result. author | String | Notification author (for specific types) text | String | Notification text (for specific types) command | String | Notification command name. ##### Functions Event Sender: `Checkable::OnNotificationSentToUser` Event Receiver: `NotificationSentUserAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone the same as the receiver. This binds notification messages to the HA zone. #### event::NotificationSentToAllUsers > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::NotificationSentToAllUsers params | Dictionary ##### Params Key | Type | Description ----------------------------|-----------------|------------------ host | String | Host name service | String | Service name notification | String | Notification name. users | Array of String | Notified user names. type | Number | enum NotificationType, same as `types` in Notification objects. cr | Serialized CR | Check result. author | String | Notification author (for specific types) text | String | Notification text (for specific types) last\_notification | Timestamp | Last notification time as UNIX timestamp. next\_notification | Timestamp | Next scheduled notification time as UNIX timestamp. notification\_number | Number | Current notification number in problem state. last\_problem\_notification | Timestamp | Last problem notification time as UNIX timestamp. no\_more\_notifications | Boolean | Whether to send future notifications when this notification becomes active on this HA node. ##### Functions Event Sender: `Checkable::OnNotificationSentToAllUsers` Event Receiver: `NotificationSentToAllUsersAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone the same as the receiver. This binds notification messages to the HA zone. #### event::ExecuteCommand > Location: `clusterevents-check.cpp` and `checkable-check.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::ExecuteCommand params | Dictionary ##### Params Key | Type | Description ---------------|---------------|------------------ host | String | Host name. service | String | Service name. command\_type | String | `check_command` or `event_command`. command | String | CheckCommand or EventCommand name. check\_timeout | Number | Check timeout of the checkable object, if specified as `check_timeout` attribute. macros | Dictionary | Command arguments as key/value pairs for remote execution. endpoint | String | The endpoint to execute the command on. deadline | Number | A Unix timestamp indicating the execution deadline source | String | The execution UUID ##### Functions **Event Sender:** This gets constructed directly in `Checkable::ExecuteCheck()`, `Checkable::ExecuteEventHandler()` or `ApiActions::ExecuteCommand()` when a remote command endpoint is configured. * `Get{CheckCommand,EventCommand}()->Execute()` simulates an execution and extracts all command arguments into the `macro` dictionary (inside lib/methods tasks). * When the endpoint is connected, the message is constructed and sent directly. * When the endpoint is not connected and not syncing replay logs and 5m after application start, generate an UNKNOWN check result for the user ("not connected"). **Event Receiver:** `ExecuteCommandAPIHandler` Special handling, calls `ClusterEvents::EnqueueCheck()` for command endpoint checks. This function enqueues check tasks into a queue which is controlled in `RemoteCheckThreadProc()`. If the `endpoint` parameter is specified and is not equal to the local endpoint then the message is forwarded to the correct endpoint zone. ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Origin endpoint's zone is not a parent zone of the receiver endpoint. * `accept_commands = false` in the `api` feature configuration sends back an UNKNOWN check result to the sender. The receiver constructs a virtual host object and looks for the local CheckCommand object. Returns UNKNOWN as check result to the sender * when the CheckCommand object does not exist. * when there was an exception triggered from check execution, e.g. the plugin binary could not be executed or similar. The returned messages are synced directly to the sender's endpoint, no cluster broadcast. > **Note**: EventCommand errors are just logged on the remote endpoint. #### event::UpdateExecutions > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::UpdateExecutions params | Dictionary ##### Params Key | Type | Description ---------------|---------------|------------------ host | String | Host name. service | String | Service name. executions | Dictionary | Executions to be updated ##### Functions **Event Sender:** `ClusterEvents::ExecutedCommandAPIHandler`, `ClusterEvents::UpdateExecutionsAPIHandler`, `ApiActions::ExecuteCommand` **Event Receiver:** `ClusterEvents::UpdateExecutionsAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::ExecutedCommand > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::ExecutedCommand params | Dictionary ##### Params Key | Type | Description ---------------|---------------|------------------ host | String | Host name. service | String | Service name. execution | String | The execution ID executed. exitStatus | Number | The command exit status. output | String | The command output. start | Number | The unix timestamp at the start of the command execution end | Number | The unix timestamp at the end of the command execution ##### Functions **Event Sender:** `ClusterEvents::ExecuteCheckFromQueue`, `ClusterEvents::ExecuteCommandAPIHandler` **Event Receiver:** `ClusterEvents::ExecutedCommandAPIHandler` ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Checkable does not exist. * Origin endpoint's zone is not allowed to access this checkable. #### event::SetRemovalInfo > Location: `clusterevents.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | event::SetRemovalInfo params | Dictionary ##### Params Key | Type | Description ---------------|-------------|--------------------------------- object\_type | String | Object type (`"Comment"` or `"Downtime"`) object\_name | String | Object name removed\_by | String | Name of the removal requestor remove\_time | Timestamp | Time of the remove operation ##### Functions **Event Sender**: `Comment::OnRemovalInfoChanged` and `Downtime::OnRemovalInfoChanged` **Event Receiver**: `SetRemovalInfoAPIHandler` This message is used to synchronize information about manual comment and downtime removals before deleting the corresponding object. ##### Permissions This message is only accepted from the local zone and from parent zones. #### config::Update > Location: `apilistener-filesync.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | config::Update params | Dictionary ##### Params Key | Type | Description -----------|---------------|------------------ update | Dictionary | Config file paths and their content. update\_v2 | Dictionary | Additional meta config files introduced in 2.4+ for compatibility reasons. ##### Functions **Event Sender:** `SendConfigUpdate()` called in `ApiListener::SyncClient()` when a new client endpoint connects. **Event Receiver:** `ConfigUpdateHandler` reads the config update content and stores them in `/var/lib/icinga2/api`. When it detects a configuration change, the function requests and application restart. ##### Permissions The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * The origin sender is not in a parent zone of the receiver. * `api` feature does not accept config. Config updates will be ignored when: * The zone is not configured on the receiver endpoint. * The zone is authoritative on this instance (this only happens on a master which has `/etc/icinga2/zones.d` populated, and prevents sync loops) #### config::UpdateObject > Location: `apilistener-configsync.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | config::UpdateObject params | Dictionary ##### Params Key | Type | Description ---------------------|-------------|------------------ name | String | Object name. type | String | Object type name. version | Number | Object version. config | String | Config file content for `_api` packages. modified\_attributes | Dictionary | Modified attributes at runtime as key value pairs. original\_attributes | Array | Original attributes as array of keys. ##### Functions **Event Sender:** Either on client connect (full sync), or runtime created/updated object `ApiListener::SendRuntimeConfigObjects()` gets called when a new endpoint is connected and runtime created config objects need to be synced. This invokes a call to `UpdateConfigObject()` to only sync this JsonRpcConnection client. `ConfigObject::OnActiveChanged` (created or deleted) or `ConfigObject::OnVersionChanged` (updated) also call `UpdateConfigObject()`. **Event Receiver:** `ConfigUpdateObjectAPIHandler` calls `ConfigObjectUtility::CreateObject()` in order to create the object if it is not already existing. Afterwards, all modified attributes are applied and in case, original attributes are restored. The object version is set as well, keeping it in sync with the sender. ##### Permissions ###### Sender Client receiver connects: The sender only syncs config object updates to a client which can access the config object, in `ApiListener::SendRuntimeConfigObjects()`. In addition to that, the client endpoint's zone is checked whether this zone may access the config object. Runtime updated object: Only if the config object belongs to the `_api` package. ###### Receiver The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Origin sender endpoint's zone is in a child zone. * `api` feature does not accept config * The received config object type does not exist (this is to prevent failures with older nodes and new object types). Error handling: * Log an error if `CreateObject` fails (only if the object does not already exist) * Local object version is newer than the received version, object will not be updated. * Compare modified and original attributes and restore any type of change here. #### config::DeleteObject > Location: `apilistener-configsync.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | config::DeleteObject params | Dictionary ##### Params Key | Type | Description --------------------|-------------|------------------ name | String | Object name. type | String | Object type name. version | Number | Object version. ##### Functions **Event Sender:** `ConfigObject::OnActiveChanged` (created or deleted) or `ConfigObject::OnVersionChanged` (updated) call `DeleteConfigObject()`. **Event Receiver:** `ConfigDeleteObjectAPIHandler` ##### Permissions ###### Sender Runtime deleted object: Only if the config object belongs to the `_api` package. ###### Receiver The receiver will not process messages from not configured endpoints. Message updates will be dropped when: * Origin sender endpoint's zone is in a child zone. * `api` feature does not accept config * The received config object type does not exist (this is to prevent failures with older nodes and new object types). * The object in question was not created at runtime, it does not belong to the `_api` package. Error handling: * Log an error if `DeleteObject` fails (only if the object does not already exist) #### pki::RequestCertificate > Location: `jsonrpcconnection-pki.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | pki::RequestCertificate params | Dictionary ##### Params Key | Type | Description --------------|---------------|------------------ ticket | String | Own ticket, or as satellite in CA proxy from local store. cert\_request | String | Certificate request content from local store, optional. ##### Functions Event Sender: `RequestCertificateHandler` Event Receiver: `RequestCertificateHandler` ##### Permissions This is an anonymous request, and the number of anonymous clients can be configured in the `api` feature. Only valid certificate request messages are processed, and valid signed certificates won't be signed again. #### pki::UpdateCertificate > Location: `jsonrpcconnection-pki.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | pki::UpdateCertificate params | Dictionary ##### Params Key | Type | Description ---------------------|---------------|------------------ status\_code | Number | Status code, 0=ok. cert | String | Signed certificate content. ca | String | Public CA certificate content. fingerprint\_request | String | Certificate fingerprint from the CSR. ##### Functions **Event Sender:** * When a client requests a certificate in `RequestCertificateHandler` and the satellite already has a signed certificate, the `pki::UpdateCertificate` message is constructed and sent back. * When the endpoint holding the master's CA private key (and TicketSalt private key) is able to sign the request, the `pki::UpdateCertificate` message is constructed and sent back. **Event Receiver:** `UpdateCertificateHandler` ##### Permissions Message updates are dropped when * The origin sender is not in a parent zone of the receiver. * The certificate fingerprint is in an invalid format. #### log::SetLogPosition > Location: `apilistener.cpp` and `jsonrpcconnection.cpp` ##### Message Body Key | Value ----------|--------- jsonrpc | 2.0 method | log::SetLogPosition params | Dictionary ##### Params Key | Type | Description --------------------|---------------|------------------ log\_position | Timestamp | The endpoint's log position as UNIX timestamp. ##### Functions **Event Sender:** During log replay to a client endpoint in `ApiListener::ReplayLog()`, each processed file generates a message which updates the log position timestamp. `ApiListener::ApiTimerHandler()` invokes a check to keep all connected endpoints and their log position in sync during replay log. **Event Receiver:** `SetLogPositionHandler` ##### Permissions The receiver will not process messages from not configured endpoints. icinga2-2.14.6/doc/20-script-debugger.md000066400000000000000000000127311501332562400175210ustar00rootroot00000000000000# Script Debugger You can run the Icinga 2 daemon with the `-X` (`--script-debugger`) parameter to enable the script debugger: ```bash icinga2 daemon -X ``` When an exception occurs or the [debugger](17-language-reference.md#breakpoints) keyword is encountered in a user script, Icinga 2 launches a console that allows the user to debug the script. You can also attach the script debugger to the [configuration validation](11-cli-commands.md#config-validation): ```bash icinga2 daemon -C -X ``` Here is a list of common errors which can be diagnosed with the script debugger: * Configuration errors e.g. [apply rules](03-monitoring-basics.md#using-apply) * Errors in user-defined [functions](17-language-reference.md#functions) ## Debugging Configuration Errors The following example illustrates the problem of a service [apply rule](03-monitoring-basics.md#using-apply-for) which expects a dictionary value for `config`, but the host custom variable only provides a string value: ``` object Host "script-debugger-host" { check_command = "icinga" vars.http_vhosts["example.org"] = "192.168.1.100" // a string value } apply Service for (http_vhost => config in host.vars.http_vhosts) { import "generic-service" vars += config // expects a dictionary check_command = "http" } ``` The error message on config validation will warn about the wrong value type, but does not provide any context which objects are affected. Enable the script debugger and run the config validation: ``` # icinga2 daemon -C -X Breakpoint encountered in /etc/icinga2/conf.d/services.conf: 59:67-65:1 Exception: Error: Error while evaluating expression: Cannot convert value of type 'String' to an object. Location: /etc/icinga2/conf.d/services.conf(62): check_command = "http" /etc/icinga2/conf.d/services.conf(63): /etc/icinga2/conf.d/services.conf(64): vars += config ^^^^^^^^^^^^^^ /etc/icinga2/conf.d/services.conf(65): } /etc/icinga2/conf.d/services.conf(66): You can inspect expressions (such as variables) by entering them at the prompt. To leave the debugger and continue the program use "$continue". <1> => ``` You can print the variables `vars` and `config` to get an idea about their values: ``` <1> => vars null <2> => config "192.168.1.100" <3> => ``` The `vars` attribute has to be a dictionary. Trying to set this attribute to a string caused the error in our configuration example. In order to determine the name of the host where the value of the `config` variable came from you can inspect attributes of the service object: ``` <3> => host_name "script-debugger-host-01" <4> => name "http" ``` Additionally you can view the service object attributes by printing the value of `this`. ## Using Breakpoints In order to halt execution in a script you can use the `debugger` keyword: ``` object Host "script-debugger-host-02" { check_command = "dummy" check_interval = 5s vars.dummy_text = {{ var text = "Hello from " + macro("$name$") debugger return text }} } ``` Icinga 2 will spawn a debugger console every time the function is executed: ``` # icinga2 daemon -X ... Breakpoint encountered in /etc/icinga2/tests/script-debugger.conf: 7:5-7:12 You can inspect expressions (such as variables) by entering them at the prompt. To leave the debugger and continue the program use "$continue". <1> => text "Hello from script-debugger-host-02" <2> => $continue ``` ## Debugging API Filters Queries against the [Icinga 2 REST API](12-icinga2-api.md#icinga2-api) can use filters, just like available in `assign where` expressions. If these filters cause an internal error, they return an empty result to the caller. In order to analyse these server-side errors, you can use the script debugger. The following example tries filter for all host objects where the custom variable `os` is set. There are various possibilities to check that, one of them would be `host.vars.os != ""`. Another idea is to use the [contains](18-library-reference.md#dictionary-contains) method on the custom attribute dictionary like this: `host.vars.contains("os")`. ```bash curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' \ -X POST 'https://localhost:5665/v1/objects/services' \ -d '{ "filter": "host.vars.contains(\"os\")", "attrs": [ "__name" ], "joins": [ "host.name", "host.vars" ], "pretty": true }' ``` This will fail on all hosts which don't have any custom variable specified. ``` # icinga2 daemon -X Breakpoint encountered. Exception: Error: Argument is not a callable object. Location: in : 1:0-1:23 You can inspect expressions (such as variables) by entering them at the prompt. To leave the debugger and continue the program use "$continue". <1> => this.host ... vars = null <2> => $continue ``` By definition, a type method can only be invoked on an actual object. In order to stay safe, add more checks to the API filter: - `host.vars && host.vars.contains("os")` or - `host.vars && typeof(host.vars) == Dictionary && host.vars.contains("os")` Example: ```bash curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' \ -X POST 'https://localhost:5665/v1/objects/services' \ -d '{ "filter": "host.vars && typeof(host.vars) == Dictionary && host.vars.contains(\"os\")", "attrs": [ "__name" ], "joins": [ "host.name", "host.vars" ], "pretty": true }' ``` icinga2-2.14.6/doc/21-development.md000066400000000000000000002562141501332562400167640ustar00rootroot00000000000000# Development This chapter provides hints on Icinga 2 debugging, development, package builds and tests. * [Debug Icinga 2](21-development.md#development-debug) * [GDB Backtrace](21-development.md#development-debug-gdb-backtrace) * [Core Dump](21-development.md#development-debug-core-dump) * [Test Icinga 2](21-development.md#development-tests) * [Snapshot Packages (Nightly Builds)](21-development.md#development-tests-snapshot-packages) * [Develop Icinga 2](21-development.md#development-develop) * [Preparations](21-development.md#development-develop-prepare) * [Design Patterns](21-development.md#development-develop-design-patterns) * [Build Tools](21-development.md#development-develop-builds-tools) * [Unit Tests](21-development.md#development-develop-tests) * [Style Guide](21-development.md#development-develop-styleguide) * [Development Environment](21-development.md#development-environment) * [Linux Dev Environment](21-development.md#development-linux-dev-env) * [macOS Dev Environment](21-development.md#development-macos-dev-env) * [Windows Dev Environment](21-development.md#development-windows-dev-env) * [Package Builds](21-development.md#development-package-builds) * [RPM](21-development.md#development-package-builds-rpms) * [DEB](21-development.md#development-package-builds-deb) * [Windows](21-development.md#development-package-builds-windows) * [Continuous Integration](21-development.md#development-ci) * [Advanced Tips](21-development.md#development-advanced) ## Debug Icinga 2 This chapter targets all users who have been asked by developers to provide a stack trace or coredump if the application crashed. It is also useful for developers working with different debuggers. > **Note:** > > This is intentionally mentioned before any development insights > as debugging is a more frequent and commonly asked question. ### Debug Requirements Make sure that the debug symbols are available for Icinga 2. The Icinga 2 packages provide a debug package which must be installed separately for all involved binaries, like `icinga2-bin` or `icinga2-ido-mysql`. Distribution | Command -------------------|------------------------------------------ Debian/Ubuntu | `apt-get install icinga2-dbg` RHEL | `yum install icinga2-debuginfo` Fedora | `dnf install icinga2-debuginfo icinga2-bin-debuginfo icinga2-ido-mysql-debuginfo` SLES/openSUSE | `zypper install icinga2-bin-debuginfo icinga2-ido-mysql-debuginfo` Furthermore, you may also have to install debug symbols for Boost and your C++ library. If you're building your own binaries, you should use the `-DCMAKE_BUILD_TYPE=Debug` cmake build flag for debug builds. ### GDB as Debugger Install GDB in your development environment. Distribution | Command -------------------|------------------------------------------ Debian/Ubuntu | `apt-get install gdb` RHEL | `yum install gdb` Fedora | `dnf install gdb` SLES/openSUSE | `zypper install gdb` #### GDB Run Run the icinga2 binary `/usr/lib{,64}/icinga2/sbin/icinga2` with gdb, `/usr/bin/icinga2` is a shell wrapper. ``` gdb --args /usr/lib/icinga2/sbin/icinga2 daemon (gdb) set follow-fork-mode child ``` When gdb halts on SIGUSR2, press `c` to continue. This signal originates from the umbrella process and can safely be ignored. > **Note** > > Since v2.11 we would attach to the umbrella process spawned with `/usr/lib/icinga2/sbin/icinga2`, > therefore rather attach to a running process. > ```bash # Typically the order of PIDs is: 1) umbrella 2) spawn helper 3) main process pidof icinga2 gdb -p $(pidof icinga2 | cut -d ' ' -f3) ``` > **Note** > > If gdb tells you it's missing debug symbols, quit gdb and install > them: `Missing separate debuginfos, use: debuginfo-install ...` Run/restart the application. ``` (gdb) r ``` Kill the running application. ``` (gdb) k ``` Continue after breakpoint. ``` (gdb) c ``` #### GDB Core Dump Either attach to the running process using `gdb -p PID` or start a new gdb run. ``` (gdb) r (gdb) generate-core-file ``` #### GDB Backtrace If Icinga 2 aborted its operation abnormally, generate a backtrace. > **Note** > > Please install the [required debug symbols](21-development.md#debug-requirements) > prior to generating a backtrace. `thread apply all` is important here since this includes all running threads. We need this information when e.g. debugging dead locks and hanging features. ``` (gdb) bt (gdb) thread apply all bt full ``` If gdb stops at a SIGPIPE signal please disable the signal before running Icinga 2. This isn't an error, but we need to workaround it. ``` (gdb) handle SIGPIPE nostop noprint pass (gdb) r ``` If you create a [new issue](https://github.com/Icinga/icinga2/issues), make sure to attach as much detail as possible. #### GDB Backtrace from Running Process If Icinga 2 is still running, generate a full backtrace from the running process and store it into a new file (e.g. for debugging dead locks). > **Note** > > Please install the [required debug symbols](21-development.md#debug-requirements) > prior to generating a backtrace. Icinga 2 runs with 2 processes: main and command executor, therefore generate two backtrace logs and add them to the GitHub issue. ```bash for pid in $(pidof icinga2); do gdb -p $pid -batch -ex "thread apply all bt full" -ex "detach" -ex "q" > gdb_bt_${pid}_`date +%s`.log; done ``` #### GDB Thread List from Running Process Instead of a full backtrace, you sometimes just need a list of running threads. ```bash for pid in $(pidof icinga2); do gdb -p $pid -batch -ex "info threads" -ex "detach" -ex "q" > gdb_threads_${pid}_`date +%s`.log; done ``` #### GDB Backtrace Stepping Identifying the problem may require stepping into the backtrace, analysing the current scope, attributes, and possible unmet requirements. `p` prints the value of the selected variable or function call result. ``` (gdb) up (gdb) down (gdb) p checkable (gdb) p checkable.px->m_Name ``` #### GDB Breakpoints To set a breakpoint to a specific function call, or file specific line. ``` (gdb) b checkable.cpp:125 (gdb) b icinga::Checkable::SetEnablePerfdata ``` GDB will ask about loading the required symbols later, select `yes` instead of `no`. Then run Icinga 2 until it reaches the first breakpoint. Continue with `c` afterwards. ``` (gdb) run (gdb) c ``` In case you want to step into the next line of code, use `n`. If there is a function call where you want to step into, use `s`. ``` (gdb) n (gdb) s ``` If you want to delete all breakpoints, use `d` and select `yes`. ``` (gdb) d ``` > **Tip** > > When debugging exceptions, set your breakpoint like this: `b __cxa_throw`. Breakpoint Example: ``` (gdb) b __cxa_throw (gdb) r (gdb) up .... (gdb) up #11 0x00007ffff7cbf9ff in icinga::Utility::GlobRecursive(icinga::String const&, icinga::String const&, boost::function const&, int) (path=..., pattern=..., callback=..., type=1) at /home/michi/coding/icinga/icinga2/lib/base/utility.cpp:609 609 callback(cpath); (gdb) l 604 605 #endif /* _WIN32 */ 606 607 std::sort(files.begin(), files.end()); 608 BOOST_FOREACH(const String& cpath, files) { 609 callback(cpath); 610 } 611 612 std::sort(dirs.begin(), dirs.end()); 613 BOOST_FOREACH(const String& cpath, dirs) { (gdb) p files $3 = std::vector of length 11, capacity 16 = {{static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/agent.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/commands.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/downtimes.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/groups.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/notifications.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/satellite.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/services.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/templates.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/test.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/timeperiods.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/users.conf"}} ``` ### Core Dump When the Icinga 2 daemon crashes with a `SIGSEGV` signal a core dump file should be written. This will help developers to analyze and fix the problem. #### Core Dump File Size Limit This requires setting the core dump file size to `unlimited`. ##### Systemd ``` systemctl edit icinga2.service [Service] ... LimitCORE=infinity systemctl daemon-reload systemctl restart icinga2 ``` ##### Init Script ``` vim /etc/init.d/icinga2 ... ulimit -c unlimited service icinga2 restart ``` ##### Verify Verify that the Icinga 2 process core file size limit is set to `unlimited`. ``` for pid in $(pidof icinga2); do cat /proc/$pid/limits; done ... Max core file size unlimited unlimited bytes ``` #### Core Dump Kernel Format The Icinga 2 daemon runs with the SUID bit set. Therefore you need to explicitly enable core dumps for SUID on Linux. ```bash sysctl -w fs.suid_dumpable=2 ``` Adjust the coredump kernel format and file location on Linux: ```bash sysctl -w kernel.core_pattern=/var/lib/cores/core.%e.%p install -m 1777 -d /var/lib/cores ``` MacOS: ```bash sysctl -w kern.corefile=/cores/core.%P chmod 777 /cores ``` #### Core Dump Analysis Once Icinga 2 crashes again a new coredump file will be written. Please attach this file to your bug report in addition to the general details. Simple test case for a `SIGSEGV` simulation with `sleep`: ``` ulimit -c unlimited sleep 1800& [1] kill -SEGV gdb `which sleep` /var/lib/cores/core.sleep. (gdb) bt rm /var/lib/cores/core.sleep.* ``` Analyzing Icinga 2: ``` gdb /usr/lib64/icinga2/sbin/icinga2 core.icinga2. (gdb) bt ``` ### LLDB as Debugger LLDB is available on macOS with the Xcode command line tools. ```bash xcode-select --install ``` In order to run Icinga 2 with LLDB you need to pass the binary as argument. Since v2.11 we would attach to the umbrella process, therefore rather attach to a running process. ```bash # Typically the order of PIDs is: 1) umbrella 2) spawn helper 3) main process pidof icinga2 lldb -p $(pidof icinga2 | cut -d ' ' -f3) ``` In case you'll need to attach to the main process immediately, you can delay the forked child process and attach to the printed PID. ``` $ icinga2 daemon -DInternal.DebugWorkerDelay=120 Closed FD 6 which we inherited from our parent process. [2020-01-29 12:22:33 +0100] information/cli: Icinga application loader (version: v2.11.0-477-gfe8701d77; debug) [2020-01-29 12:22:33 +0100] information/RunWorker: DEBUG: Current PID: 85253. Sleeping for 120 seconds to allow lldb/gdb -p attachment. ``` ```bash lldb -p 85253 ``` When lldb halts on SIGUSR2, press `c` to continue. This signal originates from the umbrella process and can safely be ignored. Breakpoint: ``` > b checkable.cpp:57 > b icinga::Checkable::ProcessCheckResult ``` Full backtrace: ``` > bt all ``` Select thread: ``` > thr sel 5 ``` Step into: ``` > s ``` Next step: ``` > n ``` Continue: ``` > c ``` Up/down in stacktrace: ``` > up > down ``` ### Debug on Windows Whenever the application crashes, the Windows error reporting (WER) can be [configured](https://docs.microsoft.com/en-gb/windows/win32/wer/collecting-user-mode-dumps) to create user-mode dumps. Tail the log file with Powershell: ``` Get-Content .\icinga2.log -tail 10 -wait ``` #### Debug on Windows: Dependencies Similar to `ldd` or `nm` on Linux/Unix. Extract the dependent DLLs from a binary with Visual Studio's `dumpbin` tool in Powershell: ``` C:> &'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\bin\Hostx64\x64\dumpbin.exe' /dependents .\debug\Bin\Debug\Debug\boosttest-test-base.exe DEBUG: 1+ >>>> &'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.22.27905\bin\Hostx64\x64\dumpbin.exe' /dependents .\debug\Bin\Debug\Debug\boosttest-test-base.exe Microsoft (R) COFF/PE Dumper Version 14.22.27905.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file .\debug\Bin\Debug\Debug\boosttest-test-base.exe File Type: EXECUTABLE IMAGE Image has the following dependencies: boost_coroutine-vc142-mt-gd-x64-1_85.dll boost_date_time-vc142-mt-gd-x64-1_85.dll boost_filesystem-vc142-mt-gd-x64-1_85.dll boost_thread-vc142-mt-gd-x64-1_85.dll boost_regex-vc142-mt-gd-x64-1_85.dll libssl-3_0-x64.dll libcrypto-3_0-x64.dll WS2_32.dll dbghelp.dll SHLWAPI.dll msi.dll boost_unit_test_framework-vc142-mt-gd-x64-1_85.dll KERNEL32.dll SHELL32.dll ADVAPI32.dll MSVCP140D.dll MSWSOCK.dll bcrypt.dll VCRUNTIME140D.dll ucrtbased.dll Summary 1000 .00cfg 68000 .data B000 .idata 148000 .pdata 69C000 .rdata 25000 .reloc 1000 .rsrc E7A000 .text 1000 .tls ``` ## Test Icinga 2 ### Snapshot Packages (Nightly Builds) Icinga provides snapshot packages as nightly builds from [Git master](https://github.com/icinga/icinga2). These packages contain development code which should be considered "work in progress". While developers ensure that tests are running fine with CI actions on PRs, things might break, or changes are not yet documented in the changelog. You can help the developers and test the snapshot packages, e.g. when larger changes or rewrites are taking place for a new major version. Your feedback is very much appreciated. Snapshot packages are available for all supported platforms including Linux and Windows and can be obtained from [https://packages.icinga.com](https://packages.icinga.com). The [Vagrant boxes](https://github.com/Icinga/icinga-vagrant) also use the Icinga snapshot packages to allow easier integration tests. It is also possible to use Docker with base OS images and installing the snapshot packages. If you encounter a problem, please [open a new issue](https://github.com/Icinga/icinga2/issues/new/choose) on GitHub and mention that you're testing the snapshot packages. #### RHEL 2.11+ requires the EPEL repository for Boost 1.66+. In addition to that, the `icinga-rpm-release` package already provides the `icinga-snapshot-builds` repository but it is disabled by default. ```bash yum -y install https://packages.icinga.com/epel/icinga-rpm-release-7-latest.noarch.rpm yum -y install epel-release yum makecache yum install --enablerepo=icinga-snapshot-builds icinga2 ``` #### Debian 2.11+ requires Boost 1.66+ which either is provided by the OS, backports or Icinga stable repositories. It is advised to configure both Icinga repositories, stable and snapshot and selectively choose the repository with the `-t` flag on `apt-get install`. ```bash apt-get update apt-get -y install apt-transport-https wget gnupg wget -O - https://packages.icinga.com/icinga.key | apt-key add - DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \ echo "deb https://packages.icinga.com/debian icinga-${DIST} main" > \ /etc/apt/sources.list.d/${DIST}-icinga.list echo "deb-src https://packages.icinga.com/debian icinga-${DIST} main" >> \ /etc/apt/sources.list.d/${DIST}-icinga.list DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \ echo "deb http://packages.icinga.com/debian icinga-${DIST}-snapshots main" > \ /etc/apt/sources.list.d/${DIST}-icinga-snapshots.list echo "deb-src http://packages.icinga.com/debian icinga-${DIST}-snapshots main" >> \ /etc/apt/sources.list.d/${DIST}-icinga-snapshots.list apt-get update ``` On Debian Stretch, you'll also need to add Debian Backports. ```bash DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \ echo "deb https://deb.debian.org/debian ${DIST}-backports main" > \ /etc/apt/sources.list.d/${DIST}-backports.list apt-get update ``` Then install the snapshot packages. ```bash DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release); \ apt-get install -t icinga-${DIST}-snapshots icinga2 ``` #### Ubuntu ```bash apt-get update apt-get -y install apt-transport-https wget gnupg wget -O - https://packages.icinga.com/icinga.key | apt-key add - . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \ echo "deb https://packages.icinga.com/ubuntu icinga-${DIST} main" > \ /etc/apt/sources.list.d/${DIST}-icinga.list echo "deb-src https://packages.icinga.com/ubuntu icinga-${DIST} main" >> \ /etc/apt/sources.list.d/${DIST}-icinga.list . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \ echo "deb https://packages.icinga.com/ubuntu icinga-${DIST}-snapshots main" > \ /etc/apt/sources.list.d/${DIST}-icinga-snapshots.list echo "deb-src https://packages.icinga.com/ubuntu icinga-${DIST}-snapshots main" >> \ /etc/apt/sources.list.d/${DIST}-icinga-snapshots.list apt-get update ``` Then install the snapshot packages. ```bash . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \ apt-get install -t icinga-${DIST}-snapshots icinga2 ``` #### SLES The required Boost packages are provided with the stable release repository. ```bash rpm --import https://packages.icinga.com/icinga.key zypper ar https://packages.icinga.com/SUSE/ICINGA-release.repo zypper ref zypper ar https://packages.icinga.com/SUSE/ICINGA-snapshot.repo zypper ref ``` Selectively install the snapshot packages using the `-r` parameter. ```bash zypper in -r icinga-snapshot-builds icinga2 ``` ### Unit Tests Build the binaries and run the tests. ```bash make -j4 -C debug make test -C debug ``` Run a specific boost test: ```bash debug/Bin/Debug/boosttest-test-base --run_test=remote_url ``` ## Develop Icinga 2 Icinga 2 can be built on many platforms such as Linux, Unix and Windows. There are limitations in terms of support, e.g. Windows is only supported for agents, not a full-featured master or satellite. Before you start with actual development, there is a couple of pre-requisites. ### Preparations #### Choose your Editor Icinga 2 can be developed with your favorite editor. Icinga developers prefer these tools: - vim - CLion (macOS, Linux) - MS Visual Studio (Windows) - Atom Editors differ on the functionality. The more helpers you get for C++ development, the faster your development workflow will be. #### Get to know the architecture Icinga 2 can run standalone or in distributed environments. It contains a whole lot more than a simple check execution engine. Read more about it in the [Technical Concepts](19-technical-concepts.md#technical-concepts) chapter. #### Get to know the code First off, you really need to know C++ and portions of C++17 and the boost libraries. Best is to start with a book or online tutorial to get into the basics. Icinga developers gained their knowledge through studies, training and self-teaching code by trying it out and asking senior developers for guidance. Here's a few books we can recommend: * [Accelerated C++: Practical Programming by Example](https://www.amazon.com/Accelerated-C-Practical-Programming-Example/dp/020170353X) (Andrew Koenig, Barbara E. Moo) * [Effective C++](https://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876) (Scott Meyers) * [Boost C++ Application Development Cookbook - Second Edition: Recipes to simplify your application development](https://www.amazon.com/dp/1787282244/ref=cm_sw_em_r_mt_dp_U_dN1OCbERS00EQ) (Antony Polukhin) * [Der C++ Programmierer](https://www.amazon.de/Programmierer-lernen-Professionell-anwenden-L%C3%B6sungen/dp/3446416447), German (Ulrich Breymann) * [C++11 programmieren](https://www.amazon.de/gp/product/3836217325/), German (Torsten T. Will) In addition, it is a good bet to also know SQL when diving into backend development. * [SQL Performance Explained](https://www.amazon.de/gp/product/3950307826/) (Markus Winand) Last but not least, if you are developing on Windows, get to know the internals about services and the Win32 API. ### Design Patterns Icinga 2 heavily relies on object-oriented programming and encapsulates common functionality into classes and objects. It also uses modern programming techniques to e.g. work with shared pointer memory management. Icinga 2 consists of libraries bundled into the main binary. Therefore you'll find many code parts in the `lib/` directory wheras the actual application is built from `icinga-app/`. Accompanied with Icinga 2, there's the Windows plugins which are standalone and compiled from `plugins/`. Library | Description ---------------|------------------------------------ base | Objects, values, types, streams, tockets, TLS, utilities, etc. config | Configuration compiler, expressions, etc. cli | CLI (sub) commands and helpers. icinga | Icinga specific objects and event handling. remote | Cluster and HTTP client/server and REST API related code. checker | Checker feature, check scheduler. notification | Notification feature, notification scheduler. methods | Command execution methods, plugins and built-in checks. perfdata | Performance data related, including Graphite, Elastic, etc. db\_ido | IDO database abstraction layer. db\_ido\_mysql | IDO database driver for MySQL. db\_ido\_pgsql | IDO database driver for PgSQL. mysql\_shin | Library stub for linking against the MySQL client libraries. pgsql\_shim | Library stub for linking against the PgSQL client libraries. #### Class Compiler Another thing you will recognize are the `.ti` files which are compiled by our own class compiler into actual source code. The meta language allows developers to easily add object attributes and specify their behaviour. Some object attributes need to be stored over restarts in the state file and therefore have the `state` attribute set. Others are treated as `config` attribute and automatically get configuration validation functions created. Hidden or read-only REST API attributes are marked with `no_user_view` and `no_user_modify`. The most beneficial thing are getters and setters being generated. The actual object inherits from `ObjectImpl` and therefore gets them "for free". Example: ``` vim lib/perfdata/gelfwriter.ti [config] enable_tls; vim lib/perfdata/gelfwriter.cpp if (GetEnableTls()) { ``` The logic is hidden in `tools/mkclass/` in case you want to learn more about it. The first steps during CMake & make also tell you about code generation. ### Build Tools #### CMake In its early development stages in 2012, Icinga 2 was built with autoconf/automake and separate Windows project files. We've found this very fragile, and have changed this into CMake as our build tool. The most common benefits: * Everything is described in CMakeLists.txt in each directory * CMake only needs to know that a sub directory needs to be included. * The global CMakeLists.txt acts as main entry point for requirement checks and library/header includes. * Separate binary build directories, the actual source tree stays clean. * CMake automatically generates a Visual Studio project file `icinga2.sln` on Windows. #### Unity Builds Another thing you should be aware of: Unity builds on and off. Typically, we already use caching mechanisms to reduce recompile time with ccache. For release builds, there's always a new build needed as the difference is huge compared to a previous (major) release. Therefore we've invented the Unity builds, which basically concatenates all source files into one big library source code file. The compiler then doesn't need to load the many small files but compiles and links this huge one. Unity builds require more memory which is why you should disable them for development builds in small sized VMs (Linux, Windows) and also Docker containers. There's a couple of header files which are included everywhere. If you touch/edit them, the cache is invalidated and you need to recompile a lot more files then. `base/utility.hpp` and `remote/zone.hpp` are good candidates for this. ### Unit Tests New functions and classes must implement new unit tests. Whenever you decide to add new functions, ensure that you don't need a complex mock or runtime attributes in order to test them. Better isolate code into function interfaces which can be invoked in the Boost tests framework. Look into the existing tests in the [test/](https://github.com/Icinga/icinga2/tree/master/test) directory and adopt new test cases. Specific tests require special time windows, they are only enabled in debug builds for developers. This is the case e.g. for testing the flapping algorithm with expected state change detection at a specific point from now. ### Style Guide Overview of project files: File Type | File Name/Extension | Description ---------------|---------------------|----------------------------- Header | .hpp | Classes, enums, typedefs inside the icinga Namespace. Source | .cpp | Method implementation for class functions, static/global variables. CMake | CMakeLists.txt | Build configuration, source and header file references. CMake Source | .cmake | Source/Header files generated from CMake placeholders. ITL/conf.d | .conf | Template library and example files as configuration Class Compiler | .ti | Object classes in our own language, generates source code as `-ti.{c,h}pp`. Lexer/Parser | .ll, .yy | Flex/Bison code generated into source code from CMake builds. Docs | .md | Markdown docs and READMEs. Anything else are additional tools and scripts for developers and build systems. All files must include the copyright header. We don't use the current year as this implies yearly updates we don't want. Depending on the file type, this must be a comment. ```cpp /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ ``` ```bash # Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ ``` #### Code Formatting **Tabs instead of spaces.** Inside Visual Studio, choose to keep tabs instead of spaces. Tabs should use 4 spaces indent by default, depending on your likings. We follow the clang format, with some exceptions. - Curly braces for functions and classes always start at a new line. ```cpp String ConfigObjectUtility::EscapeName(const String& name) { //... } String ConfigObjectUtility::CreateObjectConfig(const Type::Ptr& type, const String& fullName, bool ignoreOnError, const Array::Ptr& templates, const Dictionary::Ptr& attrs) { //... } ``` - Too long lines break at a parameter, the new line needs a tab indent. ```cpp static String CreateObjectConfig(const Type::Ptr& type, const String& fullName, bool ignoreOnError, const Array::Ptr& templates, const Dictionary::Ptr& attrs); ``` - Conditions require curly braces if it is not a single if with just one line. ```cpp if (s == "OK") { //... } else { //... } if (!n) return; ``` - There's a space between `if` and the opening brace `(`. Also after the closing brace `)` and opening curly brace `{`. - Negation with `!` doesn't need an extra space. - Else branches always start in the same line after the closing curly brace. #### Code Comments Add comments wherever you think that another developer will have a hard time to understand the complex algorithm. Or you might have forgotten it in a year and struggle again. Also use comments to highlight specific stages in a function. Generally speaking, make things easier for the team and external contributors. Comments can also be used to mark additional references and TODOs. If there is a specific GitHub issue or discussion going on, use that information as a summary and link over to it on purpose. - Single line comments may use `//` or `/* ... */` - Multi line comments must use this format: ```cpp /* Ensure to check for XY * This relies on the fact that ABC has been set before. */ ``` #### Function Docs Function header documentation must be added. The current code basis needs rework, future functions must provide this. Editors like CLion or Visual Studio allow you to type `/**` followed by Enter and generate the skeleton from the implemented function. Add a short summary in the first line about the function's purpose. Edit the param section with short description on their intention. The `return` value should describe the value type and additional details. Example: ```cpp /** * Reads a message from the connected peer. * * @param stream ASIO TLS Stream * @param yc Yield Context for ASIO * @param maxMessageLength maximum size of bytes read. * * @return A JSON string */ String JsonRpc::ReadMessage(const std::shared_ptr& stream, boost::asio::yield_context yc, ssize_t maxMessageLength) ``` While we can generate code docs from it, the main idea behind it is to provide on-point docs to fully understand all parameters and the function's purpose in the same spot. #### Header Only include other headers which are mandatory for the header definitions. If the source file requires additional headers, add them there to avoid include loops. The included header order is important. - First, include the library header `i2-.hpp`, e.g. `i2-base.hpp`. - Second, include all headers from Icinga itself, e.g. `remote/apilistener.hpp`. `base` before `icinga` before `remote`, etc. - Third, include third-party and external library headers, e.g. openssl and boost. - Fourth, include STL headers. #### Source The included header order is important. - First, include the header whose methods are implemented. - Second, include all headers from Icinga itself, e.g. `remote/apilistener.hpp`. `base` before `icinga` before `remote`, etc. - Third, include third-party and external library headers, e.g. openssl and boost. - Fourth, include STL headers. Always use an empty line after the header include parts. #### Namespace The icinga namespace is used globally, as otherwise we would need to write `icinga::Utility::FormatDateTime()`. ```cpp using namespace icinga; ``` Other namespaces must be declared in the scope they are used. Typically this is inside the function where `boost::asio` and variants would complicate the code. ```cpp namespace ssl = boost::asio::ssl; auto context (std::make_shared(ssl::context::sslv23)); ``` #### Functions Ensure to pass values and pointers as const reference. By default, all values will be copied into the function scope, and we want to avoid this wherever possible. ```cpp std::vector EventQueue::GetQueuesForType(const String& type) ``` C++ only allows to return a single value. This can be abstracted with returning a specific class object, or with using a map/set. Array and Dictionary objects increase the memory footprint, use them only where needed. A common use case for Icinga value types is where a function can return different values - an object, an array, a boolean, etc. This happens in the inner parts of the config compiler expressions, or config validation. The function caller is responsible to determine the correct value type and handle possible errors. Specific algorithms may require to populate a list, which can be passed by reference to the function. The inner function can then append values. Do not use a global shared resource here, unless this is locked by the caller. #### Conditions and Cases Prefer if-else-if-else branches. When integers are involved, switch-case statements increase readability. Don't forget about `break` though! Avoid using ternary operators where possible. Putting a condition after an assignment complicates reading the source. The compiler optimizes this anyways. Wrong: ```cpp int res = s == "OK" ? 0 : s == "WARNING" ? 1; return res; ``` Better: ```cpp int res = 3; if (s == "OK") { res = 0; } else if (s == "WARNING") { res = 1; } ``` Even better: Create a lookup map instead of if branches. The complexity is reduced to O(log(n)). ```cpp std::map stateMap = { { "OK", 1 }, { "WARNING", 2 } } auto it = stateMap.find(s); if (it == stateMap.end()) { return 3 } return it.second; ``` The code is not as short as with a ternary operator, but one can re-use this design pattern for other generic definitions with e.g. moving the lookup into a utility class. Once a unit test is written, everything works as expected in the future. #### Locks and Guards Lock access to resources where multiple threads can read and write. Icinga objects can be locked with the `ObjectLock` class. Object locks and guards must be limited to the scope where they are needed. Otherwise we could create dead locks. ```cpp { ObjectLock olock(frame.Locals); for (const Dictionary::Pair& kv : frame.Locals) { AddSuggestion(matches, word, kv.first); } } ``` #### Objects and Pointers Use shared pointers for objects. Icinga objects implement the `Ptr` typedef returning an `intrusive_ptr` for the class object (object.hpp). This also ensures reference counting for the object's lifetime. Use raw pointers with care! Some methods and classes require specific shared pointers, especially when interacting with the Boost library. #### Value Types Icinga has its own value types. These provide methods to allow generic serialization into JSON for example, and other type methods which are made available in the DSL too. - Always use `String` instead of `std::string`. If you need a C-string, use the `CStr()` method. - Avoid casts and rather use the `Convert` class methods. ```cpp double s = static_cast(v); //Wrong double s = Convert::ToDouble(v); //Correct, ToDouble also provides overloads with different value types ``` - Prefer STL containers for internal non-user interfaces. Icinga value types add a small overhead which may decrease performance if e.g. the function is called 100k times. - `Array::FromVector` and variants implement conversions, use them. #### Utilities Don't re-invent the wheel. The `Utility` class provides many helper functions which allow you e.g. to format unix timestamps, search in filesystem paths. Also inspect the Icinga objects, they also provide helper functions for formatting, splitting strings, joining arrays into strings, etc. #### Libraries 2.11 depends on [Boost 1.66](https://www.boost.org/doc/libs/1_66_0/). Use the existing libraries and header-only includes for this specific version. Note: Prefer C++17 features where possible, e.g. std::atomic and lambda functions. General: - [exception](https://www.boost.org/doc/libs/1_66_0/libs/exception/doc/boost-exception.html) (header only) - [algorithm](https://www.boost.org/doc/libs/1_66_0/libs/algorithm/doc/html/index.html) (header only) - [lexical_cast](https://www.boost.org/doc/libs/1_66_0/doc/html/boost_lexical_cast.html) (header only) - [regex](https://www.boost.org/doc/libs/1_66_0/libs/regex/doc/html/index.html) - [uuid](https://www.boost.org/doc/libs/1_66_0/libs/uuid/doc/uuid.html) (header only) - [range](https://www.boost.org/doc/libs/1_66_0/libs/range/doc/html/index.html) (header only) - [variant](https://www.boost.org/doc/libs/1_66_0/doc/html/variant.html) (header only) - [multi_index](https://www.boost.org/doc/libs/1_66_0/libs/multi_index/doc/index.html) (header only) - [function_types](https://www.boost.org/doc/libs/1_66_0/libs/function_types/doc/html/index.html) (header only) - [circular_buffer](https://www.boost.org/doc/libs/1_66_0/doc/html/circular_buffer.html) (header only) - [math](https://www.boost.org/doc/libs/1_66_0/libs/math/doc/html/index.html) (header only) - [stacktrace](https://www.boost.org/doc/libs/1_66_0/doc/html/stacktrace.html) (header only) Events and Runtime: - [system](https://www.boost.org/doc/libs/1_66_0/libs/system/doc/index.html) - [thread](https://www.boost.org/doc/libs/1_66_0/doc/html/thread.html) - [signals2](https://www.boost.org/doc/libs/1_66_0/doc/html/signals2.html) (header only) - [program_options](https://www.boost.org/doc/libs/1_66_0/doc/html/program_options.html) - [date_time](https://www.boost.org/doc/libs/1_66_0/doc/html/date_time.html) - [filesystem](https://www.boost.org/doc/libs/1_66_0/libs/filesystem/doc/index.htm) Network I/O: - [asio](https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio.html) (header only) - [beast](https://www.boost.org/doc/libs/1_66_0/libs/beast/doc/html/index.html) (header only) - [coroutine](https://www.boost.org/doc/libs/1_66_0/libs/coroutine/doc/html/index.html) - [context](https://www.boost.org/doc/libs/1_66_0/libs/context/doc/html/index.html) Consider abstracting their usage into `*utility.{c,h}pp` files with wrapping existing Icinga types. That also allows later changes without rewriting large code parts. > **Note** > > A new Boost library should be explained in a PR and discussed with the team. > > This requires package dependency changes. If you consider an external library or code to be included with Icinga, the following requirements must be fulfilled: - License is compatible with GPLv2+. Boost license, MIT works, Apache is not. - C++17 is supported - Header only implementations are preferred, external libraries require packages on every distribution. - No additional frameworks, Boost is the only allowed. - The code is proven to be robust and the GitHub repository is alive, or has 1k+ stars. Good libraries also provide a user list, if e.g. Ceph is using it, this is a good candidate. #### Log Icinga allows the user to configure logging backends, e.g. syslog or file. Any log message inside the code must use the `Log()` function. - The first parameter is the severity level, use them with care. - The second parameter defines the location/scope where the log happened. Typically we use the class name here, to better analyse the logs the user provide in GitHub issues and on the community channels. - The third parameter takes a log message string If the message string needs to be computed from existing values, everything must be converted to the String type beforehand. This conversion for every value is very expensive which is why we try to avoid it. Instead, use Log() with the shift operator where everything is written on the stream and conversions are explicitly done with templates in the background. The trick here is that the Log object is destroyed immediately after being constructed once. The destructor actually evaluates the values and sends it to registers loggers. Since flushing the stream every time a log entry occurs is very expensive, a timer takes care of flushing the stream every second. > **Tip** > > If logging stopped, the flush timer thread may be dead. > Inspect that with gdb/lldb. Avoid log messages which could irritate the user. During implementation, developers can change log levels to better see what's going one, but remember to change this back to `debug` or remove it entirely. #### Goto Avoid using `goto` statements. There are rare occasions where they are allowed: - The code would become overly complicated within nested loops and conditions. - Event processing and C interfaces. - Question/Answer loops within interactive CLI commands. #### Typedef and Auto Keywords Typedefs allow developers to use shorter names for specific types, classes and structs. ```cpp typedef std::map >::iterator Iterator; ``` These typedefs should be part of the Class definition in the header, or may be defined in the source scope where they are needed. Avoid declaring global typedefs, unless necessary. Using the `auto` keyword allows to ignore a specific value type. This comes in handy with maps/sets where no specific access is required. The following example iterates over a map returned from `GetTypes()`. ```cpp for (const auto& kv : GetTypes()) { result.insert(kv.second); } ``` The long example would require us to define a map iterator, and a slightly different algorithm. ```cpp typedef std::map TypeMap; typedef std::map::const_iterator TypeMapIterator; TypeMap types = GetTypes(); for (TypeMapIterator it = types.begin(); it != types.end(); it++) { result.insert(it.second); } ``` We could also use a pair here, but requiring to know the specific types of the map keys and values. ```cpp typedef std::pair kv_pair; for (const kv_pair& kv : GetTypes()) { result.insert(kv.second); } ``` After all, `auto` shortens the code and one does not always need to know about the specific types. Function documentation for `GetTypes()` is required though. #### Whitespace Cleanup Patches must be cleaned up and follow the indent style (tabs instead of spaces). You should also remove any trailing whitespaces. `git diff` allows to highlight such. ``` vim $HOME/.gitconfig [color "diff"] whitespace = red reverse [core] whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol ``` `vim` also can match these and visually alert you to remove them. ``` vim $HOME/.vimrc highlight ExtraWhitespace ctermbg=red guibg=red match ExtraWhitespace /\s\+$/ autocmd BufWinEnter * match ExtraWhitespace /\s\+$/ autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@ ### Linux Dev Environment If you're compiling Icinga 2 natively without any virtualization layer in between, this usually is faster. This is also the reason why developers on macOS prefer native builds over Linux or Windows VMs. Don't forget to test the actual code on Linux later! Socket specific stuff like `epoll` is not available on Unix kernels. Depending on your workstation and environment, you may either develop and run locally, use a container deployment pipeline or put everything in a high end resource remote VM. Fork https://github.com/Icinga/icinga2 into your own repository, e.g. `https://github.com/dnsmichi/icinga2`. Create two build directories for different binary builds. * `debug` contains the debug build binaries. They contain more debug information and run tremendously slower than release builds from packages. Don't use them for benchmarks. * `release` contains the release build binaries, as you would install them on a live system. This helps comparing specific scenarios for race conditions and more. ```bash mkdir -p release debug ``` Proceed with the specific distribution examples below. Keep in mind that these instructions are best effort and sometimes out-of-date. Git Master may contain updates. * [Fedora 40](21-development.md#development-linux-dev-env-fedora) * [Debian 10 Buster](21-development.md#development-linux-dev-env-debian) * [Ubuntu 18 Bionic](21-development.md#development-linux-dev-env-ubuntu) #### Fedora 40 ```bash yum -y install gdb vim git bash-completion htop yum -y install rpmdevtools ccache \ cmake make gcc-c++ flex bison \ openssl-devel boost-devel systemd-devel \ mysql-devel postgresql-devel libedit-devel \ libstdc++-devel groupadd icinga groupadd icingacmd useradd -c "icinga" -s /sbin/nologin -G icingacmd -g icinga icinga ln -s /bin/ccache /usr/local/bin/gcc ln -s /bin/ccache /usr/local/bin/g++ git clone https://github.com/icinga/icinga2.git && cd icinga2 ``` The debug build binaries contain specific code which runs slower but allows for better debugging insights. For benchmarks, change `CMAKE_BUILD_TYPE` to `RelWithDebInfo` and build inside the `release` directory. First, override the default prefix path. ```bash export I2_GENERIC="-DCMAKE_INSTALL_PREFIX=/usr/local/icinga2" ``` Second, define the two build types with their specific CMake variables. ```bash export I2_DEBUG="-DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF $I2_GENERIC" export I2_RELEASE="-DCMAKE_BUILD_TYPE=RelWithDebInfo -DICINGA2_WITH_TESTS=ON -DICINGA2_UNITY_BUILD=ON $I2_GENERIC" ``` Third, depending on your likings, you may use a bash alias for building, or invoke the commands inside: ```bash alias i2_debug="cd /root/icinga2; mkdir -p debug; cd debug; cmake $I2_DEBUG ..; make -j2; sudo make -j2 install; cd .." alias i2_release="cd /root/icinga2; mkdir -p release; cd release; cmake $I2_RELEASE ..; make -j2; sudo make -j2 install; cd .." ``` ```bash i2_debug ``` The source installation doesn't set proper permissions, this is handled in the package builds which are officially supported. ```bash chown -R icinga:icinga /usr/local/icinga2/{etc,var}/ /usr/local/icinga2/lib/icinga2/prepare-dirs /usr/local/icinga2/etc/sysconfig/icinga2 /usr/local/icinga2/sbin/icinga2 api setup vim /usr/local/icinga2/etc/icinga2/conf.d/api-users.conf /usr/local/icinga2/lib64/icinga2/sbin/icinga2 daemon ``` #### Debian 10 Debian Buster doesn't need updated Boost packages from packages.icinga.com, the distribution already provides 1.66+. For older versions such as Stretch, include the release repository for packages.icinga.com as shown in the [setup instructions](02-installation.md). ```bash docker run -ti debian:buster bash apt-get update apt-get -y install apt-transport-https wget gnupg apt-get -y install gdb vim git cmake make ccache build-essential libssl-dev bison flex default-libmysqlclient-dev libpq-dev libedit-dev monitoring-plugins apt-get -y install libboost-all-dev ``` ```bash ln -s /usr/bin/ccache /usr/local/bin/gcc ln -s /usr/bin/ccache /usr/local/bin/g++ groupadd icinga groupadd icingacmd useradd -c "icinga" -s /sbin/nologin -G icingacmd -g icinga icinga git clone https://github.com/icinga/icinga2.git && cd icinga2 mkdir debug release export I2_DEB="-DBoost_NO_BOOST_CMAKE=TRUE -DBoost_NO_SYSTEM_PATHS=TRUE -DBOOST_LIBRARYDIR=/usr/lib/x86_64-linux-gnu -DBOOST_INCLUDEDIR=/usr/include -DCMAKE_INSTALL_RPATH=/usr/lib/x86_64-linux-gnu" export I2_GENERIC="-DCMAKE_INSTALL_PREFIX=/usr/local/icinga2 -DICINGA2_PLUGINDIR=/usr/local/sbin" export I2_DEBUG="$I2_DEB $I2_GENERIC -DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF" cd debug cmake .. $I2_DEBUG cd .. make -j2 install -C debug ``` The source installation doesn't set proper permissions, this is handled in the package builds which are officially supported. ```bash chown -R icinga:icinga /usr/local/icinga2/{etc,var}/ /usr/local/icinga2/lib/icinga2/prepare-dirs /usr/local/icinga2/etc/sysconfig/icinga2 /usr/local/icinga2/sbin/icinga2 api setup vim /usr/local/icinga2/etc/icinga2/conf.d/api-users.conf /usr/local/icinga2/lib/icinga2/sbin/icinga2 daemon ``` #### Ubuntu 18 Bionic Requires Boost packages from packages.icinga.com. ```bash docker run -ti ubuntu:bionic bash apt-get update apt-get -y install apt-transport-https wget gnupg wget -O - https://packages.icinga.com/icinga.key | apt-key add - . /etc/os-release; if [ ! -z ${UBUNTU_CODENAME+x} ]; then DIST="${UBUNTU_CODENAME}"; else DIST="$(lsb_release -c| awk '{print $2}')"; fi; \ echo "deb https://packages.icinga.com/ubuntu icinga-${DIST} main" > \ /etc/apt/sources.list.d/${DIST}-icinga.list echo "deb-src https://packages.icinga.com/ubuntu icinga-${DIST} main" >> \ /etc/apt/sources.list.d/${DIST}-icinga.list apt-get update ``` ```bash apt-get -y install gdb vim git cmake make ccache build-essential libssl-dev bison flex default-libmysqlclient-dev libpq-dev libedit-dev monitoring-plugins apt-get install -y libboost1.67-icinga-all-dev ln -s /usr/bin/ccache /usr/local/bin/gcc ln -s /usr/bin/ccache /usr/local/bin/g++ groupadd icinga groupadd icingacmd useradd -c "icinga" -s /sbin/nologin -G icingacmd -g icinga icinga git clone https://github.com/icinga/icinga2.git && cd icinga2 mkdir debug release export I2_DEB="-DBoost_NO_BOOST_CMAKE=TRUE -DBoost_NO_SYSTEM_PATHS=TRUE -DBOOST_LIBRARYDIR=/usr/lib/x86_64-linux-gnu/icinga-boost -DBOOST_INCLUDEDIR=/usr/include/icinga-boost -DCMAKE_INSTALL_RPATH=/usr/lib/x86_64-linux-gnu/icinga-boost" export I2_GENERIC="-DCMAKE_INSTALL_PREFIX=/usr/local/icinga2 -DICINGA2_PLUGINDIR=/usr/local/sbin" export I2_DEBUG="$I2_DEB $I2_GENERIC -DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF" cd debug cmake .. $I2_DEBUG cd .. ``` ```bash make -j2 install -C debug ``` The source installation doesn't set proper permissions, this is handled in the package builds which are officially supported. ```bash chown -R icinga:icinga /usr/local/icinga2/{etc,var}/ /usr/local/icinga2/lib/icinga2/prepare-dirs /usr/local/icinga2/etc/sysconfig/icinga2 /usr/local/icinga2/sbin/icinga2 api setup vim /usr/local/icinga2/etc/icinga2/conf.d/api-users.conf /usr/local/icinga2/lib/icinga2/sbin/icinga2 daemon ``` ### macOS Dev Environment It is advised to use Homebrew to install required build dependencies. Macports have been reported to work as well, typically you'll get more help with Homebrew from Icinga developers. The idea is to run Icinga with the current user, avoiding root permissions. This requires at least v2.11. > **Note** > > This is a pure development setup for Icinga developers reducing the compile > time in contrast to VMs. There are no packages, startup scripts or dependency management involved. > > **macOS agents are not officially supported.** > > macOS uses its own TLS implementation, Icinga relies on extra OpenSSL packages > requiring updates apart from vendor security updates. #### Requirements Explicitly use OpenSSL 1.1.x, older versions are out of support. ```bash brew install ccache boost cmake bison flex openssl@1.1 mysql-connector-c++ postgresql libpq ``` ##### ccache ```bash sudo mkdir /opt/ccache sudo ln -s `which ccache` /opt/ccache/clang sudo ln -s `which ccache` /opt/ccache/clang++ vim $HOME/.bash_profile # ccache is managed with symlinks to avoid collision with cgo export PATH="/opt/ccache:$PATH" source $HOME/.bash_profile ``` #### Builds Icinga is built as release (optimized build for packages) and debug (more symbols and details for debugging). Debug builds typically run slower than release builds and must not be used for performance benchmarks. The preferred installation prefix is `/usr/local/icinga/icinga2`. This allows to put e.g. Icinga Web 2 into the `/usr/local/icinga` directory as well. ```bash mkdir -p release debug export I2_USER=$(id -u -n) export I2_GROUP=$(id -g -n) export I2_GENERIC="-DCMAKE_INSTALL_PREFIX=/usr/local/icinga/icinga2 -DICINGA2_USER=$I2_USER -DICINGA2_GROUP=$I2_GROUP -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl@1.1/include -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib -DICINGA2_PLUGINDIR=/usr/local/sbin -DICINGA2_WITH_PGSQL=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=ON" export I2_DEBUG="-DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF $I2_GENERIC" export I2_RELEASE="-DCMAKE_BUILD_TYPE=RelWithDebInfo -DICINGA2_WITH_TESTS=ON -DICINGA2_UNITY_BUILD=ON $I2_GENERIC" cd debug cmake $I2_DEBUG .. cd .. make -j4 -C debug make -j4 install -C debug ``` In order to run Icinga without any path prefix, and also use Bash completion it is advised to source additional things into the local dev environment. ```bash export PATH=/usr/local/icinga/icinga2/sbin/:$PATH test -f /usr/local/icinga/icinga2/etc/bash_completion.d/icinga2 && source /usr/local/icinga/icinga2/etc/bash_completion.d/icinga2 ``` ##### Build Aliases This is derived from [dnsmichi's flavour](https://github.com/dnsmichi/dotfiles) and not generally best practice. ```bash vim $HOME/.bash_profile export I2_USER=$(id -u -n) export I2_GROUP=$(id -g -n) export I2_GENERIC="-DCMAKE_INSTALL_PREFIX=/usr/local/icinga/icinga2 -DICINGA2_USER=$I2_USER -DICINGA2_GROUP=$I2_GROUP -DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl@1.1/include -DOPENSSL_SSL_LIBRARY=/usr/local/opt/openssl@1.1/lib/libssl.dylib -DOPENSSL_CRYPTO_LIBRARY=/usr/local/opt/openssl@1.1/lib/libcrypto.dylib -DICINGA2_PLUGINDIR=/usr/local/sbin -DICINGA2_WITH_PGSQL=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=ON" export I2_DEBUG="-DCMAKE_BUILD_TYPE=Debug -DICINGA2_UNITY_BUILD=OFF $I2_GENERIC" export I2_RELEASE="-DCMAKE_BUILD_TYPE=RelWithDebInfo -DICINGA2_WITH_TESTS=ON -DICINGA2_UNITY_BUILD=ON $I2_GENERIC" alias i2_debug="mkdir -p debug; cd debug; cmake $I2_DEBUG ..; make -j4; make -j4 install; cd .." alias i2_release="mkdir -p release; cd release; cmake $I2_RELEASE ..; make -j4; make -j4 install; cd .." export PATH=/usr/local/icinga/icinga2/sbin/:$PATH test -f /usr/local/icinga/icinga2/etc/bash_completion.d/icinga2 && source /usr/local/icinga/icinga2/etc/bash_completion.d/icinga2 source $HOME/.bash_profile ``` #### Permissions `make install` doesn't set all required permissions, override this. ```bash chown -R $I2_USER:$I2_GROUP /usr/local/icinga/icinga2 ``` #### Run Start Icinga in foreground. ```bash icinga2 daemon ``` Reloads triggered with HUP or cluster syncs just put the process into background. #### Plugins ```bash brew install monitoring-plugins sudo vim /usr/local/icinga/icinga2/etc/icinga2/constants.conf ``` ``` const PluginDir = "/usr/local/sbin" ``` #### Backends: Redis ```bash brew install redis brew services start redis ``` #### Databases: MariaDB ```bash brew install mariadb mkdir -p /usr/local/etc/my.cnf.d brew services start mariadb mysql_secure_installation ``` ``` vim $HOME/.my.cnf [client] user = root password = supersecurerootpassword sudo -i ln -s /Users/michi/.my.cnf $HOME/.my.cnf exit ``` ```bash mysql -e 'create database icinga;' mysql -e "grant all on icinga.* to 'icinga'@'localhost' identified by 'icinga';" mysql icinga < $HOME/dev/icinga/icinga2/lib/db_ido_mysql/schema/mysql.sql ``` #### API ```bash icinga2 api setup cd /usr/local/icinga/icinga2/var/lib/icinga2/certs HOST_NAME=mbpmif.int.netways.de icinga2 pki new-cert --cn ${HOST_NAME} --csr ${HOST_NAME}.csr --key ${HOST_NAME}.key icinga2 pki sign-csr --csr ${HOST_NAME}.csr --cert ${HOST_NAME}.crt echo "const NodeName = \"${HOST_NAME}\"" >> /usr/local/icinga/icinga2/etc/icinga2/constants.conf ``` #### Web While it is recommended to use Docker or the Icinga Web 2 development VM pointing to the shared IDO database resource/REST API, you can also install it locally on macOS. The required steps are described in [this script](https://github.com/dnsmichi/dotfiles/blob/master/icingaweb2.sh). ### Windows Dev Environment The following sections explain how to setup the required build tools and how to run and debug the code. #### TL;DR If you're going to setup a dev environment on a fresh Windows machine and don't care for the details, 1. ensure there are 35 GB free space on C: 2. run the following in an administrative Powershell: 1. Windows Server only: `Enable-WindowsOptionalFeature -FeatureName NetFx3ServerFeatures -Online` 2. `Enable-WindowsOptionalFeature -FeatureName NetFx3 -Online` (reboot when asked!) 3. `powershell -NoProfile -ExecutionPolicy Bypass -Command "Invoke-Expression (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/Icinga/icinga2/master/doc/win-dev.ps1')"` (will take some time) This installs everything needed for cloning and building Icinga 2 on the command line (Powershell) as follows: (Don't forget to open a new Powershell window to be able to use the newly installed Git.) ``` git clone https://github.com/Icinga/icinga2.git cd .\icinga2\ mkdir build cd .\build\ & "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" ` -DICINGA2_UNITY_BUILD=OFF -DBoost_INCLUDE_DIR=C:\local\boost_1_85_0-Win64 ` -DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison3\tools\win_bison.exe ` -DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison3\tools\win_flex.exe .. & "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe" .\icinga2.sln ``` Building icinga2.sln via Visual Studio itself seems to require a reboot after installing the build tools. #### Chocolatey Open an administrative command prompt (Win key, type “cmd”, right-click and “run as administrator”) and paste the following instructions: ``` @powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin ``` #### Git, Posh and Vim In case you are used to `vim`, start a new administrative Powershell: ``` choco install -y vim ``` The same applies for Git integration in Powershell: ``` choco install -y poshgit ``` ![Powershell Posh Git](images/development/windows_powershell_posh_git.png) In order to fix the colors for commands like `git status` or `git diff`, edit `$HOME/.gitconfig` in your Powershell and add the following lines: ``` vim $HOME/.gitconfig [color "status"] changed = cyan bold untracked = yellow bold added = green bold branch = cyan bold unmerged = red bold [color "diff"] frag = cyan new = green bold commit = yellow old = red white [color "branch"] current = yellow reverse local = yellow remote = green bold remote = red bold ``` #### Visual Studio Thanks to Microsoft they’ll now provide their Professional Edition of Visual Studio as community version, free for use for open source projects such as Icinga. The installation requires ~9GB disk space. [Download](https://www.visualstudio.com/downloads/) the web installer and start the installation. Note: Only Visual Studio 2019 is covered here. Older versions are not supported. You need a free Microsoft account to download and also store your preferences. Install the following complete workloads: * C++ Desktop Development * .NET Desktop Development In addition also choose these individual components on Visual Studio: * .NET * .NET Framework 4.x targeting packs * .NET Framework 4.x.y SDKs * Code tools * Git for Windows * GitHub Extension for Visual Studio * NuGet package manager * Compilers, build tools and runtimes * C# and Visual Basic Roslyn compilers * C++ 2019 Redistributable Update * C++ CMake tools for Windows * C++/CLI Support for v142 build tools (14.22) * MSBuild * MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.22) * Debugging and testing * .NET profiling tools * C++ profiling tools * Just-in-Time debugger * Development activities * C# and Visual Basic * C++ core features * IntelliCode * Live Share * Games and Graphics * Graphics debugger and GPU profiler for DirectX (required by C++ profiling tools) * SDKs, libraries and frameworks * Windows 10 SDK (10.0.18362.0 or later) * Windows Universal C Runtime ![Visual Studio Installer](images/development/windows_visual_studio_installer_01.png) ![Visual Studio Installer](images/development/windows_visual_studio_installer_02.png) ![Visual Studio Installer](images/development/windows_visual_studio_installer_03.png) After a while, Visual Studio will be ready. ##### Style Guide for Visual Studio Navigate into `Tools > Options > Text Editor` and repeat the following for - C++ - C# Navigate into `Tabs` and set: - Indenting: Smart (default) - Tab size: 4 - Indent size: 4 - Keep tabs (instead of spaces) ![Visual Studio Tabs](images/development/windows_visual_studio_tabs_c++.png) #### Flex and Bison Install it using [chocolatey](https://www.wireshark.org/docs/wsdg_html_chunked/ChSetupWin32.html): ``` choco install -y winflexbison ``` Chocolatey installs these tools into the hidden directory `C:\ProgramData\chocolatey\lib\winflexbison\tools`. #### OpenSSL Icinga 2 requires the OpenSSL library. [Download](https://slproweb.com/products/Win32OpenSSL.html) the Win64 package and install it into `c:\local\OpenSSL-Win64`. Once asked for `Copy OpenSSLs DLLs to` select `The Windows system directory`. That way CMake/Visual Studio will automatically detect them for builds and packaging. > **Note** > > We cannot use the chocolatey package as this one does not provide any development headers. > > Choose 1.1.1 LTS from manual downloads for best compatibility. #### Boost Icinga needs the development header and library files from the Boost library. Visual Studio translates into the following compiler versions: - `msvc-14.2` = Visual Studio 2019 ##### Pre-built Binaries Prefer the pre-built package over self-compiling, if the newest version already exists. Download the [boost-binaries](https://sourceforge.net/projects/boost/files/boost-binaries/) for - msvc-14.2 is Visual Studio 2019 - 64 for 64 bit builds ``` https://sourceforge.net/projects/boost/files/boost-binaries/1.85.0/boost_1_85_0-msvc-14.2-64.exe/download ``` Run the installer and leave the default installation path in `C:\local\boost_1_85_0`. ##### Source & Compile In order to use the boost development header and library files you need to [download](https://www.boost.org/users/download/) Boost and then extract it to e.g. `C:\local\boost_1_85_0`. > **Note** > > Just use `C:\local`, the zip file already contains the sub folder. Extraction takes a while, > the archive contains more than 70k files. In order to integrate Boost into Visual Studio, open the `Developer Command Prompt` from the start menu, and navigate to `C:\local\boost_1_85_0`. Execute `bootstrap.bat` first. ``` cd C:\local\boost_1_85_0 bootstrap.bat ``` Once finished, specify the required `toolset` to compile boost against Visual Studio. This takes quite some time in a Windows VM. Boost Context uses Assembler code, which isn't treated as exception safe by the VS compiler. Therefore set the additional compilation flag according to [this entry](https://lists.boost.org/Archives/boost/2015/08/224570.php). ``` b2 --toolset=msvc-14.2 link=static threading=multi runtime-link=static address-model=64 asmflags=\safeseh ``` ![Windows Boost Build in VS Development Console](images/development/windows_boost_build_dev_cmd.png) #### TortoiseGit TortoiseGit provides a graphical integration into the Windows explorer. This makes it easier to checkout, commit and whatnot. [Download](https://tortoisegit.org/download/) TortoiseGit on your system. In order to clone via Git SSH you also need to create a new directory called `.ssh` inside your user's home directory. Therefore open a command prompt (win key, type `cmd`, enter) and run `mkdir .ssh`. Add your `id_rsa` private key and `id_rsa.pub` public key files into that directory. Start the setup routine and choose `OpenSSH` as default secure transport when asked. Open a Windows Explorer window and navigate into ``` cd %HOMEPATH%\source\repos ``` Right click and select `Git Clone` from the context menu. Use `ssh://git@github.com/icinga/icinga2.git` for SSH clones, `https://github.com/icinga/icinga2.git` otherwise. #### Packages CMake uses CPack and NSIS to create the setup executable including all binaries and libraries in addition to setup dialogues and configuration. Therefore we’ll need to install [NSIS](http://nsis.sourceforge.net/Download) first. We also need to install the Windows Installer XML (WIX) toolset. This has .NET 3.5 as a dependency which might need a reboot of the system which is not handled properly by Chocolatey. Therefore install it first and reboot when asked. ``` Enable-WindowsOptionalFeature -FeatureName "NetFx3" -Online choco install -y wixtoolset ``` #### CMake Icinga 2 uses CMake to manage the build environment. You can generate the Visual Studio project files using CMake. [Download](https://cmake.org/download/) and install CMake. Select to add it to PATH for all users when asked. > **Note** > > In order to properly detect the Boost libraries and VS 2019, install CMake 3.15.2+. > > **Tip** > > Cheatsheet: https://www.brianlheim.com/2018/04/09/cmake-cheat-sheet.html Once setup is completed, open a command prompt and navigate to ``` cd %HOMEPATH%\source\repos ``` Build Icinga with specific CMake variables. This generates a new Visual Studio project file called `icinga2.sln`. Visual Studio translates into the following: - `msvc-14.2` = Visual Studio 2019 You need to specify the previously installed component paths. Variable | Value | Description ----------------------|----------------------------------------------------------------------|------------------------------------------------------- `BOOST_ROOT` | `C:\local\boost_1_85_0` | Root path where you've extracted and compiled Boost. `BOOST_LIBRARYDIR` | Binary: `C:\local\boost_1_85_0\lib64-msvc-14.2`, Source: `C:\local\boost_1_85_0\stage` | Path to the static compiled Boost libraries, directory must contain `lib`. `BISON_EXECUTABLE` | `C:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe` | Path to the Bison executable. `FLEX_EXECUTABLE` | `C:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe` | Path to the Flex executable. `ICINGA2_UNITY_BUILD` | OFF | Disable unity builds for development environments. Tip: If you have previously opened a terminal, run `refreshenv` to re-read updated PATH variables. ##### Build Scripts Icinga provides the build scripts inside the Git repository. Open a new Powershell and navigate into the cloned Git repository. Set specific environment variables and run the build scripts. ``` cd %HOMEPATH%\source\repos\icinga2 .\tools\win32\configure-dev.ps1 .\tools\win32\build.ps1 .\tools\win32\test.ps1 ``` The debug MSI package is located in the `debug` directory. If you did not follow the above steps with Boost binaries and OpenSSL paths, you can still modify the environment variables. ``` $env:CMAKE_GENERATOR='Visual Studio 16 2019' $env:CMAKE_GENERATOR_PLATFORM='x64' $env:ICINGA2_INSTALLPATH = 'C:\Program Files\Icinga2-debug' $env:ICINGA2_BUILDPATH='debug' $env:CMAKE_BUILD_TYPE='Debug' $env:OPENSSL_ROOT_DIR='C:\OpenSSL-Win64' $env:BOOST_ROOT='C:\local\boost_1_85_0' $env:BOOST_LIBRARYDIR='C:\local\boost_1_85_0\lib64-msvc-14.2' ``` #### Icinga 2 in Visual Studio This requires running the configure script once. Navigate to ``` cd %HOMEPATH%\source\repos\icinga2\debug ``` Open `icinga2.sln`. Log into Visual Studio when asked. On the right panel, select to build the `Bin/icinga-app` solution. The executable binaries are located in `Bin\Release\Debug` in your `icinga2` project directory. Navigate there and run `icinga2.exe --version`. ``` cd %HOMEPATH%\source\repos\icinga2\Bin\Release\Debug icinga2.exe --version ``` #### Release Package This is part of the build process script. Override the build type and pick a different build directory. ``` cd %HOMEPATH%\source\repos\icinga2 $env:ICINGA2_BUILDPATH='release' $env:CMAKE_BUILD_TYPE='RelWithDebInfo' .\tools\win32\configure-dev.ps1 .\tools\win32\build.ps1 .\tools\win32\test.ps1 ``` The release MSI package is located in the `release` directory. ### Embedded Dev Env: Pi > **Note** > > This isn't officially supported yet, just a few hints how you can do it yourself. The following examples source from armhf on Raspberry Pi. #### ccache ```bash apt install -y ccache /usr/sbin/update-ccache-symlinks echo 'export PATH="/usr/lib/ccache:$PATH"' | tee -a ~/.bashrc source ~/.bashrc && echo $PATH ``` #### Build Copy the icinga2 source code into `$HOME/icinga2`. Clone the `deb-icinga2` repository into `debian/`. ```bash git clone https://github.com/Icinga/icinga2 $HOME/icinga2 git clone https://github.com/Icinga/deb-icinga2 $HOME/icinga2/debian ``` Then build a Debian package and install it like normal. ```bash dpkg-buildpackage -uc -us ``` ## Package Builds This documentation is explicitly meant for packagers and the Icinga build infrastructure. The following requirements need to be fulfilled in order to build the Icinga application using a dist tarball (including notes for distributions): * cmake >= 2.6 * GNU make (make) or ninja-build * C++ compiler which supports C++17 * RHEL/Fedora/SUSE: gcc-c++ >= 7 (extra Developer Tools on RHEL7 see below) * Debian/Ubuntu: build-essential * Alpine: build-base * you can also use clang++ * pkg-config * OpenSSL library and header files >= 1.0.1 * RHEL/Fedora: openssl-devel * SUSE: libopenssl-devel * Debian/Ubuntu: libssl-dev * Alpine: libressl-dev * Boost library and header files >= 1.66.0 * RHEL/Fedora: boost166-devel * Debian/Ubuntu: libboost-all-dev * Alpine: boost-dev * GNU bison (bison) * GNU flex (flex) >= 2.5.35 * systemd headers * Only required when using systemd * Debian/Ubuntu: libsystemd-dev * RHEL/Fedora: systemd-devel ### Optional features * MySQL (disable with CMake variable `ICINGA2_WITH_MYSQL` to `OFF`) * RHEL/Fedora: mysql-devel * SUSE: libmysqlclient-devel * Debian/Ubuntu: default-libmysqlclient-dev | libmysqlclient-dev * Alpine: mariadb-dev * PostgreSQL (disable with CMake variable `ICINGA2_WITH_PGSQL` to `OFF`) * RHEL/Fedora: postgresql-devel * Debian/Ubuntu: libpq-dev * postgresql-dev on Alpine * libedit (CLI console) * RHEL/Fedora: libedit-devel (RHEL requires rhel-7-server-optional-rpms) * Debian/Ubuntu/Alpine: libedit-dev * Termcap (only required if libedit doesn't already link against termcap/ncurses) * RHEL/Fedora: libtermcap-devel * Debian/Ubuntu: (not necessary) ### Special requirements **FreeBSD**: libexecinfo (automatically used when Icinga 2 is installed via port or package) **RHEL6**: Requires a newer boost version which is available on packages.icinga.com with a version suffixed name. ### Runtime user environment By default Icinga will run as user `icinga` and group `icinga`. Additionally the external command pipe and livestatus features require a dedicated command group `icingacmd`. You can choose your own user/group names and pass them to CMake using the `ICINGA2_USER`, `ICINGA2_GROUP` and `ICINGA2_COMMAND_GROUP` variables. ```bash groupadd icinga groupadd icingacmd useradd -c "icinga" -s /sbin/nologin -G icingacmd -g icinga icinga ``` On Alpine (which uses ash busybox) you can run: ```bash addgroup -S icinga addgroup -S icingacmd adduser -S -D -H -h /var/spool/icinga2 -s /sbin/nologin -G icinga -g icinga icinga adduser icinga icingacmd ``` Add the web server user to the icingacmd group in order to grant it write permissions to the external command pipe and livestatus socket: ```bash usermod -a -G icingacmd www-data ``` Make sure to replace "www-data" with the name of the user your web server is running as. ### Building Icinga 2: Example Once you have installed all the necessary build requirements you can build Icinga 2 using the following commands: ```bash mkdir release && cd release cmake .. cd .. make -C release make install -C release ``` You can specify an alternative installation prefix using `-DCMAKE_INSTALL_PREFIX`: ```bash cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/icinga2 ``` ### CMake Variables In addition to `CMAKE_INSTALL_PREFIX` here are most of the supported Icinga-specific cmake variables. For all variables regarding defaults paths on in CMake, see [GNUInstallDirs](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html). Also see `CMakeLists.txt` for details. #### System Environment * `CMAKE_INSTALL_SYSCONFDIR`: The configuration directory; defaults to `CMAKE_INSTALL_PREFIX/etc` * `CMAKE_INSTALL_LOCALSTATEDIR`: The state directory; defaults to `CMAKE_INSTALL_PREFIX/var` * `ICINGA2_CONFIGDIR`: Main config directory; defaults to `CMAKE_INSTALL_SYSCONFDIR/icinga2` usually `/etc/icinga2` * `ICINGA2_CACHEDIR`: Directory for cache files; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/cache/icinga2` usually `/var/cache/icinga2` * `ICINGA2_DATADIR`: Data directory for the daemon; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/lib/icinga2` usually `/var/lib/icinga2` * `ICINGA2_LOGDIR`: Logfiles of the daemon; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/log/icinga2 usually `/var/log/icinga2` * `ICINGA2_SPOOLDIR`: Spooling directory ; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/spool/icinga2` usually `/var/spool/icinga2` * `ICINGA2_INITRUNDIR`: Runtime data for the init system; defaults to `CMAKE_INSTALL_LOCALSTATEDIR/run/icinga2` usually `/run/icinga2` * `ICINGA2_GIT_VERSION_INFO`: Whether to use Git to determine the version number; defaults to `ON` * `ICINGA2_USER`: The user Icinga 2 should run as; defaults to `icinga` * `ICINGA2_GROUP`: The group Icinga 2 should run as; defaults to `icinga` * `ICINGA2_COMMAND_GROUP`: The command group Icinga 2 should use; defaults to `icingacmd` * `ICINGA2_SYSCONFIGFILE`: Where to put the config file the initscript/systemd pulls it's dirs from; * defaults to `CMAKE_INSTALL_PREFIX/etc/sysconfig/icinga2` * `ICINGA2_PLUGINDIR`: The path for the Monitoring Plugins project binaries; defaults to `/usr/lib/nagios/plugins` #### Build Optimization * `ICINGA2_UNITY_BUILD`: Whether to perform a unity build; defaults to `ON`. Note: This requires additional memory and is not advised for building VMs, Docker for Mac and embedded hardware. * `ICINGA2_LTO_BUILD`: Whether to use link time optimization (LTO); defaults to `OFF` #### Init System * `USE_SYSTEMD=ON|OFF`: Use systemd or a classic SysV initscript; defaults to `OFF` * `INSTALL_SYSTEMD_SERVICE_AND_INITSCRIPT=ON|OFF` Force install both the systemd service definition file and the SysV initscript in parallel, regardless of how `USE_SYSTEMD` is set. Only use this for special packaging purposes and if you know what you are doing. Defaults to `OFF`. #### Features * `ICINGA2_WITH_CHECKER`: Determines whether the checker module is built; defaults to `ON` * `ICINGA2_WITH_COMPAT`: Determines whether the compat module is built; defaults to `ON` * `ICINGA2_WITH_LIVESTATUS`: Determines whether the Livestatus module is built; defaults to `ON` * `ICINGA2_WITH_NOTIFICATION`: Determines whether the notification module is built; defaults to `ON` * `ICINGA2_WITH_PERFDATA`: Determines whether the perfdata module is built; defaults to `ON` * `ICINGA2_WITH_TESTS`: Determines whether the unit tests are built; defaults to `ON` #### MySQL or MariaDB The following settings can be tuned for the MySQL / MariaDB IDO feature. * `ICINGA2_WITH_MYSQL`: Determines whether the MySQL IDO module is built; defaults to `ON` * `MYSQL_CLIENT_LIBS`: Client implementation used (mysqlclient / mariadbclient); defaults searches for `mysqlclient` and `mariadbclient` * `MYSQL_INCLUDE_DIR`: Directory containing include files for the mysqlclient; default empty - checking multiple paths like `/usr/include/mysql` See [FindMySQL.cmake](https://github.com/Icinga/icinga2/blob/master/third-party/cmake/FindMySQL.cmake) for implementation details. #### PostgreSQL The following settings can be tuned for the PostgreSQL IDO feature. * `ICINGA2_WITH_PGSQL`: Determines whether the PostgreSQL IDO module is built; defaults to `ON` * `PostgreSQL_INCLUDE_DIR`: Top-level directory containing the PostgreSQL include directories * `PostgreSQL_LIBRARY`: File path to PostgreSQL library : libpq.so (or libpq.so.[ver] file) See [FindPostgreSQL.cmake](https://github.com/Icinga/icinga2/blob/master/third-party/cmake/FindPostgreSQL.cmake) for implementation details. #### Version detection CMake determines the Icinga 2 version number using `git describe` if the source directory is contained in a Git repository. Otherwise the version number is extracted from the `ICINGA2_VERSION` file. This behavior can be overridden by creating a file called `icinga-version.h.force` in the source directory. Alternatively the `-DICINGA2_GIT_VERSION_INFO=OFF` option for CMake can be used to disable the usage of `git describe`. ### Building RPMs #### Build Environment on RHEL, Fedora, Amazon Linux Setup your build environment: ```bash yum -y install rpmdevtools ``` #### Build Environment on SuSE/SLES SLES: ```bash zypper addrepo http://download.opensuse.org/repositories/devel:tools/SLE_12_SP4/devel:tools.repo zypper refresh zypper install rpmdevtools spectool ``` OpenSuSE: ```bash zypper addrepo http://download.opensuse.org/repositories/devel:tools/openSUSE_Leap_15.0/devel:tools.repo zypper refresh zypper install rpmdevtools spectool ``` #### Package Builds Prepare the rpmbuild directory tree: ```bash cd $HOME rpmdev-setuptree ``` Snapshot builds: ```bash curl https://raw.githubusercontent.com/Icinga/rpm-icinga2/master/icinga2.spec -o $HOME/rpmbuild/SPECS/icinga2.spec ``` > **Note** > > The above command builds snapshot packages. Change to the `release` branch > for release package builds. Copy the tarball to `rpmbuild/SOURCES` e.g. by using the `spectool` binary provided with `rpmdevtools`: ```bash cd $HOME/rpmbuild/SOURCES spectool -g ../SPECS/icinga2.spec cd $HOME/rpmbuild ``` Install the build dependencies: ```bash yum -y install libedit-devel ncurses-devel gcc-c++ libstdc++-devel openssl-devel \ cmake flex bison boost-devel systemd mysql-devel postgresql-devel httpd \ selinux-policy-devel checkpolicy selinux-policy selinux-policy-doc ``` Note: If you are using Amazon Linux, systemd is not required. A shorter way is available using the `yum-builddep` command on RHEL based systems: ```bash yum-builddep SPECS/icinga2.spec ``` Build the RPM: ```bash rpmbuild -ba SPECS/icinga2.spec ``` #### Additional Hints ##### SELinux policy module The following packages are required to build the SELinux policy module: * checkpolicy * selinux-policy-devel * selinux-policy-doc ##### Amazon Linux If you prefer to build packages offline, a suitable Vagrant box is located [here](https://atlas.hashicorp.com/mvbcoding/boxes/awslinux/). ### Build Debian/Ubuntu packages Setup your build environment on Debian/Ubuntu, copy the 'debian' directory from the Debian packaging Git repository (https://github.com/Icinga/deb-icinga2) into your source tree and run the following command: ```bash dpkg-buildpackage -uc -us ``` ### Build Alpine Linux packages A simple way to setup a build environment is installing Alpine in a chroot. In this way, you can set up an Alpine build environment in a chroot under a different Linux distro. There is a script that simplifies these steps with just two commands, and can be found [here](https://github.com/alpinelinux/alpine-chroot-install). Once the build environment is installed, you can setup the system to build the packages by following [this document](https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package). ### Build Post Install Tasks After building Icinga 2 yourself, your package build system should at least run the following post install requirements: * enable the `checker`, `notification` and `mainlog` feature by default * run 'icinga2 api setup' in order to enable the `api` feature and generate TLS certificates for the node ### Run Icinga 2 Icinga 2 comes with a binary that takes care of loading all the relevant components (e.g. for check execution, notifications, etc.): ``` icinga2 daemon [2016-12-08 16:44:24 +0100] information/cli: Icinga application loader (version: v2.5.4-231-gb10a6b7; debug) [2016-12-08 16:44:24 +0100] information/cli: Loading configuration file(s). [2016-12-08 16:44:25 +0100] information/ConfigItem: Committing config item(s). ... ``` #### Init Script Icinga 2 can be started as a daemon using the provided init script: ``` /etc/init.d/icinga2 Usage: /etc/init.d/icinga2 {start|stop|restart|reload|checkconfig|status} ``` #### Systemd If your distribution uses systemd: ``` systemctl {start|stop|reload|status|enable|disable} icinga2 ``` In case the distribution is running systemd >227, you'll also need to package and install the `etc/initsystem/icinga2.service.limits.conf` file into `/etc/systemd/system/icinga2.service.d`. #### openrc Or if your distribution uses openrc (like Alpine): ``` rc-service icinga2 Usage: /etc/init.d/icinga2 {start|stop|restart|reload|checkconfig|status} ``` Note: the openrc's init.d is not shipped by default. A working init.d with openrc can be found here: (https://git.alpinelinux.org/cgit/aports/plain/community/icinga2/icinga2.initd). If you have customized some path, edit the file and adjust it according with your setup. Those few steps can be followed: ```bash wget https://git.alpinelinux.org/cgit/aports/plain/community/icinga2/icinga2.initd mv icinga2.initd /etc/init.d/icinga2 chmod +x /etc/init.d/icinga2 ``` Icinga 2 reads a single configuration file which is used to specify all configuration settings (global settings, hosts, services, etc.). The configuration format is explained in detail in the `doc/` directory. By default `make install` installs example configuration files in `/usr/local/etc/icinga2` unless you have specified a different prefix or sysconfdir. ### Windows Builds The Windows MSI packages are located at https://packages.icinga.com/windows/ The build infrastructure is based on GitLab CI and an Ansible provisioned Windows VM running in OpenStack. The runner uses the scripts located in `tools/win32` to configure, build and test the packages. Uploading them to the package repository is a separate step. For manual package creation, please refer to [this chapter](21-development.md#development-windows-dev-env). ![Windows build pipeline in GitLab](images/development/windows_builds_gitlab_pipeline.png) ## Continuous Integration Icinga uses the integrated CI capabilities on GitHub in the development workflow. This ensures that incoming pull requests and branches are built on create/push events. Contributors and developers can immediately see whether builds fail or succeed and help the final reviews. * For Linux, we are currently using Travis CI. * For Windows, AppVeyor has been integrated. Future plans involve making use of GitHub Actions. In addition to our development platform on GitHub, we are using GitLab's CI platform to build binary packages for all supported operating systems and distributions. These CI pipelines provide even more detailed insights into specific platform failures and developers can react faster. ### CI: Travis CI [Travis CI](https://travis-ci.org/Icinga/icinga2) provides Ubuntu as base distribution where Icinga is compiled from sources followed by running the unit tests and a config validation check. For details, please refer to the [.travis.yml](https://github.com/Icinga/icinga2/blob/master/.travis.yml) configuration file. ### CI: AppVeyor [AppVeyor](https://ci.appveyor.com/project/icinga/icinga2) provides Windows as platform where Visual Studio and Boost libraries come pre-installed. Icinga is built using the Powershell scripts located in `tools/win32`. In addition to that, the unit tests are run. Please check the [appveyor.yml](https://github.com/Icinga/icinga2/blob/master/appveyor.yml) configuration file for details. ## Advanced Development Tips ### GDB Pretty Printers Install the `boost`, `python` and `icinga2` pretty printers. Absolute paths are required, so please make sure to update the installation paths accordingly (`pwd`). ```bash mkdir -p ~/.gdb_printers && cd ~/.gdb_printers ``` Boost Pretty Printers compatible with Python 3: ``` $ git clone https://github.com/mateidavid/Boost-Pretty-Printer.git && cd Boost-Pretty-Printer $ git checkout python-3 $ pwd /home/michi/.gdb_printers/Boost-Pretty-Printer ``` Python Pretty Printers: ```bash cd ~/.gdb_printers svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python ``` Icinga 2 Pretty Printers: ```bash mkdir -p ~/.gdb_printers/icinga2 && cd ~/.gdb_printers/icinga2 wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/icingadbg.py ``` Now you'll need to modify/setup your `~/.gdbinit` configuration file. You can download the one from Icinga 2 and modify all paths. Example on Fedora 22: ``` $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/gdbinit -O ~/.gdbinit $ vim ~/.gdbinit set print pretty on python import sys sys.path.insert(0, '/home/michi/.gdb_printers/icinga2') from icingadbg import register_icinga_printers register_icinga_printers() end python import sys sys.path.insert(0, '/home/michi/.gdb_printers/python') from libstdcxx.v6.printers import register_libstdcxx_printers try: register_libstdcxx_printers(None) except: pass end python import sys sys.path.insert(0, '/home/michi/.gdb_printers/Boost-Pretty-Printer') import boost_print boost_print.register_printers() end ``` If you are getting the following error when running gdb, the `libstdcxx` printers are already preloaded in your environment and you can remove the duplicate import in your `~/.gdbinit` file. ``` RuntimeError: pretty-printer already registered: libstdc++-v6 ``` icinga2-2.14.6/doc/22-selinux.md000066400000000000000000000367101501332562400161270ustar00rootroot00000000000000# SELinux ## Introduction SELinux is a mandatory access control (MAC) system on Linux which adds a fine-grained permission system for access to all system resources such as files, devices, networks and inter-process communication. The most important questions are answered briefly in the [FAQ of the SELinux Project](https://selinuxproject.org/page/FAQ). For more details on SELinux and how to actually use and administrate it on your system have a look at [Red Hat Enterprise Linux 7 - SELinux User's and Administrator's Guide](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/index.html). For a simplified (and funny) introduction download the [SELinux Coloring Book](https://github.com/mairin/selinux-coloring-book). This documentation will use a format similar to the SELinux User's and Administrator's Guide. ### Policy Icinga 2 provides its own SELinux policy. Development target is a policy package for Red Hat Enterprise Linux 7 and derivatives running the targeted policy which confines Icinga 2 with all features and all checks executed. All other distributions will require some tweaks. ### Installation There are two ways of installing the SELinux Policy for Icinga 2 on Enterprise Linux 7. The preferred way is to install the package. The other option involves installing the SELinux policy manually which might be necessary if you need some fixes which haven't made their way into a release yet. If the system runs in enforcing mode and you encounter problems you can set Icinga 2's domain to permissive mode. ``` # sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 28 ``` You can change the configured mode by editing `/etc/selinux/config` and the current mode by executing `setenforce 0`. #### Package installation Simply add the `icinga2-selinux` package to your installation. ```bash yum install icinga2-selinux ``` Ensure that the `icinga2` process is running in its own `icinga2_t` domain after installing the policy package: ``` # systemctl restart icinga2.service # ps -eZ | grep icinga2 system_u:system_r:icinga2_t:s0 2825 ? 00:00:00 icinga2 ``` #### Manual installation This section describes the installation to support development and testing. It assumes that Icinga 2 is already installed from packages and running on the system. As a prerequisite install the `git`, `selinux-policy-devel` and `audit` packages. Enable and start the audit daemon afterwards: ```bash yum install git selinux-policy-devel audit systemctl enable auditd.service systemctl start auditd.service ``` After that clone the icinga2 git repository: ```bash git clone https://github.com/icinga/icinga2 ``` To create and install the policy package run the installation script which also labels the resources. (The script assumes Icinga 2 was started once after system startup, the labeling of the port will only happen once and fail later on.) ```bash cd tools/selinux/ ./icinga.sh ``` After that restart Icinga 2 and verify it running in its own domain `icinga2_t`. ``` # systemctl restart icinga2.service # ps -eZ | grep icinga2 system_u:system_r:icinga2_t:s0 2825 ? 00:00:00 icinga2 ``` ### General When the SELinux policy package for Icinga 2 is installed, the Icinga 2 daemon (icinga2) runs in its own domain `icinga2_t` and is separated from other confined services. Files have to be labeled correctly in order for Icinga 2 to be able to access them. For example the Icinga 2 log files have to have the `icinga2_log_t` label. Also the API port is labeled with `icinga_port_t`. Furthermore Icinga 2 can open high ports and UNIX sockets to connect to databases and features like Graphite. It executes the Nagios plugins and transitions to their context if those are labeled for example `nagios_services_plugin_exec_t` or `nagios_system_plugin_exec_t`. Additionally the Apache web server is allowed to connect to Icinga 2's command pipe in order to allow web interfaces to send commands to icinga2. This will perhaps change later on while investigating Icinga Web 2 for SELinux! ### Types The command pipe is labeled `icinga2_command_t` and other services can request access to it by using the interface `icinga2_send_commands`. The nagios plugins use their own contexts and icinga2 will transition to it. This means plugins have to be labeled correctly for their required permissions. The plugins installed from package should have set their permissions by the corresponding policy module and you can restore them using `restorecon -R -v /usr/lib64/nagios/plugins/`. To label your own plugins use `chcon -t type /path/to/plugin`, for the type have a look at table below. Type | Domain | Use case | Provided by policy package ----------------------------------|------------------------------|------------------------------------------------------------------|--------------------------- nagios_admin_plugin_exec_t | nagios_admin_plugin_t | Plugins which require require read access on all file attributes | nagios nagios_checkdisk_plugin_exec_t | nagios_checkdisk_plugin_t | Plugins which require read access to all filesystem attributes | nagios nagios_mail_plugin_exec_t | nagios_mail_plugin_t | Plugins which access the local mail service | nagios nagios_services_plugin_exec_t | nagios_services_plugin_t | Plugins monitoring network services | nagios nagios_system_plugin_exec_t | nagios_system_plugin_t | Plugins checking local system state | nagios nagios_unconfined_plugin_exec_t | nagios_unconfined_plugin_t | Plugins running without confinement | nagios nagios_eventhandler_plugin_exec_t | nagios_eventhandler_plugin_t | Eventhandler (actually running unconfined) | nagios nagios_openshift_plugin_exec_t | nagios_openshift_plugin_t | Plugins monitoring openshift | nagios nagios_notification_plugin_exec_t | nagios_notification_plugin_t | Notification commands | icinga (will be moved later) If one of those plugin domains causes problems you can set it to permissive by executing `semanage permissive -a domain`. The policy provides a role `icinga2adm_r` for confining an user which enables an administrative user managing only Icinga 2 on the system. This user will also execute the plugins in their domain instead of the users one, so you can verify their execution with the same restrictions like they have when executed by icinga2. ### Booleans SELinux is based on the least level of access required for a service to run. Using booleans you can grant more access in a defined way. The Icinga 2 policy package provides the following booleans. **icinga2_can_connect_all** Having this boolean enabled allows icinga2 to connect to all ports. This can be necessary if you use features which connect to unconfined services, for example the [influxdb writer](14-features.md#influxdb-writer). **icinga2_run_sudo** To allow Icinga 2 executing plugins via sudo you can toogle this boolean. It is disabled by default, resulting in error messages like `execvpe(sudo) failed: Permission denied`. **httpd_can_write_icinga2_command** To allow httpd to write to the command pipe of icinga2 this boolean has to be enabled. This is enabled by default, if not needed you can disable it for more security. **httpd_can_connect_icinga2_api** Enabling this boolean allows httpd to connect to the API of icinga2 (Ports labeled `icinga2_port_t`). This is enabled by default, if not needed you can disable it for more security. ### Configuration Examples #### Run the icinga2 service permissive If problems occur while running the system in enforcing mode and those problems are only caused by the policy of the icinga2 domain, you can set this domain to permissive instead of the complete system. This can be done by executing `semanage permissive -a icinga2_t`. Make sure to report the bugs in the policy afterwards. #### Confining a plugin Download and install a plugin, for example check_mysql_health. ```bash wget https://labs.consol.de/download/shinken-nagios-plugins/check_mysql_health-2.1.9.2.tar.gz tar xvzf check_mysql_health-2.1.9.2.tar.gz cd check_mysql_health-2.1.9.2/ ./configure --libexecdir /usr/lib64/nagios/plugins make make install ``` It is labeled `nagios_unconfined_plugins_exec_t` by default, so it runs without restrictions. ``` # ls -lZ /usr/lib64/nagios/plugins/check_mysql_health -rwxr-xr-x. root root system_u:object_r:nagios_unconfined_plugin_exec_t:s0 /usr/lib64/nagios/plugins/check_mysql_health ``` In this case the plugin is monitoring a service, so it should be labeled `nagios_services_plugin_exec_t` to restrict its permissions. ``` # chcon -t nagios_services_plugin_exec_t /usr/lib64/nagios/plugins/check_mysql_health # ls -lZ /usr/lib64/nagios/plugins/check_mysql_health -rwxr-xr-x. root root system_u:object_r:nagios_services_plugin_exec_t:s0 /usr/lib64/nagios/plugins/check_mysql_health ``` The plugin still runs fine but if someone changes the script to do weird stuff it will fail to do so. #### Allow icinga to connect to all ports. You are running graphite on a different port than `2003` and want `icinga2` to connect to it. Change the port value for the graphite feature according to your graphite installation before enabling it. ``` # cat /etc/icinga2/features-enabled/graphite.conf /** * The GraphiteWriter type writes check result metrics and * performance data to a graphite tcp socket. */ library "perfdata" object GraphiteWriter "graphite" { //host = "127.0.0.1" //port = 2003 port = 2004 } # icinga2 feature enable graphite ``` Before you restart the icinga2 service allow it to connect to all ports by enabling the boolean `icinga2_can_connect_all` (now and permanent). ```bash setsebool icinga2_can_connect_all true setsebool -P icinga2_can_connect_all true ``` If you restart the daemon now it will successfully connect to graphite. #### Running plugins requiring sudo Some plugins require privileged access to the system and are designied to be executed via `sudo` to get these privileges. In this case it is the CheckCommand [running_kernel](10-icinga-template-library.md#plugin-contrib-command-running_kernel) which is set to use `sudo`. # cat /etc/icinga2/conf.d/services.conf apply Service "kernel" { import "generic-service" check_command = "running_kernel" vars.running_kernel_use_sudo = true assign where host.name == NodeName } Having this Service defined will result in a UNKNOWN state and the error message `execvpe(sudo) failed: Permission denied` because SELinux dening the execution. Switching the boolean `icinga2_run_sudo` to allow the execution will result in the check executed successfully. # setsebool icinga2_run_sudo true # setsebool -P icinga2_run_sudo true #### Confining a user If you want to have an administrative account capable of only managing icinga2 and not the complete system, you can restrict the privileges by confining this user. This is completly optional! Start by adding the Icinga 2 administrator role `icinga2adm_r` to the administrative SELinux user `staff_u`. ```bash semanage user -m -R "staff_r sysadm_r system_r unconfined_r icinga2adm_r" staff_u ``` Confine your user login and create a sudo rule. ```bash semanage login -a dirk -s staff_u echo "dirk ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/dirk ``` Login to the system using ssh and verify your id. ``` $ id -Z staff_u:staff_r:staff_t:s0-s0:c0.c1023 ``` Try to execute some commands as root using sudo. ``` $ sudo id -Z staff_u:staff_r:staff_t:s0-s0:c0.c1023 $ sudo vi /etc/icinga2/icinga2.conf "/etc/icinga2/icinga2.conf" [Permission Denied] $ sudo cat /var/log/icinga2/icinga2.log cat: /var/log/icinga2/icinga2.log: Permission denied $ sudo systemctl reload icinga2.service Failed to get D-Bus connection: No connection to service manager. ``` Those commands fail because you only switch to root but do not change your SELinux role. Try again but tell sudo also to switch the SELinux role and type. ``` $ sudo -r icinga2adm_r -t icinga2adm_t id -Z staff_u:icinga2adm_r:icinga2adm_t:s0-s0:c0.c1023 $ sudo -r icinga2adm_r -t icinga2adm_t vi /etc/icinga2/icinga2.conf "/etc/icinga2/icinga2.conf" $ sudo -r icinga2adm_r -t icinga2adm_t cat /var/log/icinga2/icinga2.log [2015-03-26 20:48:14 +0000] information/DynamicObject: Dumping program state to file '/var/lib/icinga2/icinga2.state' $ sudo -r icinga2adm_r -t icinga2adm_t systemctl reload icinga2.service ``` Now the commands will work, but you have always to remember to add the arguments, so change the sudo rule to set it by default. ```bash echo "dirk ALL=(ALL) ROLE=icinga2adm_r TYPE=icinga2adm_t NOPASSWD: ALL" > /etc/sudoers.d/dirk ``` Now try the commands again without providing the role and type and they will work, but if you try to read apache logs or restart apache for example it will still fail. ``` $ sudo cat /var/log/httpd/error_log /bin/cat: /var/log/httpd/error_log: Keine Berechtigung $ sudo systemctl reload httpd.service Failed to issue method call: Access denied ``` ## Bugreports If you experience any problems while running in enforcing mode try to reproduce it in permissive mode. If the problem persists it is not related to SELinux because in permissive mode SELinux will not deny anything. After some feedback Icinga 2 is now running in a enforced domain, but still adds also some rules for other necessary services so no problems should occure at all. But you can help to enhance the policy by testing Icinga 2 running confined by SELinux. Please add the following information to [bug reports](https://icinga.com/community/): * Versions, configuration snippets, etc. * Output of `semodule -l | grep -e icinga2 -e nagios -e apache` * Output of `ps -eZ | grep icinga2` * Output of `semanage port -l | grep icinga2` * Output of `audit2allow -li /var/log/audit/audit.log` If access to a file is blocked and you can tell which one please provided the output of `ls -lZ /path/to/file` (and perhaps the directory above). If asked for full audit.log add `-w /etc/shadow -p w` to `/etc/audit/rules.d/audit.rules`, restart the audit daemon, reproduce the problem and add `/var/log/audit/audit.log` to the bug report. With the added audit rule it will include the path of files access was denied to. If asked to provide full audit log with dontaudit rules disabled executed `semodule -DB` before reproducing the problem. After that enable the rules again to prevent auditd spamming your logfile by executing `semodule -B`. icinga2-2.14.6/doc/23-migrating-from-icinga-1x.md000066400000000000000000001576001501332562400211430ustar00rootroot00000000000000# Migration from Icinga 1.x or Nagios !!! note Icinga 1.x was originally a fork of Nagios. The information provided here also applies to Nagios. ## Configuration Migration The Icinga 2 configuration format introduces plenty of behavioural changes. In order to ease migration from Icinga 1.x, this section provides hints and tips on your migration requirements. ### Automated Config Migration Depending on your previous setup, you may have already used different sources for generating the 1.x configuration files. If this is the case, we strongly recommend to use these sources in combination with the [Icinga Director](https://icinga.com/docs/director/latest/doc/01-Introduction/). This can be for example: * A CMDB or RDBMS which provides host details and facts * PuppetDB * CSV/XSL/JSON files * Cloud resources (AWS, etc.) In case you have been using Icinga Web 1.x or an addon requiring the underlying IDO database, you can use this as database resource to import the host details. Talks: * [This talk from OSMC 2016](https://www.youtube.com/watch?v=T6GBsfeXIZI) shares more insights (German). * [Automated Monitoring in heterogeneous environments](https://www.youtube.com/watch?v=bkUlS5rlHzM&list=PLeoxx10paaAn_xHJ5wBhnBJyW_d5G7-Bl&index=8) Continue reading more about [Import Sources](https://icinga.com/docs/director/latest/doc/70-Import-and-Sync/) for the Icinga Director. ### Manual Config Migration For a long-term migration of your configuration you should consider re-creating your configuration based on the proposed Icinga 2 configuration paradigm. Please read the [next chapter](23-migrating-from-icinga-1x.md#differences-1x-2) to find out more about the differences between 1.x and 2. ### Manual Config Migration Hints These hints should provide you with enough details for manually migrating your configuration, or to adapt your configuration export tool to dump Icinga 2 configuration instead of Icinga 1.x configuration. The examples are taken from Icinga 1.x test and production environments and converted straight into a possible Icinga 2 format. If you found a different strategy, please let us know! If you require in-depth explanations, please check the [next chapter](23-migrating-from-icinga-1x.md#differences-1x-2). #### Manual Config Migration Hints for Intervals By default all intervals without any duration literal are interpreted as seconds. Therefore all existing Icinga 1.x `*_interval` attributes require an additional `m` duration literal. Icinga 1.x: ``` define service { service_description service1 host_name localhost1 check_command test_customvar use generic-service check_interval 5 retry_interval 1 } ``` Icinga 2: ``` object Service "service1" { import "generic-service" host_name = "localhost1" check_command = "test_customvar" check_interval = 5m retry_interval = 1m } ``` #### Manual Config Migration Hints for Services If you have used the `host_name` attribute in Icinga 1.x with one or more host names this service belongs to, you can migrate this to the [apply rules](03-monitoring-basics.md#using-apply) syntax. Icinga 1.x: ``` define service { service_description service1 host_name localhost1,localhost2 check_command test_check use generic-service } ``` Icinga 2: ``` apply Service "service1" { import "generic-service" check_command = "test_check" assign where host.name in [ "localhost1", "localhost2" ] } ``` In Icinga 1.x you would have organized your services with hostgroups using the `hostgroup_name` attribute like the following example: ``` define service { service_description servicewithhostgroups hostgroup_name hostgroup1,hostgroup3 check_command test_check use generic-service } ``` Using Icinga 2 you can migrate this to the [apply rules](03-monitoring-basics.md#using-apply) syntax: ``` apply Service "servicewithhostgroups" { import "generic-service" check_command = "test_check" assign where "hostgroup1" in host.groups assign where "hostgroup3" in host.groups } ``` #### Manual Config Migration Hints for Group Members The Icinga 1.x hostgroup `hg1` has two members `host1` and `host2`. The hostgroup `hg2` has `host3` as a member and includes all members of the `hg1` hostgroup. ``` define hostgroup { hostgroup_name hg1 members host1,host2 } define hostgroup { hostgroup_name hg2 members host3 hostgroup_members hg1 } ``` This can be migrated to Icinga 2 and [using group assign](17-language-reference.md#group-assign). The additional nested hostgroup `hg1` is included into `hg2` with the `groups` attribute. ``` object HostGroup "hg1" { groups = [ "hg2" ] assign where host.name in [ "host1", "host2" ] } object HostGroup "hg2" { assign where host.name == "host3" } ``` These assign rules can be applied for all groups: `HostGroup`, `ServiceGroup` and `UserGroup` (requires renaming from `contactgroup`). > **Tip** > > Define custom variables and assign/ignore members based on these attribute pattern matches. #### Manual Config Migration Hints for Check Command Arguments Host and service check command arguments are separated by a `!` in Icinga 1.x. Their order is important and they are referenced as `$ARGn$` where `n` is the argument counter. ``` define command { command_name my-ping command_line $USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5 } define service { use generic-service host_name my-server service_description my-ping check_command my-ping-check!100.0,20%!500.0,60% } ``` While you could manually migrate this like (please note the new generic command arguments and default argument values!): ``` object CheckCommand "my-ping-check" { command = [ PluginDir + "/check_ping", "-4" ] arguments = { "-H" = "$ping_address$" "-w" = "$ping_wrta$,$ping_wpl$%" "-c" = "$ping_crta$,$ping_cpl$%" "-p" = "$ping_packets$" "-t" = "$ping_timeout$" } vars.ping_address = "$address$" vars.ping_wrta = 100 vars.ping_wpl = 5 vars.ping_crta = 200 vars.ping_cpl = 15 } object Service "my-ping" { import "generic-service" host_name = "my-server" check_command = "my-ping-check" vars.ping_wrta = 100 vars.ping_wpl = 20 vars.ping_crta = 500 vars.ping_cpl = 60 } ``` #### Manual Config Migration Hints for Runtime Macros Runtime macros have been renamed. A detailed comparison table can be found [here](23-migrating-from-icinga-1x.md#differences-1x-2-runtime-macros). For example, accessing the service check output looks like the following in Icinga 1.x: ``` $SERVICEOUTPUT$ ``` In Icinga 2 you will need to write: ``` $service.output$ ``` Another example referencing the host's address attribute in Icinga 1.x: ``` $HOSTADDRESS$ ``` In Icinga 2 you'd just use the following macro to access all `address` attributes (even overridden from the service objects): ``` $address$ ``` #### Manual Config Migration Hints for Runtime Custom Variables Custom variables from Icinga 1.x are available as Icinga 2 custom variables. ``` define command { command_name test_customvar command_line echo "Host CV: $_HOSTCVTEST$ Service CV: $_SERVICECVTEST$\n" } define host { host_name localhost1 check_command test_customvar use generic-host _CVTEST host cv value } define service { service_description service1 host_name localhost1 check_command test_customvar use generic-service _CVTEST service cv value } ``` Can be written as the following in Icinga 2: ``` object CheckCommand "test_customvar" { command = "echo "Host CV: $host.vars.CVTEST$ Service CV: $service.vars.CVTEST$\n"" } object Host "localhost1" { import "generic-host" check_command = "test_customvar" vars.CVTEST = "host cv value" } object Service "service1" { host_name = "localhost1" check_command = "test_customvar" vars.CVTEST = "service cv value" } ``` If you are just defining `$CVTEST$` in your command definition, its value depends on the execution scope -- the host check command will fetch the host attribute value of `vars.CVTEST` while the service check command resolves its value to the service attribute attribute `vars.CVTEST`. > **Note** > > Custom variables in Icinga 2 are case-sensitive. `vars.CVTEST` is not the same as `vars.CvTest`. #### Manual Config Migration Hints for Contacts (Users) Contacts in Icinga 1.x act as users in Icinga 2, but do not have any notification commands specified. This migration part is explained in the [next chapter](23-migrating-from-icinga-1x.md#manual-config-migration-hints-notifications). ``` define contact{ contact_name testconfig-user use generic-user alias Icinga Test User service_notification_options c,f,s,u email icinga@localhost } ``` The `service_notification_options` can be [mapped](23-migrating-from-icinga-1x.md#manual-config-migration-hints-notification-filters) into generic `state` and `type` filters, if additional notification filtering is required. `alias` gets renamed to `display_name`. ``` object User "testconfig-user" { import "generic-user" display_name = "Icinga Test User" email = "icinga@localhost" } ``` This user can be put into usergroups (former contactgroups) or referenced in newly migration notification objects. #### Manual Config Migration Hints for Notifications If you are migrating a host or service notification, you'll need to extract the following information from your existing Icinga 1.x configuration objects * host/service attribute `contacts` and `contact_groups` * host/service attribute `notification_options` * host/service attribute `notification_period` * host/service attribute `notification_interval` The clean approach is to refactor your current contacts and their notification command methods into a generic strategy * host or service has a notification type (for example mail) * which contacts (users) are notified by mail? * do the notification filters, periods, intervals still apply for them? (do a cleanup during migration) * assign users and groups to these notifications * Redesign the notifications into generic [apply rules](03-monitoring-basics.md#using-apply-notifications) The ugly workaround solution could look like this: Extract all contacts from the remaining groups, and create a unique list. This is required for determining the host and service notification commands involved. * contact attributes `host_notification_commands` and `service_notification_commands` (can be a comma separated list) * get the command line for each notification command and store them for later * create a new notification name and command name Generate a new notification object based on these values. Import the generic template based on the type (`host` or `service`). Assign it to the host or service and set the newly generated notification command name as `command` attribute. ``` object Notification "" { import "mail-host-notification" host_name = "" command = "" ``` Convert the `notification_options` attribute from Icinga 1.x to Icinga 2 `states` and `types`. Details [here](23-migrating-from-icinga-1x.md#manual-config-migration-hints-notification-filters). Add the notification period. ``` states = [ OK, Warning, Critical ] types = [ Recovery, Problem, Custom ] period = "24x7" ``` The current contact acts as `users` attribute. ``` users = [ "" ] } ``` Do this in a loop for all notification commands (depending if host or service contact). Once done, dump the collected notification commands. The result of this migration are lots of unnecessary notification objects and commands but it will unroll the Icinga 1.x logic into the revamped Icinga 2 notification object schema. If you are looking for code examples, try [LConf](https://www.netways.org). #### Manual Config Migration Hints for Notification Filters Icinga 1.x defines all notification filters in an attribute called `notification_options`. Using Icinga 2 you will have to split these values into the `states` and `types` attributes. > **Note** > > `Recovery` type requires the `Ok` state. > `Custom` and `Problem` should always be set as `type` filter. Icinga 1.x option | Icinga 2 state | Icinga 2 type ----------------------|-----------------------|------------------- o | OK (Up for hosts) | w | Warning | Problem c | Critical | Problem u | Unknown | Problem d | Down | Problem s | . | DowntimeStart / DowntimeEnd / DowntimeRemoved r | Ok | Recovery f | . | FlappingStart / FlappingEnd n | 0 (none) | 0 (none) . | . | Custom #### Manual Config Migration Hints for Escalations Escalations in Icinga 1.x are a bit tricky. By default service escalations can be applied to hosts and hostgroups and require a defined service object. The following example applies a service escalation to the service `dep_svc01` and all hosts in the `hg_svcdep2` hostgroup. The default `notification_interval` is set to `10` minutes notifying the `cg_admin` contact. After 20 minutes (`10*2`, notification_interval * first_notification) the notification is escalated to the `cg_ops` contactgroup until 60 minutes (`10*6`) have passed. ``` define service { service_description dep_svc01 host_name dep_hostsvc01,dep_hostsvc03 check_command test2 use generic-service notification_interval 10 contact_groups cg_admin } define hostgroup { hostgroup_name hg_svcdep2 members dep_hostsvc03 } # with hostgroup_name and service_description define serviceescalation { hostgroup_name hg_svcdep2 service_description dep_svc01 first_notification 2 last_notification 6 contact_groups cg_ops } ``` In Icinga 2 the service and hostgroup definition will look quite the same. Save the `notification_interval` and `contact_groups` attribute for an additional notification. ``` apply Service "dep_svc01" { import "generic-service" check_command = "test2" assign where host.name == "dep_hostsvc01" assign where host.name == "dep_hostsvc03" } object HostGroup "hg_svcdep2" { assign where host.name == "dep_hostsvc03" } apply Notification "email" to Service { import "service-mail-notification" interval = 10m user_groups = [ "cg_admin" ] assign where service.name == "dep_svc01" && (host.name == "dep_hostsvc01" || host.name == "dep_hostsvc03") } ``` Calculate the begin and end time for the newly created escalation notification: * begin = first_notification * notification_interval = 2 * 10m = 20m * end = last_notification * notification_interval = 6 * 10m = 60m = 1h Assign the notification escalation to the service `dep_svc01` on all hosts in the hostgroup `hg_svcdep2`. ``` apply Notification "email-escalation" to Service { import "service-mail-notification" interval = 10m user_groups = [ "cg_ops" ] times = { begin = 20m end = 1h } assign where service.name == "dep_svc01" && "hg_svcdep2" in host.groups } ``` The assign rule could be made more generic and the notification be applied to more than just this service belonging to hosts in the matched hostgroup. > **Note** > > When the notification is escalated, Icinga 1.x suppresses notifications to the default contacts. > In Icinga 2 an escalation is an additional notification with a defined begin and end time. The > `email` notification will continue as normal. #### Manual Config Migration Hints for Dependencies There are some dependency examples already in the [basics chapter](03-monitoring-basics.md#dependencies). Dependencies in Icinga 1.x can be confusing in terms of which host/service is the parent and which host/service acts as the child. While Icinga 1.x defines `notification_failure_criteria` and `execution_failure_criteria` as dependency filters, this behaviour has changed in Icinga 2. There is no 1:1 migration but generally speaking the state filter defined in the `execution_failure_criteria` defines the Icinga 2 `state` attribute. If the state filter matches, you can define whether to disable checks and notifications or not. The following example describes service dependencies. If you migrate from Icinga 1.x, you will only want to use the classic `Host-to-Host` and `Service-to-Service` dependency relationships. ``` define service { service_description dep_svc01 hostgroup_name hg_svcdep1 check_command test2 use generic-service } define service { service_description dep_svc02 hostgroup_name hg_svcdep2 check_command test2 use generic-service } define hostgroup { hostgroup_name hg_svcdep2 members host2 } define host{ use linux-server-template host_name host1 address 192.168.1.10 } # with hostgroup_name and service_description define servicedependency { host_name host1 dependent_hostgroup_name hg_svcdep2 service_description dep_svc01 dependent_service_description * execution_failure_criteria u,c notification_failure_criteria w,u,c inherits_parent 1 } ``` Map the dependency attributes accordingly. Icinga 1.x | Icinga 2 ----------------------|--------------------- host_name | parent_host_name dependent_host_name | child_host_name (used in assign/ignore) dependent_hostgroup_name | all child hosts in group (used in assign/ignore) service_description | parent_service_name dependent_service_description | child_service_name (used in assign/ignore) And migrate the host and services. ``` object Host "host1" { import "linux-server-template" address = "192.168.1.10" } object HostGroup "hg_svcdep2" { assign where host.name == "host2" } apply Service "dep_svc01" { import "generic-service" check_command = "test2" assign where "hp_svcdep1" in host.groups } apply Service "dep_svc02" { import "generic-service" check_command = "test2" assign where "hp_svcdep2" in host.groups } ``` When it comes to the `execution_failure_criteria` and `notification_failure_criteria` attribute migration, you will need to map the most common values, in this example `u,c` (`Unknown` and `Critical` will cause the dependency to fail). Therefore the `Dependency` should be ok on Ok and Warning. `inherits_parents` is always enabled. ``` apply Dependency "all-svc-for-hg-hg_svcdep2-on-host1-dep_svc01" to Service { parent_host_name = "host1" parent_service_name = "dep_svc01" states = [ Ok, Warning ] disable_checks = true disable_notifications = true assign where "hg_svcdep2" in host.groups } ``` Host dependencies are explained in the [next chapter](23-migrating-from-icinga-1x.md#manual-config-migration-hints-host-parents). #### Manual Config Migration Hints for Host Parents Host parents from Icinga 1.x are migrated into `Host-to-Host` dependencies in Icinga 2. The following example defines the `vmware-master` host as parent host for the guest virtual machines `vmware-vm1` and `vmware-vm2`. By default all hosts in the hostgroup `vmware` should get the parent assigned. This isn't really solvable with Icinga 1.x parents, but only with host dependencies. ``` define host{ use linux-server-template host_name vmware-master hostgroups vmware address 192.168.1.10 } define host{ use linux-server-template host_name vmware-vm1 hostgroups vmware address 192.168.27.1 parents vmware-master } define host{ use linux-server-template host_name vmware-vm2 hostgroups vmware address 192.168.28.1 parents vmware-master } ``` By default all hosts in the hostgroup `vmware` should get the parent assigned (but not the `vmware-master` host itself). This isn't really solvable with Icinga 1.x parents, but only with host dependencies as shown below: ``` define hostdependency { dependent_hostgroup_name vmware dependent_host_name !vmware-master host_name vmware-master inherits_parent 1 notification_failure_criteria d,u execution_failure_criteria d,u dependency_period testconfig-24x7 } ``` When migrating to Icinga 2, the parents must be changed to a newly created host dependency. Map the following attributes Icinga 1.x | Icinga 2 ----------------------|--------------------- host_name | parent_host_name dependent_host_name | child_host_name (used in assign/ignore) dependent_hostgroup_name | all child hosts in group (used in assign/ignore) The Icinga 2 configuration looks like this: ``` object Host "vmware-master" { import "linux-server-template" groups += [ "vmware" ] address = "192.168.1.10" vars.is_vmware_master = true } object Host "vmware-vm1" { import "linux-server-template" groups += [ "vmware" ] address = "192.168.27.1" } object Host "vmware-vm2" { import "linux-server-template" groups += [ "vmware" ] address = "192.168.28.1" } apply Dependency "vmware-master" to Host { parent_host_name = "vmware-master" assign where "vmware" in host.groups ignore where host.vars.is_vmware_master ignore where host.name == "vmware-master" } ``` For easier identification you could add the `vars.is_vmware_master` attribute to the `vmware-master` host and let the dependency ignore that instead of the hardcoded host name. That's different to the Icinga 1.x example and a best practice hint only. Another way to express the same configuration would be something like: ``` object Host "vmware-master" { import "linux-server-template" groups += [ "vmware" ] address = "192.168.1.10" } object Host "vmware-vm1" { import "linux-server-template" groups += [ "vmware" ] address = "192.168.27.1" vars.parents = [ "vmware-master" ] } object Host "vmware-vm2" { import "linux-server-template" groups += [ "vmware" ] address = "192.168.28.1" vars.parents = [ "vmware-master" ] } apply Dependency "host-to-parent-" for (parent in host.vars.parents) to Host { parent_host_name = parent } ``` This example allows finer grained host-to-host dependency, as well as multiple dependency support. #### Manual Config Migration Hints for Distributed Setups * Icinga 2 does not use active/passive instances calling OSCP commands and requiring the NSCA daemon for passing check results between instances. * Icinga 2 does not support any 1.x NEB addons for check load distribution * If your current setup consists of instances distributing the check load, you should consider building a [load distribution](06-distributed-monitoring.md#distributed-monitoring-scenarios) setup with Icinga 2. * If your current setup includes active/passive clustering with external tools like Pacemaker/DRBD, consider the [High Availability](06-distributed-monitoring.md#distributed-monitoring-scenarios) setup. * If you have build your own custom configuration deployment and check result collecting mechanism, you should re-design your setup and re-evaluate your requirements, and how they may be fulfilled using the Icinga 2 cluster capabilities. ## Differences between Icinga 1.x and 2 ### Configuration Format Icinga 1.x supports two configuration formats: key-value-based settings in the `icinga.cfg` configuration file and object-based in included files (`cfg_dir`, `cfg_file`). The path to the `icinga.cfg` configuration file must be passed to the Icinga daemon at startup. icinga.cfg: ``` enable_notifications=1 ``` objects.cfg: ``` define service { notifications_enabled 0 } ``` Icinga 2 supports objects and (global) variables, but does not make a difference between the main configuration file or any other included file. icinga2.conf: ``` const EnableNotifications = true object Service "test" { enable_notifications = false } ``` #### Sample Configuration and ITL While Icinga 1.x ships sample configuration and templates spread in various object files, Icinga 2 moves all templates into the Icinga Template Library (ITL) and includes them in the sample configuration. Additional plugin check commands are shipped with Icinga 2 as well. The ITL will be updated on every release and must not be edited by the user. There are still generic templates available for your convenience which may or may not be re-used in your configuration. For instance, `generic-service` includes all required attributes except `check_command` for a service. Sample configuration files are located in the `conf.d/` directory which is included in `icinga2.conf` by default. > **Note** > > Add your own custom templates in the `conf.d/` directory as well, e.g. inside > the [templates.conf](04-configuration.md#templates-conf) file. ### Main Config File In Icinga 1.x there are many global configuration settings available in `icinga.cfg`. Icinga 2 only uses a small set of [global constants](17-language-reference.md#constants) allowing you to specify certain different setting such as the `NodeName` in a cluster scenario. Aside from that, the [icinga2.conf](04-configuration.md#icinga2-conf) should take care of including global constants, enabled [features](11-cli-commands.md#enable-features) and the object configuration. ### Include Files and Directories In Icinga 1.x the `icinga.cfg` file contains `cfg_file` and `cfg_dir` directives. The `cfg_dir` directive recursively includes all files with a `.cfg` suffix in the given directory. Only absolute paths may be used. The `cfg_file` and `cfg_dir` directives can include the same file twice which leads to configuration errors in Icinga 1.x. ``` cfg_file=/etc/icinga/objects/commands.cfg cfg_dir=/etc/icinga/objects ``` Icinga 2 supports wildcard includes and relative paths, e.g. for including `conf.d/*.conf` in the same directory. ``` include "conf.d/*.conf" ``` If you want to include files and directories recursively, you need to define a separate option and add the directory and an optional pattern. ``` include_recursive "conf.d" ``` A global search path for includes is available for advanced features like the Icinga Template Library (ITL) or additional monitoring plugins check command configuration. ``` include include ``` By convention the `.conf` suffix is used for Icinga 2 configuration files. ### Resource File and Global Macros Global macros such as for the plugin directory, usernames and passwords can be set in the `resource.cfg` configuration file in Icinga 1.x. By convention the `USER1` macro is used to define the directory for the plugins. Icinga 2 uses global constants instead. In the default config these are set in the `constants.conf` configuration file: ``` /** * This file defines global constants which can be used in * the other configuration files. At a minimum the * PluginDir constant should be defined. */ const PluginDir = "/usr/lib/nagios/plugins" ``` [Global macros](17-language-reference.md#constants) can only be defined once. Trying to modify a global constant will result in an error. ### Configuration Comments In Icinga 1.x comments are made using a leading hash (`#`) or a semi-colon (`;`) for inline comments. In Icinga 2 comments can either be encapsulated by `/*` and `*/` (allowing for multi-line comments) or starting with two slashes (`//`). A leading hash (`#`) could also be used. ### Object Names Object names must not contain an exclamation mark (`!`). Use the `display_name` attribute to specify user-friendly names which should be shown in UIs (supported by Icinga Web 2 for example). Object names are not specified using attributes (e.g. `service_description` for services) like in Icinga 1.x but directly after their type definition. ``` define service { host_name localhost service_description ping4 } object Service "ping4" { host_name = "localhost" } ``` ### Templates In Icinga 1.x templates are identified using the `register 0` setting. Icinga 2 uses the `template` identifier: ``` template Service "ping4-template" { } ``` Icinga 1.x objects inherit from templates using the `use` attribute. Icinga 2 uses the keyword `import` with template names in double quotes. ``` define service { service_description testservice use tmpl1,tmpl2,tmpl3 } object Service "testservice" { import "tmpl1" import "tmpl2" import "tmpl3" } ``` The last template overrides previously set values. ### Object attributes Icinga 1.x separates attribute and value pairs with whitespaces/tabs. Icinga 2 requires an equal sign (=) between them. ``` define service { check_interval 5 } object Service "test" { check_interval = 5m } ``` Please note that the default time value is seconds if no duration literal is given. `check_interval = 5` behaves the same as `check_interval = 5s`. All strings require double quotes in Icinga 2. Therefore a double quote must be escaped by a backslash (e.g. in command line). If an attribute identifier starts with a number, it must be enclosed in double quotes as well. #### Alias vs. Display Name In Icinga 1.x a host can have an `alias` and a `display_name` attribute used for a more descriptive name. A service only can have a `display_name` attribute. The `alias` is used for group, timeperiod, etc. objects too. Icinga 2 only supports the `display_name` attribute which is also taken into account by Icinga web interfaces. ### Custom Variables Icinga 2 allows you to define custom variables in the `vars` dictionary. The `notes`, `notes_url`, `action_url`, `icon_image`, `icon_image_alt` attributes for host and service objects are still available in Icinga 2. `2d_coords` and `statusmap_image` are not supported in Icinga 2. Icinga 1.x custom variable attributes must be prefixed using an underscore (`_`). In Icinga 2 these attributes must be added to the `vars` dictionary as custom variables. ``` vars.dn = "cn=icinga2-dev-host,ou=icinga,ou=main,ou=IcingaConfig,ou=LConf,dc=icinga,dc=org" vars.cv = "my custom cmdb description" ``` These custom variables are also used as [command parameters](03-monitoring-basics.md#command-passing-parameters). While Icinga 1.x only supports numbers and strings as custom variable values, Icinga 2 extends that to arrays and (nested) dictionaries. For more details look [here](03-monitoring-basics.md#custom-variables). ### Host Service Relation In Icinga 1.x a service object is associated with a host by defining the `host_name` attribute in the service definition. Alternate methods refer to `hostgroup_name` or behaviour changing regular expression. The preferred way of associating hosts with services in Icinga 2 is by using the [apply](03-monitoring-basics.md#using-apply) keyword. Direct object relations between a service and a host still allow you to use the `host_name` [Service](09-object-types.md#objecttype-service) object attribute. ### Users Contacts have been renamed to users (same for groups). A contact does not only provide (custom) attributes and notification commands used for notifications, but is also used for authorization checks in Icinga 1.x. Icinga 2 changes that behavior and makes the user an attribute provider only. These attributes can be accessed using [runtime macros](03-monitoring-basics.md#runtime-macros) inside notification command definitions. In Icinga 2 notification commands are not directly associated with users. Instead the notification command is specified inside `Notification` objects next to user and user group relations. The `IdoMySqlConnection` and `LivestatusListener` types will provide the contact and contactgroups attributes for services for compatibility reasons. These values are calculated from all services, their notifications, and their users. ### Macros Various object attributes and runtime variables can be accessed as macros in commands in Icinga 1.x -- Icinga 2 supports all required [custom variables](03-monitoring-basics.md#custom-variables). #### Command Arguments If you have previously used Icinga 1.x, you may already be familiar with user and argument definitions (e.g., `USER1` or `ARG1`). Unlike in Icinga 1.x the Icinga 2 custom variables may have arbitrary names and arguments are no longer specified in the `check_command` setting. In Icinga 1.x arguments are specified in the `check_command` attribute and are separated from the command name using an exclamation mark (`!`). Please check the migration hints for a detailed [migration example](23-migrating-from-icinga-1x.md#manual-config-migration-hints-check-command-arguments). > **Note** > > The Icinga 1.x feature named `Command Expander` does not work with Icinga 2. #### Environment Macros The global configuration setting `enable_environment_macros` does not exist in Icinga 2. Macros exported into the [environment](03-monitoring-basics.md#command-environment-variables) can be set using the `env` attribute in command objects. #### Runtime Macros Icinga 2 requires an object specific namespace when accessing configuration and stateful runtime macros. Custom variables can be accessed directly. If a runtime macro from Icinga 1.x is not listed here, it is not supported by Icinga 2. Changes to user (contact) runtime macros Icinga 1.x | Icinga 2 -----------------------|---------------------- CONTACTNAME | user.name CONTACTALIAS | user.display_name CONTACTEMAIL | user.email CONTACTPAGER | user.pager `CONTACTADDRESS*` is not supported but can be accessed as `$user.vars.address1$` if set. Changes to service runtime macros Icinga 1.x | Icinga 2 -----------------------|---------------------- SERVICEDESC | service.name SERVICEDISPLAYNAME | service.display_name SERVICECHECKCOMMAND | service.check_command SERVICESTATE | service.state SERVICESTATEID | service.state_id SERVICESTATETYPE | service.state_type SERVICEATTEMPT | service.check_attempt MAXSERVICEATTEMPT | service.max_check_attempts LASTSERVICESTATE | service.last_state LASTSERVICESTATEID | service.last_state_id LASTSERVICESTATETYPE | service.last_state_type LASTSERVICESTATECHANGE | service.last_state_change SERVICEDOWNTIME | service.downtime_depth SERVICEDURATIONSEC | service.duration_sec SERVICELATENCY | service.latency SERVICEEXECUTIONTIME | service.execution_time SERVICEOUTPUT | service.output SERVICEPERFDATA | service.perfdata LASTSERVICECHECK | service.last_check SERVICENOTES | service.notes SERVICENOTESURL | service.notes_url SERVICEACTIONURL | service.action_url Changes to host runtime macros Icinga 1.x | Icinga 2 -----------------------|---------------------- HOSTNAME | host.name HOSTADDRESS | host.address HOSTADDRESS6 | host.address6 HOSTDISPLAYNAME | host.display_name HOSTALIAS | (use `host.display_name` instead) HOSTCHECKCOMMAND | host.check_command HOSTSTATE | host.state HOSTSTATEID | host.state_id HOSTSTATETYPE | host.state_type HOSTATTEMPT | host.check_attempt MAXHOSTATTEMPT | host.max_check_attempts LASTHOSTSTATE | host.last_state LASTHOSTSTATEID | host.last_state_id LASTHOSTSTATETYPE | host.last_state_type LASTHOSTSTATECHANGE | host.last_state_change HOSTDOWNTIME | host.downtime_depth HOSTDURATIONSEC | host.duration_sec HOSTLATENCY | host.latency HOSTEXECUTIONTIME | host.execution_time HOSTOUTPUT | host.output HOSTPERFDATA | host.perfdata LASTHOSTCHECK | host.last_check HOSTNOTES | host.notes HOSTNOTESURL | host.notes_url HOSTACTIONURL | host.action_url TOTALSERVICES | host.num_services TOTALSERVICESOK | host.num_services_ok TOTALSERVICESWARNING | host.num_services_warning TOTALSERVICESUNKNOWN | host.num_services_unknown TOTALSERVICESCRITICAL | host.num_services_critical Changes to command runtime macros Icinga 1.x | Icinga 2 -----------------------|---------------------- COMMANDNAME | command.name Changes to notification runtime macros Icinga 1.x | Icinga 2 -----------------------|---------------------- NOTIFICATIONTYPE | notification.type NOTIFICATIONAUTHOR | notification.author NOTIFICATIONCOMMENT | notification.comment NOTIFICATIONAUTHORNAME | (use `notification.author`) NOTIFICATIONAUTHORALIAS | (use `notification.author`) Changes to global runtime macros: Icinga 1.x | Icinga 2 -----------------------|---------------------- TIMET | icinga.timet LONGDATETIME | icinga.long_date_time SHORTDATETIME | icinga.short_date_time DATE | icinga.date TIME | icinga.time PROCESSSTARTTIME | icinga.uptime Changes to global statistic macros: Icinga 1.x | Icinga 2 ----------------------------------|---------------------- TOTALHOSTSUP | icinga.num_hosts_up TOTALHOSTSDOWN | icinga.num_hosts_down TOTALHOSTSUNREACHABLE | icinga.num_hosts_unreachable TOTALHOSTSDOWNUNHANDLED | -- TOTALHOSTSUNREACHABLEUNHANDLED | -- TOTALHOSTPROBLEMS | down TOTALHOSTPROBLEMSUNHANDLED | down-(downtime+acknowledged) TOTALSERVICESOK | icinga.num_services_ok TOTALSERVICESWARNING | icinga.num_services_warning TOTALSERVICESCRITICAL | icinga.num_services_critical TOTALSERVICESUNKNOWN | icinga.num_services_unknown TOTALSERVICESWARNINGUNHANDLED | -- TOTALSERVICESCRITICALUNHANDLED | -- TOTALSERVICESUNKNOWNUNHANDLED | -- TOTALSERVICEPROBLEMS | ok+warning+critical+unknown TOTALSERVICEPROBLEMSUNHANDLED | warning+critical+unknown-(downtime+acknowledged) ### External Commands `CHANGE_CUSTOM_CONTACT_VAR` was renamed to `CHANGE_CUSTOM_USER_VAR`. The following external commands are not supported: ``` CHANGE_*MODATTR CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD CHANGE_HOST_NOTIFICATION_TIMEPERIOD CHANGE_SVC_NOTIFICATION_TIMEPERIOD DEL_DOWNTIME_BY_HOSTGROUP_NAME DEL_DOWNTIME_BY_START_TIME_COMMENT DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST DISABLE_CONTACT_HOST_NOTIFICATIONS DISABLE_CONTACT_SVC_NOTIFICATIONS DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS DISABLE_FAILURE_PREDICTION DISABLE_HOST_AND_CHILD_NOTIFICATIONS DISABLE_HOST_FRESHNESS_CHECKS DISABLE_NOTIFICATIONS_EXPIRE_TIME DISABLE_SERVICE_FRESHNESS_CHECKS ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST ENABLE_CONTACT_HOST_NOTIFICATIONS ENABLE_CONTACT_SVC_NOTIFICATIONS ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS ENABLE_FAILURE_PREDICTION ENABLE_HOST_AND_CHILD_NOTIFICATIONS ENABLE_HOST_FRESHNESS_CHECKS ENABLE_SERVICE_FRESHNESS_CHECKS READ_STATE_INFORMATION SAVE_STATE_INFORMATION SET_HOST_NOTIFICATION_NUMBER SET_SVC_NOTIFICATION_NUMBER START_ACCEPTING_PASSIVE_HOST_CHECKS START_ACCEPTING_PASSIVE_SVC_CHECKS START_OBSESSING_OVER_HOST START_OBSESSING_OVER_HOST_CHECKS START_OBSESSING_OVER_SVC START_OBSESSING_OVER_SVC_CHECKS STOP_ACCEPTING_PASSIVE_HOST_CHECKS STOP_ACCEPTING_PASSIVE_SVC_CHECKS STOP_OBSESSING_OVER_HOST STOP_OBSESSING_OVER_HOST_CHECKS STOP_OBSESSING_OVER_SVC STOP_OBSESSING_OVER_SVC_CHECKS ``` ### Asynchronous Event Execution Unlike Icinga 1.x, Icinga 2 does not block when it's waiting for a command being executed -- whether if it's a check, a notification, an event handler, a performance data writing update, etc. That way you'll recognize low to zero (check) latencies with Icinga 2. ### Checks #### Check Output Icinga 2 does not make a difference between `output` (first line) and `long_output` (remaining lines) like in Icinga 1.x. Performance Data is provided separately. There is no output length restriction as known from Icinga 1.x using an [8KB static buffer](https://docs.icinga.com/latest/en/pluginapi.html#outputlengthrestrictions). The `IdoMysqlConnection` and `LivestatusListener` types split the raw output into `output` (first line) and `long_output` (remaining lines) for compatibility reasons. #### Initial State Icinga 1.x uses the `max_service_check_spread` setting to specify a timerange where the initial state checks must have happened. Icinga 2 will use the `retry_interval` setting instead and `check_interval` divided by 5 if `retry_interval` is not defined. ### Comments Icinga 2 doesn't support non-persistent comments. ### Commands Unlike in Icinga 1.x there are three different command types in Icinga 2: `CheckCommand`, `NotificationCommand`, and `EventCommand`. For example in Icinga 1.x it is possible to accidentally use a notification command as an event handler which might cause problems depending on which runtime macros are used in the notification command. In Icinga 2 these command types are separated and will generate an error on configuration validation if used in the wrong context. While Icinga 2 still supports the complete command line in command objects, it's recommended to use [command arguments](03-monitoring-basics.md#command-arguments) with optional and conditional command line parameters instead. It's also possible to define default argument values for the command itself which can be overridden by the host or service then. #### Command Timeouts In Icinga 1.x there were two global options defining a host and service check timeout. This was essentially bad when there only was a couple of check plugins requiring some command timeouts to be extended. Icinga 2 allows you to specify the command timeout directly on the command. So, if your VMVware check plugin takes 15 minutes, [increase the timeout](09-object-types.md#objecttype-checkcommand) accordingly. ### Groups In Icinga 2 hosts, services, and users are added to groups using the `groups` attribute in the object. The old way of listing all group members in the group's `members` attribute is available through `assign where` and `ignore where` expressions by using [group assign](03-monitoring-basics.md#group-assign-intro). ``` object Host "web-dev" { import "generic-host" } object HostGroup "dev-hosts" { display_name = "Dev Hosts" assign where match("*-dev", host.name) } ``` #### Add Service to Hostgroup where Host is Member In order to associate a service with all hosts in a host group the [apply](03-monitoring-basics.md#using-apply) keyword can be used: ``` apply Service "ping4" { import "generic-service" check_command = "ping4" assign where "dev-hosts" in host.groups } ``` ### Notifications Notifications are a new object type in Icinga 2. Imagine the following notification configuration problem in Icinga 1.x: * Service A should notify contact X via SMS * Service B should notify contact X via Mail * Service C should notify contact Y via Mail and SMS * Contact X and Y should also be used for authorization The only way achieving a semi-clean solution is to * Create contact X-sms, set service_notification_command for sms, assign contact to service A * Create contact X-mail, set service_notification_command for mail, assign contact to service B * Create contact Y, set service_notification_command for sms and mail, assign contact to service C * Create contact X without notification commands, assign to service A and B Basically you are required to create duplicated contacts for either each notification method or used for authorization only. Icinga 2 attempts to solve that problem in this way * Create user X, set SMS and Mail attributes, used for authorization * Create user Y, set SMS and Mail attributes, used for authorization * Create notification A-SMS, set command for sms, add user X, assign notification A-SMS to service A * Create notification B-Mail, set command for mail, add user X, assign notification Mail to service B * Create notification C-SMS, set command for sms, add user Y, assign notification C-SMS to service C * Create notification C-Mail, set command for mail, add user Y, assign notification C-Mail to service C Previously in Icinga 1.x it looked like this: ``` service -> (contact, contactgroup) -> notification command ``` In Icinga 2 it will look like this: ``` Service -> Notification -> NotificationCommand -> User, UserGroup ``` #### Escalations Escalations in Icinga 1.x require a separated object matching on existing objects. Escalations happen between a defined start and end time which is calculated from the notification_interval: ``` start = notification start + (notification_interval * first_notification) end = notification start + (notification_interval * last_notification) ``` In theory first_notification and last_notification can be set to readable numbers. In practice users are manipulating those attributes in combination with notification_interval in order to get a start and end time. In Icinga 2 the notification object can be used as notification escalation if the start and end times are defined within the 'times' attribute using duration literals (e.g. 30m). The Icinga 2 escalation does not replace the current running notification. In Icinga 1.x it's required to copy the contacts from the service notification to the escalation to guarantee the normal notifications once an escalation happens. That's not necessary with Icinga 2 only requiring an additional notification object for the escalation itself. #### Notification Options Unlike Icinga 1.x with the 'notification_options' attribute with comma-separated state and type filters, Icinga 2 uses two configuration attributes for that. All state and type filter use long names OR'd with a pipe together ``` notification_options w,u,c,r,f,s states = [ Warning, Unknown, Critical ] types = [ Problem, Recovery, FlappingStart, FlappingEnd, DowntimeStart, DowntimeEnd, DowntimeRemoved ] ``` Icinga 2 adds more fine-grained type filters for acknowledgements, downtime, and flapping type (start, end, ...). ### Dependencies and Parents In Icinga 1.x it's possible to define host parents to determine network reachability and keep a host's state unreachable rather than down. Furthermore there are host and service dependencies preventing unnecessary checks and notifications. A host must not depend on a service, and vice versa. All dependencies are configured as separate objects and cannot be set directly on the host or service object. A service can now depend on a host, and vice versa. A service has an implicit dependency (parent) to its host. A host to host dependency acts implicitly as host parent relation. The former `host_name` and `dependent_host_name` have been renamed to `parent_host_name` and `child_host_name` (same for the service attribute). When using apply rules the child attributes may be omitted. For detailed examples on how to use the dependencies please check the [dependencies](03-monitoring-basics.md#dependencies) chapter. Dependencies can be applied to hosts or services using the [apply rules](17-language-reference.md#apply). The `IdoMysqlConnection` and `LivestatusListener` types support the Icinga 1.x schema with dependencies and parent attributes for compatibility reasons. ### Flapping The Icinga 1.x flapping detection uses the last 21 states of a service. This value is hardcoded and cannot be changed. The algorithm on determining a flapping state is as follows: ``` flapping value = (number of actual state changes / number of possible state changes) ``` The flapping value is then compared to the low and high flapping thresholds. The algorithm used in Icinga 2 does not store the past states but calculates the flapping threshold from a single value based on counters and half-life values. Icinga 2 compares the value with a single flapping threshold configuration attribute. ### Check Result Freshness Freshness of check results must be enabled explicitly in Icinga 1.x. The attribute `freshness_threshold` defines the threshold in seconds. Once the threshold is triggered, an active freshness check is executed defined by the `check_command` attribute. Both check methods (active and passive) use the same freshness check method. In Icinga 2 active check freshness is determined by the `check_interval` attribute and no incoming check results in that period of time (last check + check interval). Passive check freshness is calculated from the `check_interval` attribute if set. There is no extra `freshness_threshold` attribute in Icinga 2. If the freshness checks are invalid, a new service check is forced. ### Real Reload In Nagios / Icinga 1.x a daemon reload does the following: * receive reload signal SIGHUP * stop all events (checks, notifications, etc.) * read the configuration from disk and validate all config objects in a single threaded fashion * validation NOT ok: stop the daemon (cannot restore old config state) * validation ok: start with new objects, dump status.dat / ido Unlike Icinga 1.x the Icinga 2 daemon reload does not block any event execution during config validation: * receive reload signal SIGHUP * fork a child process, start configuration validation in parallel work queues * parent process continues with old configuration objects and the event scheduling (doing checks, replicating cluster events, triggering alert notifications, etc.) * validation NOT ok: child process terminates, parent process continues with old configuration state (this is **essential** for the [cluster config synchronisation](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync)) * validation ok: child process signals parent process to terminate and save its current state (all events until now) into the icinga2 state file * parent process shuts down writing icinga2.state file * child process waits for parent process gone, reads the icinga2 state file and synchronizes all historical and status data * child becomes the new session leader The DB IDO configuration dump and status/historical event updates use a queue not blocking event execution. Same goes for any other enabled feature. The configuration validation itself runs in parallel allowing fast verification checks. That way your monitoring does not stop during a configuration reload. ### State Retention Icinga 1.x uses the `retention.dat` file to save its state in order to be able to reload it after a restart. In Icinga 2 this file is called `icinga2.state`. The format is **not** compatible with Icinga 1.x. ### Logging Icinga 1.x supports syslog facilities and writes its own `icinga.log` log file and archives. These logs are used in Icinga 1.x to generate historical reports. Icinga 2 compat library provides the CompatLogger object which writes the icinga.log and archive in Icinga 1.x format in order to stay compatible with addons. The native Icinga 2 logging facilities are split into three configuration objects: SyslogLogger, FileLogger, StreamLogger. Each of them has their own severity and target configuration. The Icinga 2 daemon log does not log any alerts but is considered an application log only. ### Broker Modules and Features Icinga 1.x broker modules are incompatible with Icinga 2. In order to provide compatibility with Icinga 1.x the functionality of several popular broker modules was implemented for Icinga 2: * IDOUtils * Livestatus * Cluster (allows for high availability and load balancing) ### Distributed Monitoring Icinga 1.x uses the native "obsess over host/service" method which requires the NSCA addon passing the slave's check results passively onto the master's external command pipe. While this method may be used for check load distribution, it does not provide any configuration distribution out-of-the-box. Furthermore comments, downtimes, and other stateful runtime data is not synced between the master and slave nodes. There are addons available solving the check and configuration distribution problems Icinga 1.x distributed monitoring currently suffers from. Icinga 2 implements a new built-in [distributed monitoring architecture](06-distributed-monitoring.md#distributed-monitoring-scenarios), including config and check distribution, IPv4/IPv6 support, TLS certificates and zone support for DMZ. High Availability and load balancing are also part of the Icinga 2 Cluster feature, next to local replay logs on connection loss ensuring that the event history is kept in sync. icinga2-2.14.6/doc/24-appendix.md000066400000000000000000001172441501332562400162540ustar00rootroot00000000000000# Appendix ## External Commands List Additional details can be found in the [Icinga 1.x Documentation](https://docs.icinga.com/latest/en/extcommands2.html) Command name | Parameters | Description ------------------------------------------|-----------------------------------|-------------------------- PROCESS_HOST_CHECK_RESULT | ;<host_name>;<status_code>;<plugin_output> (3) | - PROCESS_SERVICE_CHECK_RESULT | ;<host_name>;<service_name>;<return_code>;<plugin_output> (4) | - SCHEDULE_HOST_CHECK | ;<host_name>;<check_time> (2) | - SCHEDULE_FORCED_HOST_CHECK | ;<host_name>;<check_time> (2) | - SCHEDULE_SVC_CHECK | ;<host_name>;<service_name>;<check_time> (3) | - SCHEDULE_FORCED_SVC_CHECK | ;<host_name>;<service_name>;<check_time> (3) | - ENABLE_HOST_CHECK | ;<host_name> (1) | - DISABLE_HOST_CHECK | ;<host_name> (1) | - ENABLE_SVC_CHECK | ;<host_name>;<service_name> (2) | - DISABLE_SVC_CHECK | ;<host_name>;<service_name> (2) | - SHUTDOWN_PROCESS | - | - RESTART_PROCESS | - | - SCHEDULE_FORCED_HOST_SVC_CHECKS | ;<host_name>;<check_time> (2) | - SCHEDULE_HOST_SVC_CHECKS | ;<host_name>;<check_time> (2) | - ENABLE_HOST_SVC_CHECKS | ;<host_name> (1) | - DISABLE_HOST_SVC_CHECKS | ;<host_name> (1) | - ACKNOWLEDGE_SVC_PROBLEM | ;<host_name>;<service_name>;<sticky>;<notify>;<persistent>;<author>;<comment> (7) | Note: Icinga 2 treats all comments as persistent. ACKNOWLEDGE_SVC_PROBLEM_EXPIRE | ;<host_name>;<service_name>;<sticky>;<notify>;<persistent>;<timestamp>;<author>;<comment> (8) | Note: Icinga 2 treats all comments as persistent. REMOVE_SVC_ACKNOWLEDGEMENT | ;<host_name>;<service_name> (2) | - ACKNOWLEDGE_HOST_PROBLEM | ;<host_name>;<sticky>;<notify>;<persistent>;<author>;<comment> (6) | Note: Icinga 2 treats all comments as persistent. ACKNOWLEDGE_HOST_PROBLEM_EXPIRE | ;<host_name>;<sticky>;<notify>;<persistent>;<timestamp>;<author>;<comment> (7) | Note: Icinga 2 treats all comments as persistent. REMOVE_HOST_ACKNOWLEDGEMENT | ;<host_name> (1) | - DISABLE_HOST_FLAP_DETECTION | ;<host_name> (1) | - ENABLE_HOST_FLAP_DETECTION | ;<host_name> (1) | - DISABLE_SVC_FLAP_DETECTION | ;<host_name>;<service_name> (2) | - ENABLE_SVC_FLAP_DETECTION | ;<host_name>;<service_name> (2) | - ENABLE_HOSTGROUP_SVC_CHECKS | ;<hostgroup_name> (1) | - DISABLE_HOSTGROUP_SVC_CHECKS | ;<hostgroup_name> (1) | - ENABLE_SERVICEGROUP_SVC_CHECKS | ;<servicegroup_name> (1) | - DISABLE_SERVICEGROUP_SVC_CHECKS | ;<servicegroup_name> (1) | - ENABLE_PASSIVE_HOST_CHECKS | ;<host_name> (1) | - DISABLE_PASSIVE_HOST_CHECKS | ;<host_name> (1) | - ENABLE_PASSIVE_SVC_CHECKS | ;<host_name>;<service_name> (2) | - DISABLE_PASSIVE_SVC_CHECKS | ;<host_name>;<service_name> (2) | - ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS | ;<servicegroup_name> (1) | - DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS | ;<servicegroup_name> (1) | - ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS | ;<hostgroup_name> (1) | - DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS | ;<hostgroup_name> (1) | - PROCESS_FILE | ;<file_name>;<delete> (2) | - SCHEDULE_SVC_DOWNTIME | ;<host_name>;<service_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (9) | - DEL_SVC_DOWNTIME | ;<downtime_id> (1) | - SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME | ;<host_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (8) | - SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME | ;<host_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (8) | - SCHEDULE_HOST_DOWNTIME | ;<host_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (8) | - DEL_HOST_DOWNTIME | ;<downtime_id> (1) | - DEL_DOWNTIME_BY_HOST_NAME | ;<host_name>[;<service_name;>[;<start_time;>[;<comment_text;>]]] (1) | - SCHEDULE_HOST_SVC_DOWNTIME | ;<host_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (8) | - SCHEDULE_HOSTGROUP_HOST_DOWNTIME | ;<hostgroup_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (8) | - SCHEDULE_HOSTGROUP_SVC_DOWNTIME | ;<hostgroup_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (8) | - SCHEDULE_SERVICEGROUP_HOST_DOWNTIME | ;<servicegroup_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (8) | - SCHEDULE_SERVICEGROUP_SVC_DOWNTIME | ;<servicegroup_name>;<start_time>;<end_time>;<fixed>;<trigger_id>;<duration>;<author>;<comment> (8) | - ADD_HOST_COMMENT | ;<host_name>;<persistent>;<author>;<comment> (4) | Note: Icinga 2 treats all comments as persistent. DEL_HOST_COMMENT | ;<comment_id> (1) | - ADD_SVC_COMMENT | ;<host_name>;<service_name>;<persistent>;<author>;<comment> (5) | Note: Icinga 2 treats all comments as persistent. DEL_SVC_COMMENT | ;<comment_id> (1) | - DEL_ALL_HOST_COMMENTS | ;<host_name> (1) | - DEL_ALL_SVC_COMMENTS | ;<host_name>;<service_name> (2) | - SEND_CUSTOM_HOST_NOTIFICATION | ;<host_name>;<options>;<author>;<comment> (4) | - SEND_CUSTOM_SVC_NOTIFICATION | ;<host_name>;<service_name>;<options>;<author>;<comment> (5) | - DELAY_HOST_NOTIFICATION | ;<host_name>;<notification_time> (2) | - DELAY_SVC_NOTIFICATION | ;<host_name>;<service_name>;<notification_time> (3) | - ENABLE_HOST_NOTIFICATIONS | ;<host_name> (1) | - DISABLE_HOST_NOTIFICATIONS | ;<host_name> (1) | - ENABLE_SVC_NOTIFICATIONS | ;<host_name>;<service_name> (2) | - DISABLE_SVC_NOTIFICATIONS | ;<host_name>;<service_name> (2) | - ENABLE_HOST_SVC_NOTIFICATIONS | ;<host_name> (1) | - DISABLE_HOST_SVC_NOTIFICATIONS | ;<host_name> (1) | - DISABLE_HOSTGROUP_HOST_CHECKS | ;<hostgroup_name> (1) | - DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS | ;<hostgroup_name> (1) | - DISABLE_SERVICEGROUP_HOST_CHECKS | ;<servicegroup_name> (1) | - DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS | ;<servicegroup_name> (1) | - ENABLE_HOSTGROUP_HOST_CHECKS | ;<hostgroup_name> (1) | - ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS | ;<hostgroup_name> (1) | - ENABLE_SERVICEGROUP_HOST_CHECKS | ;<servicegroup_name> (1) | - ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS | ;<servicegroup_name> (1) | - ENABLE_NOTIFICATIONS | - | - DISABLE_NOTIFICATIONS | - | - ENABLE_FLAP_DETECTION | - | - DISABLE_FLAP_DETECTION | - | - ENABLE_EVENT_HANDLERS | - | - DISABLE_EVENT_HANDLERS | - | - ENABLE_PERFORMANCE_DATA | - | - DISABLE_PERFORMANCE_DATA | - | - START_EXECUTING_HOST_CHECKS | - | - STOP_EXECUTING_HOST_CHECKS | - | - START_EXECUTING_SVC_CHECKS | - | - STOP_EXECUTING_SVC_CHECKS | - | - CHANGE_NORMAL_SVC_CHECK_INTERVAL | ;<host_name>;<service_name>;<check_interval> (3) | - CHANGE_NORMAL_HOST_CHECK_INTERVAL | ;<host_name>;<check_interval> (2) | - CHANGE_RETRY_SVC_CHECK_INTERVAL | ;<host_name>;<service_name>;<check_interval> (3) | - CHANGE_RETRY_HOST_CHECK_INTERVAL | ;<host_name>;<check_interval> (2) | - ENABLE_HOST_EVENT_HANDLER | ;<host_name> (1) | - DISABLE_HOST_EVENT_HANDLER | ;<host_name> (1) | - ENABLE_SVC_EVENT_HANDLER | ;<host_name>;<service_name> (2) | - DISABLE_SVC_EVENT_HANDLER | ;<host_name>;<service_name> (2) | - CHANGE_HOST_EVENT_HANDLER | ;<host_name>;<event_command_name> (2) | - CHANGE_SVC_EVENT_HANDLER | ;<host_name>;<service_name>;<event_command_name> (3) | - CHANGE_HOST_CHECK_COMMAND | ;<host_name>;<check_command_name> (2) | - CHANGE_SVC_CHECK_COMMAND | ;<host_name>;<service_name>;<check_command_name> (3) | - CHANGE_MAX_HOST_CHECK_ATTEMPTS | ;<host_name>;<check_attempts> (2) | - CHANGE_MAX_SVC_CHECK_ATTEMPTS | ;<host_name>;<service_name>;<check_attempts> (3) | - CHANGE_HOST_CHECK_TIMEPERIOD | ;<host_name>;<timeperiod_name> (2) | - CHANGE_SVC_CHECK_TIMEPERIOD | ;<host_name>;<service_name>;<timeperiod_name> | - CHANGE_CUSTOM_HOST_VAR | ;<host_name>;<var_name>;<var_value> (3) | - CHANGE_CUSTOM_SVC_VAR | ;<host_name>;<service_name>;<var_name>;<var_value> (4) | - CHANGE_CUSTOM_USER_VAR | ;<user_name>;<var_name>;<var_value> (3) | - CHANGE_CUSTOM_CHECKCOMMAND_VAR | ;<check_command_name>;<var_name>;<var_value> (3) | - CHANGE_CUSTOM_EVENTCOMMAND_VAR | ;<event_command_name>;<var_name>;<var_value> (3) | - CHANGE_CUSTOM_NOTIFICATIONCOMMAND_VAR | ;<notification_command_name>;<var_name>;<var_value> (3) | - ENABLE_HOSTGROUP_HOST_NOTIFICATIONS | ;<hostgroup_name> (1) | - ENABLE_HOSTGROUP_SVC_NOTIFICATIONS | ;<hostgroup_name> (1) | - DISABLE_HOSTGROUP_HOST_NOTIFICATIONS | ;<hostgroup_name> (1) | - DISABLE_HOSTGROUP_SVC_NOTIFICATIONS | ;<hostgroup_name> (1) | - ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS | ;<servicegroup_name> (1) | - DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS | ;<servicegroup_name> (1) | - ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS | ;<servicegroup_name> (1) | - DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS | ;<servicegroup_name> (1) | - ## Schemas By convention `CheckCommand`, `EventCommand`, and `NotificationCommand` objects are exported using a prefix. This is mandatory for unique objects in the command tables. Object | Prefix ------------------------|------------------------ CheckCommand | check\_ EventCommand | event\_ NotificationCommand | notification\_ ### DB IDO Schema There is a detailed documentation for the Icinga IDOUtils 1.x database schema available on [https://docs.icinga.com/latest/en/db_model.html] #### DB IDO Schema Extensions Icinga 2 specific extensions are shown below: New table: `endpointstatus` Table | Column | Type | Default | Description --------------------|--------------------|----------|---------|------------- endpoints | endpoint_object_id | bigint | NULL | FK: objects table endpoints | identity | TEXT | NULL | endpoint name endpoints | node | TEXT | NULL | local node name endpoints | zone_object_id | bigint | NULL | zone object where this endpoint is a member of New table: `endpointstatus` Table | Column | Type | Default | Description --------------------|--------------------|----------|---------|------------- endpointstatus | endpoint_object_id | bigint | NULL | FK: objects table endpointstatus | identity | TEXT | NULL | endpoint name endpointstatus | node | TEXT | NULL | local node name endpointstatus | is_connected | smallint | 0 | update on endpoint connect/disconnect endpointstatus | zone_object_id | bigint | NULL | zone object where this endpoint is a member of New tables: `zones` and `zonestatus`: Table | Column | Type | Default | Description --------------------|--------------------|----------|---------|------------- zones | zone_object_id | bigint | NULL | FK: objects table zones | parent_zone_object_id | bigint | NULL | FK: zones table zones | is_global | smallint | 0 | zone is global New columns: Table | Column | Type | Default | Description --------------------|-------------------------|----------|---------|------------- all status/history | endpoint_object_id | bigint | NULL | FK: objects table servicestatus | check_source | TEXT | NULL | node name where check was executed hoststatus | check_source | TEXT | NULL | node name where check was executed statehistory | check_source | TEXT | NULL | node name where check was executed servicestatus | is_reachable | integer | NULL | object reachability hoststatus | is_reachable | integer | NULL | object reachability logentries | object_id | bigint | NULL | FK: objects table (service associated with column) {host,service}group | notes | TEXT | NULL | - {host,service}group | notes_url | TEXT | NULL | - {host,service}group | action_url | TEXT | NULL | - customvariable* | is_json | integer | 0 | Defines whether `varvalue` is a json encoded string from custom variables, or not servicestatus | original_attributes | TEXT | NULL | JSON encoded dictionary of original attributes if modified at runtime. hoststatus | original_attributes | TEXT | NULL | JSON encoded dictionary of original attributes if modified at runtime. Additional command custom variables populated from 'vars' dictionary. Additional global custom variables populated from 'Vars' constant (object_id is NULL). ### Livestatus Schema #### Livestatus Schema Extensions Icinga 2 specific extensions are shown below: New table: `endpoints`: Table | Column ----------|-------------- endpoints | name endpoints | identity endpoints | node endpoints | is_connected endpoints | zone New table: `zones`: Table | Column ----------|-------------- zone | name zone | endpoints zone | parent zone | global New columns: Table | Column ----------|-------------- hosts | is_reachable services | is_reachable hosts | cv_is_json services | cv_is_json contacts | cv_is_json hosts | check_source services | check_source downtimes | triggers downtimes | trigger_time commands | custom_variable_names commands | custom_variable_values commands | custom_variables commands | modified_attributes commands | modified_attributes_list status | custom_variable_names status | custom_variable_values status | custom_variables hosts | original_attributes services | original_attributes Command custom variables reflect the local 'vars' dictionary. Status custom variables reflect the global 'Vars' constant. #### Livestatus Hosts Table Attributes Key | Type | Note ----------------------|-----------|------------------------- name | string | . display_name | string | . alias | string | same as display_name. address | string | . address6 | string | NEW in Icinga. check_command | string | . check_command_expanded | string | . event_handler | string | . notification_period | string | host with notifications: period. check_period | string | . notes | string | . notes_expanded | string | . notes_url | string | . notes_url_expanded | string | . action_url | string | . action_url_expanded | string | . plugin_output | string | . perf_data | string | . icon_image | string | . icon_image_expanded | string | . icon_image_alt | stirng | . statusmap_image | string | . long_plugin_output | string | . max_check_attempts | int | . flap_detection_enabled | int | . check_freshness | int | . process_performance_data | int | . accept_passive_checks | int | . event_handler_enabled | int | . acknowledgement_type | int | Only 0 or 1. check_type | int | . last_state | int | . last_hard_state | int | . current_attempt | int | . last_notification | int | host with notifications: last notification. next_notification | int | host with notifications: next notification. next_check | int | . last_hard_state_change | int | . has_been_checked | int | . current_notification_number | int | host with notifications: number. total_services | int | . checks_enabled | int | . notifications_enabled | int | . acknowledged | int | . state | int | . state_type | int | . no_more_notifications | int | notification_interval == 0 && volatile == false. last_check | int | . last_state_change | int | . last_time_up | int | . last_time_down | int | . last_time_unreachable | int | . is_flapping | int | . scheduled_downtime_depth | int | . active_checks_enabled | int | . modified_attributes | array | . modified_attributes_list | array | . check_interval | double | . retry_interval | double | . notification_interval | double | host with notifications: smallest interval. low_flap_threshold | double | flapping_threshold high_flap_threshold | double | flapping_threshold latency | double | . execution_time | double | . percent_state_change | double | flapping. in_notification_period | int | host with notifications: matching period. in_check_period | int | . contacts | array | host with notifications, users and user groups. downtimes | array | id. downtimes_with_info | array | id+author+comment. comments | array | id. comments_with_info | array | id+author+comment. comments_with_extra_info | array | id+author+comment+entry_type+entry_time. custom_variable_names | array | . custom_variable_values | array | . custom_variables | array | Array of custom variable array pair. parents | array | Direct host parents. childs | array | Direct host children (Note: `childs` is inherited from the origin MK_Livestatus protocol). num_services | int | . worst_service_state | int | All services and their worst state. num_services_ok | int | All services with Ok state. num_services_warn | int | All services with Warning state. num_services_crit | int | All services with Critical state. num_services_unknown | int | All services with Unknown state. worst_service_hard_state | int | All services and their worst hard state. num_services_hard_ok | int | All services in a hard state with Ok state. num_services_hard_warn | int | All services in a hard state with Warning state. num_services_hard_crit | int | All services in a hard state with Critical state. num_services_hard_unknown | int | All services in a hard state with Unknown state. hard_state | int | Returns OK if state is OK. Returns current state if now a hard state type. Returns last hard state otherwise. staleness | int | Indicates time since last check normalized onto the check_interval. groups | array | All hostgroups this host is a member of. contact_groups | array | All usergroups associated with this host through notifications. services | array | All services associated with this host. services_with_state | array | All services associated with this host with state and hasbeenchecked. services_with_info | array | All services associated with this host with state, hasbeenchecked and output. Not supported: `initial_state`, `pending_flex_downtime`, `check_flapping_recovery_notification`, `is_executing`, `check_options`, `obsess_over_host`, `first_notification_delay`, `x_3d`, `y_3d`, `z_3d`, `x_2d`, `y_2d`, `filename`, `pnpgraph_present`. #### Livestatus Hostgroups Table Attributes Key | Type | Note ----------------------|-----------|------------------------- name | string | . alias | string | `display_name` attribute. notes | string | . notes_url | string | . action_url | string | . members | array | . members_with_state | array | Host name and state. worst_host_state | int | Of all group members. num_hosts | int | In this group. num_hosts_pending | int | . num_hosts_up | int | . num_hosts_down | int | . num_hosts_unreach | int | . num_services | int | Number of services associated with hosts in this hostgroup. worst_services_state | int | . num_services_pending | int | . num_services_ok | int | . num_services_warn | int | . num_services_crit | int | . num_services_unknown | int | . worst_service_hard_state | int | . num_services_hard_ok | int | . num_services_hard_warn | int | . num_services_hard_crit | int | . num_services_hard_unknown | int | . #### Livestatus Services Table Attributes Key | Type | Note ----------------------|-----------|------------------------- description | string | . display_name | string | . alias | string | same as display_name. check_command | string | . check_command_expanded | string | . event_handler | string | . notification_period | string | host with notifications: period. check_period | string | . notes | string | . notes_expanded | string | . notes_url | string | . notes_url_expanded | string | . action_url | string | . action_url_expanded | string | . plugin_output | string | . perf_data | string | . icon_image | string | . icon_image_expanded | string | . icon_image_alt | stirng | . statusmap_image | string | . long_plugin_output | string | . max_check_attempts | int | . flap_detection_enabled | int | . check_freshness | int | . process_performance_data | int | . accept_passive_checks | int | . event_handler_enabled | int | . acknowledgement_type | int | Only 0 or 1. check_type | int | . last_state | int | . last_hard_state | int | . current_attempt | int | . last_notification | int | service with notifications: last notification. next_notification | int | service with notifications: next notification. next_check | int | . last_hard_state_change | int | . has_been_checked | int | . current_notification_number | int | service with notifications: number. checks_enabled | int | . notifications_enabled | int | . acknowledged | int | . state | int | . state_type | int | . no_more_notifications | int | notification_interval == 0 && volatile == false. last_check | int | . last_state_change | int | . last_time_ok | int | . last_time_warning | int | . last_time_critical | int | . last_time_unknown | int | . is_flapping | int | . scheduled_downtime_depth | int | . active_checks_enabled | int | . modified_attributes | array | . modified_attributes_list | array | . check_interval | double | . retry_interval | double | . notification_interval | double | service with notifications: smallest interval. low_flap_threshold | double | flapping_threshold high_flap_threshold | double | flapping_threshold latency | double | . execution_time | double | . percent_state_change | double | flapping. in_notification_period | int | service with notifications: matching period. in_check_period | int | . contacts | array | service with notifications, users and user groups. downtimes | array | id. downtimes_with_info | array | id+author+comment. comments | array | id. comments_with_info | array | id+author+comment. comments_with_extra_info | array | id+author+comment+entry_type+entry_time. custom_variable_names | array | . custom_variable_values | array | . custom_variables | array | Array of custom variable array pair. hard_state | int | Returns OK if state is OK. Returns current state if now a hard state type. Returns last hard state otherwise. staleness | int | Indicates time since last check normalized onto the check_interval. groups | array | All hostgroups this host is a member of. contact_groups | array | All usergroups associated with this host through notifications. host_ | join | Prefix for attributes from implicit join with hosts table. Not supported: `initial_state`, `is_executing`, `check_options`, `obsess_over_service`, `first_notification_delay`, `pnpgraph_present`. #### Livestatus Servicegroups Table Attributes Key | Type | Note ----------------------|-----------|------------------------- name | string | . alias | string | `display_name` attribute. notes | string | . notes_url | string | . action_url | string | . members | array | CSV format uses `host|service` syntax. members_with_state | array | Host, service, hoststate, servicestate. worst_service_state | int | . num_services | int | . num_services_pending | int | . num_services_ok | int | . num_services_warn | int | . num_services_crit | int | . num_services_unknown | int | . num_services_hard_ok | int | . num_services_hard_warn | int | . num_services_hard_crit | int | . num_services_hard_unknown | int | . #### Livestatus Contacts Table Attributes Key | Type | Note ----------------------|-----------|------------------------- name | string | . alias | string | `display_name` attribute. email | string | . pager | string | . host_notification_period | string | . service_notification_period | string | . host_notifications_enabled | int | . service_notifications_enabled | int | . in_host_notification_period | int | . in_service_notification_period | int | . custom_variable_names | array | . custom_variable_values | array | . custom_variables | array | Array of customvariable array pairs. modified_attributes | array | . modified_attributes_list | array | . Not supported: `can_submit_commands`. #### Livestatus Contactgroups Table Attributes Key | Type | Note ----------------------|-----------|------------------------- name | string | . alias | string | `display_name` attribute. members | array | . #### Livestatus Commands Table Attributes Key | Type | Note ----------------------|-----------|------------------------- name | string | 3 types of commands in Icinga 2. line | string | . #### Livestatus Status Table Attributes Key | Type | Note ----------------------|-----------|------------------------- connections | int | Since application start. connections_rate | double | . service_checks | int | Since application start. service_checks_rate | double | . host_checks | int | Since application start. host_checks_rate | double | . external_commands | int | Since application start. external_commands_rate | double | . nagios_pid | string | Application PID. enable_notifications | int | . execute_service_checks | int | . accept_passive_service_checks | int | . execute_host_checks | int | . accept_passive_host_checks | int | . enable_event_handlers | int | . check_service_freshness | int | . check_host_freshness | int | . enable_flap_detection | int | . process_performance_data | int | . check_external_commands | int | Always enabled. program_start | int | In seconds. last_command_check | int | Always. interval_length | int | Compatibility mode: 60. num_hosts | int | . num_services | int | . program_version | string | 2.0. livestatus_active_connections | string | . Not supported: `neb_callbacks`, `neb_callbacks_rate`, `requests`, `requests_rate`, `forks`, `forks_rate`, `log_messages`, `log_messages_rate`, `livechecks`, `livechecks_rate`, `livecheck_overflows`, `livecheck_overflows_rate`, `obsess_over_services`, `obsess_over_hosts`, `last_log_rotation`, `external_command_buffer_slots`, `external_command_buffer_usage`, `external_command_buffer_max`, `cached_log_messages`, `livestatus_queued_connections`, `livestatus_threads`. #### Livestatus Comments Table Attributes Key | Type | Note ----------------------|-----------|------------------------- author | string | . comment | string | . id | int | legacy_id. entry_time | string | Seconds. type | int | 1=host, 2=service. is_service | int | . persistent | int | Always. source | string | Always external (1). entry_type | int | . expires | int | . expire_time | string | Seconds. service_ | join | Prefix for attributes from implicit join with services table. host_ | join | Prefix for attributes from implicit join with hosts table. #### Livestatus Downtimes Table Attributes Key | Type | Note ----------------------|-----------|------------------------- author | string | . comment | string | . id | int | legacy_id. entry_time | string | Seconds. type | int | 1=active, 0=pending. is_service | int | . start_time | string | Seconds. end_time | string | Seconds. fixed | int | 0=flexible, 1=fixed. duration | int | . triggered_by | int | legacy_id. triggers | int | NEW in Icinga 2. trigger_time | string | NEW in Icinga 2. service_ | join | Prefix for attributes from implicit join with services table. host_ | join | Prefix for attributes from implicit join with hosts table. #### Livestatus Timeperiods Table Attributes Key | Type | Note ----------------------|-----------|------------------------- name | string | . alias | string | `display_name` attribute. in | int | Current time is in timeperiod or not. #### Livestatus Log Table Attributes Key | Type | Note ----------------------|-----------|------------------------- time | int | Time of log event (unix timestamp). lineno | int | Line number in `CompatLogger` log file. class | int | Log message class: 0=info, 1=state, 2=program, 3=notification, 4=passive, 5=command. message | string | Complete message line. type | string | Text before the colon `:`. options | string | Text after the colon `:`. comment | string | Comment if available. plugin_output | string | Check output if available. state | int | Host or service state. state_type | int | State type if available. attempt | int | Current check attempt. service_description | string | . host_name | string | . contact_name | string | . command_name | string | . current_service_ | join | Prefix for attributes from implicit join with services table. current_host_ | join | Prefix for attributes from implicit join with hosts table. current_contact_ | join | Prefix for attributes from implicit join with contacts table. current_command_ | join | Prefix for attributes from implicit join with commands table. #### Livestatus Statehist Table Attributes Key | Type | Note ----------------------|-----------|------------------------- time | int | Time of log event (unix timestamp). lineno | int | Line number in `CompatLogger` log file. from | int | Start timestamp (unix timestamp). until | int | End timestamp (unix timestamp). duration | int | until-from. duration_part | double | duration / query_part. state | int | State: 0=ok, 1=warn, 2=crit, 3=unknown, -1=notmonitored. host_down | int | Host associated with the service is down or not. in_downtime | int | Host/service is in downtime. in_host_downtime | int | Host associated with the service is in a downtime or not. is_flapping | int | Host/service is flapping. in_notification_period | int | Host/service notification periods match or not. notification_period | string | Host/service notification period. host_name | string | . service_description | string | . log_output | string | Log file output for this state. duration_ok | int | until-from for OK state. duration_part_ok | double | . duration_warning | int | until-from for Warning state. duration_part_warning | double | . duration_critical | int | until-from for Critical state. duration_part_critical | double | . duration_unknown | int | until-from for Unknown state. duration_part_unknown | double | . duration_unmonitored | int | until-from for Not-Monitored state. duration_part_unmonitored | double | . current_service_ | join | Prefix for attributes from implicit join with services table. current_host_ | join | Prefix for attributes from implicit join with hosts table. Not supported: `debug_info`. #### Livestatus Hostsbygroup Table Attributes All [hosts](24-appendix.md#schema-livestatus-hosts-table-attributes) table attributes grouped with the [hostgroups](24-appendix.md#schema-livestatus-hostgroups-table-attributes) table prefixed with `hostgroup_`. #### Livestatus Servicesbygroup Table Attributes All [services](24-appendix.md#schema-livestatus-services-table-attributes) table attributes grouped with the [servicegroups](24-appendix.md#schema-livestatus-servicegroups-table-attributes) table prefixed with `servicegroup_`. #### Livestatus Servicesbyhostgroup Table Attributes All [services](24-appendix.md#schema-livestatus-services-table-attributes) table attributes grouped with the [hostgroups](24-appendix.md#schema-livestatus-hostgroups-table-attributes) table prefixed with `hostgroup_`. icinga2-2.14.6/doc/CMakeLists.txt000066400000000000000000000005161501332562400164300ustar00rootroot00000000000000# Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ file(GLOB DOCSRCS "*.md") if(UNIX OR CYGWIN) install( FILES icinga2.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8 ) endif() install( FILES ${DOCSRCS} DESTINATION ${CMAKE_INSTALL_DOCDIR}/markdown ) install( DIRECTORY images DESTINATION ${CMAKE_INSTALL_DOCDIR}/markdown ) icinga2-2.14.6/doc/icinga2.8000066400000000000000000000053551501332562400153030ustar00rootroot00000000000000.TH ICINGA2 "8" "October 2015" "icinga2 - The Icinga 2 network monitoring daemon" .SH NAME icinga2 \- The Icinga 2 network monitoring daemon .SH SYNOPSIS .B icinga2 .I command [ .I command options ][ .I global options ] .I command := [ .B api | ca | console | daemon | feature | node | object | pki | variable ] .B --help .SH DESCRIPTION Icinga 2 is an open source monitoring system which checks the availability of your network resources, notifies users of outages, and generates performance data for reporting. Scalable and extensible, Icinga 2 can monitor large, complex environments across multiple locations. .SH OPTIONS Details for specific command options can be viewed by invoking the command name with .B --help parameter. .SS Global options .TP .B -h,--help Show this help message. .TP .B -V,--version Show version information. .TP .B --color Use VT100 color codes even when stdout is not a terminal. .TP .BI "-D, --define" " arg" Define a constant. .TP .BI "-l, --library" " arg" Load a library. .TP .BI "-I, --include" " arg" Add include search directory. .TP .BI "-x, --log-level" " [ debug | notice | information | warning | critical ]" Specify the log level for the console log, default is .B information. .TP .BI "-X, --script-debugger" Enables the script debugger. When an exception occurs or the 'debugger' keyword is encountered in a user script Icinga 2 launches the script debugger that allows the user to debug the script. .SS daemon options The CLI command daemon provides the functionality to start/stop Icinga 2. Furthermore it provides the configuration validation. .TP .BI "-c, --config" " arg" Using this option you can specify one or more configuration files. Config files are processed in the order they are specified on the command-line. When no configuration file is specified and the .B --no-config is not used, Icinga 2 automatically falls back to using the configuration file .B ConfigDir + "/icinga2.conf" (where ConfigDir is usually .BI "/etc/icinga2" ")." .TP .B "-z, --noconfig" Start without a configuration file. .TP .B "-C, --validate" This option can be used to check if your configuration files contain errors. If any errors are found the exit status is 1, otherwise 0 is returned. .TP .BI "-e, --errorlog" " arg" Log fatal errors to the specified log file (only works in combination with .BR "--daemonize" ")." .TP .B "-d, --daemonize" Detach from the controlling terminal. .SH "REPORTING BUGS" Report bugs at .br Icinga home page: .SH COPYRIGHT Copyright \(co 2012 Icinga GmbH License GPLv2+: GNU GPL version 2 or later .br This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. icinga2-2.14.6/doc/images/000077500000000000000000000000001501332562400151335ustar00rootroot00000000000000icinga2-2.14.6/doc/images/addons/000077500000000000000000000000001501332562400164035ustar00rootroot00000000000000icinga2-2.14.6/doc/images/addons/dashing_icinga2.png000066400000000000000000032761551501332562400221450ustar00rootroot00000000000000PNG  IHDRP= iCCPICC ProfileHTSY{@:7A:JJ ĆȠ#:(X "E2(`>` 3gwϹ{=%&rD!~9 YlЃ fC׿_%@L8bv §@e"q4W"(B D'p霰/GY,QOHN@|*[ 8|y,[jq_|'diY s>ͭ%I eH=xaΏX</i\$ /1E}4^tڸ(i 4.0^1L@(R! +A!P4 %@H6AP1TUA/"t B`2k†{pNS,8Q߀><(J2GQ^`T *%BGJQըzT uՇE}FcT4 mvFlt*z=]>nDc Fcq00QL&S\tc1X2Fckؽl+ ;p83 .¥p{pGqpwqOx^o|)<.~?A#a5pBM$LFDb1XF'^&>!#H$GM*#']%>Ȧd/2|J~H~GP )JerI*c!Ðli+Z k !B6KTmQ9Kn\^qy|||k 8CBK TUEeS7QR/SF DccJ JJJJJQʆ d"=_iǝu^>pUUTUT}TTw6>UC-QPۧvYmT]QY~BaFMqM-M?MKZZZZ%ZFڮ| /iJ4Z2NבTtL6>#Jկd@0 vt|4424ld8lb023zbL1v3N56o5$5c ڙL+Loff|f]1 W5'{י[([YX4Y^ f [Y&[|l``cbԚm]a}߆bk捭-v;"vmvE#tE:^Hqtx񳓽S ?͝8/4Z]xpဋ ˥ʥϕk˭;ǽ}#kOKOiϏ^N^ZQ~ޝ> >>>|u}||cw24lF-c,!`]@{ 904\o^_ՠPpK/='O?ep4t~#Ըqu&L[s_-~=tVl9sEsO^Ⱥ0*lpqmeKQ/ix+:<:.\uzӵ3כnhiw-[;;o;nxkanw/w>]==z=<~ͣG`?{ZLYo&5<ſ}AyQ:=T;l=|vw˥/_ _M!GkקtXћɷTzom9CʇT?L%DWײo&Z~229)dXӭ p|<o@zҙ>yZLo?M?L/=-{"SD6V#,23stSx/RҚNNCC z'''&' >L>%[HS+kӲhiTXtXML:com.adobe.xmp 2032 1104 ɿ@IDATx TŹYfF]dEdT@6"6w\L_45˽*Q&lW($dQdAvuY_鮙3|yzꫯuTHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH@LY d             @y? hYd [HHHHHHHHHHHHHH2(;>;|h"             Rߗu7W'B$@$@$@$@$@$@$@$@$@$@$@$@$@&pы}+Ÿo#             E'_LBŴ IHHHHHHHHHHHHH\b.z_X $             \B0GǷBc1F# \`CT1+\HtU̵*ƨ$@$@$@$@$@$@$@$@$@$@$@$@$@$p *ƨr!њcVMa             yg;sFLFD39 )G#v4bV}9_EH|S7HHHHHHHHHHHHHH%)|#Rw&T&Feˠ: wG$@$@$@$@$@$@$@$@$@$@$@$@$pq8 ʌYzcU*?%1We             TV8}L֕o |>ЕC(CF:V׸iJ$@$@$@$@$@$@$@$@$@$@$@$@$p.:qC魭lm-Wf|}#g5$@$@$@$@$@$@$@$@$@$@$@$@$@$pW/~NԷRKH\/By"/K$@$@$@$@$@$@$@$@$@$@$@$@$@5H8۩_l%&3>n>m7a2}Y&             Pp7ʶ wNM8}xUxnۦ!}-Tnd^cErތE$@$@$@$@$@$@$@$@$@$@$@$@$Pu*6ۖ6Vvv'?6^B6c}-?SGunj>Nf,] Nfos ?O fy(ACשn V6UeyiڤKi$@$@$@$@$@$@$@$@$@$@$@$@$@$p*\sI[%e\}c~GKX%n _'.}zPD9NoUڂ`8F$@$@$@$@$@$@$@$@$@$@$@$@$@&L6V~Nmn6iWzSEзBT!6IX>P|#جCn6k$''}#5k7))sIIIVIHHHHHHHHHHHHH#111ڵ[oufnnn"K2tlosK=ǵTBwH\ dz^/^Dzv7IHHHHHHHHHHHHHC~V'dWel$g d7}ϱ."w$)ni3fY~.kKR;L^0 I@4_~K` ˂V˺nۤ.Ije?<|%~~H ^'nV7ۤf.k!;F              _&|iGgqϹao X 4q=XleeY[<>l@$@$@$@$@$@$@$@$@$@$@$@$@$@$pAk jZkIJm V9&ɌDgL7X]In&k/))i L$@$@$@$@$@$@$@$@$@$@$@$@$@$@.V|Y]'dvuҚs{ D`uݦsY.Si               6`6Ou(ugB6xG%72@6; M@:HYefY~NmIdM2G]}*F5?~_aaH *dddD2$c D\-f.lb71m^˕ ^&)'ͬeOۼct $5k֠O>hРA%; tRtIIIfIHHHHHHHHHHH`S8Xd}flbXX$@H{̺SYۂҦ_2.>9ݻwM6`.$#خ]ӇHHHHHHHHHHHZY\i_{٩&BémNKe{ PXXܮ];" @ 5va5D$@$@$@$@$@$@$@$@$@$@$@$P]uqek[lNJ ^tqM.˝ ;'&MFX#(7n}E4. EBI6Y%63;v>>`:Ӣ-X&6ӮA_ؾ׿e+vn݀uCYr0_#wVߒ(s @LJ;O|e'`Y:BZ1Vw\ ^\\{o߾F$! …M3g0 _L-Xyzsr\\5mUR/ 'T6mf_m!SrkfYU^F T>0&╰&m'_vė"_bLNNR~2.;O~\w{KOމ))Q/}j'_7?";wލnr@sN,ZgΜA)ŨJ\"..)ɐ5SqChޢy4 m+) Y            ЩH@_+)?q^?_n#ka8ۡ?| 63'o?Dc2%lr+5b:Y*뾖\hV|vm$w}+]U Ԯm\йn7bv]\q9ɱxOKTXQ/ٯ|  [͗⽄f-~zM;oQ[ƓcecUR_MX:1= ] oϭHNNF:u]w؁ <{Z"K&3cEFL壥G||y/;EW˒jVV;v,VLJ>%'$&jEX%=2~z6m1 ^tzXz~x]KTŇٚkaNC|R-'"0@xvZG_["{?~86G8jՊ0K$@$@$@$@$@$@$@$@$@$@$U[ePkkKxJ;wr/~qwia\Y>G1q UXU}syq~zK'+ҩ=~q_j; ƻ{g#ѲV M~["jiK!,j$F,vm3}̭~mK'SHLzb:Iٮ:qt9Ph.۬}E/򥬺!.)w@n_iъ|,_xϪ1.vuwїIl]X.57 1i3Cay1?lLL-Xy3 ôXl8j"6j8%_ocpX.auYz(.e{j391C*GZh(8M_br'L`׮]pK11JW}LL1]1kW"u5k ~>35թ"ˮޜS9ªs8~c;ΏBGP%{Mk\Caߟ{({mԱ3*`% رcn+.;vVz(           }gBWSq}ґb}˦"c°hyyObsXjNv-'N竟q;/м~d/ea+~g@W_Ǵ(ӆu:7H>kO^f`)9Uve][Zr kV}XCcKYG|]RI:"~qeVX.:1QKR)/_oW>e 잗Wf͂wV+Q>-5]wø pe~~+WW_}T~1%ܟ¯4} _yۗ`MHWӻ?kXڳew{> xn^wXG/ė3ӻcҌTXoѫIbW?/;;#)> - ,6p N#mڴ… ׿tR%s'\;^nhu";;;0> @ ErL=ލ+AVij p%%X;+0u5D%L?^iZGމ-xh tѽ3:?ɪ'\Ӻ5ZlNQu`IN8eb]uŷJR$lf.sYS]l$Tع ?x%8ΨQ,UUho3ՇS=zV%bcPp&Eur׫Vg,9%j7<^yҗ*%ͅvޭim=>X y}rr2֯_maXrK~K/FѠAQ;3;6l fɫYat0s$l]YGlƻ{)5_%`]pq!8wi 1YfG,3W9?SmS:&`,zz/ge~0@ÇnK=ܽ{wH[UT'\5ٮ]Ruӎ,sa Q(ԩS7ovרqHHHHHHHHHHH N(.gd|a/CjbG,)EëSbm±okbMmEmSⶫ[#;K*! =/܍sň+:Bεʪs be-6K,u3k3\ˡPw Y L_,Kqss uá-΀ k?.6_TXuNzk%23=;%K[X;~PzE7_b6p?r%ɍ޳g%ˮBz[Ъu+,l9ڹ_O9=;[3iECՖ`i>A1Ao? -\4nzFi,?\5oާA@|!Q俸*k'F8#K0D4i)n4 0EؼVZYפ 9F?wN>Kr%\}EoF&          7ᯟÐǹB|ll t}8gcمWov[;ɕBKRQ#$ThtE7udly))1zp8UR_t(U[UY꡼ͲTש@[U+z!\&m,u&v3v\asjyW;ݑkW{-ŤùCol;AW|ϑe罈#nҤx-@;[ EOUGM"ދك-Z >C!_`JOY]vK0stV3Vo^==M/{RQ] }vo, u1EV}37L~j<6IX)o#ƷCM3 T\rMʵ)bNb-d~F9*,ekLAIHHHHHHHHHH<T_-?+L=!ZT8UfvuØWcW ٨oY|?bk@[tX6{Ops0XAwYx")L̷L?>,.V@pm:wY<jm.-+e.}͞v<|%_k۷leo Kj]6wkjg˱ދxuIm_7]O|e'`rlWgj߿ y?] +.nxpI_}%ޟ+_D?ٙsF G9nÞ-HK/?RMX7m_?J n%:MŞƣoi?&펷!I# h{^lR.Gͭ/zj4lO8yBBRգE:™ 'Fl~ߘ;w.)xsvm(~/Ƥ?NN@4J-Ruufxި?en?~O=g}N($%nh;XOm=`IvR>&u]P|Ũ`*W ?Pi7˺ɦ\m{]@_8h s"5z[e¡&mx o09"[v&%yEj#DOྻF:ah{y[lv'cnKm~-czz<3J],z~ ZN:emKBGoCڜݧoR_;RĞoJme5-\rԗ!MѤ7^eX5kVxo "⧤`P5)צ\M6-#Ϥ]6=zڣQ];wĥ^Zz=Gc$          ^5j88gd(p@q/j&,;u $0oo3ziuJȮ$1שMX_+1s a/us.e6la9EݻwMlly.w5Yk7{̝3OF߾}17зWoKo; k$h~7Dx+Wūy]t?ut_5jX½[l #(C%X3f4JnJW//ދQN^H0k՞dWN(T8ydb|           p"V}qJXW^\캬sfu=d.t:rC>n?ƣcF~7`%عcQŅEqۉ"uKL%qƸiU,I|~h;6߁&h$gwTt9 $ ϹkUٺu˞%s%XכRf96=N4$@$@$@$@$@$@$@$@$@$@$@,}*ֆe!Rss7Yyvk_ӦtvtnS`>NmMrv]o:W[QC#8-V^Cjڹs'999gLi 5j yf$@ xq #0޴iSԪTdMЭ[Gcx:HHHHHHHHHHHHRUꕯ^E%By.v{Y^\;M:I@)X[O 75[lNnݦunuie{im:s";w.,^5o\=~CdHA@nYM!ϣ#uP#[l۶ͺu[$uFff&HBe,           `0$˺.$S`q}-e?MY.TG\jf6u[݌]v/whH|%жm[޽:t(7E9V_N8{,qHrFJJJ4B3& mlZȷ c&]StYfB̄5h%9妏Sד? ZG7ḵF \r\\&)u+$@$@$@$@$@$@$@$@$@$@$@$pk²mefϥ]}<3*s]6Mf5˺̥)۪U+H|$ ׬\r 3 ˂A̲i f7ۤ,IJҹul_v?'I.)X=Z|9rzN9r ˵D$@$@$@$@$@$@$@$@$@$@$@ӈ]v]׹KCj^'\/kh"39bO>HHH0, \(ڕkxٲeQʼ9O           'X™v]GKPΗ~^x&쇞h>fb-atK٩.PNr&              @zz ꕯ^EUlDlwkKY.\t)7m$&INc0ff ͷ\{~ +f/ά=)iэHHHHHHHHHHHHHH<'`le ڦc֥B;Ũ-}Qf,h?i7 CIjݬKn\t2b׵_y4'`vp ̓}IHHHHHHHHHHHHH-G3y8s؝lb2` c8|0 `DA$@$@$@$@$@$@$@$@$@$@$@$@UC 11CӦM{헮wW!pE$@$@$@$@$@$@$@$@$@$@$@$PD 㣤9օ%d֝l>?_5x3h L\.s{<ݮR7_ΜHHHHHHHHHHHHHH `jN*=_msW阒L;\1m, EٳVU"ǎ/)яd6\LL իڵk{Vk ܹs6mo jrҀ\Ϸ$~hoj#-Tpw,;>v_@=sssoZ<~q'"...^&!qF+Z!7$D =ԽWdS fT*|,L6Of{6l7ҍr9rW^y!??ܴeAa۶mXfM%K`ڴi"wŚݻ?ѣѧOr V9n8f2 "g϶&عsgl|gh}*EѤI?E9/#ǔ\s5+V>!O:ck67^>1{t¬o>Űv>?{kX} oeēa:˫h  c:aƺO1/I:M/ͷ\K!rz/uiyZWXߌu՘v'zF+ῺVKbR,M-#caü70{qZ0S :K٘7tikX*(kץ;):ٓT8-ҮP| <{e]- @5زe ?nBr|u3gXz4NcEݻW'byS޽{7tSTD3]a6.eu.̺YY~1Zیd1nu/6'?h$#vP _%;% :t绞r\'sNmX.{}Ҹ#G3f̰}i{'k/x~ᡕ::a` 慘J)K}Zzϝ0g,x?e6z93| w=e("|~%޿;r?/덑^EQ?o=W}'gOCB)t>Fߌq]l Zj}s=88mx?e><Ե:I`=Fn^PlU3~| Y/D!jX@njQK݆T}bf<|GԊ+Žd!;3pp LS85ʆ#ƣ_f-Y9o_Y+[cLW߳U&ށ6DɫEqH+U]XDkl>?cfnVTG>}+rDAr.y3ǒ0PcӟHHHHHHHHHHH V\YU%8p[ne8_ [n`=Q6No1F96_?\Jv-^afeo̲ӴڝTV]L\l&{l V~f_nڃ(mn^O$"<^͗z=%^v޻%yǬ>Æ stݡvI|{$s rk&?c<{I;bcqWNJj# ]nCО~;g}n!>W$w>"p3ޚ :=Ŕ֨xR-V=AG# C_<8V!jaso"K@b\UOC|>xQO3:b}*s =ЮnbUO@rQulqhNCH]Uŗ9a2%VPu}θc:L6Yr:务xѤy|rr\[6m2X?mz@ \(ٟ݆&O?sfcڽ2R_nY|v` vn8jWΉ ؝n.:1`;aW!Ҷ-ƾfcL&jG`KOČL|0t rpJ:%Z"2{BB%D$@$@$@$@$@$@$@$@$@$@$Pd聒;|07F.j 7a?^Q~֭޽;ԩ寓MrzvQQ٩{\D/kzk ԅ]^u/1"S~jI٬K<{=Eדi&+DgG+}W3{{,ȑq-IR;>=_=/3'$UdzR;vmY*e/*Pr\,JSrzjurOb3>#j}œ#NHk$y!\N~Jw{=.+\龅j;Ͽp]ϿYK\|r>K?pT{һ^IsѩcDfə}^O)|kҤceRz8DKST>N nsab;37#-d( 3׻wf/@~uwHiq0UÒ)/cAq萖O»_އ| q4v,X+zbPslJ,r,`:Eh|̳yj"d,P dJ+1{;1hc|ҚqtWuE|ϔaN$@$@$@$@$@$@$@$@$@$@$}GoyZj;Z&)f;r s`.xIr@͚59\@IDAT-w%m&+ZjaܹDG}ttYnJظqGvGۤ]Gݥ4Tw*T`@ߌ!echnuO!Ivs饗lss&=rH{צyo'+ZI ͻƦMbժU|9'ޗ7J-^ga]0K}%o+Ց*-Zl}/5=Yv|I!l]xn?oϚ=sS#ޥXOSƢ[s5?uznuBz s?DG[H_BDuڀ? ^˙sQObKc1ػt%ЮkRwĻS|7~Hcwkqe4RRCxݲ"R[=f{@eWly Z/Bԯtl|D+|_[`xbH~YpUf*:Rը~ȉwk♙ew.abDﶄ3/o];0"2}[ѱ?[Z](: U <> K$@$@$@$@$@$@$@$@$@$@$P dq+X"!/3e>#hԤ)$ycd3Ҥ|by_4h ̞=/ %ɸ9.\qӧ-Zdȸ (x?yd+vMI>Z.H:vU2'`Ĝ6{ݭqa1auf(V`ԤnؑQZ4J| ayy^Gi-!ſ86nx=v\$ 'BEQ"ͽY,x ?Ь4YH|4֭gWcҐhXZ }̶%x~DtK ߜ{ ] ȼI<}HE7F?P=R[z%XɿrA?"KpH}}KJb%>/-2Ѵħyc.߁~-{#"׷so [Tj'KSbٯzX^;܏֗uذ $"k*Vx/Fk"ġApxrZr̉C&* ٌ7wt+ Tx L6 1dWQMGXkԣG]-eCm۶AtG]Xѿݺu|`q^NY7)b3S="r2_D"F6@Wd*_vC—w_]/N,؏w -캗rKݺu_ėG%_#ʳ㗽nyc\3xn ~%whl<嘤Ǧv i%O?wr>;3"|xh/G=]%c]>q VⓍg[b{je)!'LyzyqKL n2gOT]ߘTL~c3;LꕌVmcK2V'FS%^or VRwz֮ܭ+1T^p K'Q7F]|xnKV̙9 JI 'Ր; ncٳorlVeDcئBfz[ Y?LJ[ء>C:GtaHHHHHHHHHHH KgKvMc_l֬7o!ek|'(TiVZ[ovG9K͗Wj X {٬t*?NB@Tpe]w䨌5k`N˷l&>o1` oҤI^|EWѴy N;;w²?GӁ Eokqee(ޛ9W KFzh&Ƿ&bb:7\`B Wvo{6oCxxQc(X]WEѿUm5^{lQ־[inp+j]ؼ=5VB+2/+u=)R|#!?iX2/̬֮fW^b`9ذ'Ggsfbtno=hӘ,lV7)ll]{Z=cjz+1ޚ ©oYxVNֱɍ[#5; ƻ.״T޷ajخY1%B ir3vl]ڭn^ngCFע:=ǂ70e<̟7Ͽ1.^/7$,Æ;a<,ϸ/=  #qcoYi,ْ%XռC,$K$@$@$@$@$@$@$@$@$@$@$@C`߾}cRf]Iv9iSEğ41Ff[haRޠM"dWy"@›ڰY6Çj7Vy-U>|X B"wG8}D4{/曭x۷[>N_!$ :ԺȪDGjj*ƌ_?1a cƌe{ڥ^̳sgsGbS>{ 3K}v`x |_VYߗWa:>=]vzy)쭆=:}q:=8E"xwc!!3ácj.tHr?~}9[cʉ3|7'rl#QVV[GsP'!-Q.-[*ѳ%: 8 qKZ1n=NZZ S%<ŗůUfnTq6բߟ#md`3^x]$qZ@֢Ʃ82-$@$@$@$@$@$@$@$@$@$@$@UH`ڵ֣YvmzOt6mѣG>fJ,wteq`k0==qq+r¢E*<꺖e.k^Fr^켏XXŖmjY:m"nU'v%vK.I|t2l-NRUaݞLSY$/:¼Z'Uu.e:>d4TL/}ѰQ?#nݺx!Z|96mdݠ oٲ+_v뇛|{iȗW_}e!ϼ{tQ(؁W#~[.4_x+ 2Dsظj:?Qt8: bT$@$@$@$@$@$@$@$@$@$@$@!XrJ/;vZѰ*]E?xw̯Hr|w߯X:kc{ƐVLW6Kj߾=T$%Pg [](E|k{\uzmu-;U'>:9t8_/84mNem\$.\``½n½K9"L)4^"JHNʝGj"|q:Y zdI\7 @%ޅ-i ~޼y)y4f$l6_z-@½n Z\n|?lrUWA}/I ^|C$pc4%AVUr0           95j9[!pPtd *W5~&B?u @xBьC o6a:|Y knu L$@$@$@$@$@$@$@$@$@$@$@$@$p1-L41j#`jfmB[~̀'P^=lذ"~Qs            *& ha1@ G:`zGy}DYU[MbX|9 mHHHHHHHHHHHH"M@vދx/SEU_^h֮ۛ0X4ozE!A)x}c K c] #)(3ƺ_>mU^UvY!؎k.7~Ŕĕ\q1Pl1Yz kwn#a_;1[j/q^ǂ0r_Y' #R))q" EI6X _zocG%f}LS([C5r;I)cm',@SPO|lcNM57Of/rɦwዴ|37c2b$/sҩ8=/vÉSj1U^-xX빻^f[)5om2tot}.Ky{ H<|Y5n_[׍ϑ9{rySZ\XUI䖼{el޲Np99Y?_bOu ,X4dy!4 [zVCwXΧ$7^D9_[s[6h>#e3q)/eu]uבl\X[?u$qs$\A>JQa&/s @7z}}l]ʱƜ]FJ*c˿ހ_~"V-H -ba'_ߦ]RøCfl*V}M8&},mNl<:^]J4=\F0b/x*Ivt5a*Yr%ЕuaX*7SdKq ,j4?er$uԯ-RrY'+)7WqZ6Lk@j0׈[&$y <ɃKszO\_mO1UjB|{Dxnx\^~3Z$PH=\1\Ԝe^D9THڙ`qyψĭ]!)F.q=,$ 8At %.=h1Y0X\'))^xGnVFJ\"%y˕_ KJ) V{63W[wn"S>Fb\X6D@{X{3"~PP!ܾ'|CE`,k'|JOL˗V|Y7ʒX|ii6GY[ws `{BCy=|Լ,^|\fƉv-yye.fߺTA N^ >"]v}2%>^GYӲMahb;y/Qo1Ͷho 8KsYGGidܳ02'7O $D^SS 1KR~[ NZJ ^[KsxϛH]gem^x{YqAT<_on֮Gj^X3Z^|-0*y$_&TXv.zRFk !N9QvPwiQMT"x^)RdU,ЭM^/^rvQ[|dl/7/H/㹭WCٍv/2o82_/{Yu-%swKnCI/׭yK/xZŹGdN<.˓uJG7&UNNoFsxz+<^uNj>^ceDGx8.Ô5{X߷r[/K@.yzo0ww%o(!#`g$l mTߒNi2o/{^xE͏^XВ:}醦Ad%"s(FF`=<O3I48FM"*"(827M;U>s=sWu[^[:uΪSg ;8Xߖ:I&iTf-m*-aG 6VVW̘rj{ A('r' LDw7cH!|wvLC\U;gW+>ccV/kIfBDٓ娗J8lMHMCC rc:1q qؘ'2lJb}yYA(FY~ mfPHSS >T X.JQ8+}^9NWj5Ù+cCjߓSS sk(#pda>Hl:u 'F$7pavo@ ř+Nڥv[Ʀց`A<5<߱I$|@o>a05}(!Vd>b\eskKYkͲg 3`7uLśs=ڱ; X܌\V8q>nE:en"ܹs65y?o,a?1'SA!6AA &MO'̈́Y 9T .U—N19;1b'7S'M_'mo'R xF̸}2ѫd9es77[ʰ3+y99Dt8uO F6'W]5ہEXPWp^U7E;_2ae9b 4"LXoys&RvX<1y(ΟNKenBE$uX]M$v+Ja#Iuͱ<SEࡏ@bwL_fܘ1p@[bKްAKրv-y8BI;krabcRs@ƍOKK73>̼pЈd),01S&xb(QWҠpB|)ҪOԡ:E|1a( V!vv޲)&.0&]=%A)}_ֹ8]"ؘXL-3a3u hq޾`q5?o3ƭ-p@:n3qbÊPoʝeY06tGesӲ7Ox/;SI%I}$IMt+ǒBCZ [6Z,̔Dm mq [ǩ1UwWG|{g DlboKSKɧE_=%ue2TK-_x5Oqqo&mӚc:%>ck)z/I0)g51q; ιx3D)=9.u#rLv*У9mXׄa9Vh @%@bTup8t` k;Oُ9q4lligІf >cořѨsÖĖwJ`ێCH4%c'$Tr8q清$ SW*6U;cCnRpeКAIFP5T&긗£L !\thTh?j( &E \jXV"6^# .TdO4.-b(al>me򗂱|RF:Ht™traMXp 3n?foɠ; Iɂ NʅgƏT )]܇T\+ҿ-4ƺ9-X$$bm"Fay~!Մ =۠bU4(/]y,۔/ÀeKpr"l}-۩cw/p8.AS#U+`]f]kj]uR c6 GL0"L ÄMr6 C ukVr]ջԷTQ3k`7"Q 06—5 mj`;oJK1~B3ЈR&M ;;RH@J!ݥvn۵^dG~NLqJ!ibXrٵθ8 (mbxgm|rFqM.+_SJ$#Q3|ƙ)XN@\Ia8OqcJrʸΦ$1&əQl$2cx,[ pb!H UMm3v0[w d%Fu-4ʁ}8MZ‚81Pqe@Ć_ c̘>]raV8^U* qϜ N@Xa;#J f6LrBR١ҡE IG4 L0~!'ijww3D$ƈo/^3;?0;mR=s`8t>)4xtjM{b5Nps3m?cc##L8SK;sw5c0uzzfd` Ύw]'2aBI  bC7<#s3SZ ߭,b c˕_C;?Mпݎd?oqpuk&6߾2>0T'}2aD) A!,Ipߎڍ93Pg$5HĐus@YYCU2s͌[帡@mK4`G-I-9޻-SŠ5Kƌt.u"vcjyJk.pR\$sm8y 0rf#@#&prP>7㶱f8Ior8!7*ޓ)æm֌;#9eF̸WPcb:I1ߏ!qo_[4r]n}]]-iߵ~]]hM6p136W!tiqFvf?bQ^XㅓerH0[506_"}|߽q0iy}!<a_\H]} ]\~߰pBٶ5RR%0Z|t$o"eeL:0s%־-]>a$~1B0!B26f2EHl 9h5e%j߶ 0 L/fv%pU aH7 Φ%\"!^0_rmRX%"!)1=&{v?ϲ:Pa K)p(8bʄNIkʹQ8>]SԞ+FF*6TM|LwS#/S،3)q ̑? p4ԯ 3SH>.Ihhf0`iL`%9*1Rs2efpnJC|g4=ˤ%3טπ'5ظ$QHqNJgwe[SD U3ٜ˘VHFp 8! [8ptӑ1\BBa;w`mO{x:)>b0Zqј@QO8[),t CS WAÉqNւsMݺn mK+qڸƐ fl\%ހ11I؄*+ܶGmmĆ1JE"4NN w٠^rVľ]R.TOb'avKDVs-Mn]~Ma-k}뮘a1pA[t3 =jTꘓ kh >&J~ۦ&uJlS7MѶhJ ߍnz'[+;7~.W䘈q$RfI+İ)gCp6+ގ&>OQx0uis'=.08ST0~JKj]9l.4r-աY0GPXX]:=¢[ݶ-Θ[昜<9NTR6amV"69aS֧ĎKB?v[Rvv*-N"X,DUd6 qƼ'޷6*DLZ'D_`rrzY'r3qm)x1Z# Dk’S[\C=IF*yn#8"Ӊ+eKh=M)wMWԅyOf,j8]C!DNoW !Ϩ<ћeq'ED+[%L|"[! ] z > oX_r$ @ ㋉-x #e'kn+8Y^1®N \kTkar ˻]Ҡ| -Tl a [hJ)T{ҒJr#;sP{RR1ƃb[T\η5nc$\ۖ2gL(!_ @䊍=` :YDoź?ӕO8(MU@PFFG4/ &f\3?ά:_1xo?i>~f|vЇ=*"-* *Р`MKX\s$BW;KUU@PTU@PTQW CF](OPTU .y/1H?fU~\|7gv?I/p9hJǝ* * * * * *0 hGM9*0 tdeͧoSfB2!w#rJs)u2(cT&pN)_=??%cD^VTU MWw*0r gQm&4 #ud* KA܉XX6YiI ǂm,n\o~?@ӿ* * *_WTG q6@6R~4@Kɜ+ֈ) P GPTP'_IlvoÆ6gwrm,?.70n&HH* *8(K4N&w8Jӱ҈7=0 CFo:!"h (՛TTU@PTU@PB}B* ,uR_53;k|WmaY>1awΙqsUי\skh* dQ+#jt * *7*UU@PTU@U@h* )|/mp]U!sŵ7ڤؘ3_3y1WYWndK2** * * * * *0` #șs9hhkZ`z|iqaو6F:ԾFˣ #J5g5m\md죜Gk K`7gbjbk:ؚ­ oY|7V̾Thu4/~.RկH߰m53=0?^c&e+U 6}_2k3QY eXl9EꭻH2`QñpcMWlGt_zL= -S8⋵Kp@Dkb}IT5)MWD3ˤ+ wب u\8́ecOȒ!0X`5e6ũZĖҺDL% ZKxg._DvR&@ q_9m)i>w >f-;:@Y)> }vM # ”æ:[ǟ`„rSG+ #u؄L 'Ɔ\X Nmdww {Fo6l:͌_]8OTX :_g2:28Nf1xg go.}'c̷Ǟ5|e0nbu<ҡ>-7IMy2֡zsF$7(o-uKr cqHb<[$0&> @I }apȵ.z'H7Ueܪ*0s?9-PQX&~ۑGj* xkE˾W33mm-wcyҡͅi˓rG>۠TU@PSX?(P2 % * * ~NI> * a9 @p$鑺߸r|O_jn[q%cY|\}CrG8Ջ6HPTU`|E==~^PTU`aɅWUU@PTο@V h Ѵ* #@n>$]=z,oySpQٶXV1]{˟q6!wz}UU@PHxTzI2NTU@PTS@K7)Ѯ* @crt@/I)* rR1[eyzi391n6_#]~"[6&w-Ýx|&݋Gw m\ 03+tQTU@PT/p;l{,Š * |GDRTU@PwJZPTU 7NO~楧d֮ZasդoG2]lx$:Sl~t~UGe|'${0oa>Rs붝Ef4?e:M]߰>&AUU`Є"7Dtʅñ[y~_bQFyQPTU@PTF\QmTTU`(Ƥ @' $?߭Nʗ渣}lN?xs4ty" =@IDAT)Gs\~Vw)IfN9PQ;̪qs-[c|̉$?dΏK+\N|_c\QՂ^Js@Pr+|p-\6`2[:zD-* Ty2v2Z*oU@6odزl ?rGKʾc?$~Lm&m6pr5U\AN0C[3|rz ]M>b}?0Lqflm%[͵=K|oܖ>Mf78NIgHLn|YH;jfrך3y5'??JGrXxy_}n/8}rfF/Ӣqœ^V{*xV- : Ck.q_78>$6Ѿ~HQ_QJ fG}hK.L;<&Q+c!u֋>!&6&ĭ΅ g7qc00<:xrΉ??u)J?IؤtF{*t# 7?>'9}$ec㡌)s>%v!ن6Y,FE?a Df4`69qF 0dN@T͝Ѹơ~a{Ŷ(Cmҫbwtck/jJ@P$"J[lFУR3 | T10v(RG߱;70h٨Lbd =@} lqݨ l}HE#2+- o86nwdO_v_hxf$ّkb}n1zo}yŸ~%a/c^^W4+%_~NVLNknܻm1Kkv@Jd{c`tiW[wSm6+@Ի֥~M /gddl>?i0PM#߲1Ŏab>:ƍs͸[6\9fLq BiYE"06YmSb}$Խj~[!NI*8vf%ӆ&&2@#FŲic#x[? I`G07RO=JR&w䠊!t+8K"?cUU@Iߚ?Q>H:xrbLIw~{$<.Xr{9l=י;kכs.Ҝp͋v(gεmDԙ* * ϣƧ * * * AQJ* eOҿYO0Dcߞ#ey3O4)y4,{VG~5ehgXnm?k|ԣ22:Rs؋ܝ0_zW7&)J#vuG* }4:!k$* *ޕ' @ h{* -V?H{Ļ֭5so7GL|ؘɕn6W1! $a?9PIz M*:~e̯?(_"b}]UUPܗT%W(* (*'gf] "$!4\Jk* ,A4]CVTU`p}׭0Xki%vSfbn>K̖6w˔Mv1hww=>6/N|PrGs$/KeaWp0ƖH]X#i/~]Gdq?S!4Es1(j{^* * * dT ̑YTU``;AIub*  x,EVTU@X C]u_$K2 nA-m|ae닻9 7.SxL# !nr~wFǤ&Gi#֘+&͎断ͷ~rl˽6n±k=XMd΂eBF[|jܜ~aC38~h9kCEX9 cakP3g_|9gכ-vXr]4p|Ji'rTZPTU@PT>)P5{xrVU@PTU@PTU@PTU`".UU@XR |aٶkZ3fbbSTeĸDV56Id<gxyiw3盻w춏rWQi)>&Kj5gC[l=Y`s`߾Ӽ>ln}&%}.7o?Ts擏3{/XP9Fg+nռ6u)u7 gH<>C9q|.{ ^0oYz;l=13;6.7ǝ=7a޸#[vx$=|wo~y/3/ϛɕOSx6}3,60wOf5;<`%O>ޜqc?o!=7x#7m0y9?cch* t;uS{KFyEPTU@PTypvRTU@PTUY%/ qar(U?mX%N8:qGiTj n/m*8tt%ZZ68QPuƖ A-"wpJ |$"w)v>ˮ\|c+Zrw53sW6?<۬Z>i1ӻĤMg?I6?#O @y<1x@qqyKa6_c^oTo3oZkx$Ǐ9x?USU}{I?/+-Wc&i_ԟ;|߫ͳOH<+$Yo|_^07k>3Ny}B} =߼^d`/-K )Ul.yZO9p6^`c!ݸ$ {7blQ,a|Q6t@_'@k:0_控8ޣ(#qC1#TMi{*@Q8 \QITUqI,Arpc}euLDIP Q $ms&Aȏ͗)N߮23ڱ&SIDL?3pCLLr FTN:%#g!F."!3'3/L>`Ueslem\AYӲxLl`QWW(w:K6A7L&{Qo3|{K_*Q|өHQ._Ʌgy䜅טym^y 戃wOF2p8O#_a M wcAHߝӎ{7q|'X1aN=0sf{Z.xsN6]ܭ>^>1Jw?{1:l5So:];w߼֭ `}AO.$<|Qyݏ'0Ω`}gPy,7z͎3fo2׭~կ+nۜsmMK}u&ą9d*xb/ oW%T¥pZ!P`@T/té>Ϧrx2܎9`n,al6'F&N|(X,aGfm&~A9YmSc .)>|:|y1p p6B4Ɓߩ1$u3Je҈ae% CdbgE6Scgp-ȟX#69)XR}('du[Ju#_J*0 ݓY悿}zjFHcE·x;?e՟f6yo?5'$e`j¼ϴ9wۗ[Ƭh5 GZ2ֲa%K֓M$}Z.N7kVfl?sSL~჎;>Xyc:GK9|WsLO=b;rm/~:(:.Ѽ+fmÙ#V_zyųNdHgs_Q+8?:n~4 N}Y+?qx'k 3߿^]k`*0T Ǭ {VªPjֻrz;",zXx`+b H٩* *P@[jjAPTU@hSn$/sʛ w/#Wd:^(w܅?/b͕6ຊy ǙMz7 w\jH[@.}}lֿiunȟw Hlh^$G/>>{%v\%*{ˬ\c yh >ѮqQ@a_|C?άߵce"yyTvԘy76D?yѯiEq-Z6c^W v8a\WYXekTU`ǔQPcSHߴ Je (4][.ްsů8* * *0 hH *0 z,|ۼ//6355eG_u=9Ǽ|\z,"m7?Ev|sNo\S\ep';klcy﷯2_'B$ߋgw Q( .Z g<`9߬mYpS}yĚBF2}Yw8ӗR$%^Ⅴlo7|ڛow?AV~>K/<KN<yOv5ܛo/ ÚǶGPF]Ra kiմ7' * * * @FBF * adk|7ߵݼ}Xm-3S{[y@4_k'nAs};l"=rRl .{YiwAݡ~ym\8` 瑳_9n6W^|[XKX}[[%Əؼ޶ً$ 0wB»H;Br؟J0׮[{.sp'-6."^Ƽ_3yYfժU?oz3@iY;yvİfՊfrr&w9GM껋ZtCPTU@PT vx*0 0ljPC A3!auQTU@PTU`1bUU@Ua "=gN=|)# sóerW&bӚ04H?as]r,{W5l\m.N/bk僮z#̓9^P+SO'/wψɂ^|lq֏ E-Mlɤm モRV$K=9O>9$㯟1++oiGT* * dPRdRU@PTUR`v/W'Hn^lxwho\_V|$az줹ΝE^H{7.>aJr1ö(pkW-7r1K/w6#.fY/]ȝp^䵧opW=-/]}ą?!a:^%^]\=*s^o~)ǚ'uErNLto!ZYpE?Ҏ3VXYAҹepQ<_bŽms + pteW}_-|W+b/ pwRU:^6(4tQ-FM.> * * * (ЯDu l/-%ͪ>ܮ\!i fM7 o#Y֪kgAzkI&r8ji4D0r) I&)RTUWrsViȚxڄ,]0S;w,36&EN>b^0I\K6rU|xc ]w:5+ Ŕ 4eL3=(^DhHy:#oOdF/:̺mcf~]aֵ> 1-g܄g]c\;3:}bێş u uξ%mj;w`[4Po[E 1cbmxI4r1C]Io9yD$vwo?3_fĜU[Li.X9aƵԞ5sxv{y(ۨ=;mqW!_'oZHpm}C͟:p˽4eE_wخZ6c^YLS߻dK-XZf>t̟q_AcͻtyxfU@N`D{ :C;tJ|hC(nb* * *P.9씗* )p>GR{$lkV;7fv{}Sz%x$z˘:۸=@Dw feBٕ]9֏(/LVEDx,6C ˡlZҖHNxc5[̮)sU+{4V_ŶO[ﻷ9G:\ * =@x Y%1 uQTUWXӫ_PTU@PTU@% (׿HN#݂$rcwxsu9˝RW&{mt]~;;P;q?ICm;-U$ʛ0bmwSָbS|U[U.,RB"I%̓2-bUIO&`\؟zܑf)0?ы6f^hޅ6PTU@PTU@X8IZwrXS8.4_O8nVTU@PTU@PTT@9,JJPTU'g︟ǧWIl/Ww¡M_4ȗ]6i/w=Ƣhɵemg1 eiBrBe+"_ܿcy1o}l_w>=qqVk$]26z@ /3'uk4cw͓ * * .rr ,yqv]lIe+* `Kxm9:8=>9: |1ctTUX󑉟a* * *CMPQ1TU@P*VIR$xrٛ{'U}`M9mG2 +V0ݶ$AIk{sM{91fqdqq1߽mĻ rk ˬmK⯘(Nf[nm0X^cU+O$, ߽{uYk ^X^Gۋ0۠TU@X h1h vMfd"ڋ{^Ӿp+pWTU@PTU`G j* ouO#)>9>nve>~ޏ,m^ /O$7fN<0IDc̋O>֜sc%%ߒ Ir5S+NU8[xggjB,6[ok`*~s=x|>{y?osc)HWWM֛">8/@2* * ,pBU`p!Nʏk察8UU@PTU@PTU``;vhX 0_ DA,~e ]q|7O}bGwmnj'n{#m'7~KK$)#a͈ ǥЧ<Ɖcٴn]ILJܷqE2tGW\ckړ1ך]gBK.6t¸y!Wh;~.VE$4%'ig/{=|o|is탳mk|Sq_)1w7 Xop&cSWaXCkKre 4*sQmTTU@ȤdRaTUo q{UGO~ܡ2ƦCj D;;?ݿO<=Z`b18S°mF+I-!&Z [[Wߨ)רW.543qc 4m|Tubc[cvŗpcby[ן]חfRqkk)*|>c^4f͚]gc_5ZtI%nqE4r?1O5WwOȝ_̫?/Io{vAo C= /xh+PX.?(TKfkQ旋V[s>e;^y*<`r~| 7'f>/HOJwO)<=Ab~'X{P%0ݾMzN?xO=Id<(sIL,߼=IA_Cj sNjb|U9 8&خˎm/\͕s85socķgr/}}&Ď2h3:†b ;4b16 bbr+Q%"7I81I!^X$jgfa 'fB+66SOPH*nL|1M@ɯզoJO&ĩo6d^6n1Џo#1(ڜ+duĈѷC6ب\Q&ܘyaeb4:F#'2&>ͷ:\w]_ߟގzn|xF*0@ $Lؑ].6O?phozc|Ul4)|Dw':fu\oxyYϳIoi1{]mg4߼*sOo4w?z9GX 8r~\}_'5B7:g4 Cmλnso:$35Ys=w5s]ã;>Wg{9w֙ Pa\0f>ޡs/wc6$gK<1X6+.r}؄$Yq?l_rQ ~~In1_\ā2{.|y? |7?xe~pf,mUTU@PTU@PTU``>%?7 XLJGPTU@PT9P c/q)4|U@PT\ m-/5Rn.867q]߻҃Gc [XٜJD~]x$wIr9>GwߑO4Ozl8swߵmMC,+dwc}Ǯ)Z<־h9fb%., {uia++cG, 83#_c,]./{Gz1 z ko*ؓ nWPTU KTU? 4Ӯ?Lԋ* ypǰu^o6 ~Tc׸TU@PF< 7V+.VvuX\5.8:_;n1;wHOTc#{%y`ueMn~Sb%;p.`3J/7x}p[ue"8"Z<0Z:C%ՙPN]h:RS똏X]MpJ4WН:I~ﮥ\׷(׆iZ$ bA]毿~9Mik<^\0s+'wy`}1{[S%юԸm|[1x-~wʝx0;͓l޸|w~BcwcoS.6U:_sGo6>"O]!ȃv, u?4;n>xfbf!dTUR:^hU~U?ogxwfe}qaS ~7߷̮\' q=\<ʽ|OGl{Yf.s[͏n|;v#Ķ 1I+bn\g.uy:-·́ _T+6m07?&WiSkN:l?s nkjō\Ev mvl3H>,ϭTuijia sbDMO `B8'BT VeP`prی7y;`a{/1~uoاn/o{ef4h8Јrc˵0ґ: [N0rx۱\aXp5:6jߚR>-њI:h-nBdpRbX?gf]W_EqkLx37O?v K_.X>q|AHLی/k|$;%_J۾E?ermauX6^X\v֠\.* @BN66g3I}ޜu'oIz?/8_=Z|_]t1Gd7}akˀd|QyM7ʣ* R.q]$%\JiXKj^~f~I^$cw;;,\P.XJuT QJ-~@:v[PXNh)9;#phsS.ZUU@P\uQTRٷ+"e @@-:SR:%FPTU4߃xUPTUA|a>4@,D cyt$vqz iDK ms#R'&8 XP]si|Z[luCPTU@PTU@PTU@PTU@PTU@rF>?+_GJ H 0ɪ(!o&󻝌/,\gxXhS.Ċa~߾߯ar7},uD]w#uk\ƶ Llwx;2 %[ frn~BUoL_[|X~x0\ª˗S1g ~O Cs!dۉls2 lwas.L ϑ(kR,PKKTjbƿ߼ɩr!H0\?.ok_π̾Rs 󈉍atdƛ[S+ڷ wkȇfp@ǹT)5[Ha|ubqB /X1w~ӚB_mُ #<48+(ñq\-ë`]H>Km;)h~abs׍%4qRum+mxva*P\650Sk ){^.~yKGA>5h*@[f} ph}T69m+F LIo7(9|tTgSWd{!0;_k[`361L?Ʀ[X?STU@PTT``ϱS.e +vӗNP ]*)-ɗ5ǥyQQcSTU@z-,;V?TU@PH%xU~(*U@PTU@PTU@X WnQO2kڜauX~~;$ U@PTPMvQ}3}`؅>>MnŰFJ)<Q)4,U@A~'jkץ@?x4GȮwM$d[DHPTU` Ek@IDAT~ٶgFa};u(%q5 %:* * WLK\* ?@j./0ڬ ?A)iU E"~7e?U@PTU`4 [|}n:V`<ʾ[}wqݕf4߬* * * fhY>'<}x`a~`xFc>yǣ)j̓ɰ:Obh*4`7N غ:laZ긤@&G`5U@PTU@p=*h*h 0p;мh%QS:o6U@PT9&T* SG^rɗx-<^q|υsڣ~[o5-aՠTU@PTU@PTU@PTU@PTU@PTU@PTU`+&Σ |%C{HirL$̀{ZlV@^P]U '3(W*څ1TXy}ۦr-NmCጞ]Kwu>c!v繷^rYCSC#i[uWa_@*il(R 8 &6gZ{gЉ=fNNk@v$$PblHJYX> T=ʼna`q,ω63~aK h {! u]>LO/_nSbߓޘOT?EXF'/bc֌N 3& &6'\F#L`bkaglHJ̘gx FBe1ctɵ18Кٗ „o)>0d˗5_V@3fZ[it^5ڃ90GJ꧿}t8e8J6SeKl$fs>:>Іa|)8$o!E S2ex[ R8׷vlpb:Sۙ]@Ç;^F?e9rB*G=lqFCp#m٢NlckC]ߐkW3WƴpSv &bW * 7ޔǧ8(S;Wu>*@~°|bb#z$$-h lq}m0_&{H(#_^c`I贿hD)3ZS$ݱ3fֆ1L֩yKG>.C%i 8P_ ATcrCoʵKv.s@O0\8.e4x02f̰xlZ08!TK}b4ìhVIC6ctԃAc\ ,P;bTQ%qrY[dcF9# &󥢺!c\k<6cEsh>;MRTU@PT*`OD7UU@PT*M}[#{ro$\RTU`)){⥊Ë!V5kQPT߷P-Zey25&d dw˟ۤi)x ^]?K_HCPTU@Ȫ@yb֝v *0ǹQ/5z)}]er9FYsMPTU`Wriܥ:XQlb DI6q]HأlRcXO1OJ*\!8lwʝ3.|~.N0K]X}1d6S* @TwBmJU@P@= )%Kj5XU@PTU@\ld0ʱeKU`/?v-X;鹿%/ [-k'岍T57cf /!v p7ojF D APTU` +#qAoeU@PF^w,@{P5A< \YTPP~З 8b Sqmc_$X\/# ؿb蝹 9x{=H%I{WH~$LNJ<6_r4MK?y[[k$C߹ͷ&Gh05U@PT%M?ZRTV@Vx!xj=+vkU~[cR?f4bb˅՗*0 >9ʣ;|}F¼߄}rlc}ǯg10bQo14U@L_sء:+U wKzxR㯻ٯtZ_D55?èA*0 'Nsٓ$yPKpc;F.~>|M䊭G'mƧjy:Z6fX^'uWR La$Wlpfbr(k f^0&8{<鯟QƘeDLl2&h3RR:挟!Ė:ra82Ȁ (W /~$WH^^ן3s33.qI.a8|v, r6V59XkQCPTU`wl1x.F:q(Ƹ`Ï/<9~?xS5r)1h \:+(0d>VU!mS"O G)0c+\8Fm0QE= hv?ǿʼnal͛cbclR~r/d*;$STVJC{q8YjOGwL9'9IK=>a|DVᑅXXkjs6#2LH ~mepu`5,hnEWƦEk%(zjJqvM_uS/@V6 "f-0`bmnCi`DR.隘ϨR}茲 ;u}*󮰣"?V_[prm^A 7FW]sH`sÙ2b\j-XYJ ,O!C cAz-V/ӆ~rz5)\8V7õ,-u]?Y-_e~pp"[L\X>N2ŗ:|_w0`Ѽ%HE8FjZ](LQˈ5{N8,7#$R8)O˲0SqKi`cDJ8/e~!**;ݱ}Ycf0Ai Lkfd Ė#٫}074,97 Ɨ?YGpظR89혩N/'Vҟ=7 %ס n÷t ʩC\899qsqOoqaVr R$ڱ.~}h#F M``BXw^.vF-))[kZPX%QB@տ2gHq.%6,5S$sffHL3l8oqJGpԋC{Jo\ۆ 6=Ocd KY([ˉ̺^ףfоhGLO"UYwE s-;O7iוǿ؛?v~Hﻧ9{{$ڣ7}BvmNTXB&.\1n$FƉuvd:Y8 呎-a'µo9/ w=\y۽ڻ >{sǵZ@y8.AWoS#Uݖ2:鸏6.{9CfY.К@hIqp5/ ˸f4#_NskVcd:fyy͊q0R+GWaP90Ĥ)/q͵> 1w-l}?e>3[\>i#)܄ʡ}ʗ L(&,\\sDQ.:Ⱥzjk>l]>ލ,~gf嶔FU{a79JܶAEM/g}@,VN69w8Q#e6evܢn_GFo[qܬ+diPW&qAM]b4-M҆cnIo5Sɟu6ve`m)[vDzI$Xj* ,'=uo3{}'K]KΟaI K#+N"\7:^bcumvPj`16n42|y0Ǹ5/\ -/157nl[[[?Ikct_<$5)KN .cv2xz`bݾkmc\yi ld5osڰ$&d~9aM[6ZzH%mnm;ǵﮛ#S]sXȎ[.q7ϥҒ>7!l{\o/9_lX3GEe'T0&'O]q9_sN q l|KC]Re/'{xw~Jnyjx3%/N|~8ԤTV}ص¸ /l\Zۚ_ZѪ*Uy/}V& @t߃f}ܭ7&cl,>KعRx$Ǿ| E+sEU ͆@#|q;̖qc6n6f^3;pcio*noе* W!{?71mևܖ4ًc{-kWqK=1m-rk{5|:|~?Hd 1уAa2o)A @ ؃oY&$9w޽>YiG>[_U@ }\B]߆ǴpOpmKt %:* 9cq}wp*tD^>vޛGWu\?$t "0a2aCdljǖI_=󭷚? kj =Dy6d0Nb lc fF6HL 1H${9unsϹH UKW5ڵk}]Dq`H}L䯘f>:hE>n;Rwu?p9[]tv:]sKScZ`hzT%% !Q94z#LSQ'>armɵS$׆e2uA$X,Ȑ{;T˵N==ւׇmxwߡBq@-?iYm79999i|)cH <ܸN.D9Ћ8d"IANu:eI+'D,׈q/ϒp`H(2DZk7H̺5!H!#r-Fd$H}){r44:\bF>:ÒOaD V/2MƻZvu(bC ?b$#']_!v߳Nf[Un &yd|rt:i0ȷ>PuS5444z&ӋTO35́O6fA\5c81fQO16t 3'$6 nM;#ԲiƢ998d~dYt5`|ypA-RqC˵n==A?Sٛ碦 `F.k%ɴdSgmհd?@au|1 Pfk$$ 97kڋlgߒF>%L8uOkr,85UL9)6_3Cs@s@s@s@s 8nBRs@s@s`eOW? 5JCחw.G*%@phȁ6tK/#§`l LԾ@ :1䚜eyƻXŻR˵4%9 {khmz~`vj@́.p@ B0|=3EfLo5e8۬@'q)2Вs'鋮+dsxp@r(W(! GY+|?~\hNSf}= rP3/^okg6D~|BJID1v;[/A͏ CQ.&D7Kۣdw<>|O.L[Ć f$ȍA|IQGO4^n,<{PU+]EFv^CMwK$Mj=nDl[]"͗._ߣm @#_0_8(?zWIք\IsU$zdͬ뙸 < 3@#f~[2Gj>RTB^&]kB_sȵ15~u}Ov~ <$' L7WoI^3HT6rUq-?cܷ?Hǭ^u])>% Ǘ+a'aU/W/>yKTa;ZwEfe_(iSȧtNzi0ȉ/D?":- DeMO٩:҇m\"^\@ER:9Ù}vnq z\F P?9yb5Q./꠰k}3^Am06zJwO?[7?,u7Ilc9ǿ f23HFYm4e|B\Ə Q -EUsvƹAu.gYg<8Qzƙn0v9w^{pvdF65vs;{L<'EVb1y1O.u9Ŕ1+Jw%iA[[|rѵ%.ޛ.$7*}~G _Tz8ngƽxQ/WRF!}WM\ @ɨdX8ܜXH2!W%(㓴K:O[ee!|mTHs@s@s9 _=\F999 `Vc&M!0uQ85z5X\3'\l}kA'@X Ѿ@o䀛F$S&\덏ԟ>0IQu4Ǐ TkkkM!pg\bJf\\eeǣWͳhĸWޕ6cթڀ߫&Ns@s@ss ;SI4I |J.bo{P9Ћ8ABk:TKMnMXWdXIݍ4kW5/t́^)ķ2噖ii4z,G!-kd4M+QG2θjΰZFc_M2l"щŵ=R OGgBZ ꗊ8p2䇒b45{|?,UfR%1h"Kib'* 5ŏK}T́[Á d0$oP]MlUǂN;́΁ 2"DuMFy핮AaUTXGN8GMgX,3w6999ps9kp)Gٗw)5>4t{l䙔k,g:s/2I\#*8SdZ~|8ߜ (3[-Ú6YuZšri5#+N-}O}mV7Ks@s@s@s@s@s@s@sbbĜM".hG[env@,84mV908 en1Li|rmu zqs)ԵEHYfu6!g7>?xo[V^2 #Wuɸn,^U|5d7RmU7Js@s@s@s@s@s@s@s̯;NÁz6}P ,CHPhySsK]"b|q=Fk<Z35hvɉDDxDβ^4{m2+4.2%^q 3Ͼī0QIXɃ r`|` 9 :Op@2!dOPpe`iu%tp O@AxE/~G@]|nD+Oj[҂} J '-tu;-GӴEN:B0PYYx, )@? 'Q3U_x+Qdx/(-AAtN'AAiRq LFRvރgw^FTвrAĠxd%j;?d9xJ8,I#tw[ / F&|ݫ>\oHo"tmW캝e#u3I C&HUAQdNetnlI9G-.wxթ R yv̳8g[WY '|AOTkO$-ҷ8 Z^ [uVOpntq©q5UqTzP%}'YUZp8M2]|p0Jl, vsHt+NElNԯ~oM7Ks@s@s@sYX|,FB)Pz;O+?]I,ctЎJjG˥^xHJ* זŊBu"K''m'u\DƃA6o=_ģ(+Dd#|ޏkceBSiHW4KVqb> lae&OΟǦ⮀(eߺ 'el{3 x[c]WcռQ@"Z?L?K\͑$];lLEbi8L$z~uԟ; m:#_^0M6/j*r0*+f#L4F',>.K8~IDmX|g ٽmo6"lN6ɳvmx Da_LA.ሃ6m;yx rv/,LCl PPLܴT, Ζ^zt@me/@ENo$"ov /jll꽍xi(4uaL:z Ƴy:Ckii;5QygAOgd)IaSVԧihuߝ7NzSYb[m`}%#Jkxt6h%%:As@s@sqi{%^}#}֫U4t^g;GNtoAʺTz9SaCYo@^ᅪ-(zAwrpd'N}OXaܥK#^Ē>* %\٪ .x:?= <$ X}_҂|SV860 BFyc(ɀ(FVՑ7}d&Jr/E?mWs)g;QNh=Y۰tQGGƺo7W YxGP>^cpoOHN6H1™$Æ)7%Ȁ_z<2:-gݣy N 05;wbG%"M,Q)a`wY0bM½PpoU~{E+k\ap11ycw{o @0)R'k HL7 E83oͻwcyksNM(-5hhh @9t;JE7~sj tq| 4f#>or:14[.IXY'quu4444xٶ3_ɘz/)vTjե:cz k{ag&"PhENl-m_"KLI"Y^f~z.-x|-u3#_qw߃Us'cw]|RO9XuKFg,Kh=Cu{9gll\DYfw Lf#Z'uNL0h6wW9(56|+ ,n*Ũ44zJ&]4^="WKnUsY-Ns@s`q b֛܅U`u>8&d.~n&^s`cZMYau:e\ӗF4SiSǾ}F^SӔ3jf'|6˰@--8NM@8úBǖok`|,dMv)#iy6gt;sl:::yE>J Y᩷QioùD]0?mt5U5JNi3]lvl~} >bqbXq _wGbYqYwwX/j*#UT?b'e%OH]Зxe ~xsP#%^vt&ec~w46|R5ELzv< Ga t=E4On\T O\C\= 隆+ؼ@5m/1 /4h*5K@Ǚia)X:͟JQz,8UP?$acHF_01jԣ#Azɣϛ9X9_UFuF_\u+md?mc[d15?Ɠtd9|.,FV{FR4du\Xu2K=ƆT[8iwՆ\<vBN}Y闎I%zUk@m|m(6Ȩ?<ǃOQw㕿݈1KPc*DGؗSa%܇i9t<ɼ/_G =TOz?GQǒ CNs?^[1ztӕ-GFфc(k>_ӻ9lضk%VVdx*nRKÎMIleIp/ҝ9T#QOS&qhXCy '?40Ak IsOMӦQ޻&#g;'ҩb((:WL 8?$ ^2~yI$CxZLCvv-͗hxq%w]0}$oHu46_SX]}(7q*kg$aSB+Sil8?T3QJ: 8 "Tsʊ|0(m?šsYx3ht*f,#Ew;HdЂ3"P}Vl?!!{>43Rx٩ɨ;{qOs&`:]# ]*sds)x~by4_:g[hr}ET}z?Jfj-(:G37j@9n{;g,_$h| k2Ӱ(d:fA}VjS4w&M"݃EߗXOc{¾+[w@7/B;oel;|k9Oٹk48N2t ]H^9`fPAT<K/%pHUϲ"#x|N:J&oDzlZJvO~НG2exq XHrЩsxq2G e^x"J=/- Kd$7^˯ }/3FG%*(O KgQ~i"iwᆭa' B}V/_cg3i_sq%T4E+1hJToA 7-$?:xF-XvxU8F  V|dk"Л&b0K" }e F`]UvXt]&ЫI=>ԛ]V#B%t~b$>!rԛvzǁgq:QsqwQJ5&d$sZO,qKxo4tr #B> \LO2,6ǥ4Jkyֺ xxѴ&x&o(J2ӳ:6}1鄤{>z o??n GFiȳЪ62ZG.GpԔr o\^Լy5GM<:iх踌w6'j: glh03Ȁ}& -1V9f(XʝeFVZԚݍwiMt CQYtq*ԍTefxJ~Br6"~)kv_d.1!E9F:?4e[Pa|Xo›8Oĺɣ{oä1PiUG[G ;s&cQ+ `C<'gFcчa""9Ki㰐`V- jon#,,+(V(j}M>oRYj"_5:9e$fZx$E!W}Y$Wj{Hћұy(V&SI`=ΙX%?/pu)XLK皨 &a37szC IoReY+(JzzeA%}//kʹz&I/z#7CkZor:Qs@s@s;f[b6%tp0=ĥc^ח\7E'[x&Y-fU1a'\?;~4#T+@;NOpU}D{ {Ūe T{-#6Ctb`cYT',)2t9}Esr*PV+e DoDx7C\Wfc(q1n0^٣V.xOkN5#blP@rҐm<߬8J&8l`+?KRET nGh/rX_eaWdN gPB,Vr+vl9Srg#,L a$l>&dK%N]Pur#In2Uu1Fɟ ߹aW`|hƬ9tCTӎ{x,;i3{tR24jSq R_^b^2Yd$O{=\3 @IDAT`k:"% ߌSQ܍ \zv.~>NgБRP8MXXEd2:48pClvxt](Gc^߁_2d|xNUOUXk3jȧs<ݎ:HY::v2\l^"-MtR--O{Rt˦)) z*e[dDwE(;Ji#<O/yM1ʘ^pFJ.֕IL ѣ>P^<.(`ν3>S,&PH3"NẂD OU ]R*aW`hD&V`^zJXnWҳ+Z*24ZoRe\#KW8 9o9f7C[Z`۰%+a+_ ( {yrsG)"}W;4. :W_M0dBk+ ʻMV{ = s-(o#_>t /˩AGM~h7D(}ey-Nijon<^Y'A -1Fs}\VϏ~WcyA!e)o#O+c8S^P0"Ȯ#Pwcmу$6>p }ll6kCKABٽL,;PW[o{n+>zlsT"c1XPc2-i8Grq|bttwjJ4 '<OiAw~%ݶ(n=h.-t\vC(7mز327*E1Ĵ +AUIʩ2\u^ܝ44B! e߅}9ExmPt k`ֽtEu,-gnϴTք0yE2m-z<%t~%=iᣳXNBr#:4M\QWCe;ڣ Xd K[j8>D#z0aqTQa:{xnQλ wFC}YX~G%7P/SlbfٝB%74Cu.=]U}82mXUݩF7uCU0Ǻ&GrN.g}^ŕjұzO2Bmg#H1/Xw$VYiQ<lol${4+:U8= h6 A&OQ-w ZHHzSPh*^|:K0}2?L\Bi5U BI[; ?sttQ0Y"1Tt"]ݱxE#'$܂5dL3/sfFoWuWT'c:GMTrЛ 'Ms@]P1o7e{IojVQ޴塋e >IqқvMrt5Ƒ贩DeЛjM7e77IoAW9$ʠ[b=Icn rRاk+OMzWNN)|Wē~x@4rj:&Ns6,2A :L41hŭ;+T2 #u gdGhi[IRv8Q&9:Lw%;q'^gLzυaٹAp} $9Q R;[uwv.wN<׏3Cw+Gw« t"{ɞ(^\DًhiM?kO4Ŝu>'1㰌HOcF1Q•44A P#W/ws3-YmifTUG[ϦX(x! 6V)6{ٷ`%O2PY BѽNP]'c/BR1Ѥ'EsIS>2"M:4lz _ËfɥJk3{qSiǪpt^(ufjZ4P}6w>C[PDswSm\?aBCQL6IG I9_<"oiÒ-G ^;}ow!-|Iw}<1e0 ҭ+ODORZ@gW̲)2הE4s䢉P>%<}wjQ1`M&@xo"?Icߒis,}2< nߖDhv\L`0$<Ѯ~碪Nx^fC~;pdtMG á7""\=O wc|^Ym۶g!U}U'ڰQi*зѾg<[m,iMz]ؾhͦE83 EV+/>5YV`˳s7ٛKYzM07:~r]oJ~PRSIowЛte'Yxa;o6̱n?M'HY@ 0^~ȟj}ApydiP"Ab4{ګ1.fNNR02Wb)rkGHq縥yuv6745쉓t[Չ?/h2 i<)ò_% t6K1. oNe_'|zp' eE"gq3_xZ(j@Mtkhhhhs/BYblj9^5mGd1;kXH?ӕgbw=-wlWoD]uur=L,}X8)K&$U!]D>y &2uIk6KbqNk6 ( /M頉lҢBFӡdr{#nC>(^9~6滳i2? ډxmjcp2+4]|WQ j1|/\dDZ5AW65V #?WXxya8 }Sd\mJmnAd!kR[r5)9Q8fgZdeWw0+>;>ça<H'c4 ]?u]ތ53p:M8֘{ QAl0Г ڛ;~MU-AC]dC%wVDa"R}`;'΢[5E_NЂz:6ʻF։ tyWTyl{N`v́2Jbշ+)w.g1#/ +_ĸS6X]'Pҝ: q7]񞁎 axqhRJ\LWւx?c!~#0?HwQX|vvC;ZװtJZm|/nv3X?`E*k^{xr% 4 h0t>8dsQP*OG研TE1Ot:Bl1KBxX%,t'G,Ch9s/c#tTsD:xOJ Fܬ(/#GM,I[S!O"a[td4>5e*֞ 7i_m8]S'jiQimƕMU2r˘gx4&jiG#sE6 W% \}7*bn&C)ltYx~Wkؼ'4xN\?ŹveH:~t0E]+> <$lj!Y]s MUP<~K ׄK]'2^‘ؤckcr.(ƀd&0s\icՉ@||m.;_F l8)Θ?y-BpSkB<ʵ4]PVZnK*ajv)ڮ@PZ0~yhhּvিd@\4;7pyJWj>w 5zy$?<Pr,zޔEzSHo֛I[E$>NNs ҧT㴳O&[K@հKq<[,#ੜK|w+ygJIjXi\0NYus4444?ʟ~3y_Ě=6)gaW&D':na]+'[sgc)+m8z2r d֕ONQ.Ɔ2;] .܎kt0ZV(QqG;/Q8Ĩ[EQ49Q7|Fmd̐Q9mʧ Bnr)'}E\8A7hϪXg;9X7/zb@wdƷ qji8*@p"l8QAx@G?w)v!l`P_Hs}ۥ(;/kvU4]Di}4=O-WErɀ\Tqխ*Ԗ.2k`Un߶LB:.`QuNBQr ;dezgԘg0),+y2(E}n6́6/~t~Fvt {0id{QR%<1K.i< YdĿ4lHGsl1 K 3ɀ/nNMKemn9r {62J٨掰MpFn:"jdVx(]KPl[ob';V }E4ټ ,ݿjŽGT}GջOB8>r Wqd[ش/. B|cA73-ɀoד vws;a'h9qAn|"*B#2<2Q`\+,pȁ8 Yl+yovg#7\Y0L?O6 lr:,T^JSwNxgkqsH+ĊuY#/[Fd+f]mb9?Cze㻺D-#>a"V͙ytl$)x~q<$TP{ _۫ӂ܆=+qt>jw֜)*"E[_466LIIJ;*hN똓3.he eRuGm]U'.;hB".8]N#cn(p+FQF|L2孔5MG\EX}m^6nD*2ރtY3x[w]ԕJRصDnRu_ޤ|S]֛ZZ|tXdZ^^MGHo:Mi,c7OobNP*3{@OV}f4խ߹ ZzO?YPM\˼[46Y[Ys5s~f a7ӏҴ=Ĺ΁5:6%,c؎|n3.mcOrD'=5 m2Ҕ ]:2Dѝڼ|[vU%嘋a\2^:3K@`wQ:y($UtTAh{ 셆cDZmuTq{=~/lxOG͊ɛI;PM@S@e8i6˟:`|wxW6FM E* //YiUx>$/vMHM/=kߤ]:ޣ}ʝ]- uX~w/D%(i,܆#uM+=m{e2 hQyG3_N=qc:̝`=kKo9v+{[c+ȏӮ12.Og*xj`+*6=( [VG~󡭽1:)4LǪ1OŶb$k}"2`*5`IT<\mZHf-H̳f՟Mm/qUgȨ NW4Žɝ6(>6iS@!rs wj+#E`_yJFڬ X7+ |G%+(+/p& lcSmA"҇W-MM>J㣮Et{PA'u®YXɇƫQ4d;aBAީF&N TQӋޅlK{ݡQsx:G)Kwl(xV-C)l+4 M<+SdjLڹ.+'/>D TOj0Nf3DzStD-r&%?$޻lciU@o:Л)6ds"*UU79ʨ7X^HS3KzF(9#:[T3tXs8a'^r\r<%2rS,򗬤9˩|„:6_ zAC?NW"_Пh*_4i=SKlc:M=wy7&hŠ*a2 l'xE4#<0Fb,Mhp^r#FEߛ?CrYcƣqzJPF zcG{P-7 ;NOKCx2+Pi+ux 5ڍ!X;rҭh燃dR)`({a1 9MVهxVv2^xP=6kLAEcvTX0gk9"L8R|B,6Gm~w]*`$Uڎk#~ӆ";g˱XcFr3zaw&7J|mz|jw_JGꇩG+;k[zI!]!v|+wPn0dhGݾ}wv4 (~;o\sx_~-jfiݑ5}u!5dM\ǦІF`OBK:brSFaӛOi(h$a7FhSSJ;R_zcb}Sǡd8 n[:c(ףK$+Ne KE(e(MH6'#h9U]t4L92 @NT.߁d5`q@ԁm5_pI}ճP$w'GGFhJ6X1陇a̯(cـ/@rrڗ2rUTxDzKIj訑>d7!gاj8rDĖ+hhOB(e(4&]]W|zKXkx$l~.'y0ҩe%KOW:!t:A~Z{F~#:h_oNi9DBqSj fEcCooCՅ2Fc,7}³q3l"kc$JTfzSЛÒ&v7YQz,|1>h=Á-7XwiϴsX-=rqV2G o3': נ) %9w+z `siF!Hd$1_š^Z},_jV}OА4߽}NmbYƫb\21+~gU٠FFsx}fdI+2 P j}1"V٦ Gx4c-gYpEi eN'st5n,uy]nKP0ahww1PFcQ<1f">5E YÄQ.{2|5cviҌ[@աNF3YN%=>ߟYnu#*bp/=.p%KÓf2]Mb~`ߏ)F+J ¯s]~'J ʼnߏs8CHܨ[yyK܂f&}t/IoͼYnD`] 7:\ :=u{mm&^*[_C3b܍`/!:OWsmXhiloxnk 'G6 oف& AwAѫ"7g~G4V#ZiEF+µI i΢)]wj3}ѿITQϕkKPRUojS PX4::Pw\m^Q <8?󧖵.OF|>lsSR`$^|/]^x})F|~^O;]pKS#VXY%L3r2ǡKPX}\I??9 :DV?vg{YF+m v]TA!Iz؋΁ɕюal"C?B+}vv~FO03޵Kޥ 6OA' 㬽T[w >HQ=ǁm%.?X.>t5t}q,xn`(-YB~(hOT[\!xmy*1 ezDStV@Gӎ{9$iH]i=saŞ&-t+Fe_0vߛMO#bf.&8u'Ϣ&FwJtBLE>RVIb|F?bxx8XڨmeX':|`agݨ:EWs2Bfu)uD.Z_%U$T*kaOim;1dh5Fk}#vAhJҘf;,_Ok3]F%U#LWf},-\Anl;UB<.in?>+sBSSaPDZW8)s`cl]J DAʀ>e9T;z뷾%[IRA ?K T~7}Kc˿F1Ʊl $k-r=DJ]yq)cyexI]՛g"ä7`7\Ϋϫ6Ү]Vkm 2Bt4q+}iZ_X!>h1L+7D{)M)l8'S䧐Ͽ.|#OK"t #$"}QX9ne,+}NWa֏ FMs 4发˰e >8440n{e*KJO&˸3&E 98gUlpj!G}j 󇂯3F[>%xu9i Yƭ^~NgA Κ}*LbR*t&V^ɗY<| )|$L nsA;o0kI#<$t%*GVJBfsT:DقڙbO?iɨ;J$Jz[X5W*Q+)s锁aVrj1:c(y2@s:rЌEx0r OPYk1XvMO?b>b=K[$._ɠO*K;G!c!73G":f eɈ)T.6 Tq͘0纐BrUQQx+J?(&(5ucGKwV'iԹٷ>Vo^)t>G៷$ 8dϙwk oRdP>fX=s.8$}Q!xKefOE=F:b%ToWX݌ɶĠBY(z2B#6~30!K7⫫ضNm4ǔ먧EY4i}CAWѴ<"?]n_DS#ov"V" $tR7Sd=؊O&@(@oL5zR d˵Y]GI^?c_UK04MA $;Fz7d{8֣}Z߽LƉYSHzS;.=GoSY6Jp Df2M"qw(8̲}S4stθ-]F8dTW%5MK"g=:sхJH$DFJhId+lDZ^c'|~:~7KK|]%Y EZT!H 5{9sf=``͇Y3DZJ7 J/m4͜hqF纞eFz籕hf"H@i2(獄̹\s*u<>ˍ%}bmfN4j \.l:L_bmSƦmYhq=Ӡ9 [LlL}5}J'X&9B4nL\ u}.tUyH`w9 Z4L=ކVQh<7+òF*v)l3iXOF%&b4 V(L8S:rOg[ xNV99 +H?aFn5i..~!оO7lsQ ]0:gAqsq9qvf6fXw[[N~;qr$eOa:]0r{Lzh'vL 3ɿL>Rn%P*\rT *9M𱠾ǜUrT|nD u,X :$92%ꃙ$ S/}XhS')Nz'O /A~esC%}pI!\a\;"\"`̥}% L08,,S>~+AXh{R:I^>s},=NF|4mxӸ,o,KA|^r?~#ӘWM}z]`;eޘf,vJOLZi_  PP-wU+8ԟ=ojr,Yץ{}.aZn\o7?\[Vzmit[A C QvA`!@6=$@.sl\BCx.2(nmsKSYY92IhLx#h<6}2K{J'"1'^>iģ'rN -cޜo,}r)@wP$ 8?Tg~ ~vߊwf_o.0g;' /4bX4fW O,~_I#:}E*=qѱhuE "sRMcp;m"f}ԓ:: 9>R=3$O>,"t,<6<']NO KA@)W>٭U-50of)ӛ: 7x ڧ\aA@(83ca7aBWغ@IDATW)~@>f"Pt aȾO.~DRbz\)F\EuN֋IԆRxzqcQ௩7 _݌bǐ`Î*vL"l:^feI˺86βf[ oyL03xu)K@R! G/6   @np.[s[`E}Ny =X Z9kB0<78g:4_xP;97dZ9|627^w|KeLtP;`Q%EÒDgX'3|dq9vrm8q[A@A@A@A@A@P` L{PB<׹s:]q@9x-rc57Ι׬3]q# |9mjNkxg0dMom􉮺tPqi'[ח = fFC£mʜy駋9Z:.n4g%i2&\pLɱ}u}/D8>i .)c"[RL<\W,.$: Fa؇St蛓5&>-dN 5œU.}sN"ϡsQ&kNug!GT|S2L%[W-ʇxbT87Хo.z\xpbS~D {#FT\r`qB}7B c'nϔͭkDHoިXeP JFuxb"aգ[|r϶əm<,Ϲ.Ư\dZ=vm.\E.R,=wu"mLn5$x|ɵLx9Lď c n\ˁLD2Avb O X}>t/)[ MqQj|¾?C 8{}wq)~eb(׎Ql ,29s’|s٥.8RtqMs䘏܉GX'Cv]珋m:T|!rc8s U\ӣWקrW"~-cpeȎ1|o.Q#E*>n4J@7eJI"$,S̢(ۓ˾EXku<[GLʞKU/28d;'[9CMUGϾ7b*bX_,clN3Ĕ&DVu>bal- !2 I=![.He GM3#qI 컛G+x;%%bIa3*;n0p5帡%\xQ IX1,| #H|B޼`=YEԆ9񡞀rjS>:0IOGܴpd>H)4-~jeL?Y`{&Mcb|?{hDRA@A@A@A1ObF* oVOНX QA W{:QX߷a|?iя>Cz?#y]f;h-Z&mC>ђ~␊BA@A@A@AG 쁘$ d@$楫LlME^ LQA NV b~C(_S<{,A>'y؉m9Եw۱WE<<t\ kqN2}.S7u=L4g 3wJA@A@A@ lhR;C]iy"4U+5at)^?Mqw* #HG |d 0?[J T?1#!+&_6F@`mz!`:A6 7d:3Ul_ϩaz3@%_+A@A@A`0F wl,BsD ohzaHZk L]\mye~j։I Ѫ6W~0SXz4Ua\ѝ|JZ"Ɔ[;/NLuQˬ7,gYn7Lw3wX$ 0   !=0Ӓ5"xO˩!A@!wsLA@'8iD*u<9FNE? SE| ޏ:R}-eLPݏSYs2iZyYFrƎ? 0 9顲2 [:}ۣo(YiE@    %C,Ո  D i!B4  3Ա Z7M4Z._52T)0`=SviUП`,XcWI:K<64 E%gɼ0I^Q:L2qS?u2tl%s"ګ;,a> ~ƖJORcR?CTƕUCLu]VYo:e(%h;NxȄ~bsEMFKRZοP Qk%gkG6p1?̷bSY톐ur-bjvuӊԜx'Na$teF5Բ£M:l26^ܹ˩ojNKJtmqNn XPѯ*&.3]IZ짵LQ,<]E&].-=)$`gRrKʹf͵|6&EKL-\\O]v@A}乬91XRLs tq&`hIx * X .cFbI[Rc$kRR>ꉝ#8'bN}#F9]b_4-}$9u JZ:8T`gtvBLBK,'2rGCgG=l[L}57K--o1#^6} rlˆR$474^pN_/m=)Ł~Ň(1PƂؖ ropHS, =dYpʧI2X=%9U6l4֓*YͦWط M. he 5M[| h6XGX 2 :\neD>_D鴈!SgCJd0S귍*N$=S#4\ڋqy擃8Nv[ۼv;+s_OaٽDr>Z椓\"+GI6&6Zx DV[Mj]o cWqsP:9kʢ.".}sa7ͮ'3LKrOiq85|?r%ŃZR%Ÿ_6>,:nxVRYT2n.F IGuc3Yl :ABThhSepam\P;fB͌RR,/93U}nE9̛=z vy_xC&=A@IC H4İB/e 4q M )_2ta䒺 T*jfE`paS4ͩcQ- 0K9 b0,Y8˻ƫXEb_z2cXHIG@ݶ˽{ FIsRܯZYACB&-|c%RԐa}˙i(eMi[~   FsR&LC@?"@_a`}>$kV=}JǞR?_ A@@p%5`W͆󫡵n~85Roe}Gk`nWx'ymtO3?@$DjN3Y ;ukc;{9?]l$ #,J{,HA@BmI 4WOS lי6~s`/'ƃ^wIl}gqؘ k/Ofd|.|+KDv=M>ݼu~>~I%U.bܻ'hnޮ:hh9^o ,D/ 16J/@~y~/K{L9$,\ssy=ܴfsJ{fWkV#y4݃ݧPϐJ.Xh/EG:O7ZXy-䒹p8e94, =pc\][pG~0]&|-_]^9iTSb.<qKBD^@_t>w\|lMi˶s߼۳PQ3 qyω\f(jݗ}PFԮ׹t=7ǃxM:b?Ηeoy?8rp4aբNA@HE`P/Rɪv'1p=|n5H+W*Rdԙjݽ?7ŧPz$[`~|gm?p$ C;Gt.[5B vȝ| oz wMaщtCuy,4SYOIcz?Mvb?9 *DT-l '_. 0^[`sc كەmZՆ_/w}#qO3~eKq~Fim+Fjհi8L] e(Ða<[wfকKgqtXӨ߾뷁%.E9[kW@ҥ-r [KWWKv\o&\:*D9<җ2Mc6@փ_UP ϗxv1  p WLyn[Pm_c?} _|&ǽPX vCzQ e{=:wZe FϠN_TyCejzMӨϲ} aNiV_~Nծ'_2wΪ5χٸR/OT4^aMO6GFK5XWZ3ˆ܎}q}~]b/)]g>:w߷w*ͭ"9N|ɚ8gì/|3u~j|;ᾎ鮷< OsS)V3oŕ1Z Z[~5KQT>",IYnXD6V? #]f[^jvIAcKc&if|Y4`㚘q6wǔ*ȅm"uϒ'S3ڊUonkz4L쥰T 9ʗ#̤OT\Զq>/ z)| ׷Kozu0~go8]V ll؄mw\ǥ8M02`n/>OZ 4߸~T/s>oύ-߲r h~ Ƃퟸ& },?>w7вeP|~GE;^'(Mp< K~,3@sgY$l -J)x~qzx%+g>4V?xʛC{'ROKA0Ƒܘܖroi9>>|Rg˽6 |vQC2>FkߍdvI;˴*N8C[cxހ 06))ll'ř02)mjƛr+QDquRwI*֖9eIMzx,6RU Py\04_$xqd& Krm+aQ1-^5PaPjBJǕf6W¼~B_N+a`;%Xݿ61]u*X7㹺_mX e0pJkag-{ǔ:(Sn~vI?0W@'? }8]2+ZN woS= 'wcr TrM7¼ۡtFz'8>=aobӻb}G:/^tTC.LJaVS9tpxÿ6ocL6zOb 㜜-8G$xw@m/ȹZ/r}%W}lWWڼvkoŗ,C '[MjͅI|0 ]?t. %®Rw;?,Bەo1_{y) x _:}L⟈|)t=W`U7c/B4q'[JP mKK!&`Ca؜|EEEfHvM/rܦөl#9Q9ir:ߧԑF"2ېlMdüf '[Ic޼ /ΩbZ6a41c}Q%meK!’9ۏ *)4 /D?Fy5wTe#~(jf̳'[Hglt[e\`ZqqGEU.|o)S8ݮ؎CCK5 Ad{fj>u)lԾӧCPίp[`OӗC~/*6]L'hF=8K)sM+> {w4;KaLbK?_ҖEV.~]r hsA`2Z>c"ިs-pOlj (,Yݵ 1W_zGrB9.mׄ_b 9ǺЌgG`+%ސע V4-x;{Ʀ] Ozz2כݰ@̞?64T7_O e4Ue"Dt61$Ls՛MFϮ|o6pe} ΝZ @ 2oz/G7FD;بꜫX;3JkRR]8$Q[dhN9'XrdrB+5qz)l :f0xtlR~E$R?LF@) heحt\bYWkY+0B,Z̆尘>1<ȫt/ATגIqi\s<.~'e|Bɫ}rޘ׉!NQ-,k w3ph/ͫҳݺ a&j_~y Ct *Vz: +CyJhݸr#̹x# ,u[U@y$QfW¬sat)?Ӹ?cPҴ0Nx:eуwhRňG0 #PfZϞƠx0f腃l0T- m^xFojGJKu@_b *w)|(tY+Z0xO~ C1?y硧jpѵPqnw=8ǯ*l+o;*5Bgn>}%E督0<. Cû{8>(X>R@9T.[3^XQaɆS ]ԭnUq0S?aew|?p~:0m=h,|_qiTs@c+g; .\K4{V*~\ l%lhT͇W@{Wᇺߍ{̾PҰǡo+ݡqjsRShJO qL:cSlD9?D&]_xY\|r27G{F2++EՆ-旕ʐ:#TiD6):չSm$C06Na /?x$ű/ҶEЌ/mKwƀ8m _~ ޹m7CB=TĴs_]Z 9=$'wKӂﱛ2,+ B|jYH{௎xbU˗*IćY׭nO^UɿiN B> g/aשuD P(ky ōuKjS:ན}P9 _;s175y B%[x Q=\ +@'#v-Q y rnWۡu\>ԇ`P6`BI3\Y 0}`' úx+^ ;/A}<| :hZAW{W{VÂV^N+^ `?0Û^X.UZ/Y[j>>avc6[ǺzbAEXװi`:Aю=CzNlyAeJ>տ*wsi퇷tjk ' 4)+4‚kgX?#6G"ʡ&oO}k 7?ef<МUT_75Bי|_qSSTy|zz,-Gpˏ?4 }_ u7l ΥF T,=pTܖz|C:O@m] +xUһ/'C]+o*͎)][:yNP,'Rs@,]K*c&op2e⃮Mh8P1(A  !5A@ GX[J``h6zEE>6-Q2T O8: cPvx~|s` ^|q^\_oz˽yC40~Tvw,A'ѺJ{u'ו55WNc0=,ƃo{5F#ׅk>jŴ6b'1Bk ]=!9t; 9rJCsx#" A@G fv~4.Z6E)Tʎ Vr)\/ޱ x{ r"p{py2E_ҏJ\WL7bS+_E~UT{X:{<)= .gC:tǨ)12.:[CS[}\+b=g؆?F썸FVS?CɁh٫]SuCUm+8k`ulku9~Z 'O™7_;\1y2SHdzx46>X]]XCΕ$t@@g H/t:CpCa*8PX^X/] kA|XW/ ;`ǻIp;.ǿWG qν,tΪLw ca> 2b BT7^NžGp g/$~k'STW@ _dCzz:/1+r|KpO ) JaWK䔂_VSe$Ͻ>:+ڱړ~Wrڨ5)3ُuPNg S3Ƭ\8h2f;ՙlzb_L^a&_uu8>3@ |&͂ @BW{'{Bl,-g{W/Uհ aiMD wLN\Mo;E7|ӜʟVqɷ.|/<3X~-{BXՀ `ME{ ʧ1GÞiƋ@psQsw3\*q*Gޅk[`l|Y(^Wx t| .Kvl)߃S^  Ej Acj$\__#>(/|+gӃ ëߓ"LxӄR% 8j{P-b:=qP[oy7 ^Լ_O%"W%ƩUH?~pd?Xrc%i&}aI:PW#֋ ZC>aח{XZ_7ͷmW<ޙT>ofjY!ؔc]Ej5%9=x}DהEԷ'{G#}q8-FGfE{ e_KpFcpH)7y9)?y *Xs~x񩢒wBe桃v3J$E[ڮ詍x8Ma^MybyI̶Xkg8g>iA@F wNsxne|r76wF<،5~'}08سgåf,n<f`a/KZ^~uZXq>xV΁OZxk ˠtUuK(hy^1UR ֛3ӴL#E0Eu}2XPЗg(Um“,F$ @V,S\\ݶ +y#k1QriiyKfv)@arolAv ˃bB=~5FwNѹ ކe0s!.83~kv%Jf_,n5CzT/,ZawMb`%_]}ҜƦSy՗B/- k$y_@5;H]5\¿0nfҿ7ۢӱ~',WXw~y^hL[0|DH!iX]8s^UoS9K#Ե3ȡGeP{?/l/_D_WHǫE* wøS:s_ }cӮ٨*'`6`3j4 Mp\A9d~ǽŸPjbF^z gtE~0д)=ڎ>|~wadTu*3s[N#$c]f66\A@&Vw\5`C] <|<Z`C#r v¿n ’Kۛ xʫj` y~94o6ljйvwKPn&~_ $ I~5p@IDATAw*h^sK~,._Kf-vێ]w6Ug&x7>{.? {1edO[Pݶ:UorX7ǴR A`PX|7f뫟7,uBEM=ܾN1[*_>Qo}_Ҳkĝ`|}?fnLuB_ctg _/ kA klLeSEf}#ŕG~Ґ$_|ԝǠv\e/kᵌM# {b OV@^(7îg ޣPz᭰ *>d:|zًJV^+,A(=Qň7W%t+t9 Sk U^sG3P[F.~g\u|W{@^Dޱ52wW"0V>~-xjI3s͡C).oa},YMX AUUrXr98?kТ~wN;E6X4Ӽywvm轪*0 iyL^{8Soq|aeja֜A8\H-#WB%Z`%km.,;r!m6GZz 2 Ќ>n7Acѯw+~JPSLtЫgC[2/dI9--9Ͽ˯P+ loO;>?O.[9aiF&S_xğ ony_ztou5#F8s~BR(ΝQ_y?$Z0*w:~CBw A 1no_q,[NQ4;|gV_iW]oYɓx*`W_jwcjKGvv̓O](.a/;2'tBuu 'kߢòJ=GϜyIqP0[ OvC|Nuy\>VCPIO¹iԸa`}`?vxc7g4B}G>}>Y73<hXcݍX. -98GTh)(2λ?yl6FO%h P9G_xuAͅ ĥ點ْ 1)+u/]3/Z,: m> ݣ8OQ'~=(ȝP2*W-L)@v.U/+NFA:5?*K1.Z~x w8)Qv1~_OprU :<ަӈ'jy3-O,g։nك| Ha#]4[iF9иTt4ΙT둆׾g^>< tp<Ã7H+6(U^RLa6. $٢’fޔIc@ߴ|K\JmX\)3h."ϤթG[116'?!]4cߦ ) j\NQ':DۗХ_f۷7F\L'lݗ^j|Ǜ@ׯMk[ WQK e4]X-`~-9Muh[-:yC;>dѫSIB EOs$PDNXz#\lM\.މץo3läuW>]EƣѮ[h 붇upj(/?wvX6z_G0e36#SC 2dMzRcgڒB/YbqSq~kxAǷrp\>uk𸆲IDrzS9` .o\ /[c?yq o&U3䴎_S\rRX)S=lT0:ѺexLYqmEBbRb\[pYƤZhPY10'Zʹxƾ&Xт}ʎ2|tI3@4Q}r]%t|pkZ|l{GZ|b䑩Xx~>\ĭx7!M?F4zYk sJ>G6Nd3:/ә99z۳M:$[<4//KM[ َ6nļ 1 #qS:z6|ffFtY:mי|[9m:$L31؍Q ӓ"KB"=LSKc"w\{`ٍ0 Bi4Bdsh3[SGqjw+E}Cŏ:م~,,~\aZ^tԥe͎ٔq=w2%OEڜxz1|1_1ܓ<;wc&Yc'C`a="X= (ٷo@0 23˥~| a(>4a߽+O$fV9=?i=Tث]'S57oĀ2^Ҟ>ləm~boɿK䣑KcЕd#g]sU֧ٱu/TM,S$&'X'. NG{}$ `G4^Qhct !3|촌OF|׀4zB:2Q-$RUs<)J| *;D6pډA/ [OApc< $KoJ6~'?T6?2S TD<ˏpg"udQ##fn>\}q3] ^Sr?fm|I?`=?Ӹ{fayazwW1Tq\}ԲǍ^Je`(G~D@LMI3^HI9{^딐&qR<t@D'D:cme0ܮ1iT'9[.CtM7Y6}1l6I՟~tI Oy=qGC7)Ֆ^G}墤= :ӯ?#!d;&%VTL4+\ESRx׼/rn  P@lN%\ #7&2{)}2F2HJ9ݠmF>91.sCҥ6SJ){$sU4fͬ,ӨtS6pHbYb`rY&Ha{W OwA`!')+ 0ߺ!MğNƀW!%ׅ4N})Eͫ-N”<#x?m3҈;s[3IF`.Or|1*ŏp{ 1cQrhӼVJ0:-RSP_'_vAZ>L *{N:T较ev&+/l߬t.9I0Bʹb"1z!}rFH?#Y0 h;a ]A@=0ܿO.K#8=i94/3J7V,_'g\>RO_7,|O˻/h5.R!RGL+`;MT9Kݜ~/@T4d* R|']jT@=%uN%&S{OՉFeJe$9)FG:ua|~m65q$>(l>l&NC!Td2MÖS'xN{*2A`ϋiLfNt׋wO{I9@:.RbɇJ>p|Jrұ븖O/ +r_#_Q'%I z̮LTe }q/)S6Ѓn~3/2\8p鱵ː?&<=n9sL|FHQP;r6g8EYQL}pխ8ʒ1'WI2V0tAUw\(;:ݙ4)Qu/ӊB %Nr|l\:o c]tl .'~Kɼ JcI踓Nc6ao6ɳ<.*+|L}oMn x@׍[ʮ|Xxb\9 tA,_eS^V 6dNtiq3OI=GFLKZ:B@.6)JєK4{/x֓龳4%SmLsˋKg.,"p^ڹ'Q(Ǘ4.ZBӱ#SxIo-81N\$q_xsn~rbtp]uߞXCuйU-DkwIl}Qx?:_k'>t4/>(k7DPhO Kf;u9˗s+.Z=|Ex:XU_ OnS6 ~dp=Ssc_ȭTI3;/%s'bC`o}7A|9Nex!uW.xث堸repmڮ5s܎0Ԃ܁lG_dKVX0^x;˜&swH,$=}$ gPv,MmS9J.ϲ9ˇSDZOꘐ:&6LGY!㛝)!%OI0 q ܻ|kݹK`/:Q-^j1lܞ<-gif9%4{gL2ؑePf޿yl팳P<hM oJuO&u s{ipsux?u _x1yV¼ D)  <9h~5K|p?YU_j{`7湥p}=U_Un&pVg}nn@5M;*&DMFyyY/ɗeth2cb4b&1W\@z7}}SϽ6~}zzιuꩪSiXQZHL߶,Kbf doXl9fY?Vu%lx|N|jxΊfРy/n^g.Am0z={z55dMCpUAM4.krEH2x(Ek?*Ch83r6Rc䛽ctY* X=ml$`=_K?#<@TuBB]uhSX~tT5egKG]L&ã.j&l!B^^W_ >wBG$c)S$MLi#ƨƴ!Q[7c32$fb^ЃĩH.KXGiztg`Kؐgv-0Gʊ0\u KTc#OΫXr+hTTbFԴWԺ2wpAeA]X*W*BK[J;ȼ%|ƶ6]-l h'.s5eA>عOڅh>ր'_Zz"Buck6b{Y2|̋9<;߽k%VE躬ƒ-o 9|5n)ǥsT_Y8WV}15 dn镝x9iBX;} Vn܈I'9%}c߱N`9~yc1BspoY!e'ν'4~3eGG[٫9sn dz;wt# ۑekX Dv^62'10YnddoęjeO+fVW[%O'O X#i:miė2rj[kWF_Q[Cl n TjRy%x(76 罣 {?9JE޽ZæZw_Ὠ<ۂe滠HᙌMt6;OTqs"ݯ{GWhh7^+)^+ۆ~EAxA={ͽkv졝{;:gV|  u 1?2_`qո::=}U7ͭ']OE[N! }u]Cp ϧ].l }OȔ$ҎCtdG ZmEaؼ2g="đN;R[Q=2tbT[^J., \ ykV8ن3Y|^/*ƏfܙI^tvډW>滾~;>WHi-GԐf"_\p6D2=X1g><#zȍY+9K{.6ta тeN Xhf3, Wb 2ħkrO6I?{i7"c8nw ,s6t0 $f .&ENCYwp=#t!{r 3f &ݤog-V GUW"&bGNX0W0HjqMiOPkk+_%*t# SueB5PmrއlzNU$Jʰ"␍ wt ڎU\Fpo "Kzt;Agc+u QzEy O|ATE W"z fN~X#mT#S `lRHqpދ>Gz 1+u=8յUb p_5s4YM,vh,S%Y^-iwnxx+w d/*Ytf Bmqޚ쑏l  |_}{ibxI)yfG'8w?ىJGo܁yFO\ <]oo[QGb1mp. "E(Oʶ]7[`^@_W:ػm0MS~g}$ Ƿ.H̒Foh {^yv~zʣzڴ gߖVl^'H,TOj9^!wh7^;94M [x Z s(O`i lZx؈0xﭸ/b8sJa4iFUl0BJ8͋Bo!C@\t3Ӿ '|i4.B]W&i?#Mm8؆&:V1!10vru NOZ@+8CG6+>2R0-e` ]铵oA?#/^$fKOctfѧx]J#;5pFdFp]A;́!91:񬀏F'V^E?ŹhKHǝ2 Zel%]ˠ 9*='ttOV+G"4YA4!z;TwS\(Zл7tY1%p4TM}>CIW_FRAWg)%mJ@"Vo?Ё+e*^H]#sGO;h>C(=8^:)"b#'䫧4]9t9#' %Fx}.һ-}H{#vH:,DasyO> ~ֶ鲃#i\ ;9qNic,Q$\NY$םN*Ɵ ~ӬNSBlw$v!'xˤun%#KTn~+c4*4 *m$UL'ƇctR{$Pm̓{eVҍ{/ T]t0xkΤe*x1K*{K.f0?NixnK .e rPF7aI͙1)xxqMDwFR3zhbGGXbAs13G*OGEQVW0.CQgZ?$TszbG17L'e9$ZJ4׹OM(J&|2-Ⱐǹ6rRwMf*.+uu=N%YX8p;YF;go+A\@;?^U ѧ"Fq Hz=I!eBsbgk2 rpi~<ڗ}p4՛HY3va%üB/ :H:-%̄>X_qn(~cASzF{#'q dM~ߝ"oR>Ll\e>XHY.1 ڑMC?uG0K>>&\<Bhi/cXF'pq,~>G $lHEWx+NӢ:ymЂxG#-稫|P)i =O"jT\E4z&?릛cze<]RY">Gsٜ|e+rȁ/'h0;?<>Qw;щ/_KaqV*֬jكؔۏX0[Y`ׯ1[`ѯmf^-*,YyTdAsPK1ù$|g8}\z+[xl#/g5u"~c4%-<%O_&F/^G;;A|Ji,'#YmZ縀X6]2 Cyw>Ǽ{6a\Ho@!aP?g_ `)*NƯf.5_jju+l~>5c0> g#lejetl^Rh:t[]s~c5`&~SƝS (>oVz)&eV/.PzR G߱twSh(yȣjNḽ멈r;#5ىDrG!}~Bt$Ǯ=1 Ƅ%B:Gcׁغ3 8u肎Η'u@S| U$#=RW݌u>Ϣa t'>Q"Z 鴼U @◔8_Yȉ&KZ?D+819Hxast΁gZj75kM4 3(Jz.Nֻ#,55 <aZu=I"ss&5kr,9}Dk™_^fV,/' gx)}Gbg>8FףM~ }k]oiWB ?OW^t7F.\u96,61#+5go f/gMB~p9$OQB>F6HPA RQ_uNP~*?Kw"|Y"#Gt2ħJN%PKOB ^7ǁ^Sԙjz,ݲ<ϱ\^cs.-0W-௱kLh a$^f`wg31?]7m̳\#LT2U2; Ꮼ@XK@IDAT_Ll -`[; T\ ǣM"Iy~_v)Oo]MZ<d૿ErQZކ>!шPI:,6:FuCגh@~V RIg?X: ܈qN<1pN=wFq^ᡷy)nI_|2@\"}o!NpIH}aN3G?*ywBsB, -xeE`sPrZ`[]9`YknԡigKxx?"q4Brݕ t4M8;t:Bϗ|TEkGfsM9'Ƿ\X/~ډx}T"מ@>9m klh55{ԶL,sb^IIxj<~hONڝVq$F)d^9Ikzyπ4v(a-p0ǧa]1c#3hw9I/ی2]#v ͆5ߢ4KH{&A&n?C;WЋGclu*HE߂Mp{ntf*‡P}:E٤FtlCb$w %m}ZSq&tb]u9JG7!xFs}dLJd^=ī90\ ڄs=>'U'F MYRa\t"Tw,7gi}2)&/ExO##Gtb|MFxJ,-v "͑Q-!j:,";[G>vBFЇƨ;*'>Gp Fϥ!|Uϰl i Oğk偮<6U{72oS˭dJ/u" h&[Il ڇ{:*[ 9\r}77p{[`sVMxyV] Ӄ-LlWˈr5@:b1 qC;qW%)(//xjzmԧx++hQA2*Ry ;Eנ"+ɹa;x#wg/yt}a/\+2XY^slf!7tc Ys:5>Ml@V,-iBtJ6-@tzI8u /[ /|]}?i;T\C xͷ=[9%SH?>s$4C3<E@")EǻN |gݤlsڊ|*l 2bк~lx:R_fՓ{v19E3iyi# }l v-Є?$*Ħd#Uxhl/$C& ]='X{v7<!#;9~<[[oDZ.qrnr}lDdV6.j cmh.;9av2܏$Z@9sn 28LBF1}=#4q6OuqRS\F4ܑfU2讵k^#=sFMmė{ ǻ\:Bϰ(:M!Sw [V p 509^H ~p!`E27Oa)1k=7g{Mp"$-;pچi•qj83^<+*79 Y2‡p c7Al$>8oU3_X;@ M4G4kۊ,+hX_]П5CW0ߓY; 99&i4ԟoTe3Z}s7Jȏ0 z'Gm둕 VQb <8\>ml=`<8iѭCOfmA67`㧎?|]{xs/Es"P_sZ#ЉZRmUpU ̿NTz&4/ذ.iKA",+yG Iss IrBwCCLiX < [8'tIG [k r'ST FѩM!&0HnB~Y<~ @mJmM+;x'I!щj:+t"9bA>2|]3sSr~Vb{_Z(]Di5Np~r$/U !Jl +a;|;y*܊f6.eZI?4I9.y]q3~,sәzK\86S] )W;Ha oY&c1K>..Os)2Ñ0E'w'[K2oeTbRS۴̂mT^R7<.7.i2p`jY%LǗ.W\8Ɯ,cƱ̫1y8ȴp㘥=dWl -`[`,P}ܹB xBSl]txlJ q[d:q1A]"{ޒ>;e[ -Cv2rOcLaxf:9Y] 4_^Uz^ KGeQV gow$`R@_wYޙaޱ;,{M|una [_(!/^8^lBek [qE#,vLґub(58$k2u]%rrbXOXue9^u0OM FF8S(F3{@lH:_#[Kzlf$Sq(.loS}Ρ|h-:ww'S[ІJ#:f`nĂ6ȶ@`Zf *z穓rS2;ܵx\-/Ã[R]s^͝󛠯~t,`;-F-`[ms<2LiLbm \}V.Adx=wb4zyq?j8{U_׊UYeƅĬ"ZDjݹSs͸F=8|);& АjևUy]2|D4mfMg0f0_M7Q+ :Z!8.:ȎC,%W&F~_b+861#=4Œu2#PcƘwLj Tz#Z&ӌ3Y.eYYo#xƽ^f0OYbG+|<_r0Vtr^Q \:BO:`ՎVdJL؝ 'h7~`LvOfz[#_fGşj_}TofNX9@P!SYPˌE/6.AtxpN =R[!5l[{+E6Arv*yr˒ ir$,vnV5SXs>1gD$?Au=/g*z Rzw.k"xQ $DzE5+@FM07s@qe!T\| +w/L"[l3g#y՚@jo d!_QBIYL.O ShP"L~#d,NT ,+4*7xb?8ƒđyXH7nU7*熁+uLlyw223FJ.4ʔ 7i4c]'w-= Bcx٢iyIBY.T]ZFNiJn3bAyA& KucK#d ɚ ƾl[d3hi"1}}g3xk4MfDAa3iB݆5Tm^S^ljQcKd^.2@=S^.c#I~22MMA^7ml -0 M26m|h\зcS <줶g D2PchUnNR :OC+˧Ut0oݿrW<6a3@}%.ɬ4ajsMnc9Mdkh[m`{~h>"=KVq-m6T1cIV(hKc^eϴFzJ+Ac;lm -`[eI `Pva]@j?~)m#Nj;Cie2(K T^9@Jݪ́iW[?.ϤSEbN/O SΞnkO˳HX)6Z4炧Ybq]!l \l.Ff} #{dR-5D?l0)'㸗CE3>mn\jl -`[`NX͉+t{e!VϞ3wIv:>WI \| "HM^@' CA:twf{v5yIX_SuWk po}V3hߔY:haЀc(l -`[`,`V͕jd_}Cl 5=a95.ފ^Ymp5ȼH|!2V}lTJl -`[ -`63}E  F{WuJ2Rqev"vy'OcZ@$y93J:gfm@&} X!weIx3I XMDH-h<7!@ni0h:ޠ38b??&b2AڸwVhd0 [. 6-ylW=ۓ\o?^_aDzr WaVҲ>2B8䆶շ-`[m,Xaf13v6m-oW.CrAo]Ĝ$HqC8KIO+b;),zΰύźfX~_)n1y 'R@ߓT k=?؟l^l -00n59YOvWc6YTt6E{\nE'$f&\\ ̖-`[ܷT~oub͘'LX \bMwZtsZ 8yc(esO)t2i ñÍkWͶml -`[ |Jɇ!%7sq䀉K۩@2ZO:v-X2@7{[]D<9H_\kIv-`[mh|w D3:,0_XY55mP5('nCgrvK\ؒt!^i=v89Ŕϝn)c*16yQOI`F<x]ܥLɸEs[O6I<',SVX[>^bE.Фi\g{>vt7ՐWp)'0?%=U.CVo=yVgiRO2[RbddlU)f۪b $W\dʤV1E;Ț .˳o]o| v0}~Jf\$}'sưᲕ);/n#d\ q?഼T뤦$.-X㍇(ׄf$ঋ,QRrl4*|P2`y/YiFN򗬤lh|wZ@ =xϵ`nKN,y ȼЃʍf<Y4$`A|rd(ZëWogZn >T4xI:DƢyB[v1):{]t-~κa.zld6"2 ;|f(RW\'hxA T< {*"O!g}}1W5-щ %}HS#3Sk .]?'؄:^f 1Bg>*l%dV;* Jdd& f^o%1p<?:tTr`n:"+㒊y7^$n)A|tQ4 y(kV!!-RB(^55y]+ЙHzw&*z\vP5l`)+[&"mF_DhȚ:4P IYe^p#LXJXʓf20( (^SieSM+(>BJTm?n2. -Q*e{ʰSp,-l{v VӜ>Lll -0hGecO7xpπK`E8Rmai}Rhk?~;FRs]},ŏo7]9zuҊ} 0Z(%[J>ct4׎Θ<[M60C e>[`j*I! rsYN3D_"=u8~|c%(zlkFHfH:AJ/JEL`3H8ǺZqQ #K+Btl ,`w=kG:&.ӒN8=xY%/d'/ ps}/Vz~9NpǎaIqEVtK<˭2P$~@Z:+0>>]@FR >vt\~/v!=g@&41ty`N98QR:h_'X& :»G8w4<:>_Ctv|~hKKRj .՛p|4-0 HG$y\GgǼK^Gu%L igGXAUe/t˾VҫpNjZd^Y25I>2o: =:#^Os1a丏@dl"HrG,视r ?ɔc#ɓ`[mfxu_ Ex(OzVCxYZaokO'~y}'hxڕ vȻG\u8y7EmJFq 0(<㑣Nn܄ͨzs 'cף"-ru#5?Gņc8zygكi2"Fn(Y(߿kw:>A+܀bן^u+qKM ?xCT2Sc_nCFDiGO?Bu+(_9w=Ho܈!+x(_<qZᾊO|PY`aJh/"}-$ ˠpO>S5=ؚ4QC]9K(NmX-\=h-l{Jމst?p{ЮBĥoR9'rDO?ϡN*4?.hT3_~mƘ3*j_rJzZ`4pIٰ9˳'qw-=?:,DlI10D]y=e] o@oGC-O %%gÑÒE0؝Cɏ_Asuԇc{CGK'\X;u31UӜ7p,(WcEO-LvL'f|Qۊ4LCPSƐ>D?Fm8BO RG0%Ւ3RO=ynْv-`[m3bՉx JἯk#8Pׅ^97$>~upǞ#gPy~q~P,e~idǁg^mV>Kq9Cu] *6`g1H [M+Pqeئmq5:T6u-W>n9TC'}'o(Zri) ]"8)J˛y?Fz"~ͥؾH6.hܼyp;zD=*ȶi9ɻjb@(QaT_dzB'ƁSsZ}zU?gI?oT}+y?:ʓ d_]wl*۰ 쫮*aR܌TΈG[&,5+Udo-fzhp MO"k$≖J@Laz2 tذ ͋qWUFIf?~m#& 94XOF[B;\0@ϧ7 b=GǷ}{0i ^t.nBx?D 95h; L8 h;Z 啢h]*B0$._p-CB=:$gpޏh :[p`lX;,붍y?F}P24 gɴK5܈z䕱+yDqһ]қewSS(-LPŐ~Hج]|. nsnQжmIY)9xZI3y'b*ݳ|19-Tz68sug-Wyg8vH;%vvSZ=ZKc}W#26y66/qeM[G/ۇb:/;ŧBi~(BEG8! c0)K8)967\m_)C)BVH2o֎gd!;-`[m>ڣX}_89I%++{'ݨǽM(O6B{ZX;pZ}3nɌI.I}رclߔNbvs7]mdI=AY%xipiFJ]09f&-_;ׁAzQVw`ҮM$ĩbi DKҗV,0) P (p5/.7m`A1w n0hNgZhۍ!,Ncrv,Tmivխi(]xISʎ>ɘQn\Ua C|I{E˒0| UH>e7ld;6ӕ|u8q }Quݛ#P\wvCܹ5@K7k|㒪AEFs]4׺ҫrAڭD/,ÒoZvζ-.uip%<#vKHcHӼ}~c)pqu@_ܟhR=trFhڑB1Wad>!4DCC7 cܱm4g i3Sx`_A,'}T٥x(OFd}WJd88:R?-|hInɊ>#=|bJDٶ lv-m -p&<//Bu}#^~"tE^hnѝԺ;i4ő&Ug]<6!;yh{qc=r ?4vt?yOĥiHN%Q|\/9pρk#%\oxzL`BJr7M4`QH߼IqE>^ K(Y1#܉9ViIArioNJ]s_%hcf\{{y?615(WІ BG d6@Xඥ98Q_u]^jE=]pFf9(5NoLq5(t }viU3|>/VQ1tH3 L"-Z{L%Sڶ Vuhr}Qmcuw _ u}U/ruw롭Gi&$!R4 )ǁ}Uwb_\o-]?BQW>mUwk|aG/ yP;099m(G_4+R[7؆_ruWCך\$ѮomHG.uNi:I`)$!mAou 8ې%gNJ=tzfm3e9t3iۙN])nsKu:&1:星xv;ujoG|k$'o ?Ok%aUE# ?DÎ% )O19ms28jZI]o3Mwp!)Xv aTyND}LGEG =&i'Dڙϋ3xa #:ɱC P[gFi^O8`7beJ"#Y&ʹĠ@{޽eut+a/S>׍Qλ:*l+IDZPYӌOd,et5K1q9t r8`krydݓM/ T[%ڀM%Oݫ'L#6n-Aro@@ޅ6? U /NJ,maTu@rb蠁R@,u*XқW>ku 2rl)m'Kw:7jd" _87V&8AʺˑVK;~fe:'CDwd4E!jeILV{s$w ~*d,)@v3p}hKh)(E$"~IJsQ+u:IPT5gl Tǘ;bKq;!LONG|6qs};i=;t:r=%yLaށObh2Al#t/yYpq 0UYLz 8{,8vߓ>ϧO $D!6YqHE*mL?DayEO7yl4lSas,m[59&c|J^F`@trJU>ܡpNs.V))*Gx;Y°`#QO x`:mhEe+8f2 3\78f2f E'QS䮑 S̈́Zkt/l+մds5,!>0/^b@/ pwNJT9"~M>g#; WY(J!>lZ5ONKg>P Ggxz'x"O$#yH1w~"1)lC-{ZǺwGvԛ.e2 (oO[xEϥ]FΨSս+OMO|Gt22Op2bwdVdX`ю>fr+8j'rx@f8vSY#XǙ;8;wSt9f'CqFaE1pZ8_;ۍذa!)A&h^Qϯ'{9k<~LmB Q̂QGƑ0ˌ܆ѷd%GovyG@9{JYxS /سg{ B(&jj/>V%gUMnѶc+/%kr,ןo[@&eΖ,D vIFE4a*O%+[Ũxccyc 3ww12&s;]TXĮaXzUm&s{҄38E$GѴ4ͽJ;1E>[K ىkh5r b'Ec>Bx߆9z'~Ȥ`"G (B#&5CΨ#.iYI/s4Z LTʚ7? Ϥ (}N:)y߶.> DS;MT?QEcOJ !,Ns,SHʺ \.&k(a,KJgS,8葖#/̓t\ (Zkl^z&9#h24>,It}>Ng͌ȈF2k(aگ=raCp8Em ޼7E,(P\|Ծ:L2d.GFsڡDs/=r$\ckrno\wxAv~BPuPӒ֌RhxySѤxȭ乥 3_|X]gͼ0f*i7'>r#βFD:s A &"vU澿pvaAQ<1]yEXEmrNts_s=p5 7‘bvAr<&,?Iiq(N߾cpօt2{<"23̏v(_iM艡Rãock"_ ,DeKb ' w᱓X"$gƁφ`Q㸞!gv'cG#D~s4Frn7`Aa' Bg_Iܻyhvx*.MGō_ӈO::I=1+79wTnV*XefKOz*.]i1ΏKb9u5GD|&v9o]k*v tZ,^g`p29;t&^R߁ S:/&[񣿚8 }U,]zXyonjG}35=@IDATݰ%ݔ>‡M['Өร5MM#~ | }[}lNiEOW<9_B{0-/Yn+(ϵTi,M T+ }zfz-A$}V7YX. _yCǺf>0zH (4)Hjibj^u0Iz>W",+ =H@'n$=u |fkt;&|]+,҇мi䘏L$6Ʋ6cHַbÁpr [;ٌVg#9or߉yO]#Hf!ZDsoB1-4XrChM@?BRA9 mk㑐JcxpUҠ225ϛI\%Ji7<ZFaXofj;L GO0wKkGiiJ!S )-xx7_MsSwMeDߵ%؟뮇sCڶ|J3bB dz^?gVqd ,τ˘?!) IV2-cc^l YajaB)pQ.jWhF+A2ɁAɌD\t4bigT衾66D-F6CedZqU#EiG8w)r3)uPӒa3xNIzI8T:5-yLlgA4L΋%8M|JSu@,XȁK Kh^ aHԏԏDjdxn6Q8#G0ڽϬYBhinoROa+};7bl -0y8rjONv onţ9|=(O{^xɚ,K-Ke;NOI3ل8!@HG)M)-׏kQH_R @lbNx<ɲ5W{ѾG{|m]gI^^{s9k}&|U|;#H?+-yeL,E f >wݦbhŭec%h[V?T~ꝘP*WƦ)Wd[핲8X{tL|w]'޵YP̼ I*&?Aih闚r^Ǐ<)%Fn..yr⸒J󸬽++bXp} *2yaûe;JݢjoȖ]FuJdCzrےMG'w`n'#j0&lyJaٱUnNJ>p8M[V$Jy7\tY8sL%_~hI7 bc􌬣۹ LYӐq4D>/\Xa=`x@Ay ؝?S,T~B޳Ce2J*9x<_wI9\Π җd 3`HG%ۥuJW\†%f=MrG; űm?(+Lv:NtHQm-iSZ;`!TV#^;(=^3 /8ߺy @<07s ޑUHs+Q: qT;y3a6Sh+(Igh|굎^#LOfXy^^r2Y7N2NleWAآmZcS7*B"vL/,b JDж+Km~)f ٜ_s 4{mlۼy_vϼUr,Ucltd<^Z֔(2oeNtE~J^8={cU X`S08nU\_tSǷcdM<hl_^qL"kuqS2'*NS)̮?~ࢱ ap0^Xqff/,?= ٞY2BX{FAteKF ٮ0lQgohqXVeJfSxD?l7 Ut凡'MDF/Hnj]V]}/mr89sdcT4潼DEvorq~xv*~WoKe!eU-V$ {jzm{Qu xS2DҸU#5ղbX>xFrfKB{ՏֻqYm4bكn%Tm\Zl{4E KѦ6֐ئK[zu5dք5"5X{\/S4FV_zמQ#-O㡨Ě׸fnB`z}Kܫ;б5:4vfj0gr|I>aV0J?b|Ht{۫sǓsg(;/ s_,z59f9SrdU?{oHsG֏ һ&-Pt± K^I !!LJ (K'՜{ȹɰ3Wwk(g0]kdտs^ùos>9q^||u<5y~wh[u.HIk}KN&FɫEz r/+Eqڎ~(fsOy K$kQf~H0 6L0(-{&ԅ/3(_DAY3].Ij+kE<1σx^ϙo}m$ L5|CϣLGlm|%J6f!4^U.]Fuzyp5/zgpTmg/ e̽i wmͶ-kh:GxgP]gL93e^W;|lR}rWH&c]19v|2㊺mi G<[c?)˖guat(m4LJ !hBTs>¤v6WeC;'X?Ը:Lwd/x(F~tW\-6e[xS?>C낯VS ʫڒFiǚzNs8d?b3͑V݋pA㚫#'XAl?"~ռ:k=i`mQ>Dz).PSa\[W*ӽ^ >#>shQfzb_aڇ=%|@_41zяmS*a:zX[® !?FG>eP4`|2~ɔDԛQ["D<hGZ~O=:GV"XM%Z;tI<y Mر.`qҿ59q4$R}f53o;vfr2݇s7gZ <ކVdyYg`LﳮܠTcy^ ~jlWp&8HoHc}Lo6;ՙa^kEq>i5c['0ƮJ!rdCXc8&v>158Hk9LZ8-d:Ъdi2ҭGRͫlnFiͣu6.HMC>Sf;}Ov"m:m<\JWiҌ$(C$$L -H]4u;h䤊d!^7#}^_Vs2F;@ʰ~a>^}~9W#S1~ii7'ॷ&Y> Oy @@|fS@ç'vɝ;W2jy$,@ :{pvX`8*NܸQz`:jUΤ"68=<|=c;ѷ!y,x=Mxbf.^Avz m11i ڱ "&dԖw-BO9wÄ2Edzg<tږLoPG.u&YҩsKfP2BʙFBM`X24?>?\}V΅T}K^8?;ly,k{ 9:oC?_rr8/]ּFK7k :@$٩8|m`l<&q|V3T.m~fE> @7168KE<y @"D-_49Θogh{s>?` w x8#a4#+ߌzj#d5,ӉWDlȆs~#8=Y{{z1VfcLW "x*o\/S>dk^e$v -O铥A:|@IlZkJc x&Q~9.8(B@x}>VU8+Mkxxl߃}Vuw@ٷ2̊pDM; 2fm3S3@BSxe*!kWu+ۯxMNSꔆi*SO qxjC9?Dr`GsA} ({,X~5 fgi/LWCm4v@iliYƦqQ9dz͙jkMv2>U}=9ƴsau;ch9eit?#;}u:H:mX>6بc =|Pӂg.%{&>E4A$q-W vy4>\X|V--*poSb| },/LcZY8r9cch/K9N˕Uk~n\c&eA&9xYyeXdr/L?gc2bTGҌ-c$}k^}6Qf]9Ɵ|{4SnL01t}{CCXAk3G#&fU˦30zu(*ГƁ0>RMx˶ N/Ui7fF\jTB6(w:R/C&Mh''Nq=̳^<xM;K|c+9q_k>Vy')}LQ4͒1U v Mx+K-+7 K3e't T г=!)0!#~aKvtj~,O TAOA6} s[|`)=yޠ-qO7{@K`ʞ>V٪S-*-S ޲]7|X;Tv(zK00e6 KaVwd3cOuX&J3²κr~l^;?ϮL#o-- M o}$3?yvUk/屍+FUX!,w! Jj#fiy0lPZDcMœ^ՇvQ$i}>lAy6r͡e+ A3BAlvN.PK۔N3%2"˜agt6Ϲ̧8օ;ޒܩhF2sIunۤ4HXt[]}. ^O':a1-SB42# "9}O¶ݦ]y;,nwR;0=^Ɨcq CCڊԦIzC(\@i4'bMefQܺxqԧұγ@c:s!(aӕ߮,wpv{HvIccٖcMϦz9$YV< *〻wbtcP|-xG[aiA ,n4c 7 c5eR/z k4p<0xyStFWyad+_JAdS)P٦8U-ɶ]_~@s>` OPN; sa1>v4W{6&#ؓQ"D<y @"x j{<8}{Yl~$x`ݼs(׏zZHlBy϶>W>p"D<y015c@ARs" )p,5HLf$ȆUc;tXvs(#$v-kjK<޼cvqg 2V A9DD- r\S -kJ;yMSK5:/uO:㐥nÀG< 0~ `>AЋc{pl:*csIh0div.xTu%ÑT;˗Ưtif\~/8Ճ10n88%?Xx eK^:~'f#fD<y @&I׸sנ|܀[Ywjں41I8N8n0V5; 蓌4NJ>?8{Sy"s8St}zLJQZDZC ҩ$L$ԨI"D<y @ [E|iy`M4{f6%!`z`Ϧͭq w&m/M؆HԖgy4ׄylx)vɦ~o|uS.Fy @x L]3{rDբsT-# (&hVu3owR&^kg-kIYef9 @]l<o5`t&uL,U}J)uFmyϽs vxYͦAp <_.YEBڍq' 3pcG3@TC] -%E`e_8&4ȄM|*=FX2SfwK([F ;>SM]N>&TapF d c'!Ζ˲ym$بY"D<y @  E|2ʮ W[Oy|NkYehd̙y8!.Voq @"uqYk`XOyܛ:$6$omVے<  U6ȳ t3`RAc{(IJkk":D/l3?XoCo_>^o<թmLMq,cא #|@D`UpC0:XZ]r72Q6(@A̚ɏ BCad#m;1ekS@ + ?\߰-ٺBuH@~eBeƟF[9zةv0OqZVJc'G.@"D<0q=Yasi{ oC&xY#mӐяg`ɺy<$\Y*9a2ҥc;JE:Ny{:uǻ?D<y|@+T9yf Xf0+x :Cж w#ZD4b`j*l G#Fm h0 +k g}t(8-'2o{$ LiJxSۗpRymҏslf5To@+ȫ|xp7!\09A װbktSj,nQ '(CSRzM}ƈmkYS69۩e~W.S$qzx" ڢQW6|1%KYfySćSL(?i6jX"$zF鶵R^/ˉUVyTvmQ6@䁱z`r=J>>y= 0+zA DtJʕ^\zUyXb}Teov"kR˺r?"<< 箦vyGcͩv|jpt)˕]|߱~%$EfS+#xgjǣ[ʞsf>L;g @Q "?^0JfnBvjor@ޱ/4)KO/ӒЕˍ{ryr 6Kfvc C ÄqL f\XӍxy?[Gpy7^)u1 a4TI$Y{Yxe2}fU\*?'=6ٲE2D sBZR**?n3Ӂ[1asȣ<׶ 9x Sg'N-6yy2p̟V KH*# +]J[NuuˮL@oޑM(]ۀ3暲eP GN4MoOSo=~`&H ԛ7DBTma0VLeJ?0.lg492 9ÃV?A>!Öwu2G?IC$T CGFؼkDѼæj?jJ:9'}D"wln>SLMyt!eY1 (UyJ`@q0=Oѣ-ޝf ֽ6s@ C\}yAxS3 \&3 RBug7c6o':dqx6&-6oB~O1I MfI 3&t$0uSzާyk_L~Pn{^ֳ@~v}||E+MQJ[iy"p%qW_:$Zk +^.W~2?j|d_sʣ^! .D^X-Y%_~_>ٲ 7F D ktNl=[ܰ.72l=YlĘqV,AڋqSQc@1x?)moS2}r)]!sn]''#pBP)95-D&i~Kh"j{DrgPwIHۮLzYQf3x@|'fS4,4He~N~Ǥ%da YPZ,pS{a.%[ Ms2]*5嚒Dϝ)ɸeC e[mئIȻRF2[423`f8b%@|A|x88e*NtiExe.} ؜ ~> =8-x%.dLfLV}Sqze1KJildtUXQa:|ER-i3GVt>)\Ae ;O W.Xl:RGhnu5RS+4H|A'LYxp|/f$~X[bJ wyDe /gJRٸL eAUCm VfϖҰ_Q=y_^׿o5뇠g1}S R2N aPVX(M>4,k2ǶOmZ[%d[^˃U{֔ʦ+xs6Nm~F}Ap)R^j>h g+Τqr|}0vP.m&kYOÌv 9c5R==>ތ)it_#wAd:yd.YSNƜnmv);2C-~e?^\*[HFW]q-|^#a2S}&^K:/*|X{g/\n'659ZxNN:s-o?_)SUI̮!ӽ'nECOgsN""BV`H{3E(EpiJ$Srj2xbTÖ Y~LM(:/aEkۯ%P~5R&8%ڑ[?'~Rq!%2WBNL- !'4I] :zPCdk3XPx7/`?a e#b2=/_M+%dBS#SH l͑RBLi̛X/eBy_6V?L3ÇĀj6W7rKOq-Ϧ<'$(⼩ʣ7dwL6KoF]pvK4|~"d5gxΡ%Mfa;|*D ϐ#|#z{|7F962sJf]V8*=ux뉣8~1@}-Z:`aO|``{T5q;bp :rE9 tWIIdtQIyvt+2e9!04Vuqs'mE <y ƫ/_x/.HAnly]]-KEPo#X$uerKo\&|h47sumi~-ŹgAa|3:< |~yFq:~Hnʟ^e&`|o/am?*wՋ|k妺"W` y|@75KsYT4=k/nZ G^I:­er=[]˗?ZV8f4/wri>>w]*=F e,w&.{Rk6vr)#&܈՞{KRwCP|_\VnR*ͫ\/7UF5ܱڰNjKVߞOhETH^RWٺG6-AEx{|E>i8W 9(ٳ}>->Nr_&_%Sw&Oom\R'?к1m>z|yx|6:{c -:ϮIߚ ʦt9^<]eu*ZC\q̬qj_\_!5^#eU"뤯Mj*$aU|<& 6Hg{vv^~ߓ]}V*l'\GxsD'f]A%o?c7w X]?S.&a47e'd`F{}&mx#LH$=j52p3c$>)6(H >xP5H>/A4MYkW*(o<,ϼ."a_!;~2x >YA*Tq]ה#é#.A g^y#Τ{S'uRhÑ6ũoTO:ޏ+`{TA=(t6xeu48&ifE<y @y`܎Ń]CX<[nX>G&4,HKIioij+^\i8~BI͂R7Z 峿<6pPMmǻJ.)v7fU8c+2 /j.7ԕ3cL_vj͖bw9!@c7:%wNtdլy_Uu -3`%Va-$oBӗZt/u *fotBpcRDGv#{;˗VJ;RYFg自S)n|\!w<9e^)pCiTW'/OV:qjAq9'|k*V/_пtNRﳣ'%*d*,3wUwni9fYdfm~\ϪɉZ|rWGeuޓ1o6ycO׭ =S0 {oT6}oڼJJ/Ih$ K8>  ( E}^NdU.?ղ3X|􀿔 e]ϭ]$N?=S7q_jva]=rS6@lq˼hA,̕2?X~SgVH^Oj5e*0A;㎫hnHf,et jf,ڀCWɌD J^kځ6{ 67IQ3ȴRģ/y32 po;wLG0EL)﬊ウ!E`"x?(bEd w?[.Z']xs/4<Hɒj)[4<c'JNr 6˩ޱYfUmRRVGd"}yMynfpeQ Xep<ǞsM>oInLÎbxWN)Jf=,fրc`tQV vԓ?0]aGWMͻu[ 72on:Riy1=f ?(3Kl0Џ>A3jū-,S8f'e3lY2LvhI"EQmqD\45Ke'nmY>0A?M c&nsԺ"Dzm{yl lMr}cׁ7vȝ[r?'7q~y/H9@̪8QcA>Y/|GOKgK %kwW&q#[-p1kO[wteRƦ .3X}C~< f)s0@IDATQ-D߁x~i,PO}ħSJ`9x_ ׭|qFbrl' D6xx1H(om&~fTYV UӦ:D8C' Y¿{z,*g͔n(u3f1UZIGm^{AEςHBdC1ѲR=m) X&\YKAi}m2)v`VonE+Ke-#gͲrSϨ'ߐK]-ȑ_ZHw2 vhxƻ<&V3*GQi{-2  xoFcgL]`FYqm/Y&=ؗ|Q8/Rg}4>^v8Z"+>񎘜|0ڭO= #]"w-{S<*羈ƃ=n,fv&ؾ~ A\c8@%v ƚr:|MjZ9dL 8yAf_8y vCfWWy=Bܾ9ۧc= \+׋-t;A|);01Ā!ug^Sr"dvkؚ2ݫe#Dž V7 u6\$_-ƖX{]-a5M[=vs]~vκ:6lT_2nR,lbv qJP'?P!4q??[N1͏Jqr(߬xcHL>S {WZ-RϘCh%uT/a@iUWW(bl}/]MCw; v6]ՀO}&x/ȫMRZ,G-`(Trs0[bJtL/jj/>

I=PȜ:[)+|9&m7I;^v;Q; cu~Xoh&lC!^KLGnxdۇmWʛ -~g?7/@]>*~}s:)ݨTIc$i&V|腞 lnMsX'=yk 3=168~ k>ڶ2U˚{[F= >;mR~-NV3>lW^/ϯVG<y @s;d;܈vɁo&XǶ}+;7__m_:*ysnHmKgoOX嘹-e.inK6߂#G8h~2xldh፵6 {;͖ya2>t&le8(GϛO'2l|X^?/E~<@*P6bkZ$%'NH-'&ZLcW2cw|\۸OB&[$'/* #EHn[mr=">v|}ur#6jJ|=Lg,Yijw W`+ oZ':.,ٖ*p;m+kM޺=R6տ_W`wl,mSg Ʒ ;=m@jç]f~!˖^ Owv˵aɑOp_R8.ϙҳULݸ83xzm^05uk}2 WOʋHA")b\7cM}Rׯ\VU2r;(+l/qd|@Ͳ2l?+ xE>C!}H=OlORz")+iƟb+8 N_bX0HV|~<9mq p\%ebihNS  8@0070 7&3;PKA&II/#Gww9kj}Fe37ANʃxS@`cF(l:dJ@X yu^KЗcC|v;#YFzYN_;)Ѧq$#.~xf0v̟gyB16 ?H'X19m0|TʥV&Ə+Ohy[7vlyM<'+m%ϗy @qVr`]r-oԏ $ p4هǫV])7,O2H7-4wda{=5x}{Ts!&DF<.7^$Aي>^)TʦKEkھFgk6N{:pfr@usb]5.Wϝ^Lѹ\rDʿ|uybl0kEr#R5~? rоB EgGltlY8=LѾҏ5ū4I>|uI_];)j F[/vn_g%: O#>@P v}KjN;8bŕA\l{%;!S-i.[oH2櫯 йQ-۟@nZ"SE3m+b5;Z:Ns-@o+09#}^=}͓ށ{%íXen?ӆ"N!v 9Sz ބ6iiC^nm>*gpPۻ(r8_@+MO*x.LanƛRntyi:/ExBЇQZ3`W;c* ~c`;E,Q"3e~ a<.Zy0~T{vʎ`;Jk&j2PCMD,Qf@.36B\-CetZoXGdF1!-wq| }w*߶)x svYhhя]N{e 3?9~8[$GIґQ3"D<0<`+/6oYG;q681yl!]EerRC[yx`'+:0;9)~ @._>_*y2s~\Y5sDF,~|c? DDVo,"?LOȃd\f.l/OV1o@Z!*9{DilidvNz${]{~C_3W3 ml):"ZPk\4?8[O^ D|OOH\ 1!&2" !&# xuS75fFLHCH 2-8_O-˟=War3me?WJi'Wug|26sZ^ Pd$[4ʾE 1QZ)X$?U$mG;%l)xmDdJxzdz[>#ҫo^/3/`wŚ_˖lA^T ] M<3hZ.3++dgnM2efOBe>wXTza;x׼NO+YTqƽkCR;W/ \CLY)Xس- =+P!K>LE>l(y @{<~Qqaɕk~eJb!(frk*c#D/ Xf &éSGuJkl& 4[\W87ywFS/23GzxMaPf͸C2ޤ(j FO e$$5v6>(o^ &LCZ7(fuff-?χו;o>￙>wS_\)8"<y @*A$1DV]BPżhJۧ{~cFM?lomً MWs4(rΜ %ss 6">90@ 4lm:2z]RrӵrÂjHp8>s3!pHV"(iܿg|fY)d*iR#M;/W>ZV/2v #|}H]la]|@.ɹ;rWrRh~]uJh؆%?b+-|hhlJjܴBU)g4N9%oUn!|LW:й,pK~Z*>LV_TVS=~dSŽ,4M_{A%Jna^x C8| ?claP{ =rAZwS=;r@@_~>upoH2:$,A#遪i?;Te[[x )NZ+?_v'鲾FY¶ߒvUlQD ah;Vfyg,dZETo[d\7 0(}ۥ3PѺHr%V*do- KJ)fMr ~M >uLG*dWܿ5I>&‘shA%&1،>jvE'asW!ܿc 4G$4ɲm{5ϔxDiUͦ08۹@PG8eחv7R$kp2PE=ɲXl:YFj,Ҳ FݍxUW0VYc`u*#AYk'lv;O&~X. {7mFe_]ke3vzlC/OdE}+ui!o;n0mlmC#r//"@-_wؗW9";3rLD('}l{@gNO;W6.5퍷i/>imĈߘ6bҔO\xr&'? ܃?UMH^G`]0flU9 eRl'uֹ~}[o̭[HQlP\xq\>&lߺ䭝_=#4ݯv`B 9xhtUŻȒY-X_9I1 ; ?ܾμ3? >j]*%QܞB Þ]>QaO`ͬS\ƌ){#Efl^繴j}Qi5#[7M9y_+$Ϝb$! y|5O]o/"AV|q;vQa{{FsL;GeJ 1auv܁᳧֧$r jw$^+}vOI\#+7U po"}w;g紕),WT=f1t z]A6*mA)MДyЃg:v2!=G1fy?b&E#5c|>$3$ikHФl3yT0S,Cz/Vˣ;utgeҡ`^8}ȢgSAZʀasd @DZEFCj+22Gl8&0a\Lɺe>Ve(^~Aiq+lwm_NS,~-L#%"DeݥXJa,T6$*{߳AJ>uTjGt.&,#jg|s$o9ϏX 53pìg`4c *_yU.O:OeΦQtS -kmC^JNXTrlݚTynqw-'~$ FVSl`ŗJ6yN1g20Y3AƍS!+c3o*VD]@)rs$AFc.çübzж)6۴vKRW@EQ-Wc1SC9Q:;Ry @eUR3+3ypS _87{馴8NgbH,@=Pg y'w,6F_"w'wm^{Q3mzKɞ2d<{gBֈeS +"29-'l|\7\]⑃[\{兽 Fo;zTUp s lh l ;z̜;VIo " 'LF0fV:!s/*dEvܙ,'9'k> Al!mcm'p⬹|e '/"*W@ejOY]GZ8VP:?KUM8?T8A뽩˶yIq^>$0gqAf- jsdH3&<6F).b ڈ=15G6z:nQfLXY||}.7 Sslm<-)>fHU;Ү8>=*d*hGѯVQZ7u*HQ+#D<0Gɦ]*ϿflU.]FAY;\n]Yȿ@ Nwcl빅~v`bz6)eQ)w|nܽ]xNKEϟ>.+RYn-FΖd##m"+;MNėfĽmxSS]?h xAiY4HߡziWjE {tıRi4FF0f|ea8'`g@RJ2L:lool^<#8ĊS*bYj!cګTĶ SCR]Zy\y_uyoAk J~|2:*5ŒDVijgR D,<|@|I è_~ht|4[dw;w< =Q&ɱ#ъp0rЄr)xL1x3+D I}ahS:IqO Lv j+S=[y*^i(;ESzwzK6xOxC`Ty~S&qםq$HA@Hd)ɤ-Q%K$۔HQĖ^ʱ|ʼnכxo8+˱->uQIx8רiC`#ջUM_U5[: 4ʤ,2̔x4bQvm԰"D<y @䁋Eys0?Vt<4Z^=M4/3x |Y-=JlqpcbQxoDvVggqz?ȯ6n#rL:q-ϕUsgϢu_]R}glF^Yb kѵ&K:#2#+<4v[dȳf\e?nhNmz7X5872V̳'6'ա2U 0O>r1\ng$JJ22/%8ʱS6A4Dcm}aٸym0h׼m7 ~SzG7G4r1z1] 89628\eש^`YO`mZL8(;WV FR-l@]81P߁#P/9]O98 uv!6سl2ImP-SB1n Od o\ѠL>NiDވtoԨ"D<y @C1ٳ2qly?,‹a;QϾxjױD_oۯr x*~a ;<,>_}帗wClbd@HgQk_ꚪ '哻5Q^i}LV-K.[,@LCVeUg#Ȩ2u}^.g~)}fLfz 7y6ɟ?L=`Mȫ~MmS=4 gȣ2j:wwQ=c u7S"O$ xn%/iUȆYhD ʣ2i W\X]tO HlLZ gc,&/FXu'A> >7rqo .S9l0aRy|N.gf7bc- NYsN0suTG t!cB;2\켜3%=\αk|T2A>vJ{y |?NG"vէv)Wv/L%tSGp1j4[5-@"D<yEx%å+8=={o%ɯ^OF" okex| n^get(o(:;~Tڠ; y]˂ d6MJqzoQ^tFirͻՙ'嗇ڤ\nZ߇q {A=|Yy sǂx4Qy =`㡲O/lUamTLnys fp=\c&Qf q joj^S@+Ck].Q~ajr z?:i>1IZ70nNcphljyfy) 3'smz1dC]:&^*>3f]5p4IN(ip ߅Ʒ{8\Q ;b]wKCgLB/XhfѦPی~ֶB'".OòHI4Mhȫ#OE<y @"DDm< \_z^@{'^.}mI#+}"¦NxVJFKM,Hܗϛ*G[~:ؖHߠ(0Xli ྫKF,) $ƚ\RNG+3+GIݴ B_ 0(KQ|)PD<]semdMʱ.^5%cp ґ[NLyJ8$MY$H5 ځ[ (*Ws<<3U0R|S$NɱONKyڎ >u Ss>G#\yTON]yQvx>ʰ!a,_G˶N5.աrMm;4oټlyA}>bu];Ni{GZ@ONj#SVвhS ֳͲ1!Q1l?x_~C#}:tudt)u!d &@ seJ›J6Ӗ3R(qioS ~ŅCZ/@$ dzuAJf,@a*WHBʊC&}$ 5y2R#' MPqmD W">'K~2vr>bm\ȮSք-3!Q?*mua2tظ|rm6o>my)_艣AdeC$Oo)t&*æa,NJ0#' DㆥKf`&NTgɺAqw-˧M 0Agȶ'z4c 񏮐b|b -dO/~aZ5[1)Bс/e<^: A0?cڧ};=9EnJ?W::̻;<i;6v.;U+IO}v1=S$XZ^7X4וalwe΀19w+WڠcoN^G|'9vaߏߚoP6u:hsy$3mpad8wZl}aNK#?F ckvyvPS3d٠J3رYL)L;aH#E !mB> `kAcf@/Qհewpwvܙker!;,{67}ݛM2rLH4{}o\O˿^8P\] /XErījx} (qCv%;B&O1̐+ĒuP+. >wʆMh]6M^AyCZB]u!$*fKG-kq)@z{mKO Qߋ 5j1F3K p_siSU&VP v=2Ԍ>8ì gN =?LC&v7l9p nԖm k =O֭Zgʢ4^ "/C>t~yHMeq@$'"$M>bۥ`dRkN~ڏ{[zڞG"(#1)f%%u\r2굕>bc+pfucu}ta0̏1щn3>N+5qbJH OBߧ#bVZ[8Τ@RIÖ8MdBГkeԢ"D<y @xXfn\>`zJA_6II˭TR2l>'{Vu7ޟz=e nJAy@_$Ialk`ʀlXL*$;# Hk`ܿQM~.,5G뚷*ojBymG<y @}̦j_uQ͌ ZIH`mT/XhDDwU>Ҫ<@V[}z&yM5oH/XxF%a8l(k`l xޱ. 36i#PmR;:6M:6qZSw}H;ⶏeV+ i+nM툨Y"D<y @2v<ryĢ<9x6;oa/_*w̟ _X-^1U`[ers܇/|A:"'pKeER\'gl΢ʣw18YZŴ Ir3|jl ćA~E>`\Q?:GOl'F*Ν V,_f pUY"D<]}bY燁 Ka3gluPX{^ &bSRO)mqyگDHϤnWk,6kBHN~n(48(CSVP.d͙xïV]l2zUiO~"֙#H? [_7ЎuqFN=̛x]C94SSP6r~mm3 z1ȏI FYfm%Fh/,H.i}L1f<0:wpԼ"dz 8{Df[d~'_MH>*#̐ms/#kJ͒"y򩭲޲~U rI~=ŪgW/'r塍Aŵɥ A-;vow9+K lh? _~q+/]+4~`?Hl]~dTԙ)Î0}ū3R7߼O!RmɪM]Wr$2}hp6)!avQrb-w\,) z#: ?WɌKa<0l E׵J)[1U p{ [/SH]SFu7He$gKE$' ISWM]VJ[Ѓ#bh!lsݥRSW,Ϳ|NGGGp#LzY.(vmBǔxL '^+]/Mnx?Y llc2`2^ ɰ]<&ۡ3HPYk;o,`d}.M@2P ng1ռh{Up .;dzԞC>5ӧ8l=*N1u36] $ T.r ~Ҙv>мC)C!y`G I]3 rx U/[Ԗcp.x<8:߅~FZ2|ޤ4G<y EZYՌ2^^ECI~v x zt e+VlE4s;G S/`y'>@IDATwmM=t<ūd5 _2yG?LbtMCSo< o4)Z$_|-@Q*= &Α5 S;Wڲ8Wh?O{f1l'(ef)'HM|9P2V,DŽt.ڃbpd{|YZS㜽kMgyҠ*7Vcj q&xh!8U& CcƼ{AXI@@ƶxM 7e!kжybyғe;m:z5|]'HؑCM.@J~'he4nJA(Nm"dqmДtzNSBۭuv6ggO$g(z7G.C 6Cֹf5iȆ(?7j]X !v$ 9q! Jn[4IJ#B(d^}MClSiWU,;ro?uLq\0O]P"v\ Kl6yzz?!WT*=ܞ=5|L| j_&F\le.zIZTϟue[Y܉U ]|FȦ@WT9/A*i;4g*B|լqs+*ܾ&`’)jlgq(ON6)9t]vKR}W4_ZNuɸ dByLr9諡% ¢}?4lۇO+fKѤZv|[áMϖIK+% NJ6i~; _c`ɿq i0w˦]iWF-Y*IJhٟ*/Wz;oxsBJgUL :A.y0WL:H삭kRQGqY,*^ĩ|5:|5<\'>A 3Ari ZmI0=~~CB}㊌JG]';gҲR: =O=HI: ̓ƤVu1ekC{/TכֿejfJ3qRהmS@cqN%)F(DڱQ"D<}ho@V-γn I/5;_6 Y"8whV-!r[=I3,,&~8`xY8v6Av/ d\2VK< qdd^ƑWMʴNzäIjb}DZ<6%|/?-(k{᫝W~/WŽz}L/̻[/17\-og;W씒 {=b{kʓ1p4Z;dlZ='DY^q0|޻ SAw6Ѻo Ѷ][ `_^}]NIS/y+Je2j&BN-4ڻ&[ֻY?З"3Ⱦ.-,ݾ ,lS̳eDdfӋ8ݾ19fn->Ya^(kdhc p NMmam!/I(_0HuLXeMYg6Yi*W}0ӱSSتu(ր>y%(SrJguyXw@>3otvO2oCLh7Y(hl6uv wնD{L@HՖt!LGq:XIzim;(VޟWzNr]ȳӶ/c7#S&E<y ;=P-_ry͘8wW {Zd//TV er_ y;%^_.yi8 2ѽ_{s˧b+{W'V|?.-C;ȟ>שy~Mh3 F4p2}ȿ'#VwAJJaV󱭲ݫ%cdoRYK7;u.aggW-_U';o5Z^?V-R-!{yٺxWK*</wiRLst7Z/b?Y*FfڻW['MsfnBItQYrloez*vp>0öUCY\K'ڿe-&H[o.T[{'xars,G&.MBp:~Eg˗_ &[}e jڻ?p[`{#{]پ7]&9zzܯ:8$1/h,+_\9G7&]P r?`q5N+Yd[N0|J'l-o{go>G%-oyQ,(3-;WN`ǜy"@cwW6IeWe7\ERtDr=S^g;H|%ֵPpHW(KX﯐I;IK4<x+$vhFQ|3"WV#Q|ߗHY W+^R{B-[.%Tb=y|3 r 8,8IkTܶγ=Mꛤ~j"\VȔ}O^+}΃gY> _8-_7d%Ec5<1Z2ϮM{dz}^rMR_2U\oSyeSjƫ%mbYTu+6xl ?/ڇ_bP[TvIĕ ԎsWxv*`tt2:4  "rq镴l"T@S rxɴ,mM#8Jjf%S|BJ4?** JdTNY ]Q/'rI3YxU>Im6|~J&A /X-ge)2s wa%\&˰liy8u,.,9VqRR`̫*UX/MZR敔}w,;;%gU#ryAG萯_}^x^aQdDclgZE^݇+jQWo`yJwa5=>l QRm\]Vʿ2K*rC'do'|;cJ7ߡz}r$.5.Z.{itMuxYrV;{.v(6CM&`'.ٱȗ3'K̙rA9.{.^.'C#]-^Qd.qRahw(h;N&IO,'c,:q[,O__*^x~!o䔰%./{bcV2W+H=L}Ԗ׷mkť|QGߒJEt}p6S%^.̵3P+zehg8]LP NUif\7%a䄡q hS?_aeGT.&[dNi*7WW$lg;uv&'θ7U:u0(yB/Ƴ^d0 PuqA])Pemb3׵n h*dSGjE[gG d^f'77u_W vʆTHb$P>:=ٴcsXO%͘l_ɔJ]-0O9R$TJQ"n)S-UuR9~Jdț/ʸ \K{M&xߍז# +L 络*X=͘0;Z!NBΟN[{IGO1VHL@h'_Ă;"皺hfV̔w~%6H׭Y>_c繂=r|<_5ݍؾO/".Md d e>p=X핃Kqr)'Z>)=Jel+ZHڏZᜱt?#ypm=L2dcr闲oG;H`\r+IqYܽR?c&Aİ׶n2]n޶4k5׳]0Ø28-dlC3ziHj %7 Ĭe꒨F+`/D^d;h~`.ؼ3([&Q1UZő8OzC2onɑA PvQKY wy#S6ϮGx/MOfy Sy#O*Ja~$J~#LQgZ!9![a4I|\]6>%eJ:g4%SkNyL'WVjx1ʦhFLQ#L9A\.P\mf)γ9elDpP~;ucM>\= ٬3G7/|F : #eY'_3 w\blxA9Fz|7=a.7w/ZLlx֒q5⭧+mw+ W]*lIx=*ߟܿpB~'z܅I#hxY~o7,~8|8`W}(,y'XIWFy k͓>rx~}] ӗȭx麿əds vUI6wP*]2bɌ:hJ8T5fĤ9PK B&[W~On܄Ӌ[ra^luXY4۷Cݬ诛/ c} u2i\vKSYj﫲WX hYj"(\| uhu#(viiRz%SrHcwɹ¹R|w&Ι'%@@oҽl)k: KWɔ٘T'o1e߫njYZ;N؞׎DϗK K9&_riEj5h|=~j]F_s}}`'|]˟z*g>^_MR |-#|ן~,dbVv=3sn/ $wIIǤ19Lj &~n{iaPN پ0+SJd/uӖPr QaHqbjZ:ylo>'CY%8$ymSҫ~ZyWLū -kaR˦epT(<ydž.Fi-h ꁡ"rt.+T},k>F-Z#'{T*0Yzczԃ>"{φ%|:|#k`XƋCbH}^9c ^KZ;&I}qD.]vDԫ_n.FGsCb,WG聒v\?]*/wnKؾԕRWJ1nb͘4>+{"~+ Qz~\Na*V:G{b ibNeL蟹P}nN31l.u;|cC-صlҔgŨ;oFtO]?sD!xpu5^/uR+,(_*s?XGn q#Yz-Ji&~i_S+EX'NimzN*K}u9_|ݐ7טd%"Y [^7.du :$ $W܂:10{uG'^#rR _D9.K?1i}6kbH{\ *SL W]teځ;8ZiY\ ~2WL7m6HmxݠUY&HAщ2S1eB2uU{PԔS{La⭤9H=7~0W^'Q5o[M@z]5uLUɣyZ6$'<˖N\Zc4N/O薍~䎭(`!8>y&t)rN/ɏU>)Ad S;s>Mtz9L͏̎<y @aGPCOA4a+s3Bo#puqv&[WNeV y%۾k,:AϯϬ7Rq*,.:-I%)#dG }1s83aAN-[9.AޟeR){E;xT0u'=>@x ;tWR6oKv^>wCj>v?0zIbiMOKF'+Q]v=]&JNJt2e!Db 2G}( jYQ|Y{S?`P!t/y7[AwtuSZmmRϿ_c+_s6&zy щ&a7 l`Σy=|LD{uZv7Php,:E6`OiX7Hy3:4uOSUePSq:5vR ۄ l/B`^mg ^xa!@ Z6\^s)q, O<@iu`wPě'۵Ae,)55xKg:j[Vb˷2a=K7{5b&nӼzASV0:xM"pr=cpƻ1p ^a# vJ>ÂGy씿yc!ta S(?L;.2;@o7˪ұR5=+X?P|vxXk M}繳ݧub~wG,[^*ߴPٶQYg8WAΛ8p> ^*UȒj}eo \2-udTnMi |kގ}Ϙ`>GzoH<# !Uhn~Á²JLXm]"UXҸ y@d8ӂ*ۂTarPbr/,5uvҾL".<_AR<[mw e r>?6Ly[s}[q/=z,-f] qߊtz`w70Nf!@9|O~7^p6O~lVSȪ9FYnQc9l_6^~6rN gK岲"^N:X ]8tA >]w^ gΈ,}Y=>G)ǾP,Ok_Lh?~Z6#Rcʩ&啭?&{j\'>.V} lwʝcCNbcL&˭u)2uذrWب<:Yy:y?i8[>/WʭxvR jyAc[Ken_ǧ;)8`L.,Gg pezEEBt_A&Sߗɴ+2Q} dZw|euKv&q`)n`֫xb,HJ$|*-vDv=/NM8*y(kH̶R|w6 DeW(5 <?4rrUJ'nƽ'eTYTw-,'x3Rћ̷Q3xyory*jԖsERsIɛm 2|IGq/Կ_#07I|DڮRi9g 0~d9A2CWK|n?[C?M&dbԷj+X>oaL>'phT`.XO\*y]e_̄HF6{eni3oߋ+ cJG긛^ףOFRc P7dll&I,yh[ܢQ2WS7re*xt<(<"Goʴzy=$EJz46VTeM98ΦOapý##D<0<f?^-u9Zfg}Tvq$M?Z,&m8sMϞW|#Mທ/&>,޻@>[gN7*mlʕrs8ًqGjtNjBY9 "i)㽐h2I6T]%ɪ%b--rv8776?~:O 44IpzwAYr\9qt3Ѡ9y1rI2ߤh@ܩ+52a~v̜0Q,r&??U7oDm:$Q^F_)-,i gd{Z9߲w~+M'_9-_Z)kj/obkr{zf(T@} ^FO,uwٲ+-K0gA /vVoپ E^[oV{ђ`7Љ>`?$-Ͳsg'ΐ}w7/~j0 iÐ! |~f3>KWp]c*L-FW='V% ㋋{UǗɘR}>o VvqL݂8thrzS|҄ݪJr%IM+&9>װ3'أ? wqRԙ@;, 1Å<.oZٟY:`;>3&<}Z\(>uP=zZ=_w|^_c@_`cϯJe.>PXQIDŤ4&/1$bA[<#/k}:']8']&HR/}}(=R>sOR:.}_d8ֹOE"'~#ɽV) Ř`uLSEZ1-Ow)oԀT./dmȧie^M:hԻ[bo$_nqjj{V\{T] PFa{!?}= 5iveb%#wY}^Z,MO|_t GmvȇaARдG%):dl<+J㖌d F93V`gkITemڷ)e):35>gP<Y5hO5y-c"B d6TC=\-Π1q<MU`|ghP>ѕFa4zNi^mPZMmgǔgS:-ѰKDdՕbXSCV90_w!wC.Yu39y*։\8zoN;~w"m]d ^җb)iIQ 乥 ˕1H >(̶=ǣ..9KN1{uб-E0'ZOIrm1ud{UYb0sp2ou4ZqLl<<ˊ7.MP>N}W2"D<y`=ulpg?кeA糧U~<){}"Vrxvb8uJ6x2uT$u6^'m+{I+UU]:(f[v-DWח--Ң?DL{ _Q9nL;)=wH C]ٞEvK4v| &IS&#[Y}>[3:-ovp/:mx(#2mi֝'|-]g_iyM}u+.0Hh,9J8z0y` ".OG پqAM8Mm>Ƨ+S+^S=ugH7S&خNK ~8u/(3^&ei_ei N v(Q2A|`%@sM|nİ cMF6 +P}ǡvh`UL3eҹ]$q6hY^ N&N&PI`j[\U@iU6il:+ lao{󘠑J󉄞nC;ç2 I=e۔<t\#,ksۏ`v@ЁZ6>`WSi(^IsadҥOk .H>aF|WGo+ݾC6ZNI ~3U31ghj砢OkQy|96=ax96/7 -7l>Hn//-~ߚ>KqDv*%/c4xG)X @%8Ctڡ#LP8C+8|ž@n6Y*NiH袈tuMT34±hc$UgYq.CQ~4tm÷ VL-'Q&)SɱBʦςEؖ+m_w:2m>e@u_@w~Dʱy6I_HO񇏅_*S @'IT]󎣒U=} Qx IGsRP{&?V ӭ' =.0KkUi߶]gȣ?\A?NU گ456=޳_K1/crq|C>QG%j@IDATxE˶_LdzNAQ۔UP("Ҵ8(KT?!έ 1*qc7F'>l4V x\{1:a}]U' 5]ϴq" lR7oHkE>.NԳy\;@`N˒-umq+:vmi NC>MOHXG QqhApOKJ2yh9z@Lalj8ͻd^b׌W34@z1cAzQT TxqAB}9)QlZcO BV;dd>əT1@Jg*2x v z5 2K?/F$>O ]~ c+u'IR{#Gᖺ{rǺ*(- [dRM+4֩m DB+%# XvSEm_)yPj)Q?: 41i4S:3%扳LWA,&rhy?9BCyHktP.hL8yUU0r `wЎ-n$M$08ҫ/Ho8,1Ӌ#?{.jS"d{lϙ}3)Sv2".VN)|62wBjƷ"9ltWgݑKɭGOȲ)!*-Z.3Ɂum?YB2lF Kyҽg4_Od:{U8ls""pD+]:ry K_#P5R*N6mgwqđ[0<&_.l|~0rm _?Cͱ4/|ڥ`U4khI)2Wɮ' P2jC5q̛`;v N뷟xv/ Xd>~_!V;vDV5SVg=1gϕl=ޘUw䬲'2zѣ,U~X"D<y`z@&"_^`1`!nNm6hvkASSժ8-MAtq4 CڧyaF G8ܮ̅G2qBrLL+.Ȭce 2o&ٗM(.2 saC/XڍIڮ>d^z=Lg>`:& #daC 3W!DuNTmQyzreP4Sw(mr c'<C>haƌYcW=Rm2W=v)Y.$"D<y @F^?][;:)ۄF{RGʠۖvу{.+EqґB_`&K3d:%mLY9 Ssvj]f,D<y Pz@AŠAcN)Yeڔ* 4ORʣnjWZOtAe?ˤK:D%Ҟj 2V#Os&?~=R?J s}Ԍ#5O7F*X,f7 sr96ۯsƉw6^} =l~ $3\}vo]<=nTU^(V:ƷH9iwNL`g<&~OI yL5`2{VfC˶21kEȐ"D<y @-:c 3X/ZN_؇X^X' =ک,4ڝ,*5{8&(MDD<y @6yOp ACiLnZk!g9]YI*S 6DER4r*|z 5mu0 {Gg4b҂.x{~.f{}lϕc FI|m' _2P 87O89[cYmn@:a⧵˼ De v۵N2i -4r:gGSb5T6U˚u(NRաi\@sN3w퍓xߘw}WP~>tKx2EȲ"D<y @s0>C؀pߕFTn-Y}>Wlね-=r}>CesFqup/]}PuPnnztDf09c%"J} Bc\3=7_idOEX 3GÐxSal+s ?t|Α8i %Ј-9 [G|B @@ +Fggz[񞽷lX)b}ik . VU?!p=-Ɲ3SAi^iz%s$fa!}Y!2k+u^VDOVDϢRRR3ݿB@2~f}<](vA07΅pM}fÒ٧]%9~ӝI哛ǛE\ l-126㱃scT@o#Y@~uVOȵQJ+r} :~d@/1gv}(N_T3YuVyexO#0ЯpL?I7{&t"MͱR:mv"lz_jW"&:!7 &A&^Pe]gdH@@ "Fcgntz㶪)8T!m=T}@@ (@Z-zd rZo'k%ui~OXzzVĆYq9Wơ r`a`7w\"+rmxDF]8\}-!*Yo ++2./:`Jr} |j>>ZrxcmNW8YwMMP(JbWZyb0 4YҲ&-E _[;-ɟ d>XJЙdMy{s}M.Yx28?v>")"@OCӫqe9oT0k;aL ZPz;iiri|F3,MPi V_VicMg?kr[%X+&ALؑKItP&Fi|j|^Kcް]]rqժ*vE#]!#YS!fS VoٴP-UbB,s[&IJ`P!֟mX:eg .DchnU;F#Q{U{< ;]};G~ƮS!m>EYfhӭM|'P 3I1=/X c-c1`F;-N|LNd[}e 0kȘ<p[ьerI.қӗWh&L+ޓEg/| )/Yd)92eJJ(Qa[%WJW=Sdlpʢ?)E&N&b uK5OIhrDYtg8OJs99޴s&gN7, RL{5!-M=VaؽAw4W%NLivh')l~|iԳثOҿo/_M)%L?LH uni߲^jh^XȂݛk(Ϝ<+:deNmob,Ojb+Jb"#=0(/^Wu x;}~4V:Fڂ1Nc76lGL&"L0rQ'xZd%U[\P^]&_W92"NDiFw4`5$铊A~ Q9U~?IY:iNNҍӭ,l!t)H<}ZAat"q{ӱ@gE$@@ Xdp^ﭞEϽexj ~p@Wgjq4q*O`śww=+%l.8N"*>? kmWNʅNUXܨk=-7lWe}jE]wmeMKŅ(mcl.ijB$+q^:&*{Sr[E s(<y\4n܈`\e*Qw;h}cҗңCpRH~۰:i AЙN~?]V/kC;׀>&gݐt=~ۘ׷LJs0D^hNnmW,ğ;L*~&׎Q;IPQ\ :xɤI,5L!sD֭dmF3&dž~?,}~q}>=|9M+>íce~ep Z@@ UNT];_Y>U]f?j̊(oVΧ`{x+򻳨ի}|Ε#d q]*K!_.[_ےs}ݾ]rO/UHZq!Z iv7ɪ5xqv;Nɿ|ZbZizrP17,1K{ x/2rW&qWm-22zcsZB|Ά|@gМ oW8úoc2x{t5h Kh}3LO[ 'M4qnzMnj-F->tԟ37:6iڶ;2xmA&1u>- 5z0;mzڬOG%.3N[6_ȟLʐ@J ~/1%v|,Í@@ |#+2~ΫkV gK6WsTÏ\ߟٮ]7VJ_3f Z硵rq24x]nj^QU#m_( RfT̵*r)Or\siҴm'HS24ZviZ)9.Ǟ:S H'+OE̻Ɏvvzf2 .`|A*y-򖧢TYL?eIR;fT@>h?)`4l$/uP7>=UIs #Y"ԥ\iro rg!0 :\Gp\͸`5>DZm$v29~:}Z/Kդ%IC1o5f4v|^[9OL^ۮ_]RHgpZr.I*;ՠRҗi~<ɶ/gz!^_n6C"OfmP@@ nw_vf2e#=!}X?2QUr|ڟ\}#ĕG"*O^Sƈ:}SVN6%K]S>Z&rN@R;y`+?E^]#h9DJs% %delf @F{ĦX-d;IK'`uTp # ;`" @@ P | X&_X+<^?,Up5L>^;(Cx4+/_FdYع]>YeNC/Q~mNګm;-ԗ$}O>B{4{t,Cd~.\$nF^]2rKlȇd }M5矐]~>i]o!gnK{T,+Id&KS=0.>+;}tmik Y쓍Nʑ=׼  }\,d4~V6}?j.֎˚ {aSwoFnY_x<.Rt|Ni_YO6WN{Oy4KӊޖJ?ӇM-"Js[c}0~b>hIh,l=lztۥ-#޶N[2sXmwo?}T]t_tN:?q4<؇oʥ-^! U* H]Re+1|:Ƕ7i/ LnSg-'R5hd 3ҼlR8V܏sU8 3QҖGfz/*:~4di:sDh_TsN~&i:U Q2u:Dt4@] hW$#}FI}l#nmaO>ݯVrYꊑ\Y `e>E@O|@@ T8/=W7My%-5?2JH;C]ՄݍyqClۋln&|wuo_zݔ+4v!/#x ;\sX^ 2ce'q[@W\<@ =mr,wč:FA9sRz1 ޏI7HgrV#x .x{~"֛y}tNm [?Dpgm4#'eeHm=Wh~<}гC},_|\0s>_Ͳ_p0B/>}GJmK4<;2- Ħީ3 j=;Z 85{3[̆Dus(o2z}7B:}{ :YO$-O=)}̍kz( ⹂-Fg: 5~2#N˘=^Ɵ}q9Ƈ\&xs|.Ybtv9:v>ZM ,UNUU75/$i}+掍UwV`ݹE|L*:Zo"RU$?);q?X"9r99P ? [da"K=nU2!ziZY ȭDra/}cPNi@Cҧ]Hn`+}*oF`z{;Q(?_Ϲvʛw {Va&Sv~Ni!xA*=fͩxV~a=~O#^ >8]rqg5vaJİ'{O|*d;{ޅymNwlM+'?k oyiS.Vl9SC'4٢siɍuot=roڕ|`z:S9uAvvGwN睢lOH×h^t/YL}K~0?X{&e%uƩ4DI7߬;ٸMU@jRnfrrlJngٲ6K"\u*#P>1Fנ4J4_E77@ ]b4@=A` z@RKOVLضdu3:N1>XD?->1d+ [ u+'!IӶHdrܲ_mdc[W>M+|Fg9j[ cȀg]sTG0q쎗f,+U*XZ'VZ6#"hr幋\y4Αc>ٜeR;}5geurlelrɇA>zͱ`Cg2O$߿fy/\}93AXue#s1[ׯ̅mNm&rcĖ-(7^*V-JjKܺMEynT \GY^ZU[Uۉi^ ^؏ɽA:K#,}<އ-Z 7vo0/r^.aH?)n-G3]^˺kw˞/*#==r?sF}MRVA5OAje19{;tLV+;;H8llZN JI:+7)Mz#{V .75ʺ;wNG/JuoyO{u~Xn>*l?>MlJ쎀ll7Eԇk>Z>!41(/ Zi`6I/< Q[8j{a 6&O:Hj5Y;eX&= 3\uϫu> 0Naɰ ٻ A1Gmz4ڰK F3iA ##XYi*&twlvY Z I >LOT+p }>n- G\x>4؁rN\2oFO6a.J@P дa,c) ['/nS9n2''bR[%C![yWҧ4>^+`,il>uM+SKSPǗO&%K)+BHdbTȊ룞b |Xr>#Fm/(F)~fW*s]p/,>>áRO[>B"cVқ%*fRMK 㟦7L<)r$eM$iDCsmt^c3 ?i:n'y*\7n @nLv)mi42 \M#B))$oWiZu0_I?79IʤqNnϼYۮē"W.)<_e_rkC~g p̠}X4Ks16WIkúmnNÛXW b8[v=#̚rtAdUW%ouOOr˸ZOTM %LSWj?IY^i&mJo\}w˚Regؙ4C|h WFWRKowʶ۱uĐ\~[jwRkSmXڮ_|3d)Ra3ԭ/ N`VȚwX<“|?}ҙmr ӨXϯH֗M҇C!ɗe(&Jw\#r5luMK>˖a^b+I<ռ`?m%۰k:ek6ˊ|]N=QF59`'2oe'mլL4H]`LS&RW[ɜ1Q>Nl 6[ƒv7t55>(ƣKg骭4gCĒ(me 3i(CƮ8mH"%bXI{*֩~ P MM2 ecw\1ku&nuK-ju>tmfkP4|DMU-j.3m|uuY2[i@\S;#&_5MO@G$a̳EqHWXA2Պ#XAegwOt"|b hzmu8|1G] ?˲n|>}3%vtŃ|J/r#@@ dEϟ?.Teg{Vf= y#fx7cj*p%07?%]rb(ÍzL7O2HweWɉ#ҷ)>zbPwIhUukS+rx0` ǃ"֭ukoJ1ӮG}$y>$uPΉ]66:,8k2,IYfuDb?%eOsb}w6kPo@ "uE^q}чjd *&02F$9V7^t$}L5͎|ӌ/s@9`@ @@`~z벶y:Q{ϝ1ի2+R(ܱ?'S>{vJܰ\dR$"@٫5҅wKNz.׵?,w_*@#VnߋfwuxOV_ nn]kW~Zi9+G(x1MJݮe;˚j? w𜈌"m|vGGd'b9$W{vavd,[AZ0=5(x+]ar@Z8!l;)Gܞ#8u|l0.-^zI/M LPWm G2.;? WO?x}>#]uޭjǼ{IJʪx[w:eͲ7/GZW̿oE`; KRpZ"l?2xWƆbU_X*{ ϭ2XƙmY=ֱORq_* ˫X8p`/Wr[@ׂI!r {fKKذdǂfʱS9=?6RND,[7{ ⃇1lj4-+L^ @u .&|>(SDT]&"]3h⟉t yNy<>>`5rUS S Վpcٸ U3&dcK7N&mLmK̆YRQTV7>J㙋ҷ?FW@@ 1p|ϝsa.w\˓~L i4?g޾)Zz$V. a/v~w!tL~y]۰ yn67ΧnOIV`h8xǼ`6v4.x,kcibg)2}|*p5f]eO]Wzף%~'ʪvi-zPig+/7=S-Hab |u?(5P=%8~-nKD-') k Ǧc=מUmǾ.;.i\߁&H»/HM {ɋxTWS߳ۥ&iZ\>(1~CZu;z,0E.~W/k:Zy߷ G-C[8-MU2xФua '񁅐F#?9P;)mz '[ L?>3~1}q۔T>&%F>g_ltHe >W6ebζQYiq.DssM},C *|NA˴۳:X4󃮁` "RNDe~}Άyi>l`M,gmS=:Xgf! 'qAW7ք xX珃>eGF h9fKLV4>=Wa%cOSDSeKu ~\g&>̧/ɘç$99'ӵSr!Kɤtn^͚?Dq| ]Lk67ϹƗTTv>I&O'י'=օdN[>rɘ~+}QMQt4b*0)KKPɇ,3$v٤h́'$5nUr۴:ܢzd &o+_|{#uXvr4ϛr5=w˪Uu2zXNկY8C<$oUl3HX杝3!]'E}?6h|UNw'o]UWzSv|i?&_;6H] {Cf"Ѳ1ثrXQ Eݍmh= _뚳϶mG "vϮ76fG>Yf;?xI)UQ6\;ؘL:xF3xU:er:f({5Ȭ%44,7 &f]%,""@IDAT~ (-& 3 oX2'r/^dUD5t:ic;^AMIVgρ$hXgV!@ M9c7/n(6i'm'ۦ:YfѓK_Cdǒ5YfXZ/u '^f}=$nJ@ @@ 4:2&aWqN{mHwOTƮe׈YL-X*/!-IG9"mAyj9ujr-toj5"g+º.ܴ7C%_ Jڪ437}*O`tJKm{](t^>(SQ v~ g .Rɞ_e\u^޳/RyX2p6L(?/1Hݩd_2,- ~Uj%],|Ck͎P7fȍ#IS'=k}: ~69ad,dNn^q#|+Q_<*bRҏ4Sx 6:>N=*W3@=ux̱QOX?c>řθW!l0hmv|b{ũ4zT%2yJ+ɣt"b;T_jzHR{,787@<۝@:ΠQOsc<Ŷd1K/S:+Dl$]NY;߱iAh⃄!@@ K?i={t#]7~Q.݈nq!7cf[?Vab>xkEm1пx~}ڄ՝s9-\I59DwDA[+NeIdIiɚXy{ܒ'O|xma΢QaD7} M> 3t3?/ծR疓&꬜@>dŕ|c/曺Lɠ/1>Q)^$?ې_x=T4 W/mqi Ɔu2G5r`(Ȅ9&0tp,|/ <<Lv.AMm,9Dӹ $NGG$۪zD 9F `. @@ P-0wɧzt [O?'_>Rm퇪y?F's@-N:l{I=oTu/iVq/wot<ƃC؆z_Ŷ'f#\lWpO s!Gr{P?=y~7S2>ß4|(~ъ`= Gd PπL\s1 :!f~h`/B}>_Zd*EKCsANl|Vyx1[И}9X5ť@Cfv9d_ytr1j![ʹΣufۤLK/K?ӔСcC':/ ܂· ضatfG4ɚdzhuS:c%eϗ(ٰ64u8u-WدCH5f>W#7PE$g OhW۳a9A}(؜߬S_IYUleu&:@79LÃLy>ݘ'K'IdQ- *|_..L, h@`!.\ KG|+-{ io}7Z!elk|͕{E|))WemLsyYSI?C"{r FVn>]1fտ,gn*~2h<0_k4qiL akȮTS$H;?ir-gѕ'}=m[fEYsyt>pESHj?uSBTX6U{qG%IqU8/MMi 4E=m1 dRAl,jKQg+w3x]mҗ!m5pZ8`]6 $72x8a$ }>s/wQ9w0>d'鮤Mʣtc$[41"$$iV%&lQ9:-W`:K?O ׷g?j7b8{yWcǐ&5h?5Ri8I3ϴaL~յ|%d1\:NOcSy[R>kd(M_a7n|I>EHtdÇI_~r}3O9dC{9$p1XFQv8/r~63N>{hH,9)FgI-'?m<% %دbsvV,rYNʢYe~Y|JN,2Je/?yc"vri<9$ivږg,÷H4N&es`E3o6ϥЬ<#:SWo%}OuJhua zǝ3amNIڬORqIߒb&J//_Fͷa*sSi*MXd# Orh擕Y=.Q"C}s2ڻ6Y+/2׵ݗ\B ,dA!j6c+B*ٺYǎQ歖x-YG^EW=j/ ˠU> >gѕeh|pd[:+3LYd) Oqԇqq\Ew{;oYP?#2ϤHh9+pQLehq NS'Zj{ͼ%F0ɤL7t ,觝bG#c@iAngRuKuJ4@ :>j 2 m 7?m=+XǴxnPfLuL&LƁ_UD?w 5LFsqCb4L3{p `+7:VXұ@T,!Cӄ"dY\[K a&}o4=(GL,߀~#ԁup3@3 CkТF,1B1"'nƒV꼀BjueMƫ|jmݝwQP0%Q&qCgFsd WڸdN./@@  ||vVU /γr'5GX ~U"&pem9\eT,6 O] #.yǐY k^;"V5,s2 O5|umkx+/[;S~j @@ pţZ~@s5'(]Hd;]Brb;mRm_,ذ^-'X`1>;94T&gLE `P+}2򛶣0u[e&%%u&H6|6/g_g6,YJi~}q@ѯ5:1@6I$;t9x@B!5!47(=D"ˎ%Ɣ,FKKۦjQ3L0n}jcEXӕqk8:d6}t@@ ,a]yAL+5(YT4Ac[۵W h Zװ{"#]rw_}EF@SȎ;RZ(NC3  @O\@v>Z5|\Kb:g}>i~O `,ɈSj26>r=3`>>Gy+G3뛕Q\ԜFi>ڃ1|dИ;ζ"˗#߈EBr\I 0m2Q~rJ/on3~$t^giAcO`8Oaݒ鶒tn|Jg2ΗF_u{h#(+D|s|߀V@Eԕ/W mM9x WG4Wr >Sp<m'N1~_̊;rN-i|ԣ9r)缥鏜{ R7_42 $ @@ P>_9#/[eyV;3PtYrf׈|9ݰ(zj]_dY|\Rh!y청)KMZ*F$?s$ZHD y{.m/E[Y^73N=Ndä\pˢZq-hFlyF6}Jd|PY4+L?RQz˵6"߉>Ȏ 6ۚPEχklnxp`^8̠=?Ѧ]K"fѯ/w:y؆[VߜA%m:ғ}b2>mZ/q:h >CG\M 2I#Q.^1`R~iGL~st2hkY}ڤ?f)4 ڨ&aR'oMÇ80d#J8fD 3@@ q&~%GNg~QqC$@)D`u?2Xf@)62#=< >I}C]g>,z ) P۱ID| ҥD'~DR&rW UHMO+uuf٘fhς$2Kɂ!xϕOl&?nA`͒4&EHZd,'Ui(/M8n^㧬%OABت&ō)h|m}+>Sc6Y@8ϥ 6G?3GA{(fO*h&9u*͖oc5`6uXyܭNZMmF7uO\%;%> `ymnNə}zhXgJG%{ %{@@ yǮLH\uCzy&i!Pmvy8nf|m ^ bբ# (  eZP˂YVQSn/Fm[=ɓe?Kb$2Ge#ܣ38@}\CV -Gw|2WkۜV紁LeB  סр]t[ڶЫcol47h׷o|JwgI(Rm}Ѐ2;R\hUb_u1eX:Hs/v>)>&Ձ:ҕFdGE^?3;:|ظ9G ;"r\ei>?Ll>$ٱ1LZ_> < @@ 0|߶QZ5y+S䦁!*"MX.Oٛi< ?[e*@z|'' ޱ[):qE"akW V_['/ϏRqqC8*(Tn'*b4_nJuIH/'%Ac)3;,-cd%=fV~O}S}ĚSkSJӦp 2ՎJ-8 ($^sK3AZG1dl_SL" ꧨ*:6.vUƫ]Pa:W~s.)j ͡<:6muߎVAǣeatCk/]z[ޱ#g/]Orw(#ІmW; YWVdPxKf3n [ v=y#XMz>Err%']lcۖ$Va2ZԚ6zjtĔדhS7dcRNI^ _N`W_AIR^ɮ/KхR|I8)|>iճeYxfV)FKQ oҙlN+/ɔ|tגRt<X}shη4Z>KͧCT]ggcʟVLFgޤi{4M6M+|H]DQ_OԤ>T~|i^ހߓ_} ḼsWĈlEuU(n_Ҵ4}Fq&X"t# ~=wG\~[YΫ+×Ҭc+w~1+Ϥ4( gb/윎?^n,͍\.I\ֲ TWRxmNi.dF+EBٚE5\Z mܝAj&^, }U;:ez.vHէNIV;J^hISY-rr`)2 t.ٲwԷ~9 7K8B6ro.~[S/ui3{j a4+ߦ[*DĒ+yXƧ< p2uSQՃ# 2Τurg0/RgŽ|eC]ߧ]uxW"|u j:]gfXcX(|' Ѡ.PvqpH&c1&cu+)7ڳL:3y(PWlG%H۹F'υəVhܔ{Qis4;c8/KK\s9qrżnADž~8yL7,/< m'"ÝLLgْ'MK擵ώ`v_XRFK휒4TSl3TU _*qfl͊W.b-,9Ui8@%Ju>&ouo=#/y'L g`R׈j /G獇,>eᙩA~N.w"etcxcuvUX"nϱ\@`^7$/SW;/MCf k -HoMZ$Wdo|'eI2sC!+)^<),gw:.5'sL'oVʉBG0`2:7e&mf0acKKT5P{ߓ Z`i&3bLڌa-::e9FAkWN/8O;[d o2y剼n~= s9,'$j'M-&_?ѹ76S ͶdܮL,8>%mMsUN0[O 2#n~\mM^<hՕ5Q^Y>gtz^LO[[E[NѭGu6"zSB^]fUWn}^Ve4]rѿWFo筲n&ip+w#ro|Hִ i^p2~&qJ"jαm{Pu1-"2}Hc}i9{I^YViCwˮ_e7&~ل^5lg?ү,_+;>469ؠ;rqmmSVE+wD}ύ؆fPN?˯D;Q.M3my2gS 6ycq\W H_Sv+[ΡArϞ5T⑚MiWdMn]> 5;JZAlcɓOoo.M_K?և}tmi+P}I9r7Z6Fسٌ~>ĤvK.ˮڿ^'ii2~ZL2 |>G3H%l6^ ZȇH}SySJ.b\hF]O4)SIe[#Mlu>/-U,fT7f]q2{֧aFՆf<6>'<ζ%ʒׯm\rR@PygO(bIa6mWMdxHLgs<58ė_πM17gbݠY]y%S5匇dāt_Hc2{tiFS-6+.ℳR@ @@ @$Y2mgM[4\el&~4՗y m5S,MGSҫ22Z+7*[wG0߸z?~ [λa_{l lw=+WF~}MO'elȺ/س!J0[W/ZS+Cg`DŽ1,Ѓ ގvы9zvS:[уur雬kw|P;:>OKnox6USU^V˦h'xmʹ8gGD/vlI6ꋇ`~2C=.҇3h+j83A|}eiNqNQ}|ZtKMկY(y0]ܛa׆ =@fl־J^Kե,6syq$&? α+u8S7W?z<|4a>шw4x:us=߁άAc~stk[i?.#QZchYE֕1X.Mg2?spDێ%bR[Io%$xm'KqYi|揵 %{%Q|7whsN!#q]3xؽ=y]8h(L["f3nuK6.=OW݉4a ~mO~NdX,sl"OeH@@ @@ @@`"01(CnSsQMwۏw~פyynέ/x[pMmҴflqxQV"<^VOjGR\[߰ǥߒίu!Y].ϛ.(!V~@"io  'O֏N\BoUCr᏿#Q}EZްM.,J~KՔ]_-Xa.rUiy4esx`Am?r nG ~80 kpVO~CNE3i cO u'5 R=x<.ɃpR8cJgw) ;^xxآۧhܤ&B h0 ʢA1,`X2A+-X,}^3&mqV7I>( & ~Kf 5 HO6^UAF9ƶcJk萣dLQh=(5iTOuѪabzlIA-|fˢNg[EuSԐb} SIKb u#HƄ=4.>]96m͌[I?&szQG!k>VQ`4^#`ai? Ӟ&Wݶ}1]LM }^|EZ"=aX@@ @@ ៧;CnBSDnB!"mM<)%=p /̌cs$'ad{Lͷ%ް+K b+iT-xOCrm[;a6Yw`$a8Ou) ױ{9r]b !s}uƪK_dڽٙ{N&BN0e; ޳϶tmwwʊ5xΙ;IF.{{v<,+;6榺("꼇>RQҾ;r@/[uz se]ߦ|Q?FJi{cwRTMhT0(5$?H 3n`PZ&?m-fKEAb]==OfЕ b4 _A|b*pP}g2|qL?Ur(I~%dT7 N,.Pv]_*zHVm]$[FF &H d;CdȚZLZCq:^x:ct&LG$4288~`ccze]zTR}{n{{ߣ[?{oÐ`Q.$"֋8)MH}X?w̦HxMgx)kmespՋ9b~Og:lo|5prZy-Zq!rIH&((EMžD~}t-D;a!0)D D D D D D D D D D D D D D D D D D D c:,Џ!DBڀs"_T!2`Goc GO[U+/ Cw2G&:KhO)~n.nGx#۞7ZLowoh{JYߺ1u?v?ѨejHss:kN2g({EɊٖ3?wVe,UWԛ8eٖ5u8vF㾄$lhw|=]kɋ ‹Dib4~MAHeL[2i,/ߒAc%>IhГ%/Itɛ5X廼CuQf4q75yb]#:X&d[Z3'g2O݆L)k'qw?kP%cXރf: kķU#ӞVg4+z<~S~_ur>x+: m'!d_q |JD6Xu֕g U̪q筂9Aײ/EcHt|\G~Qq%I)^%wyRPε⍴ؑH1zRc,>%Xm'[7m5VF = Xdm"kk5)=܅OHwgNIGy5ǘ~lz8yJFFScFOBjyP1+ivMW9Yҍv}]u(y6v!@w6rfhp6t@}!Ʉw#T.d&%{Vec!|umA򙟆!eȀM>m.>X`>O< Ty@-tmAl uAQCbl2h8iS|ov $<PǓq,4 ІVfCAomlA:&'0/\Dͩ<%n(Sd 8bOoS9v]B*ԇ4+lf8,*t2 DRI#ќR4QKҞ#\mͫg?]T&5^}U\|(:-o Zlvi&cn|JƷ@[7@'4 +D D D D D D D D D D D D D D D D D DxC?F"$NW.c΃rriƮ >Ӽ%9wejJijny%u_%<|24,yDHDzB~T.G>bںi4 q>ߐ޿xCcm׌ ȍupwepO\/9d?X)=]#58>OH3EtI,"_{LN$W/rk%G떎.:.-)eJqGzxArGo/G9 $?>Q`4@}:S2yO19kٵɟLxg%2||)w^OT0ԇjTsxc2b:O]3H7 CNlV@@@@@@@@@@@@@@@@@#0r0N½e\»K'冎H \j:POu@:GAHgQZ5'D6EP,^32P!8U 0`4ŋ@ڂáMX_3Xe&cƇξ XOhEMvZ=+41$i_`/O & Lȩ>ǒE<sֺ\}0i5y?9U4 ɲtbpÇ8+a>+Ty6s6m?+ )4=d3F~ ]6<Dzʔmb C]k1P4zۨ #!J9γ=9$W:zL(rN< .i_& L(`nϟsGf)万jW3q)@Dmm^ӣɬExxDBj1 dTU%C&m}\h~1[]2~?G[I!"% U.M7mZ!'Z$<&5̤B9F'ϵO$}9HCv gI=i}Σ)p65JcHQ:hlimD|}֦bP]nLh |Y%f?4Iܚ4b➉zVLuf'I}9EzߠޠS㭿aH/I C xG;v]EM;h㭖,zV&V߃og)$*OYx3 |1s4K\_J_uP@cC,k?13%Pgt2(Z.NEUgJOC FMiо>l f icugMK5Mm_NcPqݖ+bm[TF]j&责L~7_ 0  eYYu1eE0,`HN{"t +@hFΩ &$_:<3]7O:?*ŋPs>&륭A d_1>sc S9Ra~l%r~k>Fz G3iM9W@N/79@6˄C +`W?-o0n7|!.\ x2:l񰡋 P#W,Ks-9i#x$Uׯ4|lI]TM|)f(>N%iiNgwdy惢RF 詂W<9QnKoWz Տ#JD\ֱ|iJ#5x|eYK!kJogKfIJ"Iy_wv"-jRYp>X;sUyIi&ɥJ,jSIYl<~;-[obI7)g'~ryeȪ?ioY1_\ vBL,d巯m=dubKygr97=s`x?!״jٛ m%o^ ^X^ c&ׇlUj;ijzEw䊌]v sRA~!||MKB=lw246Gb3IkEīݜcU~ bL58zJMS΄Yt$DGMtyv9I$|7*4*dľVRw`}4&ƑASOS :dQ8 qGAY%>vmDiF?m z(O^Mv} M*SP'5OY<@cLP{l,KKMdd ""M3Ͷʢj*Ƈh&ytvl>OxDDZO֊L끵\MzBGOFp1S*=WY_!J}i>c۸mlf?xCc /my}&gu0(D D D D D D D D D D D D D D DOAA xs4iehIz${ld(f1LN3᤹&|(.mDMKM'[,߳re|̠,5.L(o.䡾x}}㘄4:ڵH7 AAY'&GBsmnG69=MǤ'-24Bq8ʕg6fbAz  Z۷4:qt!ͦ|U!vP+&JS9<m}ol1}<ʃm&Ibzf}cx:gxWp-w16%ٶA&ꦾr>52QyX'sL@@@@@|G9W2}L96Yzb p !$~cՄɣQd?a*KLThP HGJ3YJGZJ⼉7Gљ݂{hW}CeO5ǾG~KKdic47$H:ОkMڻx0驺3K+)DfmTfSN~|P>ɨJoY!X0FY|1y>5Ǿ>tc 6eHQ:XILVo͟X;/jşwӎoM|ʙp5=_B} W_0v~4GC+.Th /!'8 /D D D D D D D D D D D D D D D @m1Ch,0(y(v`C&sfy:da$`σ6D,SL#j=jB%fY%(kͷ8^L'83 O,NII|gxaD}$|<EƆNfjlm vףdX X #y%CsuhGb4⌦Sܧ~ୟצ/DB3L^;f o% G>򘼏7IhI<*3}_T7>3hhru-J*m3Yp˾q % 7O6<׮WK8/Q:ZG~HS\S"~;YFBTLj 0?Pk;7UXUWPEn2qGraf=ұxDN.sMqnГ'/.}G_;3rCň2n4#A݈dS Q#8zl{&,iEv]5ŀIu`L(Cr+`#*Y3&W zL.'Sq5<,)D!_͇0"'4kKz01=Sfdト]#HΨ_">c0Oo Es,-_'| څ,d3? 3B0`1GAĀ1ӣ!.IZb4;W>_2&o+A]yN9 oEd߉*i >|_B}Vta_F""""""""""""""07U-Bp}-`r#Є{d[7~X6_٠ȩrw[6m*FetvRcC\9ɠ ɗuY@1GRiJO `SH0p|*kn Zqu_ijX?=5, \/%,qN_8,*qH*.;YGc=z:S+ǃ/SOdՑ5V? Ҭpm6:>(:T{H*4MOP߁0H oq_,_6b8`D8܅#O7T6ץVRMB6C8Vzg%>e<11@EQ&-ʅ֬WB@O@@@@@@@@@@@@@@@M#Y?D D D D~Y=LKENU#\7Eɑ7d)Mm[u9|ډ_,?sJ1/~Є=~L1)eDŽs,v(wG ~r,Ifk6<+w%vt8&wFۄp/_'2X%D$OAژDvD%c>8rՀi톒eN02tx|8RcGb:oP? }UB$OSyq?!6,Ny&.ǿˑ + #nV8X.[->>}*,CuƖgxy>+ˑU{諶]qW<*J׈-"Nc)ZR]%IٹW)ܛO[P f,<ηb1ʰP6gqF9b^@/h 0D8Ľ{ϪrdJ)66d͡)J"bX9"GA8g `_, E6ǐ0x%d+ƙ`!%`%OBl7MAh8S(t_vxy2WSϧb|)w,>d♭JPV 䜳"_$>>G Yx)a0򕐲—IKU )'Snz]o,T6TkV_#C ~3pFKB$gљƣ8~Ҏ|~[x I6z 9&̺)MWZcLrSY|O%I~߾o%guI՗lʤ*x*oF| fx,ɱGFSWw&-9e+,||g*epvܟ %VVزӻUe=f'\d.Djzݻy윌7KSh"ko&_;.KnEZ 59q ˊU{d/_P)YhXFuId]2r99ըٱòjjތ|hrHoubߐ>~c<-Cen,imDCjd'sv7H-߃{}9Q+y.-OKk w-KGw#~h:/kW.Gx3JntY$'ʒ#a?#w:>7N ]ƺ/Ě&Mx@K'J]rme|-zfV]HI7dq9wlKWHyq'}s4xriXt =qFɏxȱrxSF7m: F%Yi.iǙSELv?CBd/1MA1BkSVes8XWIyljXС>>HgcҝN#G;_fx)n&[O?r75/+/ؚfCˍ>5 i?qg joe1 @`i7Y(g'ίW'C=c+ۨ&4|PK(?XL:ǎ1fq4߷H87%Voc@@@@@@@@@@@|GnOWSWR""P#` zS}[w[i ^h= C~ebۤnX..YKKm2i᳇Q$eɺՑ5|j};3x4NͮwIwt/[5k`Q;ldY{ޟ̈ aGCac?.Ƥ:824 tzYjLH~ңH6Fo/v+ ;u@ϞCQZ-]·;q<+c8rӦuu۩!|z[#K,}aN@_͢nYV0Y8~\to@!NXxoBF玾zmtM-'`\ 8ӑST bcmƗ3h8ox"9aΌ! <G FE97Z8]q9vܻsݻ]imXswn\n]m8GeJxT_~ٺi,^~HSm3ߓG[䧤w~SձL:_.oq9[>!V _rfikCB|zP:,gVzZ:&te32޽F/Hݍ҈L,Z-]huh~qfͩQpVֵ˥x?O/6&ƾ|_ƎHh~ڻ;\Ce/N)K'|DyH⥘e^GdsOD&OL;>yo;d;is%9#ҳ7rRQ 'z,[-o'Gü1ě:Y4Z!1Y[I$xgI$'y}n!VkF'$ηe$oo|`?=V5fxhl rT otw#Rg$i. bs${4Q 2oĢ&<adv `-aF'/`6iWyrL$k8M@Uj`e8 )NJmk2ma2[ ASɃ>@Tfg}θQ}ڲdF]ͱkC%ɝKB>6* H溦'+(NcNg8$@lDpV:X|̦Oɸ1[*/d\oÓB<>׊+-*LJU>AD y'%D D D Cx[F$c?.INql;vx{d%vf7h΁<;wax]F7no]Vg2 ɳr'ok]']>'O*G{@@O|};~Wxb u{K#ϭLݸY0좇1)A'q|qc'@iZ%ȭ0_!Wex]Hu1NK.Yq\Y9z5NN=v?{UV߃e8|~MMʐ??xfYTۤj\MAЫ=m[1u[gS0 zlic#E!?>zN;~fl w=b7|ӎQY#k.Y!L2Z^<6f^L^sx"dKH eݚV>9=Xa5iP7cF "W#NίvwmO{y}8~L44\BUѮ&(?iF7hSw6+ 6{b8响F}hm/Xȟ눸?kA ,Lw$t2q4/L6KPa>Eo8E鴒#v\吡ox8/x!4]ӥt2RMAȇ;"_qAƯ82bOkؐqIAŅr$W Q%9s;d%ҁM׭yJ.}G7F韹51%۔ 毦_9x,Y'ƄNN(Rrz \鵨, w25rVΟ=+culF[ƈ4|k_ lTa8!!!!!!!!!!!!WOq=ˍ#4DȲx35v-E[Nָy]G*L!ZK~cC@bk4/"bn>ׂB.YoZkLRTQMvBWnc:y]G3ľum<}e}nm#]]ˍ;~>1#A#u|؁Nł[/Ύ> `Q{%ޟqsbct.jW}LONȉq9=4*PђusxYU<>4k;X#+| X v1}0k1XP}Iu;ާM_'VtY:')8̈́T-[)6L<k5x7gnwXvGۻU3S-ы7ʔOonc_NGg9D`D`{Zْ܌v1yn;v'k?M?&ԫz|Si<}\w޽Y~ɋg_Tb?擼zV_2՜,7zi?kʾC'v y7ɖΕ~[{|9KU{VȖaywVufd߱7c%/[!]_/GNcqI,a!1ծYo&k>*kZH{fhzç{!;VVH4ql-N%mGuj\x*S}Ҏ=(Mg{e[K}Qx;2iM\ Ezt藥7Zi쉗҆ Ҋ[w.^HZW/#`#TE;3_# ~ =%6˲%:3Ξ:X-Ni_>;y(^j1}{8^ VQw*>.o!yؠ@SJ]q,ALx Ts4:"cR"@߀+m-w`,= GNR¼!4YU9lqlr|b'b/襤|Og \Vk"} v,/A]v#|[vKO uSK} ONTĀP+4u (6NÛL(fexڧgIܺ]6wujA@o^Ν~`lBf 1a'ha2& Q{ bW`,@˜ Z7iq?F]Pmim>W>(`r^O2)xW偧ij&*+gxIge\x0=(HIeceO 9S#x`hgX1ӠoU'ĺf?zВzldc e茋z 44a;꧌"[q &A8ɘdItlೱ+?q>?ׇ=CyB!g8/D D D D`AGۿ>HӀ"U!]xj@)[./YvW");Zޢ[(-P_:J !@IDAT7ròzjiY53v½_ݓ/PLY9s燏S\oÑ[h,-\g'opL'GYp._"3]C8wHm8~\:7u#DŽ|0Xe*ݛSaE?-KdwޗyLRg%OLj^6o␜;MVămer@FFJKSbOdmu8SsIp _iapf;i c5Xq斯3)-6pܢԵPLi %V *MO%Jh,@VbeviUi]p_Yc0+* ũ!TUYES921{ _Uߣl\՜[~{.mlޅDsdl;nt*1y+`)$v.~?'Nxߩ쨽7'\!?L?GȿY/߾zy]?}WJ=ub*-f/O0\G?Rw8磓!_H?,<Nu 僫Cd}5p&-G;e`y$d=+hV\/۱LV@oB[nO2y?6$?݋}<]{&o?ymD>u|;OѿWA$k[V6cal|הry[nX!!N"{,lw./1Q;T d~d.Ta1|{0?nLy|-=m<+O]MK+{j^1[Ď&3sζWfkg),ν+Z%u#Wq_x[yU?ތĉ黮|?7d`olK+zN=vH=O!yߗJ냯 *vlrTСo/\G.G`!dzXzg0FJ/sR9#z iij+]I}1=|ba}eo} :Hf8Q$ J7G?^<8W1 333rD=#i;Xߡw3ә q Bugl_yHNe|M1yy"$<&ʚbiΨ܇Fr} V,v >S ebFoi\9_7[t4&Я~:c扪d|NE0yGLv0~n`cqhmUdeKvcwIsC F<#^t[L0y/XgcMAEEqq<: Lyd$l9Nd5~=GubjVx W6i֊$>wޣ.Fб1i LI#w bт&k 3zig6|]' ufX)938T\>T Bpl&P1HCt}ڄqaD/-[#Ϲ͛do.0]H_&kR xV'2Aba5LzY&J# [EU)SAIE.pcӕf1]l:#i8i*O+urrAw}7Z/f]q7pO8S#GL2)zv葮AyelvыjަT>12X&2mIcϿ.&:/`'k[)q X;K#=^mꝲy*n_`T}E IUx[zw㹛knƍ}7~[b̌qHnʜQ:d\x-%*Vէ:+<y8f? 21JpzTvDNS$n)[)y]e }?&TS6)EձbJތJJ+[`VSDg*io@~qFM'O~p y`K`֣}R ?N 8g?vU*oʲ{OL$I% Ӹa+5gYﺁcWYۙgO=3vvOK$t8@{d[prFjS>yF[QIUe3#C3,eN-^*4˖iMF&ys JӆaK@,/SJ2!f#TqNp]<|-vň qO8yhG+1|E|&=ex ~A7>-էk{Y0%?4G,pg|'߶uYkx Ɍ '~;ǪLC}ɇ:Sx*2 m$eK ,ҋ}eq io@>sJT7:HgEQXj߷]7I'ː5@s jܑ|qVΏ T&`m 瘡,~P?mO:%ıRfsnX&_)td@&=tՏދADQ!ꉚyiskб,"I#9VϹŵ gN_=hZoۓ>jrjso x#jX}+~8jq mdL#ăQ)/3 >|"Ny'9E#DQ+ |*QF4|6܊w=xV>~ )X~./Vv^"ϿvQݸ~?%oC^-爱w bi9̈́]5\&ڌpQv]s*لFO/ܹw *݆|'ml(ʋO߰vpvǻn͸ѳH;BB\wg|sgo0|mO~!~ϻe]ѱ[3G>M-'_8fYˇmg>(WӱFo][-,sg峏</ ^9m&-*oo^/[={erٻklKlсs9{~&{o԰<+7Ƀxǎy{'剟@d? Q<G]Aa*NaQLܣ6ŸŸW“۟1&&y&d=|;g̖*eJQ&M+/A-@|vz7\P;tc }u4b>ٴ&tO9 䴅""""""pE`G7f=7 [7.;+mn`_xz݁zF7<,_w4y?xW?愊ɶU>ywG/Jv/$Gl|P^{/ߣS' +|vy҅?JpkXމ)ܠ+8:{:{0oN8)Fdaͷn'lC" ?_zi b%ԡ~yR5&_W^O )w!!G`;eHcijɣZ w=i gs 2cOʷ^Gt_p{cgy|׭rЧţīGr:._~f& c'LHUc;M*_CWOcN˾PվcgdGwEɷ},cċF&ྡ( tC>ذ|k}mZ$Ń;_N>w(L Iwg$a߈0pê^>KANOոA6?k1q>4=Z|l'4YRMޟ:7(O藗/4vvg.]z!}(yf; { Awq\z9u|-χe7ʗ"y?:d'q,o#+27@_ƒ >=n/k8aw"߼*LzەȻhD߄x+E`l謌 J Y0(cx|KO_'2g {adb R^|o6|%X"ʗ Xp]a>|>E.$困_oQح K 3 4XBQNl$E旉&/s9mf42*.Ia9Ff2}xΑ rG&dfMwhp1,e گshMo2!Z$>'%꙼G]/"Έ GO@ ,c[cdkJ_I#dq>ɒGC?YΝL$ks*Xy_c͖}?:GL㘓1ln%Y(㐙`B_ca]6l ~V̽sy?c{ 3MO妔RRRVH ;HKam.@^.6O#yc4)V|G "ܬshMulh ~-~,~w?x>ҷ,߽-͗Z%KW,AZ~Wlۯɲo^'ӦL}\{ݿY==q7t|~ p yXzYK9> ئHnw;~WJstL%@<NpX,X.%}]#y|LCBF/ Ay?e߯.u]#׿/l3IoOn_g[&ɺe-TsFu>&_Z2= 4,|l4~߮oCXnkgȭݘn_ *V2 Ҧ42f-[䫊#ޕ6GNBw0mYi23eK_>+_p`]gËyM-Dlޘic6gcG_n FWC^$?!.k'*po&ʽ~ᙵXרmSu2(mȃnV߁o^j˛dь{Yu 8M-rNlپSV?|GfɪEϾC}yoӻhyP݊4f2YR瑮IROb;!;v.wע~7TNaCOd^.W8_g#Q83\ o滋Da8 =KUe5@5/9TFEP0=*A\"3+ R.YyTLyo PaiMuJ s >f?'Hxх$~goKg|>Sαp0FLd"y] : +^pъ#ēb-y4_Tdg}MH`<$]%hb@@@@ҵffɖ;DgD7y9y#7(/Y&k-it4cG|5r$Gȓ~pS~Gg֙Es;,X(X.-CzXX"-mf@Y!]\m,܀oH)uSgB N7B茓߸t ?X\/*Ck.* tdF}vrj$W˖Moˣx&ȉm\4:/:B"Yrהy"v-} c3ht'I{F4آ>'?Q(|6 : .3 @lCz=c5Z"d+ղ~Ω_OG> {D{@|YF@&^Wv̧|&1Z9\9 Ӓ>|FKm,6k};a[81Fʡp?XZ $C9 Pb~:`rsNĶ͸%m4J&=7N#Ott̼^-ǽ]nik?#GNJ?'$:T'-@462 #VP4Ș#׊,+Ӡ4ƌ>k5akDJg7O@Ow ǖnsJhVؑMa46I4ÖzXqbߝ1 o g#Y_D9]߉UN9 &m0N6@/ t殾*ꐔıZxpp J-=܀ӂ&١R7[Ygz|NԾa'.jk8n׆G0o:ϣ 'O}=XK͝#C6/h?IN\e~Fgï-OI; X#Lm܉U@2ދ75F׻mGLq+MWsD_ ho'K5..kW_-͕/@ɇ&c Hb@'oqwOl|[q¼w-td[-kw̕ y3(bF230[z2Y⟅'ΎD91a1,_!>Xgķ,#ukR EIk`# p*x@ Ĩ *įt&{[.~DҖ/LD/Xi/,>`R>`G+TjUP8S=k)Gv2Ŋ8Ƹdˢ c:t7}1BLҋqG=>9>A{(h|vC? &0N>U2xtsKT}..-Fkmp>= N fe䕟}Hi Xk=:C OX,Y::)ooMN4?%SU_'eG?"M?&_ĬO>|zOЕl~_Ge?8f# 1uV7z'i@,yOGgrF<夂>t@!78C{F8ޟO[9{ i%|~vч5J|{a|oF]s|ר_kldoe'b1#ŵXlg_X͛/_3K6,Z;#vFђ>l|MXEf KdUÔ8[gJOv^@7^ijB,k!f_ups^`0pEvDI:?߽w68cFOڶ~1:cFC19_mG2&LAbcd&m~PF.dKvSH20C`5=FKWFcKO78 $y.$uIL1 re*|4Bq |2֚/FL{$+lovc&'K p|gI[VM([K֯@i_ &Pꉋq+Yd':B/2>y}\*m7Ai8{x\%B?$ u&ȟ&KT)*k], !uXC_shrG_$svD|?}+#T1~$,;/*?x|)1ފ=o Xy2Y_={0>|/dK=wdk[egojg9'P,Z"i &71?E7˖ӵrꅺ0ЇЛixx+ȦO,-K͐D6vĬў^+_ 軿z_Wn-f&<3^v ڱU>{ede#=镧͍p_sY[0+=/ojw6e,^ʏ\F oQ'퐿X},&T5S^o NW?~hʳ_IOWv;gFC^MSwI{eK$hVHSH_5E.^!):};HzYv`PV/%{Fl{O6ގ3JG9)͕LG ^~-r3a7)Sel&w ?;%-S'C]9MOڡnm73bՕ]&?^.Hoknۏ X+w-oS},Zz5K cPV-)w5z/g %D kfN"}$^/^9OVX2W<߳]j,eGp?]n'C) qMlu@tw!᎛Γeˮf58ij/&%Ø\,/$kDZXBMn_>kt}|d0_-]"̈́Gzrc3W2B!!Іkw _S#Ƨ;g:qMrm׶k=p{d띲f*s&~t C%CZuB-ܔq9zI vƀ0e{ 7!;yd&YUdXWNGv,AmW"ḥO&Nь} gi[Ӷxv0ٺ34reG؜C/Uۘ|f; a;9'[P0SsO>X59Y/'p3P)}*1qQ|)x1RG4švH_|_}|*P*{L.k5?BǥZV`->BOiXy×*nĂ$>rT=4=c+<344\&ei4"yߍh,zd dtm"6}t&YbX'~ߡ q<{,p]|U`tJSCo=._ƽMIHm}q9[ֽT-?i,1mїߗEdm>8fIeh۫q]<-J4y>9Xv"^\ w̪kg"ux/Me- Y ߅z?&9>&E #@d0EU(ga61UfJ*ƀ#{g(R|Ɠʇ|4ޘN>Y䎃wFt"HwlnhÓDg~ctV8g"Q~x! 8JxR*& UyQ94m|8Bl,_2Iŏ |q>_8Yc5&~@RxKstKЍze@ҹ >d_эP?GUv{ctQ𣖢ZѝX Z1<&0 A>kU-Ϯvh Ǭ%zcm1ȧ0eM'9v;`pʩ_91/xS LkZZ{袰:Gp[$S̚/S?kyN"y?JQ{^\EJr?ǥck6 $l8VC/Z-a_|UN;%\DO0x xajb lƒ^ P&$|`8EH(*¯O~Fmf<<}_G\T5Gc8z|C&Y,zS.񟴛69ϭ[-{vdٷ扥"GI4]0)o F/Y~#|޵+O#d4ntݳ@v9Y΄TgDIS$fܧa>`<{;FB]Xޓ-wU"!,iy ˟+B@,*s|r8|ۋɆF7Ƕ"n]=ﻱUo>vYab+@_ [߇Bj“&*rpEQfs%S܉y} ) N ^Zф|Ea ]ÐX is׶܍K{oѥ@[L;Gqg2RFs1գ˿-f+3Z2c3+{̀ۅe<$Fڣo؅z1Bb|}c5yH<2n剽~EE}ZwHAH\HkaR|X7z=-,];E^v=WVx$5A?;_nN};s̛ed9GF?#kZmv5{9&q"5"TS.#4Eψ<,Ne\ʢ<*2lRHDݑe$ &l)SŚ,(['@Rw3ΙB{1;Tp{6¸gkzfϳkJx!卑e9f9SY.LcYxxbDJE Иס,LxomLsJ~TP?q5эpUsC5>й%"?c™H#!{ G^Ѡ+泵Dym_űb$**U '8^U]Lbrvx/_2;EY:NœQc@y ac'/J;g8CGB&C]Ltg(Nµ揵DU?m6F٥͍YœvL<8Ê;75=STs5S:TLjϜXS#=߅c1 zl~>qkc0hC9.I}c̊FFo;9V_*jqJV`"S`<x{C|Q[VƑ6 b7284hB @@@@@@@sxPzx핿\MN=xLܔx}1ˉfʓE W?Luw=9cvB;cͥW|)'/VsP)!!g%m{ LPZאs< yM"l61:ye~a^b%NlЎVȪMF(u(r#͖-slXd،4eIș.uɳ}ӍǪ$.-Yܰi:&l,{@IDAT1o}||MoWՄJm107>&7Җ);b >  j08<&VV`&~d;^T`|nL(!!!!!!R|u|FYyCOKC%8}T_ӷ"[_ycT^c\`"Dpk˰](;\B'#oYr%%|Prcky` ªi+p#Wl~Zk8oS/ɾO+3Buټ:`2c§uYđ5%N=e8k {L(ťıP5mЁ^(%[6fKP5͆[ҟV 4Wdت^5"JGOåҶj>_@ k~r߰ee*b񢬮A7B@ĕۚM< @YlK&`|v?M8=.a>IOUo84\D)M3Z:c("rBYz`Sד0# W%$ HF` r_j3&E{ȎmmI~l=X)3曲m#rmkkl{sr{ur|dΙ o7{Ty;g/@b 3Q$^cWGN2,ZϊlXyu"vQNKj~ GӖS2%.1P4,WΨ8 fD>XrS4I0ъ V}c9tqc$3ifWg4@eBVoK' І὆uL"?e̞Eű;QZbcxzlM)Hki=2Q#[*u;BuA?S9o19<[z6B WgvS!x>=Re~5 mR%iַqy AU:uey!MF2jmL/XT}w BBBBB#olv"% ?/(7E<1J@@@@@@@6G䩊rzE`jHVRwR* ?3rc>g}?oR͛ˋ[* {wy'!å4R$(0D8 \'ItT~.p/41ϡiupA 3dوi$4_3Aek"T@qNR=[CSl FTuGIhCXʙ&tnF>;,t`LrO$}o[yEA90VXqRLɵ5Rk{(s6.aJi^(!!c%cŭk~{|Sqz@*je1%\tyFkCw̩#ڱŮ;"I? 3֤=+PWMKF\%M>a_lla+irqi}V pE}.QJ/VԴ5DJg,>I𳛌C T/7Hæ/C,F|=>Z-7b&qt>:)h6M{HܳqLx>SYU_Qbczı1/|&D$O'IVHWor u{8/D D D D D D D D D D D D DRЫ|"3D D JVmJ@4T h -`(Dwg!5SqeI`)Y,>ZF,I;RGX1 elrsomy&5O~ccֳaxg.n(ZSԩG$o_e!y?VN[:#Nv3qu %D D D D D D D D D D D D D D D D D D D`EUZ?N&FfrH]RO,Z!uwp+>.ZY2ePoo9mugz_!:Ivm/F,_>{.0oHoٹ5['d1}rdP'b<]rrAp*ڥ.yՍn2s'ω? ֱQPNeQfr _p-]z#V[7E"kdK}TL#5nJ|?WH7K]I)$ dfSCf=~R;_\}sRN m;}L_CHno[v,ґ#H/WΛ*]H8Lj>C&Kގd2uʔ8p,l{R{ӕK'Sr¢?$i @aFzC2QjG;%JYsa8rs&j J39TK2ǂi ŷX2P;Gx&rbtë- 'c ~ f3s䢍. }D(g#9*/OӱkꟳJXe)l-I6^vzGDX+7~>F1و9TQ>[%j 6%:EF:e~j|#3@gR%`pF} Ю'c,f|1|Ak'ODپHq&c6# ;>x$L0Vkd*ɟZ |1+ !? 0ۏɒT8v䌯Qфd@Ӳڼ!D|D #2pcp-D D D D D࢈X>y CԄ$I8I]̰!\#ugԡr)<@"3\slB 3vC`iJmFώ*mvj@Fy:ƄJk,\hI̝@8K: =ݽxHOLuI]r_^YݛTNlJBByc_ Yͳh> ^ ^=ўA6iϔ^%KV^҃ӯAh\kHu1ؿSN1[ \Yxۇ4y?й_%]݈T#YWG~pXgQuTbL$]G}쿢F繝apϢTM zOq]jM#5+d";.Klj AQy/NNg~k#6>Duyp^Bqo|;R_~8hUOc(h֓Ey|i`1ɖQ//asG??[V_6w-,y>KIʥ]8$tgC[~+s]8#ghEOLҞepxtp3CdXI%ϿTeoX**Uq10^Y|“%FYN26Gd-jdp9x5^pm] 骧99tJnV.bGsB_g,sR_oBt{g1_q\=IE8a;9EfLZP&7i{Ȅ?jq߾Qi',2 ̎>g]AfHeMұX{d[-az 9&g/iӰ fK߸&ZBo~Bo}$Ӹ| =;"wc)xUH~ysSf,y c.5gLFNm;MH߃BƛcF=Ƶ7?߾roW"6fw}i\xT5AQ*,=D&BNYz opb>Y8AN!;Gqt~Jv66{VuͽRz#BcgHW~eʴi>$pe褜:*zUH#)n2*V `,P:NM W |{J^VKU>!Cf`LNU89C5mS&qj9Wg2 ؂QFnV_* cdc]8LV[g"Qa0+[䐨5r8j,Zф#:.ȩ^:i\!=ھ0Fë)h }IF7=lg8-x*&:Pu}|x,5 A7}!Ӄh!/`} ƫ<CVuVJ.&Eǎ+>Gy:v?c%b4׍/F5aX>ƺ^2IJ3r%L R?vi&xGz40{BM6 Y<2T$'/[ &ϗk?']6&Qcu3RXSr=ұinAjoKh,zY^wrBndƴ9u؈bcyy&KӝR7 c@2ƼaZ|ω= fa&nv9'܉%tx9[򚫰Wk(BSo/+ bD=>@+0O& ʀ9%IG̩*?W^}LŒUhCa?ЅT&L"oyj1/r8RW xn</x噺ZD$!$A0GԱQp|_ߣ $#?wc)s||G:ڤC&L[. H]n:w\[Ç͘r23̐n)3e91|H 4rQ&1sJW 0,I4Ifef;筎 z=N(VI:+yz?*+l$RJ~^bpdBҹoKUSZ{`R D?݇O UQh*6ŏ<#o[?)Sp e'JOoXjGSrd g,r3)sbyIx#~Q&.T 2!4d-?nUkct4=I<~<~5|֖=4{YApqǟR 58p V)n6~w)¤=y9S0Ei3 86fJZl7_О F1P!NP >k}I|R:oz'ncHزU{^xTl{䉱cvIe<.|[Oefͥm0ОA]ZM^s]5~dY >tu.j lϯ9q wva`!!!!!!!!!!!!!!!$|J@EZ~s-m.xU+~E4,r{.x};_MMYI(IWE3?D~<߻G/odpgv>oC/4\~C&;B@=yJ7Hf 2i2xa+ZrS|v~K'$@a zSB&knq,cd@zCQ-D_`j4Ln_ =Qgr,7Bsr?\0\%9bI|diƒo~ Gae;/7_Ӎ4yiLqpt DҘ\JKեϙ=X>VaYoRQlѥʡ&0ԛZ('`~,6>g݆r,4Ibq>OLsdʘ _8k&ep-衟,ax30 ~=9bmNEAc:_ ^#ҸL~ _ ι|(/sL?Uя?@CaO0N+k6ې;5 )D D D D D D D D D D Dࢊ%E?ox.7#d-|֜ZpA<2wQerROd]= -L>cB\B5Oq,j/]gN˄ڙ2Ogz(oX4GV> 03Ϋ0!=U:~ۏ `v(KYkr-lzbl阶lhgG[^ljg*TO(L \G %)_tF3xMpZ%Vq>ʼntQdKI1cCzR PKRȖ?Ц0 ҒFm]A4r)㉚CfL9X&o->3;'#QG4'*jšG g3=$ *ZQ[z^B,!?>kU@@@@@@@@@@؈?0 ^snKұ,cΣ>#ƒ|ط;IӌYmV,c^3μoH/6o^oϳ`W÷^'H]娎:x yn|PI3w@ܱ wbrRhʑǰTG6yz{tۼb6η'ɒ%R;UfM8Oݯ若N%~$W^}N {tJm}TdzCV?p+0Jc hp8cl>ͻ^f46Lj#MD]v!f+!?&;| 2/o )5/}Ly-?0XG0rO,xn"o;dҫ /(P7>qɤ?ic3IZi&q+q~uJMQ΂;̍})`haݖ>z_ѦsiL ڒ ?y~]SBfpOTL+JO3 հ+?>Ld8: } c|L[`v&̶Oq>TSIQ~&G/c2J209+ᓶ ̦֩r6 Ty@`,% }h 6ٴ <H5WVa,STb0}OHd?% |7iG<xx 24UF`kc~Knpo _ǟ}U9э:]"=4\7-(} djz\xu唁^j]LM?L,S̠lp@(i~襭2 O^ 'Z-ۑZdѝ%lYlQZsz2˓NM%"w~GsV}#OEA'UgW$cYHv?ti( S1a_oX|cķ[ No)hћ,*GwBzv&wA7x]}]j𘯖x\׮_"~tu8+fr%=msox@םAHm$?>76Col*N@>`:teDPwtҙ:k"ܑ\o^@O,jW4j픴a,ZAbYF]B਴‹I%A>q^$茎ƏUbO;{pL5钎CS0g"t%[)|GgT^MØK!((g-0qO޵*"Jk-{6\G> b]T6γo4x7.[ eY'D3C>2KZ?F4\a}J$u o`36Jz@љhxy &9P&P9ؖз8}fa;T%2Ad,Mĕ+gןcP ƈg89kO'їQ!Q,7Yo_(lΨ۪~*B!O8SmI ql˾EFؗ>+dK;h0/%~~[x8('XHno=&y,q,aY͸ +Ys66ev~vA[VƁ6 b7284hyQ@p* ~|)xHcIR| Zgt:7zk5 /t'"8*G\r 宥G}>o48=OtէcqXӰi}8o>C]nP#p8y,0.T7u>O|?,($_bYIQ1ًc>`&$#f?ĄHjIt3iTG>iWcߓ]_& & j|~q1axWOI>҉3]>18n:u-) `ecg5QT/uRGy9> Gr[TQ!es 3q\3YϗW70Ӟc¹ I2k&a^_"4yg:'-1C  Rx|1 猍虹J>"cOגLi2*8DJI\B4&.&^[ w4to8M}4BŇq&0j%UpVνu /6i{iwHQ}Ǐ&"Ƙ$pꁏ7bM9nM&jmRإ._I#DL|#|Y5-Ƨcr6k%O3-WUݹ*"#%u}7x/< <3/.~qXؘ^nÏK.$ف'fpcx_6͗ w)i4^8GɑL㷛L tGj:_>dݯt%%-yLh&u&3\efN:TC&KM$i2e+&_ Ew {bB1dK٧jt 䲶#џhe}U=3Fg)iDz[;3 O؈QYeI:0;̎ͲН2|_bnle06Z7-{ԣ8FڤH#d])䬱4"Jet+J'7)1~Uԟ ~g8S9]㙞x=FɎrdGUqa"U,O|yb6\X[O(XD)W tR3,.eՕ(cӜ)1Tul^(ϡsZ[JX?<;ӎ\Yԯ dF5tJ@3a>clhFa_-SW֍8vس.=`LxRgmX(k"_ F:}~*g8v=^4͗Hz@Q5>v<7 ܏zt W^K\&j|f}8N#aϖt Jeo,dP>*e•þƎxWll (!?ܝNd.BO#dD.>nʖ,KPZo|,fcx[גEZkrc[ҟd2Iy)ZV_+'\ =F\-Rԛmc1ʊi%q}6P֒i-}؄G Q\c"ץVTdx%yl i \'LyDxm [27^&#4(Txdj}vsmԋɑWgv2q( _p7iK==I#m̶əiI7XTk!zlnڲ$3qSoZg j3_a=i5yTgxlm$}H|~k8{<> L/^Zѷ|I\8 S9Kƍ}+ qBBBBBBBBBBBBBBBB\-(56>< %D`4"{'`I000'*%@c%ל+D?> 2@$}EI jt x4Ih8m܇mfq )Ӟhlo&)cdKZR7#-?l_뛸Z[ޤyL0 'H?!& `!kq-"'CSX_[GW&>8W.㯾ЦgeѭM]O@}NBV90&x<HSFӠgR!v/J!Y<UtX%3k0㞕爞GWhrꄓJ8Vlqچ8ݱaX!!!!!!!!!!!!!!!!!ÎR  #x}K3B% NH1hIzR4LWjLⓇy.  CY-=aZtcRWlR:@GChSD8F:kj"h0 mckU^3c4!SB=ziוfpשzg |u(&-IeB]~ [KN!Xu~wUƗ ,)V?x4ǫ/@ @Zef'l\:bm5ߒ~3Ne>ʫ ~$l>VUqʐk\B9'6]KXaM0*y4^:o@޵ZCA +sbVVt\?1ɗ,~Ҩ;H)0@~IW?$cOʇ>y6FW}ŀbɋy1I]4mOī$q10_`kU yBߘxӶ%@9T'qIWБ,c-k1ИIY6GWfۓr|0fցZP1^;YiSv~ډ W'D*3H0߃g5HC~. əށhI}Wۚ Tʄ۳,6&UC8z[ $d* "̗/?JQt'6Ps -UHN\JGw1Lʰ43YxPή}n;=O7qkxN.)COrlp:yf4G-y$W`4 q<-#U־ko }c2}FI#Q4h5i萨}0})N^' z$w/Pkc6>LUco:-?~=0ql!L)?`:9b?%E&`+8R6, bˤ~S?5@:t@,؊}+cA|#_]UvA0b*Y%N3S&, Rrбr@IDAT6-\wX۽@H=ۺmؘMF!<}7ɥgB)6|r >sd&)?ʶE^A˶.Zm?17Uڴ]BX]U~SY-p<Gvr:=yUɼ ƊR#? y@:tjBϡQ:66xjGkSTQn!_4^ia |@AiyX9mmjLi`@6DU n-ړKפI֤e8h @(66`UstT57%Yz/tX}L^/w;|IkfޑR inȩ\>HFK?t9ʸ?y;.?bӪHrلR[gvUmyD9Q\t Bb5r489|Q 0 :.sє<24% T"]"3ph?vJLQXYOD '=LQ)<-jj#|IIsd[NJ~:0P{N /kv0V8; " o迀0CTq@Gjպٝ zTLݞWCOX5 ȶ'|۷grDAz]9^8ǠM[9_PDmAy,2ak:lJƺ ۶{K21uk/T.x$EC,H-9}h(8m &1ٌ1> 1=x?w'hcK:79shֈvy* m]Mئ ښӷY@W쭸oi/$Eum:ݠծAvugSVLJͶ9mc_IĎo;KYGy 1?Kr{JIæ5ɰ}j软jx,rx7)Bep wnoP!@ZM3?K G?W|@VC߆+~0?;ɝp72!7c"XubR&r?UIve>33K֔m M lqUʜVׅH),㇋{*s#{x#{DnG rCvG ZPWd~,WǙ^!N xDX ǔS}A߳~>mNU^=ӻE:OF03 |.PT(SEKhGliSjkC4)0%o+1kv8ɎxM@wT1ft{V䳥A+r1 &~(ǼWɏO)8a!Pnc~_XX|ߞ-7t=h% 4;RPhفpzߢa>fr#.ƽ^p#?ҽ5@:t .4煏ix;z!Jo mc=0>+!~-#VRm,{D\ɉgnI9z(O(^qEs6${V6)gkZ<|/}K{c%۰] Mg lG@,@;DFeãzC?m4=LGB.\pTRoYy iŹF]F ArRYT=wJ(J @}BV1^h5mI3ǎi'08vЪ6}=-/"cB2nsIՒܱ^]tG0y@:tL>ftL??IVVa]yɍoۗc/ڜvx;R\-~^Qw)6֥:t:Zy>Y9aa!;{TχBX,_WXξ[ K׎/-,gjU]~DaaBBRM _jnJ9v믿h{ƳzV[P[u[. FSس s E^QyG<$iiP}Ty3BXV{/'뭇wW6#TVE-x'-ʖ[Ak7I\X|񕚎>US}eJrhWPE:Mh:D6".^'G9='/8iNҧpa㨻ٴiF!-̌Ȏ{|6n} 9vôrl>' ff*<#;qR&趭ٺ":7%oǔ#uVw5deW9z\*aSE_,M9SlvT.N> pMKOi#^K$cʜ'  hjxkʃaðHQa>!ߘ'O=8{ȊmQ)`80r47۩D t:rV޻l Br}7Ç 7O 2}DdF8Jz.*xn] +t-gIzF+OuXWoM!wyˆh…" G%wIrA^{Tv?K]% wn7Zq^z%հg?+ v+s?@~7~x [[+au=UAݰZ`fO^ww䱋ُ}FVؼFXy[g _<sսsaAk hO[~-uzB&|H+%*{di3ᙥh¾s?*x-wo)XXV˻n?vXYY zGwzwnIcu0-υoD$?Op EJ$GuEN" qsSِr8  I>N<)u/W 3^L^Mz`P75Z;6I+_?c=w4'xOgŜ5vwģ۱7wֶw_:TVin z`bq_w1z%~>%۩6$pfk(%u 6O:XmnC$ʬ/| FAuUkpUK:ʤT/ewpk_UǴ^[S8LG Z!pO%lKwaSxlM}LNrؘ ߺT]]6r}GIW]qLX8J7|%nxonDa˗3pϋ8,cżJ?:y}Q}EȯsKgg]?73\pRx楏W_W Qo%r䞮ݒUumi>Jb׀Z8yxW[>r;j{z |6|s!ONdx Cw߱հ;P{{_'+=agyBVx2/~e2̾IwH[wc~ ޿_+^/~>|XN KRc<<ꬫ."eR;\ Ky5Eu9"D9= mt:5odc !m 2@2=؆˼njĄoLw*tq`LC.Paɋ ^R[WuDvãGaK϶8BB=w lƲ/\j+eۖR:h\62M`.a^ҥxA}682 FEAA1V m 3䶒"jʫPCTR8_-X6@9ICjFݗ#ɢ{Ri9&&vY.;嵓vD4l~j4 n"|xsBlU.89li?9[K9bұ&5!Z5 oR WInDؠ" AA#П#,Sj A49.˦1ʪUm>71\@`vqsb77ymENij O]APrPA=˶LdFek|({ŜRۖ $澺JXAR:T}({Hβ3qeF4sXpy3(lGZt req ]_ԕI6О2fq5nfu➀2nb!hOޯϘט^i(elgDE=e%͛NjX_z˓%+iK3ӿ/+&N'Q߿o >'OlWU%}C\[27Wlx&'i;a ͯ*mr9r6f1iv ŏkaφg_ Ù1ÕuI5Xl΋ J^p  e/WfWh9 'ah~Ś" @|B4 <8PI떄4.oXc x҂jB㗾WDTI]ILxs?NH^xq5Nx-.)w ƤY' /L Ǵ}{9FFM,vIb6$4\6&4`p< 1UXmY"|FQp"MMdݎ&ڄ,]r+S+N񸼴Mh:Q00. ";dى)kHL.Λ-h&}Ix"`Ⱦvy@=rloHY4m{H$A v91'ɸGW*\yWၤ&#QJGAF}\ے!O(aǨA?Vsۜ3&%Cۍ=6ebr:vFSVf&=mPJ=źz|13q/,Cw欚C]Ɵ.H8ډVR&}#U6deI5э՜v{\@O.$%$DYRM/"+6u;RaS޴e_Q*(^D8MP\D Fmm~"bnI0nzaAeh;|Fk?;n}'l+km6qy˵Y|#? G!5@a9v2F,{kZ}٨,T:o,j\65]>1F8p[.sKfymCsskk&3::dP01M4HJ)ϐ6*,˦Q|G]KsCQ'T9,i3ID;vk]VQRXzQ ڎ]&?W/i/g±sںœb;78]]i=]pa/pjf2,'ܬ+{W8ܻ«z9̟<[EWa2bm\m{s8vw<߬W=b _rQ 8υUi2'iĭ{o?fN$ڽc/VzCfJ_ i^/eUy VfBZ )jC~^8QؾW K{˗E:wwu8"Kӟ Kz>GC&|a/ڮ; ~1S{̯T$94Q G})qCfS| d].<uaD? '*@#r6fcpa'LA]E*ih/ϑ J[)БkbA6Czf ]m?k y xPU; oi6ܱ`h%[8 xIʧ}6ʨf'I0.v  D6@M=[Ap,'jQB2~\j~ğY2:OK{I/8NVrD%Vezft>Fpܗz=Ә$poD=f?VzUqpcB~hNn5#os r +w+6 2@Hޏ?W{G/tmwAC0ɢҙK5o$ʛՓ)6R6ooP5Gn9֪ׄsn2VA,k&?8=  3H?z(2Wg69ħŹoZ|ՙg^3/E=&l05K^L9zymt?l9X+󙯀s<#&)f ˉu_g0uB?e iүK[ V -t/ښVڝ j^PYRV~ҧ~-Eg=}wOwe->v뵒PrK)EaQ߮lxtf\ ܫwWA%'~6ljշt8wz)_7R\O!+#pųa2L*1Pp"~w}L\$ҧ?ڗ $}_f6)Ϟn /?߄d./ \~ax3WnKVJx/[ ~±? ϾxbwOeoO{f 4‰s Bŝ0+{O(v~nWq`>}asZNc7-vJR^KѮUvקĩN'KZ~Sy h}MtJK):*z==HfˑkmvU&n$CׯWU\肶FO±'a?Ж|i ˓cGTS9Gy ė05#VʛVvDEoꤚZ]`Tn'ȑCӤa62 9r2MՔ0&EVfYs7GafD7%$}`qNo*J'zN v"oU jxS(Sr@,mҐ* 4Mh kU4t9.h(]u椞%'(ڧ֞eR}r!JOk2.&Q<K$RF5Tʟ9v.8𡗮;IOZMcF;ܜs<5̋G_*\rhMU9(T(`N{ƨa}쯄˧é=~U sNa} JRISTyέOg±35 a}DXN|_[OE/]0pkP|C+ mWxp ӠS;SũH4iҜr\eSjqy #U<9η~!E+bTw]AhDg#zLl 򺎴ކԗ^6A]j3e:%cRSVxቶMWPqӿ3+{ gS߷Њb|mR^x F 0M6h8[$)eq.SG$pxftH^`0vxTKb C"Lqd~ jIaMe/{HiN9kF,$wXS?ڮ=ZmE[NH% lLmNC'9 ЀBz#=pz P\v7c hM?Qquö?*%+,u嘄?μ͆Qt4"j*c|\6r @9}F#[gr\y-YDrBqe˸uYF V1&1eRX$ȎscmcڼƜƵ]M_-YbM@r6s g/y}J`O/N-w07s,쬉"ŏښ|z"$ݤml}rRAٗWS6u΄([ B8ΞQ{0UԉF+wD{K+坪 O"$ uv(P g>h[?^0mdD.V-i* m@1 S1mzZUǔJe[ܤ}i= 7K?W{hNZ[%j,ߗǑ#vX%ܚфW@/yub,>ˋ'Az7s((uc^d@ ޻CW&?_oI>q-@x#ʿsǶqmMo"}s[*.JG_#3H raT0H(k*+17 xk;HNJ9S]=Ge{v#(NPط/; F ?rͩ(b`F!A)5`Z-<-9ߜ Ti% ]^OaF8~#̺~<f91 vmX gl9hcIjԒ ^yrb K]EpL+X Ne>{MI"/x%QO|TG:zR]m$C;Hf?. ޫnzJ6:6ztJ0ys.uNAXrNͥ9&GW(Rւ/!-WTΡM*) W'%K[u&9rF\W@IDAT{hGm96,e͇=|Eovs7!g.+o4qMfі*V6֠9Tg)уHS1i&4ǎT޴2r= }ƚeRPEtMvyƥf(zcT0k\6 KmK]O]n`emn4CME #ч)f:˦~"n\r2TdG=끌q;5pgezFwx? E'kx4 ŀ)NjW\cpLiRV:'}!Y56ּF;"7sUE'6;I tm$ETqECp#u c-u=Ņ6w%af-#Uh4e;=Rnh)Kᣖan'#V*pzS7,-‘&,rz[sݩ}eC֟L(-0Lfym~3zp-)w/TQ'lOmsQ_htj'BP{Hڗ>1#Rb_*,ch>r^d>X,BL% ~c'moj&D/WQ}~s+gl0nr =e;#h 2sLꘗ9L$;Ik&]Buv4RnoJdaoO?bE.ul1sdؗ#.aM! sl3dT=Qm [քvIx $ڽr6T r5#ߨ~(ѽ~_DWam= !5T+vCfET sy4SׯXZJluN|!wĴ{me\lI2"? ܀z4WuZkLj#C#'+ ;nr^ڲmU&ɪ^ lₓhV4aSM0Z^ :?=nOHmzd+v؝=LLYJ=n"Kq]ИS*ctHDǂ ~w8uA8:#am  &%IG./ToyJeϡMv8M)|&L<1ɡOyTY Ñn7zusgz䓊Mc/|\s̼Xa: ҪX o-veţ| gg&’u cҥ֖7%ȵЂ .( ^a?rҥ:yz^"p;zE#?U6̿e7Ԯ>KeG'Z24~t9[P2d`㓿U{x:myl br_v@[8iqQlEÆݞR q~rm4>d{##!:Q?O"^߹sM|6 hٶŽ%u2yX'a7/㺦ۈ O^AI.ymރSI$6S9+>V௫m[[aF; R&?L7Ys[ hpSH[o'2X:|Ƣ%̤N`xoQіPm+MK·=)ڞk<rm}}O%s qp0|TSc: VIVYNWkӚ $.>@9oL>6KW=rhzMlmكiC 0WLSAYlYDk{Z]ߺy7\yA(({x ߬e˧N>{2=6koM92Bovr (4N]5f댣AALXRN7#&flǦAC*ÕZl 4&xǜfzBpvKB0jv㳟~Ĺ6 =dj3cXTMа-h Mj7< Rַ4+VyJki1c4=1Fq 3}B=mM tWڝH:UHMQR"N9Q7Bp^8҄R8zM7##e 4"km/2gfS>+g/@Vllj͢ߊ7yĤ~FabG\$RiڄNb)ֽM)4R^n ekJ(4ONqnF/=N)>0q /)<hu|H`A8fiO^JueBE`-ź/F% 9`8+,(=fznޔGY<-֥ $բ?N٥/|T9q壴7'mFZN6V)޺-g" ԅp^7õzX&[i Rsੜr[ٛt6;cܲ Kx{'%;CA:yla>̓)_e̹YAuNA4_ImG68lC9(n% ,`"8I9,HKD\*sQ<fQ>I7#k6(=@6$lKDlXkml7e٩ADh>yCe n/8 4N%2DQm hJ1glqäVE ;a< _cۊ@tԇ `4Qx0@mEɩrJZt"tGYaj{pٶ3`&W%iz8vp1=,0-MX $"a2^r ,6 e`')nPvcp:"u2} p[26d yr`=4 'q#wӚH.ˎ#y)ˀƊPN> UAPrn4L+=;;k6_=JK٧'9~`#Af<tT%JƇM*W*J.'T)q:h&5Y`" .h5ܴ{wU+g[%;4gGKQ߷Hbܤz_c&2S>puMu=iwE兂Q@jBP-#sZ%*+Q#SVoö^rlr$G6YizeŶb]8mGq6d4ge:ۆf{ uסQ'"/uHoEn$VLR\Z6%8O˹7 $~P,"^ :zq]O1#MR)?[08>L8Hq]yiC8vʄ2~vueI&4>'͇ ƌÊmmu]:8ERߑ{ϫآ=#J&c/*ipLqvH^ 4V&ع/%Oۇm'6zKS'&/Ȳ;è 㲻At6(dž~ß[=㥗Cxz1IU}3S4l{ 3ټQi[9L @z9'8!\a螤t^op"kXa; `sP0OA֥8 f ā \?aX0!|Srw'UGsX{6YΛtX[v)MÊ&$e6yW}VCdfg1ttw +Jj\-er&e$ f?rumt > )^yr" )kI=[S[ڂrV|)id0KZ1T9#HzJiӲJ?E}`fjawSVݾ}#]uDkAH̺l1L ?^Q.jHw&Hħس0:Oi# $Ҷȅ'C,ë '3jC}Ӟoj{rm%ϷP-޷TڣzfPi;) Oǚxj ͞B!3"̓Z=?nF;}u[:fv"Qyv8`B.H 5*yy&ht՟]k:t<=o߼w {'=E`xK䩾66x*'*b^eɕK*KyrM OmҤs>9vf-ǭ/G~?[}d}]7U)T&096cRMg!SMHݐ6x9N$ 9㚷s;z"dž,zFPF? 0.iFU=܋K>Mpmu>a2z. 0v @36`?&YllSV$uzr'vKWylj/#i~ϟ5;`ayoO~IY?=gzILN1AhEP/Czlt|%2Є$hET/aJ2k!V2*6bQ hyhrX:_o?gǟҋl?߄m箍%ңa3w[< f<?,Ϯ:G`p%>enHZ&{`!:Lo^88˲$?n749 ^t*/1&@Kyn- >DS ֛`ڕ گ6Np*MF4HOWus|>,*O= {1hO?!#g (k+Z#9^/Olk]&:t^rDZG34vYD/)llM5wMhܭonزtG#!? Snp^S;x+:;tqCu"J\ٔ0ymՇBl9)3Q.VcEkF4v=ΦVBt{6RM*3뀧w!@޶)[6+ZpwY5 a.H&z8{2c\@wӐN.'`J; z߂:0HjȈZx^$xybG=δ\8.LĭPYbSL|\Y^>YpR/9eW+ *>T/&tJf+*@%8E:) :?Pnhi1Vrr$p6@29Vܘ:E?(P.E)f/4lVyւ=~ e7@%Z:kJhIi9kEˤtXPpV-|CYP@zK[a_+˗(<`ϸLc)+4Х*긊 ɣΘ!wɐd`[QM2wνp]mP~W:cs3m`$NmO)+w#֡]s:t5[y ol4d6?MύOo:Z=kq޸_(Ӑ‡.7 =)%tI-}J.ү Rez=,6.GE;A]7[M:,If ΁OG΋?A~OuB OH)WYCgA2{KcgOLki9<-=챩,aDz](^.6/lIݏ)ʲAM6mwNr] ^ j -,f-Wv}m b-s;ubgvx mF=9˻Ю9:t9ɽ&Uh(p5PY/vc3ZJ6?&xK[jj*' 59[g7۹GWu GMjq~Npz^-mQtR$RWVZ>|e)8"YeG2z!ոnGˉS'22祺Nϧ4~ hą簪SQf~ A1$"1u?S%hqɃSs\ǣ"' e2T me]AwMVge.g7рC;~|&')۩AjTXgHsżLwm ௪-y"4I 38 ԁ "ͷd8 QD\? l3q^cDnV:<>\ӯi/a$lPMjb!828Sq8XյlH"6nmb2r_0د[ _‰#50X"6S2D*|F~2_da;em Hv!2hRrOOkel3?* ]@ƉLAٓ8A@7rlԦX yA|Λ|\[Z:s;e)\̦Ogf:;7#6o(翗0lD8P)9]QQD;cy8QDk+Qu29T *A˰-u^"%6¬ܮ 8qyf<`JbrA !Jgue;a]@`rCHz0ml&Svi.-˥\ 8VWbj,`#5HSJ%~2&i'reNT<gC-64zʀOH G]T&+(#<@)BcJ255Ass2HD8v['+/~&8Ezs>3wdCx rJ⾽^q͹ߞYl?2O"y҆h*!Qy0( Euu_8a?jI1W,>fmٗgW%F"siJ=z @MS4C,po/6Ck_iKM=z3}qͽ4ї# Ǽ0_rM >+=鸆q,n\ _rLqy9y8dLFNBc餭AݺEZk+ddvy[Iv)u]X9##Å b!Nr;+%dzHF=ɼENgrHe6}4!N -27yX'Z: [j ҃6vKkSFlmFf"+"FD8(J_;wJMCaUi#3aYþ.w>پ-R9; s1$#<.3heM@In4!DsA6YЇ߻W⾌&& pޯ~'̣2mjbq}rv JBJ"w& <,l%sG`+*:6#X_ auUvwռ͔+bźu?,aק1NTH8KH:OiǖTU"oJ&+;>Ig|FԘwB9V榏p|qrN!^mD}vFWsAYmT4IC}B0v w_=*g^ZNi8hOa Z|D^y.c\{)8/$!'w눜'wI w=29PzUƏ*u &U?z!m-ῡu[GeBٰmwu%+# ߪnTMЫOIR亦6cOTqz}?~@$=22unRj;+ mΰ;%;|CIkd⸄21u+t |aZ4^ud%^1vtW`߁\}l) <A3om27: M'#cSr"#of.[.kߜ효p!?FվGm>EX-F ͈a2!xAV"zo/!GeP}7 :`l vdV/xȫQ1 JUċJ9FQ%Ak6? ~]mF}a ~2̤mDNz ,# vT@*rsEm MkpQb|l]*nߏl}`[HzijӁNjoGl_9l"eiY g^쫡3i>H gK=G\ih/m0?}V ~־ʺK*c@ w+[l'ɴ/0]?? z-p OiJ=z @RH=zfz @O%p>fH=z z{ݣy"W<ۤlLFB~|WIRW1)c1 H./umR]r #@ܾC֯ Ԕ1hPق}ҌB\B:wJ& FLj)ϏʹS=!3Yv/w&dύb]6ttu] +*djttlذ^6uTA#*{"J[*7ɭ?9yVbPE'Oh)f <;?vCGeK;S`~9EѮk) _ {}nree_{|_}sr[^ 9 rl۰9t;.#"ָ~ FS%1hώ ͺ4xU]t{큜SNa- 1}yp$E7 >[stnq(Zaf K]c=&8:(ceұD*fNF&RV)]R0/2$~;'γ )/&<{(S<8BBE+c^R$L6p> gyy S\SGWL?Y69Wa,l%+tcMր'>kqpPVv09xLaK l>>3# 8b+YkJsS1>++RtP N/-]hHǀ5,krCɧ>p&ʳd:soF9v80hY4?˹Ō #(/oq'li9@Wt\`E.n1be//־1|irlm˳2|+]綿z)o}J_׷!+ t}r]n&ih.re\Bf͎كcex~ZYxR?Ζ6i&Ǎ>+g;pmiڸ]N6IsV!.òﮜ\U`긑r!ݓ;#g (+i~jPNGʄdVwcĘy9qlmQ#\&m[oS,k:AMΟNzjW`R ;r /*e75wIE5t#/v8 /6+{;2 ~Q{~9p7՗&_Zm xn=!%آ)tcQ 9Dz`yˀ`uѾפ^ p.[#l;z1yW+?Niщ=\jg~ DINuE , ]Di0A,5(EVd9P⯍ >\1ѵ>ŔtG-Q8!?m{GT_vv?sN[ VӃuFPvjvAb522G,̝/ s%~ ¶ :II} ҒG$i)[aKvK='`l,wp&$WJ2s_79x"M2q`3a@IDATcA\6X;䳍iIո@63q*1 WC11 \ $ 3azS<ܮ{4h2[ P7X)KV{6cJma9&6Y_2,=P+ Zm BBu$OWe2po(ZJOi}RH=z @yNJNRH=) j˧ڒ̳Jň_,cJq:o9[>/kj =I"=\,QNYӵAj/'d0V;Oo٤ЖXϷ | Ҍ=w%2vm9q/p/etﵫb7u[?ztvVY#7"cnաX(r4|'mvL=q& ;$;<-tjy upiG2~y%yvp`yߟFyL3{f[kR y ʯafD}XU?3+č@;/=֮1:XPdOb=:!~6/ѠlJ=8h˰ȻOIs؇>d)oD̾-*M /k)S0Ch"n0f7}}PW(66۵'Vד*A%Y pDYŒpW;cK_v(ENv;ENi~ahN38ę\Ozc[Yn5Rb|;/0;m"}Eg`ȵ;E9FN:zH`ffsKK~`Aa-x}aĬlZfdvFzDm]l@:-YHڀ8|/}8J#84r ?}(mIRH=z @ Ҕz @+D_0ےK;g`[Rx#4^ i)o.-M P].1+ߟ՝=ҐiwJSyuЉE QMӜ 3|w~qf}&Җi2>*\!\4/3CۢB#f? p@Z{(m{~]~!*1eՓrn)x5köGLjl+*M~:$d0w~|!LeఖSw2}A(4[i4y!vtW$C|Đd+m& v !ܤJ`4>9+GP$㓱憣l/#,a1)Yk#Y}4N~Jھi;,Lc`= 8Z߁l\rHGGCx.OG9]Ma[7]mKeF s2|i$l[" ۥJ i1Wf VH=z @RH=z @RH=zD+;9n߂0w$_"-q'[5Ĉ"/q+y0eRm[25s :r"؍OȪkwBSGe@e{3w9ɉQNփ>~:Ӓ{;r91NmRی r\!zb9ߞW~#B$!2zUFsuۗe?Ld(`r ~n=@! =dêM$+j] 9_ߏ aP}d Ġ34 ~lg;IE/愂yW?qB19e}ae  >C~I˩C}#d((0IDghL88 +V$1,KU Zp8EM(Gkl1D.-ι[_W_sNsy.˩HHT4#:4h+8>9׏c+I.ǟEWx鯘﷍lM,?j(vN}]׉Cc2 pn|V\mq:(EÇ tIe2c;/(䰌1PBоQ252LcLOM/8s*~p!"t%_C%&Ԛ(+)w6_1<շ)U^z̷3Z•="Ci>U [tR7}2/6V=m'q?41?#AFfIVhʿ+[z33BSVbd@>tj!W..T'䏻\.7'̕'Ou+|RzߑuJ`#^}EzOz@ f"~yvJ8&?*}?~?*Ox^pNJ5"ZlWm~Wp]o+(e q`{]~#O fzoqJNW~Xb+ֺA~)xQ;Ƀo&*`NW[6D1x?13.| U zucV~.*ԼF~|ǪX|35#A ~m` >,*k߅eċ2:rtȺ;Ɠe6geh y}l3l; L=v(uPOKϥv;NOU)_uIZ:7W~8XPBᰜEuH$v6bSI8\`e 2cyTA[(eAMDxD~Qj?; ZPGL>ac}!<r(M.eR&"v|0&LV|^p O4mJ/NCŒvb%Q6>_Q1>J,V^Gx/'BۧԸt@qJo<[ިU/Ek~RlfF K.W #3%$R'1V(׬dg b}/c辭xo~|_ˑD0״Ē/?6J5j7&хK1<҃oBf!uU/ T}~ | Qf*6$(_" XR^tct'򕀈ci5]`z=']#O^4X0'~yd<ٮRT?hZkp]K{ZtJgw{zVZ'uktW !M t%'_ C7o?x?U-ر`}KvePe2~2XuYцUۜyl9KoRsv.hV90ZEyM~Yt|mD!x>4.aΝ은:?6Yp&Q7,O> Q֮ս(0 %cB.i8;,/Ie J !-Y tHz %xX$C-"WQIA ,-qj# 6@{5frvQ;>_GaFo ច}>lg Wk 8hd`,#Ġ,&`߂XɢCo Gp~ ]1\,C#R:Cơ&7}hGoMnz?Lᆋ=r7 Ýv}E:s̔C] Yw,PWyL8-'x4}znfaz} g})Xi|&jC@) pTAI (KB}Ns4,ʲhHmGeieْ K&ʓ02>ih*=\gA ջ<ޑRH=@Fzj5eZ}$= x( b.'f^ZM9'<)([>"5FR+ >+<-K$e1>d'$)/Dm䣀'Ï&%lڃf?x~IȆnyl^3/O &O@nH3^xpK*{1wI^4ǠDhu~4ME`zr;SQ-<kjao'A_>-VSU/s-]qW/~%[Ǝ=~==947 rўԃ'yiN8?|ț#b}fc7=~_v!2r&ݔ0A}W? +yZFJ/$'! 4I|佟v~[e^F9rG!4~ɛTdGa,PAVn0?/a8j A[!܅=\hL&g_qBh?ؖOQB~Ȋ9mO^G;~Bwly03k>zయ A8Cp4`^0RMQӍ;:itk| mc|œ׶ɉk>0KaM~Mn5~,:ؼ]bەuKrLeИJ_U%~W]|'/q9EuS$ WuD37D~&EÐ|y,FoFϜ8kwI`&V0~ljs ~%>QUg )@RX(=y aRWJ VbJl"c:[(AAҽL]n`fJ(\pbm3{͂E~w^2w 2':T3&8R] Q W:#-|4q6yh'W-ۊe)\k˺#$;ߪ)ex & sMٺ:bǦLCMfI2(8<<Y+6B&7O~[$[* el1t[NZ&Ķ0pσmcҠ= 'h^O@k뤵_c)@RH=z @R|=Jv6ޥ+u Gae50?ًb^ k,,H?99745 R#Cg3q>fXr;V6J?_2bw)/WT,ʹs;Ա2dEE_[#c0P_ p8ġHGĔ uEPJqɺK0l#Фd.ABIV%4xї'1i\qX}!'^R; WD//GXyFWVGq]@m{;h!p$+C8m4)0,c}r]Б8_^hn25LYf5g{,%ʾ&`.2'^ ^:_L2uSt}w}}u49LzA~,o?2@/O6}RnO*ɱf̍茦X`S8=(ZsL:>u C^u*yx[+&){Zٵ*q_i<}<^+ӏу5m;aőKQ|5/;i;6*xkɴ O.ް~7_>Yhw;OȞhZ j\,d0~뭘ЬokSyc@f|C ܲZhEqu |SQ]Ͳ6k<5*{[܏I=z9Ge0(̌K[賋!RQ$їAT`\In_+XybD&Gh,Ƅi:cѲC~޽]V e1Z! g%Cߗ`[pk~4C]GXJ50voJ^2 Na3qj'Wނv_H"&m3 M spmC@ŴAо[#ZUuQ?;9)حa>VEߪ3f8PSg X; '?Ho_V$vtA)KZ_W\ʓ:u> e2w9}C;"|bbmgY1g%l0foѪ,'`ŇYgߵݳ΀=W`UT{{nUrNluu{9V_-?m/RUһa./ɣaW {z26€o\]wдz`z`wwX@Rozy=G^xbj7l_ `1ۮN,p+MʺUOF ~c.M^&j؁`({U2G۵Z>"}/Z{,7˞A Z黺ֈ-Y"yb$%twxO_-~p̈́4Ȯu1Ÿ w]|LA/S[%=-O=suHnDg2#(J}O4d'uIFd6@f3qZs-hOy࿯4ݲER*۸Jg+W7쯀ղW \cˮdPw4`"*a!?bӞ7zNA;E-ۚ$ Lu`Qyt}TUJW<v7" xefb[+;@iueskDfLYF)jo ާenNA5g<\uυ\LJM l#"rt(/pPŒq0lUñ-'PG^mMAC8˾ݨjR8K?_GD{cB0GH:A* VHھe}drznjL`Z:'%pf*'q5X.i^\2#+ma"#IB ~XrC ~ ʵ?Ou0f|f3~nelA1|.c=3`m0ٷ7~ ORRH=z @nA&I俨U 墳Ԇny( {RJV"|Ov,mџ=U ës/ܙaRϐ!߹}2k )yM%{Z"4g}]l9*{=6xݸNݤ8p&AL>YΙ{wcB Ս^ aȶ} d ^DU%2 \fȸjW:.&.xRncX-(EP pxS!&d0"U*珧XMStdZZ=`{-#QE79Xu9Ŗvnlcؑ$h؍7rYKՙ&/xo99|+ ApRܴǽ'(|C5gyݠ;Gj1 ,7ϭ- G߹3+ Р{a^W":y,po26[ng[*+AvS1 ô!h*&X ĸ\#KcD~L. l;@< `FQ(T2i-&Ҙ[,O~) 4"H_/L> {T(\-Ҩ,ukun/2l״MhQN( ZЯ0m4wb|D7i ,3RzRn|֮P'X]em<#%Lk5MsOOz^P8K5hCU4H&gwj¤FjϏ˩s2|n{N"/&P} ]w&(HѶέE*lSX$Y{ "B7l˖[%kǫNSwCtR +6LizX3_gOIJ#Ik2-7~0y}<0[u<1`F8vmX_&ۚ/@R|f=Pz^,8 kg~rD:i?wN{<B|w!`T!6kħ9yŷ ,wWHۦ.-nrOdÇ+=7(s$aWl^g̀,E'WZlSÃ#m;[2kQIzߍmm_7~$\&=U*fzd OuۑcnTWʾC1"sĻC؍Nw]4^o%r}; l_oϡoX#o,A@sL]=#6#}nyyeR[ލvpl7\ʳ1ܞoy؏ 8YgMM^E` ?)-ѡqa bNLV7K_7=9α%~%OGTn]?)O|lk]%~7^maaƫ} kMn=67ޙ!y_/Vl{p;:"Oؗq?N<_L_E?iy؋{/_@\[n <0/ }c?9(u~b`D10Jk`Y̜ P-\Iblt\rZ,/ڞ0EP(Q;KPn'QZ?rHf_{\;q"9Ͱ@cr[2 Fo0 7L#LaU>FXToB*͝PE}<4~zL 2sҳI)-Fo6R55! 7U7@'7^?7{'Ir>uYOWѠ' N*qc2ijUU 'FY|.H"+ suV|HA(-z(Uvł6Y9SXP&*ems0/74_󂌌]14H=z @+֜*GǏ+ūWkeZ-^@s?/4}\j7}W^7AA o3򳇯6ugr?CjijHkV}?}^Zā e[ޖg7l/'OOɃ|/@<ѡдz`{ {vP?-,o=#7-8q>oka`^D.x`|Wt<`ڨ{)1iNy10mi蓽= Pk 6|s;FM#[-gD=Ouˏz8Otܻ k6NxqFx& 塵^ (h".? /v@u(y#YyKk1wcI` Ve/>ZG'o|Ġ+t'?,HQ=a똗g^6T2cLVGݽ#oJ^ϣcۑr{-҄<9UaеF|?_T{I1~+EŽ6{.-w=:&YNS$^XjTRvBFҾWKS6yM@4eptJ]Jnq_O8!y!]+}&H-,?E_ogfy%/OA#xoi߁#ԸUp2<7?_ʓ:,c3T wwcb?41/[|zQo@{19֍Fqrcm ڿ{6=~^Bp̄cb}oQط e +mjƻ %=*aEP`';8PQ (f2,AnUї2 )(>ZW܇+LIT bχz ɧ lan勱&*7ZAT _,EYW# (A l&p_GXn P\61ȕ,xîgE@Mk͎)!e^t0m򌆹LՍuޟ1iFgxˣ|sN9$Or p8#?W$PR4Y #.U'J5nN)sSrjl IW&rĶOY#FQ_ 'LTfCbv R Imq&k5 3DiDu1~ 8r|1:ge-Fc~nGYܘvn<9gQ~S JWgbsZuc"4qU?P+I,R .$K\r8Xɧ7/Rt7S3.58p s/Ֆ8 q: LK&^BX1?Qq튃EX/fC})Jӷ+l4cm5`V*% @K/D?!o H:+/"Jvr7"V:>0L5|b4H-k? / ^NPVtIyT{|I򗂫%|URۼ.M}m#˃)"V?z?ǧ| ٛ cG>ѩ0xoNO# 3c6N j~7LNi*9w$~8.ӴNB)z۹+cII)\bߵ Z*M@ LX;#/ֶBab .ِw3 $JFOȋce3gd`{El(X}{:*",^Oln+G]<|y|σhTJrT@S y%)jB '4(*X y҂'3s+ׇqu2ӫB)7rHT,)J1VDSB0<.hrmxLn&k 4rcUΦϐ y0eω F>Gm@y=s>sG#-&mkPZN?6^a%kW_yEc%W3X.™k; m,*13'e1clzi$r9Yyu|]b19~/^sd6Qw. ͂׬`x>9tIِѱ)9s;wġ+o)@%=O R\)!_)6v^&yTFOR3-{vo{m7.#K,`yn4挷TknFވ"ݑ1V}ƛJSS\ҳ{錇mSY?},OuiRO .6bS`44í򢩈YW_%ف8*`lq1mf O&yi%;+.o#7_"meh4]ޫ@+Kumtx֭'vKYE`xق\h\%xp|\~vzSI:oP&dyP+ ebBy䱀%7^Paѓiv0%sǻ\E9}fS1i>_&?(|ʜ`*JOFf"'<3'xxNk鱜lւT恓B mDkL8 {ZھNk*6f1Ad|f[9̔D)~d^y`*v~iKlr8qTt'r}ӣP.N@P>]9 O\[J2xotW)/?Zy8u`r/kSRNĔJOs&ʯK=z @]d'/] !9]7c+hbPjބJÄm,QL#n,Fq8ghOOD){ၚjoL.>HUֆ[@U|ƜCR{ cbOJ}L y[*^ ;=%Oa! G/qGu8/a=wdfpFsͲۃ*dNl )c󀽐Se /R'OG$iɺ>-;\+Oɴ ݶ>OR Cz+  ?8R޿cvfyfyH MLĐ01oWg-]ލBVyx0^eErNgvށF?w` V p}Gw k?3/-}zh$B< w?UK tf@?ȉ 5TkՏ>Ұ3yOQj#iT <%:&s/P```'x,3̠=Y3;i O`RH=z @n]pG?8&O? |Cx߁N4#uZoe_x;^$1SmyB+}'?S啕+Rog\6iu^~eߡQ5`"[xy[{)n=}i,4+,^?k쫫}6.N"Wl@_ͻG:3$$ ٙVzO4DSo| O /h t8,mjCǎO׮s1y`wo7DZscTH]^X#p|y2ހ}.$Dk̄ nla7yz1^]<7a?ȱޕ!RD"V#V _}Dp~M.N^Y+տQ]ѥL%Rg-9_͎C2.Ŀ-%NOwvGOI͡84E䇴~0DYp,O($٤6Jq6R[00&|[|OZ#V'jO[Nl~rR?uu>K#/%nȨ AV9;e܋bVں K1\sӔzm&ո 7{"mI~KGfKV߄Dg?\mArٱm]zc6>8 9/Z99Xh hप!}w>2Ն&m3MioMq=t\xHzyc[eb5y+dڊ|(X?{u ~xv$ $EH zD;#EfW7Q&=xUڵ5_Nj*kj+Sh*8ȻI$qlʦ,ŒE%Ҥ$@xw ]}H :}>n=q^>#/-w8khOyvc]Zirty9ybY?ٶGL?I>gWe{Um?3#茷fv>3oRAHM?k93|MZTgƤNF29 j{jfXa-RO/ҮaIxT]زo`P@{`UE^XX%Qj$hvld6b0}8~b[j?´.0,1k-{blut+-Q&QK(S\!ǼbQ>#Au^1R1.b^ڀ ۃcNd}0 6$=/xk?,v/I%v{/aӦO|~\tL^8/e-Q9= MՑmlΞowoO  -qyCnEzBRn`?^'0+¾)e(]y!i]}yMnj?g@im*ԽSfB;;"p?<,/^bFYSqI%rCaAdE : D}^2Q*ڮ/ }`Hax^6v`)Լ"O]$ e@>eG `!"<+wC X7rGq}MY"uB?6 ;s ocǦm|j2w6 s:DVQ9r#RU lĨfi2=&qO\Lsr$1.>jeKS&De_F?U6,ˊkUf6Lq907[f#k3k4֕l(>47+++XD1|^n ͐aiHCLx鐞WOb~`o}Uג|!o7D>KL[k7/ɟ$lńq? .xo"-_X(#=!xo {߼x֭9o O;#{ygTgԺ/S 2[sysJ>~о*=f W;-|qZ%óv=$-w䛋6""B~4\^qF>}^c{1U:rہ9-yȾoLogK8~C=Rl2v*f}~ngqSz[GIY 1@t>jSev[cZ.#oT dGRׯ[t,[06~2Y~^lM>_+'OR$/,6bğv%vM9t\A&g,6斨 h0 , }C{lW6e%C w(`ŒggDWKXQm,-ܧ/Ohf[ln|5x=~qyō2N|2xIS9%3't/+?}[ǷR9YX"}zK>*[[ڢſ'_R OKl On}0ֽ+ȃ/B c'a?r;e']~+)4y y:} ke9>>Mag K˯˧_v)13_5U|Z?EOP/}*Y<4u|ªo^}"’'A+&g=94.}DaC#eJbu9}w6NSORU_Y[߈t>K LC5% ]ʋ:/,m$mCI[-Y.LS[5Y@D?>D#B~t Kgπ 2=XNMU7MYL!jE^#wB7G``* ^_6 O&ÍhAvؘ˜Y r4$DyEiO*x~p3du\dce_f;Xh-'n3ftr2^wwȭ=rρ~iKg XC V/1oclЄ9-6z:616^ t5~,R/&V6_Om~;i&?דe1/tL}<8eLe8ja?1q\؎ Nl8{ng2Ǡm>ƋmI^UУxW]G08f}h1p|XZ`+[,]a#`Y_w+x̭Fl?6qX`mH4R@xqz^itIXI_Xn$G @6Ͷ2r mSJ]> HN`= #dJ,MPX&)bPˎjBo H IRӌd?XR"K/G3\z埔@"HfW4cce,Iyd[4&/#<_[p~* xƏ'*VwǰS*eyGأ4-SE!3%*.de«`! 8U\%,c),=DEu?MDq,-/r'3z?`EFłz?s);=VJk߼C>!JX]_ywAΣK99-~dlW Sߖ7ͼOZϵG)imIVZ<%S32|x\wfbw?"}8ێ;n1]\p${-/))6zڼ̽|w W26%'^+ݍ-_ydC*L@L%0TrkJ6?6K 1]|?>Ej=no7f=:20~,#_{ɂ==.D0ө ^zg`C%>E y6[4`>(mwIv_c Qj%壌",n|i"nz8rs<摮ԃ DŽ̟n

    IO/e+4ute?g.kcnu?OYdenpEp8iZ0kӣ(-,ֶ`ɇ>2mwLǁ_{庪{][ Ln=Awׅ^?|ױ\f;n._dL;b[ٗ,o-g'sNx.8utz4~|#+(Ϝo[=t,*Iiw}fV3򔽩Lt-䙷`z=᝔;&:Te]gUlHcvd?&ȯֵcE#D\%仳1 RyOHVUy[mލ1vm:9}wrAfuv@T==wUI՟;#-繭n=ڶ%8 =pS=&2t;V2#0@cۈtc2^7(3 a +#xr+^K9%.eluJNI(j2::srefuc4eLÇhE/MHuP{{e_ā=M8W.m^!i8";EλLJ(T߾|!{s|˭h^8%/N6l `/fl ҃7divZ;`Q#r0lV\lp" }}9(G?tavieJ̹>C?HBz񲿴yVi{ I+m\cc_7po"%k2w;*GzT~|[2MR;#K+6( Dj\ qajpfzY9SMXE=-QobdpW`WܐT^ьg9ѿc],pfqr`m1c72z{\ubHǸJ%[Mje/|e22hXGyZ 8G'< 4g!'b#ހ͘#$vv*ˊ!m dډܼi<]|EUS 6AL̖ۘp"El  (d~bN ObmκE|cl<>T0!W=<"\H<"npIhbh3<3s\|s %x } &׉C*lk+`s_7N5}pYyUuU<q@@@@@@@@@@@@@@@@@@M)3VKA̼.=+-킵y3nUV}#JnʛOY]u܃ w~T:? r+U֛kXsۯ/2dۣƲ(_sp{q8&$03'38CT;˷L|=~YѮ: J1rsZ9qL"@`{cF&X uqH{a)ڤҦgC뫑{͕SrBw ߑGG2W"cٷ^t0-p3?*Ȥ[ \\>/"wH?pۘ3_q= 1S7܎Xz58=3KXWkaG&LL^֏b|6c}' ok푕|;vVUlvpWsb@twT JS8ظ)P6|0`5:OM SSژ,C&!BNX1[ ܂;ѱH[s6"Tɪdxo Ei>|iTʆ0V-g.ɗuM{ ˺#x޽1>pN#N.r|cގ/3av~N7|ހU M(kp]|X_.1)"3MWCŋ{RM{bYc#˲mS6ň]SsibX)Z|;*my# ,Tci9w?rGf5l7 @N]'?&ck iAg )2m=wZfIiz^~D"sSSrV&(JP|f D,X:ߎ!l;"YWx{{EEd3uCCN8%\O?wp: r6R)F6NVH?u$Eܶ8\dn!qH҅suQ R+geoċN*/cd Uc+N{eeOSrԮ,̺=w;qƊVsx(FHMFtOĞvhw ]3xCrm[|@Bb]ΣckbS-|⤵/[uq]]jĵS }֖ZvP%|+; p~pވܲcV|1>cqRG[^z:V֢'- 䅋"*p\v>'BDq.D'"6Ie5rj?'Etj;s+IΆg􉊼>n$.q {ϰ4L >_e8d9I|ill|w0?~acC 02ǸN:"㈇L^vwu*B]]?N< )x x x x x x x x x x x x x x x`_<==y?Yo; C y`kYirU6 X^#5 }=#g_s?(Ǥk@zozք/m?u)`r̮VPU!/X) F+g(/(MU7q,4 ]X`ș&12}ۯ;zO1L~ey{/K͏~D`8s6F? 9i.!)"(KQʡe\q"UN;i;&V'x c" .LƫKUQJ`ké̢ 8h5)hK|c7dG 0@:{N֖W$!v7Y'A $NE.}$lQګp28TҞJmUJKv!9Y_6#$NO˲ > t+e 3ePvI2UexVU _9IDJ>`)Me+u' ڷ#ݖFoWdvc%=yy=M\q(p`EuM# cnL8y:"ǹkc˼G, 9q53p`=>DHIG@mp@wx e~%OGnuHKOYYy8iXf^/$d㍜8P/w4&j y PMXB5jB;Q(J8IHr0GVzv؟rʒ,yc2e!9Wkn\Zw>s]>p ' ce::{ [/3@L^ {1>XSyDr_xNVm z(;IFހ qj|~h{|ñ(f6</,D/3o@\yz^zda,&^ܴgsqKo/τG<=̞qȩ11N{︟?f3ϔTu\~8:m&du\hdlt@:|`tQuHMYu|ϴIiէ>,ZҎT$Asx Y]j|֙چeEW@[ A xGV#^Kb&Zc;{k۫"Ǽb^NY`c .e1hǜs{v97?'\_47V֏7]3|0g ANߒ 'h{N  +@+K"K*Q79O`2pʕs~uFU^v:Xn# 6Q-ڭNzQ,D Y@IDAT$rV]j{9VrWf% CI a3N4G"RNSF6(0U~S֮Q%RE?7:ހ>Dӕ/6m7 ڛOKtFOmkE0mZGrtt`bw%jo6}Z̲upC{sW|126#M]qwxԬc%cduWnb//sKIYY^܀vT e Sҋ>);lߞ/`_|EnEW-_|)V`|Rnj?));" eSGwr}•Ʊc/_eo@7oz;$9 ro)yUYcr׃2;=IW& f;دVYڌ=XXvc/OS6>oVoOFzeq~;7ax]b^L{NƏJS5&]X>%κᛊif~ڭc+i[,Ir:j܊I K9Y~K|3IѮˈ;sc컋yrZ[2 xcŎ*o]y24X/s5,`[?r?Te 30gPfu9*7B XuߔW\"X=XŃ;*OCm³zeRq+3FAu& `|(>pEcن#HT'O&Kg[ЎD|Iօh=sn=/ n.A} _ c4tu"U"=Y6\qR>Lw %Y7^lgY2:r43:A~<8t75;}&p,bYC&qI'MdN<ȃ_G2?ǭ+Q)6O#9ϣ8roI]ߌ \$_Ԥ;im<<<`\!4Ӹ|M>$mX9܏LiY bY*I$Xu-FY /5xnlE(.N?m~\'dd[7;,N ^ikJ'jKf=?tDžj|׽C}8^KiyZJAVs+g. x甌݂= |y0!HpHӽ.X-y`Z0`A7L7 1!03Hc,#VԞH>l*>*˕4[_R'0FG?b6l߄9\KKxlPD"fq3<ڃ /˕&pTgցLQ`0= gdr%ʜ,ScJ[hFw iK6Qkf7'؀K^*b70LOˉdjئI񼪁+r╛.0`C~z;#N GwjӉ$I2'(S췺ⲝȃ}qoo |O|I`k秤4}l~>OɮO37 LJ .d`"Yn0?g ڿO_? .n_E@%R@x$,$4=+4\Y*T$il+#}ɗ|`,8t hc)-RP⡖mO: xi&`Yh%),ف,l0QiK7Z=-{!O򅞟}~ҷ^7M:xi|Z֖I^PI& =' 'u$d*NN144e&/ ~* xc>~Z +^U[ Yd2.es0?1 Ōu}#ɗ~~q&/~/kW\I|OrSvjd'MHVxi2jMM.)7 M$_vo%aiwWOMgi-YC#|I;3/|5yױ)/_pڟķuL-W޻'3vKVQ7$J4=F[=ךҖyW|-'}|LϵY.ܗUޒZk:&y<>Ο:oa>-|UJ}#X-.K%S8wf2s'S0Dz!i} 2WͧZ8EThd#*lD|6"v+Դ8"}5Ԏo#"X FAITf[+Ӄ M py}$t}VҴzRNaln)Ӌe8b)R\-T'+>6Kyi;T䳌0Y祁TS1wn\4\2ܷ2E`jm w[> -!_yzo*b"y_MZ]Fv '=yol=xIm0x#@|9e7Nj>#ManaZk:NzH(pOۥr|/ljrdtHv&hwbt UpG? Sɜ0 J0 >ZexjtT/Şj< I' ɂCY|$uw\Mjʯlw$_/`(y>=V˾BYzVߎYds#kֲ:gѻv#ꜵ?nڿm^nx֏{j]lmr((FGp5mq ^SG'F_,Ξ2sdo;;[Ưq|qʄ#&XDQUF#~~>WtVJi6:hKfR(2{|Ԩ>s6uX+SDNrX/\z{tO#A&<̀ ִe%JRmuK@o64:lOyg)ɦNvYPO=ϲ^617Y4|_V' v-buI8xd=A5Fo 䓏)ח4VI U"!<@4ip}|k7\NqzIUGK[Tn ~3M'J݆ޱE~3VL. g;僗ɃbPg"Stl!K3Ӹ𨧒T*sB8,%~~K?P`rxd=4h.%%[RzC #܌O y;-"u>eEECD cl^W&ؤ %(*(&d'V5~u4Fʎ""UuCvjvL}ZLR}Aݩ=K@qfd;iykߠ00%(1tL+ dT>DPIl\XN9εqS+j[;lbEL|¬c&8#X1O='zuMXG< )23pOD r#-]}Gn2Iy/.jwHRUxCn˪bRm 6T+kcSM2ox4?؍2[E_~zZM7p-%U3˔"%v5UwC+ul|s![_ ѼsG 3Kun~U<3: {1hO騫."_^ ?Ps RE$][aӮvE`#mӠ%Hú;# Me{{c^/ctPz]6m4{߳VRMwG @.~b_Հ-;Ze \Z]e/#>>I䧺SYec8" 0ts'YIJF8 H&3E&;2(X29JǺ'8FN:ew_ ߅m@:o;Vӷ BMV6@5!)klvnTʼnF s>c_ē,>aHLל娨f>ea0Su28Ϻcx2@c 33kyXTWS1/q찉}5D:|3~̩i-> 3zˍ/.(imh ن/m!ߍ:MͅUeqO 'gu7`*` Je}DYlgDii "42ȩ5B_/"*9p|*M! {N Q# 0x}vױheD$<` DSG/~~l6 117/`WK+2<4$}ݝPsCg/Y^Žka)HJAї>i >rލ*§UML8+XU E^ގ}9i 9u{iOZNc2ˈy8z # 0q15JC:^+i / fmUs덂0$BЂ[7 eVtӝ6ƄRԟh`NXFo}р{9"m%xw(v:f":v3{rhSH~X Q$T/6mC2-m(dM4,d~a^.\%lώiC u)wv &CuJ}oo\YIi||j6T(<꘤M:VTZ|0ʣz#7"7!T@fBtKX= .L7먥(B$m7Jxĸ4嵡92'0-- փϗHqN#fn/fuV&y؈܉=; ۔fy`SE›6+uW$}Bwp0/x x x x x x x x x x x x x xȻ n(3`<^ui]AZVU'g8*S~@ ja>\> %VlF:#¤AIB .~_ dD}^YUZ A Rƅ>SF(BN?Je0?',|pP"]|J>jz}NMRB^+)ka9VwҊ93}YJ Xe@&o]5 l%V᳍3s7cRهV&\0>`*/>_xf2_KilRs?>־uz5tcr IH[XOG:]C;*+l ~Uc(BfRA:߯# nY^S}<\n; B8֟u(gf`pDr`-! 1 gfj[˩¢ v\.:7&0y+d]V `^@@@@@@@@@@@@@@<$a@`K}a~0ozܩ7U$mI[FC=]kMb_?J '(yՅ "*"VEv &C$% lEyXN$_9֐ⲣ3`pNh~iɇq0GA|`hΔ-ea3,9vJ[?qtfYwpxL ,^ pu-ʖ4xb[[aĉĤP lF-᳚, 9qdA &*gzc}gs%=}?.\W<+o|e|Z-ٸaξEN/ 2x>q[C!K[:0g=LDRfc8 ?b6o4KWj~a~+qwK 3ӄk&$>]ts*lt8>ʔË΢|̩#C|8gc0 :ҁmM(oҕ=}9|1XmjnŰiAeFm"kڞ;l/U9 G1A -ȃV wtȇ<( ]f6[ҁ@9Y4-sK)MpDSg^}Bwn0-x x x x x x x x x x x x x x x x xr_G[0IT$FkeD)|Xš )$g demOBf$j>7#c{~V縥>Vj3W"IUr]a !-h[Z-HTV7~ u` }=[t]h{l]:'2π\}2uqϘ0&Y&? 2j\ͭu.`*W)}孡f0礥-/+yayQJkEȁUX5+E][䳯HkrY$r9/Э.x(|\u31n)I3D97(.|sxs kk(T^3rTCh+̗~p=G7fd4.ˬ篊xX&8,s,c9c ; x9sDc 0ccA8w a g4>!&.x"S=mvszb´T;X)|~f--.~²C؞PˏYm"S=Y[5':(Wr|Z2jն}v- eXKkaI,vphvBo|'a5,2ܝ M=^Oj=zz$Y}Z>IK4X-ֶ]:cɁfSy̫5&uzO dY i=+׬{?NU;kS d[ ՊƳjm~zijׂ jUɢ1vioUM=BV5I%)cZݾS.Rjz=PI1b2_'[~NkT lPO6XN³ 8j6WS6[C IUH"gBoq,W_UI. |ۊEWV7ЮG-qľN>фńwVݠ;#kIe=}tp!~^^ݩKN.Mn='kxψx)N ETgZRݖ_MbvS-mD>pk4u3Lti=;5DlGmWHJ"J,h lpQO zxת=mT&gllw }'f g#R#RIIZ>ʪX^G5m-ۮA{k;2<~ph5;)~¶j=sUdU>XU1i f!5;2atcQ\y1Or@UvThLL&o+vT?^C:MeI &0єctUSOMܞlK 1܄A8 ڑsȌ U$0,'KUi@._l2o:s Bۑ+ş+[6m6}p}Q y$qe+Q$H qΛ[3f]5:ua2L8@9iB#X&"i0hiC҉&㕒xԏ^p 'P|D`8LBY-5!`mBסFq^@f{n_}er'3~g΋vTnM@[^ˡ3oM^e )*Cd "M7592%/m{e9snN2u%/9$C2>|@:ooוxo˂nXV~c2ܿϒ8)90E8o3i(\Ԉ;4:~׀9 PEjjSy"!{Qٛ5]LX6zej$k>g`x@#L V3` L 2Kbf$^ѴxE_ҿVH-8YUf[`ˋgE:m - >Ef|,G 3imd ;xQ}Qg٭V|CX:+9ϡ qv9&D2@^ 7a MFMeܮ}JF\-=![j5:q \ 7Pa*<k˛gyk+X 8 ]k R9lqɾ caKڨF<>KjQo>a[D.#es2&h'`‚4yYƽhuvQ^?=-f[̓6 v){Bn/x}C>w{êɭ~Droɉ ~UiOCяJoۂyxdT{l Z ;w#,+ b?=v,_֓s|[SzZMzpHoC v-w'",..xxY֯6TM|Kt2x:`ƛ/mƋ0NC P" r< όiky > e_KGl@ДƎHo߼tI~21邡sGI 'O\ DS^M02mN 2p V*|-Qwzh|c)FbɈO˸>vO!ޛFu]gSP$@$HY%Œ-ZN8'ΊtnOqs{kuJ?8yIr';c9KdKD%q' $H<S*C:Ӟ>^T W,&3և;KFG~r!y}9&@,*\\t]b8?㾩*\Mߍ}ۛ`{9rni_JBP6e[] }n.)38;xBV N/4JA|"G~:n9v=wLF *OƂ@;(Ԡ6qoH[9XZmEGR dn222>3#SصB;fUTJk2G!-(3to{E<y @"D<y @"Lx^X{iMTu \@_ܿC}{yA. T a$fXp d P||ev(ZaXG+=SOZS!!E':-vÙFg *'^~5[i֒igF3QNog?M>/W4J yXGSW"f -5V4B[Ɗ/i,+ t@$l(P'B\rYj>)j]Lo'0һ1bbv* A.ʴY26m_˕@ ]fg.өz\-Y LuR+ЌHϚ/K0h$\mRz3r'`'Oym$VU%uʫЄ*e„͋<w %&+/uc 'd*8/<}[تxLJa3 ?`{%گ4,@n6`ʋXгN Ι$ d++ }̀… 6zU%QXwe~> (*dC>i`'HJ`U8K-lkS.h,D#/'uXq|4`Uy=.]8:׶nt[9zG>ϕZ{3!=A{ ΐJOM D*buyb,&[Yܶ~QN+ivvW4 ek!dNC61f`7WXU J_S {zt|6{Oc9('aH^,sWPti*Ձ |FO &HTTA11B&Et \O}_{|="D<y @"D<y @k_E!J(eKܕ\]xgCZ&SbqP)MI@4Ci˧q6z[iKh^.ȫi{LI/K., c~rLӝҼ^Oزʰ}7ғ2^MQ9mWP LNߎxLT66A}SG+%i?hQ[`hri }M*k4&ZqV֨||h̲0Kr}>*h~3^'O94pݗz]:/i'D-s4˭v(}Nd_uIS-m*)`_ S~aQ5F`WTs5.T a`CAц,&In*Z8߾: >|RRss!Hۮ/Of%LBM.ob9D*p֟Vؗ vxA Z$@WĔ8vB[LZJTOeSPż)}πS2hkr(#=ϟ}z?my/!'g2 A'utPu;(r.G2=53.~mEqqbNLb¥r`qWP3gli6 TF9]U46e 4G$ӘR%s8 '?l& "D<y @"D<y @"=X-֖i1TCT'G$Uդ+غd%߾Wjnlה[_ z}$G^^=w|\j:{enGr _೹e w.|+OԱ@n]/JOWwXߵs\53>mOlVH}%^>&cg䕣Oƽo@S(Zz_Z.Uu-~ +X3_+vVSަ[>,ݛe%roH[Krtξ.Gmnw.ɌHYCWz1>5}s>ش@IDATr.ɥ-Atr+:IΟ& z{gsHw;i |:I/X$/V p{ [s&`Wk>I$`˜Ǫ_xtbJky`a@-dݒ`p0m>-#ѳ-[/_dCҪtN&~@>%9$Vv^y~\.\JeLPń}1ߐ}RS (~#t@Hߨ؞-M]gyWL YurdxPz!mt/I;I gq%Oċޓ>X]4.ͦk5^(Fxeau>ܮ?pq7>& `3pyb0}9YI 'hO5M~SL"R>z4) eLeNPa@<<ऄ q%1l1愤 "wpԼ"D<y @"D<y @䁟؋՟x[V*츌_ʆ8RUw%La5BM4K+rİkvVŤ[{Qp22 =ѳZviW W:;~\&FF=&5 x)^Bwlڍws2}dc$X hOE=_@<7!I׷KUG^wlQ`nu @n44'8=|É'Dh'ߒu ii"fߺc>3.8۶}M_'(-8M]Xfi?Us+$;7(S㮏;އ$ +xe^K~]P,(U$evGm8^չR%|>~SZ86vclmw/;x}J]ūaa> v7v#͜&Jɧ cvZȂAoh쀌JmvcWNز8?]$# +SNd&)GMfilmWEW/ ++6ikK|c=e ?+{%ӆ aϷ÷ i\a[_Pr]}! GzN@9:ga/#-/S]#Ir#3ߗ,CgOco@yyLZSKg"6mUnqI@0J|LDyFYD<. 庨S; y s/XK#*'O2C0p_ri:,'Nu{M/s^YN oWkgPO ~&+:|dgQ<}CZecme!iUZx-IǼ#> O' ܣh=9h0ij3&?-@;$84tpE#Ų#l mvzVr[U{OEI=ؐ *LvsKtld_ <6 "7XI7`ECIDEb%{eԲ}+)]ݯV1dK^֤BXFt -+&X51u "+>!q|:}nh Bm/ϯoU7gnQkFв֘XoY k[#iIº\.)XHR!!ש캻 &TՒk:$<Zכr3oobפjim}oq5EW..E&Wuk_[{,%#?{]-]ʄT@42:zg\XEܸ ()WCj rmR۶Wg\%a1' V{ˀߖVii~#N34 now˯r.jq9sFwT@%*ǜ ~+Llh>|-`!RQKZ∼7B_lǪ:LF%5 В \+!2M.c\ry]! y ~S e{Gϥ҆0u43Kl7^0VNs^5 *Uq܉\:8͚vl;h쐘5l@+#8[:U(p8_'ETi\m}@̛.y8l'XK^[-dBE:d*SM&k5>,,3X:UijtYD,\ m\rNePQÊlV`gq$ɟ¥i& լpo4kLzӠ2mX %h]tl-}1ˑ_]FR`(ZiXcON򌵻RhkJBc|F+JPȒf-pI*2VJy#4$ߦh~\w3h_/Ͱ2QO!fe7Zm~sTݔZؗ7U 7:謹JTgb]|JP<0mw$TouG6wHuuMX-+%IYmjl]wPx? /H&{{lS橡WSOIA_ jշ!Wgİzlnƪ>O,6"lo0 ț? q ?3e@4i&\%Ni}lϧ‧F S 31n=5M{Iulng vPx~IMam$u]OQaKǙ@ Ƅ1KMALHbW 2r ꒞a4Ւ?Q&^3 O \aM{h}V}lg2p çR#mc'bD4ѺG }B~ynddVsl;c[en9)CͱSI^ējUp0A^ P."Jl{X/4/xr<ĦΞE`9Ylu5F `&Y- @? ks |*Y*mF ƨ ee HX 4J1XQ'2qU/@& j8^ ,$Lb9Wϳ<cl%q' Z k59,?1JhWZĴ4OFf9"Dlrt6}l# .0}`1hzǥy?'q@Chr &ȼH|m4\"+CRA}i'i*,2+0у,y9d`{C܃8QφSm< E<y @"D<y @"Dk|'Pپ@t 27=.{/4/]Jn{ چ%Ȧԯkl @3`[xo2225}umilHW*lxV Eg쉫XkaWN$-9WV(9y/J󶟗n]. O 6_ƚd.(Iac2@#6K/Lm|WwI%5}nIA ?V:eLԐp)u*  أ5 cߔ0~z_gf%yh3yՕ Ydi.fc: |bZXM0nm]D!uX43$3>((4H )X+X,'x䦗p"[,f[qO,v ("ߟ.?m1n~`{Zm6BR2_ξgkBnMH7&`u93g0h^} oqu@{n 䌜Īl#8H BיGf+B;IK`9s 24 rGmuE6Ë xtG%4I _,/ק CxV=tBz.בg:PGg0-`}!:Sf'C2yuzF*j$;YWY'GmfZ&@"D<y @"D<y @ ڕx"}I;yy~wx<7.GqF;azGKd$:?-s%=3W zx>o^e~@uPgmK$t-mcjM8;Cݦ`%|r&"r&!&@AI8@L8qٺY_}ҿ 3,&5fX:Sμ8v>C ,!Wa芤x Fc< 6Ŗ\Bps~gwg3I.=M_ kL qedX'!c\22IM7Vʤ}fh.̀LII[wnýOpXJ $VC7p֐(\2!'E9FBdpeeDp\W7#f?R1y"?2y~<)}_:j.N$`Y KX'cleX$I Cȷ2:6z"Cu> E7t6$C}:fv HCn2SN^1bU e>.^wxMc?|d#*|4[/|zy10ӛ6/#=|>R((w1ht|,Z|jJZdactoQ"D<y۶㰣rL/_{YkAuwˑ}W|i99~1g"D<y @<7bQ</gzl{U΅Bݶߖ3G[3̍*D =gvIO^9xBR+҄M?!q^U:?QK}ke{_ݤ@Ћ *w;ܑ5 'jߐ V{9Vibz) @6dj<)l*4_b\@%9! {zv铽26<;ΞrAIb%iechj/8*Jڮ :^qm76;~K*gw;HcmK0IciAy6iq)k<-۱3ښ?<f8XWKUK)c\ħ2c CzxG0V1G[ˤL]8d> iSOY)cYi>z { ZA@[YP@)" i-<(4$T1ѼM֑4L7\'1cA+A5PU\}*nc59(na2:+pnNv YiQvbGJ3rIJmݒm#`N&MLK5zCi PHgE6WlWtR.3 `ge8y+5 8&fay 8*"?2p5 lQӰ&]LUVC a}%|coUzE5&8ű-~%t|y<~,8Ynh/D_b*p"z眺R,}1G-@?յ$lL<>XzuqXez-,XZXxy~9^|y|p -IOY\:qWrq21= l\.W[)avZҶ Eb+ɱF/ȁ=iŽs'i?@GTqCoܾZy @䁛+jl#lvVsFiLJgU߮bF _b8 mW>۔/l1"@"D<y @R=^E+3u_ރ3ۥ7NnlM՘abqbԵ- \&G~"g bxkM6\[ȏۡuwB`h ,/a jOP3,WH]'mG~z?r[=Rb^(Zl3]#5nV14jUtA &c`7bGJ]visyAΞ _EwQh/m4,cu:`@bO)`>,cV!Uj9&qHeQˑ3lWlv <{rJt7zuW"N_\-'T僃+Hlz0M|h\q+~փ`zulA7&Zew".)6cR >XPS% 5شSW,Hoùe!x`C 2_,ēTY`" @X\7TpIwecgnE+,_)OWД g+Q}x\DYy\<ۉ g >`N}8.?zb_o1>jM zt7A~@2h_#-ʃ ʤ %ޥ @^Gl:r\=yW VP+c&6C4O4|¾ ˜?`X꠯qU#k F lIO鱾:e|'giTt2?ʸr;䡮۹!"D<y @"g{MK,Dž,,;'g.!>˨ldnḜyԴg$>ISU5 LHN<#k!x-x? &fȤ!Sgy Am hjb<~1'O33g5φ> `~vnIt}>=9ճ/\|krY;MgȀ.tʑ'ѿae7qaڶ eئ1y&,Obu*N["D<y =rp2Tp>A6о饟y$+d^L/M.فoЖrxoBR¦-<~f$guvL@ݷTz\O\,ގVزFR=[P;!Wg6rDC7Fsj̡]4'Gidv';rt"D<y @o;҅/TYlzlq^S{4zi[A곗E_DS >4_a-杬|㤃"'+(!]9=֢ٝd첫,hS8kN r2 &G:>x2&/VgOd;B[劋4f̞Zie=^$ՕH ڰB7;sүp7ziD Ǡ>yqG'h*Jٹʽ zm+˨C4X@/*eGc414\Rܔ B}tEy4V'q{&Ǫeo+ eÇ\ϕI+x!3dJf ~2_w R43`\`re/ 2(H~ce!*0eCQG 'QlU8v|haB;W~]ڗ]9\Wj/(H 2ICYԓϣ%~(:[,ke^ڨUsTQVcl71su3vg t5eS>Լ-j I 0'=(?N`&5O^w|晶r$Uʣ\k ݬfO@e@NJՁƛ~_hbr|${p;lsWb=-0__ a<~m7/ОN+}ryyi}#rn()[;Lέ3gh&'Spy!w&u?{ߌ|?G o'_@^XGt~ lJ#շ}s2`gV/f)>3OZ(]HÿQXWCi,#(-emzRǯ ru\:(|TV_(y[4v3 ؅!ƾ}ū IB&[ ӈx(;&vO 1ѩ^H5@<ͱCm"=yc Q2SQϼG45;,&3A~cw%#cb^=y_Y\ql4V2IݝQRACPw~w=E[w]v<[e(?(k"wt>ئ4. r{H]~Nٍϟa9^~[ephP gdGfmn9Sҁ񃃗uv!_Ђ|feH6rZbp=i r^C=VOIl.Z6l? D6/J9]z1WwԘKWS̟ǎӿ/~ftDd{to!ra13J )ƚ[^.Ä"l\qWH'䤯9M}wLT@H vv4i Yϟ ec,a;R/eܪ#V#Z+xRpKV@py0 4C:eLL]ԩ\UVJcu;ȇz`G#V˥6pE|xh@7Ο}@;pEnQ0&(z`*ZX*28I YKCFqD5xL8>X:*lk #)L,_ސY4 mĄ _l,$8/ TTƥ%B{"i@7NЏ/?ap}9 ssN Hm am< >Pnr #ԥQ_i[ɫ<}@"5PalcVg)pO{UF> mW2'cI9plAɦ0M"¤K(MXyVz&r\VoBR||PM: !=c@Eq~:WhvB3OŠu`?XƱ )+cqN`{H@}tiKVxy@2&(PL 3GhtljZ*͒}]1~:v%n 8b K_ M7!To؅QH$G*$y2ӱ2յ׾YzV|oO~~59k_Pf[ѫZWR>.JϓȌ**RRd.X/?zYVE]ƳSgAڃFy;prbWmln*s96[ =_/{Z!$;-ϞQ^Pf`W??]>;Gn]&-_lN<_]D3wK7?4 ާFc_#vW>CuK8{d_Uu O>Z*e;)~o?\% sğ{ gېtY+$yu2_O~)ey#Ff ,Mۧ-d̉󌠽/@yl z/f^OrOji]81zM΂ya0}Mn#BpVz*i+i^l2&X,[݅dXl62f0>c'U4n%x2l1nPE%A'6J\Y@U C_0fYL1OFCu|FY`}~`%X+aնB.Ӧtq|7WkuY\ܒ LEk]}:ӥyc=Y\bL0`&8)KI#{K L`u!4HeK}Bc*.͵X,bW 1@p< yҏܬtV{j:s2\)ĪcsRE/cSJљsrid .JgVR2 j:vsG;,E2gi V|oyy}X#g +qqWr2&18QBWZӦ`lԤU0} %eL#`4kXDkt9T> QM(c"ZP>/3f~2֛>suciZZ7eʇ}6"NT6mqk<&E@g y[m8IԼ,H s[mt-B"Dxs$|}|[/tI/NɳgbޝK cx9_e2y.9*=O̜<{v _(f>{F䮃VP<>yh~l7 {'Z/մNvE#s ?m r !+ 0%&`|tgnC=M;@IDATo.kG<y @"D<yz{KBe_F[HY/?X`ۏ@"2m~=9/ cbr@'= plSek_2Z\H`!zSg>)G]>s!"W)ةc[JYG:?6^ghJGct+ Xͷ uE5bU7О+eyy Ve` vE*~A0`H_(h[ E)mra+rd0ڇ ,Oq.V+GEyL@N吞 )d9TYK6]4Οjl}_-u˰vrb22~eRN;+6VXg ;>a:i$ ) [R_I2V鏎OH~㢢IZ[4 x˰="@*3YZEsx ub_,+| 5cTcves 7;7!W:s_7@^GWWcx &`TpD'1")4A 0{v=v/XK >AP+ȓO/[tZ|J|&4 z,&Uc~5W«Wdehw_+P4meAۇ {W =Ƥn9Q~KWgpKwm0?V;\sٽKu}¬Y'a, g# {Z}V;:L >ԔarQ fݺ"}_ _/>s _LʟT9reZ>vu+/˹[ e1ص.ñ㧅f*Mq(JG<yf@v}$:$XwZ)ڒƋ7.ʕ5hs Qg+_;gۤ>IqWKk!&^ōިo[q t_t*1[edZ\,&u}0M:^0J*#,da\Z-!ac`FJMy0m~ fyil68ǣ !7{ԉL?3~v2veMc ,Os #Bv?jJi XbEfudw@^6mj)Y 2:=32g @-yV0϶dl!ߊI cPݱeTlAۆ JNMMaJFǖu5X]_IIOΡSgCL؊?;1w4JgCL/]kf. glKeV~Y)dKXTeRH/VP&95͢?-DŽ a)YX*/MlQ4QkLG XA{fҙU٪cÇN@6%,ccp4iE lLP__ 2r8펣5C4wd601 [%VE{T3v6i2inoʧLwx~dV?A8YL>Kk,ށډ ~ĎYAS/:&N<"D^w&h熳rpI"&Jٰ](D8y*?9" eq!O ǁȃGd?75JsvD>屗GHHGՃҴ[:u' J 3?z?S"OɹgUo之qXog8.ʳoCw>pX,&"7c=i/?;)+j Qp|` ىV/[X,*'<y [Ϳah(㰮w?.WJ&>9ۥiszÔ4#=/>Utq.JE<y`={w\۶M#g}GMEw@}7\׏|Z,B9?KBy}]@Ѫ<i+.aM.3--Vڌ+c="H +sɑkua^cΉTV-ED%$VuVڸLՙS Vd byfPA=yxoK%>(t`[G6@grgQǧ]!RV+Ѯ$ :Be HWure>j>/㒌Ma q1[]m'+VKQW6<0+A)PV^B٭&Ut{m;dlP1REzสxL갚[ӷlYS+ bA&gdptHfv"۸$*!o?ejn5ְ(31W{.n1JbG$t;@8JDp6"~xAy%' .̛lP 6t5A%Mj6v*FBuV/1ozWK'^|,ߞH>+Hl:pL>~X÷Z 餐-2o7b,/ɏ̨"JѵLgxPd2aAA\$]=_>= HitL 1gRh]݊6N_cFxӈYyĥ4[*2zI~k/"^阺,|kENI9rmO9yJLڱe26Y xL+Ωû$5=)G.a]۩9; -1Yxs(PϢRhY \ϑƭ@_$G)dկTg4 ѭמb|}҅l(D痑e}u|34FyeL>_<,(/~4};O~槗}Yoӵh, mM'~GznXlG' sw~sw{sJǿgr[WV>ZAkbFyaC7g>3-¼ڝ;OqkϷ*|; GIC"uuT3k [ѯ7yHڞyXo*\JK"?^*{(LV֖YPM$AYMRY-YVkۧ9c=cg=}z[mϴ,ږ-/t-mi$HqKoYY|}/^E|U(`27n܈*}qo5]+h ;U\&@v^Nw\a|'y>ZKئMk|YCאj҈2wlc7|İ46[=+܆__/*]@jkG2V %)J6SJ?MCSi+Pm5>} ܳvEe =! w߀q,w?;hP >΋O~&"Ngtwt7.q-J]u C{YO^pm߁!Wg3[a tKyڙDᮿ 8l;і f)Vȇ`\pFI r'`OKg @N 24]w%%~Tr C^ė8Od:[~0@lY$3sZ2;L?F>4à0:n 8\{ xA+?W&hvi̵Fu`϶4(oݶ<^bD#wb@'6К?Yy<v(uмꝞH[95Kp῀1 = ;Wf_[s18>Gz8!/ƒ9K8>tmUA 6o䱆 J@MUpr ~SzzdU>R6|Sr/'f 5j`4sks{ 2MvTn7~Mu(M*63ɯZu닫:mM֚)ң;80BM;7Ue./3mb]ɆMȃ2%A8}$!)bvVY @B#A 4~gg9@LOOeXwxwȓ rv0|lY]=kPbž C8)hvFY5W\?ku7G]Ii#v僚lV7O?i~L۠2SgF4fVAm*  K#)_L͌Z .3oz4ʬü:MM#^F&jp5/5m 3_ld{YvWP0 ьLU_vxljN\-GneTo 5mF]TOi&wa2{sNԺiN݌~pTEMZ3(Mׄ85#TQ_kׯ^o$6#goW}aWk󫔵,}tJ8'ǍLo8-٪9\_qL׍tdhl]Mqlȷ'e`TrV/j7_cfW{+kVSL֔Iz[ʋy}P`P"=Z nZ ߁R[Lk5@oMBk/햭abA;jSzSmH>Iϵsrs_` ky?P]tcOxN/VY?MymB.CW͜sevo*\xakceIFc(n;`3/Cî& y *"Hg#핽}X:socԞdy(磲kW'`dM4W#O;ʭ6cp: ?|6$Y2xݘNBk=-j\U/xYuU3㭤~;+'ʮyS֙)0ç[NVJ$4L328&Q^v2ּ]6 /oӮ3&Xe(g $m+eUigXT&%FwA>Ccy]i+➘$`># ~Ra>ֻ d`Pzze vyJV 1{hN<n[aNE*X$Ӫ8ΥnDOYbd`_>%'mqI' {:Kzu>>`8V+:XHNXevUz._g"=Wq C7ޔd"R'q.MWjv^H]RoZPQ40uW'1kAuu ~- %Ğ:L{i'GԕnF>hFҖ7j 7MeXgm|U0[DexQItHy^2X2S o ]mLyf_jaqd*:_@5}t<ЊՇ+8V\<// |B&=HuGL}zCQ1-9YƚnIEZLp 蕃Gsc1X w!b k>ڰ†6Eo~D7UP^Gɽ{bC >6=+>\ {4O앇ed ;L58{$w{/|Eo|Ѿ6xpHߑW [ǫ{ĿtG${u}H+_I͢7p|!+ Weֵk7 TH-A)ޣuiGhHd_R:ܱuۭ]Ov?$߄wl65uc]iz P஺$rAXkˀ<-hnWd[>Jnmr+(`bOyv@Jab&G@缫5yt^)pE^$U}3 .a<3WyX$}= |@e?{朔JWp<}lTPN),>Kokk}ި(<}#&;r߻s,87+g& ~Z[Jg%n]luD\ vTN.<}% Ơy;.K)F'ŻY@\G Vs9 ]{f:@YL)Y'ٍ9`&뙶e6IIO$vuuHOW'H%<rKddaj{{T𾒽${WY[ kMY&M4qbeמ: M7uydjFŘP' G͜A Uujx8M~إ'4ih1_uM?iiJKy l@~-?LH76O 6gybp{?w<{jFʙ pX ,7 u<=DPG%.29.Y`MѨqj}SI ;G=LDtR&$ u)g[<ɳ<Wwt@8 P6~v4,1> ӱo֛tKdr ،|>?pdRu肋+HM 3k[!CdPT;mf<,`? 4Ӄkh1kP @Xa\1=XQO5 (`!-%lh)WeSPz(&DpO@,6 q-jAYwkQǰhr)c!S '`)V/ *t^@^FY}BpV8"8-UW(Son=sHҜkm PȘ|i*f f3]:MUؕ ڨt Vg>xC@ȣ/iƿĶ5j @PB 5j`S4ߐnz]r5J󐤆~V o!VP6_M -%\^.'_Mw2އ[/hmwTfg'Fe%V*1XψjOC6;7*;.t6CD/@5V.=!'.O>ށO?Nzk$Ѓم0^; јEu 13(-c6$|mFX e']>~ x8f_fܬ,;:DUʸ~-id[1+7j^Ya5vA6kq@5;iTvo.OBZAb;\%1_V#2핕46m2ɹ̣r!I)Ȉ٠,E}4+K{S`j&-"ґHK2,gҋm5yK"r@-J+doĥ#-dta @Ex=y!_cpYxM 0vG^Uh..qUn4`(Gu _2Is=QekGK &f@=oPVU@ оTT}aofq>X߃eK(.I"Nuv` oWdV:"G@%[X@\1~> b0*Rm k }ކ`po1VM,~l.ZASAZǚ->%UK"2>9'̲Ãz fڒ bzE\"mʵ/iOc5 miM<|~uϯ-ܧe8PB 5j @PB \3 xU~rS\O.cz\v]Ͻ^]Ur]^ k’P6Q<ת#_H<?Ix{?f|=5 n lڣ{H=/Δ{3}Pb%9%w@ASA~aM.'ّ{~Fc+Vn}L>/uc܁+=c^2ʄ@:OKuLqH׌KO89x`D2Q}oPO1|ƾ$?/WLyi}Kp쵼$$% >(2?1-IYg&{J."LFR2fޟxFXgp+fx?сPe>a|/@nIǼ#u`??JcMbFp[aYa9 O{; ֥؁ŧb>?x~)bSDk7܅+P)2oB.?eݮ;wwKr!wP7DUMeT(h{^0>0\O݅RyPpRps9`s1 W>o"(0;0p .K@K@h\s~.gWêPQxNi.X0e~pQ8X{APj0*'] _Jv2S tr ZeZ7rFro恞n{,h[I YpLlFb a/P$XG78* @+2龼 rU ,-,aEAݰ.o QyfċAСO21o;3/_֌bM:A -M7U+ֽ{ ֏K41.؈t'rZGbx86݁1SƆ_ SB\$qV'r\-*eafpk+ Ra];`A]ƀq)u q=Yɽ[T1َ3[ph2%n|cRsk vp vw -S/ 9nB7|ÒWRf\yAmˉHИT 3𲝓q6ӏ9I D$&0Sb.ٽTޝhXwltM)SgG/}InݻC>(U –'P?'QI>( t`eRa ܑx.d̆{I?oJ|̨V5Յ>"CpJq2frZU3^KJ_ʮ]vQ dڅ[@"1><;4 +Q O-S3E ~s76"]xbF{< aq wB |]߆ 3X$8? xZdpX_JnEXgh,B.H_=ztM_s4W]xs pebR]s*!oQe-`=:Ia ʾL]9c]cӄNtU6$Ec] bH*}s;savST`jֱ[uK(=x*2ud/xZ%݄FP0D,pe6,9xqq=MŦi/STsFz-}G6\ьnjB('%>+>@4A:;A ,Hwa#5wO<#q }WO$1rng쀧2A-g Φ ukb2p>\>n#Q;nOa7Gg5q=[{ SS'[| +?"}iyo=TkY&#?+2"-T+_x]^ힶhj ۥ;>]y#UiJUERpG k֪R_ﮱQfokR—&iSV23,Z.ݙw%O RsrX?\YhdeW?(wܺK {̫`~Un1g\rge_zwyZ\rS;LI-ZdžPy9uZɅ9J/4?:"^ƊLeC=BeپW&vbX//?2?$ ~ۧLRZ>o{m^җ jL}~D;"Q'\N07_!T-vf֡3ȉםB,+9=!߭|;u9 zLb=svAOlX@ta`°VƘW=>^^A|,4ZW H됳8c3җ߾uZZϦ 6tqƥ io/OKV(-N0S`oZZ&A;qx<:=gSit.͟y@IDAT_p$zAZ>nCoz/o@hKqٝꅜօr. %HH\$a#ݎe{4&`Kla~@=ʔ!ƺ(eVK sEk+ ?X+P Y)*:pLeʍYx9 c#CY,c3>CU: 5ylr0&lԍеg1:cjY4dˇ?9 q1I#_%[ ҍ*q𦧜46ıOe2&x dMfSt~(I#O9ϕy1/؞yĤe zǚL;T|"@Wr}PV^M2n(ZnA_yܗqTqnt#ƥ嬳.yʪMhD&L(ze1inF8 :'Yύ*[kaN!/ 9*=+-W _g|gGPZhwlt&츥 \Ol"HJ*2@r(63ء=$Ȓ!7S1)]V736Ce7@ywp*TOs@^PGd硇us,9;7r 8 DӳH&iو^xAu=6nҊЩ_#Ў{scD^=}e(4YͰXIEØxc2^#H;-粭n5\Ek2𱫛N~&+Ct/Oȶ`M%Q^ ~ǀ,ʾ /dĀ_+ \;f d"ε@ѹF< ij%̖i#Ϭeꜣ p7-UNƊК#/؆ L -X.(id+nqi21Ǽ'yfALXNjt&4~2PFg 銡W:-" rb68a Q14~2 f!xܕAmц!@PB 5j @P֭|Jn{f)9'/֖%o~Mr?|Tm0>/+wV6}Wn) 5Om! / E&ONm8`UI^WRLn{v*2m=^:LD^z7أ{9YIK]m3B= 3蟸9$1}m~I|HBwv?=}ؔNK~[r]M{pS~)i _B!x:[_}si :^/Qu,$2ZY$ K NXII xn5WͩL;E;+^f7np+< \Nc M mB46>i\}X}VKUSeVBgoݼ$r-ᡴ0XKpߎ% <]vgs[w6rٗ#4*#(eXexHeFr coxwys  cP=P^i)v@uK Up/eC~z0w4[nHF+l-1lL%E"6bЪ_^ţ0}.3tu]SHu1 F/)AȪ$˵*=n^Tg(t1*jLip*ӛ%iHnDuUm:团zaw_ަYoi ?,`\= ɱgicU(hʶW3z}AyԟkX͌4 joʚuLdiLfhlveiΖEQsYc evћ#K\kq ͬɚYzTxa6)krw>6xrIo+|o׀Y4AhIPM*d kY׳}^=~U M݆]\{>$D|>׾_}6I=<yMHt,sR4 Ty=7z<ښ#46R}YpI#v3|3u&lY /r 04.Sd@<= 8o6ӧ g/9tڦp, ./842 K2,ڐ"vӟƫR\B؛'K6~+Hsr[\#ݍy )DvsIν G'7us$j+0"sI>UYvI0i"}w' rpJ&fq /Uz*VdeXSUrzXw_A,6L|АLZ,;xtO-vt'":6X.CoNJ1Lg,ͧegaZNҧ9% ~5=\+wjlzɵF(x,pagg1^7J!NZMy,CV\VÜofS´юDgL>ON6-ĺ: >eKI-&os]l~?]3VA`U/(=?gxنYHz|Jùh5t ?G{*7R ?`AsApUуG!]:q@~r|DੱXRXJ\㔁r}9AvΛ*6iǁFuH97EYHZD* us\ Cn! @&>L9W/i y^Ie+cKڗOj0|;&6`K xTܹx`+ʆv[rLf32GT-.OoÁ;=uHᡛ\$čǡ#=b4!a3ߑz~R37GJĚ`MY5jfH^ǰglTb9ytMZ/[!\_n7m1_yB8CT̋_q ~r~gg4mm4|iÿpB^;l}D?^Z?=p$.p4 xYCo lz n/*<^ ba[ywYN%_3Խt~TFc3Қ$-[ݠlQS06MIwYLއ]⸬d2p= /*}ʄvH_szu{Wģy@}O&{GSd&;ĐaIk{9p> )siF)z2$m i<'Ŏ1){=/KN]$/w|߀,@+\O8E1WFxLnf `/Q::"5da{0"S31_>2=&εSUj4^-oy'O܋M4f[T`3nѺ@Zi!F`28B<<@@8,i ɸtΣm}z4!;Zx<-᚝X ^" J\% ID0nHk[e< c;~Y6xG+0dk˒ùL t f,fujA@u!.Ǎ7W1Ax J&ϛ#ƧB ,Q]'` @7懸 NldH~.sWB< .| ͍APHfY_0G<:;gnT{d^1?趜ιy9pD`%Uze㼑n]^x_2/ivfm\yr,ڟ؆6zeent;W%Hx<x3ޡSnJ~W3c22,a$ ''YeXP@71GS࿣wFf?=!\v\=!uJ]׾1(O1MS7b^ppBv$SRҩ22;QNU|7a+6*w'lȳBzY@/(eǶa8%m{9|3^LU E@VP`4t#c}Cr"]7:&)AX\e2э Nd$iXD]Vyl\4A>Ac?ׁ. f0ćgTJw|(My)'oLS`ְ)V܌IL2z,Cv,c0UtV,UEϾQ>uI12nږμ$CŋG|) /w.;ťx/mUdQ4 õՀ];_e.z2/]oUےpZN}紗s({_&r%% r깣ܫ^ WNK:H>Rbt `ENϒ~^|yI6`)|MiP,gq ٟ>z@52|6 :ET4c3*rZ<{J7yl^` cMU5#',r7镻n̙' fƷeruWJ{IO$69T\TlS#ܷ䍧(S0sq96 *ؼ3OɉyPѐ]{ #ע6рG-}7х#C&\_eX?4"gq9^(ν 3V\gJ~MmB9ETUՅ!YDۀEwJ sF,iGes8/~ `O^=N- W풁 8εGpyOgeIϴ xL4ePd z#M@}nq6GdaѾo}' N8nYg6nl6x#`]2ΧռZ@s1R0_:*KEA. g#枌  免 t7 NJeVУ:Z.g0'FE0.^/Edq t*ea?L3ȺzcF;8aX G]ؐ7 m ~GLslzqC(QH~LlZʇ&zBB=0O^efuĻPo( FfgLVfےyAJ~WPd.mPa/I@>|̔ÕnGƝ6*)\]<9Ji!@YaBT'o&yq޸YM /mk>:h!c]1ƘH2haDPt 6ge?ׂ5 }"4 ^dC_U[yB 5jQV|?/O][wJ^|k,෈?uTw:߯0j'=s/̋k{ɣ7СH[P.xw5P]Wk +uX??s}N睏EE&C 5\>vkF1/X- $ 5^g "svH ogGRZUx,׾NG\vMjA@<w9+B|2UT)CSpE?p ' {XLH4.yӟ8X(2%N ,p Qr4F IFyGauk)+W+{=<d( ؀`z^.gҰ_'gN i1>tgo[ODc#ťbf ²_Czeg_g@Yucxܬdb $p/Q`n R Hg: 7BlLm[ >"+}{'@Pީwn5]=҅ _8)FvGv؏#pvʘyI{%0#υ@j05p#j`LM^\?'` ֍(x(Ӗr/-klwK޷C7{LLx|qy=!SF`nG&B 5м{iy\;(~B&u=Kxѕ~N[X U{6$;$4Ap6Ԇ`-8r.ԉ2pCOʹ~<2"~\ByoWDTpI:8(_#W #n6!웊eW,$=.H r#O_#|! /R_Kܤ>ON œcPkyG{zv;fzI A{~gg^ځM;ct2@؟, &kt-(-1ugKrt݀mq\< RngmDo9 Gj @\24#wҫJ8pG~g-#<7'//Iv@~ {N ! %yvb7>|*ɅI08*c`ze9o-ȱ3wm2]|á=C 4/U${(0pznVU(ӽk:ɕ_m[NQ , 5j @# 8}spOoB. n}!{$̮_u^V12oU k3Ͱm}) Bb^LXKuCf,%e$wiؼpːΥg%_^%_F$7Az^C'eWmw好$*{_56!'A}PN6ә9Nyߋ7eM1čꪘВ×"eFCo[SѢHhHI&V :iprU4Q5i #۝aN.Kx]pjp{|rm?,wvGe ^OW'\g --{>Z,6isϘ!L0_Sl*hoVXn;S28GН#Avl*5;p\ܩ Z4=RQK,Ο.ޜ'p 9Ty>*P ^zN:?Hb@":= ;w J'Rbo/;e,wf)>lVN_bF!,I"6+{ ̥'o:KꕛzS*?q\ |`|T ;n>\pL0uc LMKд1V|:kODU(nB`=x2IEAؗ} 9|&!+t,y7ֵA"rU>N3O Uuu&Ѿ 8q6wu'w6Se=C 6Tyz]e&qenC1ua54|GY֕ϔY쪓W=}Ǒ~{֍K71y9PC5-j @P"q=!k8Wx$+nf|Ƃ~a{c$@ʝ#׎"Y-A05pj`aQp$jwpAPNߕ` S`m .Q-<ߑ[a2@P@}>{yy᏾!iY֫aS6n_G1V1t`wo%FO34ܫ/|S:<*e9`k+q~x׫( 0/ck7r*Q畟enP~kә2>&oh Z@CƦ^u,7M -,RF1rT*{}-I&Lig}Q&q\^[K^Y& *ZwUehm K.S4[aX myAQ }0+κlL~3`d"r; Mrх{ܜgEg:0RN-N9 1n>ϧaU=A+o.|hDpK4{'dtu5Mvtm:Z$v`MmQID eigt'-z^*:g tYw$ۋ-"g/b~;Wpv`6rGVꈮy }"$,GLZ*aZs e7oBzٟ #IJx? +bf9qc!=cг;Dqv &Qhֶ<7x:qoq`v{:+*#pE'&&yߘy`SPB 5p5^<+qQv,E0ǎa;|R~tag<-/7(?& sp^7˓IO­cs^F^ӧlc>$w|`myⴜXS\3 /[r_u[P&z#@*6^ҷ W 0^V7k|!/. #ib;mʔx^%2 -F$kd61uCuǫĩ3FPȫsBo]kz>M$SPz7*Oy.|Ic3qmW(2-XoHG젮U3ǭ>ce5qֶXn:vc\x~J:6 -Wp^+pO_kt%޼'&=7"vEF^a_*?(kqY풊6X'nt@`osxe p]2.r&F>zPQ~笧9pYYyvq6w-]}+ƅgh_gTnp#>^&q7m./;:ǨDǎy`n#h_@ m9}|Cr%Y.,:zϢ P")X# 0hUm=`֫M?B^<7P5cڻ\UyM$kWs]o/gd4?YN~w)f\8Teg 'STiי髊p#n@?U.) XӊQy$ bwbL,E^yYKdʹߖgכ9`zʢ*=2LCXHcbkQl|%dYu/uaH٧uF??|]yS-YWv#m$3}oh/k=Zo Mfϔ~v MFxi'7iFsA?,u͜s/-t?3iGb"ZfQ4%NSDW/Q~? Q^?KLj?2."#i>,4@ xaw^j4ƙ `7 irn_Gi6M&I7m=Ww7lQSS ;Ć $|!s]^ %t>jtYMT6,i4zmY>ge2Ƥ}|AgנƲk=_L=KY:-Ƌ>oq_#ۆ0^&,/ž1VH" 5Fk&ۚQPSh+in#O/-!r^5aC"//9t|Z:tL^#&xLAl}b2^:yC6auF.M3`2p~4W3o%HJt)wȌ.3zuޜ΍MȁJm t(pj+[y_dx>5`ӫZn鳁r#{WAJGh1I8sa @=uJ"Y.MF`}!WA]a}bDln)\EY&˱UVl9*UQb*R"ٲK-YR-*`S$"HA$ `3/{{ۯ_ z=3Ϲ>Y.vvmx<=Wev/sGt뼋ͰO2€|a?&F‚!v7M5CR1q31C27Dm}0]CGEoS60ڟd__da(sm?`I;X. E#Ӣ#,xʂSgKx"s;'tgESYsu$xq~ٟ&`f|1*A!l"yO]B&yDZecɏN>.v1tmr{18g2Y|Q߃%l!w6Vxh"2yljQe0TXy(wP@$ wwб cs|~_690d|B"ڒ6q.Q@@hBnCsu׶j ek_Wj!byMUs徝r{a>f*#c̣1S!e9+DK+ ulO5 O&( Irwl$oթoyh{omކv6mn1n1vִ ;Nu"=IO\y_z AgwΖoWכ-+Mźe686~:MrKpRq/}=RTjz(c=>6{ޓNG!۸.~ak-/ٳ~+v˵x[cJ;{zmGǵO _?#R/oTM>h:I:&jA_)M=m*Ujz+ޖtR l,2PGtWe6ݿB Mq׹tM3!3i rdҹ 2s:c9&ϴP68q*fdXHoIC]a_8a<AUӝRq- ZWAْ]`(Y7g!T(+Exr$^yv %>32e0A3mֵ'Vl, 0>6ɹvun:4d:tP NZ[+a3w1LG{ueFz k|1yygpOp{Loj=-:pK=;+ė/yU$ ig#ڟ!{_<㴟_XN+pOਟ.t߫Y@IDATA#?.U`q}iZc[c1Y™uurBcJc;U+Pi"!A- ,;L# @&س`D$>yGeb!k Y__L3\ps'oPG8"ڠCA@[^?ym0 k|`5X`L[]a3l77‰/m hقr"X\Vm$8a6\gp2ZSFy}\j.[bĢ"Pw٦d`O&#_7Kv}k8< _纬` Nܮe֝j[ ,W/>E;SoS_򐆴;O G1%m!oH?3f9i wmeVd2m6'W]Љ >X 4{CpEEW|O:߯Y6*e%d\ѡ 10C&VDŽѮNPH߶2ܞ(4fMKf ,_NLNԴ֩@mnk wJ;򏍤Ͽ0mGj̦Uֿ/]ً+ixb_zSVGo\ZOWN/w}408u3rmn'?u-P[O=y6ا?4zr]ׯlrw>Bגi-pxl{=K'CuUu4N?àһ~ZXHkQ?8>Ǻ6/}FN-P[`[ Kyv#%FE+vsxۧ~ 9:'~Ys'\ ]ͽ?_) I'aʹkn!Gu Db( HTFJ[vv1f;OI AIޒbݩS3|<|38&خ;D>kݻ < <K&ECcgzx8n%]eؒ@ NP$*>*6̠JI0q.MvXe( 彥nȗ: ~Oͬ9omhxTLeZ%)MۀxST)"3~Ac<chi.Iѫ2܍?%`g8,AK Qv{~~>eqb?+!y=ksXgjK(p@Z;s(c8wr0'yέHFb˭_Y^KkqدF3-6lGsu=ϛZpdr1m}pa][]Mq‹,hy'~-aX9PW|1$]N[ű :~l,͍ӹytmCnPu׶iw`mq+WO'c ϳ#;$MYX뢣PEzjC#Hb0:…N>XT[.Ni!&\$LU lN5NJG_tBj⸍+bQ46U~fPW2[_iHJS|#t%n;:Ur|n[8B f(C2 !wf {MX{d<%6ĉ|(=Y0;|iiˈa߈eyK,lYNq_`aъ%X[6ΡE7?62Ac!Zya(EYġӎI6`/ӒMpi[ @u'&TmPqq -P[ma;[W@{d%?GһJǰ4~3/=W ﹋'q~:{M?qGS`4 =~u-P[6ןH>v8Q2/~1m,v-ڛe=%ggnt)[Z~3 㿅X]P[o`EaC7 ?wҺ83-/|RmY5Q]TvC)3nadt#$g()#/A:Qf)D;D'@^/]IZab7^T*nЭx;ځ lv.F|sfQҦ#!!5W ٹ;NμS`&!C RN5,> !<2 sWfv/=©q>⤀Zoϳ&(_Xn@cp$AmK8YܻXwS< 1񊧃LlA;Gف}p\!K__iMLlykq\uI7tZ1o&l+ʵ GӲFOrz:3?nyfu\T~DW%R܆ 9D#pq4h5daaMWq/.-^mwɮ$ cs.ǥ+l>hMIv{=9 5̋7|:m>WfqvN |,ޡJr $+؞ A&ώ YLfN۾2\ݧLSE,ym8~ Лyyئ,EeNʋ6s4X8IN]a1k\-q8DbV؎2|NG#=?;p=k+%vی.=aҠ bqMĢ"tTe(xQ'mir+,Z` E{2 k=~_:-P[@m[b3^I^)jatu:CGv~6}LyW ~;랻ӌ[/8[_n飏[{gt8kO<ԡ@m/_@Vt涗@o {K#>}wr~g{Kk -c~I[=e ۇ2GX;yh;؞ͯ)?7A cc3=&|/d}ms: 6^9)`XD>#-H9>|8g&->t`ٳ]S( V.P$ PjYsS J[VeA{g_B6r 3]䋸㘧\_-?0)t~3ǎN?2gK0Db: -rlmz8t܅tqv t8[8W彀G^6˫si#oh'_#>Zz |9^>\%;:p*Bc8f8~WpBu'Y|`8+8]KȎvQ⣈I a_G(4YK8ɮ.Cg i)x. z0Aǟ!#y7B?<>`}"2%O}WI2ˡ˳lufAFZ_I9Tഃ#GX4,Fv8zoֽW,ivE"0`Hk;x*T&u%hy_ޙ MGgytvCW.mqwދx. Bebwם.`/\]=M^2\ьA?:2{^)e6 .쵂 J3IV亐ol$$s rfYTw )+FpPG u`?__?K\wƌu-P[@m.^L_%ƙ]Qӛj^8s1- _?:x x|O1yms8`qIRA؈C&pp p{?闖ٸi7^J:ϑ*±#=Qdu 6Zav39|^kМh Gjn&LWXGODN"L,uQruݥ†'Xa{Pm|YM8QhGS <ڿ=7a mm_"ҏ<ĒY6M{ֱ}>.~xc'8eLx.v"t% @ڂ,4$GOgG v2\&!_KG{I3G:Ⴠ@E]|T-u?M<:2XcIĕ9I QRO" zy_Ñ? #Ī-he.`aA<&lJrt>*mƥQq=Smӓhf\TDuyǥtv2i%5q9$B ޥ9$悤6 7k@Ev˧Fj -P[@mj -P[@ \7?~['-y=asDBZ9u&7@m7`wĘƄLK'8N3&kq4ʅsiOQ u-ٻ¹䢎<ԪΠKd0ȓ |[uRY:mQ`aLfǽ~:=z|tItE~z+]%L0;qvՑ< 1L,W qNOh:8Pq-2#:d8j\~jّonOYQv ݂t׿|)܈H7s݂u#\׉Z _Av+p7ܶINIֽ|_iG=1NE4mVMc&mN|bXiS# u;|i!l{e.Dr^:}bARȢ3\JAǴVd SSizds'9%4p=Yݑ5"<"Rzy`۔E9rPEeemT4p* ξOK^Kd6k/łam< [9Xim>0ΐÞfu| 8q$".Le. 7d>t.yQ.Pp~BG [o;RʢvwJ8G6ձi^z!'xcѤe‡D!b$(A٫qNպl:?UZT?ڢÌeyOLK'Kťtwzbd#tJ;.h|Ж !:A,,c ^wφ;_XvhI% n$HǐYʹKlDfpVpbt>M'.0Z1%tl]dϪJtt"=Ns0=Oҩ*Noclw{ۿ>f!3Xٷu^UI"Ķ^4R_s@e*~fR!,_', eG'qtwȕ2 y6Nt)8Zii1UmO-4QCbL*czyGNnFqMI9vڿ2;'xcA]wtI\yܤ^9h/CQ#QaKnmzr1Qh@֓r|RZCYhi{]Y5uonn3X@-e{s.4x ttkY-,zB&a X9"h <Oi],R4:Bmgn+T?/" P0_|aN)oW|+q/ `QWJWόį% %VlF}Pǧ 2S*-- 3!;z_ijLb<9Yf ؜V^C>+vONL}ļ/wUqaj=5Pgw|jp9 LFȾxH; 3g]UsÌw@wؽy'^"DK؞[UY7ʺYZYzz.w;%e(x2V.!wuS+w~7Cjs#VjYYtMP{2dzzeNVlQv!77-t3ƛS k^ZUyt `FD'OiO8-\p< ?V/^wE|g)r:LB 1 ` %-h*<*2cӡǞ^OO^*2 ɓ[ثJwEU8xץPi+G-8^w3p((WQk2E%px{g0*Ğ paVvŠ'L?,1(45.43zc?XwBZCUp![AHzұL xOWtc`?kjl8U/~ywţ9|ˋiaf:wu6v/rT {$-he@8Qm!,Yd#zh` rT~C=p[[Jvep6]c!Tm,v$)2)rDyZdu!PYt\E)s8!..`Hg$3l"; l((tbTXȅ(֕4'&&ߜ[x71({'Pgux-qtѾ^/`uO"<†)iCȒ3X($zyڂ6 8AI#AØK,$pJXgDQ+ye&ĕ!b*JȈ3`ЏD7\ +8qgeQ摋wXcL%J"YǬUTw]\ r0Fca8'w}˂p::sNJa &yK"uKy|ʟ6($ς eJ,ځ8_ͧ&;(˽u^o@@j7Jq ߈ U1tTiz7a/L|oVfvLڙgnb1sm$sVD[Xz .,p̢7W^y2͕~=ijobӏS8fIF A|&}Lk .*Ĉj`Y.y<j [@]eyDcby<6e?(}k(3#<8*1Leץ1 8ޙ`u ^yb'uүOwKhiOZ‡s@zG$ed1oҹPt!bWr2@,Ӊw+fKp^=itCyIFKc`8{z9e4;mn?c-RJSi? %펎آ(Lwϖc7i' =Ձ$Z><,8RZ |۟Ϣ;F?]nS/mc?H^}ax>{jjzwu5ғ&¾sueϢR-,C% GJ_)7iX]}y}r(X]ʱ hNCj0/)Әr `\ǡ1^;ڝXTl(*2$08ߏs0ϴg+ `q® ^{w[(C|-m}|8=`k iiŝ\}-' g8G_H8;/5)W89'A9mv ȇ`^'ϱk#,2jeodžo㚁+2qCу䦐b,u4F 6]t'NW1d%d^nts}CR9t U'Q*-[heǽqY|͋lu|6 V HG8C#2ijl ߗk OۄRY] Dڌ.*-HӼ!c<Ôە䧸.f~ Üڳ8;H?p ]\tqpb!O)xI}Vʵj -P[@mj -P[@mۘ4{(fY4Mʚp"Ak\Fv&0 Ѳx# DXubBcy;n6M2%ea_U +8AMM9N@>x!pZ#z-N~l,]8Z&|S)-HoyJ8G޻Q'p:K OڎD1/_W!ÃG?5/6/tãN@:~k!}Lps<0:_Ħe9/,'py$)~r$=Hѓ]}Է[ne=o7}eem} wwdy&;+%0g~;}8Vo^jtav~_AtFcٮmc$ȳc'Kg7/-PȏcdgS/A>GfkI6~n)E{wކV3=Dl TQ Tjw:$.S6|=OC<>B\,RG>f$ 6ljAM~?Q$X4cY~|`YÑWs GhH`߃S8)Q9*y%s}NV8imG!6fpu+p rzwJsWc]bEJ{W[‘6)m]1sgRZiH#h_\[M9mHv_\MGLߜĘLo2 ?t 6@qۇG1luCF f')LqcF~,<`'^.U(m\1}#OOqqRjK6aGuUP-  LCx…Ce>v-*^ 2v,0Q b*9]/R_/諪m|??rl:mSʺ\.]ˊBY߻L;ǢLm ^¸ĭeYհ.GaCb!K\/ x6Tςr(~1nyʼn,8;yp<1'/Ǣ=Yu-P[@mj -P[@mj x[-2}39tl$j '5 0s|nzj@Iױ^1٩sVXQ}r:2;H6e:i9C:L:N <#L2qkL/0 }grk!M8.pqZd7%0wP_T?NIvt+<ʮ>./&o sW_:v9xc/?.s=|?} =p#}[0nj /6<yh$}r*09݌dcfbYμL^Aq=:>>q${[z珍ٟ)j:8 NkOr70eR\[,hƩ.Lr@''92swO vNqJc*'ɮV:w=^Q5So#N`SЁ*GNoH]Xf#xKs84X?ǝښD(i 櫡.YLu&<9h9q CbAeEC>p1] @KLlgϱ0^VTB^Yx3~8o:F)yx]k}o.dT%*#yN"Z !۰DiݔQݳ!r2]ܑlZj -P[@mj -P[[9bN0&"IHKdRE3)Ͻ|qoPRV`-LPQ\P:)&E }cny[%%z=Q8G+ugcWqR,2Blc_c٫le;[AÿUᣫOW31#>G bz2}D:n)x\BgrHp,1pXWuo|`J}OѿJB?>Jgqsjq|C*yJ2;ٕ (Ny]ORo-'JOz?G=˂-4Z'6ݒ6Q;=Rp2<ܟ}t0=u4慵)[8ڇҁ|(m\hwt%8K[fs_^Hg{@/|t0Mkͻϗξ4bx@T_xcCs@],Jh[MK_8 OGүLl 6caS¡_d?W=Jʦ4ЭjR׍ NcA3&b|>iʰ$;_SA Q(/BNZD T̃R ihԱa\Șv8:d* &( u:K+8W"ΩG~ Z脙-F4x}uN;upL8m?#s"NKKkiq~1%Nd7o rғ1GQvvf+EN6R,6Pڦ|%sȏS^Gy߱ )K8Xd"stNuwgRyNit.2'n*}HDih+psR !@Yjk8Ņ72lT2 ,`byh+4 )t&(d ֕!N/N?:;cd:j2ѻ* w:2\OMS#dg[Ebn07 畣0ζcH|ё^q*9b깝UL\[?qg pz臹%)L_k= =,U`:[F'|"JgB;M^JS#iޡt#Xqd|:t '|rnt 7W_Žcgxvޛ=f sx8JLG}APIx1;Ż;8OP}j)i{,y%pr|0>¢cH.]?RK%"naWh^anal }G,ZȄܙ|L`ģNmK~k9-Tn9u(aK]tˇqtWOvo>1;WKaB!"c+Dٙ)m)Cp ;m%e0I=8tnt(9~pvG[eC>"BnZ]l`pw]38}[iN'!J6~`G Ǥ Btpdz%2e*{a1E00D:>tOM8cC~,xXyan>=z=k g{8U] Qw|'V;#aNJ8 džNC7ϳbh:K K~?S}j[m..s@3]YK'ϤW\@ypP+/}%boWf Y̐Uƫ4 3 pX <\bO,r6y(C4be!&'(BPEIk:`sl3uy #UƮ: AZZ«1^Z;a&GQU>*ԅ Ǐn[nn<|2j.”3X;t$˜w˾4X! xoि851xZ+8/.WuZ+@IDATӅE./b6'Y{( i~P"lٲO8Vm\>EIOCmj -P[@mj -P[@m;2넣:ߜn{q5\`1Jzױ)&8+zmmB˷@q,SN–Y2Mhj+N&f&u3OwS@U&z[jiܟ3]8|^ L[LK11Szџ6ȦscJ:Ķ],N J1l݈l7:Pc&ؖiQY~v*TrqNCDKFFw'GS./%[P&nccC츤N+MsnR7p,FE 1"45N^Ʊ43¤!rz:hW8adeg9ҴuyL R̥v2v|H:8LJӑѴ?|!nbPkC :$Ktbzqݰpi>΂;Y`n< vP 8_XON/fw\L+Җ;v=% |a2x .?26#>d baHBn+:¬8_?Ⱦ}iyt8AzL*SG5t;i}uMjk*O3iG~lpMpNw(jR36e>SZuAU:r>+ǸTmaL:CNy|an>NU 4_H"3k0n5ߕ4q#+U{ c̰J;gV.-=9y_^Fڔf> ?4Q鞖ƫK2;O_]JX2vd|ZFlEuުsKfx ^.O4Cmj -P[@mj -P[@m;LD%|87Ӓ$;Ȕ"yj-C: g L.-_"2JLuue;Ǝr>tx qİ+L(7ts[8^>&sq?]УLח, #nݎMek8$CfIf6Zأp*(>`eJ~w)= '`M9BN~iG>&u>~-y, _/} $ }LzIuz?o/zSP&7"S|>f:t-h}3=4X0]3]yl~c)0J(wRw{p ]Wb7/V}fi|WlNٝ 3?QU ]'*  J Q W~M Χw9ύ{a8xV=Ih驗xrE`Ccfw8_w.t:BO>Wgi1S1Υk~:0kS5 QGY/:GVU:c+ō x4 S?tԶ@n1.%lJ{u=iG7u eyyws}8=,2*ږdzs tfuh":cWNYl~h[8%.c(^mh*r2Eڿ@,* ?KUáGQ%_u@păXUBL?w.53N+˶+#mVʦ= 绝$|haYfXpԑ?Ă+KՠX156Wmۈ:]~3ad'^3 +ڕccсScImLKK@hdk ix~?O܏CS'8dGx]zcC7YչseSl+Tr_.OjyBN|ҌGKYt5䲜,1 A7gzęvf\,)OUƜeTZ%nN^G}o8]gYȻ2KO'~ϭ8/,WvE-E~*.1ȱ!oQƆQvwvw*^ wmknZj ܞ8~r\2ҋo{-\F5nޓ~joq|\j -P[@m[,d,(g\'3H\8Oi^%CL 1zT^oѵ!L]* JS!{P֍,xL5mrᵄcafK-g5jx4Znplq::N\kLl(!捑AG"J>Pt =>8J 1 S|D Nrv}#xPx?'k쬽q:|/+ v2{hNAc,Ls|QXWsGDMtqn'נlң?5}]S8Oa;5uZ#c?9ҁ{R]VS>ˍsqϷO0vq5έw!\Nv#_KfJ!ѿܗ?8>ةgZGb<\3M~p: :w^S4X4 ?PAoMXSU1~ic*: ! 9.rnl"`)?z:܇t- =ʈKoJGN>bBbCwt2@_Zpccb!:b:OSLxd>1Vu kinBX|1t'v>wj`Ywi g#o^c<.!:ar_-CqIqb-`kݳ#`2ibO }EzOϥ{gv wWAR'vs^Y| }S|GA). .r>xjdJc"X!|IJ-ư2-|B>.xcἏœ@!;y\>y$|E]]^K0@ ⽇f``prD:09 >ƄČUEUouƘeʻwjpL^[%~ zxN}KڬwjC]Du_f춝RtI;IO}3!o=~VH{ FC7ڰn'~+^Ly%9d]6.:]lWޅ3 KMx7wHz=tz{ L t8쉳SF5߁jY7aǯ =&Vƛm%Ͱ~oBwh7ξvy?on8;k(Gs|YnjoPbdbl*sf5}-rI0homjA/`2p\u.nv_av'3O~?;& ;tt#I`'p~̣^dt,cG NccNyH~憹4D⟎>,{~-}KZSYp TwOY.H琯k+|ɡt ѻ8ioċrWO9ٯvebx7;R;djAךi\hip{l{+kga'h:'YP.zttmgE%F ".|!Ozzpm hnC+2>{Og(\ڟf&Kz䁁 y~_X>8#3_YJO K([kz) ѾA3;D*(L  gYdl:6匳+"W,iXyu{8YzD1vA ^c'/F9Np|*D+*}dI9;b]da٥Ej6Nh!hTyioyXI#ˉ#X};ܗXLmhW^2pzAgRc9ݻo BZT ҳ :$]xrv%ixdo?' LW\#{!ԯ+V[{~?pr*?8Gpfru<+˩#?B(s,p 0{)68@Pcmع_ڦx)^#v ?yOBxHg*`ERǦ8 !$0LG;A0c =h 85lj? k qS*8$t+)G?6B6쟍y'9w߃00 UН`1̘WCoE^~4:s}8gIO/@%F.w.2f;-乆P{/ie8DC6閿;2nW.NҶpL{{ ^ Wm=Gҟyjo໫]GٸtW_o2;raEbR3`d2Yց\<1/.': 7g~=xإt3/2/5ӜSre(F;PjYMe74ul=0>N†Ō"ظC"U@ҹFlL"9^aNywt1s|uU)aкcr@+8UX: u(yKmb僼}8†mg ٱt| |d%Ʒ \AuZW䫺>8'}#TZqwznN0ڀ8&Гآ\o]Nw cg~|j"-"c2u um;0Nv r<Vj!6-G]lT}N@itϢ:X`_ 7<s=L ]6R7D&b1hq@op~!3mDZ[/ZYh1XHXB)jğcɌSy5f$N/({h+1K-*Il}N9Q΂FasLM'w)HYD]䵇/׮%Y,| !>A۞r[I#`tI Ie/gYW)o;r*V)ZYnst!ܖtYf>"RR>-Cl!Lї'݅OXb|[d\+3la3xaw1%"QB+#F $~U2@G2Ov_( V[jwvwv-P[නKHڋ?VPG3[Asɻa2 .梞o>D^5N?xϤ/^8X0G+uw ?r@m=>]:Łס@mj ,鏁שWMZ8Pɉ޸S'7wEEusSVVUif0L:)܇{Zg|]:u- 'éAF]% ~ح}L w&!K ©txbIu|Y(SZCL3 eQ !f,N]3fyYUe2v4q,zS| ȆGࣤv .|t=*K93NJu *\W"Wd(^ZOuŽzHN}~s]g_c*\L Cpo ;xWLNYy-!+H9Y-/-t|еuPrȩggl_hOq;y? NG2;CیC2((: n;c=NneU}>8ppC7cvyq|sc]o9xe6 $yv~qlJ8N:[*2ix9)r mu vۇÔm|M:6~5){=v۶s]3lY.-Vpa˶y2 q:?c.k8]2 yW9~l1MmРN9u!z>^_dOȏ8A \8'h%Q<>ñv>ߗL[@jb,WX(P?uC6I(oulJnմ8LSQ/t '2:C`O ^([{v,mkAAx50چQ ƂQZ\sRxwZ^QNsk0C=&%,}i- 3{ځ7p^m7 (xGN'?:o];3Sǿ~ g6G/ߺ-?Gܖ9~r)N[ӝ;pGUܓ>|]gˆG `~K}[ }h._}1=?h??n./FZ4hxӚ9u q4;{A}OܖtfQ|g>vQ*hɻϪ0}qد<.P.3Oϔ6"EjD>ʸ'>[e 3 qwm/z"[8NP_vT-3s逎62.#%KۑMܦmt:o >Р\sZ~/Ţ.}A$M/(8a|S{ap}S $%P`!lj_6rYPc"i(`U$ȴEk?9~1H$ddx m |.E%Q_/htůN)b xp?^$ |akA] t@szWoT1.1wsU]I]I-jx@ߗxsiMoIw{v {?O{N_{~"ݛnuw|ۧҡOљtX:xt{zܖwH>b{AW>tSk]Ҏi~- N6' ;_G Ut m[-:@ h]e<'ާ 3=8`ݲTǭȉI^e=a |7 s2LVbyřR2&NisnuUd6EbhuκȗVL,@@%Ld Žlt7vtӉw)\݀M1\M gVs4=OBixqXPֿ58oI 4dznt }7EwL&=W4:]T|64R5@%N_8;9y zϥ<`~27٭ϹxDgDMUnmDz`;*{.j%oԎyfn44`ΩD=E%&atFWoإw{v{éI@]x"B|m}K=E7,%Vn5>wg3tjO _Jk6PITsSiؖt>,,իv9\[xcak&d->ؒ'YZZ4±s .Ni1) Z&N_H޷bܺy_/#x MS?mc,اEt,ʻ"m$J3ڐwHm)44cq hyQʲapaS '#P]5EU'x2KrGҷ#Ebsh3Nyt :QMN:F}F (ףЄu&|]NIO#_h:Ӻޯ6H1y1@K#22qJ>dܐᔆLLSžniL̇k{=4 FR:IT8Q]8*;) +h Tt)7V>u~|@lCTlb3(){!@3=^]wHE Ts#u +_ XV@_SG鲞9_E#:OpX4lFUr6[x2^6&xN1w1'GGo/مd׵p <={ĠoM; c1&%%\ .H gBG<+Ӯz?n Ȑ yY =#I:mw A?֜6l}cZ{܋J|;oTPt:0[+Y ѐ)U[ e@Qy @W+P| som卣[ԤYW䌂ivxF X܀nRilw׿ g=:Xlۭoŧ,T~^OZ;;+ZjygWz||kFc `*;sRvۏ/S1ҡث+/oqlo@*܃=-ԻoHw_/ھ#}{-!S>Uږ>\G6]F%%?sT?ytmط޾}kA#إ_Zm tOw3oYN;>կbkM@4hj2v s{zfsf\ſuv" +ta|\@v5ZzUEӿ|PvZ> $vGN'':C/S$8i',+[ zPN:*+:}G>h" KHEBiD njHڢsj'Ʈx^KZ3}Z{~EUƗ1Xn4 yySsʢ M ~w VdK>mCCiVD抅_kx@H#Rߙ~鐂Tty6=YYrzIد#Og.9WÏAWc9oV?#Lz$}]?v(st{-\+l(Mumu[r3mt݆Mf']ʴ*ٮg\xp1 ˄,xhդ,sc mCj-}ʤ3fQ2wWTB[Qh9,݊L %9\z~cՔ5ztc&[`3iLøh_O@JKIԫu0rI .2]-&`g2,zEJ u1h _[0D<  G[BJQ[ECr@X nS#WdϢ &~74;WI5̀|Jt@D$KV:z{sڡ-8"vڏk|_Qܮ'3Vv)PE D4m:FUi-8q`ZA]H_τl`NFU.mlY`sIs/28&%褫o.O-Lʦ9->Zfzsn+}l?yH Q ʖ"ô:ګ nhptzBт_AQ=?!91U?FdcگKvlӎ=c#z/i}~vh ]Q@ް#o\iJvɧ|aGҋN~p/.xR@SDbmE׌VV4xFw7m ?1N1&=bE(0,c /zQ1Bpҫ-+͔l [GnNP7q xu-w1xo/ }PG& [gku?se#^8~$ yZoǣl&F [[=: z_5:W;I~æO֪oaf gBQU&^ϼJL$#Oz Ƅ@|LW4…O:RЮfs5NZ@]2h[ULbcluQsiN#$٪@ܐh|>%$+mVmq{e(~ttjj*mݾc$JIyAq2g|8SV.)t+c'̓<6QS24NԆ- nWQzI; .)ޢ&dnamz= LL-iK`ٶ=MS _3yCHR߶n@7Lf|TQ{x@1盿LWPWcW^[Iƀt$ ySOf2XsEIw)eD}/̈2@g9cN<ζU4RfP:+ =]m*{lz;O}l(=tt&ص3[:~3ߑ 7Ȇ{w:X dshܗZH8>.r~Ge~vYdB^n^gpLMR[kv厏N9-?\k#ݼ^ oW3f.K4@IDATW wm ~;ԥOvV>CrsMxnάP)nWIEf7M:T_u 76Yg%H"Gޯ e(QpÒ5E-C;GU t\'Eα+. [zeie| gJ#<CfuaJ B[ oRh:LP JA+|q*(VdLuhQen*(೾uV3]ӓlYB5/+*&D=V(JYdG7ߨQ9tP,!OigdIvCRcjFsSI 8廭a|1{o_`,wx񀦼4@:j}Hu[L.s#!AhEF`P@olpX'fxziBJ'.(qJ ^p)C'[}ecp~5j}p3>{9.@tH (ǞRkTfN;Q ؆L=<Ѩ+GGiHjү-j}^';j]> d[ދŰcX'33 ]{j'!Hh~G+]=ziV3>MN(͘Te~c긐,`*@s|`XÖk޲B'cQQ>}žeA[>ԯ~|a^m\ҧV=_>Zg䢃 k̰NaX߷陴8=fKldO iTh7nh7yl-x< ^dO)uKZ68!<$#=fK=e,|a+uaǍ˳|fEe۔BribTgLm@/$MJN}i_=<{O o:t(_zqÒc1?oh 4ƛ)Kq|+@u76b#y/֠9dƐPjhuc6E?=W6ߝj :Ѐxfu Ɋ7$Hrw|{4loݍuuˑۅ6ԍ1P:_oІKVD6!?Ս6pϮ_Z|z2 q]}v[NC#{>i'ߓ?%~# gOЩ{rkqS{/oI7ؕ~\xJO iN_3nq I`c{wnV՝8y4ʗncSg27cF*/w#'ntw{ֺ_npެn6cA mk[Եw { ˯]/Gvs7 ?l'_xdYrDU_W[وn#{6Y_uuv|&;pL<QΥ|_|_6F6kf:lo34vc3<\LS>~ Rࢮ^ދ .e1]W4㭦!⒄w ]4Vx̦[tD%B/<4Ao nDlFt+yX'NM E}[ud1NC8#ӔBƥBO 0((X AlPn1wc)Sx^xFR] |Q kMN0U]&iɱv=Bzumϊ.,AF?$FcdO<@B #:䜾Mfz1ݝN<`%D^@O-fKG+踢osݻ{1- U~GzC)zh>⢬ C>(uY*u}R D{ᥫͶ;%S:G [eL !FulZEeft%c#~%}9[|ii\A*ᦅ3>)ώO:wS; Dcj%i8-ga~ ,n-rWD%3,C)YA.#1E+75z„c,^%TQEƢPH>>'oNkQ9IdR%a5vճ'tDQ4*+~W-TmDƗ zEu : J^];ĦD@!(;DIѶuíl@~6C]鐫j֧@ yx/B;ሂ dQG%0:k^mRv`?<<~qyQ!Ѯna1>mBm"7h )P.al9`/V_{} (8|z:-Mz@V%[ v6CUy4KO=Z: #*(K $ڍa֔nN^RdYN ن6E>9g ^O5C3? 71X.u }M?jٿzƍ¢|ҁc!:G-n6:ȬA参rDo7qs.EP%[!q`9ii ;̺dH|H؂m\&|ez뺵/ EvIKeB\H:@|^Gz\cwvcm-eG)/4⣭,@0b. n`ɗ5/M-9izRhe;B>Ⱥ`@^y@4x<̑SzC8䆕^L{+؆S[x@4hށRl%h_&8]1nH)󞠜ʃ/J>>4s!SFdWl=?HO%g_ /DZ!nO |vx4G?vKP_x̔4hooO{۷+?ƶFdJ6 7d!Pu̅bDG>F\CVF2PW)F-:>H>f\vs[SeezۘC*=lXYB qtP#;E {vs(":N|+<%Ӿ;:xYdTyȖ],jO[aI$ YX >H1Ic @ .Y2A2 _] vrZ"WJczYC(K;x}1 ,_h/J`^ DV_Ի/EX* 0ʁ,87Au-\/ Qע rpz2h0kZpmٽipd@"tu.͞y>_&*@ޠM}[<%8{2M>8j|dHi\'ɺ/P]Ȇ UN:Ds^PU'aObǤj*)4X_&EnAM jʕn.uL"\ζKQpjJiM>OGzFh+Xn.<Mځ) xgh$ehߪv:e&{K[,У=B@$ͨ@GXAz,?ۈCkTt"ܡǁr 9F_<ިd7:g8-z,o*AVVZ(4dJENl{c9tUS"]9VNq\ .DY:Oj_ M&Rt$<] I`G>uO|*0v T1H=%YEփk]=z/Hl{=fb9x>xܶ@ @EA=9xhQgw+A@ oS?]ln4;05O_ p- ɮi_un[E[o8LK<^Ms}Bۗ"ىsnkmD2%/^|T Dcu]<;(SCuw!F`'`*6U]|Q xotB6(oSjk4uRwk@g?x<ҟ"e/dXUcヸ7\`UBX0P{P?D^A.>#ms*[s;6փ㵺fkǯtm{=gw>탧چ$G,.Ge]֘ZvCASaㆌSJ'ʕRxqqQ̸A%kR& G0~()|N fDm" [Dɾ4I tȰnUmrU&9⛜Fƴenn*NMlC~]VdkwIBT Su#2mjj4mBklNۦҧon6~ۭ[yNh8G%'] bL,{5UA\! D{IOtz]nk)Lw[v,UFE>췍jیڈh|7jg^s/-o#ӈ>8\^Գ;aE> TqPA$3}emApX("21+:yĢZ0ՅRWͮuXyYv@o,+q繛E6+^wr⡠ %G^d[c:zPOñ>z1jOd%g,z?RPҐvo3VONk{ WN>E.C#OŇ$\Z0+O9ZKpEk#@O[Yh@øm'N_akf]{ajlЍ *N|E<}֒Ex4Z, ײh̺bL@?E;C fi]B>07T򛼁4hx{۟sHL%r/q)ˡ|݃irчuMv& A8 2N&FЈW`c_ZJ'D ?dYt${g6l%}P"o2bL!PiMN[}еuT6M̪=<>A-,K֕g7i$[nq|zH`AКі"(A.\~.蕭H| ^z= 89=W>Y!2Pȭse{|Exlhx$Fy960빪/M(@C`N;5WU /͜D/J -_J{ ޢ?75MO9ډ4C*F7, uhzCD*陹ttǴY]nv8{[ejDc~~hF@ h/ ^8fҮ7xZ]ZށL=K(;xC-bj鄋D vڑvSE37wч`nE:]C/ +<.|ּTW_ !w806s>A>Ab|U-Wx :*,Rwm /x)uhl_ME-a WfZe4ZJCCkwwkǗbP`3]JY@hJLVeuiiBzӡ{ұJz]oV!!?<QNee#k8DS_]8S.ٶ|U"s{@t$͑ۖ|:h" "zU}zFWڒ ?%4 ;8/~y9Wڈ(?Fl`^V/\(n]t!#~ /ka>Em„bn>L-GW]S|IC&^vOd r=Y=} 2Vtd,` r^ d>E2 ]Z] ax St IGw؟"r_6+l@4hCqϏ;UW9ML.0nM\9'\"1h/;dt0&W|3>lVVuCd&/;y1~nJ!W$^6?DM!0%҈AGFUm|:[DٕѩcZvaiԟ4SH44Y+|hX]}麝)M "COfghP֓~{%V=^Py vNѝЛM>zLZ-~#>5=ctX.>2vAG#b[xDdjƝVl6h9ΒOg'!/p͍|dꓷzIǜ|O|@+봑=Y嗒chly P0tN(l!-)0v|h]OtgsUPGW7L^*&u Qi*ϒwKO𥺫-5HqO_:OɥsQ/ܛ{t5zn6-F+Kc^(<ͼa^wv%=KiF_}y)7xict3)a/ȇz(8@p FʁspTRJ2ikg a!f,=AОZ-|+D;^cTMT@%eJ),vǎ4B W'XSZA-Иީ* }2qAe] ݮUJOeѮi>{up_`+]l{F ED X(ZRAعsӨsss] L|#Er-8?H)m(ٞuam],l"u;C&#M~" ̲?bY 'Ai}^d);19`bv_ @FZHK+omKmznWȣqݒdqJ_VFnEԥM`Wv˂VOjB'HIj+M~Q}o9:u.l BC^ øZϣX#`>g~,VcSep pB{!t`,r>9eż ߣ-N0MCU]gQ}%&MJ+M~H7۸xDYu運A /}x~yop~y+l睦Afl]/o/3af8_BafH鷘Ͷ>o n?N~y/Oj)]R}tkso9'Ӄ:;{_ZH;Og(Y ޷/]?,?{P:2q M#oB1#c.c);=nH\%YD6/S"&oM_IoVw7ܴϢ9Bf{F}jz&IobzQvC4h?c wp:qyzr|>ޡߪ-pnB[JYXYH8&t,ޗ)*:m?{ Kiǀ2 E-H tEkoQ9d`dL]<xW^ȠF\624b۸9u\=_A4Te)DwPs~}jn6*MxsuT .(p8;Eo R{}2wU߀ϻutqtĤzcƀ^O=|> z)t!?)P'NOM[|:4j ]ʀB f*#Vm|&ZѢ o}_ɇhoi)̨$6\;s- ޻16{{Vvi g;ښ ؒ9?e.36z" М"(Ɠۨ<|eA([5θ--?{ȋS=xW#~Yy>e+P tNၗJO)\|k-2,s@8i)xmyt^YiFz{_/+Xd 4( <_1*kߋ]vQ(<>V*;q$Ұs1P 4-(yUaeO'w\nz}=ϋ.{1|hÖnuu=96tK>Ƴ] Ity!an]vk)i\i`7vmdK:])WGyY{JfP]=_C2`#z~p^IQ;/ϺKȈ4/RihhmBo]vgAz9:w3ÿ'xI7ckRu])ttt M'+lu]4x7u3&[ _`|iG#ʯf;\6շ(4a6LXAyOCd W {ҳ~2n JHG׶?}+':rJzKyƳzFA)=u V8s[uPfPz5V48!@;GpQ%=?+<[xb_5:oj"\w(.4iЇjwT+e|8H=JdW3e4q#vgb?{+9(e5Ǽm'ݡ u|-<\JEv_!2]ЎSi`ߎU[NX:{vvtjrw3ULKrB4]ڧ;wX2o[J--^S:vj0^}}oڮ\M_ru|y/[<:f~ rWw {߮r*xRG{m?=&׹Hဲgpj#jv#UzH[N{M^#?%[\v0 :9WSrzSy.G3!tiġkזZқ=7NΦ.{%سwj6ɳi<;9L#B]?9?޾8B+=ԟvأKⓞa͘/WS͙;tj'h0kb,b}-Co'kK,Y:'udKS=p"OXN'Nj,T\JHNѠر'-^MGNZ1><ԴQ }Lڢ1/]ޑ4}|:=)wH]ۋ!;GIDzs4+Xԫ fE34:am:JPb%गo+ thA)ӈ̼Oض"4O~*>wZSm>vM8ރ䏚ʳ{8|^v@8iJt/L(%Ѩ h֢뒾[N>-WtE txL'}􉅼%ۄ]v|1#]&U^U>L_"GlSzEΞM?q47fPD_M">8_MTGjb;I&vw_]?6-g 2[G*[Mt.>#N|Ge=zbh|ckD_ܐ1}raB;N-c麥4vt:7`c~O#bQr|#$r{iA5xY '0tF#˾%ؠz7ػO`ӧtBj*C:a:_DxmGϠ2vąGAU:G@IϘ71g{~jI<;MY XTկɞGVolȉʘ7m6 vtrl2?y𙟲d}>iK^#9~)B]\HSx_H~_ u@4hMX+ӯ 2Pzӳe b&}qr)]#[(`z@ӵW)Ѯǿ/Ztwkrdhekew}jnmEx ж>%ݢ@ewlzBv# ޟ{,֙og>^1V n= U<: 'zo^- ٭lc=ؗ/FU:ﶟ}d5|z>J/1S3T-oBg+5>!er0B̟(X&ؿ2ӱKZ0'hM?cG:!-26vLݡ[T`BYthjcWͰnYf}Zyf\ٍ>x ⅝pm6KUVMȪlQY(V=xgs:[#xxs3&Ͱ F[Ё&Xv dɚ[xQ9X G"Ep`bFvc 2A)CKgN)v )Ci~FϽw 0OQ|.s{1)dFd~l eBYOi+o$xv=d_eG>!zɏ,@9IёgϾ4yl:+eX'ޫ$2ËD"gSy?zW;P:N:D.vl0mQ`5җf{)}8&SbWs">1{ l3?^7pu (CH<&ѧ/aۣl_)wr@ j [kv/ϽW_gݪBF!j,uHJE=])r+wȃ^]fݜ5S!=N+M4h^ӟw/EQ7j'M@IDATS "x w]~s5Uѽ:o1pNxMKO,ݲǥ҆ o+=|PzҫX񌪿TwHTwNeH8wd 79 oϥkE+ .@'N|hݗߞ/m9`N fsY_ސ{;>4VcFh>1A;OD!@o7iWU-W_ͥ oec SUw-)vV=vw7R\_g (6_y/Ev.hQFd|0B )]ֶ:y"[ qf-~ڵ}g:7;mPlL\B-A KI'+#-[ҬVMkq"Z)n+ l(|lD]*L(=] d7S}iHb#Gt!+s_J.u#1OYuy4ɬtH tj V1yIE ð6+S9 Y~)+|╞LrZE.Xث񲠔~1zIg^_8#'C{v[L:s7vrN` mN?7>RAsv";S &|ઇy>>.DCȬ<H7s}FF>##KN2Ӵ@_W`RB^^ޛ+ZUthd(-Ia>}c̓ȅ_|C R.@* @7x~z:-ڝFk|dFmO7qכּ(w]A79uz\lЩY]ޛ[~\ukW{TR۲$-hl` '虁 1a &3DalܸiFH6,YdU%վzod{}K˥ߩd7fl!=7367ig`V‡~1lʗ>Ӑ/q*P}WгTH.d% /3JQAgD,Htq M50'LH)Obzrї1yCxzCeY |_`fۢ,7ī@j=P{@j=P{uf1` *۹caB]3%&>v9 .ܩmy>s;rx ST^BtFN};\)E+hȻ }z ^I0sZF!r<8/"BLpegP'lT:xX|?]Ѭ6Ў >;eYriP責vf'8m_vnK?~J5onm4ۺwpz^ ١]{oAqԥ>ۦ_MوٟN/v-@TH_Ƃ]ݶ>[~s:Br-GK|zO)>+L#jcuƲ__eu/~ ??zMzVr~i(h9-^ ;N'١ .;>X#hÀ!϶?e+ω;oTgd/ZÆwsLywVڱX{;sNe/xĢN~"uQiL|І 4䕸2OnSPfO=vPS\e]ߧ1vV@?~zܬ5cOo7U\ܩ~ЉS:H'V/+iBRsA{<(Yh DIW<#bUWO7Kj-*Nei@V~J{7CLBP <> uzfƦ_\>y%×OwPcz9}lAN4qwMMW\} eo,dRlvmaTbJG޿[/gڮ"xNE&{.i ]W43FG/г݃pAH]PE&yVDP*<~8k:Ўk؛MF4zmTD5;Nϙj ʌ.Df؀ʡ'la{q͑m%9tմ/mȂ.tҷ^}S3:/}z7D+~b,8.HDrbZtyHCvr_ ]Q@ 'xSV γ$[م+|mD &ž]m[CjxM~}M_~/g^@j=P{%z W"|c2ɸ%pJtVg"M_~Af5{[%ܨ˲lgؾ7%k 6);=7r` ~l hBo^;eotԩGIp@;Ჳv я>W (Xj3.a=*;YwjŮ{%9$fAЬYczxzIǓwkцz^n@wC6>\RE ^M/k%o~vNX| -:} FM6dO5 zCx|َ=rCiPBv\AE(FҰS}Qٯԑ>6דs9-*a[67bA-z,(z[73{Trul`Z+oGߙCx~a~^aۦ]ړ tVAs1ix dG3hMѧnlߏFǹ9/ 4GxWSUKݽuFɚТd YXS:K;Bot n=J^-QSt?04h4@ٹrz'dɎ7Ŕ1$I5Oel8sRԔM(pf7D:( ڄV`7.P"e}zoikt?v\m{G݇iǾ{no j=x,[ $N{`Ssżs\Sz>ݮ`G^AA'`8XdWи}A>ʲh\A{TxF{[tJ{)X.Vx7DzhxeyK dJ/ݼ`mS6(}j\}9שD=:#y?$Ʉ4=? 5 OYt/cþy.]I/>E x|N-{?Wj]X+:wK}hy- ¿^=0.#;eRɯ7ډZ1!7<%KdE`ݩgZ8 SA!f-/y@\o,<@Vy O9ri񬠽*jW~.gtG_LnJۖWWz^ TJ;Ґ| )Ţd芴*H/"lNGk⫎=؅^UHXQ}j\GӋ۷y}/=l:A[2 3 >ݪ'BuC-8<6ӎAEVF@_HWz /ڈ.OyD໶PHmi\8 jEf&]iQUېB/6>pp|Cʽ,X{xR[5W A.hIWz&( KZ*~$5u~]$_/Q{@oE}<_vu;NϿ{+qJkֹ'ڡ9WVZ{@jxcz`y.K[Bkさs|JӮU].%l)T߲탫ǿhGT<[wZ_ZPg5't+m?Ǟx5-vԫ%O֟ 2) #@&_ݞ㕚{Yrlۊ+9'^LT > D)_py։Uh{Hq~2qZ;ϩdGo\Ef/ډa\V]vj>oz\%ܓͶ?!M,؉]>k3XyA%qS&OInInn@Kp|x>ɾoWg_x^8`‚_4lU tؤƲ ۰=U]u^zJo- 4|:Mmi,;?xWÒS}luG۪qiyWctZv>_p d΀2.TrbSbфuVX|E;=U6qy[..:~쥍$JB78ڀ?C·b = 0󜓷*eh ^@^"{MΔh:6#n:"Gbǚ ޹ޭ#檗Sb.W \gKWgp}h"ulOϢ}cqgJUٕ[:/V~(jҙK:_{@j=&˂` sm>/ S=D KcK(njwVҥSvW9G:{w+[(Ѯ;3lUC}~v){o@(T;m)ԢR#^ Nj]CHk yvrޙ-!|aGY ѩ^d?ܗsW$rNjG]E_uM<jò]< wL SIܯz v5/oIDvE[lcz_ڝ8ԼzY㯣KA;ޡH_5Nvj>4Eó׮;<>xO<%hr$5[tYv@}ƆwQ$K"C]XagYr3I|~Җ,  lncΜ~AW0NL6eLJ'hjt(i515]Z]xKћm_mζ" ZRWcxe@[2T4'm߈^;dBfh'UE]^Y@UNW9Fq"NNRwRƦ뇆+1ndw n{.A;ќ`]WnvGb\"R]:xNxxM#rYwh1IWО8ۀvkN/vRs҃O^.T# p {Y~ BAZ/ E b6/R˃j<8#}p|Avoȣ}m*mzD2zs)sQ_䡓: /;GY6z[zkChi-o(&@wۆ&xXG"5)keoFoVFteW׿>6rGl"?wȆƎhvֻw}פh_(ܺ>g>n{}ۧ?ڕSv_N~}3v\%v?$g o;6v7} CofH|TKg)Y+:6z&\ZXY施M٨`3 ySF֨wyPEn,)|3nüYggMծ6\"3dqKD;_!g#]QِrQ$¼md* ݏWJx=M&h5ƀ=?mwvSotƞv^,7v . l-?g[Ʈ?5izLr[ecp-ʢŇ>2/QO2ɱRȒQ!#Yyϕ_HK'+LJd'1}ׄybo(nIfD7巇$y_VJWҁЉ~Az-thǶrT0P3B׮| gS+E{<s(DkW&ӓ2}z[ыtq_&T]+J+: &~@yE+%X!.LgǍh WQM£OrZ{*>ޥ%NvU!C=~,g7 7 >UVR#J;T@ !^t9Q8A _Yf=rR#CD,>5{eF~R^̸SS׀X_S/`neo#=#an GU1Q ɴ$"GBC6|m|PwǢQAJ,/ltp~!,}/G#,W 팅V_O@iosAT4gL!wZ߈v$˾ya֖9X@B"(/8}`SA/ԴN+#9>3!^Re@4`\f;@lTij,$ECy}Emx~ه=C9K KmLlsuY׋%h%qw H |_ 팁+:ROv^dN߁-f0+%L@cX4 )jM4&moݴmf{۱ZS㗨:Gr̮{U=캗^ .;>NsksNUZWH06n`<;aOLi!y >SKud|˞ʶ r^QlEe՟Qn h(g6ї6‹zl+_B cBf?R/0}3迱HuX$1(q9$B 6z5^x/i":S;5NYT7?˺䏞j=P{)_p+mvQ_eS׏OڶWحwo;>a6%Tߖ#>'nyuvrYmwh7v_;3ї&#`ҾrX8occKޭ#v`nxW?K-Nן:kvA{>U{Nr~_Em괩sggЁ]vk9i[vX~ȸkО65=P{@IN~g|O6`n.Mȏ;CdeA+y- DӏHc>y,Nfs_#;6&ok}>9z=wY/-;Z.Ǒ`$,B$mTeH]B@ aROn"DeEj<J/4D![+Wd|QdN]!2էIZvNkRvO?DѐI*pUy OGf{F*OT$ԉ숝8˺馠q WJ2jټyI45;↠=#c=x?:"1]varڦtuSɡm(.)@BLyd%z[D_hg[oy9ȗyN\" &fp+/TnlxvN8M-|!#RD,zUxSs<\9ڏ}$#b?7Dǰە 16ث:{w y%;؈|9sM6r '?pG7{yLZ`1#-<ꚳ SzMh:*_}~lbڞg&tt$e*Lm9B*tE9ʹ|e G>oԧޯJ f.N=oyfpMċp\O?d}ޞ2w y@A//ٚFeܹ5=P{@&[7]k*x8od# {w'Cv;;b+3]vfOm/rM:71:]c4|!|eƻ ٮ~-rah-3Lypޏ9d{lt`%̴ 6y\N3Fu 3(8> %]ĸ(f$:|h {ZЩO:tHC;8_x5}XKH6ݟ\j.톿IHuD@m^ 9LPa@AAy{Y N?JgJmd :ZcR-C֯Q~ONNceL@=cR#zwݐ!ʙgQiUreݧs3o=i X4Ɩ_8`*}!W)R2#HUH3Ŧ|oQ)؏~U>"ALK _cr|xpˠ~V3ZuֽFtщI;7;=$d"u(sEHɜdɆ )P_'(y YiKo?) h"0˕M,2ժ?U3e/(3,<89P߁? y<7 `9,ƾ*yq\v%y+Y@h{ïyq!3U- ]A_.^P/ӎU{@euňgr$<7ޗ&nC#g/)hnm+G侫ֽ퐝N2?n>-/2gQ'ycDec9x(䓳1euUj>W'kyҾ]v]6uaܾ_ :=P{@j=3WP3ZLj1 0.ݘzU@C@g$[]pa{(0ZvA:m֛\J ,nۄ Y9W5\^e֦jPrZQ)tlJJLdO4NVzGt.J%I_W٦zY@Yۨ8p= d> є>OM@&ۑY&˓BN%XJ$xdUBl4&B :[/qxHPy\8qה+LG=5#h).ݿK2cS Y,y/g9_n783ܮhF9$GWU U}LdЙ&D"jק\Oȕr6%JatxK4:oJE-(8A0mN ^?0㔂S٤ʓm -gD}'69><@"GI;l:]x\pviV 7QGhn-gضuh-^xIMNsGvj[mKO^ iu> n*'=RQ4HAxg#Hi7L5RNIZ`BG +XE)8t-G^/>~-D⧒Yo:v.ԀXW@u\ f!e !yi}JOA^=| .Y,Bq7ܯ9Wy|苪&# HOYٛqc6)>=gƵ_e'5>}~48%,ZjѢ=;w՜i` Y% (=&%UiR Ƣː Evʜ<ؔMa#)^9ա||9*'+R|iA.|lBf6Øŝ ڠ!u4c7du= bezP{@o7eqM){zÓzԞc_'=S'4fU^x5ڃX_} v7/\n5bwvhLj=P{MNF2:@eMmJDMfinӫDZWh D mf|b?۹%S+5| 4/Ԭݹ[U#BYJ"% u&R]"fL8M e22&B}2R+rQ_)vAUTL H_Lz5ۯ M<4!;}NH;!!F{W龐-wPd_zg!Р;֧u'vk IT0l0,&CzOi `^;'vA'ŋ4eۤ{AMAɮxX6.,:{(H'eNΐ:hxW4~}ܯ=/%H?#ƙa,_WP+kHX;A0<~(-\'Ye7> ?rQؗΨ'Hޡ1w;|Z!G,g v}vb }IA(^iV[y(CoQYC'}VN6fZ FZm] ]-:գW iʼn){V8:):kgP7>z}5xF.SnEOX8\+ >A擜PI>t~`؇[kJmvhV{J_=P{@j<'F VQ/V4 Rt5CLx}gͬWfֵJLn0h@-{ lрȮ^X3 3}U?2`-*D i @IDAT| =D;]ğY*=2|[A| )%!Se+|g،A }UIcM7 ^"53v?LZ+XnPSQBxJO3-!{N4!q#j H` |%/&=_Wg E( (!:=]><`݄|FWLOUv]=qDz? >N:!o^{':]" l0|p[hk^gi@JGƣ Je19=#OM>:˰?u4d҂ Z+~G*=Ys}ݙʤ9?g9鷜Q)d G?.֭=P{@י:Nɩ]vA?..G?E;Og>w\ح?*ӯs?|~v7A~≴_ lqҾv>>k'lec/L 3:`1b8о6qv؟g?uޞJޡR5_ִY{@j=@bK?b`:kOvpOZq)>XiXomeԂ=JMLB:`:EtbȨin7bG7&P]OQe}]KG iUÂҐJIEl]$1y&gT(OF3py !OچUp_)S3U=e2\?%]Р8f&9^-9?mӑ7vj(P:5 ݡN*ȶA.ocK_hӄ|ce}lLEviuNvw٬w3zni$* pqfUW71d)0s7!J._Q[nsȆ㐫.j>5 ڰރ"]Z|ih`.sbۂ"yG* L Οxñ. KG+%]:m@M;E;Gj;11f>n6eGmvY<7=aMI "K\ S]8mSq R}=/;ʱ| 9>.Յ6v-~\>̡/eHJݪ} |-(ͨT-ɉ#W)(/eQi6XhRCGحN>ѥ4W1*CF5dH /W!%EॢX`b^V:cxDcbz}n1?G/.[R)׍IR 6P3U9J3X DAC iow9 .Bŏ!ȷ*|"d艾 &|% 22'Dz z*Mf8gr3R ]B9D}w&#bٟ1v@EǢظ-kW#x8<~.Y /ϒzk |vSH%W8}bcƴȥhq>-[YȀI8 tQn>U .6긖ԛI&ỶBzIY=t.#W 4G=EE9U-U-icǧTc޶.,^0U^+8򱤂}L6*s/P`<"@Ge|}4BЕZ޲.b;)~&7kvzD#r\]N%^=,r>hMG4c*gYQNZ UX ||cdV=P{u၏|HXE*=bGⷝvn:q8zM_ܯT}oO?}^!ʹ߮$'ɝݻ1o#ܟk}䓟4q~/Ew>֞9ڿOڭ:i`۰~XUkDj=P{e큘jZA^U.ݏo~}կ||Ay5v+FdčoN۪,̞mudBv Y/-Dt($FĻLjCÎ2Ф$ bh''%EVȭE&t+ikgzKq> ]٥ }K;<%8U|q^I*( $Eu$9A nD{`(WU+PT*H,)4wr=Gw!Bm+ 4@uD_Вm%P)\ t ҇O=:O6. uA舓9d) )V\V W !Β(ʜЯ|\NZk~k Fo(o#=U*Sc#{*GmG8D>E,p+B!^F-BUzUpЊ z2G@] m8A_w'*H /4lR}+Їbv.\-: am8Fؘ-ON zȣ}W]-t_)e/Gu` XWD/cNeXǺ}W a){'t~tBYjKкQ p *>Gfu44.? / %IR 3/ D2%  O7^s@h^Ac8{AA{]czGACҘ36>޼{]lS OvHPJi!w+]vo!o/ܻWBn]SVvPSHTNEaɃ=}-=M_z]- }ya XGy{$K^33鍾q;DocS)T R /mjC~9o s`> TPzu1vTKɯ'[js+}Y.iW* /"RE"]ONܨwz>R^V򻤴J2|[tK.^3gtbEUڹIќ=fz&-vm \G/Zآb!@EebTaXѶdZeMxZUŐv-&iS&5 WJ:JtvmwZٳIk^˵c[gi+VkSnmS1r1F]ڠQ&%lxttBCŮ =GBB9Po R)~:yK~>{ ?53u--:}+ I:׽\8ہQUULXWGC*V!; TFJ>uxWm@E// &DR@SB ̴!x* A !}EW AA ocMv'ʪWV)]Zcvl'G@QzsUdՋfߎiWf=K^j,Mo3OMA)UvyJ6Wnyn.d / `#vUʅJ3 _Bk|ȊrTҢ82.pu5Qa\VMEOV&ti;|{`^OҰ]ϟM Z,1ƃ[Q2E<}J=nߥEcZ,Xwg>𱘼mc6"m":| 892$*T, ĂSv\ @_~Պw;udC,l=͏(Ǥ2  d1 KRG|Bn0nq@*DFOo%l E7}?4VU?' MFx.o(FeиR67K\L<@f~fھ7z ~|7Gˁ/We4IdLUo{;p+cu҄u?.KOԍ=2=͔eoD{'DDz?m͛W=\)¹7M۪xA [nwSp>w{࡛%-o3=lFLVFUo4ݔ=G.V0(ǁ2jNc@'T~/$ЕqE5v*ikbreҠ۠|W|;>w՟Yז=8c ^,dH@0jWUg7g ')1I/T Zl:NO(q%u"ʴ.QY|e(gbxѫi*ȼS'lQgg.u{ăAy_ɃGRޞBR Ɯǎtp%]ى.N6&lJ\|yHfa3wGfmHт 2oSzv`/:]X{!xYtc}/qћ#c &w@W=nr:J˼Q|R}8!h3mwΘ}?(1Nq"_‘}e#G>њd]ܚ!,7ۚtwZ7XV=1d&9*_V]V7@j=P{@j=:u1 .vkmڦvd{Zک~->Tٳv_MU;O'la*V>jD1!M:B^VҤ+BⓉҸx ʶwQ6"mPv8j♋&(PQNlqL22=,MV*J"8py@|L<{L*Qک8X͕'کf]Vn_$,റ4l b XʦJj"ojc2;#,Y|(4R??؛۪c:X_8dxMDW2:'A,hs|1n-z!O~QvڝӧᇵABcPe%'a6ڦl8_/{;z߬p_ ]@GRdOO(Mfפ/0iKcb@{oNNzBxH|sexJ {\B `Qǡ']J/m#U1>SJE] "ϣNi'q .R9[+}\sv "\ 0Ӿ6WiOkte=y" MC~&a'fweV6LG<|7^YvL_=f(|BȅÓvbV'Z҇^3" wnnumw??AtsZiEhC~^T ܔm_0Z-G⥱cJsJC_2CRX7\h]C~eJeu2yj=P{@j=P{6zc55{EAs|s{ˮ۷{Uf}ڞcw‰- 7zu.4Mj He|%*gܮ]Ydaf'H6bFeJ=e[#Ԝ*]si D"*sd,AWheGy)CHTf7!>&z%C}L]vES- (JwlXS)awìG^ՄBWE+%`եv"7tAޞprְ :уm$fS $WGߢZ7 wFy d@ʅzq]\wPdY -%PyPU.WJ-ߎCOw]|f,| NvnJJ#.TI +/yІȓAKMϰ4d# z{N_ c(7M9|TCdêoJ'B,zÙyЩ[dimgvw [Аuh|O_PLh\CO*&QȸP_^ IBTiިl,䣭(W`;:}Q-I"AJfD'ԪϠ]UQ ֒Ucvag.ã|&b Peu2yj=P{@j=P{6;gfmV+c_UypjSg=gyD[ʊviF4ZxB]I\p:壎 ˀ rWiGWUdZEԼJ۹nMyowҚ\nh򫾓Ya3>\VRL,-)#&8(Ep}b' Xp[}эQb2IL)ХU+ͺ\M&90Vtx(:oWi0rEj'N\b-}Z1Ivq)/KtaWx8oˆzV7'gB&b.;ƟZs ;){U];bvEiHR.%N%Hu>xcw>q{i߬W#O/%)@,Wfs gj[2b PDfeޘ;xA~hJ~U)ښ],n/[`'ſ}QH%?鰩y;q$ r vv^(' E ;nJ?c뵸A*e;-o"vEL~oD^c o쳁%{qnwIO+nv%`W@_o!Wq?Hn۩M/ڗew!/)uM~um؜|U88)>qc͞hMO4hƕѸl'6exRmrFw]vMf'؅H`,O۲_14Jَ0Gz=t6; 6`V_só!$TI=tk!ѭ fH=8'acF"+qOdKυnӨ>pyLץKN5/:?>i#[[쳅q!1/N}J4UwPoMmȼ%.Ke]茴늃s4x[mCV\vPcېq/ߣCKEn_x@twGt~ K>Te}ﲥY- 9s-Ȉ-aN2A| 1¸my,=…m@lJ >.vvƣ'Y*D߆BG!~WW @YmmWQ*=γ=d(I ~+48ag݃:;3` "()Qaeٲ,kWVI۩֦JJJU*ÎmUލmY*eɲd=(-ʔ(S@<=9ϝ3 @m>}^}o}ouEVCmj -P[@mj -P[KfL]r+u ׍*TC7/|Clw195צ9։cR *zd"pl~Q0qEj<&Xۤp⬫ ,/[4\7wпY:dzxDOv-[< fbwǒbX &bmu2-zw 0-<ʜ." Lk2|QunKGohG a}Zvmrn]+g' ]u6}3`,ڧZ;Q{e;=c{wK>i%NS7hoxvicGk'n>h?z9U0p9/_﷑OmjC=6 ?Z%5-[,:`~=h_"UvCbumm˹%;7pO*}3IqWW/''?8`?rV[dge/54lBAD-"_#<{nnY'<뷿/=Y~{oڶM؊K];C}uW||iCvbY{l'էodth~lxW|xM|q{uŁHo rr[0~u>ٴ`~ ;$ጊK7f|Nڮ] ]Cvk xߓla;9/%ko!BO|Ou@~rީ>tkH~7^O|LmW|n8gO1_dž]9l{m!-y°aqYҩ}l>n0t,t2v a'wf6]Ì~E!tW0Nԑ>ct^Or>v TTZckMZj -P[@mj -P[@m˳@L1"ĄȈ9e]UALDl?=Vk'uN%#^pJ`X*L득ZL9pEcƒoօe;lΆNMK~в?wm=Ҳ cɬ`CgZzm{d˾TDUk%{[h#E]ELnYrJ;[vFb4Wb76OI.:w}V9|]Z {c ~Z|{aI,{^|/hI'*K_h %96cϵA?g:gvc+>; yoZdв3Wlx{ޭΡe[vZgt=VE:q?4gψCvpPN4`(w<ҴcZ ݠS ?̒=yDFݰFٻ]>P_~Ɛ/ژd_ɡW vY .vвP/2ucOs:B/F ߦWl|Ḣ| !V?-ܰq}Pإ 'ءob>?`+iP~uJ;+_KP`aSij֛apSJj> J\B'`O1>a/\ 9@C*)O}XYAQiwS:>~~VNl~_.|99Z~M!|Q&r\w`z庩 Ns}ɇ*2"e t8S~(qC  xU%\y Bb`S1| 9T ‡2B,~D;Lh;5@C;Y':] *8Q+|y`{vҶ-6 f# 'pa|,eS}-ht(Ώ۠~؅gpGoMC{zNpx;OhJfK|s1P}ƳĢ;NuSYxwu_Bmjѵj -P[@mj -P[@m/ T'3T V9j:!uŭ^e9ՅC53z1Yf12*ILh\(<E($AG x1R25Pu0ӄ&q0Rw1\LF{/m>k/ݿ8bw~{w8Z/5#Lp{_~kyCouWXN'X;QP]{7чC |vHsWU/5(z`]=Dr~ZW7Ă}op M0ܢ= #隰 ʟʙY(X'vvHѐ>2gOH1on}T'1:}hlqn|3l?<&{/{bǽ%{#oWT緼[3cia{[zl}vlE)=6wnrbuiYE 84,߆-y.3<)ҷ ژ%f3_<1hᇝ@?!{p!yIB8e9}OvHQS Z@0' -&) / M&ԜOuEYkkKm]:NOO[hfR|EFԧj\ۥO/hT >duw1cp8e6,2!r>9Ml/L!q. j~/1--ۿu\!t8IWH;dF V@*q @伎/iȣ@r=YpW'LWD 0rcyіoami%dZU2GI(wiߨ;Iu‰>SVp'}R  #J y+mNWGPbe AzR28nD ~jtд|цtBt-:5 N_Y5jտ -Q6RKj~ kP&o#ui#X'Se7tNo'~m<߉Oh6ۨ5xx)_^to:2:{)r9$ |u?|=%atKvO>Ⱦ}#j-p?dM|i_|] g3Gp e{994k ,%{Bǹ?#a 0z׼sn{Mh2 ]Kf"LLp v ng5I (Zrk6GfF19G%_O|CN˽rtu(!^lPm]//7ʆ[WMYߙG[}o !4.?ʗ!RaDI=hTad5pL|<ǾVY(5A:oc̽y~mN?+,cD^@IDATZp^?2++v֢}7M >ex @4(wYrRr٦p2l}tvh/[鎎Q 0uWxYNh?qAK{>| pR?o{ -~nZ$I1Hn @9 ͂1k+ 7r.XSbaF;wˉѱBUE#: w12]CThz3H7(cM!oK^Q6L|+RzTC(p2(sx\(W) wD¢ #maM'yO5-P[@mj -P[@m^6Unm%3S^T^Q][GyDt6Q*PCA'q;M8h>uM/P\h{B^tr+N e7OArV|\NMaP3S}57Y(Sl%bIb;eddLA qgEÜ;ɩ?hv7m]s_nMh_π1t!9oKvûu&e{东랜}tzvasqd1ŏWsHV,$<څ*D-*^sAdcS5kJfk`@?qn|/ P굤{BshN'W=~A/K ȏ ;Ë|@薲*p}m**!g>GC;4ԟǁurE:AfEmጎU)P (,˓v] IItbpQW,{v|IK[.VpvS Wj0_1P)D)),$u@!&+@b7=ώVڠ[mZrpw,hwjkT_^q.Sy~:9`S qJ ?l{A/+俇'.C ( #a6jU|ōhZ9~P yvm rc~ࢳtSo$YnDK>_Ex/ ?Mޮ\/8āҕ.w} UZq𨐯?9n EA^b0;4+ghH4Ǹ!ǚRLٝXAcnܡ,'p( 4Pd`=CWN{6bt\[O΂rb7X[W;+1黷I.ϩ |_"nz+A 3IݚGi=wx]lWO-MU:TtC-[rR{A!vZ'"i~ܽ.IN$W;`떜! f6N hxtžC{e*9跏}N~f?/c堍V^ӧW;/F;t4M\\a9";#`[7^T]t~"h.|"&0`?^k-oU}IEs(؈MSOMOyeRzk_>y tcr՗W^"$[rSY hRR /DY2@8(T8SRCNk9`,zYY8Ip!e73ZxnjSGB.oPO8=#4QZdP8Btaw6 *F#N]Qpapn1n##֚W{a['j__ PH,(쎼~C2R`)C-p(C[l\}CDw6 G4qZEiKqo\N|Nu+=vQ[5'?cڡ .˻MBLTRRB&n܁6q GJ6M( 'lG>t(meA'ATDO+JV l7(@NB\ӂmO}>&{﵃=ZG_.7s;ط}rYtj \S~eC/؟\S-P[@me&.#01i~282 ~eQR2IrU|8- .Jp(ydԁo,q.7\J(ֿ4/ )HM8+ME lV?}UdAQ92Ӵ9:b7~+!y+yhq5ߢD"gu*ǝ^wųl}zy*#ubnٷuknڥ/L,+r6AW{s{hw[wn!,O~?Qռ_ 9Z)e?UΒ϶QN/۸x9( `m4/q۬hr:0C:#֟)`awn1_# 6=E 9}D>^{;uR9 's"2^{k_c-{ ;FEd gw.Og5w8߄Cm]Ma9]cvMw` 6W%>&KE&Vl~렣%&RSLج=g:-y=+Vt )Sh)xsjSOY\N*H.%@q( 8e2s #,*u 9GtnS }a nq7F`Hd\{TMD#&748Ǣ0n_ +) 0"*x[(曬{G1_y;R>N^G$Mۯ;G4?X\V9y=ft:a~Ny9p!v{&Nl>9/>ک/g`'a7p|;Z0hxhq+wS$/=++ ?&'9-;[yb~H?Ylߟ!<ٴOt}Z1=(㨎WO' wR(+ "r~tonK;<`Ts{{?L/ <>a*CiZl喟VЯ5Ō}}wZ&ZKvDIֱ)r}VSσb AQͣc}SXϐݸ'X8^yBFWUis\Ob*d*HLB\=Wc*L6b8v\-Xih( *Wc󷎎_<WDi.r@0t?? (L&GӻcZU I3b07svv9[ԕ냾`(I إrAow .`^ zd/Gi]T911i}Y۹u]=O_ׂ2T^>%fĕvRLn8a7dwJa T (SAyC۳`[ vW߸TxUf8dՏWR:NnT~F:mغZj n,뀽K6xεm@?9҇hY=<#;.uj&9*ݮ]2u-P[@m6i&b4!E.; ~^IJp^R2QryA dd$b% ]Mb:wⱊrqjqge, z:N*TryM6}5tUYOJAW:I uOAd=mMLجd:ƾ dє=uLg`O:$ H"X _T 5='p5Ƃv?y6cd3]8 ~;b(Y"~ŃT{aOrBn+y8QZҕ%="^JC>(v `t] o=: cDG6`^oq wQƱStl O'D,i:-EIv7QĢcNn#wb)}y('&c<=H<3]\~JÅM39&=M8e#mE\+UAY}|C 앭Hƴ%̩LI9}-}4ŮdxTW8I$dlã$yn'BNґS!_.%{qHw [sNp)ڡo *?^v}INz0C: FJ#>{g;4*S4ncc7޷"gZF8KMKsՆJˣh0;zA&飌2ò~ŅF?B P ue֕-P[`| g#w-w҄RQ~ǟl8PT|߱z~[tb:kN_;.Sẵ9i9dO|vޟFuj -P[[ M̑&a>6Xv& U&IlT FygazWL"R"Dl1͒.#˓dN;C?z9,9&k e׾ d D=sONd9:֠&qANJ<\V(|1$R9uUigWwd=D%GPڳ*("A^q[xD;~iaYzL*r G򸂣CiUTz=`eX=18e ,v@xov7½~<՛ /@彲w/yQV2M/Lȹ+30补bXgGDdx<䡛9:k;5,:B~|KL5gB .6[6);|_IgاaCo;'K+ )jŹsS}&;\cօ^O Cg)J^{#:(-х`lqPAV^4yW (>fP2яi|wɧPyS3nxU!reB0꯼&vߣ(eϸv_Zת@mװtmv.zv|~D_8ְ ['m|~{.V;чȮ7e :nw-vƎt%?qʎh1w!}C;x\ܽ꘸8x/נN-p YνT!jUj -P[uaf N19X慕t[e5ڨ6фjq>hslmYwń_'P:Wcqkw`+v6h6qNy@FEyvrO&4XfBަcW&gyL~\WY VATroYeMUT! M<߲idPw`J,}^~8y}.:T .9)YbzVfYWАk{jchtDRB^S<]+:'=gQb&`SFA0Hiϲ^~1޴;-CiRw]ɯ"P8bE>#; 2Wo㱷rjӯy%Neb ZΠ5ICjkbjuǢlQߢ/Hf ^+>mtyYG <G>zW'͢[ѓlnx Q14$D`ī-+ʺ$ݣ?)!r KH46KwPwSϦvs҃Ӕw'B٧tNYFrݲ}sS<1.)+Yn \"]p®^EʊÙHx bb@;e7ȼrrsLŠbK(P1{'3}/MشX=۶(vPu 9l_QcUq6ޘ@o,`,@2 2^VAW@]&zc_$bYi^'9K|\#ӆ' 61 JMyB˘XZmCvPp//R!L.z-_6ԽLc7fcUvم+n6YYjnoU5?;b?f{&yy}/)`?{]oiߜOO|Rt>;K={aqmX蟩U -rẢ7>U랗N(qUV5z;~[YmQXG^|rVm2eWhp^ծվN-}6^ \tFeno#8kzu'O_)9 /_)`Jf WoTT91%N+Dտ]r^ 9Id99 c߂0֔Iż$ )*i^xkCIU/3Hq'ι~jޖ+Q JqǬpl5pa,Q9;#}cBo0S9 2 ?{R/&31 <> EW8Z_he?*ˑ2B!ڿ<`=}6ݱ޽oݵВ}SZ}D~pb>s}Tag#DO(}! A;e AŻmpSrVдc lӞnE^%9=r~xؔmZG#:#m#4_ήtpR;m`;B0B##^>Hjk#ّ7m-WM!9+.{vX-z*+\]gK& lA/ueScch$lrN&]Ҵ/vW'K4=>1a\;gu* 6qE6Կ6պr02 rϧr+[oCcvhrpą%;;lKw9EW vdEO߆znxNGYz~ssq\ڮQY#@iq1^;ffƨv;?5c:_eEA\9rE z(w|2НoU~|>y0N}01GNQt(XpC;8j'\ǔe!f"YA+8NS){tW<4nɔ0 HGT́z ߌu,Э_s }]tm0k z y Wr+*\e |Ud_y!m`)Uϝrzƾ=:bzLLط>j7;N*b</~-! G om7B\ze/DKBet }wL|[,Op?xuqU8DV 2zOvBVSY*(4 Dv++GD^^u|xUUU%)X!Gs8 kȋiuLp sd8Vݤx( vG/hB;0+dxedä. 31z2&c[iCzP6nG+4 eiّ6Jr@"EK-2gWrE9&QF? :Yr )M!Ѽi=,@w'L^3#mrl}}ڝ}nN=8W U%/нcOu< }-Mn rdnA9o˻ڣ~-غuMAz´-^ecک|Nw)c1%vK:4^c}/=U:WjR>]׍2ErJC >&<ԛ><61vAx1\ʒJCK ۲ܧٗMrmV-I(M=lDԮˢ=8^ ԯt*zԏ@Hq>YE]!I :`q˱?:.kɜNIQ9PbAN)6~5:vdxqVq5;râcjkdr2@{S-LJ]\j,MH;ְT{ |"`=Ȱmna&g!Yt$<)8ʕ,+E:6io m+WC~Zpzw!t+r]UٝGL'ρ_j/ڎAUbN*6 > 54۩o&.-f?:`7?PB,IE}G, y> E,T^1|ʣt׫T[ʍ ռ. h$„ 3ڍcmx@|HP,tChߺw;g厇TN9U]PqzFPZ 3Rxw Dԍ)x0Q~ÃX)YM0PwO}ou@BԻecY-霁;'CQYzC?JsjA}*,DQIqީ~]_`:-P[@mˋ7BU~98 ?Yw/ݶn߳{ݿy>#?}!7ް~ͭ_wj -P[@m^L IIsTkxe6u2]',;^`"'i]nb\R G0 B널  QW'* `ɡcbm88'O69nE[IAeEۧ TvP^9d:_ S(Xmrdb/2pItqՂu෵pw79BWW4Abrst 91CAIWp][$!k3c;Nц-q0ٯE rS svS gv9izẋ ;|y4U+h[fާ/#͝[2pa[LmWixnrn~hkzNL\v^NE'filM!'bٖp-qN"$r; 7ď1ǝ0^ RvZNZŽ},LYQf/WlxqÌ9n_-l'ՆuKc`=a._N'87?gggmB{Am^ |_G`z>~ɓrn;unߣgcIe٫F$ xBܦݷ[۪So.t;=/|FWF:{"pjLq5-phNt Sm;vNMƃ_ؒD'YZ2otE?9=e3sE_xѿqcNyW*!z:;,,ķ mQO#+{ݞxvZEk!ƘE 7*A=B\ӀELuTUޣ7/gC: dHG8Oc֊;/qa?1 !7ץ SKr(d>#F7krf֞j;lx۰5ic8 /P(|d.! Rq*}C?>ː!XiCx!b%&#f4|)]E JQd75Z+VR-P[ @:]:ߎ%,[ZnaR5".ǵK_7j?U[@mj -P[ॳRi*QM$iutpFyOGABsOq^M8FӠzAw'I_Ӗq%_IVuTĮ(v@_+D2⎊SRNώ`c*r-0=j4 UE|q4g*2i/W҉m:ISt;[tP":Bϰ3Yˮ{G;zqMӱ#WٍyQNv /~dwhMx9paw`sL?ÛDZi{nbҖ);91e'qqxXm_Ȗ$;+DBѷbl \n <Rg|G7޽qt bÂyeNTPmoS'1c1/ :Qᔜ?= -rW߆qZ?xE?J,ߣE"; iQBdjK_?>6>ܲ1e^A6Kl5 sqοegq2s?y@y3:FuM54eA1(%O/N b1 B2 u'(0d-j;]y=SZ/H+PwK# $nʺEe/$vē:?VL@ˊ\=$Z3s#E>;wF"UcFB _JGLTgl) z47g SQz4黟bLBxVf+56 Ϡ#h.CL}T>` U8 opbxBqރ|:`,;hQI:f:qECk_n|?Z8ڑX^ vy=BW@~X`<tw.;bQ/P (|î'2dO[!yjE{>0v<߄u-P[@m/f؃;uAܑ ;x{a-NGc=©yݦBO+zܼݷcSo>dMoOOguq;RlwMWmj -P[@mL\\TWKt>Xʸl.$!q 2 n<C&G5AU&#rPh^)>~>6%<)2$8kW[YҡJ@&HY$Q"GֈJ{H64 # =ARxkRsa FL>S%}3 <^f\ꑄT)ij; '\nC ]l[;(פ|e5 *,sOyKsԇ`ܟ-rf.앱mkx:>Z\E% 8/J]녝&S|+ $o7lnؘMoO3sZ2395_-%&2yOJ-J*Y+1թVilůGcܐMʏ(UK@siIrrErQi^9uZ`qAkQz9;2q {N=8kﱰcPCa -.]1-N`:]^^=z[NK܊:Eu*|s8qSWzezv粂rj"_];l|lΞ Wsh\ܽaW(R5VԮ|L48}3Z|5TΪ/۞ԸrA zvQ<[p˔*_ $B' USomDq8;sٝJv$8y2}G V.NhaּܷƷms{Q }c>'p?vv._g^:AϢs<׃ތcä,, Z=}UX N6)h8gYyשB]s6_Ieٵ*q ~&9:KA-P[@{'nLؿٿ;z ˿oA~=^?f큿(q=.=*~OAlGxHP[]ƑQ jUk -P[,$ݕ'E2YչD1͋i)VisꚸƉQGJ t Rz瓘y4yp~%T)S4Z {@J{B뮼yag/Зf.f9d _H'ϕNmx? -='i>}}f= "xEC R,ؔt0Jd[T 7t¯@a+!AqHG >}KL*P!# I_2RGT ~&3c9@eשWۃjl5)^X+ (z$\W"~WGM$U&*^|t-ݱW. xż8.XiѸiBOe"1%B1geiWlأ1Up=3ҁ-[j. _}^8k,C<7y-B~}'_P![찟!R30s ^kW*PuXEH,7~g-Cjȷ._8%ޠT0.ncЯu:mi ~#Z?,#r =s|h.; tuDU^-wB^Ze9kNm68Q66Qyc%}V:dRk 6TmӢe9JeJq]pLWrY].Qct[Rhi3N-Txs>(1> DI ܙ6eh Ⱦ6;BB7چ'ga^]|- 1}x]VYo`W 鈫Ph- P&'2sEc?+؟^CUª+lК]mj t}{Oؿc1]jۣ&8goG߷jY2}m<}.+~돟dV(ZPj -7kPZj -p5,fYDo(@ENeUv"'aG"`=)<ߨmVvLc2kI0l5>%bTy`60B %cG+nO*YX㴤L7vԺo1BG؟{ˤ)[uzu1OZ4"J8#bXL'iZ< U;Čȓ)t),^)T[{g!L!G );R^%98U|MN2EsY>Ilo.Ύ!9}~ߔf^/:/o-sr~ngp=8"TnbLamuߠxbVVC%Ka]IEPB96H@xO<1  Sq ?I + }o]M.R!dWJ] [IŻ%?RŸE5(#Pb9EC O[ȳ%Nj& TQ6MB36:/٘(NPsO%@'vkم6'e'?|Bot('Klid/s+r}DrHIbBt =s-: %":Դ>lr<t V\߂[6"sZgAchqSrTvtzAW]4mmNOׅzr s[םv#p5=aKNp<Е\jZK};xT6<'LO2> މ/<S2&''v!]| .(Xab)mĦ52NdN2ղvҵ<,rkP;_! ]W@m/[ =kC3J?V#KW} Lmj -P[nꓖsvcB, .0w* <g=jdN4Nl̍r&DHwh"'MjӫB:qӕD#Õõ(hw6QLn<ԕٽ5gY 'vYʝL~A,i_/I0 hO!\w,Ł'ms E\蓞89= Q~zi&qJ(9O(G j'>*r&Ω+x|`SN{u{g@2GSY_ +<_R8?qxR&PG.Ƿ|}|H/Ҽ`MS GES^.9_-80>nw|;scv-K8UuR؁a'!.,Qd5zx. ' cȸӻj9re쐏 9ei_6:&H/\)5]S^KРӖ :0MxE2,=;G}A䒜--4~yW~Igrh=/!~HvcO 0+CAv-MD:'ѻ Iz,0?vԃ'G2tHvKlX\=s69tdGD !NKfÎ뤆ʢM:2w"_hj]:״Y-XZф9wғ]}"U~N;Sl'ʉ]6 i =UdmtвD|󺒂uۈMbo!}O؆^c%] b,y/t|hћ.!чb ry܀< 1N@J[uOqQ켎vGb';#Ttp0u)@Tܩn*_*e)Ahl܎\J&ʑm`G3-9T;mjV.CZ9DW]Cr%VٜTIBz hZZ0:qa5%DSmCṪN6֤a3o zщg.?*)o<,\}B -ݯ402+n6.|@-1 &J} c(NW#\LJ2+OyGT漓> @?uAyQ^T={QGWNx9+KoW.7{-~$/ .i (o<}I #lXl: euyjywFck pE nW=h Ye;F,Yc&BemI2FҲ!E[$%"Hbo@wuW^yn{j @nfɳgd=zp^v_/ֳ{޺-mKM঒j^ɹfv_N7]1Lkg۷?o]HFg KOٹg7=y=rCq}M_̼wW (x3NtN G|tjzI!zRhYސYW#t⿆| Ekf^ CqMTݘj[@lvwGK1.nL #!n;cGg^ްzSP/m|<Ӊ)~Q K H _%-qJ->{vzQ ttFȉ])w`(yQvo )tHkcd-f'wU7g } D$ 94!O_)@wPO!Maf 1.}ힿU;\&E/ԔP$YeBUx9hY73-+Vl'x/Ưq%2?Cu;hB(g\pstbşM}Э)<.-wtŬY.QuhgRj v ;K^*L T=AH޳ 0n}zFOB_b/;l\wU]YJAx!W8M!#C{2< P:6s2L*Slv|-SEM@''FlذKS4̉ x%$\({c 3 ]b]s}?.?pDĢ :E ,QeOK\/?aNb9oOٟN)/ B1acZ0^x TfO'xғ1*$Ot@1 UL<^z2uxq1>xNDՎT߁q+)- ~٧2t5OҢ 7aw˸x()y<^lu:wVftg#|x)v쮯G3(GX}]܍QD:*/>k9D{C 17"ٰ( ub\y+ݲz駂؍Sw 3ѩE ЫPzƢp&r Z,}rԯԩ,Nي 2y_Y\ t`֝owx7 yvvm-Է"+8f7GVU^뾣{!lgŅu밞nxr&:~U` 9[m+SיGwH^|LTݚSʪIKJ AȎD]RWX>u3qnۆOXCCA#.2BUO4m *xehe~WA*?6%,dWy$&EtQxXsB%!G{uP2< AMj@߂&Š$7bRHKwCb2:L[ ,4j`$3L!qv^`Gcy; >peaJ%S~W_6ߡ_Q0.æ$j`HN5 x"X]ϔieS k/l.ŒX0mmi#|#]sz#hIh`パ1@ՏmW˒)烠(ǁg`ǻsʠ {؎ۀ]qSsv,.tʚT`J:ꀪ+<`Ԡ2lfz_ xw)xFx]=b;6}!L=E!]2^BJy,s?вwKo?I@bXXK}n'\n[yBBn|V6v@"4Ͷ`{yIpM_S}pbv(<~i%"vixTQ0P=Քƕ=mL(kU,#^H8UB?tSsu[(Q2:;n{ }7zVcQ0 vsƖ66+J@%b ܯuA 6~+؁ 9|$ZVhmI}309nYk.I>'7@+b,"'>6tŔɅRẫ}S.w_j|VD)a+j,ic݁ ,,f,2÷tM!э[E˶V9>E`Tx :qw[a S/`ȵ#oޏX[91`9z`])k藵-gūQƮgg>gWt)OQYf20PS7uxDyV2!"$TK[fYGF\>c^$U:f*?U:ʁ;[:|6GYvhaʴ-_W}ʐ"PQ`1G?_b j e Ol%!X_Jts+sj%ƀ!m* G6KlbsጢfMEМݩ_y(.p1MBBx8ry%8"B\UNL;Xm\^ӑB0 |aBϑ;Ϧ^&bBA;4i6%'\X Bj9^/#HƉtPcѪ}€v3y[GdfPe;x^.9\w&9mv6}){BA]o3?@P\xjH2 CvBJˎ3gǥR{woi(ֳ=`W'y\:!xl Lglnd H׿⁛n.ۓQS;F'ze}⥾9''3ACRGa6Gc@flyOI'ဖuijT2`'Ǥ ¯h LtI୲u5lD󓏪'%qrFGeFX=`!$`"Ju!۳dٴ@e]#џYp@'ytrn0hIeE[樁.26Pn$ūq~I,2>u)M4>ZL|~N5Q(Yflp2r|ex0ʡ*2-r}N )8 6Vꯂ -xsM9˱z Իcqe+gb٨>opZRg:~>JH^Kw-z JrJ>Jب:n BW1p'O19cTv7lvI]Kz#C84D'K 7oz/B'nN{ R9fB&Jo .>z>aza>S;6@j=P{@jxycjȝQlfWf跉:Fq.MR?m=zMJAGno oDh{Zf=w.#`'9h?Ot 6)Px@Wv}췵k4b7ۇ=h/[ Fͯ mٽϣǐǗbz־m)V+Plޱ94hcW mo1:;gOZ^g}6?c{7 XA?`Iުcğg|j~keBUBT7#>k_~vN=EfL~%"ɆI͔{FqRGxc#Dl ^2joϦ~d#ʇdi~J?ڰ{3zq{5jp@}H*_';/3IOɆM[̨=X+5Y/o~]HBxzx\BsX4@ /Pw?$!?,B7G*)Gcѡ- TȺt\xۉǀVj}Q_OC8lyx̐D&eo@W0te~|pBNc"6낷\><v W͒JSu &F}'lO/o>=KD9 Q.sen{€lSs>r suL9}ߟ,lbBey;m۷٘vi~@85#V~۪=?4'h Ȫ>dXzz:\pw.mD:j=P{@j=P{9{`jYEkRO*V43(y}N3Y/[:d'\/_vOW{*7J 6BY:o&IRISi&꘰#7&/ 1*?]beFGJцH^U!7I/;(WI+JK[\nnc8/n),zoޮzruOnѿ' Ҁy`T{? 6 Alc=_0O. %D w?}T[ebpӌ ?-M} vyX?wU xv/NZXh) }䡆U-Zhkv\8s:?}!{] N?H%]ˆW XJ]+?SAՏ=]:3vXònj\>hpJۦJ Rjk[@,Ѯkuc{|1;Wc$:O@75XVm\ `<:e#َvZ\o:`yZ=-hGu?0jOE7. YP,U?8n7]|ԣ:}N=a S,H3A4zH +t*65ݲ}5[WIr <]|A)@oe9 Du-+nqS-svL}W+ҏ'zv-8ܲ RoyۨMi'-ضovW{lJ>W%EJߩ >be޿<>,Jf>&Rj4,ݝx07Ǖ`yUGfsHx-QBܲD_qe*dj_ zNPhqgMe^r0E`|Qմv/|'e }0+(Qv\Rߒ.l_'~9sӖ}&+7`uEOVGO!\cf캽lZ 1Z|AEP`]uy.{)A8K9 X_g6,€^Ah5w$꛶|bJXlDA;w؜~w|!:qy^:')z^H Ϯ.-ePT۟kܟ1A7d#y%67ҘP[p 0Ψj=P{@j=P{@&^ʄx&C} ]ӰA [vwD ˡ5U ʕ"DD@Mtwmj2v0?4W͒:[J[u}1Ị´h.W E@zբiG)mO/'(A~3}=>OI>7d0 Ƿ f8'x"|E ßQ_/@tYFڤQdGKmSڂyr*^< #+C'>mv'ԇd|õin~u|zG>$ayNAկv=3 dfsMqo]{Ĭq½FWHw<$Q{vw ~B]_M ?%{ӏ{][>4n+vk!h6cw=g0/j|)F\a@Q]B^X>/ 5?>휵ot} >3.wtFMev(xߜ$EttJ] ˮ=:+6d~<`Ǿ:kkHۏ)I=:6S:ğF9 $Mj Gt4tҘ|,;ݶ?xӘТW^gyOW +w5Mw}+@z84n6rpxx=P{@j=P{@zM1ńz*ˁ/;~l] >#ѩ uHq:8rU,CiT;m|[̟Pp[R u|tٔf]A^B@D9Ö ЖѲ:d/JQ); Lpj`x^3^ʏ4u-Y.nvsOZQlH-]9"hʊ6LfO;̓E`6r>dQZNotҁ o}Kv{m ۭߒwcmnڳw ULG͟\g֎X2hy:q;D dӎurX|3m] p߿Ҳ3^ ~LWN U鐎w*{#(h]y3Dl33=?"MEy_ QtL}?+T[4_S ~BlϐO}3eWX|^`AZI kg7n֣:kw?%6dꉇ1!ߢN,pUu_A?j7~`Į廙AyĈ)i ~ȲuCv۫vvy0;}NjrLz8K7[`0"WqMYm U G (ǩx[<>۸ؕ* . ;Ɛ~G}~ yFxY@~KE'Xlm#|:'"9W|>sݲsQq ; 8c]n u<N8ee7o^wEGqc6O,}XDP9(So!3ȁ6R,R/>vyAM#ztPO1#>x_t}CE ۵}MHC8+5\Q NR]oG1l:cqJz.wGޛ%0Y>w6/?_RV5I =P{@j=P{@j\dõ:}D`]s¿#58G2 {ȃ o ;Mʧu1Fe]]s}V/~{znY;}o+O.aJDIIA}kH|lc QGi t|zSO?i6Fz+/;V|O,:?CןNA~Sfhq:X3|EZ8#LJ̫Rd$ _NIy%/d۬]Q1Ff]AWb#5R=[ɵySd _&LEǤf4[u"āq-8Ԭ/3|!1MEsAďW&k:0VH j@9(jO0it掕nN pU,R11蓯\ Q! 1hp܂ )8u [=߰bqщ6x>`jqªY}{A| ޫ CpoŀJ_ɬ*S8#Ýna[EݟićYh?TxsˆaYv,N59Ե _'j} ]3r%XRfG2p@ClB>zw m$]|CsSw<ו "A/sjif9'|qSH}"]o5cg@YrUEׁ ^N+t\ o/3lQ)lxn(^o__}O(b>dIAgMo[vQ{evlKK u0xٿ.5[yꟵ wBEytɳ 5V^: s! yz6$X۸%ۻ t_><`w#eRPG-{i7w`nWtdh2!7YzB .lBaM9ZanWRLitW>qnbU\`[%zz%LsyA-=GY tdU>0A'(7 |c-V(x߯ Ҷ$(IHP;^KPPVKvݏq}N|lZ.2Fhij @WPO+6:F$64h#c dS@IDAT0~7f "U셦}W[z.ސoef)޻y\!h'#[ݩ'h=Lw,lX틊xq/'~U $- yNtӘǯ [:~t;ܴ U4hĠ҂(Y}B{<(Z~Va_;ÆrU'&sZC^F Sm; ʉR~QoHRK'FhL~Y`.Kgаr@t˶@`W 39,F^ʒ0l2SE:nM+Ak[-(wCgh+}uvȂwYVʕ#D~͌K&>7ײywO#hi=0 Z+?A z4AtSBi(^3JX(X0)ȡE[ç\ŬSZ12 2|}Iޟj#NջR h=9/hbs\n/)eMPeH3b:|t&/>ܿe|zXY9|%)pOf/ Y ^݊>|JKԡəwj[uf»n11`eߞmA&4%n)^ԭ![H y^%9'6bvmoykssnpC7&ݴ5|2a6eU [){3]^3ơWlثE~۾Npg%_p.VX^~vrB3Sڍmyxwo[ |==yv׻\uۤSEh7jP>UƭtChc13u+e<6l*KT}ЫQ0NA@(r8c{69cpt>ks5tGt5?SFT1J];Ѩ]:CoTzaGzu44ML9v=p"@&ښwM\WuI*{hy4Q/\)bSC  b. *d l}`Ѳ& 04hWPBWuJCy*gDTrf*{hUv wqK(c껤vHϨxp0ޯ0Kv6)ZڹTqp!ae6yzG{vw~`_ꏶCq{Ǯ%;䵫4dZRP=/q wsJz(]'i5o?жkN}S~J7}ўR|o„R`=a}6:/?lWQ|װ7>B}}π],a᳠>̍C7QkE~\o{yP}g+_|>~m8b<БZv){~Z1& hQԛFlv͞=cmߘګFO5xm]vPu_%LmT5Ec+펟Z7hAV~U K=%I>"7|'+-V>:`?#vbbP@|` O<Զv޹S+:" a\̻AH]5[$&Lzj~L֕AFSz.P@b TAX U jJ 𜽚E2ȵ-`gg12fc#^{fNɂ^gW.pzA{^xО+d"{~ $\ ;8Y. \o ɗE>MMs'H:txxT`|I&$:MSc=9uڮ9+2l oKe(\R\a$[M1`e!]awAn2c@Ƴ&}f1ܰ3R4 |X+?YG:Bx1Svp=>aZqL;O5Z(Atʶs2ǯhA_<8wt5**#ƃOX,v@<,ȏE5V/}Ȕ;T^:^su%z197 :篥Тb̈S~[]f=P{~[#MP7f?p/<q{&<~C w5^Gi?uX%^s>c Tj=P{<߶u2 M%a_{ؖkگs^*?щ3][NWEo8h0MfD`&R64qN p[G():,8EgAJ"EBBYno*L痙 dwADpC&x5L]Mi*DJWEw)s\/vt/Wug'yDGpwI&4DN%#9iaXǓU/p1K9}=ʼn ۄi|܃@'tQƎgbNRp]+-5R}|?Q}M ۗӏ5OA.PP`55CO}eҥݣ_sۀ;4lZ3iy^T4w= ]<~ZLЧ >hOxϷ-cZmM8R`cNvvJA`lPj t7!P<-h%ۤ&ӷ eJ8?Ԟp( PB琓 a3/CbTCA'9 Co_TKy!7rx> ö_" znFi7ݴ|ɫZKm&l;$ϳlU鰢}w+Ns'OYgp] ~at(He#ƕ/np$dyVt_z-{@~r{Tۮ޽nbyqσGu:xZoN97M]:{;;8Օj=px`ͼ3U$(gIJ=ȫJ-VRN M3h?ц/v~sŮ5&?[u+w'yI{M`ׄDuPj@ zѷ tWېv5Mߵ&WJ^(xm + -N`Ա#/{`zx57 G@&%sH|vyO_GkQ7[ޓ= [_56)c u-*M-۟Zm+GLp[oOiGbWJ6"t3GP?R!=Ljs’J >-k:n;vfoғ)~VA1ZhZS$zlK |[[eT߆Tq^NW@xJ?fy۷aϵ# xPs{~w‡4{b\%?]9`lDyS> tdAg<ߞBNۓ )CvHi'~/Y}Bo]?;_B2ӧ~>X,g_x^# w&'퓟[˯qŝ#:Pb3s>nSs*'[7n",͙Pw^JBU02tE?*]kڅ켄W&yޯFb|Zȣ<[cnn1`/` (䗒KM = C <ǯj-RadC8_*t 8(O\ޘ|Ӝ#;qQ5}'Nbbmְzi>[ߎ2uˣ-L;84ʾī~sU{Bw7/hO\+ҷ!9 $dm'Awф3H襹g۸6u}},oE+'{NWUJ¹l(^nN K> |n7#O<ԩ@j\p\wv:F}s}]twr̚/0nJ  ɟeҫ}{V7?b_\sn{蠶{ߎ~ރ=pv!P/_>E@?J]gؚ@^`.ODmy& ,'ENLE#:۪⨉*|fKf/ LEZxi=PdMb bK3oJonsn̿,ڤFΏV3t-J$}=mM SB!{u4. o>&w )#^mĚ2]-5XF :zۆArE] jߝfI>EM[Fka& +'>AؑwÂM ,=B.R-sn/&lO{4ҽ.:! ["d@(w:z% @":O?ŜJhN3pN~YN>9z6㮡_T1sjmRMS>p;oGKcmE|v_lIE/cvJE1].]iף HgaXRe;\׽G 5ʎǤ'*Z>1$NX;+1"R;,U[,1>WZtw.g pL Dn0D@S >j^?e@opgKJ%>JѲAu0s1#tTRz5ei EQ|G{Yz)Kh=OZ,D n-h1pC"V:]z<.GGU= Ej̉SW| ^,r=aRTl;E:hW[ixfXYh ]-o]e3+Ƒ>T_W%`z8zmq~tB[K\ޑ W'D=xI<c7 cA[%qLL qٹ/=d͔>e*ᤱ: _ERF,(G'%r/"lWvEx-;6@|ىY}l>x3H?>WGcŽ=t~fu~\vC?;~Uȷ.޻{~ᗿd_^K?wѭӧ_yJ>qwMv dk3___Ww뻟:~K,Iͧ/V@sSs=P{@/m٨M*<+PBUF%~Q2?Z' _?cڇZh˚Xx`^ +?&D;נ"HjmC#C}h&CkH 9{C;pCAyc&'q&ZBbCOX\:L;Q0âm5wL`Q]8-F,-rQw;\ O)Ίtc.Z`po+%\"}$G϶8vB'|>KTn9"^ |ø|p%TIw!Šs**Bձ2j7afn˱T%|rϔAK !a|$AE n`fm'2H~Z0"NN+p+( 8!㾬)!$F M)!m_J%>q $vvs+ԉ4>^C`C>sܯ8)>)DE=n~O̬m1h{&'Y >kQy芔R>œd'd:ʶT.)ae>a.8SIzJ-l1J\n ϩ>q8h'ԟ&lB'Ì)[@/l(g\oQ"U=WLm\}s>J}IG79 *%/.@[gj=P{㏟;vUxk} WE]oW^Nן{]ݫ{{uBH}GtD3sv1vi7N{Ɔ.]?C_mi1}Nxw8{@ Œ})tL:췟O|~CT~<{̾>i7 T{(uY,;j}=P{@bNƄFz  :eyê(ڃݲ& HVS} V wM5;A\YDӓ_s=Y_[:1snkx# aŤ2qR阭4g"H>H5 L`g}SmUF*zj:;%rTmMvL|//(1%|ֿ8ۃ-k(2ڐJ}X;ZaL|l~ac e}cm IL@@:U]8,`70Z rN FM :A->SeQbHoNhiAZJ}նNHGXHVd~2 ;&?) "Ruݫ ?KZ>pԲLSOrW(.IΡi"O-aûvCtSؕ%^V$xU Y1)":5'|Oo|2 zGP`! ,|G9Ш }蝗aaѐf7F1IZ(jtǗx~~0둂(⋜ܮ;*`~԰?I.=8{t(!z͝q-96l'cR 6IH=tr>L+;N_;ɟ^fXtV/s qXy$`TcܢT=:gLؾEfEK#|Ĉz|#q=+aITzgT'ܡjXcLK:u66@^RM&ܲǮ)½ۯ?ګ [ܯE{G[)~޲sޫ(M:ݪyd6j*{0m?_^S0ۄ`ǎ>i㙮j8u>^ 9vN虭Sj<,RRe <v2?aSWl{Uo7|Za̓bRɸKe)8$4=\:h> XA@^ħR7=ЪM 1ŒuE[A*h* :95G#sv |؃ jj!7g^쐃~+6Mn]ڈvh~QWdڱ Q_;1:'=Rv8L;o}v+K 8{{N]M{R$ RaID Nʕ'DD~U@pک6" zOmn7BY)m&GF]A͖mSpǶI[S3l7Ft CÞiS;Zvw(wb® #=/X{^cѭHA_?Ηw>+GW첽%sM{ϗ$&E1r\Ӯf&s#6)pD:Pdq?)r1pR2 y:a %ZA x 3 |ʁ0Y{FT’L6R*r_I0h"X@b`W4lcޓ|bN>y٩EMҟ't>SDaB&8p+pB#;\ŧTڔ agta9~":K skvxM٨xC RDWl^o<3=kMۥpNT3ZE3\ޚƽP/|v"5{Cp9%W-w 6;;Me~?XY/=P{@큗>~i}ٛvfywlO17bWޠzNG'_xh=[oxÏ*Փv٣*ܰ;0i?>C=o׾>y{ֱUե~g5qsSj=P{%U2&{;fa5y-)ȭ9\VӖ-n͌bg:y_Ӿ \Yho{x0Ы,]ќvk~`krF &8J1i? .g)':'< }3wsu'0|t j0VK͌ϪDLn X,:HZg9c-d{/LI>MҶ5 RqQIF#&ϟW@@vߒR^8KQav߶Zw5}Q7';EM\˞PfIM?"Y`n , ' }'&Qڙg/~qsGE(oWQ:qEG׉ϞBzeZ t>]xɆEtxZ5{gۯ\ۮ߽n/Nj\hb`}yjt=@pF20Wsԗ'RN 'U.s~J J|WW6l~{7݊} "Ds91L0-lQ6Bhi WcM.1d9A|>z쀇Q(*ؙ(J=![A]s gy*h]] +H?eߔ|X6p| /hB&OA7! pwN8u&Oߌvۢv+ж5+|kH)wbמ?P!w 7NaEb"`TIwL RԇTL;6jf]7ON ofa;qұg)iig@+ſOGl6{vkAsSvOeˋ]"Yٖڥo1 j#P{Z;#v4= Nk*Qw!~n TXYS'm&/ZMb?οz% $SP4nb j ~ۮޯ3 ~'h8# Y^*9qQ)v v*; V0}Z #IlJ:҅{\i-jpRD.^7tFFxrT'PŮSI"jVtL :J]Zx#,ⴃcCGBT.!SR-EґG~=c#vjnZRdՐ|=:/^[%wwVV\2lᯉM|D-1r-OuGNر_vw5Gz>Č\o|RPGgg^.Ȕ{:,Wp~Oo7~I+}_wCs)N/sXEP3MY;yo5ZcT$_ Gi6m 瀺Q-m/F<ϵ'4ΕyԻyPVoeloO`Uo g[5}2vѾQA.Ⱕ.uVZuRΖ`Q'9źu+MCRopbb~v ^VHg3IJ-*>e{̂7 sF<}9@ux~V M}|vO YE"Ƣx/iUri!8L41) j } ЎcZl_Ѯ60&c+&Froum"­Уms^s[iД9Q{;3ڐ.!Ӽ|39eh#s}%vㆬT= :zՠL3c e K 8~vMҠ+{Z\kuxkǷێ]# l zQ?-S0t=CvD5Ӳc-((e (xC()&=&GzHpT$ɳ])'^ZNvDYпYޯՉ34:0h7 x1_;'wڵ;ɡN܉h"Gw_ !9_ Z0oorЮ)3(i<5E In`[Q@!hZڍxnƮo^PlNm|}P|@}t;Dg}b@̊}u^m#֑}5o_:jZ8p4JﺉxǦ.Gbs . sqV.W<#>Z/F2` prʼnŦ> _]"1-:0Ё:6_G4Vx@m{SZ4p\fLy=-SlSO+NAO ݵ%-4!3-NuNPhU1:exEW0h<.ePiN~~ Iԧ? Z@gP`. =|1rWC9bRijK'GGbr~D6{L}'Ɓ%u|%Ʒ@L6mRi1x}5[(ܜ CTE7?I^ ޳Ш &QG?g,7Н2$},zd񗓳ScfLl3"U>d:Jp˲!p4w$>9=E;}})n^/<^(%r5Ѯ)VFCf J7?IGc1)JT' -kZD|~Rѹ/x"2a7l@/Ǖ]7ԁsLȷ{? w/nϟԢ)rوge%s~Y4&Y.bǢxsޛY\u-d^eeTM HEiԌhah>|36c6MІ2uIBv$ (ժ-rXo~⽈UYQ3ug~~}#'4.7k5SqpG l8pF;cڍIݱcƣE~Yf;|zMis,='@iJ \y ~ճṓ±wf%ٗ8hwyg?>cf9vwN6T^ ?}ǝ:jf׏g~]7d=|ŕ[hģs/Hÿۧsw~Z3w`h\X^3y&_ȓ6%h ?5=qi1&FK:[N5F r^,J 5;&Zכ>&<0cs? 99 w"nUX8Q~@Ty-LvwvOef( CcŦ;:Ҙ "01:+N8  c \h@lN=APc0 aA*J8)C&k Dhj&k{]qE;OXSTW޽:J~vj_?;#'ᔜ+pZ;wީ59 ?/GCM0=wh}{g rb{. (Wyqrx]8vqTQ!rRc#: @#:L&zC@<8Z:?pd3$gol;xTZphkavܿ-pF곝J8 r$GU:|0q2葳K1=wec)&qjMݤv|' Lm(IwU=;]]pF]_-9{DZR!-#T

    ^]{PG"yTڜU4qÝThQFiv OWxsʦ#uRQUt`qJw<,NF<6P+v>B󷾌ݍ£SY9vh(8:zT~y&;]je;w̓vu1ec홒- f|1}8VI -<}wƢVӉ szvhlaA zlPlu@a ]c5 춏QNkN9rܼ|Y?K6*ˇi S_%Ez{0k>υgkZ h{?gEPe$?w*ຒ/7e-U԰.^(s/彂U,A#QJ (-PZvNmt 9s?|x;kτk`1@ g gχ٩op ~g˸@imJ7>77>weJ \ C| د>2ORJ ئ~hXW8VECg S! ]@IDAT_]# [o O~mpq+s8 =A]r{e͢C=^pZ`\K?AFEӔfg&/ɍ>a@n1P ( !N]o|90@OE">xS,8m(UlZ 2u[pv5âO PalM6Q|dP xqzEt^"X>`&'ş{Jbb6n~J 3p]Д/YA ײyS@  xE1@<-V=~l3bď5R ^Jo})p$<`& [\6P|꠭]kZ?IM`C",ĮY9NpXsfr6p&#?4ʉ4 s|)'\!ioGo)x챑[_ 0yH \/xlg s(t_y5`n08D{A'HI—>@6~r`,SHAFfcD.v&F_<e'gyp%? V!cbNYYYXԟz_4arnqL6p6G<Ёlz@g0]MJv_4zVgݔ ٟp=ln,WZ@i_ ?pZM^..|( S+<|[?o菘m!}*gyɧ2| ˇLo~͆>yG_Jw$|CL>n؆ e@in?|,Y 7_v%WiF`}4^?دl#K \c^1 3b#p4D eB r:y\;_h.x2/ߵ9n8tv,iL9ej^SO5Mu3kZi"\ N(;++b2|w8pDTiڪoSg![M 1:Y&k}_裎M9'r4I3Nr^ 3J.z1#v[ǵpZy;8sZ2v7 'b1a~)1in "(cW>bqNK2țC+GpzҍϮPW& R :ZXmv'~tBi{GN8Q#; \::PNIV:&*/O9KNFͧ.Ȃ̃hp(MJj|h Qmݐ#;[M;M6)kÁ#'9p(Gl%b$91" nPgR:$F?LFذ#𘘽c6 LR͖F(drU@2qQ(K/9  7.\(,G3*TfNgQ.;KCi7 DCˢ0WSd=ϳMƦI}K{}gY^~$5cѢmYʛAJ.T8SwJ=)UHzTY%x9ˉ%1ʄcGyA"G~H+/YeRL4k:BQ:t]n{zZ nCt:6N]'yl;!PoyxH04p r+y'@zbA'Ghq[j[_ nNZSZرwhwI'_z h{K=r]\VL|xSC"o1SnB=MX8-;KeK (-PZ*[gO7y2|M.^O[TcDT٩cJpinrߥ۲?8HCX[^+v"L [0o ]5dC8cEWG=zgZb ݫ /ڊ4Xb<3>yfEO;C~\VBc}tg('X .q;yƈEtt>Dft"@O`uV$;q:[z+ /D>6g2-K}j W{%_۽eJ (-PZ@iJ (-p-j܇~m +Gzn2]Z`[[ܯE}\MA÷eqĹmr to_=*6P8tznb&vg*7P1„&#h̶ `tcZoF$g@2׍OJ3SI۴jLEA&GmqZx^N8-}vM M?@?Ag!:^̦)z*ؗr@`6k ERbTjw^E=ùݔ)C]2qʗ=5۟V{vS7k#㢾9(j[e9b?wDbR?.PVT2C`N/e[vޣ=yk:"KzQ"Pw5,Ԕs:hdU+0BmrzmjcP68q)Ȣ,b³al <8):HvB7H-$taKYZlPЊd+bʩARp̝ 89D%S1IObqA OX 3e%1DGYcx8Ŏ?$f@[B JI0L[X0ժEE3SƟe,1[!xԝ_`&Ypb`@&ZVf;)>sZJU_w"p)Ӆ3Z 2ޜ>jBW q?ck:[ݕV-( pfxX΃0.˰vWM,c2Iɂ?=s*c[" 3gCsnF̅=X7icS tޯx+A/ekn2ރ=eJ (-PZ@iJ XcR?-(U0N J l? o T5?Gd3D%ȲYKQ1p4(;G(w?8y7_;]o:^| ~"-Շ`zEsnfdk᳢ITk4EFy+e$҆pJb)mX?a_: 32$8}]a)BRAƠH1ILzk"h#b}X>zvMZ5)g>R3VVm Ms2ĻbTM[)مmW).nPQU69'd77 68}Y QpY uWjvݷu*`B(3tC 6ҧuUվ%k}YvY±Ax"E]?_;wGl(N嬜jU,U8G? O w7­_ΐ^z[v47u#o,(j]דp~cCЅO`Þa^:93$$GQ7݊|LзbH tCk+ zE8:)l 2wZ$YՃr#ۄć,uR߸pŊv^V(磏ɈI8.޴+bn=!960TO jsy(n>sQbsz-hraDbu/`WڔdsBX5ص3Tfub~|zw<=^ErﱑP]CErq-ެ)O.0EW64Mپ>u/u.-PZ@iJ (-PZeזG78j#^ȞwB6W5[Nld\d %SdL+?0j| 9 E'C\!.is(cvjzԂZ @0qV4#q46߁gI @b,rÎ"GXx/@9IlIDbW(LJ| ^ M.([GFQL^\7#-:֌vkZ% S)xr>&]_V/`\⍍Ƕ'-L?WR0hB؞ẗ́ k\N_)ϱ|:= x;"_ȁni¿ 'Ttcw<ξW9I8 T: j &OLp*t:+r$߾u"q+kf4?( .R`%E Jd8e`*m<|k%p9T'xTaW= >V K7rqĦnӑ qϩLk74˒ס ZWdQݤGg=(V~G/&Q#E&X֌+9pn'1n.{" (~LGC4ٺ\}èAà F=WqN !_A_GPcQoPGF  /c2`&s<3h !}Z{Zl"8c@C}nGf 0hu/\-Ά8]ii]-u|eFc^geީj}otk6sBb?؁ mIҼ8/,輆h :]:Wgt!=<^%@]-%vplݨ7kNb C;$'5(S\yC.N&kY!x^#E9 a0=&w1Ҋt Oサ',IҺ\7_X^^ ilD-b19X#Ǣvto.WZ@iJ (-PZU@?<Ź: ,ie@i8m}Jqa+F _mQ;u=O39ۘ4$]EVAlm.%ʖkdz!i\p,ó '9ߞ&wu—|.*b@#1Ye< !uT`p1.k>8[dG|AaIYl3Y*Vɝ"XAhb|^ z=‰?+HCk^+NXlfmJxaY6$a\}8q(,䙃\a vǭ"X)nr3j -\_B'kr-NE*D%4`go[ڋvM}^0%3O^k99vȳ>.% *4|bfHd<>)ЅPчddX3sS(wNѿ "1'^=Rǐnt?[YHf#epᤃcR}-^5ٺ.ٓ?߯^Ќ./Jx4ͻ/5XA>e()6EH`I6R@|\ ;tXw(\T K>ponR; @+>))\kƼ;sPQ(t>|\9#.Z0rٌ&F\'hP{t ,2#Q]:i/n.N[spqrU*l_EFUT#HA{1aGmM1qxl^z^?'hwZ&`pYD/'e*.s^8}5a9t@N'3>k:Nؿ?)}&}~Ngft ŶbvN.5lֳom~6mھlgOіN=. JA*%~]61 Vh.dq1 rd|5k_Ӷq9n)s`kmnWڞ.gŏbτ/n4?eվd;O_1gc#;lt?wذaZp~ a^WR0oϏ^3\~{0hf3Ao,& ]>#ZeeDmڟv/ 1R(;囥GɅRq!|/wz*~dY3J/1'E˥swVa+6e2KWi#d;>LC @2 'Q߁9Exlosc_i]gu귖_!>a&;%H|:;Sw¤(;; /d׍AcHS{MV;Ruɍj;`wβެvR"bEc*q & xI/}$<@Jj"m>=P2RYK`̥p9ww3 Ld&|'6â8%## bG @#)ߣ%9K{EÝ3av۟S9vϨT²x,LiGin z٪e|t@p)- GҤ&jОz\䩓l  }ɰd7,Bbզ;9ƵZZׇo^z# =X|kZ`y%oYNɸ.9&o-A+/VFR*]nfg;Uqr,?/ˮ-MB+lJJ{[1ДQL>V=jpvxImPOuH5Z #T/XK Q9Ɯ e绸zƹqݝڇ/9Ov:)!όڀzʷ`[ly,>= ]L1nYVP+^%PPh =aw ^S0y9h%:VWOw±Vzve_gX;ABix^t~`&')a||9#M!d O@!qnarX 0Nð4"< MyqS@O1N4N2FCߔ 5b0 s@Kf œQTB'D[plp|2i,fg3Gs9$GL&c*-q2|Cg2@lT XoVG:JRԚ1,`|srwp&7&q{s@Nw~p̬ 4C{y1[aR3s;BUGӞWY94Qqr ԦHu$P>/gv'ρM;b769Wӳ?Ą4w{&\CJd?8ϵ]΄;~a"Oj]X;|rmؙnͦ.;Go߫o,G4>Wʣk?^ $_ ~ N!}^53vIsvMzc%'?yv ÿ wAylo.NvWGk't%*lE×F p56T®oxOΆƒ]:>)]r]!f3Ń:@uFxsrMM3] <䄡=wáiTq\vfzYziOJv:q'¾dpf_ۻ^!&-NsCT'פּc&s&-1M;Oe2igIj!Qs}YN!7Ռ /ũ6dXE> f?@2"W`]"ݰ(VCTVI%#t[#Jfdz'5h5r!"&y(e!b0x6.6[] /r}#1Y5jhʼnO8pyG} ʨ UNl$EC:]wNΩYG  ީtN!q1֦:SMl?a1򷻝益9m.۬A(-PZ@iJ (-p-`?*(UR^Vf**~FEǏ` OQJ .`<(xd{mwϮ+Z`:Q']7W?*Y 2rT&s67h| &JÓݷq7NuI{RK^BON=bL”\Tkʎ cl2;GqժE= |gKث=wN  }%ƼvkZGr"BKGϷV$g~Y`=oگۜ-~Ld뤉"`R<5oE;kv7 ^9O'coi2XܛNQ O? 7-'Nvuk N=Q _zp-V-`owYAፏ,o+`^6;N腝șw*ᣟ>>wDX|N amSa@51NQA6 W8A2GZUqDĔkzSF/ cZWa.LR Q%t> lh#GGz\>Z۳(Gڪv$:,rRɕC+Wќ7=+ U>k@{ 8x xL|(p}Ss m- ).+Foe^ ^K L)9HY:txࣆ]S&ǜ8x 5tmigԉrGt‰źar|hLpEyȕnb?pJ:_*IZfÐ'LJE5e@B2Ѧ5˱8rҁ[_iJ (-PZ@iW?6}VC2S~2ݒ8a"`$R2.-PZgo,{a>f>Sy Gc8*f119PB?ǎXv8b'q-G>OhHsskuM@N\5Q\(Jc4$2H0(QuW,4Q\oRW=(鿤|Í +01I6@< xy!.;5[ꬆcd׻p~\m'9\;/#-igcxbޕFʥ jWB?v~]wٵV7(=Οbp|^JxFMrձj7hA}_^ xN?Va ߼sdqK%Ԓ86pf Y UMUmMp ?Nt,?6^''ocZ'ghG_MwO<:ӠW ُ}:Wgko;Oi8'ƽ x]>XpS@v@S_[i)&my[c[֦Ule ~p5$5Oj"gv(ǹS:>zJt|59yk׸YcmLlv+q^ro'{~fGCĀU7,kLE#^0|s%|OL􉅟Z瘎N\ X)=26M'YQXkE#7ڄux*}HQX8bޛgv"1)`R.@)1靣?løtoF-TZ@iJ (-PZմ~HsS`L=sŴ ڷCÿ`],CL XL2(-PZ Y`@+\˰3E 4:v6y<…ւyqX0&4r|8c13]KzPb}YMX`µ+)4Ǡa劸Bõ^&}TW>-} H ]qz8?H鵖&e{G>hjMք^}I m}޾`|B_T92m_1IsF[SVeRʞ󯩄ﺗѲɇ 87ׄ'Gyb}jq*gW5GIL^<{';N8p7G8ݘ³rNoOO ˒{SλkaN[?ڡ}0s,* \#Vxfa!9__N)tX=;iO!lpCzQ}O^NكpXۍjJm)[qzSdN0V .o,؄dtyNO):x^ c|}2A<i#iHжR'Og?ʮx~ 0~ A|h_ ?.{=x{SS=qX|'h _nدaXH6 ZҩX:Y}VAUaAaSԴ@_. q ?AI91$Cr)+RE<:74fm;׀V(xdI!6\d 4V^<}Y_ dX'F uV.;̱+|[YÐtaCyz3:ŕwn.4۝;,hQ9!cgS1)X9Yq,^%&dx:,8q\Ŷt77o1tacO킳]״  P੐1̌P/&^öni94R.3{<^oF~#4iF_27ɅRSf4ĉK(`Jl%]ִwBu+n@iJ (-PZ@i.h~ $١~N״&hi8VctE&-zC3G.?PZz=dus8N7;</oмYmٺ"M2M˜Tj!`09׈vm>^,` @&p(U3ZMmM۷Km͔ޖDO牙g:Iy;Nܕ9܈bt@&P劓1 LZk[չur}(Aap(pb*vNW sKa#cOcl  ӎt86d ·;:j}g3t {봳^ ZwHJ~ AOX~bm{vqI^ .N# WB{eny @I!*˜@9À/`: cFY"v'K{g`/U-WX u)l R&y_,Љ>2%/)9:U}:Z䱆l\[K;iBrx'lbəŲҲsO/ݰ C nW_iJ (-PZ@i|.~/P $DS\5kVy& ֗w9A跉?~2)`?PeTZٳ-9ROi![Q;F\ #g%w&~[}מ!:F #ʦ^] {#'ߒY0y >-~f8X ;Q>#Eאu d;MUha"|pVk×8w|[gNRX}VCY>&]p~;~ ۍ⃟ԱwFm࿰&+y>h׆d=YccCNS`4bu"<0Ոx˫c_N@ZQG"?!Ui ;YN V~7 d5y 4ևeMw9WL3|?@A1G";xSQ]54=lu`|`BA,8}쒭 K@IDATI !E0ju5=}:N:O] 91c)JZ dCa bi2xVZTK=Tmw)ܠ9-8;:A@eBsLh" )|7HP6/kuMϙ ..j:1€}NPQ4%Jg7W^#lˁ< 9XgiM^E~ 7ݠN˃8 Zt~7^`mlqA`|cT(PK¥MX/ϔr+$F0Хh.-et_՘ܕ [SGqN!;lX'M cV#Kl~]\@f19ybA!{RJ (-PZ@iJ lI~KIMVkB.ib]8ܬfI2i|)MߒQiWz~ǙGȧz`jߕ+hb2<Qc*(gGD68i? s$H><,D$n\8oMwqt2Nh'.(t[_%&]!W^8I)g!L(/'U~],>#=+}vIk+lQxΊkWNeMf˭̄ 9}+xum284^IvV^#qʋMp9U^7̄u4~~]Az#O𽻺aqnnii9RmrCZ¹+sawCrãt d&|Z}ံ t\V`W?f{$n8}31p}d- eֿP3<:lDx/NvCkNu]!< Épr"WMwXCԼ+ f ੀhgBFc%\Y >Ͻ*3Z8{l\aǦ 63Ϲ\pbKE"}S>^O`ԩ֓;w~ȴ#B5|ޕ8)b|`c(r` \*`̥ƒau e0}H L:ΰ8amQ2p(]b.\_bO/aXQ7G=M{ji4.[a165e(-PZ@iJ (-PZ@iK Y?b&j jv7Mp^G.]&Yb̏_~Ԗ@ix~=g~3.\͘9&اUx*%ɖ=de99U+aC?e9e׵^NT㺛K*Wۯi5?¨? z}Mه)PGM< 鯭OݷJ}+,^oo5i^ MP~t}^ّþo6k˵\f,zzY[T۽P~OC 7"Ru%BTx&¿o,QWMFȁJY)l/fYD=sFҿ$P=(nE<5HwKA'GZdq`"V"g0d^}I Z2S5{XʟjO/!$;aiM_TڕO X_WxT&MIV\\y& \oG`zOC9MEźO˺-z DC.C\0P1 #򪁽Z 38ec#:*@nxNၓ,ZNQ ^X}i9n&\w }]ۻCp]Hoʤ9|'CjF܋4|lטi0SrP@a0Yag@<96y]1)بC!]K%WaGhV::guy}!Nig~A0zxxT7iDcw<GSb7~vAOW.S4OBsb e0leig-8q*lT/8ry9F9ޕNnle,9y]mr!|r8^[s{9⋡ٌ(o$+8+][QZz_Gq0%/ )tJV/ƖNH7f#^?-d' tLHb j9xCckJs 2;5IdT4+8yde^6aeqN0-4Daz(c B=ZБu=Xfl6r= y+6 ΀y =M|w/e n#9^dY֦&s>D@qMk< k8):s<>SpȭkI3#%$>4ad*D1+ dw>л"F^ D2S*? dwStr'$.<9PZ*d7i?-G? €]Py5'><9obYIZ9$wOq;<>+Vo¼ߩ:G` MwY͛ ]gɸ; ;hV_ktNgC[Y9Bz:ç4!'(J__2^#X&c_ y 'b/H'ttDIJ;oh =T9jOʇsa7Ni'lsxcwÜlRjZ#̞11ß}09mW[ |f9 {~/.rx [GМMHix8Yʒ;:ǢƆIK{rb 6% ^tV/ԇZ?*,a'7#HhxƒrkQb<3rId~zIWG1I?)y)fGFnņE22NXR9!:bD:[L?”7IJ{^(;.}AM? USԦ d-ʠcD = >44~`.x#Υ]ٌ֥V]M6޾(x%D?;GUpdMt҆9QpնVJ4XDž-tdiU͋tKC'[[,; [PŻ ݭm"8nX pA2(''6,,#'Y"@PWԓ[RYy-YHՋw7i| ~/ClM,#(ґCGa_CD <uY@F)2PT9h%υTڎa[nq%YT8مnۊ^x^.}l o[X !x@(Pc\n A#f`MG;m=LHmءĔp'fְ%@,ns˙F< @ImפּI\ϭJN=c;غTޯT0rapʘ`xtb|2Sc0"u93˱AnsBgb'.ǻNSىϑӄ`K8MU&˜zfVD4X Ep̾O.,bn5Ú͹\rˑSZ Ick!UM\])2qaF,ǞUM  ̲U&dteҟ&83l61Y\8غ\s.ZkpPu 8@兰F=љ '57NfZs9n'0njxam#H'? '@H}ӑ}c oCpQuhԋ>jGêa9*ִ?s/'oٰnyЊ>8.Ta6`ͬk+5)IuXGp"%rVi3\d6=H;=8@|J˖vFQ౒nSWfu=qγCkztdlKIr'1ݘiA4rg*,AF "ثk9ñQ0—`n f ,N|bWci5e'TʎU6>tMz(N}<8kM-Q3fyS4OE8Q.k#TCwYz8Kب)ghD+L΅99e}GgUN|\g@q7]Hpr5'?1H:Ѣ;㘋wgOlW>EX22VLRٳveJ (-PZ@iJ (-p%G)Kř6g`d.%#5RfƇR&;}ny+-PZ`X =?f>@ w$feDNF8jqw,%S(1>~1zZqQ+G&99>rgnRzVe?H6F$b:y:C:&+ )xs{ LvF_7er>cu ,I͛f:QK(@W#}BGc}j]s*N2噍5Grě MTO|JЫ",gBسfwhSn&99kgkrL 1'}<˺Z32#C"s?!z &ћ{ԝ֮*e<Ǒi|T dBG,tzjỈJFJI/ph2vI'xxLX HNIq=<¡N?mlѤg/wޓ:ڴ$%T~I# /- nR˜MfpdUDFzTN 3+ODyz`<7$ZT^YNx\>eh5} V" t~ Q"jOmԋ+q -πoG%S=*)|1 3Kd%yE]߈nú]m킑,bPa`e94OΠo:cIlX]m*8} wzO0 kO|O^^7Wyikp>qmuVo6ZtA5-!>su}iFvejE^Œ|}EQz;dyo|Ͷ6c(6Ŏ\V?śoYyѨmI)oV9;wHENK#X}ڒ:j\@zWCECOpkC0. }gghLbqu#_Eٮtoז-UZ@iJ (-PZU?#3i?>N?@g$EK|w]?cYML= dO}x7 p$}N!3R@8,֍)BRvQ2Ci L;٘t^i`9\zbMo@eZNz)0.sS) MBjNrt6 _fm0`e4LZFgs]̧|wup<H6P(8C8A-{!zEϔ*;ptjD(cUB}UdƪcQoC;aWO1z3jP!ҋttZ36:_pZI}NA咳r>? SDޑ0lEclQx84vt;Ng ߿\GֿS'OvVtЁ>>BTvl#ͪ6>37l[6MB幏mqxQ.ort+{{f5&u{`86: (;xHN*7(xOdx8%ݾl)5 d[8 Ntf'=).&%x ,ɁՎy:ZZ҃SۀKD{ބy740EE9~ӈՖQbSV.˂eZvګO8kgNg8*yWycd`:Q89>Ά)@[Ҵ#Zt,Su'mc W)x?O/3S/PV{q?~\ >62SWW3lb]ʭ% , QeУ=C'x:nz~}2EEte87Je'n93;Q4eQ~%͟,^r em;.Ngz ʓ0 uL{gyqv^+;奕 f9LeP%wdlW 9O/R4:sɍ< rPf6?p_3<<&P|//f KG9zw9T:6yzT'A64H켢q3eE8yK(XBho ұmsS'Nm?95c@ kefmqT8L+#Yǽ0Ioi;s(^][y͟.e򦫼ccܸߕh"~^'hL;ZSwI߅?lN=8=ŵ|QFI<CFnd_nxAZ̟HlrR:I@'N: t$I@'NoHQ#Lt8XVYAmDQ*uZ%Ch8s%?;I;,`J҉ĚSۮp3y=q8Ltx'1 HuZ M`f6r\΋-rn?DDYxϱ/˃,LXtrnh%@r`>{LOvZ;B %_\4.<Sqyp%oU6D~S"3ziYDC^6yUj> U lK52m/sxccCڂ6kcSGN/ggvq}Ź{Y^U17$TndGe<5˿XG=L#\VLqEA[X'.`ݦ єRb< m Oc(7o^X]Z-mc/pJՋ#8J9Nd_FRY]c\iݥn %4ؑ/aCNTgK(5!ͳK[ԙc*J]EF(oP Ȳb2^,W?~' Y{ėQZ>v܏"WX>&JQ~M)xdg=}8xQB">1`T4wXa}GäKd o+yuFn;gw8M]fR e$&7vFoؤ S(#Sgo7j#{6]sۙ?O;Y@'/\ syufYdC^ /o\{wk䱯@b!{ˁ0pZUoPZȁ̙_K#\q4ia$Dqk-ls$rƚFyO[hI$[N)ӈW1/NLXזQŻWU7xW'eMSd{3}ۍ;?6@m M屝(p'O5 BO,_؎X/{+e|9ܾU/V?eHv V 6SyJ?ӗF;E6t!^Kx!xXFgsgqsE g33^.gxG.?6p _f.fD~3Ј&!+3d&fmוrIf-ϲ*+ͱ7~aħA6dyr?:WN͖ u* qIVΏ'sZ;{7yA-7q2ўMk}#ru t:]: t$I@'N: tx$߫1ƒw-W6|NXh3 d]$8I[-EDr0@ įAB9$s!,Q7a&G1791m5-Z8 9n4y(hܺIJ!.{]Qnι F+Uz_uw8 n-b%`<orEK~wTdQ 蠂zȷ5 *mUnM#ChbYpUޯ4M TpJ9(K<{OM+˜?+Ѳ7BLo Q ;j,''٤ p3ϔPr2mяup:r<[ˬ77\^.8[ɿtr<- Fʉ#saEKXx*?2胶e=e4-H9G{ҫ:+HM1NjC-c7x!0W$]e6w[caJ Ƥv*v9}ؠ估 Yn*gQͫդ =z<Vq)nösD ;(uʅ)wM,Gxv{FQ<ȗnn+\]`=.)<ꛑ>?z|迡du,jq$Oێі M>\iƆIÞSO߱^Υ1m58£hpDŽLR/7;}4IG+6M1(sD+q34wĊ 7qaU=_0Mĉzg 9<,lΖkVv`me!#b&m?((E;OfezpN;lݢ /vܢ/X`lW8m2'}72|;z@: t$I@'N: t$II1* "z <,]ɢ 4 YGmw6^$IH"Ϡ6^~;@\j!1֝?\J8X7jv!Me&/xjNazZpN @MLP?,^cAJfenUd=,EC_Og*&7ISmn\X nv%`Cd=!KKXEfxu]Ml,`tu+/ynpB }pXVx εrזBFSƉxW԰7yt* VCS玖f~Z _;ekH9}\\|13UH*O:OkwT6jHGéeisske( W.1- Aq#fXX!eb, %No,1G1SQpOr2(+ o/N\m33ne eRLZFT9^PvXTT\NʼneZ=ɩ,ZNk~mp rM0>^67\EË(x}EUz@( xn)o]X]Q}LfăT 2x<ȋ:YF%ϕ82N}O{SZ06V=f }y\Wt0@,TV<6LbA%?~o0k{Pz`_79m؁r:V0֐!F.<{8N~o kM1/@<0YAmXq3>C(m3evSq:Gc]4@@Q+(cv4,O3a*I|!I^d;RF np;B3s)W(񁹻:&AO1kdWmKۓGZ@pNd1ny v.`f9?grI?te<9TYXFOY]s>Ll47ZPc16`a%YPBdyxVQS`c Sc1!xU9pLU2|Lh0Y& |w{ v$I@'N: t$I)Կbb]'kmwJ&"ۯ'OI 0a>!׸4 KZ-14oc}ܡF}qĚNK*v瘛\G͵}5$R'"BnFy#Ley?*Q'qa9rcũTu%>Ec;,p{Kk.*!Ro7¤fe2WP.eeZd]ZD| C'塌6YPw〪Nan*c *"مE(0CG3?_~e煅K\g!C%&w>Fv>)345W~TK+ssd8WP,1WRIcUdZib?rj27 0>.>56 g9]>Y_X3׮YD뮦<.+lO9Kxe-oq_*Or$0YbOϫ$Ȼx5B2l e90*%0w# hQ9h%b~vS /͔E\ L%-(vɦcG0:Tǹ%9r\|c c  nG%cV{I?ڍtS8/h+yS>mvy C\p^FClH9L<|MM{%.1:5ȅVnr>IYcM/DațA_YmfRH-SaCȌ Ghl!qxfi "\@k(l"7#l`W*!3O#tA6y'nws5^c3AggDZ )a68TG!͡uiٯ+̀NgyP"_|񒷦1BBƲІ y㽛WS)v=maCݰ Ft{Hk0ݶu*[`%ƻ7;Gܳņ5Wy XO s K~d%$c~#d;VE)qӓ'  1'L}5 s-&5wdڊй5q?$$G>x[| [9WC1 Bj(Дgc^ltX.cމryqpOsKvOx,l0qs ;ɻWVu̯1O}[<0Zo'~R?nߐQ@+p:o[ ݐ1m36&6m.6"=*zd8Ʃ>xY~,g^|ɋ՜V3ixQ.)Z,tנid qeG8cZe:G7E*i*nvLC~vl]By uUz梱s6W z<^ťp+s MHۓ'1G,̔fygaƜbƆ2f!py++Kƞ8 v9|ٶAo:'Tk%ny>ːT9S*tÑ_Ţ|PgnT|X-^8"4J G˴JM|c~^.,JS$&k(ΑO%~C[;̑ ex˰0ɿsї6PnzH˅z:'чv;g4n OWpڎ}NNBFta ՗xD}q{ M<4u#ރV(CK֝ B瘋A^K89ӳhAA0uF~vlv7w))c%"L/"/. l3ҵG M%+ؼ!>78r5HexE)0?I; ʛ`>=U~E6a v(^Abp<)ب=o<248<{RùSqi~RtÃrwhV dyYf{Սt D¢ M6\4{D{ 'Idm'y17co: hMЏby! Rjk%C&k^ ؂|sFRh#zs o3Ӓ[(lhÊN\[F>xqn@IDATQMgI߲> A̼N]zIt|8Hml',I(&UʍL>2C|9+NZCS**ROy2|_彧7(˓25^yqA2^E{֖ ui˱L@]_c1A8%B,Bp%_].G#,8ߏ9r*t5p$d&]W+ r]=B#;Fyrn =*< _=X[ZOV7o#r,).' _0&&QYBpl+ۡ [e:U63\'Jc ߣ5 lm^`cE6\Y^//o݅jO`Q/#>n<0IrBl2n{Oȣ񾼷UΡrN&ٕY}K7 v2иlBzaYidyI;dM!&,D^?|L} .q%Cx+3U i>.q  0}yU ;A0[NuFu ⛖Isq̔azG̶liU xц.E׼amF? dmGbZu\*ױIc! GHçFC_QpS8 )~4a"Ty'Y_+*U2cmgoƘװ96ԱFa,]166aL$D*+!/{ߥLo8j3_:qziI}C'(iEimX;L/ _ [iNY`6<o'b_践IA¦aY_uRy게@{ Oz7('?x1wsG4 ҎM4l"bM(&I@'N: t$I;*48Nf o &U],d; t12x@nb0,XSBVͣ|Kc'5s OoH9]+OTllCΞ0b&n8S??A☮ጚoNtVCyuM# J@tA ojһ QLapFͫ6TW*}lKwL׶9yk|G>N`fk3֖m5WDRѯ 8u?Z[6Jxcg,6}Yw W~o2ZYDאwn To [vq,ؠ` =pEhũCVCM.M6H&\ҏ|Uy~9>}j9 K&AwVȯ ~ M=+;ԡ 9~ NN?2 f HG"ȫFA IEy[f1daoZv!%7Ž3Q: t$I@'N: t$IMK?^#9} S#|r!/+  {u$pG$pVzP(r8olj DZ,yR(Dbn'oBd\ uBŢX(QtOrax2S(X(ssdyT;^%z6´ 6Xl[8!"Bx C\~y3@ȗf泯F06|2lZmOIG 7tR{hFG^M y5WGb1Pn[vDbU.pwSM~帶5"Pȣ%AdZ*_Z+򼶺^.Qlc&h6WwC[.xF`A.jpL$5lهe7qo!ȸjӌ,9dw#~;omr뎦L-Og#D;q"reqv7U]ppv;~С,У=>GqL_eA1*7pN7pWN: t$I@'NF Gh{(BF/IsE o7Cu*XݖCVRf˕^H zPՇ O(Uz _Žf'Y4A: },K!$RO֫I9O^syW1N9rL^79 țWa@~TBɣu)7i`Eɯ?Eras|im\^]M%(en3]OCynPm,|SH~_-ϲ_Ȍ>K.1aMJ͓|jIp\FӖ*y0xIzgnRM2 A`[2Ovq{~bK ]<오}GiCV3@,1W [/8_h:^GWv7ر,:ǼSf#]T7-Jp)lvr,b^)mm#X ""?/ˑ;fXj׿k;XP}=GFDžtcS1F'S?5!O7zr:W.;pga!6VjAEsV.Nr3(SQ뇷&|7$I#u'oyS|n;F"I@'N: t$I@'; y\@<)[^G54h2ТIo`q,I]"}~Ӆ;$\.~1_c?fabEGiN{g6k Pſ洣'wN!Sf=ubk} ZAs h_IS2]B!toGe |J̖ /qFͫsyF{&u_/MTRoZU*d e+?82ɋP 8[RjY[X--?NjP~u1q't2F.&Tup/T]VF8-, ?p,΀[]¢zY#BYÅlj1z4yٰ0L.#l0X-ɣr?K):t?y['a2#0'?0vU5i[OLxjlzxHy0 !J7˓H&I$<ș/2W/t"`ŷ_8@mң] 23?>U>#Xp,|o<#/j4!{ɟdfA>fb`ŵkLܹ5+kUP#w2sC/#!Qg qo 17->mvmk-G\Yy=~xPs;l]fS#|3ٌvrzm_ۡfpz+0}ts?{lBt+k|ί+M? mpu(_YX+%ל}Zz]c$>_az/[߆oV嫿 WTRz~MN_j`i5[[,~9 xw.&~9 .MlB#:I@'N: t$I@'NoXe#rEV%'} V$IH Y1_p@o3"G,wʫS#-ɺͼ2—'Ä~Uo|c_5Lߚ5=2U.(ied^!2a)@:ya1MY.r%zdЅp |'D:+cA'5HKyf3\I>n?˽_/GOp/kDK)IVKUvWxH=䕌ǯ6Փ'I؟0YOTyLfviI%(o1MSo9iMf(?F-ǜ1)_BBEN0Z!D 7ay1ߌ^<i>Fp qo ؊^1lI'{7!K? fe$:i'# OKEɇ ^;nl'NRאַrrf\-72ܬIzN),B(MSAyv5G0^Io(ä>k[[F06nEz;_[=_FyȜX,ӖI< %Em[mӣ-Ǣ2IYJ/}'a3.?H}+&^Y;ZΔ,.-84.oMx'+x_~ixV*ZnYx̀o*q~ VSv;~K]@'N: t$I@'NH <opfrC6w?O_Cf K$wIq`{e#v I̘`qk9 aAӃϞZvOz=0 <,ď~|c(C-Rřm5kat{XQ#C(" bZn"-6q.\YԹ[7e*eH:UZXXQ<WPje֓ӧPRӏ@9btrmgB˲UƸs?y@N[zj_{(Ւ+JP Ba} 1nGUN-sZ2ھOGvtp?+LQ8YINbI`|gkUc[˫,пDUh綹^sۘu 1,S`K9GÜ&r ,/$$*MGY'Vmo'^O]UlƝyh+^0:"4C `vJTep5Oƚ.+1\* _ 7 1>P$5/|Ej3w}?՗=pmw ,xT}{ >9e患5_JZ݌sʑoƏq}H9e# f }HyPY嗅ѼE%nųA?f;Y-/ qN0Q8&| !JjdAޜ g\M7NDyGK%o{d!Ny4B(X9v?7m?,+*zO;ж@ĶrWS<'U^5c^\t핦Pg4>ȵmr$yL<|DƨIעF:YL3k55 J[2`A6 GxcR_a&GCpVY%@L= &==prĕxH/#$PkY6jpL?"Y.6N;uDK6<,蛨|pV77fU]S﷦M| KvaM[e>{R']1-\3$ n*i[̝VZWy(WL_y:=sLDPae–tv4/M?hG}ky0rIxˌݬ}:dRaY,Mik?ΊF~Wq_Ǧbc}j i_Gnk8G2=ߵ^wVDKTx|@U֊{7zN=$I@'N: t$I@';!Hnp@C?CoGufNZ X1KDj@fF !Z4M1?8 gJoUNyb*?gR8 k@$NC.Jd m[G=\^0u)>(EXD Uֻn5v7| |ACԀ3_Zmgzgc1~k(7P̖#(]xk]er'@xsi `eY'1?M6|gy 90:ס!&OQϣ?][ô vJ2BfhǦG<65F>r;ekE:_c9QZ\U[~ h>-;N}QZ۟3qz;,`3l,(Q_ZŒw“wܓ s:NE#4"b*MTQcZX6 ضsZ<)(˘>/>b0aųb >Ž)2xYv? PN0 ̵'Qr{>'|R~jOT>(_*>rOD܏|wwg|'?>3Wva>G6W9[?9Q~gGۿYRO}|-wvsVϮS%4{Eͩ /}~|Y9[Xưȷ w(|GjP>kN[,?@ zSygʓ26io>^9? s]QHRAϲ x!_B7 ׾VOL(R*kJvc '{M_y7])X+eS~e*dP>xH< (- yu{(>=V͍ly>f14r,*J2?{P9y&~v2 ڨ-7HtcÊ6};sŜtCl-?_.[^v`]bhߢ-$7uRH1UR7ſYCdˏyr#}+L+OsQY:ebS{ TAKg8ʧGG',"q?tT9'JSG7+ЛҿÉ'AoY_2)t`I5@ S'O&1iĘߚ55fO3򬯬5C`' ֓4XwK`pL8vVwq397oncd+hZ`_*O֕Gȴi=A '?v^f7)3R3=x&~kABq꣟e;ߒ鄧Kƣ2?O BMHo@~rVks\2V./ ?!ʓ5.=@ᢨu+_޶1 Hy[`a!,V~kZ "~wwDȦكt=@};9~UTI{+irL?߁Hx˻9ֶoG@7po.#3n}yP7{;xluY: ݷm.jZi+-K'*rY!"H'iG4N`c;S= {֪T{uXO&&JuT{qӰՓRp ̍ՠ*5<ŸRa=Ex a-'yD}c܊ꤗO|53"'FS;.JUN[ٹrq.:K& Cf*ՉIh9q؅sA:˒U=GУʆB'c, U.<_Ũ<ԧ,E% ,`Z򳚕g5S+~Y)t5}jx?bSr2{,o|"w_d*kmw~ĩ:Njre%p6L^͙r~xP6sHrَԉ{6׹bY4'qNwQ^Ir螾o<+Z;X{;=tr c#n>>& zvGp/ll8H9X_+[G~} %x#\!ywE*4wm8liÝ +\A߽rclBUN0?rCVLxrOdy{囗gH0ޏ*/Re'ϟ,f>J_-k䢼?e_gkixb5|YX<{eL#~"O `92pWNQ~:;-*d+l+8 3r |yo+fק6Q,lL=~s^umPv3uU[#2K{ f&.H2oȅmbrpȉ)aM-I~j74g%Pģ1#]h'Y3AWG3A X;| S~xй]bfrq:^{.?3|2qTvʺbYynw[)ʺEU9]Kdy=vg|;&Plq_ Ŀghyf(ݼd(9)Lğ('ׯlTh3+TNF?p{ajQk,c,bjeZl7PSC}G?58Ak wx 2zh2s52|;#}7͖$4cW%p(W+P{xӘ+N!C\qDMGyy,"\^}Wr:QSR/Os=+_frcA}cƄcS7>9t( _@_2N?PU664&}G`-u`k~9qyGA&rن/.W O}m}B/͆iRJ[ߠHQ@5ݯXmSey{|H| Q*Ľd9@&G;ۘi)A҉HK'obvCW$teVPl@=4s[`҃~b"$o%i-p$=@2$-흯}`toO 4 }q̫ P|YNM0$V:K<蚟']QYJ0a?.BSBiij3&ka y >yE_BNLxeq,zX|Ml??<3O- >424fz 0 D.(sڻ/cKKLZ@qłh' e]N׹2I=`Q, 睕i=i;M\|-Pҕk" ],~ yMg4uѿND0e#yO-?2B+/L;vyriU=v?uE-̷y ×daHRUxIe>r\4ʦ#;6z~ NbK9ey(˷E/&@Uw!d|SO4c oFˇ8>yvT;Vmp{_)3?RX%XpgPn-pʝ_䜺'~}<x*3'y.㛅v_LwqO#}GC6Utё儵e>[(se~~Jyt0^/QXErSS"fb̕L"@IDATKqx^sx/ъ 翉 S "*QjCR]գď{P􏫼n87IjNF׮ӆ34RܤϯL&J9C),4LM:, ͫ~ƫQy7JĐK㎻ZFv"qe[[|ZFwP40󙾟Xt35.릯K?"m'{,sPvS+38Q5=Ub᪚+f_/{'>FRFoF}${]˾?  l(*;_tZ=NO}6~w[tMNwe%!G8p}?` f yxGVWyצ&˱rr~zԘ<ŷF>hmoYfbTtY7jF0Ot dM?L?d7I"f1pXcݎ\'N: t$I@'N: +$Ц7͘<7ùA6ᡟ~;Z˼s& }#ˬOEz.zA"Vj1Zl(x (w5~Ō [.rP!rQ%}sb*!ڜT.R >\:$=5 &b6h,ROClG3 8?L3&7BvٻmYX@ Ɩ'-`vW-\Wʆky#;ON).i ??fVhǹG{p"s,@$v^QXF78}a8uhy\9)K79񿺌2Φ13O$'kOq~EM lQE+ʥյ2wT>v\YZ+נ1wSn74wK:uŪ:OX$ `#5_]~Ͳ%ME}ܴ&^M[v8&c;FjUdϲ4i6wc'~ )]}<23ȗe A:km"FVo)ܾsyz<>N.Do{y)Ug%~`$8/;(ӍG˗F#~ 3񛏳r84RmPT chCn<^\:,Y8G `Ȼ'[]rožڞI-쌐 qQ%{N>V ⣃o)wE)`NT?lG77dɿuO?! k©N.@pǾd󙗾ﻕ5/0J~3{h9wjrtټy=7hȶJԆaC"o>ھ̂l$qUEY:L "\t0 X%y3͕PP"<šl2eYJ1ޮl,+)CH)$ue9ʽtM\pv6 E~YXpv}Ww˝Euz>v/ N\%ZF+Øԥ1,'8=kW,rJW%rԃrvӡZO(9uS}//.-'NBce2Ra;`+Q;>x,r _ #VacrS^T t8m~KAc{^EhvY;hh$qqCW7WI`Oc>'l>Ť;~-"ع[^,:oUU@c!"DHe%9#zHO1z4ç#&ŒIOx;(Gǎ<lJ i$XP"!P h]{սU֝;][fs;yɓ'俁|JǒN@S{8 6P|vPv*~ZP!|8e M2]?JbMD_=E&:iU4jU k]KlG^~<Z8ſ4F&lӠv+DD-YF:Aa:?7)>LUlwk ,-X:o/Uh L*-wsk LQ%?_r=eﭥGCi@:8ɓ ? #4&>2ܰGWK,éUXoUl8>a7Y_}8cG'Š{njBj!, zh$ |{# ^Y|sVz7 si2CR`jmH%6̆LHɂ )ʉ~e*.xsۤ5~ ҝ|2'5rCeAJ"6kANg[6ҖJB29JelrU?uU ܝfI6`̺WMR7rkn.(|&Ss=|2DrQ!;`n|O (irя'b\')E^n? rZߙKlFmc3ik.n i}pÀ kV]~5/wj_KY ]{xCM>W8 3X7G#ut8@=8@=8@=+8}q\u?@5==fw3I1n֥nk T\w}fU0G((kZ^'e$^Ai(,HYKĚIE.u2$y0X%}w{zu XMFeٷ.xf0tl˲4!ۉDSC낺c1yE˜L?8-F7YTESCbz)ᑱthz4v3RfgLK{f1[jcWd34qt:7|B:57F8= WO!~\'ɯa9 Y)z~'*,b>TWp&3dI1%_8 2:iڃ2=OR^:29([< i{qSiVZDGQjgM=m>&/}d i{78F_6W,@:,xca"~/x <d6+Źpd߫6Qx卦'i4PhO^>ʡi^S|i mt$rj,rGeixQ.Mf?҄/˘-/ e*|_΋vSa?>8FA*(u{=@=8@=8@=8@#61kGmw\3\g˴[q\ng5ewC^Bw.Ȇ떻y  0;pwd0JZ'XW ux` <*>Z<*h2S#e܀'EZY0=w#cqsqPlhe-DN܊u/bERVS!x-6Q~7 {ZE3(IQ%y6j"mɻ"wP>)S>P{IU(aN{kNs47m Z:7=効-7B>˴w9-qvx&a'cv35Fڇ~o(>[)NܩlpzX_Kg{̈́ TG!ߢ8肽$X*#|"k\D#VحwlynZ5͈,몺Lwƺsͳ#nXJ0fozu@E_f{c}ҕ/w)5ǁzqǁzqǁ%f_cLLCgGv5cXFp%8pKY+UUɱԽ8Y g~ШEJ [2NߨW%D wec%sOއӋMdf  "*;щu ANʨdXxi=%1/]]~WJŇwU]T&d|7'7Z{1 ܴ??e.J7z33>tf:[=w{XD]_p:tp`yY:5&Y%{?e9`Ƅ7 Yʕ4R>ba('9徂9 ͕̩#k9 %Noyn@>rq%i7>buXT&j:Lh"}-m&D"}nr:{/}?QP[fX*ۢ:7"AA} Ó$H6Џ taUAh8ǫYiϩv:a[n@ώdZddx rU]J۫oYgϤy^:0xSy弙i*7-Q4Y%lf~,5WM+nWBp4$odkKD| 5woUte?NZsmwv.rgw_6eLfڃO6!SjXx97e<:@IZsnIC|߹w k ~I|ICW`/t{'^β=mM6>=y]koeWUI8m$Wjs:'XXQSj/n"* tocT%Q 4H-M`!.4҅tSYh_bwSifaaJ/N[5>H+$tD5:vt/P7Rq|ʨRw<ʼnCx#;OTuVNwUқ:$tqRi߁O#Ӑш>tz.n@_`@2qҙ\/Q(ERGLmepS@Ԁ'mx3ºk(rWDjȉtL'/kħĚ)4ݽSd|3[,LlʢׂГEyջ/U=2DLDN^gN`8Qjf%:/Hms-!-\Iai #;G[ [&Od+L*a+`lqln1^m|fp'ph_L/]|7!8;~ t(c˳,dA2ͶXŃb*Y,)aown=:N&Xu8(}izk*JcNlJ|Xwk*_3Ukȴ~7hn_?!j[o'Qhm+E_D+p> v킕(n/[%B ēǴ4l4R{e9m9s͙ԯ/c>7NJ[η]o*@84D;Ӥr) An69r#&߼~mItot.wSmfށ  /:dٿI\w;ȁ]d7Owr\Rܖ{].n #.wLt;/=B޹c9cw.Ery;Hzק̝ }Бm[#j̬֕9iDv:t`iS f;]uҷ1 |p඿wMQ3~DZ xYQdix fI/@"ɟA*]$dAM!i5I AG1dZlgyeE5"F:Ɛie+H% ɟ\OnEeʹ00ءtSg>xw}0mm?(/_D}{{YXtSEekFxN61 /i|G̩,L~?Ni~Hk"@Ԯ7V8<\Oci/GDZ}8'xQbs}w'k- SXM1Yox= B |ꖋ.&k=B> 慙S`\ _}U4L%,qʞΤRObH۬M:&vA˫8l}z.[.YlzQ3c-`(%`d"0TYh6/ѲQ M V7dy>SpԱŦ-h!?: 7HhvY~1.{>- f pX@£iƒL+E^T=ѿ'O.&{Ʀ6o@m)MBbSO$Q/<n"guN)Y$#-I"o-+3ZE)JT> _V diXY<䅐' 龸 }Pp—\?brR-T?Eԥ*ciAxh ĮЫxr!+}Fep<ܕ+ /wVϸQO'pgn'Ny9\\oNТ'g:.V*hI~1)uR04g8㮆7в~_D|C]mm;xm,W*${yhCeU .˖( >vqd#OI~k@s4(gyM*>wBė~R68O( \:Y<x@#)W)]Γ!|djł;%lq i& '-L19eP啰 75m_f lC2,D 9eZ;%G̋2eyl!.<X0 G8R'U\Ϩ>2P@6X~m{ jzY0 #r*nec)-܏>|qTcں ,hp`ezna)x_;J,J+ (Nc,D5 b0'9 6 ,z@60[YcH:Qi'i&5KP:b>Fdý`8͌ѠIϒ,,O8mu~Xi6E66Ga8u$Wҹz:B/ }C0nZ0_G0,:Xŗ Tb H[xm&r~+h;t4ʛ<͔(rS>ȜP$|7ISnSfQH "Phpmg']] NI GwX(* r(+l͖Cn1\p\O uvNJ 蒾^%Wx: @; P >PCަѓ.+Z26/)*7"0>,ֻQș΍AE?nh9Mw?;8@XW|zZ2~46B{MԹ鹿ل>hDy56l*kʋsբL견2%KiA{ Bqq_ +`mYƔir>;@QSKxʓo 8ʼm,0V"}y_`V]zp+pdYx=WՒ~ 9 QvMDX Ox1С/{ǽTr)Gn1-L0;L4"2G} wuÆL]#`Af &6&m#y{i~ ⇰6Sp 3y*u 4E#Sk]&9hԗ2%a9W.Y9H3݀YLSe7:I#N8]O ;tPŷ}f 78"'8e+(ŝ91JI屁쳫 N*dwiq4˄ߜ/-`Ni CkAH.37y(]7!9~l1'gmgpT^X^e pw=ܧ;3'Ơ|YWY,'E~x qp1N Wͷ2#~< n=Z&it{cax#60|]'Ltm/ `94v^Zg1V}lte-hW}w7^7w^m=8@=8@=8}};Ayjg;Ɓ,]5*~l5\`+w⿎ƸPIG#һhyQ83 Xw.־`Qe- ,E:[qS?Q{VS ]@7Q4.F2]t57|qTlSt,vNskvz`z"=|`%~FœP\V:^WVkiU&AyYCܱ=:&Pon`c#޾gy3h=:)zYO+[JS_=0z%  Kl,ҞZ[qO ӖUUr5/̫x,tY+5!XLnzѻC<>/JSd,+X6':tv\}*W }C#XY@yk_g*'l0̆!$`zNX`A<\!ąE*۶hЫLeS,vY~ #)f & OךmӿWiE2G`CЍ'Pܸ0cqaZgޡUܮmqs4 "`USIR!-Fpta}bbz:ri>|e,}inrV9Nk,K ʹL"6{!,̢`os d>,A\/" KkTJG=06&/-.UY"2v(:6M?ʽQY3c8NSmCcTuy.'Gw,|D$eÃ,m5f\we܆]N).[`'oc~~3\zʖs(2/&eI'}>Ut+oo4QPsc0G_ pV3,>e;u09/>\;b{&%AxBNmsś99Yg;/t'ǣme _@m;i%i g]sݴ&Og7Mzw~RH[|hRɼ8R[E쌳Ln Z;e8|J^ c 'pbrxIC$y9Ϳ?؉wMnɞqǁzqǁzqǁzxWr {FT}2oFޭfywqY.54;˞~vp5;)roTC}9?ƃ陖:(`m&EZnf˩а¦-"e,1U #E%Z|Ls}-XM0t`ݾ/]iuqBUkl?>&[77.-ZXHs6ר˵mX UBTUUhgH,dYpWi愪(LOVn+YuWBgG0>e>s9d2 Հwtc('8J>&0߆#Z*rA pr0beg8y8|IJ.+ X)Xț"& 7JbN>(u#a4]P oNUjY9ނByrt?e5hb׀F:ґD?:vUl [ Ĉ/ND}Trsk5}S@E9~t#ikg_OQa+fz t~8¿Z{?M1PA'2}g(Ϛ}fs,csgד#0qvyۍI8JʝmKyѻ;^1qWD>vӳ |p*~3LN3.rr~U#1\`9G-2xEJ\?0\xۤ&U8;[Ad? E*D/)('{$0ב5d4}ses9veUsiٚ_XLu61t3d^%v9O7: E;aǰ? mQhAP'lxb|D Uy4YW^]Q7Q/ƫe2L./N] םn5 k8ϻA 9'x_"zchsȓ3OV6(3 h6BEyJ8 Xas9u}WE>*_b._c=M/1S9rB '1_ZizUfTy=Țnv/`C"Wm{woXl[^&M{p f:88R|=l<4* <}b%0aUY{kT_:ȉ{GeJ.aߺGj8 (Q^aSiaJ:iqoȡJO9!]=]վ(:0A^]#y+p^ZYD/ rduI6RLo#=,^/f M봱GCnE 1eG82 G8A{Г(gkkZQuмnGe?e>Wy]M#ᨸD&d#Ӕ98,򒉱Q@d(kzFvmks\.!sɴqvd83lsz W>&?2ܩtS@׶Zy&U*_3Z,iiP9NC#11U+G'C#Sr.*b83Jmޗq߫,1pH_2*_},~ "״?=˳튶mU?ڞa@SM0 K2>lJ*}'r~gӖ71o?FWQ%Ki6M{nfD4pK2_ȖeHawtY6j?\K/fwO\=8@=8@=8?9TeNZNʛ6];^~{؝;w\*+B9 Q&YUW g3jq+'j[gy!:h(ϣ 6XKKThQ{47,^^mb"n MHs-(8>&ȧ8 hW"zN}hk4`=j =M(VYWAMW#mmrʮi{iEi@h?]"~(H& BqJ~Qp(8&;.c!h>>o]쭤ixy>sSi >/e3,poR [CV%NX{:J8}iR.lD) Bj\\ pWʐw7d2`9\:PyrlmW@nP1tEQنġ0j}> qS`Z6p6896Ƭ~:@%|Mjo3·wګפ{Æ zuka>Zwp#J~Ai?V66s@ڋ2~%Juo,;Oc\PiBLЖI픖܎mv w/pƣ\}%x[';F22x.lW"M bbJ쫘#9&G'.#N>iD)! 6qCLqOQx<>1/g7ߩsZ yئdxξLifi֟r:qD߂O̿ỡ'kl}S3ip|"ŔBOW8t&[% ߴ<ʠ-|<# (|hb%{ `b+Mqi~rzUc}w=@=8@=8@=80|x:mdͥg~tNӡ6&'}N8`{ɏLB_\ف̓A34sź~Zfjai:ϦIꘌ^"9>{?9R2J[uݴFV\~v_H/]ʁُf06˶)gn'*̍]L55t*-陏L/Cvڧ3+N1O.V҉kW絨X0U~ߟN~p:;y!}[]ExؗZ_Nru`NЩ1 t~\`}uOXc:qv%=gDs/.UN6?]#X@yB](9G03{ fd:GݚT< 'k_quom5ҸD#t#? @_4i֜yLΣ o/ Nb|{(pn>r)A[{b^SJx<s#7vN|c,C0 V܂e6-ӏC &1uEV(Clgo=iWٷ;^-[@aww&)g*9_??yH$ƃ}X> Ln[p[uWTo9Fx)|~ ̷mw`$ %~{ryX7ي&ޛ$F>qC-ӌ#'}P FAtɻV61&jsب. Ùqǁzqǁzqǁ9Ѵp`:saoōq ɽk?=ǒt4._N7 4fgƅ;bUwM(=y*p|2s@zrw8>Ƅ[Mkթq9NCoFxs]]ZPZORXXɮ3g3LMl}k˫řcIH?"@9sJy.-\֗X  Z*m{*\0tz]Q/'_{4vt,El7ZOG8t)*U=hzܞ466^]tc(Q8TO/c~a Q1 r' fv8zV$ s(4v~Nl@>Ybr /cULT9h@,]?NC+<>0O`S)Q t_Mg[3c[÷^"Lz:4f aG[Tü`~gM5&qmHX@jsC+i dQ3nO4I}o 7LՆ~j2ϬAR ~\ | .Y@ ţzþUJ}AZ淔&1P:r~*ǒxHSZ kE"(N+.$ٰy4,A\0(9y/Ե?[Fpה,i, \7 T:*ќ|[x7in r2DCDs%<$"*_y_s}.J)r0&'وc(Τ[a7B les$d$;_qa4OVv ζVȇƪX2fJ1ɂyj;8+Q<\5H)ٻd[KBJ#ۨr6ѿ-a6oi "Ui܉ږ2e!`8dy't  !޿DGVF>7/x]L8@=8@=8@̥'`7sx.}2ӐU0u;e7nɱcif;4VreJ N~:|C{ӧTޣ \J{pK?^NҧTs׾~hzӇfӇ=[Ɂ,ٷnx texw\.:/3{'ۗy/JWm *?QZ)שoηr(}tO-`w~lʕpޢ5`AἛ[*_5kO ^ћq( Z%CӞ8T(Y{trx,O̅:::>s^]_KH&cdply`jBA**QQ"}KG1]'P55yR>pEI_GiI[>f:D_-iN鏠t>̃`b~ds:I'7YT4=~N+_EمrE[MI7P(4TBGj"A(caImOVܡ,%`6vKO!(mG-L4Ω>(/?+/it =|DY?~ s-0H:[1["6 +ԮqB0un$TWُ=㊵cʮPvkhVޓGhݔ l^% bQ'观g*5ı@%Bqd[((Pࣜ{G8u톇:t,DAu̓5||Ns7ܓ5[(W> 첰³Ìs}h?.hr,f1u(diU1.6bΑ?L,q2'7ѫ£ħ\!Z!|9vbq)h/u8ӷJ+SɎAC[ogm1L=^Yǻ)ܶÐ)N3?"lNb#'CMuOo nSʫZD܃Dl?3jG9:oxx7dDFOݰR 6M#* `/yr\AU?GJzwu[AN㱿D>#9o2%L:Mq۷FwY%pbN_.`_H~:%}&u9^Į+n3MfyTwYQA e9z:tIk9 aF_ @ogh1,]co 5̍Z`ܺqNY@bџ9nBP+]%4:? h4MUyJ4Ez>cb.]UۗZW򥚑uWo&lYE9xo%my{+S.I*mM8uej<)<bJG VnO=0򥲾\%nhְߏп~^Z8E@E;ndhq]>\̝dKyKl͈NMJxSߏrOdM}w??_ P:#ifLzǸ`\j:̥`yo|jm"=q?Wvw>&Iq)Op*X5<}պa2^P.Q}̡X_Fgٿ-wyl2UPľtٜ'tQm WYyh?Ntun yrF9rPΚ~9dQmip(ʡ_wS!=GuVzr`X >y{_>[/{&g^a];sfL̦GI=T=t~hAsN_ZFWaLoOc~x:ƼHgt3]VQ@OIuNϽjz}zgӖHP8? )giʖ6Wۍth:=i p^ԑo+ fՌ9M!NE23eN?8V#kݞl3(4Yc4`^,xjJ[?YDVfQ"L c5 \ \7x G rwIAMkamŒ>CiP4](G/s2\s08n`:;0ყy(YN1}VI E oƴx ^_Ȃ֒mi{(\/ Dj@5K|J>`xˢ %ĉt6mrB^S)Ȧ8.ϦLᎡLWa1TtQO"G8ydjb/ʅӜ*e)^xqP+lF!0HҾQ4y6t$6 $6 4lj_ӯ+y y$'δ2uC\ZDwv 'C5.V3*iۜpJF*oQ ValE+h_#~e>JCW"f#=yKr\FJٲX!S23\wKd8J\PtfX}wJ\/lx ]>p2x;~8|"UXfɾ-:h'7F||݂m([^!|E1kVI4hCbӘdJ@ͶI9/Sm#1M20"UkF.dXNJ+s9#yq;JxLx{SG3ۋTx7_w#m~HIm0LMk*g:-p=)MOt%X1ɲb{_ H^Wa)jRxNyw:%Wzw&* m %ެSv%<;*o_M뿩BI\TqKw奬g'^N.en?ɮj%x ح$D3S}Y;۪N7ߜwnwJJ<99/twv[hzyKDekhDABr]Cy NiףV㭛O& ~{'ZsZ;+fuvfu'GGCwj.]#C:H:s'GϥGXŎq}-=}OI`"9(^?xtM>uzz쏣~օ܏ݟ S__SC7ӳ+Cp/d}y*eyOzK?4QOcEW񹿛3ӣjx =Fz⯗ʿ_y{#ҩxPQ62\uUNg n[ZwTW!{ǤfVw~iPOyO2-qO.E5r*N|]oGF,Sj*JБqk+_GM٨(\]]p/\슶S'`ey9]kֹ@:tD#sT?~x:=w ,Hq#b{O>Ħpݓ>•T;'}bL_~{_Lc)~Ps\pBz??=N扁Vz⥼!B?Ox!Q֡-\+8-_>NoжlnWғsD'Mp' v>(0*>ƮiaK:"o,``$㦓Uq \ K|ZkTSx TೱDViP9c *"7I" Q2@ҫhj{}fӫM%]\({߯{/=u*DD0~cVdZgC c:I^MUw~Kܢhphc2@>H9PRۍ4 ȼ1(s)~JNy %m'iƪDdIc0tj m?376԰Try<P+O8Pk&ӷ aesAk%lpkN:svu:vWQ'q}"϶g`GttY&dp*&,?h:i7I3q3Ez~g)Uj8f/|<jUɨ֑wJy~(?˘N-'|?9`C?d hgM@x&}}|LR|pġ 3 *9/fl]Ⱥb̕4fkCK?Apާx DEz7ո-Vu;eڪpvNSNLf*{6KRظ777篤 c.9\`ߊzmǺo xDxJh"+k5!0:WLs8}UKW GXVZ@=8@=8@|{0}t?X/|/ʧߟޛڗ0e Dzirƴ?=3֯/ӽ;?eѹ+)}cGQoCp  OJ{}鹧w>v[|s0| #Us|:_L82>o+=b:Ѯ3x+l>tzTC!WWXL@^a#=ؑ0=tLOs_O?hqL˾by!JNi^\EK 8֏@ KNiN!җ._{7{>S5\i.-xA\>k֍2[lpE7֘fw>8Sk>8?¿}r (??ߝKGXk?6wzzWKxpzzZQ}hKg}3ð/,~tα_{=/=(jP|F(”xT=Sn@9/@c7 %,Wĉ%HۭT]|tJ-dgQ@yBy.$ȕthjOj.,3 hIg52-/`efQ]~%jSFy H4 t gy&r,VfC[]luM?Sf'7ӱ6GX= k뜾n;E}QPSNri5`QA ;Q=ՀXU閛f}ayqzoN&2c_}9sBI5\*=eYހWZI$/gRZNpO:xPH)cIsAlOpCDoo f<&:h(Q6lb)~A!9~ٰLt* qEʥK2mnI4ИM6b޺t20óX@unq:kWW`/RcS{\#́r3CCUG֙ hY%SG٤r7ś BG>~]]wg v(˱g*ԉFyp񌻓i28DX>:"ro ۀ"`g9}kRO>*ϦqTXYXy;&UËW=޹(Dji:˼" {}̍8`+2hmGAqMet'|n9e>DO0"o(ʐ4=:-Ӭc*?"l{,ªO~gnO).s;TwSI2Mgz" +Ϋ?{olqo؛$6J$F)!kdvL0r8O ~䛩yQd(g<%k$Z$E }=}nԖrnm(?,=*d Z={َ7ȇu=Jľ|e'9jjS$чv|[X1z- ݬz* 0 |fz]M޹ttwȫx5\c~ώ󚗦m$\3ftW5;XK2>Jǖ:ߡ7epȒw\ VzoM1>etr-]fM%~AWZ{ab;ݹ?HK/K/K/w_q:~XイVDIɏ[~^{/||B QL毠׮'Ř'V7{I~W!\/bȟ-vw/>Jڭ/#lʓK#wOُs)kO+=|G~_zq|7>Q`sóRI-wH& _MGS\yӣO~:N8xn3U5*Oq¿rT#SoίWSR6ڧ $mcRD*W̳pY՘j 3Tڅ{8}Xwq҉TZ.9J9X95RD9z""t55'ZOռƥg\}{|\]rl|aymkסDž$V<+9Wvp.c-~p|;(ǭ'{ި,wΖ_/@ʳwUcVZpV\V7ϗ'kl:~Ղ.hDP?i25T/g_,gQ}r8é-LzOL 8^Cios:5x?YP,s"YX),`7*Mq'_a7Q2337Qs[|>'wP򴒋xw7tEgyylۑ8:LU)h, 6cXf8xf Gś* 5x]DUl[ށPp#Pt} @mpkxn*X̍ZSnsqp\]dnW-0*ۓ b(rm_r9DzXE!]tc֠mn`pRvh챱m6ԼVQP҇$[ Nk I>R礱V܄pzt +\e5m}>(ÇhFUm6;7pwxZ6#~ OMӗWZB`|=9֊ qA14yn>Z8Q {Rug~euVwيHmq;u~a__\\O>||zHzZ+O|Ry3vg9-^yY#k(+\-g' pb|?V˯?۵1 ?. l1f$#!!m@qfԉ#\$40.n an~Xܩc\ $4 ;Nc9+vOV#c1Wc߬Ө'Qجp%uIV9sd&Vp'wQpTi_L>5?>T>13U6e?9'pթ˾ hA<0Q>==QkE,ɹ+&+7Gs&56}jǎb|b;>Fr#-ϭ_-rvp2L_]g 9>>IPNr9Wf’(N_^-/+,^S,KDMj2XoS=~X EY1MVT+}!)XGP.JXOpu\) lYE¿'ƒfmnSE(#+``sEW$TJ{D';ˉM](4ɣ\5+O%mU#kzQj"QXĢɜM=Io)Olb δG>C@Ĕc5F=!#t B S}a(S1ZB9Bl *鯞eQ  ]6bC_?P67Ү{K-7n`)3l @x=,&{{s9, y@6JZzGJ!pL(eNwJ\r|k.?vWy=sW,FMh\ܜ No#V0܌c~q[x&L }jdS~ٿ!WYFiiL{M^?HT>Y:a8vH589lOo9).Uk.x f&pzѱrM7(sF1]:֕*m>`P:V-g7`19@3i7 wk!K\ cSs%}3.#ؿďeKX_?Ryk:ޣ(Y{+_R+|Jn'~CɊ`wnK dee5Y(xh f{aC a<_(_𪥁7ovsB !6pmo)8JQimkmjc Gy~B&mH-PlQ -~\d{cHRͺr}E?̻|||ڗ:9Ttt"he}_k}zT*ü}@|V5*Zmk",6&-ѧ7ξ >jnC-f\/LUgwz.Hx@yDxgڏ;c95̷{([|M'G&jo.(˕)8 .ea}+a7tm#)sH7<Gf# ltbޯީ~]_} %З@_} %З@_} %J2o7Hُt|K[)lҤើY`AwR‡y-kQtSSfpZ{9pO_.ssJyP߿rߢ~k#<=ٞEWZ/-C'y/V=M[jR9c~ew/t} LMcduxlwY]o/rz\s-z%?݇`eRs~o' *Mޙ3^ʭ8{ziqLZG'0G nkcbMNw0,, Wx<6GZRW U?sLM{h]DeMhn~^eS{|WN3Mew1gca;]TpBځ{;VAF^[gsCQf9}d:uo/_*?3r5u,|b"=^W|[9\gzT~IZUd}.ސACuDJqU4 룞p]B}v Le#4'nQ{eJN{&O'PnMY Eq( vy\w~Ԅ!,,LMQ'P>\^^-Ql,$-CPnKx?nǃ2>QEIJbw,qS~ r3N-qm4M{/M`펠[Ai {_Q^S-'%$4" zV鑌w] -Ҏ[e[tº=lT[P:{H;oQ}<l QƐG>$ BT\=VU+h78} !OYi~t 8ǔ? Jjsm G)*dVCߴ'9ݢSfߋ1ͦ iXߦ 226RX)=R$ S1a>fSAgszJ'*79PўnPn>ߏU~|#>N@nL%^Ӣs0M8SJ=Q1"5)euџ`KF3-¤7PӶ^1y7-Hlj+F L@}sM AJDibG |(.* -kH"sUt^=2Nm?GkJ9ƷI,D 6yid|$pty2<)f}uW[&O pď94~ʧ#ѯQ^~+/iK4ղ4zz7ҤMU*}bL:w(+Ƹrd>1GnPqrvqʈir>N )Z߈Hz_I%-o yfueYoZ wQ n>~Gz*on>OȂ5mI1,ڮ6`CXYCE[SVƳ>I6h ۘga~}1{Z8L;6Pn6p_1}ח@_} %З@_} %З@_} x_Ԃm*o(/p+=(>Hyfr!ʝO>rŋw$3~L?Zfekk7]*{珟,O_*G8thy,ލezƙyC-/,gnjB(.v+ )w8 Ҕr[CK%CD lXȩe ^wH%lݸ bѩ+WT4Yg˧ߝ#w_ &//gfۿ0?oH@ƿ.yXE[]x>7=^ኒ?\nOr\'+w8Z'˹-rω4kﬗ߻LKVT\>Ʌ}'sgΰ|9^"rchad9YYqLf,ޗTyy3c/q*(\-{3Qd|֩G̗(7Q}d9*fx|ks,T)LAgb܏"Td+_qOϖYVi-W\)K^bQELo("edu$xrT.Fu7uOZ@W!9餢yAQˣs| % K%wٯp 8 3ԡ{qnfn Nq:ktXv%4=hy6J,LԠQ?IoSϐ'ќAAW(bqSdz&u";&YnnByk()tv]xM۰̺}(삀2'] 1tu+Fok k8IQq|3B mn\e8rRjҼc^3TklM!]:W XcTOA@c؞Z]XG A9eB~W9y=2~gnwe~c~n#WVeB~&\EqM;lX?G N&Xoqj# '&@r=4peTe;qb&{X|I{EWPooӗ7c_:JorWv`#5ɻc@o7sԟ﨨aV軾K/K/Kݓ07q|{(9(]w|nnؐ hywR* (?/_r|URon/ogk4-/,^5G2JqMtX oⳋ>g=S8| ~NB]tAQQo;, vğPNGϛ?U*u1BA.\b͡^xx3o^9H$6B@B,Ѯ&,#xoJS?3Uky- <+K/3R~4ww'.sg)Z]=UՑ,@tɬ-_-n£A: O?[9 S; lxnf\>\f41ɯ鱲5*k_kyr{?;SC!Qu$ szEa]-is@B|ĥPhktU2B\H(UbD;z~R9)F u* r}ByG.!l!+OˆJQNC2+0S)<4.ڜDVl\iM╗\D ^pQQ/y([1&U"Xi#'?9s|bBP:6WZ$u.e{S.at23;ZL9yFX* ..&Q/痰#>d7B_^()U-+x_< R=3&=컴.*K&Z`ch $ᆃe&au Yy2@PxjD)2\s8`z^(3%:h e |(J1UhBg@*aGdYɏk=IcCȸc ;%<cnwC60?4[hv9|1r|nu\w/1~ jUWQ|oN6}3\- :bÂt+rf43uZu2X#LwB'ljv:MxT~Dׁ{)Py;}7Bf1fl 1ǹp9y0Uƹi3(gLJPyHg wĝ {Kk>?Y]k$oͲD2-yMG3N_ m"76T9:P&:.YQY_G)[q oTc?]3y: w9 N6oz4z3M?pjw8ư='ϴoؿOW_+kLzQD|ۡ͸쨷*sX Gݭa W/zCCw98{+x{n8FNDFC/ood{&alga!S_CׄغH,Am{:{nIa؄?(IAnO3Ur{PzpA+kVxRݍ *!u盞0ߌwM:Qپt`=PKz 7"o;3pW)g78a=x2=zTsCg}=ƺ{]W'.]녤foQ^a8Nl??sFSw_3x&l3|rkn,NwQ*׬a` vԤTGfQV+O_9CY|i`~.瓆C).y?ǡ +9I͂9K%OS3JO{&^_P2 f8*wsv(_TEDnkwPzu庺zPL/C>ԃn@vy Cc,1LnzװGW~+(&q8ʽYi˸ݨo3Yuzw#NENlSaB1D#| ٓӅD&-p l8:''1q w?Esvt@9{m<wx"Vk&㘑?ML}9رrR\,=ŝAgț:tYO3: Ͱ8΂w{"zEǎ;¹sB#kZ-K IG )}x~ 铜X(9==N/#X X({K( 6v_E/3  NBG_E|.ax*z 5Q8yi5T=7Q?Rғ{ȿ:)ލA dMBoSD'e#֜.F/'ZEM~ dYu&+ţ'ha"V!O(a{*_p,VfQLCP+io˟BB+ ˝SJ¹-58FUcO|Syϣ5뇣f~ U7ؼr"^^.#Gv!ZGʺ"1mdzJ}Mߥm]v^ltMŭu =}W⥓FKOp.HՄ|8qs+)∱N;C"3BюD:%xv1wTzdߓm]UҘG&]Si be]^_(:w.Ώ7f)hc9c\V.@B$XBp])F[9Eckl66'kߏxJ.6Q]lDk\ @{8e85dƍm\{Zv ? >ilh:ϰArŋC~|8*l@<e' `0###PG 2Z}Oۓ;V*Y{|,LLc4,x_2FA33Q>xXlXcݭ)7kȄw>x;.bB3,>:HX8웴 Hʏc`%M޿7c%,l}tZ In+koQ'~р'~eŕ16IHFGQ23焩-+C{3ͯ~ %M^ifC3醰8ﶘ sKrI-6 `шCͼyqh ښ5edgvb'^sr{W}9¿!Iu=M?֝|eXXvVNtxĝH3a7#F]mV~>:㶃`ukuִT9(h35;^:5|lYK8Jvա1wλVˌwjdA%zꉹƷ'~$ ӎg+;]S\KY>uV._^*-E/ <I3 yTI3/M;lGf<YZV{݁ yǮ4;F >=N>ohl(C Fw"4ߴ.e*ndXDǴ qɶ|'R7׏AVFc.+vvOݲ9mfY?pU7PNw1vs4$%&n-P[0;ۦ^i@jߎۄgxs~hW90/Tq1wq#ee9p=: 7Lw+Wʗv&X#`G]٤k-괠(0GSSFVKU?{j̳lw<ݐ{K$CbJ[7L>kݸo`;a7ep{}C]Q"79D\H#rp3]\ ߅p W*:#!5`y}i+^Ƽ\ /4B)]c~[ 'a1i)m:rJ sO2:C8ML&JH=kq Ō'fxDCJCíPš% H;m]_Ymxӷ{sWZҵr pd/_|(ki33e.2U:\3pl`2m[S6eSȍc;A҂Zkx5)w6\LqYt!PɅ|jÄ*.кțmȯq }GG\E;l8=Kݢq(cfy Ưn2]瓓 Ji0hkWT'](t88i17{499\nmL0xᭅڼ.;a!2w[O!Iaf_Bl+dɶZڴlYN*@/5P v4= 㤣H3 X[ ѕ">7tTzk\\w121IaNkj ='sqJ.Fg9vCY@..lz<95ŵBXfP|y E/aJq$%soTyjl|t|<2ٟg: [[ TlV,OrWNBBNlPH)yVySD≫F78O]iM>) :oǫ``(pD8(RB}0ء{B=0Z[1FTAfZ-ysl@UT1mC_R0G_"h͠6t-e;Ga2.Rk%`6(cfuӗт777}Ti;7l*+m*AT f +C4+N=)7qxB@FS&W3]ju>fn)/=-Oel G]#h:@O:+(XH퐰_o#aM$&u}X?ߩ+*Rn?!K~q"Ա&ysαo5﭂`;6E)sd!cI-癫x`'$ |3bŇ }:*U>mm/-9}߫նS gLm% qwӴFx\ "ͅA?t u"M_!~;u8yGOd5p7no(m.~Dh9}Lrp&ǸW8Dxx7nRVȌ,:En!̋r,q`g[ #&"7f9W &?X+6==Y>B&[.v2\5VCNSJ5z`N@YLkǂ$ PքEDcZPЎ} ,~ru{bC#ˤN@ =N!m"{_*Y $ǚ`9:8']eQrbbYPv -OyBIEk>[t6 m +pb]-V)ؼ:mH.a~: n֑A,p[аtTXerqܸQ&"dK#i*UPxGjS֜_} e^d3^/[{\7X0Fa#b:4mL@= 3(n4+QzxboA2t?Se Qf!7-# bCѫFGV*C)㩲qQY G媬:˳=y8ڂڄmۇ[dl$Es"-Sn7׫"y&8 w9ɮePcC9(ar -60X/QYob axkExA* ׹j ` 4BO8E{( \ λx~c)~9ĘRo峭}]rrQ}5zz[%CNCj:EBȴnQeU'A| Ȕᔽ5r|kn lAz pu:|D)/7Dtn"&ۄ" HŦ.n(iPSKa)w;;Vl7Eजu-۽;< ,. tG2q5d^e3hig~1]puh #>+U ET&sP@cm5- /=ASͤ3D'j{/|DcZVQF^ӭS9j@DO!+q%켌=xr}V[Zw?a ;5%З@_} %З@_} %З@_"@w~wǂ<#sU~{m͵U@/]-C4Ē.G;Y|Nײp?Fއ8ᤙNtA?"5vنuCWᆂpMXo60GW9I*} (`| o`3dK'iyQ<ӄ0>2;ɺ0ah~ו= %!v[ d">z*=dg|a\87 + mFȂLW[B6Jsai~i mVvdō7ݍ4c/~W{H H_ 8f0qڡ> p!@V\6 Hul;!x|3gNL{9v^3v +S(2dй%Ɲ\WKouCŭ4ˍR6βޟ .ndӵcY>Or; '7_y:i FnƳ8 mQяO# 3<2sqۉ~FImagA,62iDZ7cB|qي9: o8^uK':PT?uBgZ2Q:^yQ\D5P7Y czSnY2 @i u|nI~bl|G~hY7q4Wޝ~`Klߞ{"4~whنs|P\p'hXz-q%:NO$LX&!ԀI+\W߹m/K/K/~%:HNgZw<~;=fA'rL{w+a^m+ͮ+}_5+q\"4u5V7%>}ƥOx7Mk8Iɂe<3 o5S/5<4T oIv!υ2(MCoeʬ'ӍwjZhi]1SN8΢'Og1Lu5]_-YD &9!z iN4 *L=T( (v]FyncjBf()ZQOۅzO{.̯qhgC0>Fi;Q1ͩYhנ2ew5]E0 iEr$B( |Du1xo8Ï0U I6K<0 ,^A{%n , P63:$JUҞ# w Vf)BUr:A;NT9+\q6ݥl@W/w;}*Ax`SGοdqDR5xt&PJBm8c|CafB cPZqia Tpqp,Gs(?b"Т XFmi̻pyxn3&)(-mL8l C6mSl}mKt'\G;p _A-Y_Nf4u C:f?'5 w3EM0o\֡}BIgvǼ/.> *|tMXgV%&_! <;W{kL9C9BEPè@1@7mنAΨ^sآ2z}n D'#uD" 80ԟL7X[^(mlBv5F5?rik:8iϱcܣLLѯ .OyGu;E-'޽w036} (H:;*߇q 7ӭ㜾g#֬Vx&\7}VWB2<eK/K/K'M݋͸҄1_tǷ0 I';|\xZSv=:I=2n/&~-\ d5qX;~+,ء@cu}J{4ʥ8"@ΕJݽ(rƜ ì_SAns8QSQ&ly"EZa=-Xbq^e'k,s5wcڢ@Ax #<8\Cҹr 6i!Z; !TsCd@_0 >K$̓7£~lN%P_"LCrv1Y!.NIݢ{*I=ڎEU(oxG?a>i M﷡(;ڞ3/$;UG SPK^%K8ByOWwg f[$n3rH5LH"=*NNo,nyB)Ѝ`–Da;Ris.O\WU6GٱP֓z(鷕W# 2TL@UؔSz?XW,CeXZL{l`١jG]/y xh-ZF; tW"BT|: fylue8# 53S^>T)G6ƏaE9t TZ^7,;:8PPZd{W+)%l*R*n#kkrNƪr7VK\[ŕ xĉQ8H Ibo#/,+08c8}ҕi2`{-;:|Cl:6zFW\`@IDATN8Uv:}Wô⮅`?IYD[k6|tW1@.xLOz"͹cO.>s 1\{92[J#)xOdp u8WFn B8<j6ZtFcDëWmܨ379ޛ|wM` VMgxH̰mwG8|&Mהƣx7܈g,g~x֝44'lWw+[vIQ!sQra-x1.96o5q叾WV;!]qɦK7ݵ&-ME)qȿ<ᮯ^_} %З@_} %З@_} %pÂD:R\x~/)^7em0@N)u3ܝ߉WN!o/kt7 =# 6XxDtK]'`8]xɲ*t|D`nevH&{ӮA'sѲՒZˬ1P.WRf7)fz(dǩ{OͰ0dռ6^[Z,g6Pq':f6 _$Pntw,&no_X^GY, EDMׅP GȏFj@?])g߳;j}ː6E[XEWgஉp# /&Ij೮M8N-vx>T&PqES|]dwQn"E ߣWH wOԍ_n,@{ shQ`Q^]]C7Oy/`^WCnw7@$<4ޣ*)b'a~D,:O?*.\e{,6OoM1qsJ}fE +lDPL\(w=9f(|e(ouF6amb8YO: /ItH [hTZWG zzhҀOK}afrL,W`qknbJw8щ.0sGF&0>Voox+! vU`cU>4.-˅0<^uQ"0,9[S>)3/W%2"+y.QFіKh;&%S<cL˘eݐ0/h1Qrk8y21,(\uPZLmA*xof7q(o7 0۲Gywq1&Gx|ϼ)]Ew~bwu{*= }lNh&1%I=71iQ dZBV4 Ց1\? ʂDs.qDYyWd+̡y1jbIhG8[nZa:[jn4XY>F;qu:yx^Ėt|ikC˯_x`. H*ljD #l\8ڮHK;No x αZWaUtX7 ~e#$OIârdL-؄Ժ_a8 Y~RK\nResCa;#h|v%w} %З@_} %З@_} %З@_wZWä%|/MuU@ȴ΂ERNv˽G:NU'Of\@E'ʯ#Dla\wx/}i]vLc5j:+,^U.ιaZXXH;Ȅ[sҝ XfN>n nLr|]_.?Q)WHY\rf(?Y~pinӜ)k+hǩcx94c!\  )uϰc1$2!Ƞ ,`)5_"NNK51/l˨4i 3и륍Ұ79^G6ˑ[n,<)|M߹QT[|٤͸ovGGƲX2. /݌t7ʓ2/*Q)S8+ex ~)%?En`SI{qƅ)N妏]*~<'S^C=ʐ&m7w 4HJSXq.tLf9ľ+47M~җ>U9s5]ypͼfYk~ʹ& GoY* YϴOR1H `!~,}gw\Zr6ev}EMm)lx3ݹUɓ|Mbjlo 8*{cCZ#^_} %З@_} %З@_} %$Cs7q7?Z0rjxgKM^ioG}>˅*v=xwO6yKbf܅'vHx(;''C2-}8:M)܀ɢj]\eEx*ݓC. c(]W?U[mDgD,x_ UNDfU/*?3?bp f_/$&l-wk?bqqr8ef=nCD0OɋO>pC8|+EK<+zrUEY8jI`q4OeD/h':n&Dqt9/3X0/o9ał*TuS&8 iDv;.Log؜0}d)SW~ g-<ɞUgav||(iU9om*9<̵s(Y=[(ǯ`nܓWλ6.x md 9HRM+;.| kƻbkM#M G<< QNb{ݧQTrbLdži @G\3f':傢=e1||j|q6]lVZ.-/ [rqsZ2M94xW<&vhEa_ƁqSeji>0'txB.mU6f`3 &w8Zou|urlYÊpٜ(K\⾬m!Ͳ|$Qe[_ɊL;dJ2&#_؆3͊|T$w9VئU%ԫ1g;i"c=?4!߲P"yjS-*MZG\aU 7 -0xpXPNL~sYFa~eW(Fu[/4Ex,0O3=UQ.JYz C-ex|\œw/_)][./?Z&Y"}rRnq\sQ( qhS`m/kDv%*y3 T'6E(wIe;5VݮWZdmsyM:2}Y6g0=Hd߮-<|/W/n s {}2˶S>7ajD$GI#lvlŧ5Ϗ?(MI@ISwۓNn#Ifn_fNXnZXY7'a͗+_N-dF־ ;qi5*JQ<4atƋ QayL{Mט?`6 N >SO!OH*^ KK7*W\n*$i*S e<9_E&҄7ώoa\\`@ͼ9$F Y0Z "QL4<9y/ģSз{Cw)ʿ lc`vf7{ooum;;l>fgzwVNbe'{gw[ӓGMNetϗLR*ptӥYaGM[[z'}b5FyȝG>zWt9G[^u&N.Is]H48؎ .UE?5l#.Χ\c=R\@[ǴsC,mȅM{AZM@s}4tA`OP_ $ayt]Pֱu"͸MP]ف1]q%ReB p |'^]}ǟi \ѕW":7 d)^QM <) QhxGzDYeGh$ٰ/ψ@zLB!K£.4Gm{PѺ߹<{,H_ᔛu&u,9λr>o|8n?䴛sti&ˌrP'zWxR<? _@8!dMz-c1Oob:?˜69-܀~Vyy ?Vg/êXԓ?ʑLz{Vc4 }~)-Ox0\|@jzi'݃G7iVh#ngoZ7YݿQ;n"qX|7qZM Mx\+'*ca\}ߗfnI&Ehr)b<3pp4Uvk/rBBkq8*twXg80q̄lNy|?% !&*׳f; ~8KG?s2w8g \3v$XA{+k 1]`zwswv 3&|߰{[[s> .=IrpkX~W2'OJhf6<'R#^ڐ*_bh勔y^6/ %'h0N ;9nO&] ;KHcr;r:‰ETG-b^r1n vV &y0^c̣ SֱUc}i_7?q>gLj?Smg ;!=7҃rD7EFc6ܸ)Ϫ |`YBtL["mءxh'/Z{ixXBxq :z 285,kȧpc 9I#X1M"|܂}v'r|t=QzO~LK z"sNd0o^1>I:F1oHOw?OOY`q© 0>*.~R7ɟM:hf[h+(KZ 7?F= @u҇a rmކlw`\L Z.@j "]^'GKjJ{e3X]e*u[y+ibPHI%JZ"X鍤'P9+,vfL\MHvB#c8|Zgah|EXB8;y*g0˝`Rm ;{wm{gcEqG'G\ nhht k<(L}5= KL!_,_+bu3V4G/aO_{VNt jxOޛ@ f#Sr?Ȥ<7ݦ1υ{K5k]+ӷG߻삱[f;VXu5Yvh2>X|COx_!~ x?oe`%)HEVQ@y"\T 8^Tƽk ו [gUw12ƣC[nx_^yO7T8W",][L@qm"\xv_vrt':0ŸHNtb`ޤy԰Zi0a~޴.&\$0s?>z&e`dBd.M4#g KHy@_GаwFv{;dMyis^oy?-4~O|Y7k6M# W˸$T:Ǎ-oz'i>_%^/iy3nG'\TۑX/].^>ЃuH)P'ҁm8mo5qJ@8Qm7˕GYɅU.^s{Yɸ̷BLgJ40i`I& L40i`775}w _)<$=sH3gq;E,_>ico`W.|6Q7Hb"iUCMa(_6sL9wڰ҈w͍u6GkGfPEWpP$:Pر0]s#u|lzh z;uęLEKN#܈Wы:yϮQ&DxuRL}n0pwe.a$8R{ 흲cs7'NJ~zV6Xq`q'')n@8|?\c{`)|N˨ʃF8˕D_<O&%nB#gv:;?\{ɶ?Z0>lq; 1ܺCP .rt<k|Bбθ);y$v3q.m#ƥFFO1?(ĒGt2-t& kbGxj8?'m"}\]3fcrɻrs.pw_e'Kzw{>;5#%b ?_3 ~JCXǎbdGӹ@=zʨB3҈cssRZFx\ C ,)mtK+ {G ,]Ώh |NӹnE#<,8/}~S;{@LEvr+O9ó}ֳH <@9L;=#i_ qz:ge)StsH̅ ރQŹ]&{eT9J>گx,Pꕘ 'i^~wm{ 'Cnvt~%ubgZ V*+.@8kP<$O8.ћG7ǀ&xS{ 47rG/қ-o(:JUz-2cfz|ux1`,V^/xN.I?:a$э8OqT$ʐzU疷 s>5^ExOye)߁WI}vJ_`i؅mrI]> +\=qn+U,]XDrMV*m~Ot?#p{޷\ *[iJ"~6eӸms bP8UަG.3\czJ2*7XK=Bژg%/7ξ GNMCk,rҩ N?gX+),zxcFwÃ\srX3ˈ˱ڱA8ESoxʪA-II& L40i`I" Hӣ7|C >{S=ܔ2Y2契pl0+3Ȭ] &z7su ڌO0cqq1/ߴ5d+=ɗa&Ѹ֙P]c7RLN/%Nۼ!A#j?a;@d"7ί v$gd >Hnu6=&ݴGI1Իh%Wuĵ92_SNxa#zA{Wn#rll1iu?>~r!KS)W;?^9~{w'׎ٙ0$>h?_`tXvA'ބF!nw $UqoʁIS~h&TyzaD|ptA],踓޺5Wd }{N *%ƽ#Kn2 |a"W[K[ |Nƙ`)Zj .LMe2%Ie傮kPY (_~ J.I^tl8p1q1A^MsAƸ1XҊ7,Saaa!^.|ÁW0*hWt-_a]C闅'_Eaӏ 8W[r2o݅N3g t9wW\7.b+2ϱ`nׯlӫT'Gyɩ8}w&s7Ll!ԉSGWJ̌=? ?^E_<-,y2_ 6׻ < p5 A`없w@y/'v+|k!P& m\]AoFͲ: /u.zܤI& L40i`I& 5Gq1cݕ%9K_ͳ04' +wSZMV-;iσ4ewEVe)'NpU>Y~WXqx6>pЏp\:ձ3F9&V|0$b_eJ* glS`yNjwEknamĕu΋'!,-!yK'Ƥ3!}Y pt?'k{CO >u-/ I':#x͍44Lu[$mw|*dvwLFoC!s1}_pceBZ]vn`d\pfL??Kvwsxv_kBVԋ#ȗ>A WQ>Ԝ.(.?i[qmS*7 c.Fo/8 uz=<$](w^aZx.9I9N8t9fb[oí95aH.0$Nc!y.qV}Iqyvctd~=BU&8)bE^ 9rYv/aD װ ·{W q ,jk89%U *f,^n` ΅W`ESL3c8:c-ڃ}9' \])T'.J}=cʸacّ6ѝwXqGv?=Tl;+SJtQy㕂4, 5@@AY_" w{죓}']`L:w }dSxT<&nau8Yd_>KRF8@8c訛kw4٭@IDAT1xlOZ+T8DM3Gp~|X? 8O0z|u>.DT\יOpjdl?)[a:tW2,1~eec~Lߞ-?8\<1qWqf7֍$;PV٬#tZeYh_˙J&AL'S 2_-MhD>"|8.e/<)ݡ 'ݬ,n9E)eV1 bg{Ty\ ] ?5iDW&:L>'#NX蒗@Oyy拄N5JeHx-7<ĭ#"|j$O7Z!]px->L3, `针>Ztn<$T~(0A\ۛ|,w6P~{>F(!o;Q$4[ۜ{X;& L40i`I& L40iؿߴ_M+]r}|iZbGq|l|ʏӤd.*_ag׍+OQ7,.IhjLjQ竴MyOGsEMůnlk.N q9UOa@Yf{c:O1QK ʪ {%*6,tO/8#쑯ƽ#y-3AwWֻ13wOڗuw7tCrx;uĎ] Q6Z߻ OOb_v?1zdL2Fg0 p*Zo9iZH1dzвsP!LbÀx*G+vf90hmZc Y 5wxS5jF05hԅ:jzݩUL-~ uMfNx:aZ7P=!©VT͉rxB˸][wˌ^/0&q2}k,̈́~itvcHot|BGѧ2T #Gڲp3L& (haPu;L=:>n}y{}E)#H루eպ$(,ŖKې>K*3c,w\z]p~, <Ncx tc.< ({ýv q ˴]=gumy#wp~#.q^˔.|4~ge,,=aE[P㽋v잧GK 2S7vvvKI;z0 uk9^ c1 yaı1 XU'@uۇs0Ѐt W:_2gn뿕g1Y. /Q7]AFOҺq4ym"Sʴʥ}\bZ%\sWi/w/pFQ =pބ wNhY Oo[OG?/x/^dUy"ytiDw*=\prMkYey_$.>i)W ߬ O<Ӭ1hx7ʝig>v)H97i`I& L40i`_1 Do6u&9nW)mV_w'l=qEDQt 0}J|fUqWe+Qd~1RO$>qg5bPd彨 =k/(/Ɛ @.Z@Fe&AQ=τ;5F# M|wڻg t0^4Pzyu[V-& =~;끻w;G~z7gra}cgow[[~xp+v?-*Cwrv&F)]LB.e7X)'FT&g"cFx6p}#j|ʱOئ ЧD Z6۴ZJw9BXkwwU8LC::qW/=64zʴ|?ņ\c`;k9H=y;+1'D>6 #d4Bn1f>Fwm -ȽJ-ag\װϢ3g~E߻t9Ϻ)uB >9 9)׺ޚ?~[~&}/o~v;0h/i|vqc 6y ys,A7vxV}up/؇#pܥg"~ p1a ;їe0G(#ϡsݓ}o8o/UvMϣk)tu@iDPh/$J5YL.XpG#sILICkЃf,Kfřeښmi:P%,ۯݾ a 4wK$@:1p E-,G8a=(&E +x=#×WÍp* Ҙѧ\$iŇ/`Jڐq_henݛy C:TNT(^ǾeJS{8/ؕ<} ]+ާ>RvqC/-LХlB؀m4SHCr8 ,^锫p2_#WS g7kѹ.kQۗ,4#ޕ=klB_'/XGob]a/gec^Dˏa=4p=~;5Y_~:^ɳ ep_RfymWKx;:u_O% 3q:oFemQx< ;slun1S43 Fo{ߞp%ëm(Gƒ|GV Fs[pSP#}p/"_ -*] _Y`Y]l|H$;W|WW1+?ŋVÕ<ҌVR]ˬ&>Wy S$^EǾa_2PXǿF踐^[jpa1,2ֲपs I;#0W0]wp%x2}G$ *d+ԓpk``"nILQ~{פhtqDz0ɼʟ2ANL_+(>[aޅ3c߀ ֈ/B6`[]{2y}EO0v 0|[y{k#);OG\łacw &`s;ή՟v?g. y`YGf |˽N [G/UZ$ ozk9Yo p5x3 m4'd͸w#]aZ [Ld{'(2iqYX Y+]GZnfn{{}K;^/gۘ-7_Fr g9'x/y 5ihO^1iБL+mg I!^I</,.NYh9!i?{OHhOJGRSvy*93ZRmª&r[}5bYE'ox/~Y \p5?}V~i _Yūr3w\Y4Ή$G=ӆ\l/\L{ nYv{&'Wò)/2NV:ȫgR'3f(M~uDžf 4Vk B qgc[ړ3v߳ 2I& L40i`Ihnjܕ0I^OxWN  6f'_X_|N^gi'py$sJǕ6fUNEy%GR~[Vy ljJ#(Se3jpҋP_ns CsN 4[9Z΅c^O1|wj~z[4: Z5pKWUnƺ5& y6bPcgt&K|Uc#W0vWw"nϣ(K=d3=hj_6>n|ۗ0`ya蘼v}oέv;sK/ç&ݻ쾅r;/{b#&QOO8]1('˜BD}U'Oa)umSL?ilcIZ'gڄw'MW0xLL덼 KԺe6Ff}hozX 4rqq.Zf>$.a: X~P50K`Et {sk:oN%LH3qLe#csd?Ezװ2vWv F)yZ1D<Í㖲ZCUYuT8 HtVB5p.bwGzvzOXNwg_r?8Г\ t 7^c<.:A+lM<87ƌ,/y4 ]ڈ Iƥxx%Nnmif(u_oc 2aHCY^5}W kԽFIFW,a&-o!Y\_u1>.1 ==0vu=mƭclʘO{J\ާaj.m8/zw|

    ,s"+y _Y{vKk0O@1_))i_Y]ĕNep5;%'tb~EגAesiI_Ӄl>XɹiO,;e>JbݝHg') Y ? sQK Nxi`97-"AlPtq+6tXp'689SlOO9xJ-)Ft`|&XWӱ1^.]pȋ?dzN;H+G~"yC11EpoS-ܧ~ >ĪS9Ψ]v ,<4˕ w8올|U7GZ|;$V*m#Ϋ\`|Ű~H. fz{ cI3gWΜ],7gO^O$o5]Ѥ8]{ʢ9zǾ[41FW*2"gk}-tG3Wus1/xM\wm)} O|X?]J$<>IƋטDŽDᵅ (3A㲏ca3&WS2^'e]1>~DqmvrXvou?=w>%;ゲL|Ù87{N*:.mwkfo}0v+tDztwf 9fDR~?oՌ۔N2;io gViigap-nཱྀ@tމݴ\4mK^kL1$xd}?*ҩ7yy ]12ew+ͼ:njvb̿Fj _}ӽ'ol龻q 1t???Ġ|cw U'ݟ=>w^;Kܟux_IF|#KMmcVl8.^>.{-<ƣ^qpwW۳Xjb&NE$]umݍ1D=n[ԃ{O.,耦8瘈< qEj{Į*xĭ;Ƕs̶XԁmϪO8wuvdD 1mN$jPp0+e&?m^nA/qՏC߉p^b|} U+;ZwG{ h/I"{.]m`zD|*FQ#Dd< yٍN';\*DxM1F}/\+ \`oBEGB7Dᓄzl>}0۶Q7ƙv 08HK~&^(6,;0&|EOy|t_-z-Wa 4"ͩ/e Q.n{JcO u⑅Ua7`{)8곅7e,3rJGW["/ H%S78|gi'H)Aˍ]~i芶h ,雖" h,SLg2|LO?$̻cUBc˼/2dM%v}ƨCkyGoIL04$ j|E? D;>՟㢧9E!TĻ WC^\y ~iHN2e%ne-+:Me DWƈyg3>QU8qC0~(i̐.և67$Xy>E#δxguŋ/"_c+Rhp$4Ztjl>4?.L7_yqO뇾oLO11b( , WF9~|w>Jwwwֻ}^w~@Gg'[M40i`I& L5;?Lhy+50#C֏۝?5%,cYJk>5ig qfeIY wϖ{. ~ !nP|N8.$22=ӝ> x$~1P{<=>oI}W M"n&vFA^"G ZmmG<]Xm WSMDr9 ƢrMSdZ… U<~ҀI{GHvR݇LaxEwWK'qU}aMBL7Ӫ0s Ar]]^cّ.O8Wou=6^v?e=׋]fy;wP/rg-wήf +hcd`xœUod]I?IFZE_Ch^ޝ4xf_u.9;}j7Mpwwi|=<Oy`;C Xzz.hI&J\b0h~+a\?ᔉA $sWkv ?iH${9aWc3T .W= J4_uvoҗ0x.\~Np`Gu ms7vڟ|s?>VV,,a]w>5έ>VX ;Yt9x ^M,r֥]$ʌ C{5ΉRKȎz+H0e{WFӒA7_>@^uҲ-.zw 6ubOUȽ߻{{)㭧p%#jA&_r4d Yk֢ѭw awyt=_YNk UW2x$xc9m3=zQ7[~S4;Z9>/Z#-~yO,>.#IW Y~,Se.dЕDgM]qdL++ul\_2<w07YBؓ<׎N̶λFvߟƫO<<1ޗN`Q.p^;xU!_}> :||qx(5n_:(8\xkf\0p/1hDn9&G4t*^Ǣg.7@n= od& j1@aV?*L 8nn`th܀}FHsz%eʙqtRqWyfxfKw\1$QG_y h /^"]cF['w/.3Q.p0yz]I"~]N1g>1 |$wah\X$ TVI[σ,mOX4";)WN_k뤃c~qLtڶeGc)F<$4D^t]`EW=:q[R""v'yO{4\$[ۺdy'H8y 2y"ހZ`(0oJū,Z[ #ρm(\CԱrha.v p0(;'D>h;ۅLN?W71MQ6^y=摎F$sUN񚃰cPx}oomѤdWی ywSxéj 6E KBEEC?8a}qeu Wy߼mSk`[: qCw8/ fJF''-UƳ[wn/hibl^~ "=J\`{]#冰:U f`(QiILvEB靴͜=9i{1"g~;Iy|i<o4mғ~O?1zdN\q-KD>jHжљSH/o' Y\0tI.X&䌣f9KWmV{ߔ |osmw{Q_pִb' L40i`I& ]?@W: 3}3]rpM_W d-LcqoH=}Nr2=}/GxүG3i9ّ3pMW9+*<,Ve"x|?.^0S|G<& "EN}g{G91,:yF{g"L޽1W=[):*3YogSۜ}oKxeXmMqB1g.p' DN#x 1]t1)}Uvc^~awOﲻ96_ߟ}} XE Wݿ9\nr ݱ0@j3F%!cU6"EpP08yC2)Ml<=Հb5 K3DDŽ?(w0&fg}v̮1z1^M~/c>guq Vln} LMCdT2 #Pӫ:Ȥ5e,^ ov,$gIv'x'x3&~ zctw{l+6Ln`0*AD``-yO  ~ȯiy_JGsƗ#B4Fs_bxtyOI+ԁd?E?s0R`}?xzwVS~dV>@OwY~1;w8] "_v?=<'{6zCgIATS9gݿ?dv49qʯ/}2';:2sfl"oɋF {Kn|SF~f)3KYaX&#qxvc Nh@6H F6H4\E"_e|IkLcVYfwidqtmAzR'Vͩ1`{\2^[%+1=i-$ا'9)q6E;mg+Wr ĝcv@E 6Nd6YV /X4u[\ootw'Y_K?vw #\`ot2s>eBܖ%lilh+Q>΅^. '7YDK DZO޳lB]njxli*x[\>B࢝n\E!XXP߼=P8Jx#1})y!'뜼3yI=:[4 Vq٤jK.(잰['7i`I& L40iQ%"xqID̈́M4h%ccRcg;߮!@?ރ5?xMZ_23<~L7&Ct$G|kQ G&`E`QJTX…|3t$Dn`re,ܠ5 iטh;pבOT=w@IDATFcwLO|љp nURfRU.s4 X\Qo[>8Z^fH+ f5]3/pihhp[R/sXeC>#}N\L'Zh}ZwCz$1Nq34~(x.04zR`|=}2lltG~ iO3ǎ|v0?Zc1k*0\dG0Rwrdr/u){}uN+bY~@z?=H)_eDqA p &E 7,9ns5h4 6EnZSsi6\Rܐ")R  39ۍ^|Y(@|2737u?,nu{pL]bg3{ 2ѿ1]O< awiqzM|m (Lz_YGL{(X2۷Mrx%Ż}t7ʖ~QC: LJTPXDYzfw$S3fC혎M\ bFQLTh)˨+2i~m8Q!/Dq ]OHubxz,7}NP:Iy!I'~x% DjUW )}#l6rO vpЭq) NX(r6M\w?::>r[@y}Nh{YGݿq]AF+8c8,u2CeޚW>%3 qLK_RXwn-\Kf* u)9N>  1d~S.dPiJL\ |ԣVCsj J;k(yb1}9cW c5e눻7My3dM9<6$,S0hM%S&ox +>CnpamڊAPb&gʤS}lE_0ܾP~;(w;WkxQRy+m~gv:rx컘FNΨC? $]Py+5{v7e>/N>drbI~T'Co MYѴofΫ^~1[-œbwظO,j$`bSƮNDScgZg"%JU^3 ?&6?ʚe_p1[2]En|V I~G>X-ٷȱ+|gۤ,^\4|;O#N9(~HE^^riqYƾcfn_n#VTtlV|&4`t+pddߒzS.H^8_Er_3nO /d)3&Ht빕Mmk3Zox7aV;{ ;0~U^'*A:vuLgcv֝o{{M>?~ŬF{Gޡ-єc'?ɪKeU&s]y2n;Mlx_LPdžtLHlBy @*M Uc'?pw.c$7ٍQ*Y"$~g;IiPm[ҬCoidfNAG0g2Y{6x]TARUx2顝 H Opt$*#l`&Trwq]ecdcwÛtrG%w=y*rVyB"MK=NU22Q :5=`~,[@LႀADZx=AS2.x]STV;X_WUT,lY* e3ͳ6[=8 F-K;e<0y 1Tf.&]gmr:`29$ɸKt2k&9D(Iϱgԑzyϯ8&t*]r GL_ep# G3}yp=wr 3gS?<v'OmgvPN :(;SC } I5I>l7B?(R_\,>g\)t=Bԇ;<{T3Z;Q0Y)L"XqeBd+1(Gej&g("CliH;Ӿp^ao7m=ӝG?>-QS= x|]kZ|W@ۆrsa}ң?>>$w02FLd;uqy ϴ[[vӧY(vyrxz 噓4w/2=!~X|,8z59`ܪe\f"nӞ;~K &p~WĨd2}ϧwA]~@_(.??~{W[݇E?<~]v)&ƶ l|+&𴤢 ]Q+h`6+f˯]*UH'/|¿ 0hQv11l,ȎGG}[fQJ%ڛ<|g椔SNp7$y}!,vFI-mX~$Oڂ0yw@5*E[:zn. 0lI|,O_ٮZtu}:‚`_7=jkӐ&eբƎ)ylHa>e(+GCG5И&n~S9B^>5@OX┭SQo>{}1(Ϗ&+bbk@cw#}"'Rsʣ_,`x0w#!u!> G},tǴmwba^hS?Mّ9] 0*;SMG$Io>+0>-'}L0:4߿}v]L~q|_?^珺_>?:? ]_I7y" ̞WMfV~]I)}ο~MN{A0.T($-%\#ęHIilmKm])T(|r'a02r`LF~$:S2nZ^v< @aO QwxvV{ĝ}!*H u )&yK%{4YcYJȝMQL{enZAQĤQ a6Qw jv/'-/ K(% eG.""3GХmҶwSA4:"[ /1T5|ۦ=5.glB86yu(ۜ6109z ;y.ۃ(WNJKF>YK=3Aؑ?e[ޒJR?krAv&B_g_`{j T'*\xF]qgg6cscG^ʭm"0%};AVdV| K|]laRlqe(D&fmlp{JM5;3!Fg,iwFw]xh{LL!o.hr 9e<D&Fi1Y KT%K ZZ1w0ʏqex7sQ!`M5*iBZCNKا?[dG1Mxc? CB>=^cwY<+egE8|[>W+QT1&oCI07M6alZ5NFId,-{{wg1rc$Nf^4r;' >J#7cpolw*ܸzZTmy$p/mD3ECP[ +8-[勐k8&)__(7aN;#[)G;Ҟ0I.08A|NXKaV@ՙdYMVx}l +βqtf}󸓺 `sJuW1J|:aƟN4ޓ̎P=7 Pɂ9poh ԙfcw6R2AMdsS೓IL(d·~Q)G2vk`f i)7"=@OQ;ʹDdC,R7T~f?ſL$g 4eݓY`[d<̼,Sݒ&~&;wٟq=3Fpj ue|aoiy>#ţߟcOP-x;]޽{w7Fy 4GL_0#=MZ)۾\l73G~EPxw9S.z3vѺcW3Eke cd%f #@_kp籋Nw1sE$sMlGLi~눓SQFeꎼp&s2VF61@˓N Qn:*mO9k[6@a*,Wil5qi bT|ʴ 0F:TD+/9v4e|bu^|Ә_@뷼6<Gm"-p5OÙ3).z^ËmIr fZL_}h.k 22Y~Jފ4C=.0E[r3wJUF)Ik?菖.Yt;Ud86e>,#B*! !:kh֒MD;|rDžhǦ=4a 2u`-Jƿe~ [yZ j6cw.W}SQ34<S2JzQz]0ڦ-xԋʃ ,`Mӄ 4Y39# d ,V/_6. ufg$},hbܰ>Vg~9ude[ZY)ɂw*߭n%p+[ JVl d2m;^׏kN>v?Gyu|͇ wf ?G~#ukn%0S֝ Gr 6#8'g(obC %]JMcVH>s3Z^nآsiy0}i{H;Kdo`7̮{e& >OXq 'S|Dr y62q28SL4~cL$-4~M?2`+ P`_>{(S$?딍dꁗi<&"NFj{oҚ@6cآS}'t+N[:o^_?/,l0>pSݙ뜪G.0f6qL<2y̾U( j= WKKY1{'Gg"\:9=\$wϘ-G958k_\uqxȮ3_w{Ϻ_w<8~dOş{jMc3%i֔_YPu>苨< m%(]\r~L~&=wYrf" W)U+.=xtsN28.dWU'rL`c w$ywHoe}""%;Pڳq;} ַv[9`G'Ϻ'\cX(ODԂUխ)<դj~KH }LԷ~qCa_oJ_hO2-u#<34Z#[(hcwɟL߅|ږsg&DjDz6 !/[\AЉ~6$N)GYe•u4vZ޴?<2b($%2e n$Oxy5ϖy#$Oc., ^;bO</{©x_}짧a:*:z{VXF׾y`r) 2鳨[^Q@\ܠ/)[}N41fʩV/!16NåqYqo4"o$CB^R-Eͭ\ &L68+.뮴yU>K?R(~Ҙ·ļ'lR&.swP㺖PhWsJk\Ĥz>zwTU`aJ'88>G\+CDdZ?Wl/_`U>rpR #eI1yEz.Ɖ~7WglU}Jy5x՗ݿcawtg?g*ngV9}/xM{}׳y[ JV}H<ɿ[s+[ JZq7.>zfA.Cb'Fa=[x2 G>-(?v@db}%V֙<1X5OZMևMp ЧG1ɎOBTYؼT︳2̘=wV&~]ϧw8}] (^;`O&ۛG_HZFo~vl' v|r-J(+-oʓ8\堽IZ{=Q/vcQ^ ӣSN,?g"׵5 k_":frxSֻW'@; OZ{Y+N2l i/ئ?+Lł{+,Uɝճye/Z @j9Lg+x+r*tҽm>͗[u$ijЯ)+DIS$>в' !Rմ{)v3 o^JegޣnI v{>u q^yP{^G_ O! ݍw0'LNz m6*G =#kz3r U=(&7exR;H_p.e{ik6`ў>~wG@(ZD83-y*~L3Kiaƕ_$[)Kʲ O~>/,b@JmN_x`n ֛%t}{38*CAoL22B?alʂ0݌x1YU]yomK5O.⌇?z-W0ɃB<۸7iDI $?%.d^9]AëP֤%pF>j˵4Y/x/w.ux:vzO_= ӟ:7:45]}Qi!WSMc⹮|Q3.2> BL Ӣ~_&p4{4V<-id]2h]>8Sntͣ5?kZޒ$=h wC..N[HxwEl w?ovC~/;YN^tV6> ]6[ V~x{/2xkn%p+[ 1K` Lԇw4뎒nLsëVeB٧~Wݗ(ׁ>>ʸ}AHC h1b[s+IXؔ7zx*j8|㫺Yxj#:B[Z#^T.#{(-qhzַ 2EXv0)]q"ϣU^,qM0q46u|-N!e|c uJ1O1Cb~%O,{c9QFl"MQhp}lH{߲eyR&ѿS* P,],@b{z]sԝǙ{2 my+kjZ:<'-&{yOzwxڤ\iO=Ӕ;};v_1Aqeʪ!R=aah\0?7;"y2ejB([ wEBv-ZyM@x>^j϶1^ŸmT _KF`1[ёrq em'Cxm i%P/^q1D9 (ϻvv,`E&JeO -+;қ%8{~Ua,T?UBȣ(󼩩4ҟ6%ȭ>c.DHɓSҊ6 etyr ;u첼s$7Wl[rETycG4l[*z!4Sޏ) yc0-m!2צ|}lc4 U`'+鸱&*Yjg!5iOдD6vbV9Xr!Hu [}'Ə˖LhzӦp>+ :!O>D)IJ:`J{Ӕ\-ʴu'yE M|ro?~Ë|iIBs{Nہo{ً|ݥQ(*اLX ,TakJEnwZp_7G7*_&aW\Tѳ<[%i[jX'aկtEwçUu`MW<.37lt\yS;NZ^/'>.aϡGQ,|ة#29M |i"Y#Zؖ =Gފ4iGBJhYwFuBFe"KLY*ڥk" V(yXNz*0@/A&r_H{'`VϘ zWh@=y19BXD+? ?%y|-u|^ݮâ<)*gYc3bnŀ\2?JRONxN)?jLuqT3 y^h_PΈhscTޟ@f]uLQT,,LSelwf_w);u>(W_p # V5]`k8Vip~aߣ_;|? So8VȖ(lEڝ:^d:lLfw.P <LCX }+D'IF$qR\ OQ@,FؖI>AǩP}H>}BǶxHxB>.*-s.Ÿu GL_C| =G8rBX=e6IeƯpNzE9ӅmyǺ$~`ġFOXMFiHOz^U,3b__EV+7L?)W.T&l T;.!}> iOOR7 r.q{OIҏ"7m^?Ϻc_̿1U 4R*ȷWqW(ņ;E,rV~*ȏO;WMD-4lKU~ھͤoOטlzAcd (N塩G$4W**9wܼ9| 6{0p4~SУuƤ=^T-[ JVts^H0wu-ЙY-}Qw~!!TNRGw-ErxX;`Z`C3\;X~ G>¡I[ C<+ 4n>nw1gLПȝ=kD$mv4 sAwV_CeF14ANSFR"NeR^ޑ;E /n'ʌs'/ d~Ή ߿ɕgwuwu>JWv'7*#_i(RZ3z`--sO'@IK}ǯ \=&i&jdizTKp/|=]ve| YDIY+SܡOAZ3=j_L0VL˵0QJs7N˽0x5)D3b'G('G;e]ߧyif/##U;#(68wv],Qݡ.\@ꄟ\a<ڲꑿ&8Rw!|U&=%rc ^;X@{h޾^z.G@w^RC)CtSЖԱ&>" {B٢?ZCqڔ^)f?9@}tq:v]\PN}]_ٯ@gVT02" ,麿}O #5d6ӷ5aA6[ (Z oZ`ӹ  _餯37{C[%S!Xf6%Tdٕ 0aRH#=Cvc~Ĥݷ(}䲵Q%o'(w=j41! x7{ܶ#Yirȉ p(W(ߺ}|.#hn=~S@u +4>$-Hğ$MVSx45MI,*y@=|1|߆Oe4Ce*3kT:)3}%OّiS#NJẁdcx(wYF3^Vo",Qk9r@V`)w#}q@g3X&ۖ Xv}QzK&u[E8SoD/#a{[2**;{"^t#O<~#{vcdq.|[b,۱ÂEpA9'.Oލ-U~ָb,ErO-$֟"Ai6suLx$qzh%`0KGF޸(`ӱS! ^NyCS{sNTO82śh tҧ7)MqcFxTvDc|xi>)[ש|ܦd~DžnȬ%8SOb++6//T3DE_~i2N}meB.^i(/yFh//YdyLyrzc]6Vn%U$Q#,9]]/ӃO3x qRK1_ )6pxm[w]Op׵{ELDs?ďzs,NJSE*SS1N3R=siN>6_f $-]%׮>G}Yky-&iO)CDrŧ|v~e}B4-愉%Pw~?}M2T] My)|w5Z>d昉woy3 UGLyy1A{L6\F g݃FYCI I_FVy BOO(ʔ >[$ w+8W.$87%+Ͷ3'1NLЌok201=fn+?4 Q> 6i I,'ky2>ԧd'w)'y90O[<{ +_6;sPAߒi9`G=!< L{׭cq%.x_p.KUלnqB/IscŲ+k~ Og=8LV1K=iDec^aeyP/_SnwyPz-"#zzse>J8߅{+,<73ȔM2K($֑"zǪ˫ΩΨ{TT ]md W|4~oR.2|\nnO8?< A4@ZXnD%;pˌ6k L M; n/LL"̴-iyT%9yMǣoRE/xW~αοq%n:Vk.zB=Sy e.HODE\j6~sW4Ę?Eٯ|?2$d O-3]`tE@IDATicaXSzi+x+4HNG yM <`s|4"ow_yp!ឤa?r\mca/|9+⯼}A2p?|V&z6ϴZqS7x@)_|5}V_g nc{ud}ڈeu"(P/&[4X&|41 VLʮnPS~goTeح6 }t|_[O\&~?O .0%u qW/}+&<;#l~|Ax{v-x?[6֟u{c̑|焕'*^ڌ]r+_d48K9^^J<0/dfὑ#s,7Ʒ8 •pW@1*Q"$ gy"=) ?D6 4 W dn0r7wcBWF6 a,'S~w h6ŏ<ήWj]$=I3&ΘP B$P[Ti+?*~MrljkLSw7&B6 wty '`$ov),g$%'mHqXqJ7['([V& uar ?_iF! ܵҪ 5 ;psB~Xr*B ,dx*_3nc&Nm#4UNPeW&:$gL=aw_ΞycN~q3~n~vo1\{{b 1i;v# w3r}Ž+txwy#0M_f?8}(x niū8?]Ѿ@qzTE e`zٵ^y ED;BsDk<m#.sOMU' `A}{߯ ua_ ~&e rqw42j0w.]`|gGv ~H_Ae+KE.uU{. E !o`œ6špa=rFӸh_k0V1񒩰蛏LR19y YLYr4&YT !A;S.^y7G_{ȽJuEҧStx{&te;Jjèpoom 3_C.fvI &ʃEu0qL:8Th ҭ,CHA LL+y%cݚYp}o\*3!12{TETțuoTzC!w։zU%SA&MMZ?uHWFưK|s0M8슫6gÔ `M+Oo6x 7`01 `q' AMs<ۄ(>Α+<e|Nd+2S}{߃O)3\K| ;+5¢Jں{LϮGQHkH_-'lQ wquw8w ~T䊉3&W܅RRyM?i\`,{ +IOm}.!7F7(ySU4>]Y|\@4ȫ&iH GV0~x1\i3>o&|tc+C S8^O[J掖 >W#{U7|H:n1fwx}$?ڽwN5y Oض '(N_iiO!8%=s䩋cMUY6AE( M#%c R-$}Ja&0M(N_2a0w>HڌK]PZ3Ͻ؏ն[Lov_p -8/}ش4T4";5Y.kH{x*/Ȣ /i:yW pvN9L/vLx^PwdEhmb[|ϭb>ց6uAe?:%}yv.2aN5lKLzL;U sŤ.11;; x/ظiF-y-L2 fJ_gLY@MǗ ^kSh c8xxYD)a Yjr_ |%'49 Yw)H0p\+~ "$0wh0#7n1"/LyQ/GCcF2ˮzÒ2㻗jKqQ.IeN0^҇SBl(\d\VU1M#5Yt"@y6\-\I˪F:ӀCC\dH͸0i2]TUܫS)'S ,;jbe{c]ɇ^nv."g~f,W{8~ >I<a˫06F߇4%uoF^S ISYz@Ps̿|1"}aOMo !"6.k~AEIGKSo[WN>6LS~qLK= ְl9Pҙ_aFeE't[h6uEe 4B=xX?\ 싧uOns0\X'\G].bV&)ӕnwpW aBG묲;jn%p+[ |E 䥀dHx5ƹ0~/Jw`&zg~+|497ԯ 1{ȍ &Л4iQʇ/NK0A"ܙWYw3<ɋݯx>GRw>US}|3H&rwzUeb㘿1ʩ*`ª%-/ ]KBGL+//s0^ 1́f}cAGL,.zş1lUGwFuc%f*]&pąAN;Q$i"<wgJ*+'!dy|%5;yvqg K3dYXA%lhɢόk}Cd`a?Gw43&3DߵuN.,85K8“a@=32,P+4[- gnTT\j |X$Oe3N#:j{ojnS&Ɂ噓T-^= ABx :N{.zT?0¹gT4E/v5tYb,eE&EV8b A VΝ.m ȫ)-So, 3;6UHũ,l' P &5waoQ, I[7 *E'iey-RWNi_dP̏?{h_[ړ;m? &X=fz n(@evW!L{(BF_\{Oy|S |Kշy&Q-Z\V x5YPM:gdbVPLƘj2̄"x?*}eS ΛEAO8=aєd{~=yH[&A@'uA>(?SGvҏ1z)s%qrL 2&J  <ֱ?#Ħ q4Oq:f×7$Uf|σ?0dcm,h[xsaKW+ ;7)k\̘xHꎼnpGަh <.|i[G[ ꓙއ@;ݱ^rN6FbC:emѶ.ޥ ,]N|lepGkqp㦗\É#F,òQ;(\gVr-LڜmB&Oū!M5:Uyj#ݖGЁl@1Sf;^jwB旘t2; )9cOP\31ȱD{t{*yNZDC:=]V2)&^sO!°n''bIr _EK{oI'q dxI?ɗNڧt:l`_70n.?w.vdm^eRyq2q _x F଴%Wqw0e4 ]¬;e',}aӴ;Ht{ǢTY° <|\߂JVP#)v*I_4 QSqߪnS46i^N 5t=<܀`f6@"GЛG&7dgD岚lpVq=$A/},+Os)QyJ:+_ǫKw 7Nјx' x#YN3Y&ME>2G"_ :_|X1i͇N&`>;./eo{WϏ;=QX?{F~垯{uwC^w}6<:S+XR|_=QӮLM~ J2 l>y*y_Ӂs@g; ?43#bsjRg"c, -SU;i䔫4:' )K2^> jd+xn;|MWu8gRǭ0YnOp?h6uE?郍_2~ `2F4)=YɴC*pAܒ ;19=x=ɝm8e`C߷$>c"L\rR~ZYgBV*ӜLUr)<* 28In kB[w ,~kL%`R~ u#u =!} .s8L8M;ۀPDʦ4Q w1>j"㱪}>IT8ӋC{\6>í/NQW̓':`>̭{wSݮWų8|)(zWFA* 2wz!wU޳({GԷ;ۋ߹}~teևw,v^t/w=&lz '.VqQygyI*3N~pY߄ذ1xw2ɻbkS]佊%vR8wڟ;)_t*5kKiYuw#-o VWL"+9;Νww1?KQLZ.~}a>öOmC܁VU}Yjڔ Wso]>$.XzMdFD%60u1B0;OjϪ$cpd1uztG٣2@`1+M6/3} EԷ7>~T4P)۲#?i6Sm:/ ADX6 K?^619R/jdRk~5kʊ0Jن8Z ǘ8|B$ a[ShZ)٦%r ,uxȢdIw1)}1G|t-8hBiSIy;(oʹO}b̍kG0zO2ͳ1 C+*I? -OmX{'»m?ߴ=iM~,WJچٮ}nٴ'ʫI+{ WxNe_):y7?"ECpTB^\q[l٤}y9M_xO̻m5ۙݭn%p+[ m dg/?y9d -} ~Q2RZ>Z—0uMo_C@Oޗ17;&@ OD<)&O7q>s4dVରk{WPwMLL_f+YtN g=ٗ cy 7Khϓ^p˿;~evv>:/apAD[d^xqqoqb߻Q>ɳݿnU#>`V{cD;8[}-}̑{tcޏMIޝ$_){'7J_TY }CV= n.{9L' yЎ2m5YwnP5vSK݉%7f*GSeL/Tpel%##aa 0gEF8e'Vqf] Gz7uDyv" Z4q͑P3*~' らZs+X>-rA"73 )a^f߿e"ACs'VRL,X.cw<'o3wk0^_ +/7ݔi38p:y={װ]WNbtQy;]x m'=]-bzc`T{̟S'sc's_gCLcK^Ϊ(ݼ!S(gвmp%̙je7댈]J&@ݐ{?bxEs:Ów%~ؖRqgomts3)r!Ϸtij'SX9Vq)e rFP mHmR8%$.O!y!Q{X!=!=L\U;Tb QD@*4O"O4o_ӕ*hS"A-OW?_eu@7!Jl^kqY6z,L);6 Gԯ=*֣UĮoKEߣ?TKN=@uy?vw,qFHR>2یr2>aOgOgќS?T0P/l .u 6,ވ_\xx1~$]{E3_ &]Ui0k0 GC} h'C`^SՇ.)_JePpC`p̶ۨD,.D |#1y~9Y>Qc'C#xB-6\ rwذ}Ɖ3 M9v7aVg,=KA~3$&/dX WtT9J#QY>FncIPqyAXSS'\(IE) ̫ h/sx= qMwX 2PNe nߣ]Gq] }GCݕ?3|79E'sMfYUy{S<ůhm!uن x@Z9طL0D("فCX[П}ِ|2gduuXky+x]+>VJiT4~˷q2?t 984I0ay u -Kk ݧ,rsbY]j?(2)u f9⭹n%p+[ | 8`%4&s yр IOӫבufďq7gN9Fg;ou>FHopB3q=?+}љ&Z77$3>hxVo"|SIO@R>TBWi} *a`=p1|sD#{WTs=)(#G}χL<t{|ɗO>>DN|w9e;|ԃ{=_^w"8cr9w8ˇGNM<}_?ަU ~ YpL㙕nf/E\̅FטYv!x*ug UAʼnNT$%&^<>:$t?GSRM'w;0('1t2WI}&AٕNDF*cNkUϼɄo#.a 3#L(eE%J|M-lU0Iھ] ,0Qg,Q -Cp]z$4)8ĢШZq$bZbv5a.ŕJ\X9~ˆ&k6cܝ}*IEdㅴ^tԯtD&m&"@G}%!cG{oyrqNVwjp[_b?jYǽv;˺|`XE8OxP>,lp[PilϽlrp.ۘ(%qۑ'?U >eؼK@'p:$_dU&pȉuyte .NYW-K ]"i=Wvԗ8fI$W59nR;Ucѣ+oj,'(&mŘvzR;+l9#8Fx >rC8y~#\8*Ƥa0'0>MAWr,Fbꎽb;ex>zbCs~/X}U)'> M̼^ ,Ponn%w`rgd(p(nɂ7~?f|nP?ICj72Cpę\Dѥ4Nz-hl](fB`/A_=6VX(G9&JxA/!p0 7'">vu?³T0?W(8),+iyYre+ٕQI'_M7vN=:rlW[_룢r"M*m;򌁐0xo.*cF_}qАB#iA'HԧO!Nv&um_Wy,JOwjx8%fՋTQJ/f] eV~sܕ1ޅw pT)%N `LWnyΏ6TH| aɑd"G@ﲟ?$K}>r`}/`]ޏ<1az;Kgv{x;IG3&YC3dkpK;vnI;t:[J|.=]/M\8{Ɠ?=.|N)a ?, Iҍo}X<;l#%M\MQD?czydAa9@]u~?mXBGW }p|r!=JpMi yhƁfÉ2~/'g)&4懵J=j@3ez"_>^9hB}ʹd< !8qD=ЬsųJC+XqJF$x'A@JFց8Hhw6^3kNTo0nvo3yz1b}!*Q [&Ei p$Oy84 ="NjNc|{ ]q:G3G4fǒ-qwU:+v, `f/ۙ^*;1 鸗)n 5zoU8L`B~Q}hS`[];qwyF;m4w"G[sܫɽT5W@[ OT8.Y_:culNztUѧ'gAVuDzޣRL{  }J~AM(*m('yа1LcvJo:&/pt꼣mbwCGh]|Zs]=ѩ9hF1&T9yۂd7!X3#LSV(T..%8`9T61Lpx79bCeL{ Cҍ pqHn0ʚ a/ږ6fN||(ܴ%9cla /xBOT0s.}fLQBB* iۇU{_BJuShTlI}>Ay_vujV_ºEۮ?ّ»8t;v#g'x/3WS.(g OoP!1"jcȅFr2}:{ uy,鱅C^ۓFg]8jy^[G{;8繿s_nQ֤tG_ϕ]=vc1={= xp7I \22c?B42i+5nQ*8ekmJ%JFhqO<b[׫)ytu_RqWT$8/DE}J<,^rئ}ٞ*Z5>7kb|F2u"8R}Jo8Bd=!Tp$%k9øtlU3`:a 2G}"f $.rY> Φ.Sg1XІte>]#WdwC;&؆ޙNXBiq*ؔ>X~%+:}Grh9x|ۈ r!GHG('AcD5i<{Tx_Ȕ:A-~!8[8W2}Z%{&Grc3|fA|#69OzѠy-"FL..h|:A6Ҋ涘B']$a{)f݄GZ5T T T T T << Krb0(p^Bp!yLGԭ)pJx._4u+#=L(' $APzէHvbGQ0}!{2 10`]&J?3F`6LR/3/:?'x~pC}ë-MLjk,Æ&wlB\u$ym?'g<{qt7sp31:~)N:~<~L*;5ƦT$?x츮Bv=s]v+RmГ&) ku ^.>Qt g>(#sg%v^B'xenNGg4qේL9qɹxx0&7],DW`$q#WZq/N":< @6\taB׍BOmc t;'1]g+'gs \3CŮr׍g|J ><׺7U O|:Y:IY}^-8Ѵ'8ՂR9Z sJ Й<#DR@Zq)٢+r >q:m4Hhf-|7lIkg%~X`hYPrG,D/Xb''%>byg3tTZcf9w. 7bg^/Zp zz%MIO M{:Rv|Q5ݢbȄ"6>` #lNe$wj5ybv/JW|~,}dq;"Uv gXA'鴟{WҲ:ϙ9;fS_m)~/`,AS!S} {4xg?Ma~HgVWU5]sFYsNp Mmz V{ ]~=&1\ r?J4jw×TĂKhBVs NdBQ4ã(98ӥKU9oOAfa bQ3y![O&MI?;Rq3E>I!$,Zs]m-@aMz߾xL_ͦ{NsGx[ӖNS0BwWLQt uyNP,ޕL; P98(DTPv ^FޟNFD7#1Љr3)/{- Kqv=?bJä́ BߔN۴>ؚgZ~fHL5o2PݽpI6p ṃa>wK>>~? 9HË !)(pO^ ۬ZK+dbZޥw&}-ƎwbbYG3yZq).NRVNjȜߋjq\+9kb'r^qO"W)jU ^_(4lA@q~XxSffr#&./`YfЂG? n#EپY,|eqOKi&K`*&B,m|Lhly^H+j/Ɨ£.7u@&e?#d;P|l6w8 |Ps_@Yl[H`,@PLrS֍<'xEy@F!/4a dJBRy:ueO%^^`?GbNjX~=`]a.ށm>r_G_|GƑt~6rB?THGm<ӷ~1z:^q2'ո~xzc'}py5=kE4a2԰mn*gR\?pm?@?lCcRTԖ IsI{ > IkFM#]S䘤 (Kb,8f9DL8rIouJ:ki}s}m!?/rrsf@"! 2]prY9$ԓ{IfVI^o<@<|~&_N=t>rS^ωq]whA' 9$% hYϵli!z1_貍k].?=0_4䂜/3VV 0ai,\ZS;۹-5ٖmWuBn* P|!l_y<)!pLђ`==o6z#͢Mi&9چ}v"D0is8|}EN;зEdzdq݁q5sN|ttlY}L3gU8B=K#"ݣ_NxYXd㰗ɭ 5bȌ~7kRF]ws(d>= 盹RwKrMo6Ns !<8 w:jO.N_?~F1bX0Jf'm)"!`yS0 iNe"phX'% Qdv Fț..zܲ{{|,a*伇U n= =1>LRl)} t}ur{AЉ2THqY|} peodqc#OY~t7P O :Z{(_x0V|=..r*_^|bUe>p]R‹;ń#5r=|l 0m`?@_<ځ`r[C-roP"+Dԇ ܯXo{`9kЗZ>m?%J_.o2C@#Њ >pVL }bZcvڗ#ypb :>*<8wg{<^Uv hxwbm}m |N mmÖDei64mhq㪊8Yڎq~jÌ`TJiRGĺ߷;yG&x/+}VeUL:'m-‚ >s h7]o JXd{ cj5Dqmanȣ@I/E8EQg2 <{xv$ymI}zG;#DL @ O0Kwfce!S= aG%{x /`ĄU)p#w ~y=x<~k],i<:>QBYCoPօt7W#ztY^w@ ע =a2J|-Y8;oI[Hoݭq)?LrKt!~|: oe7mU)[!QJ+7Juݲ ^)*Ò]y}t.ҥ˗"'P~؝vEvRJ|TDiɬ&38V #5tN8emGL #v+~aKyxNDT|LCс{0`'$lCLD{p҆PE.od|ȶI%Po7}| [8n^|{qH/7h&Nu 3:a-+*+>T#YArs=Ϳh|%w[[T MM2ݍ6S=4ԏMwhA}Pso&\v8߸t_s) <﬏ki=G#ΜOv{Rϓz@G϶ޛ-+&fǫM8lׯj'x߽~6Gy)SG{xRӕWd2vݹ? myiaMe7 qՁ|8%tn>Lljt/Ou~Ze=OΉ=3<ϥY?f=ZkG'}cqle=oE'uд\+մ^ lO"1j5eC)aKI`K9C o*oǥ1dx#qNAxV(P2`aPFr_ a/ e%mYCGo K'')@-Cq39'׉;LxzpNbd9}Q=FV;1@`.3mN,gۄ\Մtl:C^E8(xkE>GE=g4>cgV_6* ^D +m@."}V Wbۈ>c 4kZ:`+sSNp̨m26t'" 7A]?TD#0z{xnUcU4? v"@ \.],D*v 73|JPO lh6} {ӹ#*@hA$R4P@t2E!p4x]}'g pPLI7[_Yt#YyN';to8MI ^o |y߫ ?jѷq!Č̯(< HsOg#W֟ Vdn!neMjlX\(t龚 X8]W^'qg5ݶH8r]}/YL89IfKNQNZj,YW}ig<{.jk뭴b-qDGy%0m"+7hͰV&z e$2+hb'9Oz.tAd*C Z4e@=Ll@]/9vg}i.!q?ޑ| WlxvF>8'~cV}xBÜ~3p?׼٪~TKL$¬lz@rC҇G[|pʨwN<!to޺A<Gaqu~Ċ<Dfa6E !^IˬӇh ۻ!Dm?v/퇖.}䣯G>⮍~ģ>qIS2]ֿ^]Y|IחX>,>:>. ̃(uʣKypFPQWii}zwdtqMJ=| o бc"׏m&!?Nmwkё"?pٰYM·kܸ?=wS.iע,d~|bU4)[f chȂvJ5WVs> 0r΂Q/ʠC1r}PWn0'gm7l?g;C K< 8B^]ԇa?j\t7zRZua h>_W,Nv 3Ǹ!7 voe;O7lASK|{/FY7FB4nezeqo˧LK\M'b"_[{VΤ3oM-Ćjrl̩լm7QʆvxMߨI]lL$ NPԡndr#E5uREAzp1*y)osΤV )Γzq?1Փ]SpNfM^<;N;=;@zr8?"5T,f8Z/VNV<Y.iv?i;Ԑ6-v{G>gG4;sT v|j:멳;:uJsgm:;}Ѷ&m*g2}p9GŅ;,'h?];ޥkAiS M:8h4? r}~}I® dJ+qBmZX%;8Wds*ct:FV+ GQ}3ݾ=I@8t—ek҉몮uE&q7jM DOva $9uv  ]Cۡ-8XmP E`:` ^F{$4Y ><-ЍUh1dZA,90h0,@9]@P 3U_!t/NwyB6HS2Xn#1a2em00Rg`zޥwrWmzogsĸbѐǧ…/ mVdֲ9M5y8';Y:q8MIDܾB|_Jwio x֑9'Ꟍ7޶o3tD^i2P~P%^} eq6P|w?ulwyN]x(t=%5TL Y= 7x>`;?>ɓeJgX!=Oozsz:?Tv&9]0];|srm-9y㴺Ƀם. x2-)*Sb2``<@$(7zP6n("l<O'`{B{ by VlybM& l4+GyS6҇on|)ljS֎uy?`Ayb#7InQQ{&.**G8Xv:@j<~Am='tlnw!%k;鮅ccԮ)-7/whǦ?*O" r:-bh[M!~v}}}CdKyj99/#Q}D؏IA.l KS]a?kQ<&vL6֙'-cY f>rqr])jj@`|'xMG]?/-ZX|9PGz慄Y2豓"$<9eO_P=Ć)獒 qg7 X@"%2.2l,hq{PK.$ D#=Z:VDω4~ #֙d&ԡ.6ջ%|5^MSܸN4VOջm]sYS RKw0&TOѧJuR_+CL[?d(;px? Na佨$+ Od'yAmwߵx*˂H{Whv=sBDŽߠ'<[B=>}ǘ@m&yؑb<xG_@(?xhFH Ȏ {Gڌ3>2/l>P-R7`{ ݺ3 DOrfkAxw=z`?- auVTD.K`+beFpcв&цHGlR1^ E ʼ舺gn]!!`^JG@]/qH,`7?,2? %g}0A թ6DƤ'iX(q->0!VTN ]rψߘNLłʹT xtNOh#NŘކN85D?O:gM p *;JJ `v$eDS7ʇvBcO $2D8.Y*xi6-^n?ŞG&kW0xp[$ A[ҁUدۓJvÏXi? $/c11,F¶v+)X>#Bpq 5N:'8.ȄG>q=uN\_^N:4x]B~_ĎpzܺArF kޖ5T T T T T T T T \u sۚdaWz/g&RJujbjjjjjjjjgv3rtNP89u!j23M!vZ1rioƧ N ]r{':lZcMGVZԧvj:vC/rv. "]eϜu{fk ޼5͇$6PTW}W{]Mvij\褋4ߤxΈϼk܄N5Ϫ m}Nd+wWo Qz<lA'V&Y>a daO2i q4CO2}ȷ э]ߠ5^' H0.&/8=!?pJ N}U,éu$n;WF#iѴ}qkuMx wXC[^K`ʥ||\GYuvըJxlZ@gvIMNk2xo*&kJ*mh \v!Sm ,NT v,9LO/9"xώے)lN..*oR4=ffҼԞZKrsg "NXv+TL6cނ,&f1JS_|7lDn\Z:켟|KkrPp`T$)<[Kyӯ xX+x1eMdrhZ@׵T5bKڠ#抅.Tu֟X >GZvsAvw_,쾧 9pvÊl8vvVT(MYԻdM9g$ 5ShuxLY Mj&NNoLjf7GV8Č<1E9nr.0<[/1.$Şr-m-,XKt;nqri7Y.ݪo8c5Ggv!_p:Z:g"p0ںg<8Ezz=GpVs^q}<ٝӟoso [=we#/}x.:Ygo!ewU="~2|,0\!6 2 G сK,gn '8Ag+. s[SN-xfSޭ@.>y]X>R! cq-&rq}G{}?BOb;#qe>P<}e )Á{;)?Œw??+ty{~IMy5 wkBD#{L'#]> _Zjjjj+l{%WqX .Ԥ 4 |jm3mLnՍt^s+#k_zݪ8p~"Olf`kQx9n [te򛏛iǤƚ禶ӃԖ|b{?EXZKl3rHk>GOoӺn8 %By*~1η)~xQ}pV83Ӆ| r؝TZI9gHawWߡgpZ*ntW:eQ 9v krhj10Eu-Ȥ:";8$DlpDm$8jrsFY/N m< Qb'68 D C o:G\X\+gAp`/S=i(v?0M&">?(j9h;NzN『F}*Á!T_OwW)^oB.(lҴƥ\"1M?%a>jއaiZk5\z `Wk4r{ ,_=jZZZZZZZ*ZBL`Ll-JK:6MCG4l;]WqjjjjjjjYڎkANe1OX1h:W`[_M9㗕9#GĆ׎-W;oZpy=ݫEg!9g#Vv3\k\]|޽ToY͟)Qfu68,xsE@d]9-g]Vk}#^ Ǣmx| u2Xs;ӌ7v7^NZqzm+=댝ځ/Y5ж,u$D& Q1Y)!~ۖq L@문AvrF f)ďv2P)7}M>@U['CV&g\nkubdRG fTBa\Cld>݁P prXsoħg'YƜ"'ؘ>+AN|FKs3iFeKX^hmCuw;)\Q%"\@84~9v+ޘphY")yB1,;hYtinXBpoXmy@/SFC<D<)?Ȼ_ףucS=orۣ:a%3Vn:j35GeP.<&_4ʎ.< SA6@P-P-P-P-P-P-P-P-p,9lڶ3MGdpqGq]vIU"Mc92WԘFlk:G%Ϳn oLpZG3;SUlnNW}+;Ƒ*GƞSiBG(+G?uéNMc7묢pbsb (;8d^ai}xZB%rI;}\8%zsT8Kh+)āZ'^W'lk9Cq?u(>-z{7u 86(%D#M[E6wo:bEuڡHe]9<@[C@@@@EZd WLh"4#Yq3"WW*ZZZZZZZiSἊqYYbpq '(V3hNa-o5v\sԛ^Y &ӚP η夶6t<5&̼ GںN T;q$'#3cRO(~vT?Hw,ux ohl0:OxR~!Gы)뚑-]K?&Weǭ2LQɿSji];7^@I"!A-Ma i=J^.dEa VylO˿EO| ڐ# 2e>AMr6 YL+qJ֯T(l:%JۆAF-FqClR_tW'I f.Ox6}YP񧭯xAǽE+,`QN:M»=]ޙ/Y9~Mz =q%ZG/۩!*`> \m(-P%P5gL@@@@@@@@@@@cQF3䪮I&J=2Il@@@@@@g^g+`qӓ?/1;[%}7ciZ  V;>>>Z\(D;^Q\d S0i6N+gQl\WqT_;{>!a1 ܏s0& ;},hym[l,( N]^%Ӂ`Z'(BVU!^VTxn&x^PqFD2 ^YO;|1 q޳(8npNy{zvvZ뙠:i5; wB%."#z9NTp?[kW-P-P-P-P-P-P-P-P-P-P-P-p-H\# :V-3 6x̸BkLN9jVdM :'`C.vMΗ@] G8ǃݺxqĉrvu\C"S؅p>^pAoɝ5#SrN( qSNpyi>HuqB8hNOKJڤ #\}ڸdMM]g<%9,+6/r8lmi4z&BxP`2ce[>H a{nbڅCNap̒? `"4+dva@|9 ϰ{}z42LM:bC&d.7E-}HW1te(R>{2Cܳ>*14;k}oǾ#\#C^[.8mF(GQcUU-'0vk74=2h)/F_?|覦8ips_R9 7-~M%BK>Ri #?Z+U-P-P-P-P-P-P-P-P-P-P-P-p- 34rT7-j Gcߖ7\<q g[,𵓞|Ɛږβх1%bIpؙBA%PN@bvpӗ89++I~N4iZ/3'u!v]<+gb/@O7pL:Ni(y#Dk:z-AY^*\1Sɰ/@7^БZҔSbӊZ{v YFIsۡ rrY4iu!q<.4Y\o7OYhwJxKD:ǂТNfюĄ:5(-K?o7Ie"Ȍ8{9| E Fдs3gw?sFw 6DYk[Jo~MV5q$G +?C;ʄq&rpY uY`ViXp.mm7ocgy& 8 xLgJtNǤ*,Q']ف?>%t- >+ps;t)&P; (@n5B!:(%xL0нB1u)q{k{2ߋzBp`oYÑЎYS:Ac7K+)qcS6B,X;†QǾvyBM6ۥjU-P-P-P-P-P-P-P-P-P-P-P-P-b҂.x2E6'ȨZZZZZZZZ`d N"Pi4v"o"} x#4!#Ɩ۱ )&xe~\EFhqDB 9 ]8ęov7D8 D_G}˱&])hW:e[z1kL:3s^L)oWve!iኝ =7@QsZxNjrp)W8(۶_ҥ `-@=?;gY,SL#[H zLڼwO.eV}|J\˂K4̌Ѷgs |2Mˌ?FQhf^AG2qZpS6a'.IυLp utҒsfYo ``k:4GŇb=4u<!˰N6gfʊWlX>}rJK 73tFH]AyXm$BƨzӣE}: (m`-0} jXKY 0jLh٥QylUŪ;`aY2Ÿ-,xm5&"xULq.j'UoM>Ӗ`A:^ #*C|ewu+xov۩(a*ߎ|mނnW^)_&T6%Ӫvo;=ⅣvJ| r!,>ޚfGa)|ڊ7ǂp~Ï2v5|~K /E-uR,6ļy?E ="J0tdXgʘ C1Y14^y.K]@Id^'fqE*D}\zپ[Ltr>0C]'Vp}A V]2tC6~%@Z0%sta։!ñA}0K1tOQVEq5oOX#}oɹi,{Sb.,gFq3}9'~fVi"ZY羼D`s!)mCxoEjjjjjjjjjk}n馛̌&W.G`>0١1PxtZಎ8ͱlE ixr lY4o.6"vqXxs㆜8qLڒm0Ǡʩ8.G'پ$;rT{qtVs[wK?ڱ,jCuL aS^Wby^#vqpѵ 8F$AaOXЇ>Ga΋v=' 'f;/uxtx)y*:De[×ОvS#0/.m3OQoB˼G̺ 5t<b1mMW,ͽ x||v߃l@ \Ny-JWt?j?з:D*Jk K]C=ըVZZZZmٔ^gZJןk;H/K_ >B>e0OI?B9|oIIK?+ eM5*)Va^1e^zt z'?1=yKߩ5T T T T T \4(2^p7m[')b^k#׵0[3;,G}ECBG /Sv#SCz3Āט̔>jP @^)?Rie/VBgJJyΕhs)K>{=_+5y'5*agOO{ɓ۾?3>3SԄ''sAϻo}kO_ w}黾ӧs_ɖ𖷼GUJ?? ZvFf׸[{7+^ Mcqx鵯}mzӟ J L;w.'ng n6vӯگ??MO{ҼV>O.>oo%v]8ѳ KV T T T T 4(eڧi}e-q c6N!b$/|+k٪2,,,xuw__׿ٳ>c>F!ٟ3?g}*n=/<%M??}'|B:zhZ\\L1?O~ǒ cǎ}G|DV'q36d<- }(c<|A|~zڭ4NXYYII ť 뮡˿L8 y[{;/+I/zыܦOq3a{3dw~z||foF`Moz k5T T T T \1Z8.`W*@׻#Ҕcs\\ գ/uū ٹ]MCGij[1/{kvp8E^]eخci^NY'%\ٖ8) OvcpݻAM\n+^DnJ?h4Cxҳ Qj@ne ǟ?-I>qH35LYRE2- mPmLХ ޅq&\ېf:N\".(|wh97E첧߄5>'7[3`'>:3˿=~4P`'>|9 dW=NOOOߪqֶ8 H]O3sck^IUv0/Ѡ?Z܆/b7q٩Nj׽u;;8rXſ+IYt&0c?cvv`z3}br/| =[/˾__O_U_>>:K#t@@@(neBՄHi}'r`n!<2_%9r$ovz^OB2}g8ae_`# ;ߥ__m2Vd^Ox>~x ;G~r;.WQ,ȅY5 ov utjq ຅>M-eu%D޴OF %"D]qnɌsc糝FݘGg#0E tG͘ҴG) eڑoR&u߶}Fj)X+bikbU8diYjjjjjCh_A ojڦ6)w)3II鉷t)}PO۝ X_Jϔ^ B >&enT]eiysG}NPx_@'zrS&xΤ)(&P><ԩS__0vOG./L̲;dW؏$%W՞L _E_,W|WOco_Ubgۭ~']HO(>%rnDO@@@@i;q/o DD45\ `.q̌p$;mOO#9/Np~Xw}Uw~zƅ,`d[??jz׻<4&v8 y|'261"Zkx ry1^j7}7ya%gCYza,*`ɉz';q{ ew$tmch+?/ᴦ.,x΄o=}~n@fƿ|lO]YHXX] o>^Jw㕼e8);d{C^k(zcup!'q4jwpgi9&ơ8DŽ?&O*ߵ#U!'Nz[xHY2O \ʢ"Np<@!LpixAq8۝jE[.0 XT zH:\CڗG+l E0 1yiP2iߐ6\ї 'G?hܻПtBPB!Si۫!kiKk!hJ/Ҥ H4)KA"+T""V BQDR ~͹w7lrvNNNNr /Ն_rJ Lz) a٥IY^-++IqPL˼*Ius.OێDς$.=Q _uuXDωO'4?^v+w$Y8xgp-Sm򺪲N8ib-zSˉݖ1>퐶 9,*<\.!UNqk=S\MʦLXP?NqRvhWKW-IphRb0.|s&qod͝ q+0+92y]5晇91?!N\YFoWVsk?o6эMk+u2kc"@F 惔)B! u=lh(N7ـ)9lAo Jlllk!a #oiv ]>67ǬN] >trtb {F xch֫:=LV1݉fwX@#4CgAa~Q@q *lpS"kVF: J~ff#(!8N WQ~YT0uE;G9dګ,]:,NƫC>y4-,WFP*u-!c_=*x[)˛3L~Z?)6`#T/X,=wIlQp&#PZ)^ְn8/^v^myy^I`ͷ<;Lbw@waWʩNA\=J ,8L Zod z}@gAz-4@XǓR9=SONSSFuEV]Zc5(ϸq"ei;pZ׿1Wu7xUE[Y`T 6(pAlllllXnUH\b9~4} &;1߂|'չO?m7'q#qڹ&L7|s WM ܉sDYfqNvm6Lͭȧ6 xO;s2nll@c'sC栴. ƍ u8qSgCMABu6~ڀ/"{}ex[L@Q (4?+i[llllٷnX{Z_秃ܫx>g2:TWqds ߞ 7Qt 'tF9=1uދMvWKcO/vƂoXI@Ԉ7iNկ2s ثNSWn4~cٵb\]:ћzRiH:*];nž;_yj"Nsi/'x\zUD@lɍ&kw_qv!i5<;?O&Csp v /̇>!ͩF5yg:׃)G<`;>1{*!~'7 peNDŽ l1O5bare]ꫯXѝP_z>)[=qʩ,Ns +X)׼.t?#É'Xpk]s [ [ [ [ [ -7~궛myw-ZbsX Ps';vav*w >Wa [: f"#U7xguۼ曔a%3ΰao0~xkc@qNdԵtnLma /v*?̛၈37hp 3ƶM](dɫnpmZ`k#Xc=\&MqX\׫uڂrF0'Hx(g~>L.vB) {eyaM`~OϘf|/(h_1aF^SL=)-A 2. 4z;G E^sQTi>Z>)6w >#4FlÃfU~@$#d^W yM,@,M[l$L 9YSp`|JGSC>rGKX1NnPO?Ƹywc[`=K]@ys^>ftamjYTsթg'x*cЍE}C4|wfxmG?L`d1Lk ꨓrQeTvo1"+w:^:7Rʦ^uŞUTys<[ [ [ [ [x+GS: (-bт 7 sxF3YzysbZkpu~}dž>^o>Vy'qry |չ\`y{5yMJ0͛y%*os ߁ԛd d d d Y`kNi14OlFk0e|ִJtm~#ֿo`lO!ZBu| Tpʵrkܴrh9q5x^^̕S貃QM@8/&.5dVXJ"[MI%7ÁNŧm |G2X)jm 0߀Z9ѝN6ɧ7ڵ4oc\Y|/O3CсTb0:).c#]L㼜|c|`C >r&OBT:|fô<ۥF55棃x_h7eA%k".36"B JhRJepʇ|_IDiֿ*H\c=,(G/q  ]d@aK:M1&Vَ^8oIO/”]~I/lFo&?9sn~ME4nTn:i<x+A<ҚES =ov[\`vd;Xd9T C[f?ko[[)0 DS+yq>@kmIPx?Ryŵ]O?@`aof o+ |Qvb?. sABjFe`;rDbOj,D<۽ dD7҉h4_<;+X<:aЕM6C 7N1$3H$/notUzZ1[D}᡿ yK`2I\oO:=|PR|fF!] C3n΍:_~l:LwGǸ%[x6Ig\c|'}VF:jtS<w----Ё2/X`UWw dm -%mNҰ7=1`]CREv:wV &o]o}pԳ! ):HOlX5a սPcw'y+nXمq6y}5+yО_)ī^翯۟--0,`Z1+ J:pE6s ycf|asQofqC| {((H+'38r29ዷe@@|O%^BR^G>SuVhu3uHx/Iq֒d\Eas:?Q^N/F~SnĚg<@nȅ-\7ca|6ˢ q0ə0TE8-eUvu$dcDqtf֖o_,2Ǣ+Q=`Ia7Tq ̀NlhARtnmS:}o7dqH*Xgq|ϓOt2.@iPNS mgȈS?ôcs^)HEXqJÞ6'|^5zGMvB83!pt _yD:'?w [NoWdt^t~yw<`f}ƯR,RMN,\JVlllllllS4W3+y>ws(<s$` v!󐟶=Q?J45I %AX#4qr櫭vX`$ァ x;89)0M mG*3J *!Sztѹ|"DIoKw-LAtQg *ⱓ~0ғd_,K4#Ocz Y!Shҕ8SOs%M>Br}J^'N!UD]~ æUX؆tS#&f' ~+#^mLtY"WAslBFی0M5{t-gKhS4Im݌3Xa̠?d '$ u1['#tkGfoY>7f_9ay G\Hs髭]*{FgdVMZHcQ>)zha]wL,?2nb_q>۾v:O}\[v :}}9-------0$ugz͓cP<pͳy,})Oޏ{N0U`0=]<Nv RCL>02 JyM~"##Fu~X)q]l'7Y-(6 b2fb{k*uK,-咄<؈:Sf< K d vROSNuy6b4 o!HLypg}W3+]!/6t8޾~v2AʾL|ƚo`Lf8!ӵ#u+({6_lh@:G[,v!:!NV$%V 5k\O s0ܼllllllllllllaj_Wa bp$п@kBxu˼X|z\]Q*ﲫw޿i [*f d d d d d H.ɼO J':0M@QK_iX9B'?){j%!OTJr@>" |gZGX]+Wxqm]@6{BN&%3=]L=>wTߨ?fu+,)+qEPԛ+AYcrD l´芭VOa]26{!@˷~|ңl-Ϣ30tCANcLx[T|cyGc^f;ʙ yy6^iC/j}G8t44`>裣H_J81}QriljHqOzZ1S]8ӊXg*9b =#4Gf g/aMjflllllah6 ~Ð/7K,p"G-)󓴡rI*557V;t߃'ĦW aiz}NWs<[ [ [ [ [ [ [`,Rqr9.9]4Hx QJPM>/ugWzqK5=e3 hCn?J–/2{U96L`gM9B7{ Ԝq!)EuB|8@' [,O)߀UcW}RDYɻr\([y]g.zظSY7 \8T5"<+볼1t)bh/mϼlCE=:Bg#;{zfDe ̚?bQTmC?j`LFiJn$l^A؆"Qr}}) w6N#VMy-N-̑zF1I)[ [ [ [ [`Yo!E/xPN}!޾w! k%] *.vZsCpn!V:ГŢτ}B!zVIvYYn=# NҦ />[p !Wl|$Z2,%S@@@@@@ xbe&|><`ufmM=Wُ[ @N*ϔџv-} xq8xv^F#44ե z¤*/wxFHXpMIȴ>Ri.lC+n|ʧ / 6R 2䗀)(N!a ZieB  >JY!.-n2:rL(@Vd7 nf^$C@ԅ.:yyIgG7ø'S66go)R% m,#CDeۉ4 +_ϔLo6>ÝbxNIcg'X<@G><;u̥P/s]uiEYUx_>tmτꆢٕdi–G y5YIIp};iD* ؾa[mީm?zt+.١ !`K.$Lsn:uj8<Ўͳ2晠⹤ .h F甌nnur?zꩶj=sW|o FU ha1q7㜦C^IQxOwiߑONˑ()@xw?g< a!Oc̯.-d7--!|xܹ4/kJCoPYp`iy60R<+g eZmt\dN4|ŹרૢvPP}=H:ZYׁQ0zt*gࡒ佢ZsS3!szG*Èlx OV/@%Yh#d*l^U^iguMOz)*W\xlXyŠ hHdYeK;Ŭv(l6.(*{Rո>WMޏ-u6#"i͖i?,s;-S0ۉNw>\ԅPm`yl2zlуU:؎F"RV!,6E>83916RO9^ @9|3;/U" k<֩ ?FoQJn^f,(^i״)ʳߞs C:iENߧ$67FcRox?}s.zj5#Z 0J VS&(ԡ^!⋂/ǡ"Zmyҟ36º(2XrR\,zլKD"ṉEx«±S[CL'E.&nV<G]XseYFF_~@WյZ,ra=׿_װ{_Sz~?j>*au=3/(F&o}x㍭)lkaz׻Š+XAHcc~AS_ybsX|v }4ܗ™q)}ki_p#sݷ]s:?%҉ s|C@y6C-fׂs|un<_VΙknܝyY+%=A:-@#ſy5*HgT mXIkS6ɩMg'͜tjI WN #4 L}x|"*7pnJ0vB7!c1zaA/$/,}?fXa=a4M'$R-u⼱$`Y!z5lz) 7|O'd2PNuX# $US 6/#ز y3.)֗^}+WdUEr,Go G|gv:Dy[#N@cD>ROM>iƨϴe%L7N6O0^M*O{Vȳz'&@IDATOl1zdD 2{/ا8RDן&y:eH% :^hx|]G>DR4.i(>6-DX-:e1U-6$^m*2&C)WU[iI]M oW-grŗꕆkZnjT^{5ݦ{v~*3 7鄧l阱+}RW֭w"UI&0&ۄ¤*]{MVph8{PaRXpmߢ`8b}ب() ijNxMK.ÏNmTKC@GFtXhE_{ ?6"o]tQF;#l6.;cn<+4}^WH,\ih@4ZP9~ᇭz@aV;4Pw 6K/tn-L81I[o=ӏ>eНEf8:յR/܀JY6=Yg*X?o46;@po Zj)k;馛J[r{uPM VNi{'5;P7_|IM^Qoo58O:j1mA?O;/:a%Ұ;cl4p–, 0 SkƏom'`H|Kmf%>z|Ѝ7 .i#Zh@5mb߀;%1?]s=%BwBR/YgdwS n|_n f/쀮c]؀óc#S 8[qn U瓾gv6Kƭܑ>b^i/\o`p^?\_9kW€?S 8.dNSxS,FS}N肇>E>p^^rz| SdVooZ'<خ;,<,)tLFB QswgJAY|}H6yKָ*MhMWi]=z%DkٸIt ֠4l:XjLNEro٧WXcѭvP Â>pݍ{ S&>LjȻ%Kž('|,D`We^-čAvvfkWel3T9jKJ5܍I-u7q5o*[Mƽnӽ\;?tTtm}>KVg;SQǪ\gwۡ8͞o*ީ&0K _B6-7 aUB>?ϮdՕVлQužEa|]r,XKZ?.S fmfG}UNs}k Ƞ At/! !d1m4>e^}զ*` '*|@soVc7pړ,``,q0:i?6mA? ɵ]t,+E>'ӟ8weV p>:G޸q g#= :}s=k'eɯYl˩lt' vNHu ,\@җثh󩧞j.[l[m8%`2} lj}+g ׼JY6>oظ_wu@i|YgYP1ꫛl&?l@6D 8x[;lTwl 'y}6Q/qcA,ɌZl9昰+}tdYN gsϵ[om:>;x@q!uuwy'3S:g 1Y\tMmJuW]uU܂LlX7|S]u'8]/;gSL4}]^ןlRw97i`Wp-8[w|0.F:ba3_;~{3ồv;߷? >G?Qc-1#2Ǐo>^{=|7ًK:?*|-@5I*?F 2yf=oVoPZZky6,k G+ںxsɣpWYW]*.U6wޏ9 e0 ~yJ'%xO$&a7Yȋ2l0Zt1@Whm,abX+MUЧm6qkHӵG]!;a6D|Q [o .%61m mDB5FQ?0!u ZmdvqXE}ཌྷX7|l<𫺥y #2z Ӥ(|i>M/ גў."G֖0/`mB{М7&_fW6aт .XtG>RmsZ=y0gSmM; @x@]8y}DG4bW6(}ʕҀ@ܢ=￿ (`0N[S[̡:9]8nI`Bou|؝qI'd@w cueQ:>mm®Y3]EGv Wl6 64m.+qA],UƋ߈ee!c9|Œ<_<_g#Z߳Z o<_V}W?TqrȃuyVezUɨ/qv_-wǏQr=]pLAudSY|Yq҉`=YQ//EL(;g%n{, 6wzxQssRuBW_=3 ZK{L|9k|}=65BO*п?r{G,#F &]=Uɷ@nůS |Dd5Q^*8R2[ӝ zX# v6ǮV\eYx ҎEtP? }zf)Ɠt(c^c@{<m+ŭ]0r[mmW"BqKJ W!Gz5|kzg)8'd܂llll(S?wPrGDB+<ym}r!Dn"r9;Vߵ/{& )HNq@ RN[@n  D .%$@y5|P*+a@̔1&Yب#luLQeS ˉmdp;%g;̕,PqҙSg8nf= uWmK=$8}Ώ-}ܢ |Ppid^1^8lMq6B^;ORb4.YٖlN`;j8u9O9l^&hrӇؖMu;mЋM0|@Syu~7VCl^W'l"57ĦSu}A}׍[9':LǩTg!ȁFynvži>+DÌGmMP|X+Dp,[$ʺM )Tdm%iu9]O3F?內6'eD*X!CH{j^MrhsH18}}tWՋ џ,x=|=U?*NSGgNȚ6f ۄ 4;'SJurp8! 0s =f{ ?S?ls(q@Y@=lcf)TlJ 5QZzk &Sdd/v샸XN ޛO] `OKi&WsuSN֫֫" ?rO(aGr3|s宿 %b 6{"4<| S/m`wỽ]Vl䩌odQ(pUөeo4u33^>:7|>wn/T˲Ӣ g5jʶwsgۍ mӆ|+W(xqE&!) G^l&_ գ}%unj|݌|@@@@@\I蟮?@Na_p]z7`/Wַ;?Ww62=\.:0.Om@%%ZʳuӼ)Ї<6 +4Gs=ve8Nwq&ys=r:kjn;~n*:yڃ ޛΉwѮcfdp_$62ꣻSX|1\ĦhܸqOZg*#m+WwsS)e)ycsm Naouɳqg?O d!MozSn\nGSQ{+Н|WWǖnVs3;tk)YI"8!o'I&+V,KxXYwF9LuV|_ZxҴCgTÞv+7soοN;iʉX UgWF$2Y()Nc9ARK.F.H9;5!$fa:SlCB DTKya)hV#NU8ZWE?NUͪ^@崳AB{hW~/Mkמʣȥ#4"h(&t<}=ަ:qP?RG؁> |o ܦ:gSIS}~?݀Nvh+J}@4qԧtGCB8F.П h»7Z=D̚>'kxv± ፛}BfbqjUCxMH#Z/H)uPoݮYpdB87!<\*my֑mN<_oڬj4wU4[Ts:nUSz5Yf!x(8O.X8iGt+Xdm\cN\I1L> 0>  |4,#uyZŧRfs}Ŝ_P'snqw4& [`9I%IqCQdHGZOY}|cP-l' %?R yخWFȍԿO| Yi!ÜzÂܹ}(Y{<0b@.H]A7j7n%Y>r^أ ft"ףU>PZiNvx}8! ON6MTӬyi9zN]J8<}o$Éok$1.@n)QuYA|nbħ3wx\Y?A =-\U2]{`4>Q'x$FѢO;ϣrOxWqӸC K>@&9uSgl~NYƫ0y_*ؖEs9mz;ߩ?ut[Muv[?Mv{?zt:w֮?5T6VxzA'2 c5DD#ϜsUwJnOc~ N ]tu6Z7q+i 6ӍSzM˲gӍK[mRzǏ/x~/?I_»>%n|D秗Y0e|ր+p%(׮$ߊ?ZH]U?Jq).^woz -&O28t=- Ku3c% %@)JƢi /QP<2#′r pր|O~Yۦx%>S '\%oGH>/>$e:+^"GEM,WAQ胜 \* i/SiCOwy^LՃ+xFfh,cH 6:)St 9: PP$1dD9'e"[Q*Kx݌KZzWe0:9'eXo3iڶ9aGN焺uۗ-+i~"^'ld|u"ەOfl*gẶmR:-0[`m M,~s[aYm}^~s̩rve|/@y 6WdJ4CQP9kI]1zWZAC!|!|SEO Ox.;+ ~->޾oH2*y4p!,0@ lӌ<_7N}kIXGc]y|}L!$Ւ'qh7YIZtZe Ң J|t@1#n VV/^g#nC,Qs0=ă.o#4#?^rU)oRu>|+zHx燐6RzUĹ!%ےEŅ 䠻ӧ)pSMfW|,+< fV&z6[ʴ67>!?UzSy.|\"qAL|-ݡWxITcPw M><1t<01|D"ldY'EHmKSTe#1 pYd d d d d d d d d d d d d `G)q_:g/RY]RuSj ,<Eq-[elllllllyE^ G\ɓ2 kHK′|XM h-M8 6N_LF$@x$7zK>Dk _rfdFF'33ՅlbĽ,uq8Nt-k9 *ྵ:T6AMuY:){ŇoqLKuΊ\'DxGZDዼx( 6ˏi^%kCR?'ic LۘJ yƨ^fCh9}hX=\Ӯmi$8Q_nʳHCb*$0突5(}RDĻߦ+TՁugQrׄo\&[ [ [ [ [ [ [? cO{`B}z{]*4iMBzzEM-;jm8~Ư:)[ [ [ [ [ [ [`~@ j(j@uRבk\ ծ/kt=x픺| &Cu J0VAYy>Zz+tx]_q|'i+^o;_"Z:ӚDC "N۹:MS.}r_Η>RK:!k^s#:)[ [ [ [ [ [ [`8Xpˁ4@0p-NI9/,eT9/Vt*;9CʟAXN"UAyG@,xIySmH!+OS$[ٴLL. Q^!xqr rHxoz0Qף<2-ɖJAydrd(S[u^ɤO spRGSQDRGXؼ,%t9`N؅>7'x;uրm(7CpwUuzQ5Cq8mjWJ4QXZq,}Έ^|Ű1c:<^x{(P 'OkV㛺z!a5, ݦL ;N>LX_b%ĬK.),!tBx3e d d Z`!4I/ 6w?yvi|放ts /o Rkno@~] Չ} s7Ĝ#o0LN8Q?wN oll9h}8k#[SPL=>Q"up84`Ws^i {uE|Tl=m ~g Y|6tWƻ-KnSȦ ^R盝TYV6)e= ’HL!8nޕNc֕ >d_MxDHP"^3tbiʶ%LK1x=HsYCdw$T{E]7E,uC\d-qz>U5FP3[P';m)[ [ [ [ [`KZ|-Ik'D}Yo ~S]{>)O¯Ӗn ҫ7j!bEqJ/yr/-`5?3γ>ƍy_O,gJ_L$ "Rwv#_5yMm3 y ӟꫯn&;P,YgBG?Qm?& /0}?.,p Zmz\wu1 MG|KW_m`:~߅|aa,_~{UW[oq]vpGZ=gyf`@o|N;d?l~ǖ'=6 e`CssC䶤9IQ`Na]ZomyvS1gjc'ul;&=gNcЭys=o{m^6 )grH76L @I_ ^@^us=8b׳>D"e||-F5 _Q{ "SOZl`0g% CV?>OqS{z7~]Rr 1 'o~Zg d d d T-{S/*u%xUׇk?/vNo.H>'?Z-?p-}xX'Rb׆NC;Q͡O>Yd[x+ B,u]aE5cцӱ?/oy[r50{g}8,BOvx~6nr*|\r:1;?mc~̳-e,{^g_!okyFIo >sꩧڸvfcsF@@0@wnom7.i\P%-K/tB:i7":wy~~Oٔz6tͩjNo2 ;vO>idDY淀īea@_6͓ܚLPyLk78lT+MGίcq\듟k_}㫮eu8ޠ>{؜nY`K߸'xڃ}nNn llk.ճB%LR|I\c/dy?]uL"7UxL\aJ*4J<2hp\Sl ^7YEY^㙼.],OYX]'2AX!jxc; 1V&FftNO)K) zRo*Dysȼ ـ`:Gb^7ept9>x%,|`z.9;<O}=0TCI}> ƀ|o36<+l Ş# (My< p%2xry%,&x4UHO6'PHeIMfd d d d r,B8!"Byk |ws~E-_-YEs!]>~}X8B~~qm:7d8%_|_JLY; x'E;Nr"E0Nlq\`P,!+Dz[d{,uF|8d'Snr12+,>PƢ&'ZjvdSi,bi')~tSQIɢnyMDs9luۧr٘o|&={ 9 m`~G@~7_+*Wƿ o uf@_u1a<8\o}r,2|eU}{,0v! [jyؖS9Tr/4;gc`uRbA2^YŦMD}+ԁcՉX6pZF dz͸'D9)%G' 6i7pCw}mAʟt }k~k;}Gj܉ys~3{L6:[IlcR7AvgC7ncBC]țۄ^;v31oPChm?]vu>c#?Eڌ&N(;)[5Ճm*axʖ4>k >$1Ԅo:8~<~IsKpn!|!\y\ !p2I'85b/MZ1.,ڛ~ CQW>Ŋ} Cba,\c (GU`SN,tۢWH(Goy[$6 > 8:W+n馶0fmc!? _@$Dha,N6ۂj;qEO5踩`m56s7EC=NALN=\3@IDATla=,0]w5L0!p r,Az^G>XfX?^oc,p7㧮?y=}`t~!N׷#_,fS/~+51p/_N}t0Ѕ-2G"2 M|-z.NkyNP2]Ȍ(xfOo9by&O~YOL/뢬ҍW#?Grr{t̙cG}Dxclg49 !M<#;qoKʓ##2llH.Z!ִŕ䡋0GYt&QY&a4oXD胍b+4e෥S[2\ONߏ)|ͮqm&}_Mt|g%e:%8 1V C?6ӏUծ?鏔8 D{|Q{57nG}N6BK.Nܛ4ӷlrl`q|->wC<ʟ" ʌgl{PłnM*m؈v8b>^녗<{]vم$K!}&8udzIc7ӬOݳɾ 4BpE n EDQQ-Q5QI ט&Ƹ*/{n;w=,tݪ:uԩsO= fhP>PnR&|yOxf,b8L-*T5y{4|6vb,w ϚcN㘶q߱mRڛk4_0a$`7Yua5k=X`!m1fY;8]^Es08~v31^rYq~r/vwǴI;*̥1"%=+ue8E,K{N5X7o^Nư<y{ *(X$J)*$&c:56DQ9oC:.E7 0NiE7~@ʽg4UۛHI[ÏͧAH1ՆŦؽX\I1%<7Zm< l/O6hTU"QF0R!"i@BC;vxFQ|7{9bM'GqPF}:}!lp(G(sۼbo ʹ^߉AR/U4 j+@ #OSN{AʋN O(u+h.R9DP&3g9D}h8Aρ ~{ϼF]|כ|ڕVrvq?b|/$?y 釺'Ay:@ TD$4gV)٦z6g霞%N| =QRz4uvs|[OkO8Q־ɛؚovv+@'짿\Yϛ7솭e0pt@ "FL01bΉI@Ø ` x$ǚ{ 8n=B_M&;!ӌ]lD2lg{[?c#4e" 2'$#rLjr@?Tvr +25;}0YLF=q\gQBo;ry#_;7'@;M7e܎\oϷ);N>dxIGc&]yf|P]f]4b7|-;y|\> k^8 6v1.8Нb>#M\g#S> WzpT`&74u @"z,Z=t؉SO=^0XYb#:8&E7׸>(qEEN kGrfzֳ|5,c8'k1fax9),vm㘨Ӧ{@^ >P7dc<5l#3o,~*(XD7gց&>yŸ0&/ 璜*nV^]+Y4{wҀ#CibpCi,j<πAHl)_qb?bWT }5(AaoFޖ~= _F@E" b GcT_Mx_~xV{':adՌ˺^ ]3Gץ( ,>OKj6_RJ+A 3"3랴GͪݙMx Чޱ8~ T{Kit7vѿ~7tٹl,¬:dZl=>ʗ(Th\r0!h4 X̮x@ZvCPc HLd ")W=8IU>Lܩ?j>'Qk~߃<1s@,A|ڈ @m$|sdR1vRdR>Ģn&O9]MO~-=x;;*jƎw&v٩h"LC\XL0+/LJųm̱ W+W_?\]N-`"9>~@&wmb>|Ϝ K@N@繚$[Eglu_ϻE qܰ0^]/:}>t |s'@Jy8ߧ|989;m\cSvKχXw 7'W|\8sba&}nCv=v]>89voHmS5uoo- ^Y}dC[1sxAzԣiߴs[x 2~wX}d1(8m5N;~B+Gbf\ٟ/(X$ؑeEח~s>:\O2*s0Ž!( gu_敤|-GŁb Iv'&J 0L'@=,(zHH{Re*vЮ62Gv[!*JwIq]^},&8' ݏI슏yQ$c2'ܧM>d]҈OWq] CG:riΤ۪݆룰Σ3dC(p9m= aO,x>nymGOL3<Ȑ\,xyLZ/'~G>z׿aFOnC[sӱꇭouve:/;ߩo._ Asy祇G Q'շ;F0gb0Jrj=3{Kܗ|\_#G i.]4P];g=9^u t[67R_3h8Ysf9K=pXa~„5kPY2Ĥ &c @3m1rL& (&[0B6;@K&*c[?i`{nO'6 nWNMBx q!ڞضe;L*ɟڞ-<`W^_|6i[Gm.Ggs`!@?Ю7X.?i}gQxbrׇ@Ajeqp ^ {)+T7@iṿVP2eR3Krv#]K$AY;y|CyM5)a(.qt#^opݗ4+O1geÝrc~RBÁbA,}-dWG>v}DzXJ:IUM  ;*f:o./('$7U 1xC%_ h9׼= Ru'}g )~(ϺDT9ƒOUWgCU'?.B.Ss,ruru?C}z!d6j^~Ur<c Gwgbq>2iM&},o'2IS_mM?wf_ B'u|Թ; b 螯-кKhƟm.2iښ߷hʑos&ۦv43jl@7CҤl iRhPGh.cҴВ\ߵmem7':; 6tf[B|V{٩Bd.ܙg4a|k/Eفiۣ8ӳ+qkgO)/(X$Ti##9 : 0Kp rH"  y^ectrR/7"}T4;0FtM8`g>@{l@W֌ ^ov'T,~Ej1{DU2:b:dz*Ð3(~ gu?:^$ݞץi7>ߍ.,hzMlѦi]"$m` ρOm!JN{қݤmx  Ӧ+ԟuOxU/"_/vqt+:d۬tV>>o3Hqnw atP|O`T7ud[j3=̋AiTk%ԲB{xWk_=b[@n&Ö3:kC}\a?%DZivP@^pN(v1<0,B2X H hKNKp7PЖtgzR}B(I\n]^B޷@J{H(vI*쪓U9Y_@Q>H |>@I  6SqQ~Kl_Nqn;"]qxT;iTNiʂ M"a>GsL>ixަbe= x?*~\IAG(L:9y_#!]1[u#3OwP5ovfAIQOR./]NX&||NÜс4/cS<qj0КWUE{=N l.~1+^#:36,`qL41^H/a?]q/`W*!b:BD\6w v S+pR(} }/fZ{gQu(t댅^D4Sٕt3sTM%>vVq e> ʧ뉪?B;ԉD55!2QOm6xHN@P>r?:*^>>]ȟ lTQZN誃;FQ7 st[H\l#-}k{zNg>i`3KkRz&|bim|SZj@8 hLJ̰|/OM]'2壟UAuyds)^iɄp=Q`ϙwԠgc )1c!6rPĩW!LNuiGG_G뤅:)6>(93Z1T^gvyA(.Ґۭ8ʜءQRUT.BP4Y]fռmʓY>tF@i8GY0|yZDʄneܖm!8WCto~m)jW\q*G^ʴwA7q;}pw<DwV?0(mn^Jl̲x2;;Xvi?s]|rI3XigC;Swއ.(((((((-i|JӶJU]e1J{iUϴ gl[/,}e b:Nߩ[MC<3zvG3=zlBEcjcLQߢFQ2%mR[idҽ֍c3 c @v~LO~w% `cO t]oV9 uU E2ԃU!D% Qs#m%x=U|,()28IYIG̟?!Er~LcL B~Ru))ݵҗ⁻.{]bw@@@@@@xi&D5ѥsOtF!{\?AKiT``b=9hH-H.#펓cjM;vx z 28FvO dGuj8m=P؆S*K.f@1VNGpt,INOv/R\41=#/bN>tzuR> / "-dҿQ7ŴQtۘ@1̓ ~>oYՖ|G jxsWAE/Ī +m䇮lSrd]^k$ħ!b 'SS<.%ůqWj]ѝx8=dJ26BJґT:k%ǂ<7P\X^wuTlR%*(((((((M2Ҿ\#6<5^X%+V*?rQJz8'1 Ճv>;zـז J}]yߤS6ۦI]a e9_Z'hSOb;ۧo)GqFԋ>,GO 킊i!p=fk\GK&9^._ QL!ۜ|Q7btBGFKR;N%-QmU4x{]EP)6e\yh4u2)},׹KRy_Kz4 K!ŎqMjWc,xb}N+||ޒOuUew[oGUCC v=o]v˴MHϴ,PZGO|0Em/Zl cLI.M`u\.Jb%=`w 3~b8lTGnC~ߨ ;uGu^^`LQBa8T==iI{Hy+ /.Hp%6HBGy3" u4e!Cy2LNIO}S }}؎Μڣۥhul^ʢ t9EۋP:rYxyn둮\ 4`T%y-SK>Q-urLi= M5Q&*BĤxkeA}T$T@`{9y0UhelH^;T4?dŀj֬췕Cj@;$ ]CZ75f7+?48X.`^]ŖSYbU}W]KNy>O | tcO]v]"QZOaWȐ4Iic:/x}G(zIw8c<lpn*=Uӳ1ρU6!t9/A{ _m (}>ɘqV4+z1 >( ^W[1ezfu^ -9J=UH;tl4u;H_BGQNgJOu9{o˥KLkWZ= 3sZS lќW?>@E YjB>l+9Zfd4+Uj7M;L,塰K:F|i mID:)Oݘχ N]t>YB+p|My(H/^XTٸ/}:O;{$=m#]S;7H讚!<@ov{UbAr^qCqSrE\r'nRDsFv(s4jz?k~lG gBnވCg#FG-FNHS)2$Mz\xa1궲Y6$~ij!eQ[LӒHI҉⁽>̪d3)401-J*(((((((MpPly:a (Sb(GaKCG~CټG{mhǖ gGpݫd*:IFuHF۲W:ѣnۥ}∛(' S?&*2ϒKOFLn*){}A"%2g!6"e[m&m4ÿ<^_7ȰB솟D;KHG:o /WV9 :KK-b;]=+ݯouנr2('鼞U5yh@8A@>_&'NwشNo{?YjjaGԗ$>+}mٙ\SA/l+mD88_Mn?B齀 y`Jh~nBWnF~9蠃l```&DKZAa9xTDLp*(((((((<~U^<@ <Ԙ@ƆAgvk'5K]]ЁJ}m8qR+G:Ay.*!]ŸJs[7 {}^[ȏWc\lxl 6hY=Ȇ[Uy[**{ p/O>vV5\e$[cCPmכ#;9Xu%|gƵBΧo*dII4LTuMUrۅRmv3<;BJuKN# :u *y@OdN?/ۑt᝗nS4[4m)neI,YsjemVcZ (Æy׷)M?Wy'ϲYHi'_̈x|'aNnf 3/{̑f=l22̎>|kGݾߨ}W^쉏6;yMUǙ}*nK<Xޯ;Jg϶:k6nhjC׼57u{-XWP*f"؎] Hӹ] L)j~Ngr>\4$6UU}I#OM:K9ɣˁn-@-;ݑsg<;LZWr<;O(O];у )A7c7mPg^mX00o_Ϗo'*c׿fA7*~щ=zf3A]^y%·y*a;>EOh~0\h'D[wϺ{ MOﰞ~-aw7J/镀>CےxWϭS!^3Pwy*a+D&dI@{~GYuV싴Nj>4)u Ny>7n3IO|a[/,E0S3=b@~fo? ϩYͨwoJ~~+av-c€'>lD-Zy|~h="1ַeGq{6md/| wwmddwd>c>+lÆ K:r7㫷;<}'>׿ގ;8og?kxZV\i~5.˿G=Qv{m;üի_\s't6VqLƋ]7َ=Xf/~qmާܧ,x+_ik<կ~駟l.^*⁽9h Lhhw bM4'N/T<x-b|j-o׼fؔO}SvM7蜘S'Q?;Jڂ=ծ]Z@@@gܜNLB}StSK4P:\༾9{voxNo;'M t9o2a7o[$n1ۤcשlDٌqߤiG%G )s sJPJ'f]vyQaxF@:~LsF 0՜)NY@#e-I':JRG J#LjMI6 f#n*_@u? ~>},pT~'^jϻk(|~kTAs)Ӛ;u[d@9_p 4yEHl4o.uvCe"tեQ"GDQL,ST\S mEzR藏9bD-gLЙazKzȄ9&!DFm/Q/ٔj+7G٬?Ȋd7DVV%pzfOzfv??1s^hK>U7;AfW^] \؉O`f$9GՀ++` wLﷻn^W ^>q2X>3 {;) _ opP>m4#wd)?y/??ګ^*{^ӳF n~}>)b/v}t: .>0&,`|>z}??wnw (^{mG+q@@@@Ec+'N Mi $N0b<#d%Η'B]y;ܧ;cC[=ծ6[ xxx`wz`+TkhǴCzvV12al_lU|t]wfn&7 ]V]=)Pi9a4d%`p> č.t?dE=Txw]<1UH{BFtɞ~q!We#&}^xEc}<7\_Jϕר.d&M&ҝbd"SIT\.|C&C2ۺIOy%w}\W~?1;Y;OH11k7;H[l{#O}ڪo7gАuQvA9`Y|##/A{v3=P/~?7og?پ_ͽ}1 #&P8 }uʁxg~#ߥ}{c.mү??ro}+Ůa{wLʳnh'xw%|~y>x#/@IDATo q.efh|@@@wz4YHlٲ81SL zvpq.>{ۉI]|"Hư,e|'ᔤ 2 W,e tp:lwlIs`ڏ f1 -$5c83^ơNI?s*drκDt]$rui@{įN)' 2vaǘs |_&`{?0k(^&{~/Q4϶N)Z)}%x^1>-:xc*2P/_E:NI_6t,JoRL {LB>U>xn␉~F\t=z|uyĔ'%-fotj3dR4%ٺQ$Zu*tF Yr&Ь ?G>o7;2%w|ҷ_Dtj@VTڥ0?3;t [G\!K9ĄgǀAP|~ғcBȆ=q>|7ӥ^Lr>5΋.<@ B׾5/{vb رi1I qdj 9w&ganm~di6R}E⁽||6NyG &p؈~NjR]M/(((`3v'ڥ~4:g, l{@aň @:BMצh-(UzH .ߢ[uYHgg: @ĘS Ɯޫ".ɑ$[3HU %0URT{Riˇl@ yfktg`}037s~Oհ~ߩ * Ƿ) ֭Ad5|i?@=-<cq~FlW?qJCjCz^mĞGmL1M䔗ς/:M`N2gXZY-9g=W)΋4znUY u[3ިK<ґӍ*d{(1=^xO`~ӟ2) .y&;s]LvL2I >&9=e}{oV^N@f@8ď~}5'G@<&Y rHGr0?9|>9<'{|&]xxxxx.U;~/S{(8d0yE:bQ`ܲ7?CX|DEq*~ߥK'E"pԯ~+_6GO=T?10̛ns=,J%7p>Yӱq*ĩP,f\q1D{AQtޙg^q;3X(0¾lSf~`OLXȂ"M>xUɝ'5*@I1q!;G5g֓5 nwʯPN찏5@(JI%RQe<,=r5It_q>m!9dhnREcS]Ed~:j%IT Yx˾T}&t ;},sQE r)&B'>Q 퀁^;Trӑ-z/ZpyVn`jTazt  |EN+k)?#?_wK=~oWep@l{j*u ˆ0B#Gߠ[czmE:2{-vE'6=HvJlq~dr~ F{#L3bAv79/~"#rWihs%d/+Tߕj`ßVe?_~6;Ifg3Y?|ߵŎ,v+Uӟ=`]mL mLtIyʢr\rk ?Oٕn>& +|no|E~f'y]'0 x!&rQ.{]|{OLsXq= 8,_LOLok `qY9G\.?yq ? e~ = aM} {1N;mSj<އ\軳^†TN;1:&P  8 g|MlXcPm% &;c҇8YrK <)ېnL!jȺSnO\{DF:Ì>#0+׭rhGEj6 Kr]y~AH"5yQ⧨P}Q?CoŢ&;ܧ*&s,vA;RڅР-ؔVuFt4Q= :O+p{! NG"<%9.^kjS| ;<>g _NϤzҜ,G/=ўT% T]:uh-ĩe7:LԁKT]fE?T?7tQ&Oa>:,)>/bbF:rsJhۑlܓ8 :s}/S^xxxxx`y/sά:UO}*wf/y ^Y}U~5בflJ1CE;]-oyKq;`pT/GBCOB%X ^`|Qyƅ8R k_Zߑߘ|=묳u6E!;>ȈO" <}A䱡&~<ۛ15>R&cp.T }`,D!}lJW庇{R<1'?u˝ϸN-[{k^;{XrW0fcH=^1"J^C?]m?v>|c3NQq'1m eY`闿eubK-(([9TP'28"X#>r&yキ+;\( +ڋ2(\:K!BWse[vn}cB>.uG2lʽ,w3%ĩKu̞|Qn?eձ67fˎK֮3{ I}*p &9q/79 4l:yD;J;˦ܵExxxx`z|dF>ìN=qB3"OLt#<Gmv˟')f1.Sx_ P '>ؗSRI Lkw{t!|!ng4XeQ7gEQPLC&9/Jϧm29-<5Iycy!x/It[?˯m E>(xWb?P󜢸(yj_6Gn>2wGI_'|t7nv4n-ng<UgkuCO]aY[O-D6Lo⋦E[EzZu7goSOzC'VNj!Q޿"[aZpؕ)m>1뜋5.Ю`}jlO`2xE0Jd:Jw G28I"_ubbMt;JhZ)I k[$H`~XBn_&_ʮz)d n;'}O{^~?"' ІT8h~CQEL) .6ڵoof]v]yR wBUy ^~> IuoT",F{|p9g`@\noTL|ȿZ`!:٠O-3mMz]d=3HUo6 6퓆OjϬ< xS^y'&mϡ9co\۔i|-sySiLDHuLx5됼2r(dy2މ;$CtVp?xˉ:- Xzְt_0WSޜeW$ԣ.<ҵJU[>`J16 _0,rm좁ЩSH.5^?þ q&nd@%qJEHBȆ:|:"]+BйDӾDzSQ>&ka [avN&4YWT=JIS z֓fkxٓc^Y+vK.d[ 6d Gb}ٛ_b2[[w_$3O7Hub4o^mGُ~fʷWmX aϚ#+pZ>U= WW "9v *;x@|Wi?6T1 nj]}UqRJ[ҙr.;P,a@+NdL5)ּf[$)'`')GCtU"|x[#)8 :7 vOD](H[J&~gaƦlI:AX6czrqmdБ$a0)3geLb$Y|>׏Ps8l[R޳@=>#Gv?n}wSfi}> ء 3jo^#v˨2NH6>N}'߉q;#Ug>&+>4L?]F@U݃GpZQn?mB'V"/T3 NbOmH dA [nMK+_u?KoOiwf};T1Q3{~~|=B`|D6(^/iT=om');}4]2M̭5~ʃɼk]dS[ӧh7>}3:f*((((((pSrTN>SZ}A&ul7TE"]{l :I8nDD7MVv&|,<_.55U8xJyHy=Ghͻ3zawe!ǹ|>jjqؚ >:ju^|_斎:pezm@>I׿JWOcrSz}Fz^ygu9U4G8$@|!dV;UFq_v!/>[nu"k@Möv󰍎KVz9y iUq*2}lxFrYl)Eَf_rTkǥN_wxxx`o_avQUo޷?fx-ǎ2:5\vcI-/;3df~Jvc~[綈:PUn${`ޡR3VM`hz/5&p8*PrK3XuDGؗ8^L^cPSJ)i02袬.5}O%#0ӁvS9CllͧNU0>6^4hV[{#)٤)wvZ|ǓG|(}p1zз nGǕ|Cr,7?>@PGgDt >c?J CE O^'T 7Jo ɣJʺ}Wj0>fpqNi{O E(\>P&&bbrŀdaHecHw>]~8|0orNܟF[AiY=mbʱ1f>ey#LN!T/;[Ulv2]uU̞s;Wscccя~N=T;cݫYY ,3ݲeˢ.׿nOzғ,Fw|&j_ovu4mݺuvg7u[g?~_~YZ&|2S#R|&@l۫nhx@Q^We }m@0IWـ^,O@3fNG߮cox)=C6{ a"v.YA1e)C5>$Ԇ~@xӞrw? ]sTߟqYʏ9TviD Ijcg)yiek! 9&T˩N')wݺnE'7W3e!`BwJLY?y)(YvOL iUs'^UR]~$f3}bz?3"T-KN~|סwvWi^dv~r֝_#fGNQjJLrkH{"=Aߘ]( "]Hrp`:Ȟ'O~NE{E/z]ֆQ6:&B#ZWE$~v{A:-b;U@ӲelJ= 뮻Ї.Ǝ2}NA6= pmW+ejwQFՠ΋@7)}4U$.1EH*aS .+((ث< &Pw*0}{.1{5Մr~tk/#C2{{z&F?Y`O_.$~}g?پ]q @1d@z?kvuS{:0m-7|?O>6o9 ء_A}KM7}?C믷</-h 'c'wqvGt4d<ӟSt|tlv&`":ߜ ~#ca;797/۱Z}mp _n>~z@իfyh3S=b!5F7FFFKM#76mpz?Y} 6`zǵrN:!}5\^u/-u-~͟/ظlذjׇ<+\q;9_B7 6N8B@>?}{önڞg<_k9>&>w1l6񜣛>x#|n@W yKE(oF?7x>'gbeџ~bGk!>|Ɖ!{ m \g}|vm [k)`q32*"P\Ph}qfe޺Uq#c;qĉȬEDuJKf]G>Q,8u/tG=V?Q5OL?WgR>1iVܲytz|hNO'&ĤlJ0ַIsm z1(*KU;Xrʳ,2b!I.'+ G !蜃uM&EbO.-owzLNtMe eƠzx^7 5IlWz;CPG,iO>y/u*@ne(}XaCbTG@ahqɟd[6 8 8 As"ԆհBI$h&5jĺhu[( ؤoQ~#r aTzёG,0vzwknBd_>:Ұ\}5(qK[Oևe?X|1~uh6VYU2>hۜ8e~̳ Wqأv _gPҴe>D_B~7N^-x־{>/Э\3&$ lO' S:W"jiT=rk|3>J;[3 4x>Ъ|O[M@p:ѩZf3ΈhһJ%9t'mw:z0v\^WuPUksY]uVVW.V[͞x돟k ,@~Wx͝ő] a}B.,v#Z_N4Yf.N *TH9 w:_vea]w]8cPBDI @Vb@NUsL'?i豃`JvNNnx8@UQg.z'LB_/ _ $Ծ |gU'zJt[cs%?lހ,8 MWb%٧?_f}cLh`su[|l\! {}6+G> c#~uZ\tE,#`4v 0} tO>ԧl<Oc:~ݴ6_YLX>`cjժU'3[}x!Q#C,vW:~Zb{~>D[V83wO|o9rPt&鞠<ez6=ý=S&@K[dzVOu2. ag}SS-|wT< Opy\Jg=]n?e8hw:$-|bR>1i!gBNw-ԩ族w-񷀿 ĤfmӔOLjLk:[$Ta]5nRr3>'pA]u ^\t.#X(0NLȥi6WC i,2~QD\/ gȝV*ߎ-JR--4#Wma1^(74ȚMrTyEOc+90;^lL_5Vyrk='l|,$I'ۄ/' ؟L4<3F<:ѷx ,C:]V?S:x4#ŭ c|V1o(]6@ap%fwcR# C w0'ye#-amS(N{MZ9iPBσ~"WvqoN+*&`:Fe \z-ߚ!kh¤҇N nUC$m3m/bSצ)7)2+ib]45˼ھyqgR.wJոg[ <Q<ոE=&Csb~sc“H\] +!Mu(}UQ|ykׇpw~%D/+~;5Gh؏گiB`!%av0:߉2!p衇xw+M:0_~^:P~fr 0O}SW\bĎV&I} 8/m @ eWZe1vS@" q p oNr&ʂ@Evb;%&S$-k_rFUPG; l E/| &}<9>ttk <=m8@Y}(\z饖΂ q@nWlB Sh߽G_W~fښښE .b'S$8Vg[&W_W  7bBmubwI_=78~h*'-l|Vx``@kJu 6{o}?t=zj]9=l&YDއv3f"׼wv3x.~(t$ {:ԙ>3|w:q[w@N fMr.v9x{;axf;c =D,p|z֕Fy jO<d)'6g0nKu5XL>1)+ xd|bR>1)g>1i XuJ]'&vybR;<y@q2^/;na z3 =WdkbO Ļ;Kq.-:j)dVyLuƇ1y䗲{zMe>#n >5~?@W[tFO \rVדG+@^kzIτS} 0AȪ#wJÞfBn\]LQلtcH,6imSLʲC_TE憗=V$}s=b;t H&(XerLX!~lNoߧ]r&|sh0}=@{è(;۵rbL~7㴤vHåJ`&; [-c"wD3H:27#[ [ [ [@: u^jW)y@w[0/?K4E*u)oφ𪗄vHpqG ]b%}v+]l@@ ;qxxacM)F~} 跦qY'ζOvfs?czЉm]GNh/c}.ŧ-|N}@ c Afu&=AI:H8i. s ȭ<<|qjw6Y'l>r aCe1i4㛆w3?8ߍt+ ߒ}j@aH~6ǥx *^G`m't7Gi(Y~l6L_I)˝cL9Z-ao#ESrCauaN ,e}ݑYQ6mx(j\[\G2SVw7"i&N=DƑcy4'-3 /y޽0y,+zîKʝ {Ss塧Oߑg%caCKsK|d|SE^Ċ$ҒO\Omg f+Kj0z;;7=~{/):hT߫ߑ]c\1=OK4KG=bSDlҎ!9 4㗮ejh4(7#[ [ [ [nn3u\~:o}0?R]92\yup=&йC_[q;m9 ;{p[zu>Z(MyvJT6&.u2us8ɳk{800a{f*6ΑN8΀b3)͂lƢǟ mۖ]x3Lq5<tUdHsd3=OmnOR<ؖ [@b=mTk.؀;]O.4[5ٖzorjRǂC2^{\xvs2;wgK=OySʺ|,~O>?r3n|$=Tu{|8!F)Mr#Z9SpPj5U~Vc'y';2\v_aSOc, } ӝzdVNFx~c#QWVg&l'*9ޔsfkswieB.aI,sԟ>M j'~n3lĤ|bFxOL'&ZĤZ-Tx߯;.Tg4˶ĉI%P>U#s4+C)w#x@ UbM8)W}[ UvJe>KS+6Hv=J!R]Z%.3bx^?>e|-tA2p h!|'R3:ʔO5腽M?rxDZikp=jFAnx}os|o5m˻&ŽZvﶴ/젩q~SWlv_q{~PX39-1%)nҰ?59g|3J?3OυAD~.1K$@c g>w^ШmT aΗMϚG6c1[icz'}HZ5o[t._---p- t[G!8 x1|:ꨣ 4Pz7/XfTNmvbBcə(<M)Ї6 #9&;ˮiS/8R2@SN1yf>?>uq4>`# i2/$8tJB7ɀcB@}twB~j[yE>ǘc `gQrʰN;s=NH:C77[u[/IE&Ӷrt7'p>^r>f<ٖ { /4~tիWۉ B[ᶯXpq_qǸ؉ q0 11E; _oGPu;Y~7݇uuZʾЏe:n9}n?\>$ij+C$/yqq!eݟM9N:Wןa6,:s'|:V@<fRڊAG㖲qޗ_~}"bfZHC],ށ/xg [N6_~dN BNҮэCᶉd.^myOL'&1zx@$3Cߑ3MQIĤĤuKԑ.{9rC! |[Q6Xx\ZY t&?uTlI+{FjmJ Dxt161" Ԏi6nOr-$y0JZϨ#~7|zP:%x҄Q&y^`j6IiUO`s~)$Kkv c{'MxzEkْpc.zt"XF+*.nd{_zk((x2[gnZlo~oq/>>;236|vk3#Ýz -ձ=k`ɂ2@+s}Sj>oܙd8[~a&e d d d ܽ,Wl4 }!G0uYK)wTMh9keTG*zVIx؝j0]W9C*gaqvA]/xf*r!@J{v\`7$)Et0؄=zm ;j[H㻪 tu @t&Nn[ڕҋ_b^*+7.\K[uzz:I ;9:S9Xz_O(ͫ-}gxqO3fU 0gqMj}v[y}u>|/zыt/0W*?wA,d u6O+T {jѦNgAu2)ݸE>6lCMuݟ,<7\.g]z3Kh!㠮?)SGu㐴lBzz?ɫKcci|[ =Džb>>R-<.~ffw" #;nɳW]xlNjlꬖɶϩ=2x {\sŶzk袋l&__ԑgsM:g[?8>㝍Mj1v99.Mfuc<=ɠucjkND4,4b@Ԥ>bfVT~-.cbE/5~EM!, o_ǝZ!rg+BgCC-!|.` c dI>1)OL/ҿcƢ|b XN/'&3|bR7pv޷>>Inp@U0Xw氿Tn@1+Ȁ\ՅLs vz~ 8M "f,z>S"\GMu?c!^s~6(Ieiv{}ac!#|v"k[Y6|( yƯL{&LF,hefBdXosPj+o:HuVǺtúMkօ{.[*Zחq<=^?6n޸!ܤeI]iτ&{H}>"7re?.ŭo/ 9A[;I<q+Ā^AmPό%Y${tv386'z>ߧAslu0 >)Gی?&Iӂ~iņ8wj<IžyvS {;xx4=- s>n.k~sv`d ⏖kз.f$m8aq44˶KOyfҧMR۰Yz#g$L\HEJX4Sf+"S,ͳWk˙ʛΛ[a"MI:q:y=65Oӫ:1cL*z:31y.ӑ1oe|^zpuRSs̻;9Fjä&[췭& aҎpfaK$}!!^xdrA1|_}>d53\;8M/*L #(]ur ~|p#32ԩ3;Q>;%gCx_eQ|h2BfaC݉IMT[ NLS?~dD?1Z~s~`Â)NX81O瞍Uvt塚p{Y]nuՕ4D[9\9lE23مЮ6_ICu fM;$Nae:>3ɛk~SOt ^T;cvmFI׮?g+{l2[=iӦi'&4mYD<1h@ק꽍ŕzлZ?8rXl,^^(߼tלss%`n^=یan`w"PdpBHZ0&67;ܔO:g6ėt@)-^P{(g>v!]l4j< mퟆY[ Eʊ WymDg:*u#NROqRN#Ɍb-gZ)5YSI$>SQ43͎߼HW݀:bUYA3Y_G[!J;Y'<6,7a)BxBE&l2E|R7 g94MXHosOLjJ@sn6uzy;ʁۙ{WI~.wsض ;mlw>ڈ]VBdz_7V'&d4{U{ % /HQ#lsԓó6A|b>@/r)`B<7򩔥Q:9 Uf5^k\*`p ɕf`- $Ra(6t^4R/ |}-_r wv@6: NͶ!CfIT,r[Sg6mغ%=v#}]^<-}3f-&%`}r }yvxgo_n0BZD341FK*3ݷI/vƳ{]U:uL}]xQ|Gt@M;a#HA9WO4I_3J~,W}좐TR9(䢏q)ēW451% 0%&WNr,rZ~î|25pG FtY/MO˦uR޺m98f<;耩lcRCWGzU]h\~j4\o#H`jalɝsN9 E6XFmMˢ}8$j7-p#BnŤ7\˞W܋~bf*uڣ8b~h?dt'Vex@@@@@@l-~?s 㘜Ց6SVCH;?JbPε扗^}L>Y!<v;^ ӏ//Į޿vAvMk5Sy9(,pA&&c;Ƣ?۶[YgUSr9.Їj.Az/4slg7am@1+o\0zo&|>gl)x OWx潿;Jq9e.oFJˤ>?ٔ{jI!+b"EE mEAd⋘w".Sw$"/u$Ǩ1Oz]O;,"++F2JOb(|Dy'~=KW%UG[4_:V=E( tn2,*Iu!>qJSG( dH pjߠU3kC]MnvKd~kKQtcרpNKq%=y~TN7_"pXeƵxgBrJ#ԫfYLޥ4S|Y0Gq] .B铴~]ǵk}B'4H[cArU:š_-_ icHO2uR$䱤v*QK)\t6hSea}ȝI>316ϵ|؜< 0:q0R[M\uԡ4Gmm4M@kD5pood/xjzG>`-\}˩Q?Ykvpr\5LM?O֮Ѭn1&D߸8ʵUJe d d d d d d ̳xWHP &:pZs;85 _H;%:^VYt'>B |QKMx)/l eU07NYcʼ],45vtۼ|[{j 4&&(2<,PZFϔα]\,Dыw8{TPlo$Y:;=bD6tI̊LяHv2['#ޥl+VTyZ,o! Q¥)4DnM)a~Peĩ"!I󾠟S>ŇNb:չ->|dFBX'GÍ6\ X?w7S/v4$1voVu֢/7{W|6I_b?m?!FFa7x68GJr[}:}OJ>!$~Bn'=G3 eQ5v3S:3gHL|oa|E4 !cѶxrGǧ0M g _ M ԗ k#Z%&bm? /о; 5gUh׿F9mm>9mA?'?ɭ3|M7tN~흰Comi~;Kﵦyk^vm_-nݺ{6@|S;ԑ"I?- :9o ev]( #Uk@lLnPca>#xX?fa3n!rՌM:u`XN:C =֛EC,^RR>fg/ +* ),qD22e d d d d -K=xizLJ,@®ځuh]xq_߮࿏o} .L)N)xHڟ_W>*26r{nmZ" oN)A/7|sl .LGydxôpc$O,n 5Llxwi'gߧs컨~Ã; o;\ya= N9唰;rs|# _{r ~ɏB ׽u"+—pij|4ܫ*`G8vmnpWX90?я/%/yUt?o _WLߢ}_q{uﵱOO/ h&BKCxB 9"fm޴xϳxYɾ'."T51NysZn?!:#ظLѓ!wld9Qy/cZk QF]=!~ƥU '$gR29ң`ҫCbX]ڱѰN?nDt4hW|ڂ/d{!Y2ɵ׵.p mҥa&y1~_ g<#,_4o}{p{o|x կ~e;|7x׽As?q`/ރ 崆T|n ]  ] DZ{gZ 7/<E[C]PNL~G=Qky?̆qvyX郏~/}ۿycSNv;we''ӟco|w4z E^fw#7,(,@<8__{]5 4v)2;cʗiOSHg}yꩧ%:|gO~bN"q}.wnܴ ~̽BlKI'dZOߐwQG#Ȥ_WjaW}{c|}ݽr--p7Gj ]]6e4|g#r̫ӔYC~Yi1,,chr!36[xo϶J]8]f["X_|)xoT+W ωI}ww#:]pN~鄝8w];~Ns<э]~k1N]7j$:nY޿x㽘w;㝛_lX}E'7S@B[IX}&o[Zy[8]L*A7*D9-ITMVolcTl)żRDI)yRO\xŞo$D;v]]o+M u e TxӸB,#Y;v@rAm145lye~l' MMem^vFE>ʤIyow>JX-7>{ pLiyodOτR?zÈQ<;8_H?9ۏIƐ6F kiE= چcbKW%ʤTy3M1E:aM[-ͭX5*}^ׇz_?}&PEʎU)އ]L*?brƒl(1ީTv~C20L0IOZ! ~6i/MY&7iK5\c[lLd1)䫯XhD6O|Bfc0z}Ӥ o]Lq8Nvq_tEf;ovXl63Yw5wy6.r4`O] 8φַeŘdt}ml `f3s]':ف`L{O3ΰ}֗ϔc2qDŽd;!d^~-v! [T7e9ci,>i"Ɲ3dp/GmHJ!ؗ>lD}Bs b p  ^B po3 ;Q~J"k zֳ_ʟ[zܥL[Bk~M4}NLY-L'&ŧ27՗o㥲H[f抬-L Ȼ}E$=^wַ|UwANw5޽y .݉w~;MOOkꪫ׾5[ &b<;ͼC;,]o; !~˂mdƉ2o,Fɔ--,+ j攦y~kPv{{{{NeN2 $q8[>ǥ~~0#omre#o]o~_d 4 ,,;-@l,opl?!^wVneeKSiuhÉS[ g )%>aeO@j׫ȝ*pvs3&RO ڥ sl>voQ憵LǗnӰb\ҴQ7t) 1noeItuy·^4z塃 acĔw t-ǓJDq?GQmd0"Spj,w^}fOmtklMK^27~Z}Qs[!ܪҷd5FmFkMadž5FqҙǨd6AoUhWbmX*&+},OeߊJzR8-r)[ [ [ [ [`XcQ>o!7Cß?*/L@+]L tW #w@593BOBxǦ8W, /p+&8ƚI?>\zz/ h`*dW;&a?IO">|#ã׿&Y}&ގdN(g;S vr7 ZʾcN>yLbO h;N*8蠃̦Mol1c;Z\&s[xg6z;afu9;Uԧ>5^&'>utSOv0;zx≶ ]\L :_WájYLyv[)G'Ewq3>.rLn#ӉEۑO`3ɮ%w5+s?8b $5 bP=1B>masx }L39 G,:4t.}I:/';Y טDvƉc}> 3XĽG<6Зؐ} xHd d d d 2T?x a&b%'&x_'&fznln~79{||wTO fF!oE  `E c){lgid|XyVo5sKc{ nnC#Y]a2v+F1cc_—A荒h0쵚藿"xs}vk~R:!ܹVgPGSYD𣟅$d'-) {q0t[ࢃʩ hvj 0'8w°8|=smG O2 (`s&Bg@es3Lfщ2:Uۉ\mMt@=cʕ+MDz|>7<;74 h_LQb_ƎyτhS)=Nc=ұvqs:  X8C`{4E.|O~rӉ/>c{"Na`{؅>؈v8Naʽ|2h ޟs $ XÉ ՝ܫܛ+ wD/nPEPUz cX"=~@@1)T9-MY@J0@-Y_oX&OSS]o7](wL 43JiPG Ωk,:ҲI F;^8ڨ|ABe=qJʻXdD) 㻍3_w[ҕ)`uH~|F]alP>:lSd#.#ug^1k7'vRVԇP%nb[x̶ `[F'1q'FT{^Yn4Ô~T 'ɬN~J6zIf|~>L 膡vpvۯѮ{C;߬ C7Z*woQٿէTnZ)ܴp_7n^'ymaT+kN|' v.pjGabR7Ɏj{ ؚo8 ]Ȇ:&6kV#Ǐu1)uڟԇ؜~D{*3 3O_obv׼5&X ؝ T'< @=]2m6)vN;4c =ýc;3GٯZʎIG/vW 2gWncqI|c},cŸ'SB ~@?q- K̗ll@3{*boT>1՘ B38] I'n;OL'&=Qr^p ׎Zq=)r{Bx 4",(렠ŕ2{#NE\s2GZv;E 7Q?/@MAVu:Ҷ]}'?پkc#07ujc@|W7Y=_lT!Te4sygm>9ꨣm9>`L-oO{Nڨ!{wϳoC+O@Og1 8$l^t1D= k8O8Xz;ξX瞣8S#Б#FXxQ7Ă@EtsƘ/o"g2iҰg=Y~8zDF+|x$T'YAW"Uĸy]\k>dajG)BXۋ`>¤# ~'Lf5UA +<pDYO^?%FxS.q*9nkblw2=HbcCw [$I|YJr]VREI7攡6b~e$˸4ψvuq&2Pe(}"!|^ucE/z|)QS^LD;^YчA'X֌g&䡪 I 2e d ,fxIwN^J,jޏ iyR  ޙÉIOzғlqm8}l"ޱIĤnz:^?|bR>1)9-U-xW.}rr]m7i~SLrlpfsE۵L Tu9+2Zǰ"+G8ƍ1 ӏ)Sa+UA-)&nc\yȂ J֝ 8}\~}&v@ 4_X4=*7!PuAc;>Q rjZ=t6K [g8.}b/"srrViTxҳ-ui"E/w T㴂xv&:)'O/]ڈv^ EiBΪnMR&.k[gҷFvpE]*ZQ-0n:774دӱir8[ [ [ [xVWOIߑx_-ҿ31 ,OL*N(Hmû$&$l;I][Ӻzql~pnaWv-:2N蜢YJ20<""2̏xȢA7u"-{zOQ<xϷYX.{ b;0*!@r[~kM(z >habQ Ձ~嘯rF^HFکɍ, KBȢ}_ʇd#B!KT/:n.Hbn>q{Ir<+u 'lbHvs  *OXof ETr+]ϼWl0~WLQ4^q6ʩatrԋȩnU\ǓՅ= r=>jCi{Z^"ۑo+p&-ѭd/4G3HߘF#3]59&eMV5i|S}mK:+˄@Gꋶ¡$2U}:YuZ:ZnءNJ:*dyH73β.׳Vƶ˘ ~-M0V.85GN­IΟm̟------,Bү&Hz}g@?=jp;ou~_Vp.Z݉IN$ҫIr  Ĥv@;<ɐ3.\n];ɫDZ/yU-|ʠvrTB-^OW7Nޚq)Ec݉IT,t8ݢ˺اLa$dg)&l-c׳az&`mDh^ &8]7p @)AH7P `Ki & rEzZGsq^˸4v {{srlmL]N^lFFm1#+W8ڌYdq%x|E^2Sy&.򤍷TNq74ʱ6H5v% nƏ,9o鄌(Q1"4-Ŝ<(1U:ၷ~_T5buluuU˥N˓q1tdW2 ”wf Aw@'߻g2ފ)aNpDMʟe$~W֨zب1Q;ydpdޒ^=w$ENYt!Kult OT6 W99&!^I#➖=4eY^5Ni]YHd d d d d d d d d d d d d d d d lhUgZ7p== zr@:+IԵu$*1Yǟ P-3:Φ?Qg&[#}6m/Nu'&WOd9}wDp֢0?&lcmW9@< *JQ"2p_)ElL N3O;ʴ)6˧ycBmYJkt0̤URlG:90j6W)7V]t-:$G2LKuP]rf >yBMNX ʱ‰(*AX-@9y8I?qD!#gϋoK HiO؛P2䌇%6{wpGϬ>eG=' \To߸W=Z>GO1N@~ȨT>LQJ;PbCss{G8묳Wh--pcm{v *08QdGQ#"P#)OAdJpƓ21$zKJ.qK9QQ: Fic,#vK_Xtە!;K4It*r"1 >Y=) hɩvb [qm""hז2n$߃no8S,S:.I2>ytS/To K/~-aN?V?:k~T2|i^u3>(/Љsb7BձϾKI^ܻ̔m[}SFF@~(zfaɧ;ʚ# + 20 JYLdKN%`R',#X  ݑ 'h|-H[D;V@z6%pNT<Ңx :$(V[fG'=nu r|F]ܢ|F aT_}i;"S䶬{;,vr4lfp^G.B g#X#?u}Cs^eqS>^d\u\/\ԅ1jhfR$Z!JYꖳ-'^)ܫM>}I=+)s X5# rx,**&՟kgL~fw&%E$S$C1h-|5r3]l6bvYwBҶ{9ӌ2QT[N~olxZt LnD_d0xX2)xωQJg=uv 䟜ֆ|) HnuBɷ<.@7()R xolKүwQC]w%Z#Ou\6Yw BIo1[tΑllllllliSvB㳑^x_sP} xhb dJ)ʙB^I^ӒzL!5qŰ.X ]6@Pl7A?C1?b)bރcy V'9NzNb^=>302r]DC":u^N;\| QVnm(ñl FEZ⪰O&a{&&hNSlگZ"˧ Usx4̗և%rO^V? SDϨw,Akݽa_>U"NK <1SwBNZ PI*ȮENxR-MFzZM]K{٦4kVf5ij K5kxiGqI~@@@@@@@@h5_ i(SچׁM"ݽ=,CåL˙ #ڮ4VIh/Y[A7_Lˌ~YU/U®{%z50# "3:z4nOD\Tq"G9=% ·V.%L>jRn+ x *Z+^w_x=Dq)2)`}нIېxto}sZN+J +vŻ /̭XI?M|jbWv#hRc L[n!1uݮWqiC~ uLŘ>wp|k2|OR o|ZA[@`¦Z}Jz.6@vL຤~؀: dC_FA, ϴ[|jJ#1P.c&-c$zzyhr >up$m Oy};߲ ۟ON=ݾvk]t~]e d d d d d d d d d d d =, ~ѱ ݀L(gVm-( }]lv|DJ0|rH&{S1:WVlE ,".Am9h1 (ya~ J)N搭z#V[xz<(ʕG{m.D)/aˊzXq%h¶BAՏ}^dzd!È!O vw^F F+(c~"yJ+Ru[kujV]7M#|b3눺~+L. 2^[ =GUyQ/|۽$~aIMl/g¯g _sl"I&C&\!}Ya*dQb#OH"98g s6a-----pi{YV` w<(&tUwR1uSwcf1~|.%8p.*i^gcvz]< M.؀ŬV!ii46ɑmGtR۵<[PBC;kJOMdI#_ٱ/aߕ~a|&5q7k~e2ni2`zޓ)[ [ [ [ [ [ [ [`X 0,x3 y8p yydB!'%.TVʩBҝ TR>Ub=iyQI@h!K@BMDb$ ( E( ҋ@)(MzSH"-;&>{sݷܽw|nߙygٝ,-.ON;"<,O/82H#m<1&)V>*#7~ʡA~ ߢL܅-6ta0f)y#:dY;X:z-#+ xaDC>d/I:q1Ɍ{S)i@ ׾gkпh\\sJ'kFk/=G+}e,-$fP C#wyS%S T;%fr}ɧɉ[ Li`{*c{A|u2_ OHHHHHHr 8 x_]El*y\+\eωL'/]:6egkȧlم>z 7moa!z)[3ex`3å#Qr_V6--hU QI~1>dlӮL+beռ4 2:Vu*Zmh~/$?Y vځ]-E4e| az;Fr]Fg? il!y]0@|g'ep>}u~`'GYX˩W`*^@@@@d+촅ǘmD|LP7cl`"k"B#NQ~ yO"Ľ^uW tȞ?YnlE^z9RotO;4裏EYDƌ#gqz''O_3묳ʏc1bs92`;߶]kv N=Twev[]̠^.2_zo뮻N^|Ep egtoLqN:t[h,saHjhu]w/Kb-d?9cbl&>gumvnl,f茎Qq,`1 % $ $ $ Lyr34u^6Qv'黅$z̍7K&p {>la,i}&ely>V]xw?7ui?lQg;s\ދWdȠ:7Y^60Ǹ m'7)z_`EX:pR+y.셽4]&-'n-`hG :vzu *knm n|E[څ-e!),,׶/ӟLާM^asq 2wdһ鮗>U*}5?&0tfe ;~|Z2]B^C&mO++a7X۴1yidb0Ŀp[t?Ի: s;l*_n;Tg]$nemJ@Cg:y0{o(Z"_XY䴋A#ׅo%2,"Y|Quof|Fd(;hC>vMص[ʠAl|'EYtE妛n2Оwe Кgy~2믷i?3l^6Lآ"ԏt$w}(/a~!R2`;y+e ᜢ*!9~#'ȼkj4Mww}vyr@/ 'W aDdddd Nt ul@zvTp2Vu% ^ |mwo3p?G GmqYQk;s^fɋ_*|ca/7ay^.u|'j$Ӊ:n4}WµNa iLU!ϭ2>ЁOD^Nmo^^Tddddϱ* "<0 2ÑZϊlnN}8}xՍ["NƁЛ:9餓N2Zh!!= /)!Y jUh#Eo|_.sh BOڢMl 6dKhkN:CE1Q>> Xcﶱ:9*tgQ%o|6ֻ+l,ؖzc,U[l?^^z%\r-ge ?PfNobL}Azy|rZk-w=́kv2Gq_U#ͼAfJ!w#"sA n=uw,Sfx[Bt5\׉Nb}S)˃υiz?BSqr ~cF'9;E~W'_G̎?ـڛc麟8@s?_gZd56=IlD'&7nM {&0}#ǎkEilxNAl_~lWP$&moqct2:cBOͪ5vTyK̭'+,l ";|I-',~_|E[$ȩHs}b㏷O3t>{'`믿n}*OS<5?O\BsIGq-|8qva2l0󳈀I#I#k>7Ăſ/kE) |K٘C1,zg'=~'5wyvj-AU,O;CNw)D^ y:~-7DiQ v]yY@1km.irq({>ʸRӄ2Ww'#䙠:Fui:.O0Ϣ i/ԝNciG\)Q:Js}QE  o4'%?/,cn# L0@8-%^F~,8Ù2%ؽuqz|?9C>]Vm9NzUۇ-] %Y wrȱe -}Oi|36tMm9:,2 <;Vz뭰 iɓr7z2/:=?M @!]{p1;h;NtƳ&DÃ[a (Ge`xq!KV.ro9y~iT%dz;Hli[zurյKxQyV4aD9iBrē6&O7{Nyr}Y~9_ՒA s ,,,O w^v$s)&+`~M%ۡ]~Ip?\!q/L|綌M_0&5;Bɷ&e:4GUM_w KHHH-PntlC'5lO 0Y9 Etr;8%Uu\.l)ʩU<4pe ӋgNdNE[Ω;r}.ibҨ #3䳼yY܇0}bD{ % $ $ $ $ |,ӂ?+8\eOOHHHhxnsO?ZD1vإWzVp^Ɣ:8 Ru2?y4rOHMn;=#Lcfx}*ЦPRVjxQ@'+#sXMӑmpd꽑)ḙ%¦A/le+,?Z]*Mg9<_ 0wi㊴'+1ݫZx!']\. ~1]vYӇII1|4U".)O|iX`_ZFm'p~0TDvyg/ B:I z4yCۅɟ,,,,z j*-A1(#{(H&ێwI1P.ژ@=A_#Ѝpr# ٍޛGӒyX~%~;C=eV{~,T ă8 ]a_z3.\0~yW4ʧ=?_ Ý!{ XuVyyk׿xy\W1J3}ˁ y\vzwa5i\,p hOuDKr5KW= /2q{}ٽzX ?Kn^y=#=UWALE𭙘F+L͘{O^ VJ`wzeiLYv(7$_xͧ:quUvyUܔ,c(c޻n C ZAUCӁ~Ϫ,ƒ>~=0nE?j(m tvŃKt;CWmroWۜ89ĝ,,,,,,Ы,g~h@PvHw?ǵY#7^5Mn_N"+-#C?RtU]"'&Ǟ.GEm߉\{K{l};Rw҉_/©J?g4}Eeu._VdD~zf61|W^/п՞:.B؃t|㠙AĢ5|^:s6f9V\۱c=n?嵰v+b@l q G:,o/߸~ x]=Y0PǨq7e ?]! '+"/C5v,O02hޞE t 5IvQ7^}.] 2=-1M!*MX^84}QtOx[_mSodulƲ#/0/h yz0l1;tʝP_CX>E7```ݲ|z^EK_Ga= C7s?pcyڝP4/˔)h2 C'DVYjE|/X`mb.hE~IF@@@@,Њ[Le7Mj)xPqQc\b7Jx g'Ox:F@=-d~I  N0щq(|}U6 + $8c4ML=s-UJ./kyNԅS"'1i:Z  \'\VcҺKCw]M?WK=HZl j$/^N&B_ֆ"N{Z| /\EnL'G(~ i!K!{:{ivaeZel}grWtwӎ:&@{O4c[`>z.D>Y Y Y Yy |RUvQRܚ3 S w<u$DeayT7^ ]t,hfpjȏ0aȋÌ0m~]C[+2;]Z|(Ey|r x-{*i˹@oq n(+?`׉L 0O?x.:|근9{& $ $ |-pD_,3Vd>aܨqȦ>]5;VXe)lxlY&Q/Y Y Y Y Y Y YXpdڻ])QOnz1,,,,,,,PQx宁Hh;f];o @wVHgXucyciqr~{!(ρx ;p_wȄ,d0ek|7AVz,$+9e2P.s)z흅fn7\} el>.v*Jfvia.F_)HsY{ 9ӓYTO lȈE3cZO;Rdv"Co]3֝`"-,rgr#WȾ}ziwXcV|[䛺H`uۭy_wxlRNW/\uUv!CdmO_ \q+Əzge]ѥW_}5\Ģ:u/ / vᝒ5#$Ɩ^{q]/dvv[+C={%ѣeĈX?WqV>A-rq;m;(wwhO4SW?y~k2z婧20  H1ٷ[o?y[zz|u T8[}a W,Rj :0.4,lT>O<񄬽M(C!xiٷI1JPLuYeyW+54l<]AB[mLh],g׿o~0]W~xWb x~]mLUgu,?ʰJ:i!2yP}ɧ:a8`JO:o|/zr\!(~2gP?ݫk L#Nǃ\vA`G OubkYM\O{ X/YWS2#tЙ83* *vrOXjo_ℌ^[.eI3Qˉeؽ*QRzAf7/~n"އrPF; 5ʗ,,,yV)_޳݈ß/abl  ȳ>+#G_9c=;M >^[V^yea',"$@ @62\pA5OxC=x mc"/Dd;D9\B K,a6I*kU}ֳgV=ї}> l#Xٰolmz~^}Uk%&cРAO;ghPmȘK~xFOo3|̘1rWZk5'8 4RN򙾟%z:^9}z ЂqAůl'> ޓ.xr>njۏ?)ʝ ^y(.MV'7a= /һ42<,t3>xM_?)65UmB2JCKe\UT&.GeȮ+ L QUz }vzX*ga 3(##l֊BUzh-R^^WL2>Qm$]Y~Feepߐu‚2>l: )+~ALf닼^Þcxc̯Gȃx\E"sD]3$3"Eg56j"Ide7@XԳ.ܝ\|0H$$hs@z@"v:r%K xzisi87 KeP?Ao .rxXlx=\{ d  1+9fyu15I HIY[k1.nA׿(J<~Pî޿/E((ߚkξ,6l-83“' 3@gi$-yoƶFwoQ۾v OʮV@lS}˪c)'l,5jSN`ccSO= ؕEϔ Ağpi+XGvqyްsmY_lHH,ݶlxig'q}>pmYU%?@b l{R?; '}RW~x~̠~&Lm 뮻}[؀<ȥ_~,ϋ.p@2ӆh;U+qYruיHlXֆh+UT?i'rg*O>Q,Y^VX!ԿY}_0O†k=x'mg9ϭ2L?s3ezz9EI+{P?i;9KO}֞/PYY͡?2^,a16ȳr/E׫_U_F.8l5|h㢻z0nZz΍w5b6gn]3n0^R=i#'4^:6K6f#Bӟ ̲q xT\jPc6>we.b*8`,{A}W𹷲):nTV .ߴ˛\Z{ȓr@VND]nﰞ\OwC04P. |z=tK /򥮭nuGm[{.,}{j ق\&7%#cv!@΍^ڎC7smwSF]n'l8*ҟyNJfz{-4pA? i?-|"%Km3$N[p98U@6.71`cm5P?;k%@HPHw1;X 0Gs~_4 yБ_W ~W*ݖ([ ]@Lvs>;Z>v?=OYr}o@U4^t>|SRN@XXx&cqe43%_~ٕE,`W(He2(w]C@mgg^{e2Ya[@hf!u뮻Mj@;S@].[" @G+@[{YlZQ{ߞk `hF'v;a+_ԦBRoe|<Lm\\maw$s=fka 6l3_P}kc>UW7ew?K>8zh]ɮZH =n[PnJf1R=xO aIX(m~SE>t!oYgY@N Lg9mp gVh,V .-ݲ4(ld'N~hLӭ69hчiD6]Wm S.C?sꑺ?cã~ٜ逛w-C Sx^WwDeNa'8yǏ\xeiП.R7/3#yOoe:Ƴ1e| [2Ŏ-\{l\&a©U53}6iOP,muz;CݶӊrwfD:ucתO/'ɣz}򵚟λ5,|Iú1Np*kuG2ׁ^ q_%.'plT&Q\i Egrupȗ4)x.XO.tPY4LNeMo,{v2kzj(ruq1/xֈy!k>w!_׭6A{nOxBz_q8e^f3P8S \wȺk(^JԄN !1y|?t!Z"g@<ϥljcg+RLzEEn;;|7J?` ف P?;}-NPC-ą!*ـ/jOt,+~@̐ dD^SqY;}Bc )GfL*3}م pȗay\mK= $}Ώ-}RtnFl (M[ldpb+6ȅM)WX@U2y,Z}3莭A'9Na+6ɟI#\oKb[Q0;PB/\d_> fI8HeQfCWէȁFo}B,~'aUhN-}ꀟ4V.Rb:xoɛ\F?Wlj*Kº^ߡ qbU]dYɏhI=$qv=gU)c24ɒѽi-ꍥ2MOO4 RQވrCV'l{@ԎƋ)X27,?!lPaEV[;EhӅ7^w] v (e&Q̤\#V1gOڢLS&'.gC#yM#lI I;3mOP*4^fqg_ag?uwIc=]K#G9ƙ!v?׀BPp&N nrdA oTvG''2^(Z=ү3Rw/2ç^SObMREq_zEdgR\n"ꞅ0S `2;{n‰{ rypjЁ.Y<yl>>Xg0rb؄>x"\l>^~y &'@: |xP ,dhgj"љߌyc/dzܼg3 :9PVlXf[tG?8`?wĉM<vb'paU;~hEr yټ ?a,nK DZȉUuxsS%Wm彼ZA]1`ы/-a+ٰ}:rϻӁ Oy/Ǟr_I쌭c.yW++A QSaY,ӻ>Az>ug!: 8mB}?N6BhȦ=R&#bݺ /? h6'M(+yn>TnDg'O V=ї}>y\b*2olZ yKeMiuGm}I[mC\3E~z=xcƌq.m>ٳjd_,djx/ 02o1?s o\gI`T/նUq| 5>X'x\,6!]p칌&Ve'zY9ȧO4e-@z&83.ԇ&X l@!8LagxTh&^0a2￿ '>9FyI(&ةIygfbI^d:e!%dy6A жL^r5-9Db"mhذavk*BnMuQvObWmH13M8;SqL0qav*zZ҅m\f[ (@>TVs=WG=z؀tMmm1DR-Ov$tG$z7΀Q& &V wBB`'.>CD5G3zOݲr lU'_>|.<ЏeBIr\;x|3ݟ} ʓrs~FB,U9N2WVءBoc9ƒ1 HЬDy{}HCY}UWp+fo=zU!&-!/@\sw&lb_3Θ[wT ׅKx/@OGĤv4ϐɚtG=tԁ"?;K6}7AdMh{>Uٟ"SU^Q=(J}o{T G@}+T8ʨQ]B8\'6{<97c|Dg, VL;9),Tȋ^\wưnC_l=ڼc(*Bq1f荭XX 9|f Co iF۳P08dĢ _-0e BO!m<왉<;)=[hg .?K` x@ %:c ~1~#vxYؓx;OP&>TEv)} 6RVt[mgvçx^!IcA 1-ScY'>Q,Y^Vǘ,nV1-b'2L: gmOGEcv>`+uSyva7\,@G *=yNxy|SWO΅3K3{]TS;vOj4gK)9Ǜ}e8 P2u]@nmׯB="\?-^VFu*/{XnxG2´QT< `nAT銴Z'}@m;h"K?.~d0Ty&+wiqeDӫ_wΪ=+4p.[ԐXq0/:Exz zWkM,,,,,,0#[I>ub’ bIPvV@L38-p/ëd{yw_cgB1I$.` >'lD"92D>LP0qr!tvaAHe@|O&砓N:@vqYcޙA^mIjgŸI&a9qV_ nVe;Н:Œ^S賈(Y= Mȳ}ZGqDZ}[{ꆺE -xa&<݆Um*Ʉ4vrI>Y+ϰ-!ʆ$MC˜\mBx؟䕅¶XS>-{7Nq'qMY6((?ٵu٤%%CzaO!}[٤E|S~%B,c.C>J`wB#J4!@s&1ﲘx| @ +M"-|Sټ ׉HDxr {f<( rRx$rp-#y6aW@{^@ݚ)`\x)Mq(-J d3~!kYIOӏ/O~|P^2{Uٕ͏ɒ*9(W#o mpvDzKt`N p98Uv]! P .d"m@PY(tnq*ᒏSYg'lc9?g }leq'[r}϶=OB~q$AS8D=IOk4ۆ\v=qѣmsH)^lTON5à)q>v q튦I0|00[z\x=x\x"^oP>/?m%SNo]iS\헣ཌྷ%_ ;#)a\!d{nV+#e'L>:'磨f{ 5-N6&&0Əjm˫I=NH;,곹z7{R{ԏef$ "+1H<3A{ tݭ i2jʤWE.RwA4Y"&pI>]t?t!V!K#1GDN;-DF뢁vcwvtWͿ,dAv:6zb'|*QN{v7*Х#?!@9,K8/sHfv zn&lϱBF9ԩ8݃#a';Y!XXox">-eW6lc# #͑΀? pȷ?!'NTq m,ƶ3H M<-``䓷)I2l;Nq}ǂP /|װaLי.z`7?}jӄ.mۭtŐ^/?)ϕW^i/k.'vk] 4§PE(<8MIh;q98 h kH`y\gUyxO y$̮GZ V?)󏶀.-6 wɠBޟei\n>Mؖ8S>x:ao ޙ~yЎ ޡfryru<-" Yܨݰ]dl*TVzeW.*Kpp2쮓ޙ\PeH`F shW[VkG@IDAT)TOVU|u! Gw6b=ힶ/woa}){\c͈  vp]|8;#o*[9|cz+NYsL;]OjiiKp"W7yY\Dv߿@x,VemaYL:;h1xoFCBEpNGq562vTı|ZN7ÎNxle4Gs=߄ @ޣG6l 2D=X;!^h 7:(}iӿ-3mݜ`qav*zZ҅m\f[v ."mw+裏cܸq`B@;q'|ҎgY>vv[0Wò<ntx{RZDvkĉVo>f9sgtFh+oC$.lч2gUES(̆'vhЛCs%5+Qn)nPVe3w|x6{%mK.O$!.Bbt5X{ m&8{/g̭QLJ zyHnvk( QU cg,.>} St~sPpqoY_|kQ Q F| RGz_^|:K-xcָ63>g5vI#725@+dTٕN:Z~vq:{Ep  egkBvo/@'KX0tI !>?a`6zBP A{ ,&bkY\̋~ AȘ޽Q9l6P=P ꕩzd=c M% iFvGx$Az%M_UG؁: k<7Z-*ZY*lR_3 `بD=X]Q(s鯋B.]|)8U_\u8s@2.ss?E1E-Oĥܗ^si2$4s9.4tRxS}L~yC.~\MAPC^Y&nd1iz"'0,΋{%o¹;,Qg7l1ݫL_7åSG[Ȣ]2y)q8ޏ yF9sk(]*71Ɍy{X\v7Ch_|sJxY//.R]~y{߇n rxƐky[!Q@@@@@/OX+Z߹s:kv^u&O9tD&\.GۧY{U(}u&t]0c{DN I]d%A3,/ciYcuwߔuGđ,0[`&Ǐi5zeɶ xyᇗG>2 +sA;4_@=a:]I .xX$SG~|eU2)^A i<ʯ .A r|:3 V/OASpY{;1VZϸť,Dž_,qvlg#wnr=5LX?mSء'اfC ;0Ujj{r7oy ;UYSVU4KXlgԐi\IT5#Ǻ?{gwt%f3!AR(/*ފ[5U yzEPE!Ĭ1V C俾u9>>Ϙ>Ϲ{Z{{stV.+SƧ8yT뷡~d|Pu,sCYvqU婃Cԧ*O}Bٝ韢8aQ9㒊6Ǹ~woD^POt~ӭ~u䛐b"+ Hv#oȉUdf7ƍsl}ݩ?|0atk+q$v\tENO?]`;aʾr?wxNYuUeg߈$߈ .tI7Uy.$,(g4?ԅDzTmb⃣XKtM). D"@D "hbS׎1GS5`kߑGviC p!iV:32-)aFY,d5L @d~tȔ2i|z`%N &g xZik2y9`嗷cI8qf8=xଯ F_US}2馛Z0p1EmqzחO?v9!d09##xh;qc=-1&~v ?CdSq1C?zɃ| 7.C>Nevc 8Md[M7 1z6N=8bXeaK.?O_n3cXϱv^c8ĉ<ކ|~VyY?OO>_0 ?!./X`[RBe o;E:F0lcD~&(D !+|-DY?6o 5Pn[ʋy"@D "0hVl VA>eSt sڅ6NpFO5CWaiJy"Q5y\M T))8&vIuj=d@u,|'ؑ_ k-e]]9H89v~СyXذvۙ||eX` յ^+#FoYgeFڲ^lq-h;nXԞ-Y/a~G7is.No;ٙc)v2 ]ݐByb#,BƆdРAv"E7~N o!X.ԛrчF2VX@9,h0`_r%Cq{?A$*'mOc"a3YW7/gX" 5XNs=-? 09_YA~ڑzsR>{YŢ'"qkD[vtuF$f!C.?rSdc=~HZH]8yȓ󬯧6JS*cxNl2TW{}=y`yW>gVXSzF~="1ާ }a]짞zv%yG1a:M58AlW+I&0YtU6E'  駌4%0dQ,atS^^0z1nB'#6da-c8Sѽ~!+ƃ)2>.k6G7"Bj:ӿA_qڹ4)/\f,qc3A.$6%2JR*=lz{ 皼Tα4%`<:0<%F}v^o߄K|vi+\^%MuyBv˧ڟA?BlCn4FUD"3%O?мVr|>GCDKE#D|&{e`dRP^xU",ٔdR7 ~ykI'E6\O$'tws;1sT>ON0qtv#1ylCV hy&8f|ǛV~|u'1tbF&< L,G~C2[#&0"Fy\ MalN'{QN]19}9yݘ(#kb[ wvcf;=G:AH:uk/;!}5cNN}B.}<"ˎ ӦϮ}!=r-Lڍ,~qֶ#tA#DSOڊL0N0lֶx<p y{mByN=G 'A>, #=~Hgpc~,:3]'0ӖۏLq; ֈ4g}Џlv1xrK맍nO/r"k"Kv/3/z+ȧj(Fn$.OȑpҢOX"wMvc?|5+`Ӆg(m%NPif>GN1c"Mw_SbI9dSO=U +RpbAfUy3n^NG,&e.>&5clj\cX'W\a/ƻ'yB24ЇE2cE;, G~X>yS'}1c, 9"^a|ˉk0v, Ӕ!YP@Y bH@3hNߙѼڂT8u/ nFk8"pY| f|L|PQ7;.`#_vupH#u-_eGk>&Ҷo q+7,?rLV#dI˪ {9.a Cņ6`\X@D "b:Yd#}ʤ7p RWP9rtO>vqAt27?,`y5JZhnǍbXfCcLH1!1Ɋq .fw:fUٷ9eN.L,Q&A&4@S~G6yd%rOaוW^io>|!/bt)82YdvCzaKװzY1Z sb"A􍲉LHvJwٙD"E;U(RLB|^] T&'>!F &R1cC7M6h#t}xv<uQV?>e@}Is[m-HF!z9N 膟>=s#RD "$za׋(۳ϚT⌉X}v]9㒊 ݄݁.wM"u|va,窌ӓȀ* _xbPY(yf<{w/x#6Na/g, >³=c$q,]brG,=5VoGp:'#';8Sԭi |{CmqK`kK?'c="d0s= 'Q1v?3m,,8 [ _Ee{l,`񣏧=؊vgAj;m(Wojǜ>1zh7|c;+,D"C9YWzof4e̅!NT>}F$i)#GDZ/7!Dʯ)[IeW%` qb^^t+w~ow~iV_w{x [\B6rp̙yFUa6Z WzŚD"̊y B}>0G#spd?W eCI( Lq1G&0r):nAϷO:$'PL0) ~O>&Jb 2dR =gM6ox[$qeaX,*@FLvSlb6~&ّjȏgg5Gg&,wygb-lc&Oa+DmaŒL߽?QQ}jkZ8|!2I$SԎ{dOKx饗fy#X;E<_=X]g&)kapa\BANJ}-;1G+(/d"\mՄ]r#C yaJhSF|&9 |)eޭޏ|s=8p`3t>|xfL~j̆c1Tf'/g}dfLB:ױ.vZ!z6mXc I{ 1pÌoړ14KQϘzp~ ƍghCǰL?dQ, /.M1#ԾC5Crq/Po yԧzsԟO=3&qUHܷ,2cډ1!.2>rqY`;ωFKz-+q2}7eCe Lv^>V~y<cb?FDRygd 2`1qEg \-_fTAPxPnkyХ٤2JJuvE=#>R#m.y[g~?5i ?kL'wa3W\&iY\G(3L*D"F]{ԇ #gN 08&0&0??L 3G:,@o32yE#Kvy'__Y$v_qsr.[ EqXDZ`.}Gy&w&ZBv |ٸBf%0*#I;jyǏX˻ l!k`09묳l7|#DN#ZpΧhpӍ%)N~h_Nb Ydq~ UO!/еx0@-$-tGc"b'GVCH1 \~5j}rXD2` ܹi $wX$bb= 6X8 b! ˢ_@g*W}=wr!viG>b{MpD@rΰP}If<<gaC5F1D/l.XnkUi"^Vag|<;1sCCS8adzKp EH7d;2ɍC 'y^s>9 g=@t*"㰿;O:z2;H6qH0" ԡ0es:.;9]bs,8`!:uHJ:&gZ?z!3v8cԡ$b ҹ;.|N&`qXG -G.}ʏӇ÷ @}E] .c_pvc_/(Dێݩ'mE]]g .c>&}ePGdIY6<'rr?`igBbA ]XmEzѽBXtvcGwtO[r2)b&\T@WA 8&-} wi4qxm}X!-$KKud";jwY:?򤦸'"u#upk]]oìFoH]QU xyL>r2@5&:v0dWsPejV>vqd?4›Qr^'! ,>Ϝ+#pVmUFu }(=S( Bm;@-KזVT4b\D "t]pUf,'"B?_[9Bu;:Oz=sA<%D< a#_ +tƜ_9?,"MO8i:d˯%Gp=$'cQč&:° РO:Cq .fw:y?J=̏ٵ.xi'0I v2٩Ν3.f:Çg /.K7#Nv&K޲CzaKwa8 _~v|!CLDu ivXco|1c|V0o|>>3nv/ &z8 3t$ F._;؁28 >-.w_P@y`9a>D*1󙀐 l L5O>/?Gu-&}Ku]'DYtPyAw='x~(,ύH@!ZB:Fa'iF>W*_Yz,s'o2QXd<1rUDEY` F菣?ƛCR }pQa+eB T0iR\KOeWbk26Lg ueߓL KzUra!_ArZ"NiZ:8Q^mC^ yd OtF`/++'edj8igzqS7͔/(lX:dh~4Sg To4nVm Ҡ R0K%U^Aa{~.O]!&mPYKVo|D٦PZ;J2>U TYTz05zT;n?/t| :5lZE۳T>ri@D "D"c2WS}66gbqŷ ISD,2Pw/ȓUOVVG@Jd{Hj7?,^I2!a ' \⅏sF_ xrק T8K.DN:$\>3sWۑDqeO>d3uٵaEdMoxգ1NWFd̢da=3-/FZA6`?NxvVC~<;C;l`vXFI}ja+niS>-^gd 8'08sBԑ =.`P{=v9`0"g Z#g nyэ>  (l`w:zpоNylYXb#EʩvwqO/i O1;]'\GO/NLc|>Mnvavzep'2W\a E\,C|ѽi'A\8Dg<¥. ?@ZFpTQzѰ>,.'x 1gDB-" S>+BvM#jQCGׇ2IzxjU7Lx +ׇ |>F6~t8E1U~^}t dz"]y.J<_$f\oMMQ-\е"v| Y~Q_bUKC֟]6if:me,vvg0֪k™ߞ:UGk8ŒM{nٲQ-DŽr^E{kOS1RT*L~SQuyZjǷLo7f_OvSv)mBEy`֓/3 ]5-r$ߟYυzp3,9rd;Iὑg.WчКrb8"hzt>Xo6ظ~pVi:s6/sz>?ǩ])>GeB?c:y:}}nGN군#bB3NCu#u^$QutsaPUfOrZVѕ Gv% `VD&(F\=y$k_LnG<՘?y|Z_+(2}Һy|!FnWBXBig7=vh>.+KP+-.Qv鏳;^n( CTO]3aDH"pA u~{c<.q~y8\nO rxcHy~+r\nYYR=O ?V)#GW ︐jE!0mAZD:,vǓ˰xBYę@Eu-,D" ?+RD "0"X/o(#ccœ͟\J6vS4vhqC0H~L7ncϴ^HUف9oj_5~>F7Q@WpB_0K:C,)tBCB? kY?/pV9!'&i~[dtu +˱ |3띟N?L8[FZ ":&@D{ `@j#DQ!F"@D "qdKٴv۸+RD "D"@ c1KAfFrFh 6G1֛horz\es7FeZ0R/X / 8 ;/<_TUա3(g:P`oX]4#X)|?Nb/~@#엣ZXysy=\Ep|^KK5q!X;\р-N @hg=ٍv 8{i/Pe^"Uã*<Z^O ":XbD "DL]綾w.?+uD"@D "03! gy42|\=4$踏 ߝ҂ȥxotHuqfW&@q::/ytU=@IDATB35-[@Vp*qJ6S ap];CEs_y2=`n??Cf%-ROxz>]uuˍB;ʥC'3>/sYD&Xy)Nb쎘D#rx^-)"D"@D`lU0׍^,6"D"L@.8|86)z:_׫jϜ7."Jw ;~ʶ-!uy-'4eDU s'-Gji|{;ǩ(#wqS/t,rD~qq (RSSI*NO6qc=Y]\aMo~n"!"@D "D:KX\mǨX)B#@D "DZun-;9)5܇L1cg+e&n$0>C>T:$UqS^8c`[p)P庚fk6o%W ou˴oֆvAG` ,Vfp?Pmm+ٌro{U/3ocV8.!kFrg2|m%/1Yr  h f)YeJ%PX "MYiɋS /jY:4?#Ѽdw Pzʣ9/a Md!/ s8r(T%4YMԶz*Щ 0k7 >F5pG7l\F?9I2\"=Mr\U GfFtw2.fO _/u^js&y!" ٠=rӂyP|ZCNEe5Mӱ`oG0*-bj%mP Wo>o͗r ˏ>\1sFomY$RD "D"@!`Cp~ŌԋG"@D ">1,3cz0Q6sogu=y[i8yfǯBc^&S/Y>eG2) {eǞ> Gl.]CLoiʛ9~ G'[~vBWT4Ԫ;cU]݉?+/~{ZCHf50'rp)"D"@D:otYdEdg/m81ZY?YzOg[.j;F"@D "BOb}y6r`4Z4fg}Jx2ϥ4zBܖa.wI/zn]RS"x_vvZ(551x6 ݲQᇟfkN5;kkYe60L gF|vctp)#D2Vke}7]Šm&tAMcʔ)rYg%z^;>Kdc=VZD".I#0=l͚3[0s? %͙fiqAD@""@D "НбϟU͏$[o5xᵍ3LJFF`rRL븭h㸐^qY?-[,?y!*.cn*^Wx1L=#QXFf8%cgW\׋1p{mt-ϬH;:Vs!Hݷq oY2}EK:A=rJo*:t.e챝ګUv*ItiW_}%ΪmDm/4Tf?W=4~x3ޏ=Zn;.}Y=Y#OD "D4}8(%ޕM%];5]ld,LOOkjQXD "D"@}0/byul~.G/1nzxq9k st~Mu2Zs_$.B,nDj!$&Y?<0v5".];x{ȏO4IwgȮ3{&2pEaCDƍOsbC>q˯Dƫ1zc'>r$<>laW_.[mAo~'a`{ [o\p2n8{~c=䪫_nZO]vEX[oaF ^z}sϵ;%С®H@D "߼oD"@D "`]&%:̫J̐` o5caHmSr>ZZv;0sQY|~/A\ybΎ?ErR8ѕkO]K8~|:NY_T%^S/ͽ0 B?N[1ˇswXDyx\m?U`7dZC71/Ex^!<"E"6`#Fv uU]pUbLj? I? YguWXF࣏ERr%Ey"'yVbyuE~"|쬟0a[~y摑#GʰatE.tݏq}Ȑ!zO?TxYxe̘1(s1^ ``_al X?x}$z @ڨQl= m?qD}".&7H@D "N]B:_ִ:%+ulrz֫^:lC FD"@D "$ǘ.1Ωag>}[ CB6' o4T =Ls x] a8'',K8^:3Y虖1t;nAumS?/ӪZʉ4ȱ,yJN~(. 5HP.qpGoO({ =ۥ qbW:~X{-StA< <|K{|4cğj~A#)" /1J9_}ԇ/]`:D7ȣiVE%xZo~Ƿ?0.|' a:«l&{Ĉ߷o_=Fxq W_] @t!#7xOD "D3J{5\ͭ fL ]^6H@D "D"0 ,'(fj(Ac=l]m̱.qs }^ jDǵ0͠Kʼzn3XL٭ji 14J xQzZL~y $'y%s6yḡ=]2Zi# +0fqMm`q]]>"u Z}@Qss[)3~{x'P|mT5Fvc\gzg~8o7cYn~Pr0S&l"\rʫjXD"n'>~kjU1$tgz[AiSw.(P- [jZkؚ= (+m}N#=^›.@Y//8tыyf1qA>)dFP7@s2xP"&?2kmՊy8Gs=(²Z*e^r=l:{%q=p[f r<nV){ϡ;{k<>0]ㅫ;7Z_dMcXd"XMLx99:9&FW4\s̋Օ YsdCuj0}r]wݥYN;Sx?ь?6~E ;uQz mۄ$@ƙgYXdva2zhKςꫯ:{[-R~ad$}E1."D" ?EsM%&!ZMXNmW#E""}Z1=#e5ְq'sb_>O>t,b_R~_J+ԋ:D".sNH|Jtx&xyFoOa/kzkc:瘧c\?ܜ`kqq)( -y]5hIWT f{".$c^:0`q WF|-dUuV@]xR2^Oך.lww<yzz#O1/s&WL3Aec@:CTF?0kmZ|1-"h_e f=pX:uDXoy`\~D_z{]z\kIKuK?K}?I Ey/9b?J&(?S:0_|M .UVYž9 <9_V 40OQ^{B^v{?SX#1\ThD"@!pWN64զW:~J/ο&i;VdEDP;zk!Xs{Eu%1~\A?') 9VdS}_"KN<#t'c/TƀLdFCȜZ`%.Ii/F?]O<,Rn\`9;刱a<񕓖8œ,x@ve2SOp>c >LG>#3i^P?.ܷy7eʔ)rظtI;X> 6L{ˌ,Nz饗d}5}nYuUm1. Yk l5_q;ﴱ>f7;9k6dرcDRB}o @3܌g:>h8<܅?ƹ(j-+xש5L?J ~y4du8K/X i^Q|3}\P7s8t3 -j*δG0ȷk>2¸F^~-Yth(@{*k֯Fo``+q=^GWy\ -y;<G7"X|05g|}Ur_ˋ THij";\};odB {d"wC*a|#1'q􋁜O ]tEf?N7xC.b us9 aL aEm-ewyNGb8zJxLF/܌ﯿp K ~l馂?OiKӟ/!za?3y0cx㍭< 7|Ǩ!Ʉ dС2n86QW^91jmO6]zf焪;Q6`P4_86`Fwyڗ,p"vS_l>,(,,څz衲zp19?sC^6;Y"pQG7"DytvZ97cDOyH?LKR52d[))|N3?(K -ƂȦ~RY!O?Wb~|xZH8[$p5z s !Ѷ]9W)"MQafar^6^S$e8F"܏ G_~bwes }ȉR"@D "tNHf>=ls\~=weʷȻ+MoMH#/y\?O-&} DȐEZ,9EF%rO Jvz#5'j|W%6y"ǝC=:WEN_h} #{mַj+aa-"ft}_0ڳ#+Fp /]?M*vgݏCȑ#mG}VٱM8Q8:~M6ıӛȋ/hsϙ#:D^ʤ^ћ|-]9j{|e2n9 T4u>].`F_*;>QFlPo3Nl '8)#߼ќ0qhp51c؇0+nb<ӶhnGAONb`aDARF"@3XT o [̅kIE+ɑ ic-2*+sc95.$A\p:NSӗO`kjgu~78:$ :^oo\Sz"y<8P~FD GyC\!$Ó]ƑIkiY՜1t$ܛs)]L\ft{6tR@D "D"?*}"SfF[CgX|:W=es״bٓi|jlOwa~BÆ$+nJ^Qr);-EV՝^s1B ܠ1>ce7:{0cG6Gclgg=92]a̅!{6O88yݭʢ 夫L}!BAҨ|6Y,,~HBat *9abnUλW"HҨ~^Ww=>u)A] 0>w]4<䮧G7"$)"+yI 7p=a喁@D)n'̤_ni%G"@D "B@|L3 yMwܿٿ孩c*.>?Xs ؋-tݝJɷycSqy{z,>K]oDM6ao?hB |1c 7`><.F߶cэ!6c3;Շ.?2~9*48Gc0g8;Ǐo¼@  eL&b{Z]1dM뮻ʯ~+Îw@92E|9ߥ^hv쯼ʦ }6Ygu>zV;9=p X=f~@"@D6<9W_ئԼ!!「[F8.,=1ـ'2M?*őd qb )OQ]=#"1ܛ>׆:uY|J7w]CM(g>iTl\t9U5t/7'&!w7 '@Z+7TT8cKh0OG"@xq/dGR9LL{U 󵿖@D "D"l'7UV>B;$3dpn7{=_w$/ӷX::s ˯FExA/&~eQRx}kgkHjmv {vM?:NwH=Dp:G9vvd p$-yJu!1暙㏗#8¾֓/_/B'ud׷|]vY3.ĨA,RXd| sg:ؒ0zNSO=xYdmqrE]ĎN`@< _F3`;EK\NL-B E Zp/0!RD "F\,QjsS*|.ϓ z؏yҼꟑ:yCvEѐQ?)' &4Y4I#qewE?cwԽ֞i6I7s֖0LUi.˲xw OS>qFڀ@k, ]ep:;aqqs+/RI^a>ا G{ $1oMymy k⬼p[#{(S/uyP8J!e/4~4^[tsԻ*ph+󁋇u'/op+TZWB ]UYZ.m!$"EehqE[ ֣S_&.5- c(gg$~1 PI-wH&Z&49fa";o~K5Pٗtj9[nܺrQGˋD"@D !0ˏ5=uqp67xnfSr߻0xx#KCE>*W캵j+ٿPCw" W 'gslEDd߭?%c_#|:Fzm-qOpWǯ?!ۉlo.1w-2d .͢6xa€ӟԾ3j7="țe?;Z2.;c͢f|OE~̼HXxZ[\L,3\TnQF z0BmcDf&xGϲBi:.>:6aͥ͞V-fVy:޻ctoil]2 G\ ;W R[S \g*ãxM?N$c R> -T`dRn"VLN.`1fmLy 5씗"\Nzy r%ZxaFl(WtϷ_I]W^>(eg2@xcEKtҙcUP ^&zϻ<fy&v)rNDDrEDֈ@D "D"3rѹ:(?NWN| _&DXTdߋL1X~,r0?⾻L"%hqal_ k&rD.ȥ׉2N9*aa|ߙDXdZ">Ȇ \r1stvc(]aͦf_rGfzhCYY 0g8ד6_b ]\_P xcZD "}]q!FB)S#^9)=>G1f2^!d2ƤpHyV{( xZQs5c2ݔ;]HhX[4ݜMnv4tWMs:]*9YLdk:i (V?:v &q:\io8Լi:6MNNic{fQǾ}zt\ۍc2; WkzJS%K-&"/M,@.#X?[wD^2;3YKdؐwL}UNB /(2}s2V&;P+,;}]gGr\&2","l+f€ŷ{;C?l$A5b"G9d7jFfў0>[ky襗^6ͬ<(z^GT(B32 /p6rTGb.՞Fֽ,zcmuJ,`ޯ|3zE + ~ՁϛJMh\&pu4=|GˋD"@D "PO[5E&yֳn` HNyZ(VyA9~i|&[ 7F)-Q@ƅv]o==aA]C9?`yq_1r}QdŅxh һ$̀\*ݲQZUj=eȑVIJb")$4Rf7#"4RMwcp z7|sniZ@m8\az"#Ov{/r>i#7NWֳdCݪ]JN)__Kʄb0+e}1o)?ɃdɺKݨNec0aeҤI/:#}׿eF}KH6u ^{M4F`|HQ# ꫯ.,vx͠RKe@d?nFq_vrT+S3.O;8Agvc eaLDJ9~WLeGSB][tG?˷OM8xMpE6|w}ZkeZ‚F+Oh'x#o"~]AXW7ZS?S7wGY'+[ 1bլާy[JF [t+!φ2~&O,Ǐ7yA_q`@;ԇ?xK}ǬorQf|dP*b i=⊆zO.9`kâY7e{OOe!: O=+,bZy啫FG4h ?k<+>OMݨ+yn?{̲{ֳ'z \˞s{{܏sgolȗ?3A?|ޒF]&׃I~gP}Ș ~xFw]g#ӫGOD "D"@ xW] -LӘӱzK٢"Cs1֌?+ if8yC/<=/ƌ S>|I(v~E{yq"5eKZ' \.i#xrWS˗"?2sbyr1n[VA6_KV>Oa\pB2rzV̽g``WÆ1wŀ_\f"^?o[8߽I~ g5"*ϼ { NvOTJ$n tv9x / .GY],.||8Π $d9 aB$BQEf.!l L$!$,KȒI"$(|(o@\BUy~y]9N?Uu]wU>}wWw>*ߒ׾9_>pf-|a#GNr,m'o:Y²8O8|[Z oxCqDaq,l%]vY@E_g85pĪm{o8p>*}ljew(ކQc6Iɾk6]~ [W\qE+Srf8rַG o+.گZqrHه;|>؇ի^28q= W~7^vq4 A,+˜Á\YM8;l\tE1pŖ78 'C+o۲?@_>xGOʘ|nw[Ck9$,`'?8*c'&ud|8p`|8.r``^O=?=@`c5?Zmo, pҷ>s9q*+ا=$ [s2Z'ر_ۿ]!WCmoC2 Cr{1ϼᡇZq[wd.q. 8/9V?˸qgxk`|89s3p^W37pCozӛ&ϡ־ clٳg c;nÐEgޕ-_wpW%FYvۤ{}ϝOt[}6'f^?v{a&`&`&ك|7b6m%9,sfl_]Gt@IDAT'Ar%{~*7R2QtN|=,@[SǸ7;kC=PX.C_Tĥb.TP8qerɺ]Pdz|.Ӿ(,)i)#|LǶ y*.JUSXiz߱7S~qdlYm1-:ԩØ;+:7RF$DJ+.yZziy0!.pqq\i~V?}SJGlJ,uyx-BLK7_Ro4;~GJ_?ßo-tJ~>ǏzjJ/ukFZOف1G<)J7qN 8!YBGYr☨Ks? O(>ő*ț'|rqlm޶dE}Cg3ي1NLrg9| ъC~:?N{>O}SSGKSxϞ=1.,:8Ą<g6ik_ MrC< ;-yғTllqB6׵l,ܢzSX lcpHc^/8ؙl0):$t`܆e H>ƖɛټMa5}9'#oSVI88q~m&f aCC0Wr2nOCacv6 oY'ќj'ޚJ >/}nj%YT1(CmD!Sm1vbDsy1~w~'ݻ<$ Qʨ3MkK/;Ri創 [k{2 Uj}͝(/bL6vEFhmϵEhc!3ޮ;]W&;h|%t)?%v(f[*F l9.qp8pp~NJ'ݥ,qӗUvKSz)n)}s)}N)CfC]ɶ18_9p8!:Zp*B` p& eBlm.9q('`K\Z6pK/NYz 3eq0mo{[y F쯜sPgt|2>sCk~l";&/*:&(2Xi/}i9>>srhOAN=oW8` u,L}k}ƈǛCG{XVkC9v6sc.Mݖ Q;Υ,:[&~+_)+_Axn CsfC<"7C(wjƳc%f޸MHەznwSO_ӓOMk)¹1?hyqTSz: ~}Wbwӝfc8Vp<?}1dcQ9z=- QGhSYE { aSp{mUʧTaO򖷤3EU0[`|Xq~<|ϝ;1h\գPsAuc~vəmװ9}Wڟp.nTkU^<钟%.ٽSЕ,Z:EWTu}&es::uRug!82^3˲C_判S{n(c_?LbCՒlo}en'p90lu7CRe=%;'?52FJny0Y|CsS!ykw]Ӓ7-&r4x#YƼH{k9CbkOOox?/j8ʦ8MkTcG&4!gYr>-@}ND N C9 q=d]ޚfh%\pe6guVoss#`inRqL7;p& nF?l}W~dcqbe7pP᠃*7_Gn1x6dZɁ`9e.fmFq_Y Xa|x ;ސQ]91f>3axtظ >}a{<cxXXX$;/|aYq~<1)QVC@@b\gV;Kٚpo9xVc"qjsϞ=?'lϱ;ty,~I'o܇}>YiIY9qq aW6[мŎBb^kn"snּn=7N9ăK m//9tǖ(a/K*~Cn*_uTV2]As_t)=SzC?%w) ?GI1)}Rz)= "' OyL~3 )=N8)I>񔆮:+[˧qXy,8"x0$_<@?A؛R 78a؟׿Z =qZStG]$aHu9rޛe>2Sk:\ߧo+l1܊@_[XXt߷\΃^''5Y'~tk,-iroʧSYKvb}Rn}⚍uf%."]INL~^]fD?GGA%#y?mQ6v_^HWq,>װeicm}gd`llc7lG&5'ԶOZB~fyo1"2}zm%G{3 fPVGG^K'ZiɈa\ia #k$M8ʔ&?W.}U}0?-[ynh y{ߪA&1= ,Y3Wi@_Vk~VfֽMnQm@-D *u:Y@_]/]]N}j|{'Ԋ Im3!(SɦtYt̘{Q,۴L/QOi/7'>Pgv7^Lnbwnq

    />`>cԴ>9Ŭu~bɚOny[g}[T?.^]p}^_}O}zpKÖߣ}5 }^&h1}.(~/|D}29}j}'u}dԿ.H3\_o&y~u<|>Xvr޽ץ]N!\Z)a'^9hAsi's>[oAcq}3o}˹٧igs\ȝwn}\Kh1T|e^~ns1^؇Xwū+}#~kI߿/~׎s寏?'x\s~3g}t5sgcc|.~/zG]N}aM8}OQcѹFAAs=q/@ָ 5uXHkz b*?F^̱O{"9v^C<>b9\y5XVvfW%r)\߻KyZ߾/y}'!W^;E?/x~ϫ~~{y;G.hSCχG,6G]bO 54O>X˅O^0}^cu]e1i!lD?9sixbݮqWyιɧX}y9Ƙ{ry_D]s0OH\o3f^?}]o ]\_g(~~笟}ׇ߭c}g߿/#kO_?kl߷Y?EKZ\ן¯9mwR.>Uo]ָꋶ7/ơ19Fa Zֹ{۶v}T+=ؙIК:IlI@yss1EKW K\|Z@k qڷg|:Ý:ۆf5Qz~ߘ.hXfK{| rEuFmsV>d/`V>{b՟?/՟gNV}SfgZW#ϢyUU }vOLzo[E~B$ ‡ݖេYhڜބ8 .^y@s"l}tr<;O_pd5s׋7^_/jZc_;^)nyw՝+CƋ?O-,>>YcIe>3VZX)k>5?~?{ }~}_U/7u1:3Yl't4c2d]ۃ<߹7=? 9G,6)O}x&xu_rd;[tG4ڟ>zttz{^yϻyMf֚ͅnlfW ӧdٟv= >.>yɩrSS%{v_`'Vfo_oˣT }vV!fvN/_~Ղt7_6 뷦!3` kxΉ7='HG2Wţ_RO2K|q8@; 1Bhr!>оGOZ5Г̩s<:Y}p;O,9}s;xWYu(Ϭ\sI\X}g_VP}:7ds^s|iP睇olidN= @csو'dl!cXػN-5d7&^FF9h'$mn?CNma_0}vn?1xsysƏ/cWܱv_Y(61|c~Xk׿gy/;xB|sN?:9?8c2ZI?1p`2A mq荵d{r's'}97<@ч׏~u_}-`N}AOh<p-Y'HǗ2ounLm93??HXWX/˿˿̢뉙VZhX ԟ7ZccƟ<\>/;duey}ΫM/^6߅>.o - ÍM"i̓;g?~Ə7~~:\2Ih~pxZIËt!9m|p_}f{5ٿߎb;olbg/ϝ#;,XUUV?wNJc<=yg֟Ɵׯ^#};Ͽ~v^ẓ6>7'|x ҝl;yMѧOg~ 7ad'K6>0n1n4cKW?6> ӏ7>ᛏ~ |{ 9W gOҩh/ڳO=_ٟvȸ'˝?ΚXY]xcݿv{Μwbs\ch|LJ^|z8yo.>: ]_q~t$ۚUSCF1"Dt:q =eҗS҃hpNO:sZ^sËNg|Wg?1ޜiNc- kZ4n?o^x8aWTwՖ7V=5tFVcUIKnǿW)t^/?by;{G>, Q.Ycv>Fn1? Dpΰq'6Ycm_ޣ}SA4c}=/1}{<w1/S_E>>w}̾w KmOXy/c4ic_w]}zk?՟Bd?gw` zקswlE_ݞI]tm'ڀ>@,};e$/}e@$[_^dNɣk9$߇yBo}@zǓ.XۚCڇwGۺ1v_ߵo )O'.,. _O˿?V}?WC0__~W;u8X>yzN/N}ld/ZhO@3?:}ܩO?ƵWǁ? &lbM$7ٜބjM8y`:<|H-=o\j=fOɛ暎S/^qg߼t}O6_,/Hgٓ_O ?:oׯ_o?w׽V^_ߢʟk,>T׿P/<ޓ~b6>@9ltZ|ڏ~xNmM1`@ h0Qћ \pO~ě'}}~pu?hxOq`L6|~kC7f?{ I&px@scēD;ōş;{.>5W5_9r'Gv'G2b$Vws5N\ߺ [.x}>޻߼ O?l9M?ǖO l"MZ`x-nA gp}MgʙɾOMO2tg57>qz^><u_dE1^s҇0'\ wu?n ~fU{ou&}bş'wfxgw̵|{;kR,83N(YG^MS{?-/6hZ2Ⱦ>O9yo'{?-e\k -H'ыק~uۧǓ!]xŸ|9d:J'pzswg'| O\[Y]Y}rdǗYWZB qs\nV~?v?b{;^}' Wբ[{P/zN=tl4Gm:⥣tCC?$| 5Am86g]ݏ,CO1Ⱦ;CO>ʒ4^"졥~rc= d2ƧN=ٯ%|>ٟsVjoNӽv'M?wsrygGfE.x7Ouq<:{3=fyӾhfctxcp0 :r]M6o;tiSV.vs;y٣ Mㅦt3[6ZOkǖ'_ -Ӿ>xåWm_x'./<9c+rN:W?˿?c߫T'x~Ww$i_ /,<ଝѳŮ1^Nsky֔Ӟ~s `[?ٲG PG`&{>phuY{:k3Nps_:?n?jm- /k[omOs ܹJOEF6 |9?{}s3lgwgw՟wOw?wg}}݂9|dݏ;{m81G7mrj gn[\EOpyѾemyQgl~B1s{?Oc~_޺OsXu{d՟?w׿q3VD'lyzq|Zh愖'[v)"a"-| 4a= ~ ~w@}u;ξ6tԏ'd~p黺/Y-=Ltflj~kO߶n?-,~'˿?VyB)^:=p@mFG[uo_scד+V/ t:*81#[P;hO?k}-`ÝsH>c~n.0 q=sn/t09<8m:5xz15>}\?zg?>ӕٟ'zPXy{X:=?_~;NZ]]]'Z#W8B9NYIK>ѶwOWǽ_scpL5c>-\=5|I ^k=o?LI´|^=/g§]?}fO/te^]/6Q2f_ۺ㽺/dُ?d6q6yݾw'7埧~X-ꏧt~_ɯG \mS?V-gGUbVꟓ~?uſtiQ>m~5)ɧ#`y|p?xOgn6`M[᩽΂3?6E_@x6~^yاS?p\d?ퟺZ٢>GO&Z}@g2҉>ޘvزsX |u_}3c|_ā՟?P׭{ﭳ:}Ñ{~_|vxݾ=Gg666 dь5;u`q6D 6_ h@ qda54.d#Z {k0>\ó /'Wcҝxӏ/fl'zg |o_Ĝ^ag{_,.VZ?WR]k,Q.hYSL=G5|' #?16^ݗt~>8 OQv)irM^0a8p.<4?\_j[[v/ tf>\/tԢxwx£\WC@G&t}r@x}{e}f=8+A)|'OVZY]t{Y}RCœgF??K'|ewwӱk/߫?ΏHO^S.6L:~Ǐ' ҏG͸S'Zx[S|{⏆7aO :Kh/:|}z׋W{NtgO꾠1Ym|hSGx[C|>tNg_?}~=BX;>,.,>sQ|Xk3R|_vc?ăݿ(wT_;V>9Yў›=O??ɾe߇`@I3ʾēt^KsHOi-t[p[ZhOӾ;Bxrg9·gq>lm>7O-8ۧ;с)ُ>ӏs;şcwǗu=Q}u\g?_r}VOV.>:pDžߏ/μYО5;+jç=w~Nrd[7[И-}1뿃649 |\8/'9RhL_opg~7nHi?^|?ǯ|2mݧ^YY|k}pIZY]-:?)9'_?:?DL?˿_T~_{ϼV8h{^O}ɥ37FՇ{ }lu#? )|St.Ŷ@sT^889ǟ\.[dN=Z 1ƟLsL ?HO?n'ƳOz?{bOW?N꟧\:JXx~[??E՟?;?=̳{8?_ht'};Caвm8f W®qK'r>dN&?ُÓ==klѳeۧd?;OW{daտg}Jd;!k՟OXzT>믾c }?nzࢧ9ef  ^oʟ{~U.;9E79õkg'(|/'i}GO&{G^2wh?bW?, ߛe]]uV|y.V(cV\yQOh?Yy|pt=yMw=/6/ThxOYxBW%l='Ւa1[hVOE~kNduƓ on٧[kwѝ'V-erGY?W*'\*~#X~Xcue9Clߗ!ol}-Wc~mhα~ϹUOv.xkW_+"8 =m"G^{u_<ť.4OE7d{뷞i= ћg~:o>k鏞w/1N0;a>7oadMܲ#?VR\+%|H_u_%9}cz}/>2-??N.lt4d-~-zsD'N/&;pgXpACksltI[{51߳&9-O,ᢓO,8׏'=Z'-?]ټT}K/~?'}wd^g@ng~WX[\k>&|9pW@W8Sɑ~zvƔhهg+~/>H7b9sg<9;×dI֚ɀߣ{/\t2^^:jOptzt%̅zq>oٷt׾]?A';?OltbqeBoz99r"tOYo?納甉N'#j XgϹ7>wMZfgnϾG}3wwX'.+?js6VQuwz;1W\d= -:ހ|+ȃo,MOsO]Dc 4{76$xQs8 zZ<9xZxGp@x4}6Foi:nco~c_?yZ9Wcu8O߿}j|7Hv|k}vȮᛟ?~=~ sa8 hs}9 ^i5`'}Au<Y}sz/<=/~Yc?䂳:pg'6^YYog=Lqgwә}76-N39;r)%QZd/V?8͆ d{>YK _ ҾjOo_vs>.<{co[_D1cGW>^wzj)~^z\GNY?92lH/Gs% O˪eğs᣽xkl|B}#Gjʎ1YNjC# |IDATO>}D :ٟse⪘c8_'-,X ?V1VR';W ث~୷qw,ģu~ϿtQ{c>xSt/J'S\+z'Clf_ӥ~o?x~|z1wxRl7ş/3W|sR_w͛?Vc?vwK> No?νNؓxߪӶZ]/? L 9K^BNí`)w?>> \ӑ΋ m÷ҙ>@db]'o啕eM'y h?dϗQ\养Xk}gCNu8?;P}y}GTqyϹ^^\qPۄ8o/ø|IȤM.>/֟t_Dkq}6_^~&O69/xZqzno3ovxPX}oőVZ#?#y[YYyCgdgG|ϷNݖkV<~'7˿˿˿yrm헛7&,*{화{z_ݏ?9? OYo6?/|v\8#_|R.\N V pO_hdzOX!{ة]u97(jZ}rm~g P!+XGk7?'Lm2xK'|5NGg5o=qQ[0^yTL[G{(_WLO~),޻%U{ ݳk,>q3Sۙ1^}TL[G{(_cD|rpdw] wfv cL1ꏯ_O(=AY{sFs;Fǿ9^hI?ƂY̠);[/ah;0?3hC?=|r?=ڝ?Ϟ~ѷO=sB{loZ=qϽG?_{a9;>ⅾsb}2:g,.:#ЮXa/T\ @_3(XԖl,`b\ 6ţ甩+0EKxyN_߽Έ>8cO4--~X}+??=c_wL\YMgfoc8'sg?n} ?7'e.-'P.kkӒϸ֓lӗ`~~=Y G.w-,:79>o/O>??ϙ9`^{X\şۋ[YfhU '&6y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y`y2]IENDB`icinga2-2.14.6/doc/images/addons/icinga_reporting.png000066400000000000000000011427561501332562400224540ustar00rootroot00000000000000PNG  IHDRk. iCCPICC ProfileHT-ޑN)"I T숸kADD\"kłmPľAu],Pyy9͝{̙9@ELX ,a8*ЇD "#1#"Bb$[j\p WB2^sD\P\_AXU4 N Nd4z2&&aud6[8iH¶B@0xrl.H]`=2R'o9S949Oe~(\o+0} ~ Q(JBĨbT9ՈjGundWh, t,ADoDW[ѷw ĸaXLf1S4c.a0CX,5ź`t2F.l;p8K.p;qqgq!'< B|ߋ#( npNI"Db 1XAl$^">$#H$WR$I@ZM %]! >Ud_|\G>GG~GPL(ޔ$J.erI`R*RRhQUxHP4Vd*.TW,W>bfn+|Uc+4:. < aqX`C!!!OB-BšapXpضs 綆pVG9Db##""FE-ꌦF/>!'fs̃XXilGb~ +'j& ےpIqIIm74i~; L,Ypu̅).b/:IO>ήaRSF8\onw+=KH-M}摶-m/ *o҃Ϩόlg%g3ud,EE"Y[qVIHrUqtCj&]'̫8n%KKn,Xa8:/_|`sޕʔ WZ⚌5_Ppuu E EAC ;7|/_+-)/ڏv?V8)uSfͻ``ri~ධm-emZXgqt"m-;V+|7Tջ{w=%{$-5&5=@}fmI:a`.mn Ç>wѺqo(8*= 9qqfjsq Բe*kKl9|ݽ_N韪:vz3gώ{u>`Ǣ.ܾyRȥ+._dvqU'1^wrFN6w9wt3LW[~.fݾ7N읻eww˼~b?RzTXqo5ɜen<~`3w_ R?{V^ {Uկ^# #Coon|ш>},g/_-Z[dzEl1{R J"TDWMiI& 'ݓ @79 wMHZdVDF2b 4IT.R+"M!goH8aJOHQD/_ 2oWW"I(iTXtXML:com.adobe.xmp 1553 1131 k"@IDATx]ECH%z ((RED) vφ"VDRDHQ4=@B/!B}Ι{rnMrowf֬Ykٳgf9{LF#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`uu5Z8*ԯZZkI怼O,C>fQJgsy@enLGQZOZ˲,qAKh , _1ѵCB{ *[k y1ѵCBWڀkom.`O1`T?P׼<ż7ؙT (8!F&ާɬ'@'L'tuK/_itrcӅ8TꬷȾtI^̇M~“PTr$o+ןǟ(zߕk?tς>锿GZIWesBYx!*\"JυЉPOR,XG4I'졋Ca=*CB30*׃?4Vz\Z.=g?^_^zZs Zk(}%;O}גk+R1^0"%C, qBd,9$G(9Yl/5;#YҾt' ?3ʨ.de+}K}QwqGǟ8uS4?|Sן?u2gxr8*goz=o7 $Ԟ?'+z+4:f@'N2Շ$PWzeSIJwdl^%6v xo*ׂʵOk<KeaF>iSxeCn!CCɧ,vޘ}㯾CO}>W_Fw-G^tA*'\˺/ԣY(uW] SƉd~7_1i)24hor-k+)ea,-e@|z)B`r y]+=2s?ko>2^xBk.=2uv-\GHm~: {񧒳U%),'/@+<,||H:$/]2JK#_[e ؓB T-K2WԞ2QGۯ)5>W/j㚮<ԮϿJk|-?5se(,=z-_kL?5[!J3vxiո*{!P}ן??Exh|!͵u4PFKejW#L~퓆'ľt)NZ<Ҫ+|'? A0%HD&_i^y+M.v _yG!W}s/ ^}ڲR=)shN+\ s\Fxxʵ?^xQ+#Cm:: q??x1"@s?j ?@a֏\9X3A/כ*-"*S2u="/G>#Tgd!O2 f0 . /Aʼn 8r:1 AN02(Ae:j?zkmWmծk=x6:B?T?+^{wmJ^Nן^UzҺkۻGǏ`~˽A{?T6엲+?2s~IH:y'M(YdW~iY2?s؆W.:Fr`퓧|}d~kϾگQ kܶοwW7PKv0{ 3wzboĵ iyV}o??x3- BϾf\΄?D4; !wBZCC' Uk *!~+!C"n+O|t/Ԩb,MpIy@<:t$/,o`Gԁbz#+NOZȊa)+%]~EB*o*ׅ)#_R!?=TlϿqDWׯ$Nrȕ?*OUBmTJ;K{ʗ>͓h<$Ȑ_ʐ %ΒDV5:jQ'N醏=N*T=/D2*>쫼ڏ-ۯ%aiMRpן 9?^Upߵ15z]#6^{\h̤?Zgj+/4~bۜzu\tM|RVGB$!_+_2/;o5/ 5 ;!%VeCG |=POe#,!':T^eO6ڳOd9T6dlke4Yji~k<(5B:|3ޔcNWry5ZB]+y_9qa?=z!͕5_o?W8?WR"S#Vy][(L?_K8?tsNHH&XY^O(B2JNeѡ^i<#5xhQL90$J.U@K^UYҔTV'|yWyI*-68/ؑ}xFg##Ա=ݡ}t~[o|a?=Tr6h ", 5ނ^y_Ͽ嚣3zQ3/(/^p亱j}ca^:i,_i\)Kʐ.ItB'x{#ZoHr=Np+nQH"5 P%*G.KqP)'䗏PlIё}tA<zixFU7WXdžyҲ_wdȗl7AJBo /F?*ǟ?v҄P)G><_XC}CB?*א[Hi<P1 x^xGkCBbzR*_s!\U⩲UP?R^%Gt>a9! OzOe۲";s)yEU`( I 0B($^K| 'p 9CFeM!,qA2P: N>H\ɑFi)/j>m_/i_6"Q6qPF$ɓNP}X6d%#!RilWDF*]ɭ4l.d9I.U>T8eed>tYREzR*e㱧gSu29X0 "Qrҏ\[}BաR8GI$'eVPձtdgȕ$(g5FןǟڼR7".#$zHeS6r/?$?_4n2xi*ˆP(_B y!$*_^y߭WmY{5ZiGyb\Re`zo1%N9D4ۢ TQ?qþ6 dS@d"#BG=E@R?q5\0!5$= x䐝^79SoFhWhMͳSSSԯ_4k)Mnȏѻ;78刣Qi,eӀO7{ccs;iӦg;/2/?W|&;  %|O8GG\Sidn5X <l/ S9!'U~% v;:s4mܯd0F#`0F#`0F`럆 n3FKQ=|Ǐ MZy F{O9AlIrND0ғ$},Rp5Yx:<@\ryQFOO/?wz_}{;if!g2F#`0F#`0F#%xRbVifڌiulѯ^v٥~_UM>rGh΃&\DOPr.9?W$(Ai"*GC2)÷ 4<=*@c!@W9⋯M P2#`0F#`0F#`;3-6FZ/huoGNiU&2!洛G>qC#]Qٹ"҇C8Aa@jʑO h##>B+I| &#`0F#`0F#`0=ǁ_Zl|ּqGj[ÓZ`e9y9Α!/9Hʗέs@PP8A4D#YPaS|mDHCDNB:l0#`0F#`0F#`@O!Я_9k|[+mMH>ێ9'N,| V&p_Fj*LE+<5J`yʑȯ'K7DVm! Y*#`0F#`0F#`@-g|#ZO!M^/7'>6"IKx6ig 0{5=4ޡ/94(Hz(QN]IxH3#`0F#`0F#`YZG-g+M%p\N|ˏ._ʶr3on7hl<ć*M#TR .u28H'+?#`@_E`AiҠ8MF,fϞϘf[SҴd0F#`0}_ w/4߸|ؤK_6n%Ozʯ2 K.SY"T" „9SKwK?穃bzp@4ϖxLFEҒÇ."-v3@Go7&xd0F#`0}3i e.&_7-҉|唇LY^)GTߐNlT#IRaU*Nh@:P6H zh !x| ; 0F`QC`¢v>R×H\&#`0F#` /ȹ[q;[[ak#H/߼)N~!mP pG8/m'OđG6Xm GN2?5#`)^jX*O 0F#`0Fo"h!YǧݞyGoH?>ȟ!B|䲯2tX*t = S\ d[WC8dk@ld PяH~dXT!ɯMFZr4}焹F#`0F,GB&ڄ~0O|D'/}ؗ^t h"4@qFJ"ʲi$Df@' _6D`2F, o ,gڭ\H0#`0F#`@C\:k4kIyk[GNox.;itp^ƃ] U*S\`&2ʏhT ' DHi$JjA#%U]"P*&>i}=ԁ|m@!>eC\)ɜ~r_~4tiŊCy/M}0iCiyiR*-=+Ii'St z(9twz Y|2rOL<65tj蜾N0&MF5gyc2F#`0F>@o◆Ł??nȓ^~oUEM<o =C<˲OwH2ҡ`䩔R!DdGeɎaVy*N!zF<3[J#@h:i&ÆԗԔffzaR@h{rZyCi <]_S1 R/vDO _?  }RjJoN6N/͗'6Z#wd0s5VO|'݉߹qys2O?B˸0F#`0F,XA皫MbB8Y㥕ǖՄrr6;'2NyD<ϖwFbhI&B<˄@2Ke "9a}H'j^״dt0VAQ5W^s@FىjC=<-V^B 0b̓PB[CgEd+xg9 _|p28N f̘էOJ}뭷VMߘy9ni񽽚s%E;}oJ3g2W_{-~V|-ϸ}˭0qd0F#`03Npf—8 ^G'́oRyű)}KiP}_C$NB(W!tayhO(> $_4dHb8J'[".KG 5XAk2|Dy0˺*tI }py*&CO~bg5瓖7J}ӄ I/RͩNQ@_CI#tBz'{}ݗ>9ʮtꩿP?t u( VU'#<\]wu'n(k؄jkLύn&<|^~vz*o|3]zM6-Qc.Ƥtŗvxz{t(wm_zB?fؾ^Kg}NSOely*>2uo~;'S_fAjk̼?Sq=5/T[0F#`0F-gitpTԦYs'h3ǿn~nb~Q@eD=c]V[-ui+nW2?4-H?);ftg6tz{vzO:ğSY\`ÎH}`[oȣVp`tMc)SӀ8=!74cfRڍī>t#F]v5mVBη҉?yzӏ~ôO]viZqŕ^{6p رcәgoz-^ûwȼuv3ϤK.$=C(GӚkeϿ|~w%f}{68NinK_rQz#j[lEe'ڽӬxuwܞ實Kq}/U?w< oR|M騖_ /[2eJ~8-%\n\G?=>~zl2-̲YZJ+#EC~61:Ci>~oW1}FmA믿?|0(czOF/,Qٱ9;dsFo̘1|4hPֵ&?>S6ޝs SN1)Xtr-Y'byJڝ}ɿN/nj^'מiwH?s/>+[/}%۞)}*m O-|p ^mAzM?D:㬳cOYgn_@묓gG8ytl:f;lU:_=6_{Ʊ_M[EW\yus msQΘ13m9^_oݴ![2I<%km'>o+2k}'"ƛ/_7ݜ~/vItʫN8*S9ICK:RK-YV!fZ<ҦllyqxСJ|TD/ϽPVs\+ .8ݶۤGCl vcQf0F#`0F,df͇M;ơC_6$?8!gvȉ'?7qu\K5,eI>2%+9ZC%q5@) "<B=r@2!Ka# ԼѦသ%PDَyC_¡_(@GF "g^SA#n6ᐏCI"NqdԿ)ִtSI7HHO ~fE{lЍ ʿ_|1uݱ+pzNm812=PQpvoO?-1";߉ k6MV%cv};DžltEV˕.]p_9ώѣG'6|-_{ohi[qiuͯ`7n\ȑiĉod>' 矋͎s~gI~FN;4"6ANÑ94]~_wo+qƟ:%m{u"͚믿.lssmӱwnv*oNzx6pp^z\J8<şyf\=`w282_~49kv7pCZze2H^ilY6zhu{_;s o /s5̫pfϞO[oLɵg}E?~]tɥWēpj6Xneߺ֒㟛7$%'?K+B~ON؂?!oӰDGqX?91VY.d6 <(7* #`0F#`@"Д&VmxUG4ǕO82 +RtO(؁TBx@ NGgd)M(]j*RN!_>| 題vV(nd DiGLC^ LiWseȵS َi |O24pxb*j}S14qf zkwYvt{҃Oi/JPF)F Fԡ_47IweLdv”p>unT֫iV\qŀ@ ָMj%5&;͆|H(?>>cu͊SK2oB,2ىƛCwœ Ю?WҾ_`N{ƽݛf9~^k^{2;t SҰi뭶e۫S?q<]ӣm6s=b'E{j]/'M!^]ͯS=f[񭑑#F׿]^ _ʗc믗Gͱ67k|]ޗՏSEW^6Wa(#|_<

    _]yIrKoH~;+z'#_*\&a zI~OpTwsxbbQ7c^\{;xU~q_bMS3g| _ʛ(lz7'|-|ЁOUgʸhlh)^lVfH`SA]g>FLIFJKF#`0F# Zq5Ł"ɧ ķMZeCe^*B)Fꍩ) 덂0z!G8P!- f"MvmfϪbS3y酿_~x- #@`9dl ҈OƝ~зXC˼ˆ@h,ہ^tx+!Zrˆ'@@F4~4BSi +j)IoA~I)O&'$ɐ_0bĈjHjFDpCzμqkur 2 ^+/!|ĺ qu8E_O &#al8xtx$Њ+X@ m8i=Jw+xQ=stWß ˸u>g9$u֙銿_q㼭'"^y|I2 yZ@||,8_Ci|Rz*J7 #XA]7sm,O,tGIZ_{Q?]|녧phDlqqFW'cWK sFO+5O<?<QJȧG9r͜.k^;ʟ>,~ǭiqO;c6@L6/77>6JV|y+O Ix G~)]MɷGZ ^auz8L?4=2cV:gҬlDPyL'?;o L͏?Oē 1 +Wxɧܦ1Ǥ>+Z` yoO?"V aʵ +P'ڥH*>˻^{=6*?|l *}X8|]O=t:uqk s6*UH8O[lY:3c|x.qYڟ_%'6;#a=$6xEҨ#FX8j(^oY023_tw 423^uS|[5^1}P/ǘv7TBߝ_!ߟ^-cW}cNkͼ>{<{&wB[įgCjx)sI6<65˛#oV:58[y#<^>?0Wťn|LpA>l<o_{uj8[ne)M>,,Cc^tW-‰(艍5X3ؚw12܌7.xӍ^_{e{n7FwΧkMc|4]޽kjƆ?I` 015o1)vK|C;gj\8ux8GQlg,eW=(6 dɧz׍77>p>s:7 7dxuRKwH'.mS--6l0ixzaC[n-c "F߾!pj 6 8o$z^F#`0F#ЃK4_4~nP3]xZm '8tz;P錨vIhz9땦N.*NBR*G #=ȊA\ Y93+a?^etn2mB|!BxC Y)*us YCPz+_12Fj(iS jiv;94oN~)o/?w#·zXvx/g}r=K޽ćh>P"MμOī\~Ϣoy ַ_>Cf_k{~xG'|"Ǎ{:]fƶWi)go-6E| }{_zWkV[nUSZ*!1 [<36 l8ژiGwiƼ"~3꿁򐙧4]]|ڱ?uPV:C棫n!eo|ّ!~? e]&P1_ϛ8ۢ<7wGm yW\әc8Jl`gݲz6k|=<`爿i? z_)n g~ϵxɥW2| }d}I_|E{jVRwbCt_.HjmY/>/36Ph) =eB|ؤx5蘸Hm=oN;=x'+jWxgӱ?vq)dldH ٛ#`0F#`#PY\>j{׫ ~5\o;SҬ%.qK)Q8- ^We_MU*:Wo-ʪ ҿ/[+W?n #U ȹɖF^^#k8o$7յ;;7R!_˫{{㉆%i!{oʼn?O `Xcb xgС /݄(kP㉚Aqۺxj|Xn;mFm{iޟ_776>j/-]zvQwPU>/FĘhk$xN}˫Ug_PBΨǠ"#`0F#`@C? g _U|#ڊ_OJ|a'_8<՚P# j䐅6T *Fy@H9! !x]Q$LN|B 6f4|ȀʤxWՂ>zV8}x UW]֎_>oFn W~(;<m9rha#^+G؀ '^xLbսp'yaQ@@F[nw_Eѱ 7 s}3!QOmH_G'lC5z}W=ugr7I84]Za݆uTT&߮]3%o2j Z#`0F#`@YhK7oeC!Ȋ]蒼B#oG}YʫN$UM Pe4D8!^TaTR*z q Ky@aY" -Ɏi!'⧪q8AwD_ޓGhse>dJip_M5w}nwDµ;>>xO:#үZ4d|`O",ت0F#`0F`A`xakOq6[.7 ie—.: T42ʗN5 xo”bFU9$>G=}@wyH˶*e4qllkߕߢb-|Ek s~z'9^5#`0F#`Xth?/% 5U#`0F|!sೆG>~kV~tWl C9/ΡKx><#4PQ 1FvG=T"J>J BNHgٳ dXxMe\$Ni0F#`B@?&_~so"/yD_~KM*m IrãA4T (j$|dEJe %^*zSRYd3F`FH, [bĵl2F#`0F@z_9l_7kmD4oVy !tGBԏ]P J */1P"r#S9 ȩHmA|hvR]F  𸰵1\K-ĢX#`0F# ]yjrPotd2[ox#-_k5$9f0P` AxthM#YCѡt8ҫrJQ1D:0 3LK07m3 K _"FvC0F#`X(o\iz!xMoK7 \e_>s$+!TR  j@ °cȗe"eUeIR^ 9}("d]پ_gԂ#`Jp8² e(#"zcpQ=n0F#`0}?Zn|]_#U~&8S~Dr e eK?/[no#ʦ"WJ>D4 @(0 iO`GUV #;8yUWG +X0F#Їlu˷MEoxT'w>JWʫL)GD c4Hed@ÿL#eMpsc[qBŗ]M|n說\Cm>t* z4ViBQ 䈣p8 'ؠT-HaG`YciV|dc}U0F#`0F#// ?)g#`@7ZN~~!eG\otNzʗvȇ$>ɛ:* bI h/7Ay-9+lƒ:YxI\:>cF>cf&#`0F#`0F`D?.LqL\P4p@|dXO-6k9􉓇/PrrvlD[zy&SM HT?|)ਫ਼Gh:R)eXq5=FU:@`e j`CC؅*7&Y*Q529MH$P"rAO|€D!|e{̘93=/ ^]c#`0F#`0F`>! %0|˧ZjB%M>җ-x&Iq@ʗ}۲OQ]5$J8Q:FSRW e,Z{W#`0F#`Xd_x ƀU jbFL|kzYWq/-6h@>tPZzA HI37!uDuG i|@J-؆d,6ڥΌ(Te1(+ q)-=A/aOtʸd(#YVX<~ >w\a#`0F#`0| ?+*JE _}3x،4p?>k8Y˯OJͳgQ.[j>Pae98H)٥\[A"b}OCPAD"BUFFP*,C4q1j<9ic'O,) (A24]׿ۯ657F#`0Fi <[ubHBW_=3fH{l|ӁpS~3imi,Ӥ)3ҔӌpذyWՖOktZ|u][߿e]Ҫc wlJN)O=TWt pF{iM6T rqϧ[,qrL>--4|뭄W^MoN~3 48mݺ^k?'SS=Ekɇ8uS6i !G !%M\#}tS^:CCQRBUPʨqe$O>l22EZdF4A>` MF:'CݞQE-=.wʵ17J~Ga2zylJ`w]-7߬zӟ4L|XX#`~7ޜM ڔDྒྷ?o$tIٹV˯{'Y7+F][qg)9W!Ǟ{#&O4WwU-Z?]x-?\w.iPjv#7ó5JS=A,YNOO1(M|GHO*x3ϲI]ѭdܔj=%e?uNr5Z;M<)4^}O ,q Y*2I#GL+Rko}3 Vqjpɧ,3jQ铱w}e#\}M X1{W:Ȏ7.5\nHRU#=/=Мbƛ]ܗM*?L?|i5ͺcih72qε|qorjJ+vm9V7i5z&$_S>H=3 wm5C`VUxәg>v]G{NtuL[~qrzlpoN~`fx _y[:못a{lU-!m-[k7f_1%=;i̐)ST-6+ XxG""I2AD &Y Ls("Q*dA$կj[v"삽<5==$AAASˬ?]Tٴipy0]W)rRZ IҠB>ɱGf.Z.) k5OI…ya UcM !BhB£g:=psD7\Srÿq~ґ-/6ZYV J(2vM 2 7Pcnn d˦^dQYks _J(B7;rZy٧kW_f#L|H3F T rם:/;qK[zXDF[nRz=UZUfA[ݮJ1z8g\ÏUrSAꫢ_\fL> }rE)ow?^zX4! Ϊ P1 t4oi}W'yKOyI=#Rǁ2lpyFT:FN;@}zI'IϞ=~@')8s};UWrB%U(7}z<֨Z#>꾖`;*7ZAZByW}򉮟*thdd&O#yݰIel۹[nU`j+D0Ibb=L\xF PXb%&fw퓞wȊM*8صUu9A,CmBM1C{,2\1CE0ad9rD#%*۰Nl$Α_lsadβUr եhd9J"۩sŋeeRj|2  #C`޻GH"lk~\Y.q O]^sM8򺀴#DFQ( FS]x 3 ~ʱ[\#m` e 2IQn3/$DL9$=mW֎>}e2W*H mZ_ǁG9NP0M(5u;G]4!QprϜ¹j6 ]|9 ~wv0cn(!8 koبa8PZAРݍ.3@b 銿Wφ jC ْ֩U kqR/\׏?j< Νnvi2'AժVV-s~zwWuL9^ݰF'?uޯ_|%USx 5i U_/ڬv 4 kU{U*Ws>ӵ -ףJ)A76]pLڞ^[!>/cu5g*X]5˯9VMլQ5%Z<jHy ]Oy\hBj"ѱpWL=M&tS==$[avÅSs#%6l tQ3hCou}_N8X7o` w!/; .g}N'5Ws'ޠCM}N` ?{p jSwba?9NWy!xo?IJNXƷ#2ƌVʹg :\_],}B`,MN-C=xb)uN~qfni:ͱxR]Qvaj"pJ`%cϪkXR7eukݘ"o .G)>Y(q?tιN~wF9Fkbn}řgk';f͚֎>hon 'aj>o<&ۄs<}N׬NIn >΃^m!<Yo%X +k DfS0*dһݺ;,W#TnΆ.S0+ly@{I Rm1c;p\-eBɫ`Gۅ`"wsfM/rZc@Rla#x]_^~McMplBI'$9U,ٔztihr]wXbprF#NhNȗ]~?3b + ;-6s=EJiܸky? fҵ[7'<9A?ѯ Bӳ?:t LS'5Wsy۶o 5HT,S܇)ٳ7 9sez@m7 :hB. b/6+H| *L d?Bw=Wc~ ~;Aմko\ZCݜcqq<. k( .4W @&bH)#o䣜 `~mϞѺuskJzg?bg YݓG&: +i ;FحYS6!@H﹑0w|݁QSl<[K5hނ΋(q2frƱO˗;=GMkl<5~og4E~K,L^#,ݩg2u] 9 y  '999ρVx兗^ukށH0mlԈYJNz}yQӾBx(#XCdy_|V˜9sREs9ov`/,]t e(i~{}6xcȳ?Qo-vߟ+KBDsJeR>M&'Iyվ~Hהv r2lBA6URr SXc7aCڥ\]蒷BRT(=ev RINίx< r\$ٸY Nȑ~OxxsI%\9VK͞%J5bY@MZ%.3M۷jñNL#; JBrA)愀кU˔-=ʥRRg@Mhk/q:ԃ_F|iGA@??\U.[z ?q'#RvF:l(O5"ZI,{4VF~@Vf:5a4”$S&ojH 3 2tnߟOҳWӝd[8=#?oԨ;?،F[nn'v_%4U0XQ}v*trS0uȄvHP48l|9|CȐę?W] =]|4zW0+3 B($aw}'O?p .u2E${ ,,mŴ?Rn6ºV-.uuT| ğ-e"48'Xx+w-!v|6s2Tݍ׹*zkwVy(X/aYq i>ɦg#tM_L+34(m4¬MmoKl#"@{b#1ersA3Hګ?4ngj_+> 4; zy8 iVFlPl0){Mm F@}49'z.N[M1CBb6 @{ ~/UQ);DynyuW]+'c "# P䳌-Շ"w$qYGΎ8иs'=A@BHEBM5psn5揌֩e*luE.Чzp| _`]Z7_Hǩ^yV7۟.9EfM6ҵkWU#\hcsd. J-.Jbєߐ5[o&%M+O^Y ؓU'f.WHCE-O^!t:.;uBvϏJ(-^RaܬY3gi`*UZՙB3f_-`z颂R8>-,$5b 83bĺB)+x+ \ bCɃITJھM2e$YD./Y>JuM{e(TSZܺmO-ޕSS+QԂ v`j"8Xs !wPU'{D-C5o,u)W^BVЋz-a&u@IDATسnajBģUy-k\LB_|x$9ILTG]g+ih68`Ok24x >ڵug tM"Їڶm~Gv樯Fɭ<8^8V[oZkd=tලZZ| @!W_u|#&lIp";~wCpA:ڹ+U m͑dfP.8lT@[! !.Ϋ`UPjӾ ml#@OovP'aA ۝5o=LDiݒe֬^52L@`mQ|Vp"'LAc(^ > |ǫBfTtwE*JQbt0 pP R#΍ArjׯuE,v6`_i+9m5c͂ڗc$ !X'*}61oT7sA/8ֈsB313j8;/ T>Nsclj#a J΄b Oe.;7Z >xے[}(US.2QDpѡ:[ E*LڌjՁc џ;q[0(M?;c.ǥ~Vyoi5(:_F'Bh5kXe0o7Hݘ7G;,V\~\`#U&>x_zڪfe>lu˛^<&*.].=>C^t6FE^Qj*/ yMZd** ݸQ2t|]"0/ɋMf2BU܁g{Q&ԓW#(.38">9)ۭ {Ru,і_x^j,cU kYH ߺz!0tJyy 6! yjIߨ TG=mE`u~B!܄zhYFwqCpAϞXqPAA{~l_8>ЧbJ8[ i`7 :Ԓ滅-Fl B/3ugq {BkM1ef @֨V-."|{ 4 e*r>|Z Y('x z"#)!D11w7#_Y#HFD3~{TsssssoE-[\ߋм=ܢ;J|p+'}d|5ԩSEjZ.A_BwyGnl$S`vN O>%W}w=wv ؙdW`x֝*8#%8lj~N6#zV+Z8p'|G) &&6>lΙ*YWfU>۱YjΫYCȆ}̝rj@,;<!2?ia%qORzjf#-eG04Fsj?$Ll2Ѣ?嗆 HtQG) 6ׁDg|Mtf;q: EUYjj7oQW0gi̙2}tiӶn} @ڵk);we3$&$;/Eq.x-ЭoI〹:7%YN/=odɒ"Tcy zBjfQ.gОwHH5_U[>w5̈́^%I,Y |#^̵ (]߲ؑ0| ֹSa7~nFMP*Zh * -q%p5(|^#v)YhtKf訣B7M3x8%"! 7'}3[E:vVX!":RQP¸sELggWwF]tp-.ueM`vxPC>H߱GWC٘J[]qW7MxBa*Qg7nTqHcAڔɕdi@~ > vdu!r LH4S -@P~ 9l2iG/M7$d9@0,ab9,0qW8' ǁ i7[1 M#-7s85Tjw ~|Fas8gVyM_ M /h&L^z`ΨQjJ`S K7Um. Akotڇlq~7eWѳr%͜m_=h1re_0&ڴnn}Q++8 nփk(pw;Zp$]Ҩq#5EƢz/=jի4Ռ|0i2TU}YtpQ|6o\ͷpݫۅDe08sA'hG4N҃9 ilGu]zpr%jNEFG Wqx. +ib0ugX0q2c0TEP!3ipm+?h_긅SSv.0=lwÝ8vmR<֨nQx Bg]Yujlw>UlM3~ѽbb 1!g'pyKzen c *'eƺQǹ36NpHj}qw(Bpsʕ\uuN>)LO? }6XѰ7P2خw.TI߹s 8xΝ\q(~[ڵq V zvH,:]z|_gG=XYb vNp9fM[{4>`KV( g3;0<8~_/a~z0!>.?>ñ>x0 }1U$kYbSuhAbw;}1h[{bta{<<<<}X󝣎,-T(UZ[FY/6o)5Ŷ?:ǫkD*[P^>~+$?X5 ' )AG7t ̯\Be׆Bn&"ѠdF Z7da4xAPKc" a4r`05D,0PB\$~fj'@P@9!@yܠ ^OxH@$x>8ۺ4x RJ9MwyW!4:!s=Nwp0|n  E84edwV "HRv.W)+J7$@=nnݺd 'pk.]U` Ggt}if/Z\̊q.u6i=Lɽ2=vKoU y羅-E֘5 kls06z8l^1+к}]]R' '+[_vy~:i qi< m{@X jPUo@ 4ܛ7P8x ÅSI!B_">ɺ}TMv>W:EeXn޼};HAʕ/z3E-~Rû믹R#K]trT81\)jUvVPzύ0sCG9B>@e P4 Q?(?\_0-⣅ l[bGK-an{uN 56-||UF-Vtr3!.}9:^i1M ROnc6b>Ï`:))DDƥuͻY&$-iaqcD^{MqM˻g,:o5U5W~i A!qV6ՃZE4~Osh}xnc|wԆuP |@<ߥ[nGWr:iOe*Mqn w߳ªaw$P. g?3ܘ]9A;v'E-*4m)+>;d\ۼ06k" r1ZEٳg`rh̓qYOujk߾} iZs{HHjx$B R9e扵(0AK.MUhSQ̣_fvOn;E3Jv:_}Z6UJPeݽ{P {n*UT攥䑢9$DxWg,W3z{1ӧ`6h]O-38|,\<K~0u\K0O8aiR<= , pi4"vmi5q͛'?Zz]8q䁂eOk0 eopGBFS2RdY|5jaio}>6֫vmo<L㝷&k׭*WU+ T%5ʝe8rHi,N)_7|Է{Iټj*|d)iR%I׳M̕;]u|s%š9it"226Y6gV;C;{ =Kͯ;FVn&Rz|ÏԶ,|Lத֑ٽoCi}$7sssss +`nA$1ݻ4m4v Dk?j./)ʶO?%yպͲh:)udIms ([`s Gkq°J0fgr5o.,'|IdKCTfĵq擆|\@#k8Q%қ`0!TtceᯠfEn@_OH%Y#O@!5cӇf]>>$ϾZ@VA|/EGwۻSH»;)\0GW&D0J&L7,xplpvғE#ReP)[zIceNXL"AzDVUHyLG#"r)Gc90-nq㇂~؉0?vY999999999999999ݝɺԓ'Gʗ&O?ϕk6eJ Mԕ[^|pMDXŁ{ < OwP@D8Bs ~ o' K>:ʹzSᖇ0 Wot"AzY(AOCLYؤ1`9G#෴cF߈G\9}6"O' |n՞^p8wr38ΥzKgX978?kaB`E8~apmDX,,aR 0SUKF\ 7`V *,Ax@Қ0[; PTc,I=>ʢ|’NCW޳+"Kiq nra@r `eû6lR0 ri[aฆ[\|~5鸦~Ko< נ # FBN^# Kѩ­ "-~&-?ʷjZ'ρlƿӪ߰w ׏K3FО 7Iq[+|p’kXFQ.BS?˗n`e'ρl@ |o!۰uwƞ&@s[`@0`i%eO>tIGՏx[xZ@6s`7,1?f{Ȁz+ ط5 LIk吆OSKcDO=q#Óg44sma߮-O|,9Cv!(06Ĭ?` Msssssssssssssssssssss 8?4[v~n׆acRX 3,=>?qq-vHc?7c7dZm㚟뷲ug"('LY߮˔>[Zh!gy!i`wEON?Tr}O~F~,hؿK|_M9pq_4lԩҫgO0n,]ʔ-+ 5K]y=%Sީ?jk mqfHpM5"sMZ -FC~(0 0ҧKѕnXBpi! 4ؕc.BC$i:'KW*c8ң>*ٮ:7xM2{u\cL)EelAKx@B=*DP9$V#wq|i6e˖oKRßbzotʽLԣ}.Bmaw,.sP֭[?tMᚚ(O '9Y:t ?(PPli۳ρ] 3cicaH8 h!K㡔eXx@i\dRVCL%2GV5Y8,k8i-E¹5zHgB`8Y~lL?ÄG k?PG}$+P$ܹSޱx{A諩q]Ua&ws}wxb/_K8ʕ*HU(>|޽n^g}@|7P^ʗ+9u_ve2vUH2 )yK鄽aN~Y(/2og(QBuTr#EZEe=<<CUR~_Kg:qFfN8׀u[뷲o욲[Hix*q 'D:kaܔ4&4Po8ʳ<+[O2G}rA ,.~OrܿؓOˀ~}GǬo޼ҭ{ӳ{48xhڃŇy˪UYyeu^_#\~%"D0:l~jT1Y:JNA vȚS\G={GM;d)uQaF;nlqY(^\jժ)7k+իW gJ;#3c0؇&4?]hۧ3|wç5Nxxw|"`ʖK5aswǙ3S|y׷ HЎo~K<$Q?~@Xh|iO8gs v<<:tԅ?t2t=r9O=%3Ot}クx3prWӯy|6|NG/ϝCVk˟7L4r뗿89`PHԿ{;kT9x.'߱z*+Eo;Y@nEľ[z FkNx[ X/-ŤȺw%={ ?u֙'{O\|4G}5j~J[o u(yQ>ҥ*,tM^tYڴixF =Gڴ!.8r3M{Z\"0d 25_L,ԬYH r$Q\V$/!oDk#G ;_~nZvү߰A. -Q-RE^dt?9=lχtѬőQz"-"20ρslbQ5?0j`6[x ͛],6pY .ܜvZ޳W*!kRr%Yfz6ս[ ݄!!jp.&n}[6Ib17۶Emѷn)Xei,Ӧo!+UW)>+y~y'ۥEkʔ9nX]h&)-UG/A/Aۦ}K~>T#AbVJ3g!v N4c 2d5kJݺu)>xC7oB >EiwMR^|;8U:W";o0OP~5WfL?Kf<'A5) حK hH&p)1E7 %PslA1u#&NΪYbTPAZ7V՝ ,pc3Sҥe˖-RjUx3zXyۻRFuY_|IzQyݷ]i(Ul9)*v6(H{wi*`N:mp%X+WxK}2@:w+$?rezjgE-<ԳGWo|EZexʒKe )ecZk?G,:\sT鐡Ҷ͍2?7"]cE)"\nQ%̎Ev}wKH!+m㏜X@L; ,\ rHݰr1s!\[\:I -PC8:鬍4G_ը. P5HO82i 2G:B54 h *ne.XK2Bw}><5jԈ;xt?0P'+QrgΤƍU:} |5Wɥ͛r74NQW&-/L=l!MJ>y < $ - 'ڴŋݶx4_ 2{P Nw.'p]NY.j< 'RnWzXQsjlZh.] /67^m.ZҢ ]һχʧjh4h4۶q-i\Ӌ/ |wSݷ^O>3`r qdl]',@r͋_@4lk|rr)`"E\q?AMO=񞻿;>,P0vdN,u! -:;e~?rکETpQTv~٧cWHMG2lAqEfuoK/<]ovS9>=t\=)|{7M>U)p˲kxauXU~'b˚U@AWR=N/* DN *RpYެ_rspe]e{7%غR}'z]Pdwe$!OO _8)g>M/F~%O=Yʈ/F Ϝ],]¸ko-ҍoDZDc {[,UJƌp 7z$L'nEP8rPK~3tG:=_|ʹBw@2O^XG ח_~|ܷCxH׷ߌi *ll7JXG8MV=۵Gj]T.RZ^D\پu=hd0ڭf0O 8XkY.ܟbzǬ97mcqw.kws)|sW)`y绢OOUZ&mLXa~瞑reʳ/@k&|c[|="TGrǟT-$_|n2W'Hl$/}eT^|WkՕ5+9#EU*W #< lZb8}'pDfoUp4e>Yŗ_ɣ<$vvZQv[V9ZCd~sܳ4cVSJAo\sCk]dݧ nGl[اd̄@iZ),v`|FB@IDAT ~,LMC<.NRgC?Uv[*V,/t._(|٥͝>&u. BkueKl8S[SjW*FO?ty, (a@IE>+,~Gɾݻ$jW5Nx[,}kX_,ts\vyU9MwcgƝ:}˖`}ܓQMUt9+|P7E0 (8 ^ YQ^ z89J?v^'̈xp M]q-~vPQQ~AI"XdUBCHH~\%7&Po8 ?e4ǵrpMBz#ϞhWb2owB)[tN*4Jn}9 tڴRE9FLBHД>dpS[x! /6Zl^wc[=tzjPa' c@s͚՝ ~VyN,hv ^v:B.g!\%YT]%dIIzj?#gǾmjH%HOj(;(;>{C/6rx]ˀú5 +UZ*+>%y\*Ԭ4J(ZR M$odT*M >`!cI'dm\c}c5 ;܂КCw\=x:?Gyy{TY2pLQ>V!B"LjCG ՠ!w?/tiOFjh)Xtl)6lAW֕&KwSS:UȊ۱x30z\ s"9߱$119H\33pЧr*ٮ;~5ǔ"U#)CMTt`QVsWAb猹(# ھFfyLe`̺?;V"0@I9߯5k7oD h oV!ei*!x>Ů2OZϙJwSMthcr Ő?\vB*heg Ǚth{}0iTJwfzNB`:cGnznF}V ﲃVi+kYK̮Z/y*s$dDI;UFR=3]EG;CygX9k\KNl6%OtU+: x؁' gy׸q]圳%U~,sΓ7Jklix.&vx8\8?Go7 4oOZ\fm !oAypN'Sol#VVB\n?oiqKK|0Oh3iP ,ilKKٔd*uf%x~-oi^Z,4~mc12bb5T01sVL4ӡ ˥?gL| @XTpqjE`tWMvj6 O0d@ ¢C+ 7)DBeMԲ!}O>4jx[hIkvYTb%C&g,x_f 5UT ޗbQ 5.("@Gdί? P@X߼^m\1)ҏ;]D1frgO} (p+dW%!#\美[6Ⱦ k,|&AٲG'|6٫Pݷc~3tE9%y2=+DZ.N”$BLٶ]  =z}''ג9=k=8D#8s&6ŚOڞ_]K.Z*\}<90F3;YИuex8HZ"ه>4Մ0 ._d9#׾u[rO8D^[ZG䣱#Ufe5in t8fW_8-[`3Zo7լY#U0 ~}H(L>"vG>`cW^b v5QQ&jL1Ecb{7` " JQ:A?;;]9s{߹Q}ss~^>C8dU/R_3S_]m[ +۽ӭֈ݇clQ¿ljIOA{ٶ8NHj_&7VHuYܻұMHhfr–>47^W|6Cy\~n s.%+ 'Q 4дi0lذϐ/b8Yg 9M$QJtsd-*:dG!50 $zeRF>#Ώٹi"JegMCV\yaĉq[v3&c7v_'\T=M.I"o5YftU>dv$:?7aU![왴Aa9͙vS,J1=Va;l_}-:X񒔲ƝuwɪnbSnAbb_x͟آ=8#پ弓zaOP}o$%U7ts\ dv-\v!C̪]&h ,< V[YW??\tE᠃<f+y\rI,ǙP^a9ȘT k3bk\V0۞w~\ #gGp?5)$ou\JCNvX4מ>z-ޟ{#\4ܛ-r7w|>{G$dYu{Φy#5g{!RZ{Q4P+Ÿ:r G '{@-ziʨ>Ӟ ҏ\r=#v|P*{^~cOil;GpW2fqکqz"`3Ӂ(94Y*̬V ϵCN4/cy9,*ALg,M&2V5`ɋIkG2߽wuO83O<v6ӑG_,0Lqf{C2qV'{GpU`ʰ4jBȨ2hw O?\m~e{3sx3.&SN:1\cX˾3 SNysrޯ.!;HoMzeoG}w"Q9F[ ,>VF p?;+6SY'o/oUaUv3 n6lc|)Ls)'E~#xϮDY7 +Ǿ_v9SdeXxš)'H}vپW?ԽcU7{gNmom#bqomt;thIsua|YRݫL}lhV\Aȁ,\nosyƉFp \繂 Vrn u>w?+;/}VYw瞟V'uOQ#;ʫ qf;C!!xpퟯW>6 {#S/mɧ~Wwlùc̖FvX bN<#s8/"[)s^깔ǝYK~si٪œm=_A7?,~Na.aɪyaiU9DOW|YxoɰaՔѡWR[y!0*KqgcUdU??1^Vr8q+"R=Oݟ|$\Org=}^-sG6 P?*ˮj$N93&~yՅbYads\x0By1Rӊ̨ʔ!߽‹ { Kb/ /9.clM#֨\nlE%{f 3˴C:wvm{ί{!zeo b\_zqPiwk;<ޭ]0rwm_V(ĭ~&s-c^8K {)%A7le*<%߫HE sL/bվ}F±[%-0.z6HEC-mKG]Qԇ߄%[;6˹ êYg_^5D 5\4Ui|㮮wx~b+evoV]8dE?\G-3ÿ^&@qN~ |!-M/#ͥrWBAK©#)2S=1"-:!OʓS:)RK4B. A{z0tr饗#*F*mc3⊂۪ Iʎ >tlo/I; چCU۬?X>WAJVZ/׿}}ۿjvl.ܦYh/.~O3Scu\dW%?>ƓYc[-/~~v\qڐ_W} #T;w.M&3q8j RSWU&en}>GY4S6RU{VT#Gi*#8TNYDák@("&AOZ[e]BkwWuuHF;uuBu.mfZt B=tSXzog%`k; k oXhjD{H-?y5җhtm_U`VE6߯Uj A DJVcGCf9uRRwmו39#UMC| by5" %^|xl>L<:6CIzAM>W&nYQzQWP,KAI_(PBG giI2Pmgu@OXIm_'KV8#8#8#8#8#T18a]"q cCГrxl9'?N}9 uHgt l+}q鲏M'/`,1u}j4qƤlXI BT`zԧ\u Sƕ>u#@@0$\GpGpGpGpGp* G o-^oچ-~.;N&]BG$>yӎlROqsJh.%uBFC<5:'!h`QN˖.6T8LձhsCPff&͑8#8#8#8#8#9E3\lj㿭sAeXxBzx(Ӆ-HS:Au-֥}:H!PFC^i#8#8#8#8#8@#P?mhAݼ"2>/B^Bc!sυFCa9:ъrƺO,'ApGpGpGpGpGs65ߓ~N< u"`@俈zDcG Q tOrՕ@+JH-QG@H#}_uGpGpGpGpG\m4j0.n_} 5QK6@e)4! H&8 {ՆeˉkrGpGpGpGpGpGiŹO/ *%rGo}<4ZVȞ:O\أe> em^=]GpGpGpGpGpE1F#>)NH4KQ:b @_? q5JNPv!ʒzFԾS(ٞGpGpGpGpGpGJvujq)NXhˉK VF2@uki.Jυ`CNe5$YFjg /:#8#8#8#8#8|vM߅$N)_`_  ե!:ꐖ3>H?zzK9d{߯jXly8#8#8#8#8#TwÓa .q6tŷ.i.#RIZѾUN%{ʷRF$ 9i(M* O| 8BA_qҔs kpOJ\6W5IuGpGpGpGpGpGXyt"d -86|6!z%-B}%9d$n(g'Ha^Q|JIC 5,{:C^#eGvaiݾlp8#8#8#8#8#T:)9ɋeW]ɋ[/}ԁc+e*Xm5.]}:'<: ]qar"}>X4 U8:HS#8#8#8#8#8#P4]xy9ɟS 0qaWg#I]APN,v<lvtm8#8#8#8#8#T65iy(ĉyHS}U>")O"=БKa<#gCWSpGpGpGpGpGdRs|;} /s ~Y"CI0T_N%"P Ij4ʓV >uS˺ܳC;v GpGi9>V9eGpGN"ᤗ_;O*C.:?n(I 'M;j(&B2lkh:2#e ~cPN:䓇IIT.۔I;Wo\GpGpGpGpGpJGy'@ۑy/ztvgѴӡ2Ǟ#8#8#8#8#8#P׆ "ÿB r $9.@"T>']:j_ȗ`G6s/]GpGpGpGpGpF&ox.^>/IB>Hrɡ@: Wĩ9phuV8{pGpGpGpGpGH5ǞQAJ_>i:ȥr:N!`YѹbA=ej}~zb]GpGpGpGpGpJB ?c6ڤ-S'ɿ*T¢$/=q%}#=؂ZaB]Ey+$zHz> GpGpGpGpGpGr(kT3A{N`|.%} I@QFꀴZ!?4@ONYPGŽV6}WX{8#8#8#8#8#T)b.>TϞ 9➋M^ t(GL +|@6L~=w"\.#8#8#8#8#8@\c_qijJNsCԣcD䓖Msa|:T= )'.!.ۄ&W&pqGpGpGpGpGp*?5j#O^W¼$s)2Xz8ª@A>y"-Ba#Ч>iS6KZ*#|&.ۅ _[x¶]DpGZ4j4(kf:#8#0eʔUjTkɷZvGpG*(iW;mc =/Da 'O" վl+#Bzj^u klߵMx->:M]͡aNڮ=T;L6,}?\sM//4 ^#mѓ6>8f0ۆ6P8#8ut z=o`۩^7_شCU?xv+KF`T+7uOy6`SRxjt$sAx m[=kMWC|''ۢSO 'Iwù?۬:e59#8k6Eq.CJ;屃 ?b Rq-u&"aE\u,[ AQiuNN9HquJ:'.*%lH yAh_l.j>4k[&6һuҙ_?l_~&Nz^~B`…a 7 w^ԩSgr!_W\"Ϫܹs 7>ШQ^{?>`o[xqt{sΉ~/!o"zUVUSJRfO>=lqAo֌3\p,6~f9$ʼn㖴7?y8#8U= 2Gޞn? ~K=QK&ҋO!iF2oՁ-ܢcCW+d+Y_ejYe Aq.H P86ȓHWi2B3rmFRf1fnq C|>c³ҥKcޒ%+Vğ|yvLAjTmwAzn  6:v>^-[p6ω9`}G'pB1ӤYn.~k|.0WI(g8#8U+W<7:0pϾVE[ aL\`"o8l;_+y%wKfDHv!ј'NGG] \rItMþ'ڹg3 B_ \` R"X"L^=cƌ+^)|䙑gBt J`u„_y䙵d-9>U+ڵ:Gx&pGp ?6G3 tinϦUȁ"^ P7$zLċn=eѱB*v"+(E=pɮEsK!N!t"d<M("HkAlh@+@SrB[4an.:*#53u2c7ƅw0|f3>>?<`7uϭuCU#[ݺu 6od%^ʕ!FhFKLZ2'bGb}OrP;e_3OU*6xp GMvBng[fj%,?GxkڴixGus%g}QTS/n a;ʒ*SN9%n7lrX;h~C_L;!ӎ#8#Ppn9Uuϊlg) Þ'Ga F=8#8e"]!:aeH޲xח2IÖTi< .ݢ٥L1$ix2?1I=9*i/ "_''C|9 dG$P֓Jc-cحmԬqxj̊T:@A1fAs838믿>g? +W^z뭸.9СCs`fŽ;XT+{*wy'`N 3[jRpb߳gBӈW?S#8#!{pmrHpPN52bΟB8ˊ~{B;VAl!ĶBp\Y 쯉Lo?Vd`|π8ǹ\pO+lkJ8@O4}F H]z?|<{```rIR)μ29: @."Ei9TQu-֥}Dy(#L!/YnP[xmxhb.\8S @ŋfϞl9~88xܸqqK 6 7x~g7|sxGV[m7~ʔ)q\^%$xq=SU _$dK߱?hI?ZȬrGpG`-F֏O, Cc_t_ /|=Fh߾}/MHs;gd[ 3 e}J ,|d7/<-&`#5̒pv+[o8dС[q/nM%oFZ:0՞?9a0K@IDATB߶̓?+m;#kr'DY(sFQϏ a˜elS].I+>C-s"ႎD/"84(]ƴ~<#ҧaGeC:Vʆꑖӭo>;hYka[ݾwj0:wO-:qҺܳTl-[X`[‡0{-S/^V4i;Jb9|E-Ujz q.a`6pu9sAxж3ҖY+y#8#y]\b,5+VR18_hQxlO9p)O<1M̳"2 9v73 ϞgK"WU"mA{vgfKcv^@(ϧ⺎#8@!C׶iJlڰ~1fK(IgmBA2.E!pp\J禌8!#҄|QI#8ɓ>%mZ/]R:c85Qtzjpu8@7 ʢNc U=٤r/*V0na7*Vpq)z^8{^l +u@'V-@^āH3&W)8#8ufqe H6B7~ݺu SNRʃr `\ ٤IVyk#Kjѿ_|8kKeX-u޻W&̦t xZ7if.Yuៗ{4졃–Zź. ?zlDX3krGpGpqkId5B޽׎(GpG| Xŝc~[\6iq PŪ|ĹͱAP."G6ev(ÖlȞ[Qv)ĉ`A Ӏ&_@:O9"B&j's.u5-ˎ:R=RGm9v8l q*&Slmrpbv9~8k˞lӎ@`ZeD+w#8#8@"J={ƫR 1GpGp>!r݊S&8ܶoJ@W:=:'8 iO}#r[4THSIuq)MℲKgOaQ'OjdS_ j[ՁXX![o,rqGpGpGpGpG%$]=w1N+Ҿse*XMzW\0\ĕF_^ݧVXD}r*>g꒼lҡE)gm+%GpGpGpGpGp#P?CBmʿóK9J!a_  !:t&MBl#?.H~^U&)_m+4/w{˦aFYf6뵉%ˆ eҕN3Lv ڦwhf$]Wa7⥎#8#8#8#8#8Y(wCFa 툔gYPā(]\G˥U4zi_*'=[Vi)ĉ1It|#cS ȓi!_$FW4\蓧MU7ps GNݼGع{[s , #위& }{|{<=aVrqGpGpGpGpGgs' MȅtIF_eI=<ɥ[2 ى##ľ@Wh,qu44F:-+JfgHsi#~إ>8!.))W)~ΨM<^ƶ`FceGpGpGpGpGpjB ?'yipܤui=!6 CW+ącIClypG\$)04Fgh8I#(U. JY4Ohj.IBv/aEza5YuG b;|O'@C{wLܷs)'B O2f;sy}6с@۷g-Tq qD\?l~VU#?AxY6m6C l~jGO5]V5qiI5N;8#8s]7ZKGϊn9#8??)"|84V!P/Z8r*&NuN#/w+N鲟GyVQeʐ:Ogt'`,#AԵdC>:jWehtЙtÜ62ylF rnp ?BlH̙X=)1G[-hns,Nl;yau-gYKb+%&l M{}64U*]6^"'VRpGpGpGpGpz)f^堀+"1HZ@@>o+}9$f{S]iOGG(CrCڱhG>3:<{VYC]4_d/`f[) tE8ŏ;S)+@ݿK=N쌄BtQt`}7ҷƗ<m+:V/t_EQr׿N~]Jgڥ{X o'0Vm$mSJ VQdsqGpGpGpGpG^~[6e.n4|7g) ×SPܹlYVmRF\6ˆEc9aNA,ap08u8G' !B}\ "5pJrVc є2;7$Q^;״9Q%R|_uΡƅHVMîEd>l+tJ8ȟh6ܘ`9ZJPP+!$<왏JNJn4s+UrC69c`t<pGpGpGpGpk]$v!aB!$!4N}KSy҈eOt%]/l[g?ms;[qhnڙç|yȀaQb۟5]ۦM|8cawhzȍ׋[M2r&iY#HPyt֎KV#:cT[m4 s rRiYx|f{%h'Ű[ * *JrqGpGpGpGpuL4HSHK܀ vҞ8ptCT!I\G9i9 dKV[X!BC p!U:DdGDd?OFj_uLyj7&ls{_/;y#oQD$h=fvɃE|;l;gq\-ݵE^T"`ۦǯ I)֫ >niqP32V!mIt@PU Dȇ9#8#8#8#8 |8QD&|5[Vo+$gNy նeW?Ch=l"cn$˿%Y, Eg:&}:4 Qg/>y@՞5'u(S諬S]ܭ{o- 6?Q; ؖ'dY%Eq@ĜlqTpAR /XYc˲]I*ˁ?s$q3YK>nLIGpGpGpGpG`FFo\l틻J9?nv$/ q%}òI+f팒>q  H~J N G9d+$Seqvj,_HgG$oL*L9c`Yj.ڮw:i9npGGpGpGpGpG`]@0I6BCԋ .Ih1Y&ziʒuGA]9p.Ⱦ'E}RAq0u!DhRХ0Fq}쒖dt(.*hWD8<%l"lߵMN\v<FN9àέ 3bp@O ؔ%7VaQKtHzpGpGBa?1޲I0Yꚳ(0=䠧F"Zb]]nd9e* +N~X¿xq/|~0tT*b/_¡'8&-(9ag~﯇v{1ߔ٥wgYz(2ϭw KUWߌQ!9wo+rZ)o}QWy]c/o]pu -+e~'r4zq@>i9Е8u('EN|+YdAX)#pU_$dNSچ7]nZ<\U];?6YKeg4pfAiV:'%3?^eЩٴ{8#8#T'b3f͟Omα\B~[i]7MvM'f|-O91j5N '> f|%-I)qb# 6HON3LUyk_CK :<|-^?>ߜH_lC>o5 #HA;ϻi_#K*?g)-ž87" I_<79\u{;G?˾tcSO:oRA#Tg'A%;A\"]Ir'Kꑯ+}eYjTR]ndʇPWƆIhTHQg1p$$>鋋˙$})L.`NF[]lgh$ӫ Y2WJjWjJVk YaTqps!6 ǥ߳]غS:#8#8uVmgAl|]ۖmhqZGd $z_O + ;d2=:lӓu*xvWA||N,hlB+wxRŒ.iVB<>,;lBw{Є ΗɶZ{g\j_C,6QS+63wpR@.ܶw qzrTw.1{cv]33x:V0@4ߨ%/m1I <ߪitk+D޵潐-&7yxCl7}MeqNw=m5^Ls"%ǫ1Vcg5aAb@{87^u|C^fn80f%ʁvqOe ]י1M_.ڮJE l\dV戓uOx{ĕ;{dH!cW8f$ ]5,XΑ9f+A<eA1\2w6Ci퇚/c8Gzul91Cw1+^[whjh{/н3ckX<8*}m KlPu_L tJUw߼=GpGXmK qG? a]2'9[i~q=N@>dD+g1ܭ{ES,>h2ö79 \dD.F3q-Fs>. _pmc4]'C=ph?ϑ4=="Sfv?>6Ψ,nx[ {HwYsmL.9=6L+o\JZ"g:8⭉Zq8a읊XH?&tx.#8#T'8nSm#3%y7s(` yMm~̚dY$I3]eƷp@Ѭ>rȏl;$NF^yPiըaѬ54)<6f?vЖqr)IMpb&owg(xfշ˻3p4Hn5GHsg3տx[sPg.G7@ZßH Yq>foc3g3" 83}x@gW?yٶbuMK@a+m Nn%KJ}mU9+[<ʕ{OOՉuvfwlٹD "<wԼq\6 4FR 'H[tjWp~!8 x8#P9 U#<OW4-BoH"E]ԾEmb ]0d':G(C2;:SFɁGZ2d<@#O6O?$t)/W ܠ]xiʼp?WLJZ W1t@ҼKa[ C 0':xl7KܨcxPu aъ{Ɲ{w__=-vءyyޡGIs}l7sQya/e6&GpGpMHǿnf@HIl-t?^HL@T}U  ;F$QsY 5g5@L6#Y2␿}\|ȉq">tΓ,K;Pi3_H?;8)LbO[IP5OR8D2̘^'V0<8woVPC8n{'>+j= Of@]&w%Ec6WmEd?g }T[LqiZ$i;#d<+ÿZ몝7 }m=X=Hn%|:^Sd!^CNJ=VGpvFpI\|)Kr!_Bq:RN(ޢ16)V/iِB+-5NC\B5FG,UgAT_u=}Xu@hGSWLgC|`YxxBC&ιxш6JͼߦS ݌?p{]Z>%z00ϖ!cpܷ'}o0sڋ六&-Z#(Ӂ~(DgĬEf16iw߯\.`Jmaav3Ǯi:m.~JtDdc`K-}}4=7(g; ۙmGpGp Bak!Hm556~5IhTtVaO6i3_x#8@Nj.}uxwqsJ%+dCƳByxeẃquA޿c#ar=Àvo[WVw~^< dĪmmEcSzoN[HKpVnIjˌyrqGpG8oK3|mè>:zevr>WG7M|qx.geIW=r? ?V@@Ngy OZX]rΠ@}|d$Iϙfb>`0薶J7H @J[>qͶ6i-8_@_x>Z 'z`\K̆C|};'ءsT?a q90[r/>/jT4<@p 8}{|6g\$9Kllk&V |[wiʘ~qC%\ Υ`o܋ڋ+4$>rY)u0a*TsGpJ#P,_ 7 𵝌SƗ<|5qBZ`Yi.}Iٖ}ꡗL}BSH\-T(K4(B # :*~djاPdqk+|}c6X{֐r {ܹYY*sV8@9gڥ̾ dYYOC?fѽu\p A<3שּP/&hѨ~̹ esWscvavn O E>tf6]x@.][f6{(5 om9lYy l%+g^ޘ0lb |B8tGpJG2U[-m0]BtAwY-t~pmOpjp`t6@@"es y@>ި>eKEUb VRT̶9gZM 9xMQ>׿{pG +p\g~qSmS eJ=վ }D%NJ2d#ԥ!:L>8%hLSc[ezAj?:W!G~CL:HўόM?[8_4>dM#mlWt@O[J{tkKC ł3`+"VM+ })NrP Ʃÿ[8]JSFpbc1l˜Oߤs~̴0~pN8#8#Pm+7.lm[GpG4V߆'&-n[)ϲNqN(Kv#fG˥U4i_*'=[ViQ'J̑ ӱdCz8K"$eQOBl(8>i.ꐇqGpGp8ׯx]pI>t+.8yUnYyKUk_<*]+*`/b/P,{}v˳WT=ޱ PĎ~wp)kߙ$;;9kΜY;Ie!pӆs6B-'>s*WXTZ  rDם: TSL8.2w9hGhl߄?c#`"cڄKKc Ja+ ΀ruZf1F#`0F#`AppܜO N{+'ءReO9șbQI$-+"* :c0tB#ՙEIW)u׀8.%]}"vb@#? 3C]jەz0F#`0F#`FqS.'?)O}1-zJq{#fȎwVCq@c2:]X>XKHOv(c,S'Md:DJc׵0FUPu0F#`0F#`ii5Nt !!9W\C]yAN;r6?Ƥ#`0F#`0F#`hj7Vn{w^9*)H;Z, e8H)ui*C?:y="l#P1ܪS#`B0F#`0F#`@"PU77g_k+bߘ"i 9HA@~9)BsIɞ.@=k#`Ae˖h)0Mm#`0F#`0Fhn{t0R@K M) b_?4ګ a rBH/M?,F44LZjr:#`0F#`0F#0Fa8l?!N])*U.NQsQT}ǢBe'ƘETD`0,i9y9g A{DJ_6(@PC21QArF/_z#!^uDQ:_((<(s޶66|n0F#`0F#`h!W o ?Ẃ@@<MyηN8oz9-;vzqvuj}Kuɹ@(R!L0Pd0ur 0IUF;te?fP^l=EO0±O*=r"yѱwIt)Kw0F#`0F#`0c_%z1N2kxǦ^y^z.ǿS=lHiЦ$FCbN8ꄁD>d'U=)i G@z-e#RySЧ6BIrUeN@5ܺ`Y@IDATQytM0F#`0F#`9ESY#S.)8rqⷩC8G^'N>GO}ѿ }1[^q"hXa0R2k0ZU mG0 8d<+[K۔N#% W95;8ݻt0F#`0F#`@=' -n\T.th'r?إ/'ׁr~|nQZ'B>psqN.qHOcUb#\_ytR"SXn1+ ->o0F#`0F#`0M@ecr_\ .;q1IhDdMhqЖ~ԯR(+8tQ!q" 4t @<}=l#t˹ס裫4flkO v&eأ=d'vϹvR(8d Xp!"ё7=tH94ИMR\.!r8 _>/U)ys_܁ @q2n#`0F#`0FLL>yU9eH~iv!OЏxťˆDb;*)2ZPЅ yhPP`tMGvOȣ[Rr6ϗTvhr yq]3 ]#`0F#`0FIBeyxlxmJC8N[c2rÿ?Wxa <_s#`0F#`0F#`IuN⿥ǹvVyѫ+;r.=%Ŷ8(8(!3PR94XA9mu.X: =C[ CmHU8Me^p lfe˖᪫ |MhݺuԩSz7~2h"ɁK/ᄏX:[c5ҵۉ0fe]=/g1+wy5aF#`0F#`0FAw& FÕեO}^&{8 iH՗dTu|^~YƉ VuS0 z` C INW^9 ZX}??NW%W4Na-lI8f)uYay 3O8蠃ˆ#f#`0F#`0F#0& g)&ZBplp'\B_s( uЎ6'$ /SDpbCD,n%uH+@ w^PHKxG}4|iE-X~-r-wMkVX~S_V@*gϞFN9唰袋ZoժU8C´N9=bg+WN8!'8է#`0F#`0F#0N/삈Pב|u|66mϦ-xoRϹo=e<u^T:`tBY~a*'O~~ac#?`W@R꧚ziq[\LoR_0s|iI$>hꫯHM74 6,7sIjx_::VI9ieĭޚ{IeY‡~Y8','dӊF#ᨣ ۷O.<7R6p%W P^N #O?ErZy]t 88ypקP4챀o}r:X`9tMV2h9}SϪ6۷oばI8/6.6:t2a Я_@Q:x5Äq0F#`0F#`[[s'LᵱE[+ TS{8sh#^UIN)9^UUd~B2<Ɓj:`('eEdRF;Kvy@=mHJ\csi?!$SL1E /Ϫ 8 v\pK$o;,Hrn۶m N_A#G&e!l$ϯ*!Ŏ^H{}#`0F#`0F#`z'sRߤpՈo%sry.[Ӗ<m)xՈ5(Ru <@Ii'g\:y}<-?u5>[mU"Yбcǰ''5˿1mQX|œd>,C/i697Y޽_8XJ+%7ޘ ]SNXJҮ]4{PO?=~"쉁ڈfeI~1F#`0F#`0F`#3j.{L/ ^N r5pAS#68jퟶ5 1 ġa^O=Tڛ`ʑ0=`c2ҥK"NgvۀE"Ͱ Z53lԼ;D(۰bKN7q#zr-S/>@x7ӦڄBp$|afroF#`0F#`0F$W"4'I+{wT3*Ws9Cp9@!/z1iG*{ԓrSAjx駟?~˖-]w]`rrw]w5gNor|'L('> _}Uau.P,7vqUrVL9igBhï{.p)>(yi?H@wa1F#`0F#`0Fw esN=7|5P,}7dž걃 ئu)=٧4P =]8 u Te誟|(].s`@gxs06lsA("8n_ }i9f'%uq >|:&s9⿸A9;z΅ }ytY_lwҪVP0YJ:Qy4hи0F#`hBIF^/=FI_ (` +NLEu`'SqP'{5 7 h_As9K9(qL)g"ہ #^r$k#`0F#`0F/6q=B`3V! ܦe!V\/@7&"!!B=>]ЧE/)L|,1ߤ7M3F#`0F4} <@ wk-"L1ᦛnRhç~BlN=ԣeÍ0:_~yy*!EǎC^B۶mUtA ^xaxgIK/WP}7症PH=FmWDFy뭷?j ޵kװN;%C ~xm{ZF hjb^yO9MۆW'=vT V$H\QUF[wo,JI  Iq(F.qN{գmσx`'˞hF8ls{<?x+3?]EnְB ^;w}i_UCB3 S:tfB!_~Ǵ{[lT#`[o\s,޽{c{G'Mfi8׽' ."fBvq#l. 8`uY|I|Wy^}pgJy[cb5YW_>GjF@|676B=r{ιyڊWقP.<"=Rk E +)F5x] uXlc+5HvdW A.VyPj#`0F#`3#u1Ao;  HDI'|DL9 8 aBVR[H}V'| K O81!_<  8(,F 6lXJv%g}^z饤jMLg5;yz_+]Y]2B2AJm+{PFLqS۫mz!6KB^WZZ'00&[4.VV,J}Rl iMmW Y0Fk̒ι+hVƸUW]v}4)dFoeM n _H;'_~9,iuWĝ>{XnLqZBYuA^dE=%G?buI3Ֆf;" ,R |s=7/i@]9ٌI@p8pOʊcBӆ|8߿R yT#0!A*=?XcpW6%\BX9K q;8|}֯_pYg5:(S@zb;GaY -Z^(g}FnC8&5.nȫ[/l&U9UVcy>w!p@Xr%k^s=$w WYeބV[m5:3˒wftAvJGqDXve ud{ RyN,}&SF|Gwdu\pD43bWÑ馛.|뮻ҽ=sAB\EY@8f=> ~xjOX o6Gb0pzUz~w'5߫m۶-8`'t,&_{)<;mP8/>~2Ntr}R𛏕CL :SJ+V!vr]^@ w΁|8|5V!xrqS%\׹ſ&>]s{ԗj2D*0 F(,Xʸ@]0uSƃ2.@er`W8P=Vm韶?f-F ra&D_~JĶێ0i~bW#^e!,!QO930ڬ&4(NAfL̂%7ΰ={6 ˘O8'ljM)8!n98r,gp!yMU~R 1JJ5H ӟly AW6Е>):9B?׸(#e- 2{? 1o=#Ʉei3#Xwy?̐*_X"c&6o,Hf65aZ<~7D@K(Y ̦Z߬FI lBf&"Db-4=3Z_.GҞ 3LOH\UifF,Ħ@b%lճgs"S"6d13AIAß]#K}f-ܒbhs/1"lv'3#G5??D36֧)csYXBO;#8}gR|暡Yիp|ɑ^J8rfyhl1sIPy{eQ/4=pM>BLeQ"e촹kr{8s;!p,+i %G9zp_Zq~fe7ߜ> <- L3*.'>K<(s]cK8qQc^ss_@3t=L1ýcǎ_q8#fB|G$:d71'N$ z85Swᐌl̲\>g<[X(Ll5wX>}(qjF< 8~Cҳg Œtl#8jqu=C,=ʟ>Jr^vei?t xF/':tHՇvXaeWg :L(!EKIrRzՔq3f0F`R@gm'07,LdbՄF3 m;^Es??.Tb ("ΩӔՑ"ՀS:rտڪіv*S[1@Yǐu(cN GYZn,sAC>T32P!C$R_=QՒB>s0˕쳀0sas<͗vBl%}|1>C )jD&_N \܎jDaȘ}dfH@ t_xo:Y@x^ٰ|X)#ɯ_e^66e67f!<9IP}ٜ:dUdh߾}jfϐЖQL믟V~3ijDﭞ|.yOyaR_Wg0F*`f;LY]?0͊>ojLSWiO[+2wRT}Ǣ'[y9:皩KN<--8.4h,<9O er .21QAr٦M޿F!&@ AUxf>S59iLIH3 RQ79DCFNSL0UT-,<СCM=9{&(3|9% БGYS-hFmTp@ʏOww;o Ş|XA8WE׉@gpP!=*xyVl}PN!@Ybigq;{a5V{qDZp.7 ! HGW|.rng0F`PkVF Ẃ]< ?8oҼ;zB{y*BLrkcfƆ^gLu#b_RyVp58>UWQk\b0F#0>"gxGJ2iAe'bC'sN{D}@&)m%yҽ1/st8: Te3p.NڒJ?fW_ة0Mţi rئϛJz ievV@c]~rL{c_|r8cYEP{_{6~٢N>TؼgEo }X#`0F`"@ 粹"@ S1v8 ĉ۪,iK?W?s 7&t&#:Fe20@ \>hp.]qVտfإV~1F#`0F#`0F#D<8qǾF5NGC r,O!y]@WSF=sv#`0F#`0F#`n;[ |W-/"kMc0r2lv'E;PX#S!5=0F#`0F#`0FM$5]+ D}cA9 j kpr*AI!%6˹2.˰пfelƠbb0F#`8xg' U#`0FX~~;4oMW-RU9jC8o٠NcQa۫NӾTD`0E^F\#pr6yi-GOVe1Bg4#`0F#`&fj;1k3F#`FQ/2&/{<ЃW>y}\Rl]yeur.x ©cBcslPyt1Ht5ew8##`0F#`0F#`XBYo-; Ib=|5@i:c'Cs g9C]9ӆzRla"討r-/|fiof~CvR>( ><,袁 30tFm6jfypwbv_uUaHwҭ[?{luꞌ0F#`0F#`0͈W{걩)+G}4/ï>+Rءo1q)o JիW O-tCvm뇩*qCu}aL!.OPdw 뮻nZQϦT3u_(eKTRhr$V>oMߦMD_wu}V\qdcРAaȐ!aKNӧj HNT@?/$?! gm馛 O=TѣG8¾M=OB 뭷^r,"aVqdg /Br,RguV@ -PXyS8&tqd0fJ ;weB`O\1F#`0F#`0M"Dp9.>[e"9N^y? <9v'_LvŏҜkdžc0jtyD1yH4X }tuqj6lDrPFԎ~4>ѥ&wy m۶ MW7#<0 IGdبT֭[lߒ?Y!3τ+2=#iVHkI>N^;|'ih{lRnVJy4Lfup #_}UZ5A1H T=ܓb0F#`0F#`&)n/_ " Z2 b)B)l~vJ8oqrƶ+yю2 yυ_mJ(YQSF 8ڵkt;sbOءj0E VB" +-X׶mV*%_=/)e%ŔSjI&.4F#`0F#`0v LTogr$*L6Ҝw;NJߘPB#*N(nR@N@c_6HmY@{tI]\}lu~o|" @{ <8Sеkd 5PN6ۤ=\rD:ছn ?b-Bsp 7U mYw9U>ǀCiShHѣGdy/R52+$*c={wc9RأJ3F#`0F#`00 S m& -r٤Mwԫ[yu~q|:}h%5NK:*YY_ ԙ~(Su4"st8 i>"iG X"5ڿԢ BP@\W:)!j0|w}7oF`!_ᄡ΀>;QPJЗJڶo>|ᇁC;mxI6[;H{&s1aiMe'J ]ZlFjF#`0F#`0F`F7|o᳛V˿˙Ԕ\Du*B^R0.e"c6庪#&"/ yb.ؤ=:!#Փf`. yCj*8 ]@SN(1 PEgɕ#bf(*\{rti&P\&N>|xU)\RURB w(OZ|p?R8?hРm}#轱[Q\`0F#Pm[[ ҺuZX#`lDy\>c{]uoq+&t (Ofk2H})Wу\:/٦>)l+O"jWwV*ri>08йd,j ^6$`Kyѕm.!BS(;@-e_LWa6m.0rr `K{kq0Z0F#`0F#``C^ĉ@uÆ&@O+}{>iųGGJiEQJJQs!ņ:& e ՀqBPUj?6#`0F#`0F#`hZ#8\շj/OҨBlΥ @U:lQO;xCr٧\^MyR+R: #`0F#`0F#`hZ^/+0qaՉ`u@9r]APObx _?Pߤb0F#`0F#`0Fhn{LG5NtDCs2׹ǁ b_D?-  :(9vlT#`0F#`0F#`hZg6/@IDATJsѹr;N@7&2.y"?/ǖ6U,m(bH)ui*C_:yY0F#`0F#`0F4-{"U7-ξſWr1 B~*vA@~9)BsI]W{l?6-F#`0F#`0F#`Gp(8ĽŸy[ !ENAءp`Cz1[p:4Eس#`0F#`0F#`hjkÁ7=:ÿWPNƠyAH*="]Rʤ+pנVkfq~HE6&Ao/?t9F;odɨ'*~PrÏ?|?JyF"W/_R-ǭ.x㏪: >{(֏(9)y.4F#`hN^|tW/_񽀘FDcCA  ѯ^@mV}/mi2U*NCE8]Z"7\vqask3:4,JanL]ǜ}Au9 d?, |?aͷ[{w:Gܛ[^xz`r"sqUXRB *y%{)|g5WMIC.LKW#ymEX&3O CQFC )Z'^pi*Yt陧wΧny?{y:PV\pNG ptlsmP_|R??Ti@kjA3 53zy@:>^~vPrӡcB6$3|Nԟӱ_}ݰJ{`\ḵO?zYg SL_> 0ر{3F`"Gtag__}(χQ?(֭[VZe5{O'_|y<#O[oay -dfi wt}rʺ;7"S/W?އڕpp\} gn,5bK-m}ɇYyiwsB"E)}J+9 Jj&iLm Wwtgl|"ګs/ -[M;vٽIsS^{m; Cm6xBY~:zD8C_r-b0|_|N?@ѣG` }ݗh_M7[oqB L@؟wyaРAaxaYfs 3\W\B?paUWM(|>s= Zk{'6*ؿߠzjx 3 ,@8cSMQ{,\pae GyKƇ*9MӦnjҙWf.l9y{Cõ=PѦV /]oxt>m+f4C ?SAUCFCNTu7qݔG*[Ω8wړ /=RڠKDcsA R5& vɆsp <εʩM:1 ]9oXcb@LJv: f"s qry'>wi۴j?;n^4U{dGy; N:pc#+3C\HP>&Yhxg e٫g"2 F&LqI\7;f,+l*%r嗆[2A6BF"ᔃc72< } rJ+^wܑW^yeǰ_>s_pD7&NJK/4l6GnK 0Ôӄ8&tm&r@x賗9* 詰|6fH=x-CӅO?~JzV%mz Yq>G_#91_N B9oeb[^-⑷Z9S ]lO&F` צ=9 K/ 'Ͽ!<ۯ/=cGHV]g"i ^~4!" t g9WR/1#+qixÎJ9#벳NEG'`w^Mn{&ZS1㏆}y|خ>t$."{SH Jdďǝ;(D XhfoH"ķ)FQ_GF;;* {RK6NB07$ɇ medÃq%ɽv.nyRͯ/zH7^~1~葁57D&%9)~=B׸lِ1SvV_aeX,/q !9vv'է3H9/^Sa3f|vVUz\:.:}\ E,K1|"K3|NRC4@E 6mtڂUȧ~Rf3?0pT]t.3S~뭷x``V,LWf"BO̐EsM$u8vmY]lSۇ={5T99tӅ' ky睓1=SOc|w fƉq'ZuO>%bW^g];x4K6-ygDV p-8xpBG1{キPs.KdD;+o‡~ʹO<1aĊšX0ga}xF7=\rvZ |%< Y sgdк<c V$8uffπGyA;w+PܠxHX|S?o"S>,2cß&q كoKe}O?VWOβ`xW cυ[/2ߚVG}EiQr.9:$OtI 6#8yF,Jdrb2]E#`W"Q^BQv¼/fnn)ton0BvLtY>>yQLqcȲ N>!BgI3RBls?bOb.Cԣ{ NB?~ؓZ_Dfg] {$1:>W Չ2n<4zE/FzƋ/X+3 ^Xm RO#ݝCHf+C8v'Jľ7( BKtJNYD 9䍆39 zSX+:)t 3CHO:J{P4߄Ѐj+:[>g8;:\ޟ107zKSl&eSŠ9\%EiR(FOߋp"PYq&\%s}ѩ'> wZ2VJƧ:3ս>dK 1e*jsvN" җ^z)|%6dI#%b@sL-fB\3Crdxt?3a]vID矟"Bh@vߞ{~ !Yd!}р3‰/|{S^4۞X\m q!^89+N6f.ayINz(i-Esΰ:k"k[qSrN; B_c5{dK@=ѠrN?cEMgyfŸ\=gF*;D$~1F`!jl.;#ϖ|r Syd-vڥ"<<סC(fw]./Rn|3 8?ԥKҶm9ECig ?2°F%aڽ{{(lԤs 'I#|5آLuhcAth7GQNJ_:j9ՇGSVy馊R/:cu LujK9]D[wVWW[RV#0f@BVyDdP^:66?s\ ?'bַ<fB@L=RBH bKXq.;S)3-Hѷ_59Xjff oW @& 3 Au~^)d fu:ofuB j6N~@+ڈ _~iz /n~Ϳb>Qa2E2e?Ìu$,CdP4{z}|h5X# G u!dt [SgYoa9=lǝGt.c|;i-v%$,/C| D4 VyS8O93:+}Nͤg| W_}NC5&YH RA,zMr"@3'R6d9G 7obHx ͺe"BCz;ƻFv{.;蠃#Y8 p&d@\s.jFq߼@w񳲔n5eԵ3V;p_>RѣG8 E fojph.pr:9KV9r^ :tH$={ +0j.UyAsXJ,A4_r%wNL&ܥ2~!0Ôӆ_{8ufj5]׺4i\6W"E򫜛?q1-hDd۪ryO=:hQVq"0D28R|. " ks >/`e7)PǸcGĭ hZ6{"?~h!)Zō߁1!o+bqUi1>|oh$*גikՊU$Ͽ`2ÌS/>{5vM?n`zqu=Ҫ#t4X.@gi@<~6ZEf-q p GF#u.1yyT& _"}޻TK[ȩ*{@te|VY5i2J!v? .$>Y[~5Jڔ^*Қk.[> 셳m>lԊ{0g&>_!BWQgS(cƮ ƃ 3տ =UwчwrTR89acI#4!O:tᄾaCn-ѣ"ݻwO2{)Dxmޙ7/rlq\n9?O$~ l&T+El)7p8@.pE !Zn%*e8>^~崡'$پW<,Rk +47x)СCC-; 6 L_NZb[4@vuUC IT)se#<)<+1p$¹yy1xPÞ  H*l,a+o<Ss">g'xG',lq'1[ ƕ 52 @2sI 6~4-{Ǚ n98wć{'Ģd ]eݼDʁ tP`.s0(t8Q^Q.j 8]q۷':(ގDC!)M/ tdÝ^3pJBuդ0ozUWM^ziq3g@!?19utw̉ Z#k63^!˚"~㶰kV7g g$K9 kz޻Ŕ-QgShg w?*C=Ti#a]i#\Ve O>Pb ;Z͐۩:"ñCK,Qf9 }݂$ȓO>9(vwn#ΪB O=cׯ_裏RfͥCiL/[#0OW’z ׀B,?qX+)LQG=1 ?n8Śk J9B89xr +p VO+g!={Pjley#O$^ $E` zb8ҟ.m:.pLOudHr] 6:զ-q'%y54~@PE!D5iu)b~ 'I1‹>bO0I'K15^ꁬ{Bg<7~h"([ԈƲ5X{15vhb^ƆXc ,(w< 33˰; smDϦRya y|Y6{/7ܖ͈9}̔ Kbl\u18sYk1Oƞo];{gNdpH.ָF߉tNkb@~'"D:K;_ĺ䳼/Gj-N7?scz(ѴZF^ـg3人XN=6Zf6f|k2ۀ,GB!p+3 !XiqG>XdM2NbXaHJ#)vEGGG#y&b\g5$*ft1Þ؊ Ϡ:+>Ә;J,ٴ l0SMΊ+fPpbLTpex~a3,]<v_o8f)^]n=pcGNW2G?=V Nez_-^^(|xk8<6xo!u@_PWil']ҪO>;!~~k+cB::O'2S:źUG!%'(}tGȁBuХl~HJX?FH_|0?NS,uz]/yt7&P!g/?,oq5 &f/HHcuW<6&cʚ7!K/Q:?~adm9Uicnj+=Al_re`\K̙OK*^f)bK5O?+hFk٪ư7::ӟGe#%þ 93\,F4,_/<_Fgᷜ 0 7YfƵw[l1Roi}|Ɍ<9̳&_0|,^~Yt?pزD- c#i]r㇎)tʭ6N }p4?Qwd'>-iL=?i'"S<; >N72Փa1S}n!$4ٜڠQ!&vzdӭ1II4 <|$r(<7A4 >OFQ꬝&wޭRS֯Q>xhhcH}v?SFn#`*D( w~1٠m_VN22IT6uf7hbL΅`H~Hc9NR Tq4&lR 93B6֦ˍh9xưX+3=Z = K!)@XsN8Y[͉PZvh>,3"Q: 1_h-KɘZ}''0p}8aODd?!Q<*MhG'OU/ˊ dHR_ʣ#N@z*W>L'J(]"dțʲh!́,D`oA| )OD ?6*eɖeW^Ik '{9:)w{m{e0FrZs #`0.aֽ!4eק sH,!~=F;U'G9Bxñ HC:Q:$ҞN '⟺T5]B: 6:.P+%sesnKC%:ؠ2"7w`1F#`0F#`̈zAO&46q⿵sgϢrOoOw We4E K9N%Tg'CtDԓU9zBuХ\ב>uBcn0gV?ʺqU gY k#`0F#`0F#0}$rQC&-_6eCꡫR8|%iQN;I=K8 lO1i$lQN@rb9B<7R Ebjgu^(,nR+dlMm7ap!xWbF#`0F#`0FL/ K_EiHPY4->e#PQe箶I3F#`0F#`0F Z=mN QO$q:ASrAe8upT>u-F&h:?_ԗVJeF#`0F#`0FT-mR;u)^ #j"6@eOFp )J Ğ`Gieʉj&IvK,^x&[Ͼ%d9  ={,zfeld_XWj#`0F#`0Fi]FF9C!ŞO ~B )CХ#/,E:&d'8yK]@BR['INN;]vбc&?Cx]wia wq4ehEm^pr] w?8YW>f2%Ly0+Z F#`0F#`0F`Fa9|5ܴzݜyjP^E2쳇/*qu] kPWWvyFg%h-/8\{/ j`րB ЭE?<(LOa6Bs#`0F#`0F#0xu3Vt[qrۗ^.g&zNV #C;BR^ ُryVȓÀ%쐔v~&7e "իWV=|6矏#bZkC~:}%ۆ'x"vmaȐ!am0`} mYh߾}3fL8sb۲rENaÆ?<5JŹp} ni?>|c^8KbܸqSO vXwyL -X8c",{G¥^kÑ"flAEÔm6Oy\#S{9uf_4?0F#`0F#`@!оm0q2tefCk@ ' !i% ūcG`FAj|>y8Tw{&+3!߉RKRN _gu_Yȅ^Cf H~́w_e|A}@bqXz̆:+L81t5A+?9`+8 a/|Cs)[^R}~~1}˖3jscr?bcmZ-ٰOr!Sآ0F#`0F#`@E}+cց׶ / Æt`{UYʹqūgќ/8"=B%EK)Fy e4a+O(; O'8q^9g 5[@\p0|)CJ9;M6$1G /5,g$1#q >l ^x򇍙%ԥNʑg//<1~ mM0!wǏ]yC9$yOΕQnSn/Ly0C1CcfC2O) ^d0F#`0F#d^Xϼ] bM!5V" 駼8\vsj[z9_{Ikј`Sž4"!61@DmC'M=u"{。W^q3b1z͖)ln?? <8M :uMЁݺu =4]4hPӧO8餓 I#&M37ߌ7رt &=} $L>0Z~y'+_ٚF#`0EH0F֎Bst u`u/_ CF͖[Eee@` Jg *\o8锧u8|<x,Cą!O\ܹT菈Be 10qP'%qc#S]yACAW꤀PKGm`C+ysF#tP܄8IVMJX|CW_}uCϞ=c;,1cW_ z`"qTQ%a \pA;aĆu+G`ʝdy?ʭT^cuWr #`0FG}0F#вlҺH߫f KÝs )_ Y!⾉'Or\7u-j/g4=X]-g J%l7@,@uk85)#82ل>#aS_6IU@7&ɩsi:䫓:Q:!}"G'NV6tBjӉQPN[]dY A喋ט8qbQ s Ǿ @7|C`O4&lձK՛y|\iRU1#`0F#`0FCnG}B,Q^:)[8pqK!};,+ǿF&eeldPnLhNNN脀c0:'DNң\U}Y@#q߆&UTNӸpը7.2#`0F#`0F >Ζ )׶ "^領7^Rq"@cPN I@|#%$O}uZu>N ȗ`G6/]F$9zpQɺ+7'~fh?E?0F#`0F#`@eDVś>}/_bB̗#:i"r((M'YLC)D9 TWj_uK=婮Bphj WM6-F#`0F#`0F#`@J8ً"BVq!2_D҄AAG^9zPș {Z@IDAT2ِ3vR;S}lX0F#`0F#`0FT'BKp啶/~,ť\'Be|lOG!TG\!%eݴ.z1=b0F#`0F#`03q⺛?N/>}%Ƅ#qY`|Dg(t)K>IjC2aY{O#`0F#`0F#`@hAvT/J9NG" "Er:uBV'8ziUԾg"#`0F#`0F#`@۶n1;;Jw8}E$~)%!@h8fjWqBt*6) MXqf1F#`0F#`0FuYӾ÷k>}.)jJ0NA@4!:!TzC*bK:Jl,Gѷ#`0F#`0F#`* m]o_^rtAu4uu(_iZu˫!yҧ>zU}}/g!h1͈#<&N|B} i믿> ]KF˽vg}y睊`,<+2j o6?TJ550iD-<{q! XL^Q~>f{ytkF#`0@n1;;qrpZwGH^ʿgߘP }ђGc*#8Qr:tكaT}٠?i=Pu t=tI$@c1FB~pYg%XhMH., /pQj@"\|9"Ga} /|[o5UYʽv8Tj~:^N8lH=ϲ VYY%MtMw]gyv 7o=ߵkװ:]v%tYK^ypWGrrg\:Yyg7x#Zj%t)?X޾}pWļqƅO?=[1=\s;.,1]K/>\KQ{o&\xᅁg_)믿N:ip& _~yXob(ysYk¡ ꫯE]{ィk?|*J)j?gB{r 6,tAu]B\sM!]wXo9Fm7C; 'fp.3IL0  ;vl{(?ޥЮtWQ~߱c+4h06R#Bnݦz,՚mڅ%0<4y;u ڴ ~ӌ٦&4pp燭QYGy!iSOErL5,Z\q"` J4: 6tB+@SrBgѨ3[C>iuKRn1F`#[niK/4Dꪫ"qFB Քr-[lєN׮QyW_Bc#^?0r)%ΜEo~F6p1wwO?4o8h~pWFr!_>׿5t=:bXg9ְ}y煕W^992pSlք o ?ƌpVrp\p^y3zu]sDk\fma]I%:-zqX`ȑ#srsΉ|;xpù6t۾}l9R6Yw_t"xEj Q.0F`EgB{H,=ꨣ RK=pol. >9e 4a6lvqǂ6<ֶ}8u=J]}HÇc\'fN+˿Gcz>8,0{`~>{A~˜IABD7m&xoqܷOWOt g¢ JtFKOLidOOrl O]B~n1F@x}g*BHH>S0c.zOr]a4N; (}70J䥄zûロF )?a-C=#ځ(C'[FӾ Bf40ʔ0.a&lw5@xIP"HdFf-鵣?\cke-BB˜Q"{ه4jԨ8 iGUA{GƑGqD{ ȹy7^Pwm0`G/=Oq-!_jR/Af qތcA7̆?t]t#ovzNG}H\_V羅anjf@oV+|7<̐Obꫡ.+X1.f(:qSc9LN0xeKY';3Xx-%jLBe @cR#,Fr7l| Х #m#MBaM:63a%nĎlC;?qzԮc8fŝfL'[dV,# 18tYRBW{)@*C23FrP_;3L<n g@A[\CD ik '=2,(p$=O␺/rtpW- XBZ3N|0Grr7G G²7ZsD*v:w?p!ꪫtkc'{˙t)޽{SC8H y<'%F*? q0Bȧ3pBGpa3)?#Y89 4[89H]M^<嗘A‡bϞ=cg=~{{ 2\}XTK!=e)ifLW 9lY+a OI1I{oNHDR u9³(Ǧu0́x&Ż- AJ .)kÝgs3J\Ryb G +jJ\̦g 8 Y70i4,ߺ-6|S&{ӿo0W? ߎ!< afL'[Ն-W/6d~c1!D+H!zHw_Mە K}lA9u)בE-FTb3R^FA 1bix ?|31 3$҃<,h#S 5 1a(bH@ȷM6$LYхI'6ρ|s=MFNhsW^^ 9a„, Sk] e MYwkK1/B59w ŸaOf p0‘;s-JLEgJ+mC1den lEӂY҅>lTpA#Ъ%_|1:S~,Á,1d8θr{sgvCTWWH@rکeH~g.fH] ܿ8U N0w\ Fx 1} Rxlm$JK\!B6U^,āǹibzqD_?:p )5B~rX:'իLyWg2?: zgNE֬,B{ Kgu {@x)uaqlAܛ B8Ui0;2Ȃ~@u,É+59R0F`) |sobK=Rq02߼|1NtwX&Ệ epԋWNx9?L&'G_j%^9$Wo? 8Cgì& |sB߄p\5q%Ӵxo@G'.i"$M]%Cg\@(CҶ>ԗ-lj@uR;:SF鉒GZ2d<@#O6JO]hx >ʇFP:@ -Ib3|tBx6f@$l#>>S!A/qifˑ6hJ1N~RY;,ՔNܟ8y3){>@sJ5Ly8RL 3G};04GSO=5cޫ$r8x4Ç5?=5P W $ڈT0f^jwwM\Rszj@L3ɬQ*Tf2{ ȷ]:MoԳ&;Hw꿕92a-ⳕ͞r˖qT]B gјGW!=YQq5NCB5FG8!QgAɩtR9 (CYGA;a1FA(1URQ𱙮[Xk,=#LQj,i!hsa|ed/Xvk`:#P.GX^H  #,/gk/b*|fc@A,+؀4٢=3 ig }%Vh"TLdɝJr^zZ^7RF8{G$>*9F"\R׉m ÍI!WKzy,T9{{ J8p2jf)>yVq͘e/8 ;T̰Y=&ゾ]!mib%sg!?OFH?H@,sb=CSyS%jn]3#.BX$&1_}7:G$=f.r!/7e)3{@ŒR/\#z8Uq6"89*o>Cp=GҌw3hw|i)c Bl6F2|3ksΉ3Tk%Υý3@q *i]fi yeb%€;hZzk~(y~G:>f.L<1#c@2oOYhVG8rB9_ciKʼn+OI9B=l3cA?t1IqjN8eK(/SPtjXs>"#P  7DRDzr)K|@ȔuE`[ Z6^p !Y[ҙͤ}%#deBG.#jHH:_ XR?L -1qxpEn1̷͇֪_+iF3e CL_*g <#lYp%C2ʚ{ Ŗr).DFNt zpbsݻwy^q"p!n)OFG./9sG'N`_ ~sKp+`T?+Cl`*v#||2*h{2p9j)I}o f|_hZ<}、}0[ꨄbAx1P:Pz|0 q3HHRK_cbRfd ,c ߷ )f3U'5Nf};nDJ~<+Y8 w§cRXRm0qr@QmIR_9 o&M9D|59&dBo D(q)mP-ِ=ϊ ˴ ٴz%j0r $#!DaS,K]xj+ˎ:#`/m@d4*-g?B%]eu]9e/ϺuuuS>2I6QHc7Vh//KzʭzƁc%oqD-SVlF0cƐ 51/Bu2dH{b}f!ie xfz+NLǡHq;qF022)՗BT İi%?~l>뮻t(B ']^Q: 1>DZZ q!vQGUgS-O78xw3K!?XJ#Y,!L(m4_3J'2`8O1 \[L }6N9&ce1F̄0hQ|c? oRKAT;ݮe0 K?RI€)f3[g=,i-}1+Nypro[>;wB:w8X-::fM*|548)On[f%dYOud[3NA@ʕE  ya@G0q5'?Ix:{F#P!-W9m= ٩Cl@ $2LkC5&fTִO!m'iYS`(B6!.oF~4G=1OˆF@4#St!+,2[}R9,uE˦H 8p`@J R*K\,`- 8H =j733iH;-5cZi9|@WKxăAp&03(ŏ V(6K1أb%_{LCLOH&B8tG__W0Ue>QBV:quPzbn=cziLnEvP:2:ˋOX)ߡ*Q0@!i9g!1X!,8n_{$#y`$<#TG T,FWRߺF#Pj;_$jk.Đ2 R' p* 8,FYM\{S?4pN̸(zAS6g͉P&̽HxqAsڵi>S?&5D`Jف@qpۉSN=B2 KGi١P튇ǖ0*," ҠbC#:AGJHS~qTWOC,n1F࣑kϒ,ShA u]zbokI!BVhRұ#`@@C3r"cf\q2U#0cyٔYJs~ܰ)ፑCv#J numCǭP6Ad4r}$h_*W;LuZ)lj:a:G>i:YV̓]lFW4b_} }teSaU0ьa¦6,)fL#0}{J7Y>k] ת+3}`1#`̊MsLXb%Ysf/ -mYn#`0F -86|6!z%-}{<ҳdųGG}b)Ԩ:L' 5,{:C%U.NrBWNKE!ySmBɆQV1yJe p\ 5F#`0Fv`6~/g%5vό0Fh|S^o-nůShL0CW>"񆠏Sǁ:L:Ru#.{.<;?Mf-Bx'2RIuuu 5G->Sn:{!/>r :*ÄlPG,e [YVSbAԾ&:}ԫX$;uQ1>bĈr˅_?q;n(e\rI`s]v%la.+Tyw^+˜13U0F#`0F#`0MG.Z7tS˪u8|<x,Cą!O\9m8I+OV9'rbr4v)~Fq4&xęgO?&IJ??%}݁5]tѸ!)u;rzv[pgqF k:lb?!x㍹wXv}n!SJ=r'G묳Nnbsib1F#`0F#`0FhXqnO@ 1!t i>t ifɘ>}tҶm?Vt5&hB /p\矟O>t%|a饗mCF>0z(|g"㫯  /BԩSX}c9NvXGT!,ba-E?sq*1SbeiAu]7W[m5o$#`0F#`0F#`4WR8Jۇo ճ ,u DGrR|t4!BʉsP&}Ծc* HR5A@9ryX0&[o.׻wK/fs9 f\s5{ni,^~ç~XJ):uYqf/g< ;Q^b/曩)Ǎ0F#`0F#`0F濛>/) nJW=Ht@"''z:j_hl:H%)޽{loLرcC׮]ـY!;qзoHS[n jkɊ+h2dH.>a„0t@93 Yy啣݋/XY1=f<|K3<ᢋ. tPXc5SM-F#`0F#`0F#0 ) GND8sɃ&ؓK~ھlQN\zJ{WLeZ)lj t6>:"򩇠IrdY|ٓ-&6]˲-^xGc..#|]$ӧO{hg70F#`0F#`0F V>!Eފ&LoR}j_uIí#%""ŹlRg0LcjCQG2lN*}0T:Mm?Ztm*Çi|ݜbKb򨣎#q@\}q1\K-"a1e˸lV; pMBd`f)eN:)v`F­0Bz=zÆ Uq:0aĈ9GCM0F#`0F#`@>g3Ϸ׶%oڮ}8|-lj_/B:ԡ ꣋ !:}UVvo a>;>0`@8#‚ .g5\y啹.n-/'=3_~yqt p _ꢇPP86I@X ׳_~w1:x,lspe~;|~7U94&,a4sz,?DqTK:t Km":'?XY[ _MMeɑ4 }Փ.ʮlzV N.ԗ,: `I ʰNJ@H? qĩGgY4G] uH~jG@@~E,/$ }]`dܸq )> :ڨڞ0F#`0F#`$_rʳy.e0X]4698qe3!W9:QW NˎǾ,Z\Xc"rB8:4ˢQL:yeEdI#*'$*յG @PHyL#`0Dh==5FYc ~ 3mw 1^H2$;!8R'd?@:"(giB9#j\6 '‚RL9 #iu)S')dGu)㜜M⨇DzISޔbE 1F "Pe0F#P,jZ#`u /ZFJ20q2T &쁰~*w⾕rEpՄS>\voCU^ʩS7mWOE'N #1.⟐!?ˊ.DWi[iG.iM۝A2ꢏ,h7 0ma\k0FZGAj F#0+ kKF }+cULiw'\{$d[ÆFCŇR{߄ңzOvR+)8dtXp""ёs=t9,OzGBe}&ҔQC|ڣ}Hl3_#`0F#`f>*gd0FerF-[orFmF>>8\uʟ'.^z۪G"^]uI\툏/^\lOͷ"# 2:J#ɧSfjWqBtNPe4!zb#`0F#`0F#`C*-nM!gm.RNr.W5PT!+Q `H}"qG:*K=-1[Qglehk0F#`0F#`lrm+A[.ſ//zTnLBiP>k u˫!yW>z!MjՃF#`0F#`0FT6R̜Tzm㿳 N].w Π}K,YXq"`Iu>! QΠGZ(6(G8:)־vT匀b0F#`0F#`@2jC׶ JwÿS'ϲ K(Qo2@b8Y4/=B [lP#}@\΅n9Sb0F#`0F#` 'ά9!*'ʎ'wSwxugBIoLDA\ ꫡ I@W'([ؗsqU|S`#`0F#`0F#` mۊ΍'M([5Nqڔye{ꡫR8\gx>zӎlROqJj:!!kytNB\щ@-Փ]lq%`GF#.;Yt8i0F#`0F#`0F а>ܴl8俫ſŃ<"ѯ46z8T7t)G\S;HmB0F#`0F#`0F#DhI>uKJYz"SC(@!ROK)Q98wbAD㭀^#",+tdOqQO'EcPT}Y0F#`0F#`0FT6m#r/}&%%5\LQ:LIECq5JNPv!Se/}Ծ9JSY0F#`0F#`0FHR^oy)NXn+K YMzQGTY!9+> 9HSv>9j$?><#a'=w}7[(}g $>;Tԗrϳ"V.W_}5|7e뷄~ִ~g uT"'O_|E4נ?SY ~s(g*jg*F#`0ῳv̔~IoL0/PY@Z?uHARk?m/ Po>uYa%(Z R. / /\TZl_|qHѣGg}/ߤ&Fz衰;6~kTÁp뭷^O駟N(/gX﬒&o.33oK-T_:u|A,o߾}+b޸q駟z뭘kq\rɘ.祗^ g}v}ɥ=C / TyMM{7ZYAoo$6ϔ>;~i?8h9 ďG}׿aV vZ`a]vkpy1cl oСCoyW-\?;pQZqD }9s3<^xXL?9w`Ayv`r4o+Rt{LMߠevg2NħzZMSoWT9WQǬlЗSN9%GAM{A~Bn@IkG̋'ƈe-K)HU^jу=yJ>CƊF>$,2jԨxpoP裏|B}G#8bOʽybk ѮtsPkw K0K ¹!RbKom[,&|4p=Y)!}⾁lzI9jWr߮a-f@x~lVK.a98:3C߾}"Յ^z 8ݥ S)7$ i~ os1#ɻ;oV2(?̌jC;@IDAT/5l$YdhK6i4-B9̔[,7CVf p? U _(={}1?)kWkZ_k0wx386cGK .)|d VDfby]0z!ƤXxG仍Y|#!u4fEK9MG|n):w^fW&䙰}C]b_~uΡSg8=tj1N\+0%o-n.1]:u& `ߨBVGKwrGGtRƁ-ʩGq@OW;*ϊn]0UDrHo.0lذ8>Bu)F=:4 /7|B⠽xdgyd}׿˱0R9 XCDTD\A @1J%4]iS=kȻAE?avf0pN`R̎hM]; kG␗ٔ%#{x8 !Y{2ш8(>p2^)TD -zIR_N% U5io'OQ>Z'VYelQ'?sc=6.ioy) ql跄|8J--gҲ.Rn{S9+<# , ij(֍BKˬ0Y뮻H5!E8Xgu3{ty/\Fzs/ <ͯ1>9gnAT?g|-Y;O`[׿rlz 3\]H`#iY@tAq.!D5 rlM矏K?ǨL>JEHIYp1Z40el |RL0!9ɔQ 늣+%6 6dC?2FR/x\ℏio[|%xM74fs]!7h8炰 9`X3 H]TBp(12=E:؆2Dw9ף1=53gt- $Hi>^|L}lYtEc(pqF8Z(H3t?T{ZфÐQ}  )`p.YoΝ=U: 㷤D*+{lm#Ϭ|)f3_/?G%֔}*%_ͷ] ䷚R879z=S=S>Vd!\ޛA c+Gp2$>x?T均8 y<=,RJ!A<#`@#~S9bv,3bG}2hCil3|/0o1f"N.|װZA]]];K ^G8R=?0ql8FsQ@zm\_=p6̢ g-N: w]7qtho'>v ſgѨGŢ"⿔1)M#:):. |lzKtb#PQI*"KdDd˪ˇ&FP:@cTń%f T_i!fŃ ǒpABCP)qjFkAݻw /,Gˆ9>S,!" 9V_!Sj!u82½ALpm?:Tu (K^F`͵k˨w,XS(DЈn]?|Pk!ĹeFC0FVBoqT(6~H뼹 0ׅ!J07'Q9AA%/Q\!'G F|z3SdyNh`F9b{{2 )7&O=U>dUw??}saP a8@DnbuYސg%[X?bU[ f#kB˻6$=9/Հbfh T*40bopH0B7B`fa0nR=s?iBܾS|?}۾P4Oaĸ}ToVa>Հ62|nGNZejɣS{iϊ#_O(= JU/X˔!BFP 'K'uu 3I7PyھlmPj"н{8RZƦ}\c) g,y4QFK D/#{G-$K +bah8|I#fhf)>yVq͘e/8 ;Xs3pqH+U0M q"^~i,cu 0É,,cg˞Tv!͇&#а]Hk%{+{|f&'ː0˲j)I~8߂À8!]cB8@^:@{Č-H{0Zbۘ%XBT(J .)g.{'EG(#.iE#Ñw^"v!9h"\0ff9)It. SO XZ6E|ފ̒7n\J+ʼ "#Ƌ,!&M",[te¬rfp9q!9L'1 `C2˚1>/l8 L!tY R7) =Y:L=tLcǦYK"}|| ; X1Ǎt=, xsCd2+/&0yvϐgg&Վ ^a{d)=[1fOVa}~ya~WY12m:jglR׿3ߙֱໍb%P".WiB:61,G>#V6"Y'tR:\؟Us: 9#1ϡGVu]/&ҩ23 kL:Hmeļ3Pg@%{zR{ptZ#y3/?Ӗl4(3Nl׎%8ϼQ_/<ۙLC4F-G<+8xW`1u?;CLs+;Yb6Վ@Y5f̘D9M[\!<CVc8j#`EY<# FK0مqsq&qm.z4?@X}˜_xp+$ G ^VO:m̩6e?٢T>QeJAUaPrDJa`ؑct"iCdC7DyRl!ԗ: ]%[S/L@%È"ǏO3,Bm1{y{A/B|i1/_ޙMiYהZSְ=L_ $2L{LǬ\i/}~?;2{2#^z|Lf <13f0c矟rY.3hIw{*EφvgÉ٫pu}75 3x,k~=7ȴVgϰ}PǍAVՍ.m;=wfO˿3SbR[N !x|gG& _!y:ƍV(M l BLU "j&(7;R@LZ_3;n7F %<^+L }|7Dt\j# g2\+i&{vauxggZ^8-VGowF7>sڡO?v}8d,z7+kg=|m#KYFg0^g"vˉwHmwc'`L&OJYc6qӦ"󥫾-ptI)#yosNۈҾR2P_0HRX>@~ 6K[iW9OW}TVUtSy2Ka({eeY̮@AuSto,c0, Mx7vsh7X%ʓ^ (=O n Aj:0G؎w[0^6lZkm4'nt>ԟLDxJ[x!^Kؒ KI2v)b7DHkaV'Y~{2F/2Hg_{ c;Uul> ;؟me*. ;1=#`LE ?905?i6F`8!@@ڕ;y1kF:n>{< Fh\55D=HUkpԣG*>Iv9-Νy@\9Uvј\諭If  JEl7meBC=ܐ !{M!49~xp S{ԩ.b<¸@H @%lτF;\feCOOOj#x]찕I V6YR >M$سOg> 8{O#E`muxAw,x #\Ӓm#`0F#`0- PD!F9}G6VV">y.D D0#OvRMr@TRz/z#RE`Ч>j[Yf'G#F%o&.;̶f~3QU g;Za"]vYXuU62hf#e V@@"X ~rD<P΃,OW]uUGsM+3&;;찤ᛐXY}Lf")Iw|GKaόzHކ~3A>aF#`0F#`0F:IFx' O g+O;pܤ#~[|9eDՎ K>cʿӆّulDQ"8^ui`HҞYg,jpynٖ>)XݺYlw!3iDfw rف6sNZx.z.a"1B| xa>{3k{M}ꩧR[lEg V=HX! A7_~9- [+!ַR;+;8qp>91K/4V (/rȅ+ڽF#`0F#`0FL*AW8mxk[\vV܇箵#.CzOz>K75j!8vj83ڸSGT}CzJ.W!_ӔSo {CtSKi`E_NZn?0F#`0F#`T&+ӆ ={Ϧ2/Ÿ:P)tC= N˖EuZ2mEO;zSPHJ\?b`@UWr/¶:>`0aB*s2 ! Z'xbefz0dʭF~lE#{ںNJxp\i?L4)7n\tm)?><:(a>mL vۅ7x#a V g=<`K(.@"VH0m0F#`0F#`0[G -:s[:[5qANY@턤 lcD%>+Vjptph2y;R^VJs9g]ܧch?Ik/pNim`#`0F`BkGk0F`!k{A0on"qT ߮tq N}NNPI*\u?ՇTvNrXB=20"c69 P$CTk<7B[ܐ5R..AK ">#uH'cpW fS) ҖCe~Up@n+k1F#`0F#`0Ft-;62hekLWGP+o&!(NTWBǥ"* mT?y Qb0F#`0F#` k/!@m<A-[z;хcgЍԦMb!QyV P^AWթFjcK+G+NS#`0F#`0F#`c ̱ȠlCϔ϶lMS{mDG:]8"ѯGA}c>(in_l1F#`0F#`0FtWƁuKLەJ`wn7V" KĿ|Ў(@=u<ؔmI:F#oT#`0F#`0F#`:B&pc7'<^,9?4e@` vW hTvFp9.>[u9WN8n׭lǝxrRIl]lRِR hUqą(3͢j裫S1!lO`m}flQG.h|+1k1F#`0F ?&Oڵj2>yBej O@AW"Aش#`0F#`0F#`@;m&l᳻G쒜Co&E}q \y (e#s!/H_w`^i0F#`0F#`,O>=X ?Th)AʪUTāo]\G%K=IdOjJA3I`<0!OT/4j,y¾nv)0F#`0F#`0F`o22tgmq~&R,T @cL"QAϝ_^O݌"U_ .Aǥ~#`0F#`0F#`0E~7oތN8T!sB3D$?y1* [ӏRGzGv']y7:0F#`0F#`0F#m]ܾx|/T GD˰Dk*3DGWva,S/M:S?䛴?v,F#`0F#`0F#`:@oG+AtDCSVv!E=E3 !fPKGQf1F#`0F#`0F#Y*+wU^ĿvLd])T҇:.n\7SQ}?v#`0F#`0F#`,3઻o?|@7  D/+ "eRzR f=݀?M0F#`0F#`0FN#m{D`V}؇O? GhtÅ l5 س#`0F#`0F#`4?|<<{Co&i0) }j@Oz*eR(#=8t_ Bb3Jas5g53h1nak'=&'ZWՕF#`0F#`0FL]jo\"\_-[9o!9W.NYdl>6 kEpg8Bh#Mo>PrG^~3ґtWl85]G±-~̃@l!eg۬!,Ps;S[4㿣O}iտ{>\W >~Hn\`8%IUT|2z(G*=fLje FG&;m0F#`F?|0aBx衇~ON;ۇ5\~ӟ&la7ni0DOv[ ,a Gy{^u{gX}S'N W]uUk[o5xՠç>nQDUU3>p}eY&z}oU_N9唰+8_[mh|8묳4/| a-B`èC }s= QGb Gv5ҫ;5!'bϮJmV/_|E(_ru_;;1z;y(Ǫp.VٔN"\@VFWmCTmکd~c$O?> E)(y.D PyTORƷ_n'6J>s_t3UzBA,F#`0F}&MfqDtI;HWF38#: / {8s g{Fdnp=n/ '/})\p+_J8o&Oo<5 |?xuQoK.$<3LxWϼO?0wC(+.xNo׬JL}J+.F}ȴVUQJ>wTAFՔu@(t{7B7ׇ0&"z9.g(?X(t2}Txcn_<{fo]\"+m2buAo`>et~/[) 9/OnG}miRt0?ځ,|#;NaCN_;y&<0F#`,f;>;Tf̅Z(N=g K,D ]B`?yj7cC9$F٭Zj~Gr5獀0CVlgy¬X -.<Ӑ[/2,[nIAV?S=I3]vmZddMs̑*w@ Jz /|KgguF`CkBq 勮 ɸ˯hхR3릺&g_҆riB[CO lhܤ6,T]PZa1A-`i#UYu 88T)Q/r}K`KVX ˗m">{ZFPaĉ'XǏ+bc40ܧ[qA!K%릗 uR/:Y#P{PzRw׸b0F#`[[\wui+ ;:믟f4Ӹ%QieCGB BxIIf)UuIi0PC-F\6w̤ytxlR.;qؕviC}UG_颞PZ "0""I)B>5`|إ,th/*P _y-i:lif-=ě|#̬!ˬi!G?QVE?%D *lECpu !p f0F#`$RL^G^Թ#X-0وw! {uKvu Y߳w &HA6PMX٭C~U ?4.&n7 Y˜Cg='qҕS#`PCZofd믿V$XJ HƎ7λWc{s!ryA P WV+l9眵j G6bM:pu!O8-L9*9{.P憴ͦCyCu Oq|A!_ N0A65"2z\/>أ?d'V~O=ɿkL%D2`9F(3 D!@c68 Q tg" u9i/ک"d~_ (:nfx^-}s=s;SӬg˂ |Ϋ.偽;G^ wSOSz9/WU8S|Agi3 w\e|b}?o~d;j{E].Ҥ3\s%.,/*C{t0)3N+B=PjP#v}F#`0SwG$d{]m{<}JXqLBxO}A]MjjIM0A>O@v7N׿5s OlTO ^{-~xQl;g?Y85F YB0z|T.>8s9'p@2[tS.%"/ڬPpcǦ7q6b@fC!AzlAKAZ) JiE7@IDAT AVw} +`m'tR *|O,s+A^'dwV%(Ay-F#`0Fxw",fËa*ebAf)`wVn™DFs;{Oʿ>(%P5^Dδ|ŵi4; 45>ʏ3DZ9N4 ?%F嘭҃NRC|7ԑGX8uAqH.J'7E^FqPf $0+ ҍUIhӠ9@ѓb:z./jY- DD5ۅ-z ϙO%:3'HΒZ2s -럇clĪ-{ _I_kuٳӓRA WkVD h";uj0F#`L;Gz~N'NLun, c9FAPq>M7ݔSbWO%ec̘13❥EB[#`\pA r>/NA?*y3rW_*n#a+d><-[D,0R76s2 ##Gv"Jwۯb D<{%BgBCiC I|խ?:7ͥG78'[*p _MJWo+lEO{^'{:&}E;}TT'ۤjc\6 -mS]-Z-@nP!TN걇mT6FDg!($76fŰ/DeYnŞ/L<:#Qc*ƬV3 zzzÕ/cV9r-(?fy 믿~‰ f-iSVp~K4O=TR? *bD٤zF#`0F VRs\0DkG+2~o%;ʜjiVp V=0& LVC7ڱ5u0F`( l ge>쳉y [7Q7oSy/wAGɶH>>8!sqO<ص x@@һN U'嫯!ƄJoo y⹨?>"hpp|" g|/N{Nڰ`:_s_RlpQO.ٍb ]1A08qʺ  6tCԡ+@ӇvRla|`7ڨTk=bK}fhfN~XqcǦ=FYk ?+ a;o%e2{<)Np2 !% =f{"^ zzz>'l]iYB3l B,~z| 5P>P #`0FB$uMۜ;S=z대.]oW:]>YЪMM%jgQCAʵ7O-l"IГxnl+,}ǿӎMr^ FoF7D0PݨڱϘ.GZ@1\ @`A[fʳm(9A^{핶D:RPgTy%:nܸ:=eC9$Es3 l}p_Gt?8蠃R\P_RUW]UݖyYNMF3dpHqt|F#`0Εyym񞒯h0F#0&KQ-xoאse{җccMm?A=!\ƒe@_f1+j$@8k<으wM HX0F#`/xk #`[ Az`F`y./x+?:3Ӟ9guV48a zo̘1i/SVH(O~Ru/ _EAt93BVSwp!ѪMh|KװZwuWMy+~LaagF/nZ UWb0F#`0F#`F[9`؃'ԩN]F"Μ>_Kpsr̠pNd)R& #=,K#H/VY@@|)]E#<|RWE#`0F#`0FL+;'lʴW@x!ԋ&o Rv 䥧<:i#ECdCd?6W3c.D7B/%٣ }.\أuύW_F#`0F#`0F#`:@8n X;) JD: ,~"Lȝk@ \?6"ҧN *Wг#`0F#`0F#`|r_ʷ_<}!.MbOzjeh jת\UF e6?Z_ab0F#`0F#`0Fgw~[%9N)L0/HAȹ PO F0>CS_ڑ"4n'?0F#`0F#`0D`Hiω=w:ٶ!Y|7<96eqp:HYu*V8pRK }_})GW;)>VM)8h& Iӗ2ye~z٠Qcȫ.uMY0F#`0F#`0@`] :vn_ܻw b:yHmkPsS7cHeGv՗0u%<ԯQb0F#`0F#` V![rV&-қP*r.]}': ]qavR P/.+FSG0F#`0F#`0F ҆0vq@Lg;/E*@#"eXm"5X`@N+;0ک^&٩]MZ;#`0F#`0F#`@G( Ar!g:06=X :?Hr_zu"0$Vy1h"ե>ÖQ>VUu'o1F#`0F#`0Ft ґׅw>lcN#C@` @5ѝ|8|5rœ#L?D\8r%2cwʹ=u nž6Qǀtôn8|IƆ.e+A_Wcb0F#`~L3G(cT3bDRxinqᤴ)H r_7q }ĝ:KJ"I^6bGLpa Ѐ:!`B+ س#`0F#`0F#`:qlD⵻?|<<{Ci%A> :" H: \5hQ/lS#`0F#`0F#`@4C>7@ëox9!HQ?FP`pr RՆ>yV9ȏt#_ F#`0F#`0FA#R &v ?V `X")kjg ;.6tChuhֲ#`0F#`0F#|FlbH"0϶+wiտ{;"Rnc2''?'q@z'ϥ O($ꯔJ!X[_. >#i0F#`0F#`jNPD϶7]#L^i|,<$+TN2my=8dYB ;Z תuj0F#`0F#`0FcTv&-.1 ^Byqϥ`|IEԃ< СQ0AHdCvԧȿ85F#`0F#`0F#1*Anp 1i50F?KD>e٤.o [3PtHU>WJ;y y&E7^*L#`0F#`0F#`TB@\6iGݪo((5n V IK(4u{,Hf"C BF=y< = /'IAC'OYC-B᳟lկ~6xJ+Es}7w W]uUx]_,Ǐ+b?O. =Xc=Fmf}Nm@&NX0F#`0F#`0Ftj8kjRndpp\ũf6!v.\USlpQOqm(00'ynJPMЏbC7D<}h ':3Uc}soK[Kʃ~pPx o 3Xc?a@cM &8â.&O~߆N;-?L}aOGqDXn)y.iÃ>VXa_2l&i駟O<0m6#`0FԄ C=?gF曁3<31-ꫯ}{imى0O>9vm_r%~w4;3=4=3H_v`+暩@-YڑO}Savk8 G}tReY&z}o*_N9唰+'JҢa㬳JA/| a-guS+z<4^g/LoZ_w=jBO<5HJh(}cȼޝUm/mPBx{q&Qa&NW̦8mч6])%(}I:#S+In^;u҇|^GL ZOv>ǖ"7e'f)7rA^ml>ϥE]?5E4u7wQc2B9VJ?Z*\~假9cKS_>m%,=VM|L3|noW0ۇ-,F#`0Fl&M~9餓wܑʣ>v}ʅvJ#`rnp=I<ʚɠ\/}K ._W 'xY}L}9S_:*@3Q\r%'L^+$yl39INXqqg:?Å^X`vV\>JP 6[/@B7,0j筦XiCi/N__F}@(}'NqWTC\6;ſ~J8h&9Y/0ԏuE_elG:oVuiG.|vQoҶ䩧 D~n~yL+ZYrʀ*꣥Z (lG W^yeβ?i pN᠃ z3yƏ؊oO:iVg>X0F#`0֬ygV[sLdiѣ .VH~Q$zBx7a]wݕw}w`,ʆ}kiB=^?xb,"ԞK_WӹryFf/|c[f5<BPvD[o0,&Bҳ?Az~'NYL0]veV+4 b8˙@*W.@c^:6 bz"sg!sυPFHG4u׀uO1Oۀ/ }Ev ʯmK .!&OTt<["Ig#!b:<ǚ?t);5F#`0F`X!]w]ʌk:+٠/x_zW\Ux/һYdKwDikU/~VRmΫ7F Zk*)Oo>})& 3 ƍ7E\l?+ C2v|>b:B|u|eSX+_xy(_~M_}ڨܲSPsWyc0ȶ3FH%=q6o pN(3clC؞&u)^誟lG]g "w23tD7ޝ(&ʀ;mf #$_?"( sK=K,F#`0F x`OlLEX 8wYGR[B,Iثvf礫VcE63aY9 lvD=+xXsuwjv[Yo^* Q& g);6oY c I:V ry_AZgc-uftk}<uY!O8 a8o.8jRMu!їiWS^\:upZ]ڨCę?k p r.P0͠pNd)R T6'XfI?\GWj'_RwudiK/E`c"͖說v93<׿5}6` @:^H`U{'ju\6F#`0F`!1vf [b@&&4qاvAʶXInpvAjWtsnZQ^:FᆀVK<Ʌb-WM'h{ꩧx&LMP-z3y6<5L٬VM<9 ?|:;B[ a%CS(;g) _MvxD7)B;voS۴"ء [!{K+A  r9^9D vD:Hm:lOR/Սbu!mKq [e_L`9+8\駟nf+Ys5W  +x3OSZ7.Yd3Um?588>; d(mv(}Q(@w3y 48"[yDU SG_$>S>m]x0_~A5ca3=\Scx\O6xjuQg.3G6L3/i˃!jE%]0F#`0 5X#uYi3+Y9j4Ô-\oYw0H؂ٲK3g@iqۤIfm&1P8&DYJ#`HA,E]4!?%Z!ナ}h`e]+򕯤 2@{ngߞwaM7ݴMKV@(U(uo(?HK.>DFk=ebOa7_4)49|xtLē+ ]|9[yU*Stl_SuS3nH@7.}CW7H]H䗔3ԖەBo%$[m,⚖dP.oFj&zhXuUz&Lhv#`0F#`IfEL81}{K)?Xp1T˵f" />)lVG`+R`lҷHnHF4`5W_X PFrN" y^}I6WYe\} r}染sP6a;=1#`0F`$" [KtZ m}ʐg#`@}xNr` ,ڮ5e-+ yƲB4rgj'V\iz%lG:Ԗo>..o;= "_yM裣>㏄z`|ȶ'cm'[G~ 9?ECVLq h08WBUzl)O]f.٧N7JzDi_i#m#`0F v۠Ee#``u[ѵ+JڵL l}!0BT|6<76B =RV0K8DiW=:'T.lH/fANǞ#`0F#`0F#`@  { J(R1@އqQ@H: \5h>^,/]F#`0F#`0F#`:@7oxW/o(\ (089BQ@)jC<}rQG:vˆS#`0F#`0F#`0F7_˿7ģ } ]L{CW]-F#`0F#`0F 0X%liտ{;"Rnc2''?'q@zs/k"WJ|-/a4F#`0F#`0F Tww&kwDr ?/RǠbʉVP Z!?,KqaG+_Z/N0F#`0F#`0FʃaCv?N83 ? K*byEA C;`8Ȇ Oqj0F#`0F#`4 a⃶cC ϶aU/~;_x׭tȧ,saz=Ji'/!/ۤ}Ke#`0F#`0F#`:@i]H$ݶEt`".Z\4ΰ?nտt774ncnU%M+0@C<W=l#4r32:RBg"#`0F#`0FN"PZ`P:rPP|:НQg Q+t3i xę[#U>أ?d'V%[C~5&R.DJ ~U(nD>6:\(U)@J?٣M!|r(F_DH}`0F#`0ɓ'#`Xo,7ѣG|/F%>><\uΟSM?m$Hxť˿DZ;ت+2ZRFHUs¥vH!t:1X ݘMÅP=&J!#`0F@;/}?F#`@B3Cxn;@e;#V P_nj⽕҆PN_It)?s' F @d<t:!U*ձC7([Z0F#`0F#`0CA94 `PLMenߍw 4hk;o% j@KD33R'.DHHWѣ og#`0F#`0F#8+:吲B ϶ ]Pũw&SGJ]οb}p320H}! QGYP(6hG<:)*QDb0F#`0F#`@H)w̚ %vصÿ3>{/y`F1}}. l#^zSp}nQp!ۊi0F#`0F#`O> +1hn@wxuDROf"RTd?yE+/?h jG~ \?Cv^We0F#`0F#`0F`p+xpf{"g;j~qҤ_#Nv8olxV?t՗]RGR_Lѣ?I?/h!!ku NB^эC@-]ly%`GF#UPI;BD,`#j,`54jlQ-5-Jbޢ(bCEEγg˙{gag8Gqb260000000000huMKFnM<9ˋ~d(A,:&}ԏfł/c58Pǵl30000000000'PDhK=|FLJ}4M:e%Kϋ F;gi+%PGMXI}=+Ƨm}1p۷o}i{c C Q[3_ҩA^ϋG@WYDM1|١X)&h~b֥Ku]cA6[n1eʔxꩧoOuME=ScUWn)zW^ye,Bq '3i|SZj|*_>]vBV u]RK%QAKM@'Zk?~| +ve裏[n>}!ڻw:uJ ~m?^::tzh_}9]0000000000hIy][YkLCe/Y U惀ʎЦτHOF2+)a@Yr jPWmrY"DϞ=xw >ԯW^qA%ўeY& u{^C%џ;3mD{/Xw /V-]ve; $b-jiU^{b77z}a&`&`&`&`&`&`&`&`&`&0Тѫ90yF̵4n6:gQ;1X ?bЦkGWwos.iT!kh8(/ec*3Yf2iØ6 ?M??>*տ$l-J$dM7m&6|OS@q?1r(x;}NNs[c38#%!3  'PKϵtnҴq,Mɪkcɵc|](34I5eu 4]imϚ( 7EYr_7;gɓcܸq|`̘1 7G^';cuѨQ7fÇ+Lgy^;Z֭[7|i>T0 p9Iv!X`&`&`&`&`&`&03{p)S4np XtEvH4gZ"M>LaĉbLLLLL*!%TWm};mᆭ>ON8!>4[n#Fhyx@0هb?xJ-Σ:*\p4I^4_0\wu5} ;,~s-$6d6[b2 rK/%>K.S\^v=c5(5?b"-/2'[['Q֙Z'oLT|NVGk/h<'E%gc9'Տ%ͫGQn.]&KKFFZgbkӟ2uC\v,?C;qi<Ĥ^cr.iK:d d2(k0M WgԮ qM_)ˊɗzǘnňeƯxxA&J2U\rI;jjGf/dvoOja%Ȼ{xxgS?OJ,'.Z*z|a&`&`&`&`&`&^x!"KP*ÿ0ytEjhӟi w=m}}g+Ro>?رc:F?2$%ЮVۥ_ѓ.#o1{BbN,T(ڪЮ׿lN6i[J Q5|XԼFԜsIT aTUo5W#OUɫzF<_"*[Շ4O-X~#Ly饗obA8U;o=:nk5Lo᳚4fe/~X}Ճ.~_*Զn[GRvkȑm]g?߿c银~G.ԅ|>MJA%qkF H ̛xx O>dSOaСC㪫G}4+/ᄅoV*ѩSXve^nm*3g+Ɩ܌O" {/ެ.F.8Hn`|AaEYBjZ5_y٨zwZDOlR]DlEʤL#LdYV'[-"!}]u^>Z>?+z5pS/IZ{W4N ݈$e,?&/%FO}n  _Bq/5R!~`u4iRq1: 9ޢ}7PF;/O?5GIn7%/ԎJ m/S1J90;vNЖC_ v@ȋ|ώz @%I՝v)ꫯʯ<< Dz&ioB{>Ŵex^Sf>K b/f&?*(˟kE11ʴ[Z{V,߬1 A4MRGxY1g$}U ݘGhC\|hEkNhn{s @@f Y7՞?WPkV>$qdj3'c $ V.~IboLelmpl&mZtESr7X{O>mķy7oٶyj ?/6'!6B :$0y=l)tYg>fD޸ |} ئꫯ>̷x.cŞϬ Kel35IbV*f1W_}5=sO?Ƒeuf=/6 bQQso[\uKpG:V(|T"QB9Ӧ$4oiƹFrQW2> ;cЦشq^#+v%͙f0 p^uU;u_kŦ(600000'6yTHGl`3fLz[o#747V)@8R_M ~mFH"~^gl^(sOblM~%$V]uմ 6lEI-^6Xz/6'؎IŊ3 Md_w\aDx>c5Opj|MPZrV=1ک$ ʿ)7/~u Iy dexN&V@"϶CW? {uoP7N<Ĵ55<; U׿53?>fĻ7Ygx Yb!pCw2۝!GwI"lcPFo0 ag$83gqWu>PL`%sI|sH@`+YgT_Ϻ3<3_VM=[s/,;sgBbs=p$IJ>e$+XYV JǴEc~P5d݈?{*8g5/V[%ڝqlD,\Ӣj-#m@hmeWGo其Կq%;KI(џ LmJWOe|eJ (aj1G_N}uV MLLLLL`#w$FveĽ=yKHoŐsNxctmI( c9&]#oV\ `2boް7m{@[\?bbM ~0-2H 濾(wצU | zJo7SBAX?)m B D{/5Wztc{lm^L`%p7% rguߊ!)5sK.r+ɳX 棃$&t9SCYGEV8qbVg˪f%*snxN^˽y&`&`&`&`M`kޞoic /Bih(&Lǿ1q͆XhU,fC_ԩS7{cԨQqy祏<1%ƿy9h/H Ҡ?ojl:w\/,5x;V0!ɢ1\g„ i[R񱙀 ,6kZU^Se y|,ؼno~󛴭ӷ# *oۋ+y{Xי [x?D_[,ǖoe~hr L--7ʷd[f/3u2 O WmçN=Ib'=#N_zƗOs9I3eLg 0$I&C38ӏvJdBe|G}#^>mO@P&LLLLLL`6%@loTJRu[neK/ޖ4hP-5㘀 vA@o&fL;Ѹ9K﬘9&.Oc1>ט[Gj($b0 Ae5|11EmGbPfK`ՇqƯO000000َ+$J`>}ٜIb 2&`&`&`?$Ѭ1jnoY,[~^cW3~GefUō3~LB>L1ue94qM?Lfǯ%f&`&`&`&`&`&`&`&`&`&`-M@Zvٍ̈|5gMZ^/D0X~1NI h,O鏟Фڸ8XD&`&`&`&`&`&`&`&`&`&`-KҴ[]%&DP|9%gł/3 iWr_.\P⡢!h3000000000hqlYؕhUΊM"~iB>! Bz#f>ʜaaj#1H2Avŭx|DLLLLLLLLLLf%6ѿ^z49#d5059%ZkR?uqAC!oc|G>O>$+LLLLLLLLLLLԽĎ.![/KO-?FPVniN U|r&ڸnpn(+(}uDeM>8˙W k{ ѺJ^l|慾. 첸9eb icLDe&׬SMGU 匟LLLLLLLLLLL`hKP/ &(D0 #sPFW +:ˏF,&~)9YU![ @耴i+ Th=#;:BUK4jp&(\I*szP@*m꧳|K bk|ʴ8匟LLLLLLLLLL[9lGmv oZK^/;/܀&ܬCց`X>(|V Pe`ROBU~5PX$'+2[|k uV<w[aԿ[J/K4 G: D_JI͊_0uJpHs>u~ Ϛm&`&`&`&`&`&`&`&`&`&21sه@;M fTDhK{fwT{ɻ_ҡAB $ d F;gi0PGMXI}=+Ƨf&`&`&`&`&`&`&`&`&`-Fj'Zl -Q[3wK:5Hϋy_>B>b?CH(1k؞)&u/;:d͏v|5~V @Zd:u_?~mK&T ӆدn&Y1\grxƧ1^ EL2ݍoLLPC׏rܹsB@9}ѷesM;7z5 9fFoN T#6m1F,P<Ϛ[9IM40JP }4y1pF^SGLfW\f&`&`&`&`&`sܹoLLڊ?_>ޜ~[M ezV5ڧUUIFFǤwL~hҿ*_iK(Ƣtt>x:hW}V,m85g!84A&~NeΊdNLLLLLLLLLL8b(g@$Τuҿ5&SWs˯7DgP{}DԮlu?F %Vpoc\O@IƯf&`&`&`&`&`&`&`&`&`3M3Mq @" zvٸ첼N&M Ae1 |9$|@ *YS7}؂8-j+r :EcV5X#>Cl&`&`&`&`&`&`&`&`&` y!PNn3;#[/A~^'Q le% H (ˁȯ21:W )cJ^Ul~:L=sU 1bDzk]ho';.N2 ͳpae.V[ņn-X7n&`&`&`&`&`&`&`&`&0Մ|?uZw+=M͙?rѿSk2}głQ/2&?87iؔS>&M7K x&C]8 N72q_9goFN?[oŐ!Cbjl=餓\@( qLLLLLLLL&]5mn$PNh٭kli/}>hMY@ $s_& _iS2\ $4aڨg~y|12}1`GY(nKp cŶn\rI,q /}}/[&-_oFj?#bw;Ɨ_~'pB<ñ+_O>d/GݣO/3[nKJfCÇUlAb]s5i=#XѣG|Gqv0000000000y4qpPFӞlOѱgT-||᧳o_}ٵ{PVL^[['NAc2M7,e&1Y|9cS /+~C~f窫{ol6G"Y?qO\0;vll1hРֹsdM믿g}6zzjj# 뮻{'tcN::7n馛bʔ)1y ALBϞ=ؖNs$ak.FdxXji>?LLLLLLLLLLZ hΔPk}%!8sL~,~JC}'TΊ:SnClݻwtڵx0@gEvuץ륗^:}S;\X >K*.vmTNJ{gnxS]w'xb*cOa8 u G}t΁pjoB MY:vLiҿOQ !gؚͩ;uLlԐ4y-_u~B6`я:n3uL^Y1sVUGpڙɶ?3bl)|)VC믿~Z)pקY 3f3$d H `>`:B@vF o7`lz2+a&LiX}c3000000000&t[32o3M/OiÇz0&5gzSP +F' ۑGY(V ヒ*`!oT`5l%P1~%^{-&M0oRkMIJ,`mQ:-l&`&`&`&`&`&`&`&`&`&`m{VeK~ z|0h|A eBҡ%'^E8'TԱ3+nִ ҾQ0~6lXJ0}[s1lt9 `R" ݺ+ [׿U۰r$p}Euuuwqi.|_f&`&`&`&`&`&`&`&`&`&Ptm4пgd|xty&-(MPI|&A( g/g+kzq-|o MV}Kع瞛"yLWU>cܸqwi$d/+Zve<2:`%B[/k>}'dB/_I38#XkǚJf&`&`&`&`&`&`&`&`&`&P QUZuk32>s._brL7MPL ]3Is6% rV,J4j ї~S_2,'NL">9ԗ2u~m:R_^}I XywHR|'i8M U:tHmh=ӱp;- %,N=~1n>8+M]gIVʩ#n鬱u:~(#ߗVN0(ALΊkjOџpVŠ?梛ɊcJTP^_~ĭ6xmݖ|@M3zn[ o,oLc쥗^:XuVS͒LLLLLLLLLL@@::8Z5vMqmS€v4wS560G㧆6\P}s9I`L`6$:ߦ臯gqS\t _bQ;[ٮ}l1m6}a֋'x"br ,#sEO>l 60ȔiҎ={lys̚7㏣wѩS;y}{UvudWw?mGctci4xν{Ǯ֗w>iTFEK)c¥n{xtjҮedүɥwu,?|Jԓ$ 6~ \Ȯt́A(˟I2A(sV;gPXL,Q_8M][o6/?fR ,'%~?j^{$iyk8yV7HߺѣGkLfC~\(/RqQG߳Ğyv\zikl_qq]waVxV?cw9i6d8];i曘/RgO<1g| bVc=6Ԩ\j~ĸ+S҄9wEuƱқfb*2jk_G>uq|W}-.\PDw/^|xK?uH,ӣo ^?w(NsE]2dҤѩѬ1oiǗ37gM5j'uͳ˂N+_GV,mh$3e]Oל 93&ю)x:>WMLLLLLadw_wtP60yC=/B\tEIXg[o5aA{{x㍱g2eJL};vXx|iK7<8o5[v7.%81F?bRc_e]R?>nbq\r@f1/N{Xg- ǯ[,Щ{ScWv V.4u{?{=1jiwNK"=#uK/k(7O~RpOY1e9E=?LfTVlk600000' 6%\l>UW]u۩ܲN:)y]رcCw9N>$^HL br6lsѣ peTހ%0ǧ~:́.F[uu 7W5jT|+{b&MJc| !>w1<4y睗+90M| lw(XcxWz*6lX:tht5}@g5ϷΝ;@jg ilc˦ Vhxf5+ϽHgu\)/^1z/'ď[9/ݽox㋩_Y/ڵ_Ѥ%ɒ M<>E|g1J4 vm$oYyc'A%_ hco>zקɓӛO>dvG+bZAo>9bĈ$z/ iCJ+7t:uj7%/Ԏś#{3G!́-F؛A+؜ }İ @K;SꫯҪx2c$`y .k|湋l12A~ghC+Gr4 XMͭdk8+'D}]yϸVFw#~cabbVٚ螭:hhGا=] -bBEqƝ;F-:ӎҵ釾͵ڲb|9c#=^z?KKW ͉q⦠[kk5g18P;̄0MT>uL8$7+&j 511LLLLL]l!C|/H (_s5ik b8`dj\i+ xVuV> z\7oAk8~@bK"_.hJNo{Dt~~o>o~ij[.Úbsjq?LLVuYqݯ_|UG^xa\}YUdŞl/?$ֈkŬTblso5Ƒ]lł8f->wUU)ŐLLgXw}<C[5>̶,jh~xc{^?V&D$Nøs54ztqnKuԣ[cѱѵ{LƵpꚘɗk3_iQg9I&AЍ˺Y|tY1uyTR'0CIBkqf&`&`&`&`&`,'[͛syO?)+N-W&=H vi/&Zƛl#>c*F{H3.Nb ??} aK7^I2.%/۰EY$]/F,]S &`&Ѐ̋/8;*)\1ų-JQ]c `$6x(|ƇD.[uƳ-X,ߨaEY۾}+3=^xߒg}IAEn:"]z>U~k">Z{ǻƙ/~P_b%֊W?ތzt rkD"M͒ =V5^йҿѶu]Jک-;_ډ/S_VM`eՓH GW}9s3W?~a3:~mo400000yo&s=#|#;%x%϶CW?b5LCMO<1mM/; U|[_W9/4?>fĻGG5b?I&![١i{$ǠoB뮻.u!\;J_|60<+Of>ꫧ3IWJV~kuI~;3o[eԃ>'S_u|;HM Ɋ?=.$+5 $y`eY%+*e>>G;iw6z,c5vqPR1.q{7O'?y-%.\{dpi㤕  m737.wCfhmKS/6>bI8(@]^.[V`bu 6)3igrV PGR@醲Ç'?>?+LLLLLL`%w$Fvmg6oLTeNgx=slM@I0s1* U1coXޢ~~mu-DH ~0-2x ܵ^JKbJo7SBAӟ!uXyL`%p7% gk7CRk`l9rȴg.6lذǛSEBׇy >)uz7㦱S3Vl隤1\|y`z.~QQqO4.xf$Z55z5ghy}[8փ&aV;1ԞUࠞ>K͙|tSZ̠2Mn6|uC\Oɟm|uTQG(TGs_F,; Yڇ[m+ S>ٰ+l5lY$A{7Fw^(1oX@hU14(ۼ3Ν; j ގնJ$LHc8Wz Agل 6kZUUF3TVi' Jl=DrZrm1L '_W!{t uo}98|LFblze]TFqſ7=&oZ $$Svtl SF >\74җBWP|bҦXԜ)&?e 5e ȟLɘ 7eN_L e600000w 4%$J @ k{1|]sMC>^Se,+6/&m4~[~vML`f xZ^*2dAܱ(>\&MmY4Qso}A#?UKQi}sҴe{oW7g|9ӗ23SG;(&TD$`XLCFYchҴ~NuG|4dnX@8Ef&`&`&`&`&`&0`k 7*flsćK%i-2}⥗^Jo4 qLLLluVFFnM@uҪk8kƓ.ˊTGQ]F |p2(I?H㦩/'?b0_8$hgȊ6000000ّ+$J;>}ٴIb 2&`&`&`?$47gߜѪ1Ҽd%bqX9Kϊ1цϡOcפ8kpb0u9O OyQȷg%ǧf&`&`&`&`&`&`&`&`&`&`-J Q[3\M"@IW:5q&A)Ӯ1%(O}H*T:>}m&`&`&H@IDAT`&`&`&`&`&`&`&`&ТV"97K[~Kr!p9 *~AH-01y L27xC]kNi @KhkݥKOo3%L_¾V({5 fUx<}(s~Rg30000000000%PU\tޚtrgn9ӿI.(D#sR \ү$Yq~4(?f&`&`&`&`&`&`&`&`&`&`@^n-[cr_*s.w|ҬCA2@}4ku?F %/ d6$ T(kLl&`&`&`&`&`&`&`&`&`&`-I=MlrwtvY^(ߜ_8 2*+Ypds~ 0ԗvҼ>lQ?MLLLLLLLLLLһѰ֍=-;iKYvR裲v嚃}94br_j̡xϪ4g$9c/הIh|bBYs=SbШpSu/u3;~f&`&`&`&`&`&`&`&`&`NxLmkR_YqW}ڈ:7RePrm&`&`&`&`&`&`&`&`&`&2̿hrَ@ۺRқߥIk!勰D0U3mĢ~?+>~k|Ԟ5=>j{>}=cСeLLLLLLLLLmlȊm3GfwwQ:l[r"B Y¿bC@d+Qc4Ʀ>k|תַo8Ck׮iܯ:xǛkZw}MLLLLLLLLLm 1ID[_Z0 ]52mN!G[ &Z5@Ƥ_"o loõ񬘌6QAY\3g,ڈQڳb?L9#8fgP41MF?)^VL7#@|C7Q<0yQj6`4֣>Z>c=6]2ފV,tԩKm[ne)?PfmbVJm. sL2ݳoLLf7[/fplWuܹқ34pδ)I q_7giѻeF=JH;W,|4.gKOkrŤY1s.itl40aLC#&ڙ&F44~Ж5\+6uGJ쫯.; $b֭[:Q]]NqI4lN"0ew40000 q 00 |qԜyĘwgx 3M`@9"YhFBk4jLz55vC?iɤK3:%'}K}~|Ţt-]}2ƆSsF 0&NYrV=1rN9S_2(&1(+Ɨ,?uz".2,Sb;0Y)cuBǎᅬ''_|1 @pdP mh囼 ߔ#A9PP=>:S6)#oJ]ȇ>c}omj~vX'ěo/K/t91"~oV$L4)~H qpwG~uή000000000jFr @"m֖7cW2>|C;d|~5efJ Mpbc.LƘˆ2_~|Ռm.8c6K{iqgwIXvEL6tPG~X&ӜԜ}(3H^M G6|⇩ ?b^qF\s#a@%ohmӧOڊ裏>j449 @Ҡ>yHȷSvGv@9Xb3000P޽I{&`&`&0Lm1mx:D+{|6ے~X Y>-ݚ:WK6 _gڈ~%eΊy}=kN~9k~K?F&QCX7%Or~RǍP" +(K7HO<ʊÙ%&駟'7eK7m&`&`&`&`&`&`&`&`&`-L :w[U4s4kvihʴK;GF.[6mטĥ?~Gu5}A)~L,II Mv x܈L188Sj|LLLLLLLLLLZ@]-oJǗi%D'F?&CB>׊I]zbQD:δSQVlk60000000000e[Kn-[8c;t)7i85g,(c F ꩓1ph",sj r-_qq.w?LLLLLLLLLLL% M̤i{HI"(B>X/3—k 8uø_f&`&`&`&`&`&`&`&`&`&`-J]$q]/]&HoIB>g`Pq_~U3>LT$hL;לgdLLLLLLLLLLfп+g|܏ޮsr" FP5)}qppV~CTL,dbeB?ʕLLLLLLLLLLZ@M rvAn )]}9{I.$ƀաzmWeF"]sNO̎ @Ju[ԕ(3/&(L]^.[9Iay_&F0Mzdcv`ԩ&J qJ*rl&`&`&`&`&`&`&`&`&`&`&0K]KiC` ez%W$Z |8L9?+&f^ڏ 6.tG?>;jj&u(Z5000000009@u4qltk*%SFPа?SρїC7gk/=Wډ:_]7 ^V> ` B]T9?2oL%bc%28͏_u쬋TwaTuׂ&;פ3Ul&`&`&`&`&0c{Og{$0q%}`&0o6mZ|Eoqr„ K2+V_|꛻/?oέE?? [dA:f2"u-ޱ}&[x[h8 ΁hܭj搫d|| XF4g׍: Ɠ,PLCITG?b`j'v:>g27RLxu] Q SN9iB5:GJ$dI&$_9=Y0000ل_~믿l2k}Ql3$e.$u9vqn*bw0b?xJ,RqQGł .ng[>CcuM+⮻;~s-$6d8"'r@3Έ^z)U-2q'F.]>`\pjű[E+ɓ'9?Ç7Y@jDN[gk1Q}9/f;czQd"zm?!:Vjʎ8[Sr`3Q. ryhz!:12qM=6+?AY1C⌯,OuW5:7 cb`L\Ġq Gm#u~\kN"d4lsB!vۗ'?j ӾV"do2LLLLL@ Wbk 2$n8蠃k)q+NC !z(^xᅸ袋]&ziF$v}c>;2eJL};vIIKc;Rs,Rc]v%?3U YL`jyͨQseݷOWde3.ꟍ^TWdn=U}1Q?D,hTmIr$NsUA"Qs`֭3:>s}P*aͅj q 2ӟ,98OC5aE}އ>=N}È}fs uH$ʬѭ[Xc5W_M zแ :4v>hJ"+doV*LԩS,i2nm#̓R!}yFʱZk5*D(6?K"0xK|lL;UkלYדg#}?_6p+oNeRUth.>˯"7⠊4 <WVVn= fd_P$*u*gʰhk3)Ӯ1%(jŤ>$*N%(s\8OBBLᖽ6nד50005ڂy7[}#Cotwygl<nԆw}vlTxHF;ǖ^Q$I Nv[lEr-ArqO-K9^tmQǒK.޽{z㖹r)f%L{m׿VX!+#F$Qy?iՉ.n&`s5V(Or$*o,ًe0_+={seӿtοُP,4 0 =p&sp9Vj~ ,@J.lf_<_~rg&Լf]կ(={DtMB=:Ӛw9)7)HO_W9R!]u?J4 <WԽHvt9(P~K1 7fR %>LL ov1 gL;gWj|9_N\8}euiBvg&+lmF}]0߶g&`&`&`&0 J!oiSO=5C匈;$W|VnMM745K#o"##kmݳgϸSba=| 裏?V\qŴ7LBme֋_|1T@LVZ)ԩSo߾)yv,v 1؃9 al1z'P)/I &L`%@⒤N;emf_}UZ'BBgq)9Fo _Ts(c5eІV,&bsIV,ߦ:X׵l+A>U,ꃼ}ZOT-lѾ]ߔ2>i6b))~TI"h"D W€nNӎɇ37:bj7KW7U'6;ouɄ쿬߼-j{Yi -#r!e000 j] \˿)O}y[$X #YZ !l]޽{͛/rJPplŖD2^tESr7g| 6;%2?}x?LV/r>N@x '*l&`&;묳 3fk! y_~F#8".¸꫃$ MȊ=v_~,I $Y|٪4j`%$s[lb}\rhw~Q?uVOTkDQ}aTm=4viHȶ5zsLI;Lm'Uh8spnz548&[e?{&wU;$:A4J*""`A Q:J3"HQD HޤJ@BHμdfv&lI[<: &0y~_N^+>2Js>ЮqnTi*1!d5hD^etxl1Iu d1=OA92bDHG93~0F#`:b%1cҪOvpG믿>XM@sW\.\I=w uQho= Uܭp5)?!lv@;6r-Q.)%\L@Uݛqe|v$:>Lݜ])~2 !PG BΕ䧎Me }'?NK-F'#W4u)Ȑv ؍0F#0S^>aOf*eR#rJ"X1ۧ~\JaĈ 6Ԝ X`gTZEK~tA5UT`,C IGd RnԨQ] {n} `^yS@A93ґ !.F?  첋NKSw 9ڍb PFxx4{HAK޹vm޹P; uq2=w$rAB`G;8:Q{D㖰]wݪm?=ch9﷩Sۣ mW+[OZ<0~oS q_@Fܡt䛠øWBaMRLxB#B=;R.GmihX<ʉ͋)ܶ#R]plFd2|?Qƿ.?:ԈHcXHFP] $2zGG'teO(Ї:/u?El9}[ɧoo~8Lnex3_χ_.xbwf@uo XЖvҥc>>/)ڋ 0߄#`0FKhVwpAT ;SXkVcU5"Jp aNKҮ! ,@jF; 鳚Wcf~`Sy15Xcdě72n#`rxM0!]Uy{haPqة8+[lXji@+\|VÃD]! /7 8CW\:yă=V:xtCYDBWȧtU>VA L="Ҵ@i d GhlgM'˅c /=0 [ep/u(`hsvSD' 4@1ؗN]#`0FtCILŸ5I%^M'kO8D nr6.8#ӱJC.Uq#0/o}‘o%d16~*Ĺ/Z{3ղ9/ ! w -NT?)66<;SC;n:S/V%'iM_S!6<)#LfRUJ5 U@@ŪK='V{=.߫Í®+.;.H8cυ9 L4u/lhdO>m߽pKo3\a)q7Ͻ>ތ嵽7 A\ҧ&u?+|uý \|o8v_">ǾQ?ֿNA@@n@0F#`z FՄcV0Zz=XZ-;tЩvPt1F#`f r~& Oq997My+o_S*vFHvQ/j` ]RDzCc6l';!'P_I?督WXULo<ъ']Hxsp+} w>8)"'}y@>X?:_Xh֧8icƆa1J 9G KFޗߋKE]5F?񰍀0F#`@vH;UVmJoqڍ#`Qt5=N} 0UVQgU\<(z#QI6clW>+sK'˯BA^~oR8g;LsE_X812o0< _|[ʹ#q8pK{l\8 ~|JcC <,NK7Gi &B $\pD(F#`0F#`0F(]ȣ ]"MN—Gw叺L}1;N9GȯX! ^"y=em`yu=(u~ѵ0 xD+ z 2)Be[Aڱ_=G]:Oމ=NHGmw {M;^tޠ |"^̑CGܑW Y(lp˅~1pF<|i ,8w?zਣkw\37RP{6Zr@AQN{  q#`0F#`0Ft5=tHAĽ~6PO`@?4Oգp!2:btt9lR}½χ'< /w/ ĀmW ܩHȑw=l} w;enxqEq?('su]3)ZPr/@B%/v:o #`0F#`0F.׆ {zÿ7*O*c@ p З4o,Q[Ɓ-NBtϿWIogcxU×%Gޖ.d~E\qО3$M.D \lB=w)#> ˆmٯO3F#`ĉÀA\ #`ow0h,Ec'|H\oӎhM)m/u\8-{I}cQZ,U)JTU8sTu P@R6WqG_&en"y!q;j_;  H)F+F@xB_'=w$h \4F#`0F#`03㿋|{3s.8 ESf <RO&vhڰt -F!0Xv"<ҝBxN\f#`0F#`0Fg ,@VB;^]c@fN҃ yJD(ӆmm SP $Ѹ /u<95;FБFڍP W|zIL30F#`0F#Уx_&>u^5b(@X͔rzlH}EA P@:# &>l(܎T_%ʖS#_J1U rN0!ґF1&S #`0F#`0FGޚonKs4f_@% Fc`z,*SGzlQ@'U>n̦|~Rbz@B@BB=i)gGY0F#`0F#`:¶0dk]@mÀIwڛ&՞0Yz<®@A=u"c6 ` ‘GO]>KYj6w"$'"0U ߢ2i $y@'c6F#`0F#`@@p$SC$I)݉ N8܎ D@SV`R+PiB=ʲOSC(F_S?OVX-##Ϻ\( mi 1T됷#`0F#`0Ft$E FO/L( %0qmoaWCJ9@cȽrt+wIL!JQ2|`W\kL/i]zJ&: G <B4P(tc!@ 1W;:sPfytTOCr !9ӿs@w_Gd0FG`ҤIo0F|x,=sU~g.ŋcCuy;xmRt҆P#H_ѧNyIܿx=l$4PPfD49_.*SDc6 u9TR'`G B`2xz~aĉ1;|j#Ѝȃ_ʓV>lNie>m7b0F#L܎#`-x7 ^~wl9YmϻD8b]bsljjqQ#n[-҃NR3GvlWvХ,=%Ŷ( LW $裁LF#]G6d灃4F#`0F#`0F ~ݭ7 ~J;^?_NAAr= .)R0 z-P(6hG<:ة] /E#`0F#`0F#0\ށ00v; Nt ΢~wTﱪ@ַ'C}} l#^zSp@bU9m?}-F#`0F#`0FAW;6hw1t==;:BT'D~{"RTd?yE+@C@Ԏ$ \?Cv^O7o0-F#`0F#`0FB'Pw4mi}]^/NTk iˆoCW}I%/yD)|=#SA(}1@@41thв~ !O=H9{e'fS#`0F#`0F#`f)u9]@qp;(&8hOr^`[Ӄ-z(c>GA}cK;}P@ine&#`0F#`0F#`pJAç?xзEԋ8C}2BJ?D+(G;Чc660F#`0F#`0FE ;Ψs~&.0 _D=u"#hmz'O*pAlJ&yheD6/j0F#`0F#`0FD+o&ǿï5Qp#"qO Ac\73RvTXUn'_?#`0F#`0F#`0@Wߍ?w.>],Ԟ(y"@ GHG4x4MjY0F#`0F#`0Ft(tus3oglI_WrõЈJ /_~PBr=l#/}_=0F#`0F#`0F@kw-KyFK&.*Ğ8@Ԯ]!yȫ> (ӗ O@A"A#`0F#`0F#`@G"%w(.wHT/+`e`c~==?]آثɟ .`Xr%C^r_40yO)SGgcC9$<[oQԍ0F#`0F#`gpؔuC.O8mqJiGrŷ.e#٤,IydOjZi$E#r z1)vXzMl"|QG^4&%ZNy睷l/cdž-"\uU [YT%1"|_Å^ ;I|GtL/N8!|sK/pO+2\s5}}LJ?XeU}N:餩P‡EY$d|d1F#`0F`"p9nuԉ&2e-~&L\0?q0ٿ 3O?=s=Yfe <_<<0q2TOSkÏ~w@IDATwߝ!ڑ6,? Z*+~|ᗿey/8 otg7Ia^ c׾vyz6w8nU,Mޘ<~m VܦXs7\߭w`X_14^w䃲l" M@g#'~:&/r6Jv*l/<;{.OodW}i`kKHOvc,&-C6DJ{|y.j nX"dVJ'0G ꫯ^4~[ /#'? :+W$s=w9A+袋?W^y%`G$,n/r"v` K8g +կ;3&a>.>_ve)~tH.V` s=1g1F#`0F4oH4y;}a5_|qo3hݍqi$uNoO~K/ ÇO ??0iҤpD˖[nFBtMua?^z?1cĉg B^xἺjqX8$ӟ4 Jt 3\2,׹OǏ [pDrn-.>;|_n?!7ʮ]3㵫_I"퉢"UW2: TCz(z G}'ڔٲ]N䛒W^9ECFl.@¼y'H-i{V#_oR wT/$z#l{^V)@BPaȐ!"pB4y/F` '쬻)&[w^jc cdWL EO=T_P?Aک7#`0F#`GՠC7|sZ,.avGթ|v\o̢&vUs,9䐴 aŮzo-=#B%48193}Zkt衇BA@ @ _p@ZKcgfvئw1l4ߣ~_]|aᴈaÆv~ k:ƈinw&V-n|}{+wnqI-deѫv_Գ붎G`SvC܅3{snyFwO]Zpp넇Ä&ݟfL)΃C^6v!Іxrv Nv8r/[#2)cv*rnrU@{"C D`#L:& ƱCp>!t|h2ϣ`+A_Wc9Cf=f|C I]~ ^l]C !%Šr]>{/!v=0ϗ1J8I69CũR.K&}iS,a'‡xXY0F#`h`=G臣3[lD(]BG޷:3ؐ|/m{O>$<즮&|wb7v2R [cq}9K/XwRX_Me YO oFb5AH|cMǹB@xXM= GWߗ ?26vs~i T대ȏV뮻 ;y< =y'6lae?ZV_ve>?kxCmӼ[Оb 馛@ &2N] ԩ^u h{a) 509 5t?ًٲ=胮l+}Rtd2Bvk\5%>`%}-F Q]U.@v5?zSJTDt/sjV>^RbW{cY|1IQ%0@Oqj0F#`@s@Jq&n:wqj I2 "հ+fRK.IA X=iؒ=Z9~U˦= >0Hw[=)@c,Bp;^H @l}10` |o#,|s BW\Y:5F%AUNs@X eMeŵHzNHn *ϼwލ]E+ة;R_MxOT mjfu3y&}"|'a$O ;wxcRsYo9M|8@v=)~ ԣO_Rtd+f;>hm(×&yوNZSͩAq0ի[8jgP<& ᏠˠiGO~C^?6e:#[vZqVm$ s^|e{VŒ3&񁙕8\TCė /|V@AA l{Ӝ+q5EJ&"CK+_Jޖ9y4?CS܆F#`0FL!a%k, ?9-x&|EvU[;$wVrtv>@K8UD:+SY -pl`W /\H-vgܸq!sJSGm`s!_mL<,N;#wC$#`fob8R褓N z_pP~QVCNJdT,eTKy3G B5e.Gu=ݛ ;c,.J^fŦP}øs)pm b@@yRk; 9 GCM"[9)@=/|?٢T>QeZi$  GqGTD>40e˞li`O6A^~/V5.|hoW { Qm~ " w,(zqǥnge> #|8S^>r'BT @ȰlV[9P0P%:*W [A|5jT\UI|Ў0-N0F#`h!|`>Y!/|%_#VB60`>D~pgO.R r7e X1B"s,B3'@A5{;YM; eyD xYʬ.kl)Qo1FrK؅}x>`:)9#`fKf92q]ROO{wrZ{ !C3:r)#xЕwbX.Æ KǾղ*C#z.o BRH_|񢫥] >|= Káˇ=k\!Li1NE%M/[ܵIUuiCr\rP,0F8`pF^e jӀH\OF:S*RVӰ„UKu&0zhk*iOxI(x)Kzt1V( L;}xW!_e@K>; $l)/.cUȉ3n>DBRo~~0.#`0F`5?@³=ni>_}:3u,C#,XL԰=\B ; 狆dT ׀cPuc<*x{4oXχs/9X|g$:4|8TQ _EԕB]>T|7)zJ;Vk!Ga1}ѫ*3HQ<&+MJ_6AЮC: T^Ko >43ẼU+vzD_W+TLmrGͥm#`0F$ceB0A XʥŬT%ȠPJ80qu׭QXZsZqp<{CS{:~01މpLkpp<5RϦӖŹS&OŕSC?6PjNOb=ukc $AM=ihCA_@PA_CJ]V/`[@wC ͡cBͼ; G#f7pC}i "bVXh3/; јp].7xc…,FZ.0aB:fMj?yT{zyxA#̉il};U;8ߒwǥYbxa%' 7v!X?-Rޚ:H|jɑ< {']l']|7c[]S_5b0eXC>y1Q@@̖c ={e9o1F#`0F#j ¿ZJ❺zҞ~q4K&-Wm\1l:v^sIt.캰#`EX~} y,if'Cg~E`r᱉/LP5fjvqpK M*>//?y٣ҍUե B>p,Uq$g1@kI09!=Gdb=zzd_}KKDsj0F#`0vH%1x㍻̿#`0=fАE.[z5] !GNJ_ȯcG/?jZ`{Q!0a#:K =M&~A(KWm҆s#`0F#`0F#`@G#Qiw:}w^F2>"X/֞GQ_6ԑGL{'Y0F#`0F#`0F(]w%w |W-"kk|Fc0NSOJ6sʓ@CԆlX##MN#`0F#`0F#`f&] coĿ÷k>}]zJ"1*O=ʤЇTmu E-LAb܏|3ѷ#`0F#`0F#`PJmw]o^F DzT㊴->L:=?z3E-F#`0F#`0F#.ĩ+Pſ3.u,ڧHCH G =}P(6hG<:ة_7\G}X0F#`0F#`0F`&!ewO3;SɿǪkCW fS)#8@;(K;>A\6?0F#`0F#`0Ft Ѯ࿧WGP(jl$ Rr:ȅIA}Dbئ~J]l`[/B~-F#`0F#`0FAwKvM[4mi}e8fwt|y~*?7J!Վy<>y]LPuGY>C'fS4q١-S#`0F#`0F#`f!s/:Cݹ"t~Wſ4DG:=8"ѯGA}c S@)B@[~c#`0F#`0F#1lȪcVnKAg5"k*Dԋz< Ru׀uO1VO#`0F#`0F#!4ay[6}wɎ3FH;=h4@_M^D=u"#hmz'O*pAl O&y$ʈl_O#`0F#`0F#`@!p*:AXv36+]7i=~]ܾ9|%M̹ ̑'D; =RI寖yHXO#`0F#`0F#`@ ؜.{p۫ߟ61e@fw T [9M) _zy>Bo<O;voS۴"ءM\=u'UFrL59D vD:LL6r.}^n+V'R0F#`0F`C`ҤIܜGK<><#`0F#`,@3_pgI<)#`0]@۫cpva Y*#YhFL&?N 1roſ/]+2)|:> _'"GUK BDDd5hD^etx 1Iu/ER0F#`0F#`0Ft tF  >KQ]f+0Ay <"O9V_WR_;#`0F#`0F#` #6F@a newj;y@ "` R ar0P VCƢ`_2V#`0F#`0F#$mwV)tﶫzk_W$Bl@c"s65(SRّ]h#KPAyMN[0F#`0F#`0K;Ȑt;ݖJ[ŭåǿ_{]iW!sB3D$?y1*[ӏ2BOQ?u#`0F#`0F#` #0*2K"0}ۮ濛ϯNP?IhOY9E6c[\{̖oW0ܞ`G 84 R@GM E2]_BhQ5.:ӦqQ7]N6,7.<Ƣ.\pЯ_0pпGMSN9% 2$O? cƌ Gu4Vla/b=#`0F#`0F#`V / -.6 D&7N{r|W@ܹl#?)B _.e#fz 9SzSƖIC# 4=th_csMYc;L<9 &O}7?>Kͩ0F#`0F#`0FL?p֕$=57.>~Mʣv9-ΝvŕSC?.m 53TΤE?"DУ C=Ӧ4f:)BJtI /fS;); dzb:MZcUªU}^l|蠥Z*TE\̎:j{7 wM/M6$#`p2; \]CBa䎄:=믿~8cGÆ .hu]#`0F#`v;c 7^ݮߴ_r8ulvl@#駇{' Yft ."_r5<B?Oi1~zj9fe x("/|⧸3[o5?`OXivͩm,Za+VZ;>2grˆ(aCMebV+pҀ 'N|5:H,ȗFҎoJ[]z/>=f}f'jO0;@~ BO>0ٔstSϣ39IU>)oȞn)pYgt/ғN:) 2$s 4!G.B.H~*&7ޘO?t(m{ #GLbP ppOiܣX"pǦpysfǩ0F#`0F`VFa]%,Xo~WBY;#<>Ds4N!)^zi>|x8|&MԤo>}+Y6laԨQNpXp]{39cĉϼMuwޞkN;;wed{<׿&+L@`CaBۓ~hh; 19+|eVX&B#O7,2)к׈߄fI=CC^? S5K#Sozwƫ1֕F~LV&ΧFHX*&CE _emDF m9b|W`)U̝t@^y啔Ue'/9vJ^O=Tҭ DpJr/.݌sϝ\,yWW@$Xo.1H~+R|X0F#`wvCN+@9vuĈiHi-lA^Ʊ+R8Cw"lHVZom%[{wygH[`9]ZkCMe*N3|Azዕ]Kcg,bq ;ctMܹf|0`(26\;]'E5Ҭc⮔5W _>4;BxϞU0: mO=*g_ZNi(l^h,*W;ę[#AGŇ{'Ī]uO_c"/UEUl(< g@uLʣ gB ]/jhM!6+Dw ;n8D@B r?~9PדWA #`0F#`@%m{VB^_*J;M;1~$r+L! 7lذD]@s<$;_|}tȎ_~9JZ҉<8&. 7j sb,voFc=:#k L06vvs,$vvwy JΟ{ !,FVl$wjr"%\r,/x7ë&(A2sh{0hFrErѡpP!8nm'L;RǥxQt\ko!tOr^OOKᮻ~v+.rMoO0$"UGR:3 D0)Pml 8t(3C߇vmUEX1˝nCM?39}%`s7%a5;W]ut+ߕ v-0vHp<9Cjc>(k%H C`AD*XH01;KuV8"Ԛ1A.[Mk1F$oD6 K9 #ʼk !C$8V+|?Ex7J53<3Z)lί&pt D`:{q@PX~pqA;BCa]m mc[#zˠڛCa_ / w%ԺyZ=Fxq:xlxk<<6xo!WelR']O}P?/_9صб=a>QfD49(@?N:h&.J 6AlR}t9#`0F6%ٍ A ypVb;$ v+pI#XY.~ɀR2ǵ2:VrL:{Nsƿ/FjAsӸqB^Xy˱ESGm`WLzͿژ 8ʈ]#`@%!}̘$ByРAy4>8vE م]d RGQ渷jRf5'|2s QKG0wKU㺎C7,(lz;qo(VrPsx_0PvPk15zh9.yuRυZx>$VYgV̔aևl"`j}J\إ@O}c8G$~Nիy(&]~z a=LW kFd"`x!l)Qot'tPJFPS#`f/f8#ʻ@bˎ Ż#j Q] 6x~F@.Gqt»#ŎYeذal?C /p[: fV:gP Z|t\͚H{X?/mm~®;Ļ mUCaхCOOLw,' mS"j"J=g?\55|5i?bč[Õե^Ncv)dTm|ކ~MQ{".N D4ʁЦn:>elЎyP-o1[0F#`0g%1cҪOvhg4믿<`5)GKϱCWW\qEvlrQ')pQG)y^,@Tq5\7<5*Clv@p-XeɵKsZ~9ֻ7"x<n1(#pq'= v4;8zj>|x RP#d۩0WXOx \.tb;[oT_O<1ݿ.ntL5}qgUW]ޛ/rUbwA Gq?e޻+Yf}Z)cFA(l~.n2, \]1CXb+KmpY*F.zh!R #Z6L4Y8;Go?'}*XU]cQ2>O^P.eM"fSz(C;)D] ݼo,ۨgnK#`0F#0!ͽ"|Xѿ;$83U\JUnnRVr)boq(#F26lS[H뮻.@F:{Xa+oO ?U 2$ ^v4^HQFv%{awO+9{WNB3 .ugs$믿ih1F`EK/MKA<.gwwqG%{v`EnͩvnAdy;I(܃߅,v&pt\Ygl0u]ꮶFm[AbPoZmCJSF# [mwܗ.P.w,/&0.s&O &}OuCaBm1xzҚeSbga6"I_<7|6 ˜W\y̖ss[ŧO;6zy},V zk()@ԖQh.Wy&PG(Uڨ'y.WP-F;!Q%E|~mwb0F#Pbc.8ҦR)PBϘ\; ٬ԥ>GǸ+`NK8VXh3/vTg_~Secu,f?0 l„ 5j[zBW{.-޳yР3'zϨߺ[\2Gӎ⎃NXb2\!,@/prYM )~a yFL}ྩRPOY)plYG!OP^}S}V[2HDu8 <I|h4~@Ԏ:!0Ij .8[0F#`0=Z@W@Vy[|{!ҿju7 NnUFyXǧ#8 *jv獀03"FA7+yZ3;A2@ 4ڛ Ňl ,H M2_uSX<آHթ?9u/lSJ%')U!2Zd &y&ƃ)k0ԓg KyCJ#`0F#`@wD8ި<17 @IDATp TQu[ou{Ke:c;F#`@FDwN*-Λ:yY )e/u9 =!| ֊0|PrMr0>m'I$jCOv4H'#`0F#`@7EvIpl16x.oF#`@G ; ;gN=eē -!vR1d\ʆҿԨ009W48tЧMt"Ό§>}l/]F#`0F#`0F#`: N围#9^Í+!?wB@>G !#@Ry&@=b0F#`0F#`0Fjŧ#Nmv(zAcUȞO<أ&)_? O?0F#`0F#`0FEPN^M\U=!qꣁ](CW} P/ $y~` /Edש0F#`0F#`0FD>KQ]+ !@Q_19W^"CY zzK;R/tE#`0F#`0F#` Jnxr8l'G8nⴣJe2ȿlR?K_ADWRxE;k+z}hڕW}=#`0F#`0F#`fAϰ Lﶫfx|5!"k*@#"eXm"5X`@N+;0ک^&٩=MZ;#`0F#`0F#` #PXoav5=2 "#bҟ_e/b_D?-.MBu*cGz#`0F#`0F#1i61]og *_ſ3Kk {{"C H^O1XPdHuc1աNQ#`0F#`0F#qÁ;km/ nb؀c! 5@6!\- &bBnՀ1;w#’o=֞=fWf|kDi qOҿٷt|vM53M3b>Ҁ31}1y 9?<6 UNcKE EݱG#"yxZW3`b0je3^34tzߜSF80˙*%1hN׌zL熫 ?؜i`c?U;uJBqÇ^ќbs1f&`&`&`&`&`SqMU100)ګFpئlٿu{k4jLz55v4tdҿSOJ"ЗXSO2ՒDP&@ ᧉQMq-JUzS,)&1(k\+l&`&`&`&`&`&0hN}|G&`&`&N>I1 <3fL7p}cZv..,&5إK袋ɿOce{.z溷Y;Iv-:xbjy 9 @Fe)@K/Gs KF <*ӎ/g4nҿAr1W;>3i,W_GQn$$I` H(Ӯp}hBMhS ܬb խ7ްjk׮q-mA\p|M~ѻwcwW_}5{챪}k a04'#GLmNaJ_fDx衇=Ѧ7`&`&`&`&`&`&`&`&`& #_ڦF-6&ФC!mC[:vQ,%(C?иs]q8K[/׿5&5g3>eţ-*[I|D*f F5e gMpsC~:_L7pPW_m\s͕}S2K|'TOd{G;ꨣ>oz'c$ꫯOt=kK/M(3 /_y8#b饗?ޱk_T5jT,"qGFϞ=>KI :th>oy~`7xx饗bK.$85I^{-^`L1#<#F`s=ws1K$]???{t}ݑ0000000008r-Y!#K Gߖȯzlio2U4reQ8EF挠 B/mLB_p pS?`\Wm\ck-DӠtM~sЯ_|4#7?>fi8SroM" +"u-Yfx~M6 O\\H oM73}ۥ2H4gK,DJN f|Y Cg]UiE ARSO=U`3O5W tү33աk[cѱѵ{LƵvꚘbICW}~>!VE#Hs0$5)eb MB7YmJ Uh#|t l*-<@g뮻l [M||ڗkI{?IK.d:K _/T[+Ǟ2 ?alܔW{?OJK9}7f&'aD6ɪݟ}6000000000LQ㔶wStZ>4gLc@Mk% $_ $QO_]'6pu{OWiTM}A;}4g:6E9oÿ1Ps/0An O68m,YQG:np>~S;ˍ`S$駟6-f?p%_!ψ#W^1lذ$?SqRMG}t|,ꫯb{i_Tfm芎Mb!^z:цQOY:9>\P/=X_KZ:>əU55gLPA F90LMFL`j'>seP=mӗ-2_6[[Q^{jM~Mqv)L&{a*.,Ԕ}'M5LLLLLLLLLH~hҤ9K~/MvѲѽs[r:|9ӗ23񩣝q~*S_jI"h J0i Rj Mzяډ]^q']UWTGQDg5dyp2|b$s>Rĸi)eU +0L<Eo600000h s9'~XuU[ӽCaZĸW_}Ϗ= =Cbe&`bi,ELyyIKl: c='xb >+r/[n%Sgv>ֲ41&Iq`00&Á? rOyQhۋf300000R=e^Yv.*K-T{Lc tsO}j㋋s=7KS?<[ݵG\yfuiv{u#"6㰸cy׉>NczN>qb[MtQ$]{ߓ~U& ^&_ięm:LrƔ ~:Th @$۠w^lֱ;ǥ^,vjGw_ӛo{WlVqQG%Fb"a+-/b!r!Ra{ozx}Ԇ5H2:'v+_&vK7?Ɛkeg] F~*FY|q{Ģ3l6=o.m]O&X́僐0PK a#A72  gqt1R;Ƨf&`&`&`&`&`K[=oq'QytaoetMZknS7xcjC Z 6,-RAՌ7XY d[ox,e<H2?$;xSl\sMܨfo˒( AK/g88p`z;%5G뮻nx rx`,bi\bc-ˁ g3XZM6Xf?ur(y-4(=p&sp-Vm~2KJ~l EYAy=g/g~slXj%R>}=?[{ߵ/]fm2s_2ee"G~E1|8S~M18E1P\ cqLLLLL:-D)6(18c8T ĭ-""56lDuY'5K#o>C '__l=%X5~ No/ˀW^y% e.Ih[eUgI_* QfK,ヒ93%/ԎśX#k3G!́%F:$AkOWBMbcMoXs5c$L qIRuW_} ȱjs"={ 믗I?: (ceA|̓ghUYih 9MB$_,wS[}ݎzw~B1 ״݃w_";ӏ ѫѦѲ1*?Zs l1i_:x~3ckn\]EՒD 7Ep,nIbW51δcp.?}06eAf&`&`&`&`&`6ek52ʗ]vYZ$x^Fk6 ouK/ySk{.H`@g -$s̑:㫭ZN)!?zꩴ{wM`޼<aM99)6q\ @&/򗿔63fi! q=sU83o[A2_+JgEfi&K@`Y#I"Tj1+ ^ ,IJq$sY}l%3C &}˅P1s02 F6-=[::J&K7ߥӮzoukk|ι?NOVKA A|"$4ť )d+BQָfmy\sߘ *600000|j^}XuU+o7oKMP6-xo#> §/{p-Xb oؼQ枰jK!vtKpviiO+I^:?bַot[lvmS_iNmǼ/똳OLs ׿5;WRAXgcM%*=!o,݆c745Ymذaiٷj1s_|l%$UDq~뫏b9H_4,OW ?n{tLE">[cdZ4zs~QfbksN%cLt/;1͗24e+r"  З0i2m!re f&`&`&`&`&`o#`?O `o5:gO#8"-Mgͩ|3ov_JKiɱb?$-\uُA{B/ t.˦3IW-KVZ)WNH|jjԨQi?Jc3k-%+vu%_SquI-5c"̳+XZcۯm oW)?8祛c7ݐ0;J usV7MbOm'3G捦QFF́|WڷsѼeJW/%^:;eL~9pnpn\757$07\r֤U1ţ .L(s0>C_bsM=7\C6C/Ø: 9dӹE1000L6`"DrKJ~SkDJ1}Ɵ%7;oSO=5m*J;x#B堽#yCWs`ojY%&$Y3-tMwn30,=ztZfM_U5ׇv*2V5T550icy| :kήFQLx5 3!MT>gMLM M)NQ8Ga꧱Rϵ~aEf&`&`&`&`&`&4U2w6* ԧ~_= ؿ1n qLLL hҿѤsZ7(}]uSVpp-_S=KZ8g㌩bI;Uᧄ M*H7k&I'DeuWYա>9rh bȟLLLLLL j_IE>}m$1\sv t|,Xz84+0S,\?jC/\K'ƣ.L_Eqkܩ4  k} mL~qp}T?ck||4Ecp]>>u60000000000hS{=W~ޚ񕠠ߜiLD~ƿi#A@=}0&5gzSP(՟-60000000000hkv|8I y?O@P/~UƆGIUC[O< 5hf|4}ty&-OTs>L:( g/g+k2(f 5Կ[3>t&y|S ʁЯi |0%t^m e r=}Uߒn60000000000Y- ^:{M0jI"(@`KZT;Ф`2Q|6C=!_m5߸Ef&`&`&`&`&`&`&`&`&`&`? vѿ;Akj_=}r&Qbcce.Ob.3 DL2Łџz-QD:SG?,k׋aC40000000000 0~|M. ߫ȅjNT@D_pMiDѷobm-v8b5lor8~ذa hg1?/~ LWv R2N=5͛~.N_OvqZza97i DPך Jp kR?uqPYZFɆܨ#:kQG 4VQlM34N;b-/b\p6l7f!?N;mZѯ_5jTU0^y؅Z(]vx⭷ުMLLLL&q&-{ L2X>8lS6Uݺuf_bG饧Uˇ3j+׿[b&^`\k/g&$`ee k&YMV [T%Mq諺?C <8Ǝ[gJhx衇}|St=G0000jp @!P #xӘ$D޻D]ZQFFFNVoSF+8CW?y)obpN꥛k,)6gK9oÿՒD Ik@6D L_ ЇTb0Š8ꋯ ꉇm̓z5~LrF|Pn&%N8` qI1t=f̘K/q)Dݣk׮i?q'O?qG +br-_W\qE*{,_~ep o}eDϞ=?3<3{VZ)qS~\{닅^8Ã>Nlo /0w>|x+x %}ݗg00000000 80_${pYCMhh՜Y::tqYMZ818sZ#XsEU2}8(V73aL&AY}QLx _ƈE@Gn)&ZƧo =_ob,eāmoߟGw}So;9=6[i_XqSGI CիW{tM}J СC㣏>k&aJ}bUWo&}XoR~0Z*%1>Ӕ p_Qh#e.$@T^yS"k桸> LaJV;~-0CF':>:.?UTQ˗9K짬lq5PDԎd *\?Cv^Go`q]#WpM7ϞDw}7 w}wAP^H JrbvKs=7$Ijbw,r-S$>ˁfmDM_| b.W_d;PIߎ#<2k;#N?!9Rm+}@;Yg}a&`&`&`&`&`&`&`&`S V)7CmFk7Ss=54iҽ_#KӦlt\V?|՗3Kәze8I?j$4 %4q!Q4m10NGs'@8EU"|IYtOMu`١ Ѿ1 {lJ8j^q9ԟq,DA$I{.%82}7bĈ4_(phy"Y7H_Ilvk꛲|NqyS.oo*LLLLLLLLLL`J&Ш97 X7T S|8KLmu2'YԏX]xy"B}31Pڰ>,]h9".rj,flL\'/GzJN$)ʣ16W>묳RB ~x<ɝX:+lL⣒ cCf[ T\~N>1nȳ000023oG000O`6zFg<z\5FEw;i#sWszk^.!kr&Zx}qYN,rnA:悮y$OPQB21qSIӦQ/L>5yuMCGP\XEuiN[d_}p&y_x8/qƥ{R?m>y̘1cNp 0000000000 4^6~IV6ѶT._:x~(x:hW}QnL9M'b>麨*юfrù<6n31i)_|Dbcg3`)" @ mkl+V}^N~ԣ31]S.\O'^ȗuE%$0'IKP\reI,#.}4.g)hڜGIE6]k<5.^-RUM: 2p>}(SRǵtMOlanxtaM* 5F}mZ?ҹ%KӖ`4m>*S\9їC+&vx/\'6hIrN_)@ybBEzŠQs(_f'u"LLLLLLLLLLڜ@{M/]tXաhў`ɠzMr>iY"Q\ KRAePZ/m&`&`&`&`&`&`&`&`&`&`&жoO[cK[EN7-@IDAT4&Y/>$SVδqvQ֧8^]SԮ?u000000<'l |_oG0<*cdao͖ؗ_~yK?/Aj|صX@fA={T1,V^wnӗ6\OSȵs6ֶM`AN]E˗PTLFE1%+>ᯉ(Y_(VQ %8c<>uƦL5> 9o}-q_|裏bWD;ꨣwIc4(8∘a&\< @ iŃ>3OtA1묳 >cq'&>+{-oY)RJ:Ww=tAvl$?xgϟOݻwèQ3ΈeY&= /͏\rI;6i6!Cw@nnFr(F?jx qDa~/Gh&u,u;oѽ[CۻC+˟w`8~#Lg*@4\b]7e!|bIo?7uX)Svãܜ ȵ_jg,7 m6u]ON_27.?]v- 'tRz1bĈ8;l_^xag};ώg=X6?8scС)W]uUUg&0Q7dQIv4p}~1ӌQY1~#y?s i~u ފ;95bQᯒCkseGG6y*-5~U^wkw~#ۛ( ДKY@8cy=$0yC7ǙܷLu3'n600000x΋:vyK10N}7J`<ȸJof^V[ 1Ɂܲw}w)""v7`8GMmK\#i+"5=#><{7W_?|lvi1cƤ*勅/r8qI`-BxgҜ~nҸKi<L:YէOd\n^H yo^{ѣGH<ߺuk|zג/45 ,@r2lI;̓^h6&@ O+_x[u^'U?in&Y|pa\$%H~E ~?*GnĸoXS5?г9ysL.[}KGo^7Ӝi3!8j Øל1NCI4f|bLLLLLL`i ޾m=3n[:2oFqM7Zk[nԆ6lXZNo<"K[ǒnZQ$I NJc 6k&,Ռ{mY,K/_c5e=e!`nG}tI$\pAZn[,Kl4$Gf,"&`SV(Or$RK-n= kB{Ek0_4L[Dрcf?bg;ojРA3W$~7j8fiO ֊.q{ùHB?dԭlBk6$&:0Twwk!/9cE @ 5>ԓ е80ꔄP_Ç^ќbs1͏k t:RmQc9&C@b-+b>_ #:[o>C '__38cOfM~8;W^⋧/^y$eUVIo##v?ȖXb.}]9)yv,r 1X9 a,1zo+͉᭷ޚjqwo~BL:9$UH|W髀 K,f< Dzx_/->x6yM}6|Znb̯d$yN  ܗlb˯n"4ꁨ`Č?S]QbՊ/Nl\RHſ+@w"ra˴B/b<ѰF>s^F́]' 6oiSELť>_h,?]K{WebcLg0,|8Kȧ&F7ŵ kLX>SLbPָWTLLLLLLs2:{Z2#_*H`|&2B.җg9%f}oL}RҀy KX{9H `V[-viȐO=TK_ poy˗SKm &?M9idfb O_8p tjB/Kh3c"s=w^5Qy3<3|*=y&T>$XֈkZJ,3XjeH/Pڎ='n">B~>_)@8cS_&Zƛ,#sy{=a$ *bK'iBo\7^I2,B$/۰}kO,]W dcT @#@2/;WRP@XwR..,1Wx\a `$6x|ƇD.KtƳ'K)_$BnÆ 3U'L&]; H?׹GO#yT>(DBE̋S[uk wrèe {"vԿzEz#>HB<Ʃb߅SB摊2ѭo M]gIV$ GgݜYcU504tQ&Fޗ&bcc&GPk\rD48ߕ#SG _}J{C_m5W @"@IO>2=0ޮRIYZ"7~BbOdNS#HKS}Y@bXO?4?6~5ߎ_iQͣ,DDgd"˘N;mjcncx2Fe$..$G\`qf|YK%@Zh\oޒ+ v @"sI|le'Jg_HRF2u'pB\tEɗF&*i?~זkr)Hn3XK/Z\KǴ#b\!O ԭr$.: )F]ܳacd"*]?4b~|ݵX{Qibw|m")A;c,RCOt_Eܖ{Sÿ6\g.GrUR<14&~Ə/ smo600000TAoo馉kf*e*K E,μ:|$Fƨa3P R,WPnʕ~ Fv,{ /~AoR_jc?Ś*~0A%2X/܈#;qͽ袋s駧%Alufj @%pW% u{Ő9Ym{wg.6oN~b6N7dȐI4 /2A_XU7QG$Yn+X񫶉b!eEvG NJyaIoFD$5NK~usE7I>/6 ߢc!~`$7DR.o_`oH2Lcr~+|i (r\_:6m#67gQFk^/.1dϩF&MM:pP1ß&6rVXl:8O)%86oС7k=:<2u:h;=z>&`&`&`&` /=2,_hSn|)PIcjs~|hU)f/dQfl.|7ǩ6ybƿy9hH A%՜?ذPn|۱ZV ImƌoK>L#li5}U\y~"WzVWZi_"6000000FXި!Qqd@>mU_:Ϧe^x hqLLL` k=Bp-;iYbQLF0y_G/h\uПՒDM2jW _&1& _>ї2}u.Q$6000000I/$}%2I5\cLLL:+L6zntp Ҷ%TK/=3GS* \Ko79qX~MnIFLMp R憘$\k|W7QE7ޢ%BAf&`&`&`&`&`&`&`&`&`&@n%p`⹮j: R@`u1*sƇSqH,(kB;e9%BAf&`&`&`&`&`&`&`&`&`&s@w1&b)P4H' al~\sƇ>ՆP%]lPXG%o300000000006%пߥעWRKI` qM_rE,>&ƙ:??~43*LLLLLLLLLLڜ@nwqCԕ(3/uTOgrl$La QuSMGT_;\.rFౙ LM.%;/ӧ\/*[6@A_ɂ8S/?2׊A?Ҏ`J.qk @?^Rv wkwtuL *?3%SV$&v|'nPiWʴ:ǧ/~k .]$_&Yk ҴiGFFoW}9˙1/M(G;(&TA9i Jy(k"1|HhҊ~K L=V~Yڈx(NPf&`&`&`&`&`&`&`&`&`F`Z͞!ܻw۸>ڴl4ɩ^84gX/G:ĢЯkbGH:oQ,Ҏ?F\KsLLLLLLLLLڎ.#u,-6&SFoo&1IQB H`asρqqu}S{QL}+OLLLLLLLLLڄ@J˴IxZ͖3j/{R\߯˨5@꩓OA]g2āESZbR>SoO000000000hu1h@DrEm &%B{sS;}^ \ipJ_> MGca\c$rT&A@L NÇ[sZ/խ$nX>97++Q_ CV 屹9L1簙 TI`ܸqS}LLL`")@nݺ^Ms~-z%koڥK/JYڷ/\Og ƗѮyns-I&17T>MX҆@ŒOYF;}9cFYrqARn|c&(LLLLLL`"0 ;uݘ @;`'q3WƼ{ȶ&09Ŷ~=&4Z4zsymr:tiՉ$1"A~ĠMz:55\֜AD0i2m!re7 LLLLLLLLLڄm!ﴥ֨?]̷V[C{ǤSfOՒD 21ӗkLTP6PWsQ@r_67DO000000000h!k@h!)D6ֿ]*]mKP4hO0r65)SeGq՗#.IusWEw ?|m9J#mrkliޤ5PEg"D~ʪcՙ6bN?Z?+>~k|ʘUV}S㧎a&`&`&`&`&`&`&`&`&`JFOjZmoC_:U cXm5Y]3Lɀ\Wqa.S/|||ѡ9O L2KPwo$>VZ_} 籸f}PQC:]GɆ/l&`&`&`&`&`&`&`&`&`&`&ж7VnO[z;s@?׵j; Sj͙KY@8cy=$0҇:n3uoq׍O>vl&`&`&`&`&`&`&`&`&`&`&жD@n/[}KGo$L %8Fz Lkj̡$AQLt_i30000000000&wkLJ{VK  K>BiW=>X8Đ_Q,%b|LLLLLLLLLLL HFo5ǣˣ7iy"#7M@%>L:Q$Ϊ?&_WpפWeQjg0000000000hkf|tuM%C &ЙzO>)y@€4|裱Z:bl&`&`&`&`&`&`&`&`&`&`mM=onh{' SRMeѼ/4ƫu|LLLLLLLLLLڌ@J8KgߥWe"Cрxpϡd|]s&Y>ʂ(ÇvL#q S %'>WMLLLLLj$O'|RLLZKᅬ/bwp=ztc.Ut-UKoTWK/?IëL2Ɵ=uB3]KOl}{4&SF+omIϯ'`Bw=,m:Q_ITD}9˿(&?e+K{O!LLLLLj'p9oj:/}Quohc9&Zh]a&9 vi$<tP: c='xb >+r_rKᆬg<rJ)_*v})l8gM?qѽ{ :5*8XfeCq%رcӜ6l2dHyw_OF c9y;F7J\Zui+w)]ݗ}]\yi8KOhInl/׿Oќ8K.雏C=ꠞUԅ BCg`L + 1yt\4|ڸ84 @'@6r좋.*x`C'\< @!p=O?guVᇸI lqWƮ'|r|1nܸvڵF?_3tIzň# D;Sɛwމ /0>Kc杈}gϞWW,W_\{1t**>zwWb?G]%^] 8,n|quDy^ӽ'6>.O3}s`=iOv@{$kI"(B>ʜPVbAS"B7R |>O/ 600000NKA;zcwK/4g7oyq}|kb:*W4! \w}w)""v7`8GMmK\#i+"5=#>gR[,go< Я']ɸX-KNY}_3r%q!\ÿV5Yeԑlȍ:`CuAcE t>RF?w&vN_' AD35!JkET!5W<[m((1TS*5wgs#|>Y]YZě=NHP-$~䊘kzvM7MO<@Xa ck&%=|  JzKB}{w_O7ӨlUWMOr>}bxWBہ``rH25{#A{O[S.7Iׯ=ωg30$U` 9^\ɸ ><%PI_|N}(c5uvV.&rFr4 M~o`O>H `ޙAjgAi?f?ҿ V-J9Vk z4oŠO/XJƫVKI0.29 T"AsƦdiѳ\,~j.X1[l&`&`&`&`&`&Л j] V#) Ӳ$q 2o+P[!v[~ټΛ7O>䓁V~@bK"y/)93)!?=X|afKƓoFZ aծܚqI&LD@oviŏ8:th!=@2o-rgϥ: 5$B9/[5q[ lĶq$sYdrc|(yɹ0sͅ3 |s̕lm?[UQKC CзO~?oS؜J&]RbS_y$/ZҖN~``z[1\(mX|eN<|cs͌0l&`&`&`&`&`B 1"A)VgnStSN*o'+b G/ѣGxK‰'me<6B-?𙛧W1\F!vu[p 3߾\'^I2jEJ^ a -P:)^6XzWZ1) P60̼袋QGU|Kvu>vL..l1Wɸ1#C3>$r0}l07jx#,>ޞ3UGMGGqAzHo^5u@Ҁ? >Wx~RX}2HY6hG=Rf2ЪѦѫ)Y::tqU}'-)9W?㈃1{lJxc jeé3#"g%j2_F,8tAM1)k600000x'IǏtmݖI;8cؼ, Tmo9N_Wi}| 뮻GGX$)\ۗ i{$ǠoB:u!\;d~Y8%g  T>OkJ$x7]w^SN9%\veɗƍ'S_m|corOɊQF1c" @R^c+9@b. ,6lX%ä GK'N;?3a Z(,2`颫~K^U ϟ̚j]CshT$SJNpM2Oh!D/dJ.0~NѮt~7m&`&`&`&`&`&Ы x] ><ѿ6$S|,'UbJ~*y3HbOni%pGs-ܲ"Wނ[bO?OS@S4σ>8==ŚJ~Ç-2x7]D9ୄ/8 `^iRBA9Ӗ |˧qn30뮻.%/q<[c=|)uy7b#G,~95[p2w1y[ś lWi}}D했5:ej5K5=<;6VMFWp{;c10kuJ x;~'obBѲoQaK-_6e{᫱R2:ve<8ih /A!kaZ4%*2xNSz8|KvyhnZxn3F Zu҃L'm*K^=0000ohSj)PNc㚥xsѪ\R_gˢn0vpgү\ mZoi^M;m նJ$LHc8{& @{o2͚ުaXz=x>' *vk"9}w5c~d3s7,7x{㇕KXlθa|Sa҇o|կݺ5_iG'i.64oSb:N (1ޝk.ک+AEc~hZ;;4S@&TgbMN2Y}]4(*s0~j300000MT)1>YJr>y[g!?WNr#!cq}w#~m^{ʭܸu0.ck@_3<=o2ty6O&=bU7uD&R7%Z5&;9719S*ybQrX-cSÏ~m[e($/JdacBu9S\ڀDeLLLLLLz(b{r6G|R2ܘFm&LHOˮ ޠhVSsG,㚟t~Ǯ"j5MDJMB8!b@iZޏQ>1z@(9G_8l&`&`&`&`&`&`=oHTzK)2dHVNc6jLLL(-R\ڨciдMI?&-\.6L9c0bΟ:Рr}yEi1Eѯh}:@I$ TiB&Hq] @# g7E֪rU Q3# P 2+Ypdk>~~K?Vi|‡-G 4@AލN͹nm}HYm)SJV4pJ91rh~?Ι_P<Ǧ/tf")13s$4Q`jW :. .P60000000000h8f.]~Er;A'{e2]Oqy;mA8lmDqI*|Wf&`&`&`&`&`&`&`&`&`&`%PN斶ޙ.}1hUS8Za`W%}Ģq*~$hW|1ja&`&`&`&`&`&`&`&`&`%з$FFfv+*$WtA$+$k:g!K~k>j1@t~ѡ3f&`&`&`&`&`&`&`&`&`&0|ݎ=@ֿ;_F-I|$#s6׹' a_B?y,Bd|ģMQf&`&`&`&`&`&`&`&`&`!B4&8n Vn-5\z%۩W4L. X9  ?c- ](~s:f3000000000aط2s/֘`c;w[V,[}KzɈO iXΡ$Ayt_]Ĵ @C.N$4dBiwWr߫b|g$㛋6b"?9> 18_cc5E><LLLLLLLLLB`9?n_o<^`JъlLLLLLLLLLL1@h %& j[.+W.QC~Iυ}&Tb?xx9ȴ`][цiJky61l&`&`&`&`&`&`&`&`&`&mcSǒHw[&iw\jWw%W\ O@% ʫ$zs[ s' SRA[!Ŧ4Fbli3000000000hqGma'fߥWeH;9LsJb,8|ǔLPI[O;hgPMc𣮒~2Mo>to"f&`&`&`&`&`&`&`&`&03׆EtBk[iҺg>ܵ/=U Όe!uv$j2FZu?9B5|98(kDHLLLLLLLLLL D=x9߫R%s #SWbAJC]/_1pڨqθ 4@>InM_;UHį$!$iGܗ1SBPq/O~)o"Dj60000000000/L׿̋2GoijN *#O?)a S2%s q 4@!viпk+r%"0&Ԃ8gk"jMO_vFLLLLLLLLLL sxAԕ(.uC˘O>C{g'~53쭷 ]f~Q^fx,/aC~m ,mu?Կû:?/V52" /!? ~6ӆ?%"}J b~mQm~7LLLLLL!p=#1a=g ofַ5K/38#io|3}ML:=% \rpa?-zjqG뭷^:g_npA3fL1U5$N>0a„{e sL0`@qn*ƍ sNX}ÑG١qW>(im ;cpIZ[p)wFT|;נ#B2o3f/ m=,5,9K}mO3pfѯemC˖ˡN+Ϫr4kR[KV['ƨXcWQ''c5).~˵v Z\ctdZ>E?,^c)12S_旯K000000^L;h ., 6,\uU / O>d{Oj&3pxy睗QI n F /Ç~M84_qD?o3~a7ON:) wyg ^yp饗ui|? evy裏_}L eǑB먟3/ aae}F'Z>U`$Y rՔ3SܝϚSrObxJg\> Ng41o~A':@I4x3ڔвcCWw-󣟣KsAQ'[O8G8g!/K>3:񈯋T/7?*8 Jlm<$N<0JG㏋?oG?Q@xxON*O="Ɉ_~9زW_Mx *d )Aщ'UIx| Rr\\O˒(`{g}6]nփx:wJOܲ?>lfI$\rIng?YXyӼ+go}JD\s5Nf&{ Dy$qo& |` /IDrͶPIK,D*' :ZjbO gܧb7|f޸ q袋W\&KZ.ys0zsjh{kZoՔJ=m_MZ^@(w,^wJW5U*$ <1P:V Cg@_1(Kc+Yx|)]]sĪLLLLLzD)*] 'ġZH n!~cM뮻'a7t,}<1VX! zˀ>X`|`РAaUVIoG~GPS/.R5ztlKM?6&ѿUW)[q<ә~:-\vFx5< nzCN+~̘H$9 jv!s=7׿| Y3qRqNUYΗO6[-mEY$}ǡ5@^A˦wB=uH5ݽeUC˰}$wEL ;(lŤxLrCFv._Xн?G%?tiՉ.1Hɏ9ӹ]󫍱Ǵ^ꌯjTͩtR&'a,`1Y,m Ps0 bOcuѕç V5?|1bDBS<B~=:p[ $N<4op.Xbo=ɛ|#n-%x%rCg!n)Z|v)p1Ǥ)y]Y@ 7|sޝկ3&M wuW֑K~ d"<˜ O7cз W_:H.Q2G "O7.l&`'7p`kt8IWJ u]"0urJ˒/oM7.}OGj&n5jT3fL.$5 $ͲaÆ]!?+: l^K}-~Oֲ7C94 }~}O!&|d|0}ƛ oZ1s7b=~lYyLjK{.]#+9)KGGv- IW%$8ZȇW+!.:~_c61f&`&`&`&`&`7ElM:<2yR-%,%OqIѭ:c$8t[Vd[zk@X12p?ijz>y>XSC2|EOF(wUWJÞ{foVZ)%>̖ |GƵ^[-0LR{#[I1 [}➋9‒ on!v1 ѸB,L`ZM#lD qu)V[Wj͍eBKNO8r۟^ eCѣbҡR_ИZ7IɯH}Hs/?{7Zjg}+uihܜDFFggP.?rQ,qFяQG;|>Vl/Øzk)K2,{kzLLLL_xzl_hSj)PNc"CX\@*3S,ocǎ gyf(\ mZoi^M;m նJ$LHc8{I_XGLJ p/2eJfMoU;_XΟ6>' *vk"9}w5c|ДK?__Yc[zX[![B'}>ی^@{?nǃ6;I3$y?^)?GE_!v(\猡E*>ᯋT2X 1Jb`̡ e F3Fqiq600000 I@C/@^!3jϼɍm|L+.q[,M^5ϋ*_Qj X՛ѢѬI:H_v58ˇRc5ӏMy)jq&B{'LLLLLLz b{r6G|R2ܘFm&LHO˲PEq0006j΁z8z >40%s>uwi>sꌕIT|ՒDP Jqhr ;ňfms)V>c?Vm&`&`&`&`&`&`=oHTzKm.>I6ڨ'bLLLzChh$ Ы1z^m*GFf z '?ڨ˟s|5?sGL:}ĦMjÿS#HgF`-z >|h cSb_?qtQ_2 g30000000000hBE($X½ _َBiW;>o&8+X-&1?l&`&`&`&`&`&`&`&`&`&`&hҵwe~xtyVK&A ɗ6 .Zj~@8Yi~40000000000Fh.ޕեW %C PIΘܔ< arhzqLLLLLLLLLLI7s3?<{WeQKA_>ZY K _0s4?y‡-P |)+Q2!+B(_!vb$>*}lAs|k"0WI|5&ALLLLLLLLLLA5Mӿ5tUW2A{E0_ JHWI[FHϓ)GeѺ74u~ui&`&`&`&`&`&`&`&`&`&` #P x]:{E&+:{{%$뜒Xd=c( d@>1%āL1L`1ʚ7/000000000huWoP$i M{ߑ_#Z ?>B>u%$K>uAr_:~猫k~: @lI×hT8)4nXO>IFnGGӗzU&B>! LBv}JڈU>$}PܺLLLLLLLLLZۉmr0Nn3]s2/Vz]檆Pߙ@%q)Z%ӆ*kh#ِm_bmAsŪLLLLLLLLLCeBˉwעz*1s8ʗL(o Qo heѥ9Az@%+տ5[b'^`^si,%yU%$E]A㜅R* չ|cS2 u.?Xjj,hl&`&`&`&`&`"iӦ͊k200MFaj]տ?[UQKC CзO~?oS؜J&]RbS_y$/ZҖN~``z[1\(mX|eN<|cs34l&`&`&`&`&`$zw200&x' Ͻ7ԍ"܋V%,2琮DFFfiGf>i&NɹGh(cS2`c87V+N0Dzc5 |կ # cmc ꂦX 4 C# wZJN#j]Cs_Om$((S"szcDƩ/sO~@h:?LLLLLLLLLL1~7~1({T n>}$_7M^/;/^@ԡyP^3q@6\1N,+pš/sn3000000000nǻ5ރ{.z7JK7 G6LD_JhIբ.6% (1ĢЖ+?vLLLLLLLLLL1^`Jc9J#P﶐Dh+.$Wt(tH/ADd>+)0Fo<8j[n~l&`&`&`&`&`&`&`&`&`&3Z%y6$ n팚cWZ`POhkӧkJĮ6h$1Ũ6 @ Dh){E*49A%3.f3 7 IP(1ѹM~f&`&`&`&`&`&`&`&`&`&`&lݥKO:3%N_¾en30000000000(lL[sK[GKL4֩C勰B0䫒>b8z?+>~k~UW{@00000000000h]\t|H;pIW`IbuB0%r_Ob5(ṆCsSO @ƏNZj!g)SO>w ~ixw^mkkkopպzy;S4{뭷c-]ܯO߰% ~ʎ_tvmÎ;X.L`?Xz("̻¡]f}70aSߌO\{t8qCIMmQ{2fggS@VbzНKpjЃZԾ9g&-\o̥_甚Xs㼬ie; %s/(ch"(icԆ?sk~|k? vdwqLƧ~z|UW]N:餀vwxB0C{ ?x8>cƌp7"@mu]F~_?0L6-pil~Ow^>+K/MxӜ9)ba;x / ;sG믿>V%ȀžKoKaqN|aԲ[^u0syKL GK(}`H +s 6_k)6K?pv/^_ae^\^&Zuo̯}gEJPGv ,sJvSP V Oz'LLLLLz.kpWx^*29c}W<8qbN;;$^IL br4lgR}XTؽޛ%asik6U~8㌴ޱcdžᩧ {:Kss \_bXX8;=gyf_x4yc˦yf&{ &!C5\3< C=9rd:dMœs$op߿`W53;^~?d7k]R$B]VZ) ]zSW XkS:|7/?%|goZ,Lx{bxgû? M>3[l;`$\]azpcçuɍJ =|BxCfOo%t4k4[6߫Z-Ip/_m a_?ƫ_ 7 l!4lذ&\s͕em|l͒H\r%igaWNjz%H͟yq K$ʓ$o~3]0_y'{KC꽆{RK-U=|tS™+iõX7|)7.H\/aW%}AFp1|s ΑΧ|y}KεH/1'|0 &s$ I{ߜ6Zxp ۄmm=hP] +Dj.` L8Lğ)ܟ>hsXS)ցq8ոX @$(xV[%'pBj'W|&u]ӓnizjN} +~e@{|<8\s5ID`l~S,|?< 4(* {. eIh[O|xJj?/f&`K| Jٽl.ƽQ<k|a CK\L !4 MD`.d={~?|h, |}k8LpJtգXO;|طef"I/6m gZB/Rs4jLiҮNky-BUO΅9b5Vs+`jӼ*å :l!C|H Ȩ7I[o*H`GBell]7e;oJ pciɓ'f-]O޾ij[.Urk㤇rH8sïGKy3Dova&k N;1c"C͛Pv)wf!\@`[#I"J1Ui önlG2wEIߌ)7m# G[ri;^X%MpkՆ,[a wHdB:?4oo&=>1ާo8h+|/~yBCYC ?аѫyTJ\XK@mһ)ScSq~6#&5c{%bX&cc:N;,D#!Y vX Z8>iØS +6~QE춙 @#Pχ#F)VgnϓSN(Zo'+b G/ѣGxK‰'me<6B|/@"~.37ObԹ&DA9Cb$8묳ҷw?JaV /Ra[h9o aӵծܚ6Bba$: Hf^tEᨣ*%#c9{9[U5"ol݆qc745Q |%}'D>h{Dp>%<% 7ui[Ls(4pSH)O\V0taO3Êh3&vb?)I@.ÿ|}|gͰ񢫅Mkq,\/ytkqj %6IfӗSgsN1K+q}SG6%ޡġ3'/8SBĀq,1ɨӧvͯyh?h300000DytO  Ovm)yӤl-B?!\tMaJMc9&mMBVTկ~LJ|lހ4iR뮻GGX$ۗ i{$ǠoB:u!\;d~YrJ0nܸti&p_||'95X#$]Ѷx7]w^GW5|corOɊQF1c" @R^c+9Cb. , z;>~|׿N\mw 6_l܋9B+1k$:ߒaPo>[Ϥù`ڢظ%nKn7 [i0l•/ܞ&b Hb[{㇜ges4~pt;U=K^-_RԚ 90lFH@'AuJS2~.7Om)ᇏGy>XSC2|EOF(wUWJÞ{foVZ)%>;m?D >ǟzk9[pFYjj0^GKKA2> n|+$AG+5ݷz-|}8{ގ;;x#7:V3[k\guʾVklF`zL"\ ?Zvp㷏M\؅_XcȲGsG<|I1⇖xG_x ׾xW?9͂? ѣ9ۥISYcߪӏ/%7oHߖ^9'4qn?~Gmʆޙk1XSb3V/V?%>O?m_bK}KGctӊS@O#A:eA6|/ڞv^ @y O7mJ7 SoL}\to. ZY9lYƎ\Qjy>Ο~wR[Ϧ "[=R:8~jGNvT&Y60X1|^%4?sTZ(P'eG(1 gW aZ0s\gu r|_Zxf&`&`&`&`&`&3 539Cŕ4m-H߀0aBzZvVEq0006&M| Ҷ%TK?iZщxJ)NlJs}Υk~ך(90~Vg-I '( $\||J-4VS<ι( _[K[s)@; ~600000xC[ls1dȐ-$FmԴ= @'Pؖ ==:ZuӆI.]qG&]]cI]H/^ZbhM-@IDATC e; Z.D e괳(3:%>,T>CI9%~u7"1 IzqNj_v *: C C"?>T_i9(%lPXM(zo&`&`&`&`&`&`&`&`&`&`&@إm7CKEH$P ✱: c+L6k|5?. @c j+QJCyh6Jr=Zr_dH;BTg1qЦZ(1Ǐ:>ĩ4p]*c30000000004MSC)cSy=ڃ9#+YvQH`78W ~LoPWr![ @C JNawEGWǔPh?!3O)I-v2N]]k:Jg,~~f&`&`&`&`&`&`&`&`&`&` !ЧҤ){K& M~4olt\8|5_JRT^\LG?(&TA+9i yɨk!0|HhъqK N;V~lmD<LLLLLLLLLLL! MKFw<3z82 u~1GAccK?ctp/><m857LLLLLLLLLFoˎ -$wu~3I;%KdasρqQ2N[)16kJ >3NƖ> 4A 7$<n팚wGZ/6 $pAӯJ(ADI1z sL1&`&`&`&`&`&`&`&`&`&.J8DO$P&B3oMYMG_/>+:\irJg\> Ng41o~A POcsԫOLLLLLLLLLM`a ̽X8@"mw-󣟣Ks23S"?d+%e/8g!ؔL>3:T/7?*8 4Q+DBh6? ~ZK ruұs}fkId|U˿)PQT*ӏ؏'JjAaSA*dt6G/vm&`&`&`&`&`&`&`&`&`&09$w~SŒVI ƁD|Do Q@(]]~ @|饿K/n'>*5ȟ:X]tSql&`&`&`&`&`&0KR100fh{_KCxiR3E`CB ?oMK\:iҸUJf^Q1rA|_19|/kS{t1AgF-#8c9N"@ vŠSkᢨ_b; e3000000000pkz쨘 J,wK_X!vhO0dGE=Tvڴ-(jm%:qh\-Gw 4@;BcP($akni^:u5|Y&X|UA,G]RGvǏ~OSj6&`&`&`&`&`&`&`&`&`&]m?C twl/_{߈D zV}-V,S2 U|X /V<:47eı @ Zc8B$еm_wQK Mu~%K?9P[vx8J6T?LLLLLLLLLLAf gfIun Vn-5\z%_v 3S | %s>8JrxׅO>wa60000000000h,7ЪKw~vU wfZ $Kg,o(@I % )1OCIXMt_]Ĵ @ 4[p@j$X½ !#Kgx> bthij @ HFoݕ߫ZEPI| @RKI|-Zc5>]FŬ4|] @ 4SFj ʡD`J]}SgLnJ0-#hzW &`&`&`&`&`&`&`&`&`&`&hԿKlLLLLLLLLLLLK!;^ Z;V5e; /?τJ$G[xc<ڢ6LU8,_k󷵉a{40000000000FhmMux ]ߕL^G.WrB'RUju9}֫~J*ec.ͯj_q] @vi--5tE^C :$Y>ʂ(Ç~L#q S %'1W&`&`&`&`&`&`&`&`&`&`&0$B3oz痾ԚDȓc !!sŤ-利XP|(զ1QWI?uuŦ7_:7@a300000?>L:Aux?Saʔ)iK/^|:F'7|LL+FO? nUM >˟-Zlė1?; [oyuo`2C8g8°J[Z ssh4ki3EIg~֫5SV5^o̸X¹s1>a\ [ "u1-rv|c`M7$0LLLLLL>\pAc=ˆ#X놭:r-lqtW_n0l93a+MLY:=% \rpa?-zjqyG뭷^:g_tP^}1coqV Wl8Ä R2,90`qƅs9'#WzRi}ĸ+G}ִۆwܱtϿ$-GhVQ1-ȯϿZ;#*QrkPs! }3BٗjZ_3Szh=⤨"nZ8_uZ,MiѫفGj΁Kd<O)?ʼnMi:cxRsiTtս{ ? B 6L RX$k~WQ E^~! ,FgI N:)\{aW6 دїc=py%a}FmIb$vmpuׅQF_? ӦM p@ۯ_p駇7<\uU#wY+K/4Ns惈}\0o.[>޸ ;}` ?82=\hv%!,5,]}Cgph;к!Zh9`xsZ9?<(pfCmOD>'Zxz<[`;-$Юy^c$C@hN?I3:%>,C eMN?u7"5 @%Ӡ_|qe]^{?@x:d{lt&Niq+:DLx$ !}ǁ獄_~9B;JXve-aw'OF_ 0Jq C  kfxrzȑ#&l޸ pg OLJ]2s1`1#B3H`)eq ¯2G bEIADQ((@b2wG|Q;""#*srOkϛɬo9'y=ٗK.ܹ^Mv-_~+!SzHHdM_?On$|/JJ}/b>8S\rIB;@ŝV[m8c⥗^7|sҎ>ӧO.?[|:=yL QU6qbSN9%C{gvob 6vaY,mQ{AJ3;)W=ĦFi-\~<}&M 64+'}!m]' +[mH`=QѫѪЪ1m]]}s<`9E\SlJ.m9墕r~[< j\1XbGWÇ1O[}!J0l&`&`&`&`&`.#2d|[cS@Fˏ!"&ܩ cn^*c3O AlO6X"Zkw_qM;Ƨ>@Bd+*ډW&`&01ˌyP5)S:.wrz^̆"ku}CUR kDMV.f+_{xWz*osqAF<\T9*S̉~wolyTN6bmeWGf #*GXt mm[p4lc1iq#{|cj{f``q2N')&u@bW@3qJj. n9Ϲef&`&`&`&`&`?f||_ϏQ/B瓠<33fh | Gsϧ_[v̚5tw0CfÃxxJ=X;yr601Hcqq'G2ֹ %]\Ky\;e<1.m<>&=ܓtޚ$= powqG=Mc,wmMAKEe1d]Ӭ؈k;֏EuOjX}rT6jST8NDQYo,u^4ZzWl%УoOKĤM@ߖtn祟#toJڷKOW~gO??5[ʇ$# }剩\`jfĴP 6F\bt?LLLLLL`$/oϟޑmqW>Mʣ%J_[mU&&/Dz㤓NϷ.u@哧sNJ60.>;?&wޙc , y|>>r`[nYt\7ةS^r[b-_ׂk(5vuwpu2\sM tP~cmwz꩝B͝i<ѕ !2;#^Wtg{*xo/ӝFkQ9+wj|+G6&b z=Xnq W~4n4lقҿ_4vuZ\%!0URX(qF[9~1ƵAP)N r]p}щS "K"HyԻ{3*/䓪k@vZ讻2P6?楘;S[:mȌH/<=ܼp I`Gx򗿜x7Ȱ BϛC_"_y #<#RvXL6-.4^\)[dOv=xdJh~$]ӧl.=iyW[s @ m,Uϻ(*#VXݵGVFekbmtʴWzZEl:^pyT1*?f'gJbJ22z_EsV]Q_е\Qw?uh1G8՗4O%לVcYHBR`HZ&8qK,S5Ur|c6 ØR'X %zi.Zqn3F|;lϢk &_xD\I9Df={vKa ?5qU;=/xwB>cTm0X 83gkwtkр;h5 As{؜.>kQ/}a+`e"VY)G8B1Z-v{!CI2䩚15/Fsg:Qіi ?NDbtJU ,: ID}y^&LЪm:bb\킲^>.ML`,`z5^mĉN#Fן=m#8ykZ$fntkC.ni4`%}< 5qJocXǕ9P{é[+kI9dZ>8|99ͥz1hė)Fui&`&`&`&`&`&`&`&`&`&`}#]FSVrÁ:?pϼ2 CX&J6JTg:'@I\WLG~kCԟ6 g")136u6ܘbW Nr_';S( hߝK{.]-9uH Lv2_^&ռA8<ڈ>ⲩ:84f&`&`&`&`&`&`&`&`&`&`%Ph-m-}8]:s;ڰia`W%cbyu+~lЯ11ND10000000000>mt|mHopIW`Ibf!6J_0NR5(Ns~Pnı X|s1D`dֿ5o@7HG>W[#Kؗx6.TF#}jG '7 a+-5-}zp@RJ͆_XPWf_'>eni6000000000w'9~oD@-[}ۥw> gZ $Kg.wh316ςhSbk:6 R5 (Ĵ <}:ksc4o{_h#ϙwn6X½ ʹ!#Kg|h|A jcӡg3000000000io$ ӑtm4пG=]!g:i)0%0-Sꎁҟ1*mJl,ԯxuC*64 _ @e򤨜z\T㚨GO֓A7^ށ#FxVج搶ҼOYjeU.MLLLLL`\xWdLLL`$6@wՄ z=tk ZvAF~#U"[}I@5h:__~o_lm&`&`&`&`&`&0 LLF@YQvVă*o3Z558Z5v恴nNnKOǟzGi8dYF``Ġ> #-G?ik!_m~'B/&`&`&`&`&`&`&`&`&`"&m\{['4A?n6!||X/pP K[_:~mw"f&`&`&`&`&`&`&`&`&`&oY5;O/;wtw;bIB>%0$Gܗ1˸SB11C/^f:){;5 $~X7~v}`5w4%$2kQvAPj ?š*SK>j٠XژGLLLLLLLLLLLb=w']}7{[.l"ZmPW"C](?7O8Df&`&`&`&`&`&`&`&`&`&wuytBԵQ9Jg]>}{jn6, aZ  QG{t`iJ q.aqFLLLLLLLLLL`~5;P/;GgNZ[1ڣ1@A_(Xzm`q9?'isMl50000000000>=]ӆB+Bp&QRb?uV0_B hɠT,ksku5~ߐ`jLLLLLLLLLLL/$_7>/MRk6i3捖]ߚRK\JI2?~G1:m IPPP/u},NF] щFXK`GɣG]qRuHLLLLLLLLLLB8}iih Rޖ R c>ĢЯ61yl:hn6|c|,WΣܔ60000000000;&h#v4Ҡz Kdasρ(G)1>k(};gS5m1 @nxgzћ]w3g̓|1cFom&`o?|˳Y\+wk-݆t˜^{mHp_|1{2OG]xK<IJ`en=aj g>psx8#4krAߺ@$ŷODcNKџqD|~>c_5gԇx"֦1gtO6l˴}ӟԩSc]w_WP}8W~v60&?mڴ馛&{l*yi_zc~xm'?#8qOol:||3Qxկ~5? 6 N:Xj$(vuwx׻'pB12wq9+|$g*8*{Ud?_:-5r碲Fj5ymTvQ]~]w83+P}|f {jRyL;yR vr1飆V}C ͛R~}x~e|3O/->4pY/ca̙2?-MZ$×Z e-q~LZK,T@9JijSW\79>7#V_<+ONc1xIs/9~ߪ=P;h|K_D"&ӟF,0b6{ ?ܑs՗Xb,hsLp!eY&w_KnoK~vZL0q<@s]^r%o{s: [,:kkLw3z!l"ZKb#aM6t~'Zq_ TƼ:̈_ͷE<רlZ-WzoD_ͨOs:+=xt7CRw0:){=bVzXϿ8WQ!^ ^w& L>%fBzfDHҿ#6Okg300000EkY=иꪫJ:2>}/b>8.<'hwi}ݚֲ7Zs1K/o9 iG}tӧNr/rj40b(*[lE>i𶷽-=yFrXku0q|m~Dњk疟'NnkzZgux;lxXJysG'qǫzl݄<u_]Ɯ(+,T}jLl]Deko;k]fܲQMw<[g};~:->-*\1y+'hU%tLB==~BF,186/qRbȔrthZ,/ LLLLLR<{wΧ|)dqGs=+ o~_$;?5 e`6w/ Hx7syq?馛M P!9I& | !QkQ pi&` 1&{ςkwFi;] l {wȆ-w5_]6 ɸA\=#hV1WX&gX|\4ܝlMa twTJA ֎XaF|ҫ}՛os’zb|il/D̜k9ADءOTgfʗG55ʛܥ{l7͏^sTnYK#ι 7Dx$:.hb< ?T._ʱ;;z7*u}m tnҴq4Lqisc.+&m#5NɡxO]s[7`XXPHBNLݑ@6Ra6 6'K|ӧ*SLLLLL=5l6믿ģ0^x&gyf3f4ڼ;O"6aff7?<8J#?~I:|hJɁ|iK\yKs/댗Zzjf_:;uL~(;&vr*j:tPbkX"Q\- dU'u?LLLLLL`$/oϟޑmqW>Mʣ%J_[mU&&/Dz㤓NϷ.u@哧s\/VfK/>#΃&`#ވ֊.6>"g9"=z/'+}$*E/Iuf]3z7?E]E41ңQwFm|~?Nֻ/}9h]@$.{ژD~JeUɘh? lhtbʥ:s1`G]LLLLLL`#{$G zUw՛nm~;_6 f;ӦBl~g oʎ9y3Az<^|`jTe|Rk.:dHlgZoTűu2Z,a#@1SI8j1^}}L/E+7.m&0P`>Yc0000 _hlSnoL\y;ZlM,˅/xwm ,x̙3cw4 nG!/ՏsbsK >տ0w!+^=bw"_m*S"x(ͺu9c{ߦ; .klS]RDl@IDATcs?yQ`~JJR5%įur,FmՉNmF%~b~1?&_qO S "MIX\M0Uw>buv clrX@߫M8)#N' hglܣl 0" !dX3S)\9mI oֿO+ԕXfZ;}s8@ѡ@Z<uV.Ti>NX,^'㣼*SWc}XsZ @ ԟ~6=Z7Hk ~8"X  d % ڔΡMTml [5ؽ'LLLLLLLLLLM`C_6X½ O!#Kg| N|MƦC?f&`&`&`&`&`&`&`&`&`&`& ] |4GGGhF@;GNZw 8c Q|)铯EkeQvLLLLLLLLLLM`4otGW.ߑG)wrOP~-N ~q2ԙS60.K0WOl&`&`&`&`&`&`&`&`&`&`&0_M^Kg F7 %"5"hmh>^xC_c]篿"M |!0*w:vS[DR엟R'6cGxoc>zD}櫤yX֮WbX &`&`&`&`&`&`&`&`&`&`&Y5;Hwm&Ho9PRU*:ukDr?m*es.Wn+K0000000000pFSFKgoDb}[4xpϡ jS]>f@91m&(2fy8.40000000000o"Vk~pߖItHȧs~4?*.ؔsm6000000000X|%}oe[K^ w'}旞?pɲ:]A?}S5 (-G?ik!_m~'B/&`&`&`&`&`&`&`&`&`"0e~ErFmҴC]fA@Gȧ)9u_1pf^O}'l&`&`&`&`&`&`&`&`&`"P~r1F@GMNz |J`Iӏ/?bqUćjc@c! qPg6e}'Bf300000000Gf9!{;_/p;$/M~}]gM :9#Z>qЦć9OqʔĒl6(V6Q%?6000000000aFBh@l =b=w']}7{3H&1 6 \SfLR,Q3_ 窏692f#g* @? T&OʩE?x`Jg&ǚoxrz0uZB4t0j⯧?tu3^)^n|`9͕K}M1|cRoDVB1B4 lt('qGs铑~q駭%600000qIW_200DpnU&L\ЪѦѫ)ѻ%KG.N?:6ON 0Jgq0rѬlmHЯysO,@(Nvn8)&u 3ރ; F8Կ=^7CO#렭 cAsSOĢ,WkΟm&`&`&`&`&`&`&`&`&`&E (c@&hC_{ %藷G ?q90%c}ׂ)P0Gw< $SW J88V 8_c\cW]b&`&`&`&`&`&`&`&`&`&`}&0w9}"! PŪB0m?ka~jQѡܔc30000000000~m{^w&>iO8%3^Ƣ;tBf_>͆NLLLLLL~{<3L3g9>`̘1r~7Wӥ ,t:]k?=|k;/bQKsX<ɰsѳJkOi=;yRĄ%{k$vZhY|7SokK9)e C\Rx>96Uk͡2b9K~*LLLLLLz! >O6l˴}ӟԩSc]w_WP}dӦMn)q*u ; h:?!7x{fO~|<#o1N?|]`|3fW6`8餓b2뮋~w+N8!c͍v#9J^G>g}=TvpT9)ȧ0tZRuܲ1#V^6Qώ卑;*4b Ǟ㿒\$$~֮y좨^s}_D@F~=N5yofGs-}7qEy ,:]@?~tAo;^~xW|.OsWַЇ>?+_J ׿Heo/~1~w%3}v_wB{1q~{1xq>^͋;*7<|D )GefʇqOό~ 0~[4?m;l"{v;>~%3O `3A\jcӠg300000Eя~bs=7|:G N>ofE̗]vevũK.$!b Zpqw},ojsLKsoG}tӧ 1 6?b 401OuwmoK+W^{'ko#\sX~8e[ʒkzZgux;lxXJysG'qǫzl݄<ޕd)k̉sI3Q}uU[cUu7CT] |_Z6!nܱPjG 6Z$?!YA1m(;+ƴ\-?ic@q\ s>U.MLLLLL`#3w9=9)šn@=3 7~O Y66h|w0_wqSniԐr-A}ҤIffeÁlxk"H83{-7&`&Phq.hs=mg Dz5pٰ.qLynS={G lb nkoyސ`kW~B ޵Q:5IF~#U2OVNq(S܌)J04tQ'F9&!)AIEjM]Gg1sZt28 0֠ +61{ܱM>600000X!#㓬2w^~ 18Nw+c| vWlbء$!̥:<ֈ6]V9*oq߃Nvމ0㑨;#*Ugwp3ϦM[r9.l7$q/hK\נӚ_:6cjuR~gm\}ȏ21cNGSNN& uL e,FuڜT9Ou@s.|uʯ|eϘLLLLLI{'IoO  ؆nW^ye<ӤN:|rnYYl T>yz9be60.>;?=#Ӭ|:f&` Nױ-}B .FԩM/-Nv}k5_;:\sM tP~cmwz꩝Bc;x+wygr\@z r~\A|W_V"|tT6NwG sh<(m> |5Vw&[9⠈1m ׋Ucat'M c7>bpгGuK=tDKO~Ġθ|)uWb0^Ωmvck84 EbQ>. ,y/Gg<3OL>ʻHXJ>zie1Oy/e R̝v)[}!ց3_? ucGj\~q NHE;FPե icl6t];#[>Mm>8bڴiqWse]/ocvb^y}|;] ͏k~Gl>O>=S<@TwQT>G k$JO/G勇g5ҦWeʔ#J/fODˣǎQ7A<9+xTV?sWMw:fq3&-mCKNxJL7~hܥƮ8֛odrP'97u69jq L!bIUg48l pr` _9~hGPۭ.}n.Zqn3F| ;lϢk &cxD\"Df={vKa ?5qU;ŜN.xNh}&`&(qF3gΌɓ'wtkܙ;h5Pnt;W?Ήi~/-6_Th=13=Rs~e"VY)Gx8B$*pTf&`&`&`&`&`:NBR'QcrV6a„Vm)j&`&0 Q]b}6q^ؿ;F[H1hk/l?Xל-sNoɤiwS]i΁M)|JWԕ硳OzfD\ɋOeG ttNDfAn 2b*^6b૓h)yl&`&`&`&`&`&`&`&`&`&`&;jЮGENy{ߵI^ipF G]#fWuJ|X(s10Nqڔi~;D¥ |" [5iW;+nw}58mLΉAe,F 8)v;ӉQJ+fXQ_}e30000000000]:6:nxyѿwbO>Ӛ{jm8g,#6h3W"@skWEb_Zgb*f&`&`&`&`&`&`&`&`&`&ouo4mm.GoO>)1bOyQ%sŅ:g}ܳmMa,XNH:)+c$6eR D*u\||`fclɘ[d&`&`&`&`&`&`&`&`&0(\|Ц{K֦J}\u4mOs)ѽ)񧎕yŔ1؊|okevNZ2zٯɨk!5M-Z}3ojs c+NӶ!Gob&`&`&`&`&`&`&`&`#"P>ڴl4o|0͡NZzwwH0(C]d<649e\ӁcڼмhPLl&`&`&`&`&`&`&`&`&`&`&WMj4jq@`.FMK7Ni(įZW9H.#8my`̡ZNaiOCy3LLLLLLLLLL?+et1Bm8#iܝoưoк>jin"0Y'/> Ƶq"Ӂ?u5uODbuʯXO. O$ÔLuJLzO T6.́nM[:7бOWc ;IƧéki_;11k& L8iMt0uL'Z5(>sX'Ƹbj tҭ_2B=ޘ1cF~k=P,񶷽oLLLL`%?p޳MLL`l>9+Ίx𑱹@7qI }ZR߬Kg Ή歍 F~G\i3a8+\<-k ( Nq(ʯ50/6 Tߥ UDy 6g}6o$L4)HxLLLLLLLL` qmNA{i՟p#]MSJNլkKw4r &en5OѺKG!֢䫝 KB0 _ɲ"ѯ36u~bLO짍T=L`8q\ k7w 3000000X߁0l$IOaSoKn3ͻz:^wIz;mjk0pJXmqcρɟ:99Wfmy6kp}/'OK˴9l&`&`&`&`&`&`&`&` @~KL d-Կ_kGGG~fNtT;̡c.uwLq)5F?uYXKV  XN1J,"OsYe<됟N W.ť:%dӆ3 ! K-T^  tyeY0 v000000009}|NݵEm]kFn:m4la@j^jJVs)>9T'Tm$mMbTgA$a9YNC \̧y:O')o1'U74(7$ L 0^zҼ0&`&`&`&`&`&`&`&jzufqt!<)1mL~k#q0ҏ!A!7hԕ Eꓦ3 J?IEM<\N6㊗㊀/ӡ#Ny8u|Gh@ \{w9 (>Nń>--1mȏ~m_s)9a:&}R)d9#U8e[c1ÙN2H>b'C'  KG2sh>17|sA\l&0v?w馛Ey%&`&`&`&`&`&`&`&`&`]xf%giCFFF^-Zmi1:?ZB-=UU5*b+miEIGf$*C2p`6($ubKɸNqbinfÇ1qK6rSO=uk]H_T5n4I ~.נ~RnPn #it7pí)6ЧfMߥkSʤ{ko|Cf1JƘ++c̕湊1W&EPQ*J`'|XTmĠ?݅@##Z8qڌiC;BV^yO@7Y%c6ʟQj\|>MLLLLLLLLFNͭ|^x 'py&sҷѯ"uom.FNyj:Aҏ>փֺD`eZ$c,$DR564?ס+'}ʡx7# 7tYm&M2m(lJ$N ysT⠺IujfRernO{g2R;?~Ц?D! Ԯ-eOզ`*/+^9 Ԧ?9r__G_뺯u7| pMߒX%7Xi$ 1`,UX-1-V/K<#quo۬nߧ +;y_H<m-(J!hӯM\UV7}RԦOF> qLk_bhHN$:QJs<*SWc㜘b|s;RuH|\39N q姮XubCSaʚtԉќ6,?Ϝ?R[suߝ\# f 㿿u?|ӿ)GV!:kQbҖTmSǗ|_ǴFA)7Nyu*sQ2&xz3Ml*k\es~Ο M= ;L ߜ'|ssRL3_T5_]9?jCpu/ߝ*q~W^o(]T{ccL+<(@PTmfbPjcusHc #&J|t̕o1RGp90]_ jŏ<3FE8:R5ו/KƕG%QWTmSg1~㴱rLmeEsM-w4GOɡxe~0Ʊ?\ȭ0~X?W9ЧTmG?ןڵ7ܿ/߿C~6?;~nߟO~oρ 9ww-iËLF]}u4b(?u_7h\}3yџ6՟4R 9K+(>`~E?ZKɸLq4F)O)K[uQ WKCÙ:SPLfӢ{ےƵv{}}CRpr $# Y.ptrhZAg __O6;vzԽ/?AF5'|;ȡSϿyIlWh@zpco_{eOsdw}UD[J0F?W WEυ Vi+vg?^u*gYu w+:gn=/2ljW[Gp2su_hS1疸ZzM?y:dODqOI3kAp֠87V&NebMvf\h٬KC67?2x=mZ@crxgJ?2 p;'f0l5Hz E~8ג)8?ߘywI |y-|h<_v}vm1}?t9&[?˿;3^Ny E gݱs 1X?UњNV\sCNXIt+l{ڏXЫox'_C"B8G O"}wɾƓ?g=Y4^~'madѵ8i ?OtD-?qNZco-ўK"6~4 :yȐv4 GKN7_}xE4;V"R&[cgEN>Yyrk|yO\vu5Yc{b}߿WX}}y;"O\3"gן}el㷇w?(*=uLhOq/ι E3/M}rD+.ًnN{/A3HB?Hoh4Hm3xl_}zx׸৯e[{>޸ s d;hssLϱKto+D8/z{}D;Gi,,|#;?ǤDlVSxY[\NKWZpF_w<՟ԟi@|?N@ХSNޅ~a4aN K7Ɛomߌi/}2^W7yp/hN\^(09~&Qxf"i6<隤>~“H/Zz GHrMW_?g[qa߸@pO7}-{1-lynG?_{Mrg_\}rΟvkZ]qTG3vP{=Gl>sh'?q>A~zѴo@?'a? }{)7l|88cIDAT?ǁy_ yN:Z텾ĵAICG}Ov4V :mnrCc3tɄk4xh6Vtdjd/x^Ѳu/?M:͉g?Jܫ]9+W<__?W[v7VXZc5ۙg9Yl>hgO[-w6:'{~td⥓Mo5NWy uc'sƍ9nNX?I?Yg/[?__Α-)_+:;3{հc׽տw Vc?vOUg럜{' Zx҇A4Ol^*/Av?=tCq@{dY5Hm/ dB?:ق`xEt T95'|m3;/[d5K1_NK,;%?d'zix.Ϻ[Οc{/T[`b_>uTb;O |Q;|uCA=qp\L. 9c-7HNl hkD/ N[eq KC;Oy7J'Z:|Yh_œ|CO [@K._ɦO&/[>k?S;vVSX?Dc߻U-Y&:3s'v_R.{C%\w=CyfWOVc;Yo{2w^ߟ/C]]NK阭&d&K{M:d =8hɓ//tc?ZO9>odal=t?]O?Z6g{/m-,:3Egxi?Z{Ja{=ȑ#b[[ٙ{_vs~1pYE޽WQCL/;7@&1_诃oso }|6.>Ɨ\2l[l}@mlg埞] En/qޒɴ yxZ4@-ZxЌ9{. q( X'h}Ygoik VqXģ5['s{c?ZV'}=r~3#^gNwj>oɗKWcʿ 򥍏whl*>klJl'%}?xxOl'?k~({t6惇y ѳOlSt4x8'D?ߑ[8l}ދ핳cT9s<ϝgv]qwV8BgٮZeTg>œC`d_?\b}r/VgkY{_۹JC8y@G;e쟾v7&?/%~BkoO/coD spx$gIo gW[P.ETF/ ɑilA?O?2xvۅ~̓| mv/?ƕ.~cC}_ysvXk?:rls}x}~oΛ_3+;)|l}? }9ξaӁ<ƭtNjp7:?l-p9=M$~Z9&[PأSKWvڸ0?e~Ot#hgN]ـȞlɀ26~?_?{Z}go-|?{m_u/p^~~X!WWkQ<_}8ˆhd2t}բ%" {|8> [?]m|cdoCE`වAp귙(@=MA~z Vrr<̮6jł>hZOvvɞzo\kO;"ȋu.usg/jjuTw_Z^[WP^y3^d+/~>z􉯟OztiLўt?+1& 9 vN=AΏdG`'\~-ƚl|=.M8^2*v?-G緖7FqB_1zlm-<{gSGYTw3?V\Ǔ7sTowxQ|V_Zyd_z@=}|}dwGhɠ%_> ?}i=8в &8"d3Ai)P'ۯ'h9hѳ=Cעw;<--fLxqY ,?g^ٍ^2K+x ;ǣoogs~s1ߟ?jZ>Zu_Oʭ?Vxpr;WZMn_w< 1ÿ}2γ ~:ghrKK]/ym89 u!tҫ hњoʿ, Ko3Vj~r4

    ~:⣃jw =߳f^Kc},XsΟ{=s8g,YFBX9g|r|LYycOg{?t|7瘿;:k#ʕVJp@Ow|/ym\'xetw~߿M6[t=f[F@7l}&7 }ȓ4gg>>@WHx6'qkOK~kǯPd} 7?A2dZ?<_;;/*ZZ9#w>CuGꏟR7c[^{OzJlģZ[mz3_CAqƋǟ~O}AɰhNpВ' {obZc]lОt?{"NyoƬYm'R?˿;v_՟9!wkݿw^|]-R[ޭXd_ߋA}%=(9]:ZW+Z/_?pևGC˞Em9o \çt?Xx?V˂{Ghh^'}:x̟ M*08V/`djh?Ӣhdt?G6GvN翾6Wx~{Q^Z,{$_s;E>NV ~1\^)u,,sbgVywJpc_OW |+w:\e[Kl$۷7xɱ ;Ǖ56z7.Mʗp5Q>(lenZvz-^>4N <Ɔmm~ Yx/E)n|t ~I'yt`,~>_[K[y'匝?w՟wkݿo;Ս}+n}.q}?Ay_[wh`Z-pڅd?ɰGGq3] dA&ࣧEӢi{qE#3Ȣij OPuË)g=l-,ʈygog{oz՟Oݽwk;wS?QjOor{C@-:[ ^ӆ>g; SL<;w^il| mM{ (zIxt[Ppv|/óK朗>> Oy zOt ?΅tɳZ:#_жA{ K?ցgwO9\a]8s;w>Pnzr ꏢRqY}kW9lamzr՟g~|e4x]*[4%׳.=x NlmC6gzWωa-@6i EK/{|υfC/Ux^mc$,r6ϠXF{ſ9gꏪVE:$$F]h߻c߫Wߕss{UI' Tܷhcɿ>8?~ߓ?%#6~mz˗s`H?њHA˗p& {G <B?>_!lzaɡ8~⇳u+?ܓg3r;ő?_gkķܹis;xYqvV_?VcOwkݿvR;I;sމ?"+FU}[N>fWEB_S {4^dO~sk0)0*$ch&d z:Gk|x\Ndomzxoƭ9^9xz ?͉OȁF.Gɂxf?hi_n(ƋDe{QiKo玧?wY]-Chc ku?;k(PsfQ\v>Gf}/޻WуO.E'G?{}Foc#_ڻwM_/v=7y@[~x8#msD[@ҿ@^2̏z# ?^Zvxdm \Pߝ>)/'c߻]'V;wKkdݿw߼W+3O}eMKhNΏ'(g<; t~n|ГM[iV{M4= VN/~Ailg?x槖~:k OdWGo ɲKi ܓMߓ+;u ֹ wB;cz߫Wvf񜕻ܵ;(Pǿ!'z}}̷ֻ';]׏#zOAz7>O~t?9CFޔ cHhxɡ ЭM.xa' ?ӿ'?~cA?Z}_âi|9ós?O Ă^/[?Gw=!@9VcgBpvv϶OO3u(&vCNh=_KRv˿W79˿d>dAtyH֬O}_?c+;=/?: v}? 9Æ "11hǂ+  ]>zYZd#Gz?Ib`_Xvyz<>9\[seS[\-1q???k\c,Qgust&wzj?]a Vo|4g]9~dh'gL'=*4?ƚ4s2,HM罟N6# >^DA&='=;omR?nG?Zz=m8Y;[{r\rƣS_'ͳvZ7v/;ܱwP|;;=Z h;w}r'wXo?{N?ꮯ/;SĪ4gq?88H^KC|V_ cj+`O6!ãK/7肒^pΖ)wu?^d 8;^-ɥ?yc_Ο|s;SDV=yr׽՟?sϹ"roo׹w,^~\-D;ig7]-ރAUMބ=M2^}cV-)S sڣl?Y2mK>;4 }h9Zd~kx_;b%fq\1z_+' sa=ߝX;vw|pNyݿ S/tsO:xlGS&}3L dx Z_jZAK<\?)O.ߍ"hLo 6 }}?ۿ??qo;?˿΋?O iV[]ԚZdz&vc?`S{ˍ?mD:9t2Ao8=w/|ߋ/2kd٨%|ˀ$h/t/=|f % +ߪd,-_諯t<ƫwʰA;/{slzVz֟5wr!}1u!6?{?wvb_{sg燳c뎃5k׾w}BFmB]myYd+n'tk?tׇܽG >&Y` 8c\{ٽ(^ʅ YC:~h7VWn?{|kncݴZh'm}}?k}},YD\a,kbSKvh^yϯk_k}} WZeO֟E|gv~m9?Y#I- NĬ9ge/m_0MdtxSyq^AKީW/yvҹЏX/{e :0p,|;96Zp?M8m?`^˿Zpftw+~Vꏟ]aV^{\buWOyoݣ{Jw۝3>}~C:wݩO.`C_9_&\@%3 \2hM?>ҧ }iAg]dZ`э" O[ EE?_E Gђo>`?˿9wkb}v8GW\ԗDygC;23*~=e-Ok7mb*8kXo2ѶCkvD{J<'{+g]Z3w$Sbk[US&uzh.ܑhOgrgn)VINh??E5SsG=%VVݞX%JƚB Dl~tu WdѾ~s_]?"4&oY \/_W/(kAe5~ 1G^lq]?\'d*;gvikcom-,Egud :G'_{X'W֍v ՟߫C_sجz֋Z%Wן{&T6/}xWO+f{ nrPC VC xwA\^L5|M64 AN5?ϝ_);vk_U׿?W<뎃 VM&Vu l@<Ġh >+Ӯ r??'{^;$O?Z~-Pp?9-(|3GxQ륶 g|ccmEyY'Zkq{(&ZXyb!&˿eq->[k,kd:/v^A8h=` 1Z;0#`Ǔ';j?;+W4c6gN9^{$5^ W_0́lB?l/J& ?OfS?:X/5;V~^#g,)oZ1;W _Ί՟wC }&t8hž|Oϝ|?ry ~k[OOT O>Ïq=ǀIA{3^e< >zrh{`|vE G&;@z_v7ϝ?˓Qߟgou;bWys]Wowo߬^{,Ov^mXb?rZw=|Ogu69|:h;[Rxy͉үultBŞ}w|Ag?zxAk?@/Ϳ Es[Yw]՟wkt8Ǿ{V@SC}{(:|?x5b]ȯﯧ~zǸ='~u_4Ii$tGA ˃^z:hK2𢡓?СNde=_|Տb?]O'Nj~sBa{\9c7vSbw3c?_Տ}Sþ?þ?ιuU9#Th˿_}/ZtZrxwlD>[`z 8/Ϝz{i}$c-dkA#[_>,J/_ܸ{5W `}Z Twݿ:-c?QG߭+wt}uu{oꁾ1a# [Y c^ %zY^hAtxɠ2xbhz.cv&pr}]HMn?in:{b~YysKd&vkߝ?V:C~XŪ5V{bbx;z{ok߇+frN9uU)%ҳ7-o%_7p֋EEx4-YpDɟ>[{x6d$Ϟ;ۚܩ=ωd;v9Śx??N~N5%]Y9s5Z+ZkZsxkJKVskV/,&;9֔v';jp^6m=y6͋jx Vt8={xh}*n6 =Y'.JZwΟ?Όs3dCu'[RU|?VXcYx =k5wXGX,f4/di׏N-zx| <^4ZޚEOVۃNj'2OM/fxj{A2xy-6@lx1 OVۃNjobY-^x| <^4_dx ^j“d/"[lbV$M'b&Zd= xh< 6'E_E扷 Ŭ/H//2OM/fxj{A2xy-6@lx1 OVۃNjobY-^x| <^4_dx ^j“doރ~_6Xfl4s8z}zS~$|E'~/[?˿;v@uWuYS\q\ X) wv{ݿw!.rE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`XE`X{#p:_}IENDB`icinga2-2.14.6/doc/images/addons/icingaweb2_businessprocess.png000066400000000000000000005426031501332562400244470ustar00rootroot00000000000000PNG  IHDRPZx iCCPICC ProfileHTSY{@:7A:JJ ĆȠ#:(X "E2(`>` 3gwϹ{=%&rD!~9 YlЃ fC׿_%@L8bv §@e"q4W"(B D'p霰/GY,QOHN@|*[ 8|y,[jq_|'diY s>ͭ%I eH=xaΏX</i\$ /1E}4^tڸ(i 4.0^1L@(R! +A!P4 %@H6AP1TUA/"t B`2k†{pNS,8Q߀><(J2GQ^`T *%BGJQըzT uՇE}FcT4 mvFlt*z=]>nDc Fcq00QL&S\tc1X2Fckؽl+ ;p83 .¥p{pGqpwqOx^o|)<.~?A#a5pBM$LFDb1XF'^&>!#H$GM*#']%>Ȧd/2|J~H~GP )JerI*c!Ðli+Z k !B6KTmQ9Kn\^qy|||k 8CBK TUEeS7QR/SF DccJ JJJJJQʆ d"=_iǝu^>pUUTUT}TTw6>UC-QPۧvYmT]QY~BaFMqM-M?MKZZZZ%ZFڮ| /iJ4Z2NבTtL6>#Jկd@0 vt|4424ld8lb023zbL1v3N56o5$5c ڙL+Loff|f]1 W5'{י[([YX4Y^ f [Y&[|l``cbԚm]a}߆bk捭-v;"vmvE#tE:^Hqtx񳓽S ?͝8/4Z]xpဋ ˥ʥϕk˭;ǽ}#kOKOiϏ^N^ZQ~ޝ> >>>|u}||cw24lF-c,!`]@{ 904\o^_ՠPpK/='O?ep4t~#Ըqu&L[s_-~=tVl9sEsO^Ⱥ0*lpqmeKQ/ix+:<:.\uzӵ3כnhiw-[;;o;nxkanw/w>]==z=<~ͣG`?{ZLYo&5<ſ}AyQ:=T;l=|vw˥/_ _M!GkקtXћɷTzom9CʇT?L%DWײo&Z~229)dXӭ p|<o@zҙ>yZLo?M?L/=-{"SD6V#,23stSx/RҚNNCC z'''&' >L>%[HS+kӲhiTXtXML:com.adobe.xmp 2030 1104 =6@IDATx|UE);{ RE,յkmWݵZֲ"(H}o^n.^侙9swΝ B)fIHHHHHHHHHHHH@I;hNf;la 6~mHHHHHHHHHHHHHH]:/8OY @ ա}+7͑ GsMi,gܙ ) pV8tg3a$@$@$@$@$@$@$@$@$@$@$@$@$@g3A~&vNSSѦNHHHHHHHHHHHHH™~*ڬ8UתhB;IHHHHHHHHHHHHH,!Ph»LpTWV+nw @e9+nPv켮UM#*Ӷn1 N*!^+flVN7;a4@$@$@$@$@$@$@$@$@$@$@$@$@$@g`9O7;A rlCOElTny6W#            8; )YmU(>KyꗧxEm1M$@$@$@$@$@$@$@$@$@$@$@$@$@g2:SR?]~wj fIHHHHHHHHHHHHBYhkK+ZΦ߲S H '             @y w۰[!٩t:mKGc+l{M]             @G/X:vmWBSD.OSr3l_̺L @ o_-޾lԱ㷬mW=iN9T\i             8GIeҩsi[VN嫎S2orTO-dЗm,#             SA"k_uʽy 2iW'`YU9ӎS@˼{ H2 uIHHHHHHHHHHHHH tNTNn'c.ooYu˕ qmVn'W&tfuʛL Y*mo:tdg^UtW\N@;{+#h5hoty0l+-             'PNfK}_2骝S1ǁ:+}']2dVױ2cki}$@$@$@$@$@$@$@$@$@$@$@$@$@$pqMN$ 77flˬq ֺt,bI׮*sKBUZ6c3$eRNlKIHHHHHHHHHHHHHt!ڛI&eMzHHHHHHHHHHHHHH XNm8ճ+%rيV|ȷ4LdCd\R@t-X0Ħ7];Ueⴏ1}7o><**GIII fIHHHHHHHHHHHHHN!!!)뒒~7n999Uā/{ fǹ9m-{9ɥZkw@|(kӛ*3罥i_sիWO>b              ӈ@jj;Æ rާn,|^V=K0$Oorճֳ͋s;DwM*YfΛҖr[iHHHHHHHHHHHHH,u2#i7X$/Arzz`:7=)o.Λc[,o;r IHHHHHHHHHHHHHN{novK;a6˭i#l%WϾILǽɬפ[NysNKlMت;$@$@$@$@$@$@$@$@$@$@$@$@$@$@5Ϸv[}-sJ["`Tg鴵S^IlN "L^RR@ HHHHHHHHHHHHHH<nov ao2-Xkrb-Ꜥ ǽӳʜL26vN C@v`LIfuyo<0tԪ-o2sYG $@$@$@$@$@$@$@$@$@$@$@$@$@$@g&ձḆ9ˬ2ź]Yd@EBE:TWXVuMҰvZI `ٳ'jժLE$@$@$@$@$@$@$@$@$@$@$@g}%jkev21MW.*AkysZ2b1o źu0tP4hРXHJ %% .e-fHHHHHHHHHHH~|f缔;촮i7ȃ{ *3ZKޤ=u}`Ѯ];:UH@cIIISHHHHHHHHHHH~O>`s^ֵd"Jx9nBv2JZFan(?%uxk[sᇗ  cK% jBaA@t]jބǴeXO55wEQd`#b۷ÇwRc @Ȭy˄ ufHHHHHHHHHHHH `KZ^Nu,rvu}]JԊ 2Yf;ef}=鰄Ϝ4iઓ~Ûpe(jާ-Q؆jPp"bZʦ$I@jF %-C&+B@ kVdn]ǡW3*;|uE5XD$,W:ƍ, L@u4Ė\Dלudqe9;IlNV*3iZ8~һ06ʡ&eNyfڋӾIvv-5}]S#?M2cowϙ2pG'"2NͪWBJ\6Kԃ?e&ʱLۃ2>99 P{?ĉq1Qd砨aaሮmޏň#Ѣe { z0htX           @_em~?vc 91"zߋ@ .#q앸]M9cyu^͛\|7JzZpS3.'U.uk'2or]/(q{ q_:vZfL\zAǗe}V QxC-bG۲<̴8Ŕ>ȏAÛt u'L{UK$D:"jৼW6UXTDGGNWٳ{/g z `ALN0s ,_Q(Q̜1ZliH,9W9e5رOnXXd~oeK$@$@$@$@$@$@$@$@$@$@$@#PPcSlUP7g0yjS>X/N{Q QFK~FNRo>`S^S;O%me2mN$\tv :y)N\筱YZf1Egw CX)A.:q/7T/6'ZLtDח^io,l^y5]t+긗]v-mÒ~ַد""P\: G[rtyhۮ=w}ݲI+UBra/fP4 ШnU6G^QW ɢ4lܐݻV)耥?di~z[ǽ8;wl8U4l۶hfM+9cuHHHHHHHHHHHN" .ng4~xp /0@^YACߍOՄxy_ ?̄\7xrlfuxg#<ԓa`K,}*{|F^+8̛"^X Vȵ̬0׺Z&رu*{c.wI\u,vt[lng:dmwawǁ/ieF,f"\ZRcǝ]a ?5k]3]i!K+Cׇ=⌌ c6;U?#^fggg#77%iPuK~E؞wyX2=0մɽي8p뙞kl^{]~g|N*]f\ }S~"N|WOZn\+vӣXG㺑Wc1w '7Yֱnʜ5+3׳c.(lǽqoroe:-yL;.M~L ))x϶SŐW6mIЫOoStšXN-{Ŭ3V)=y^88q>6c9)}.78ze_>pwWwԃy36o^_>{ 1JZF#p;"&ëaH D3dǹ+&nӅpp5!7iW6YAh\<9|5k8[iKpi;rT.ڴ,q̄a1hYv鱽s$Dޅ76m/-ۄOX:cܚ %-奒 *qori8j {nV%J=Ƿr]RcǝfEGt}1y}+#2ɋÞb-/[ͽ䪩b匯D&M0r(٧VD*?vrgf绹xiAo5Cq+S W)7xjL!}c\)܏zkf{<1mQ'4g-K{^q^ή_zK}9lC0?^!``j6C[5YV=N,{?L9O`cqK/ƸxĽA7=vG<6vdڵmu*y^6>rI^f X4(a޶JBExrL#Zཅ>Vbef~7]2ℏPZha,YKd&N%vaߎ ~ (/%w>vDv0o<|駞IL|9s+Zue6<#e֭Tv3O$@$@$@$@$@$@$@$@$@$@$4و_&!mZ%;z,:4a84SʟƒRVxcRmX.A&T0C}MN{- Y?J?= hZB!7eTq/_k3sHuڭfnr괹L2ˋ,Ml {tCJ_5acӪ@tDW( 'ԃB\&6]y]_ap|w [9T=yCJ&ibS z)w۷Q'){qFtiӿ -ŧ&D.]P~}qW^= nxmY.{WE۷l޽ux⢗0ᨥ٩Zf cW铸Visμo: ȳ@عy'IH^[\ ֭{*q߈;z^߮x-DŽοᒞG9@œرn.zӽ2VjI"ç/L3d\+/y{'eϢ(9mlGR=)k1 ~pG0s**ڒ |J,n6ނ/Gmƍy:%э1UTOWl.v/aZE#^0([4ggԕ=2)hcWKVIq|4s6|x;v@ʗE1mۀo .mo'BJ^:cq 7㷍/RKHlV[ap@aqq?IJe 8%-2)lVsBHIMM5+%]Nc y@$@$@$@$@$@$@$@$@$@$@$p(BAX4r#~xw0䅑QqQ+|þph_!}B| cƽKH{}1pظuvlG.yGܶM`}5k\ԺB+c<k[Ӣ#AִQh0ā'k;f]sZZ| xE_*(?7oAC x:FԇZp]_ oD@\+{wMqg@jxpQX?e&"27i*3핹<   {|,,Ƭk/a0㏰kN:xK,ŚիqA߱{ GI랆1yXNj.%9s#\dD[QJ,3L|=CzX9.'V`V+K*<mxw3_o.b0!0ĵ2S7t¡upk{w C,;ƴf ๹e.V>/uz ۲nB6/\*{aR X_d&ƻ/`x|>M֩:? VS{ VQc74tkk%RpA!Z^v=:$`x׸0}s!?='fIH-hDzZ]=q{pZ5}k\F|1 v1ȅ@-c]iEѣ1ZmL܏Zg414WFZ^-P_R.+^m]e&:⒑]d4Q΋# vmԈkLC[:drP?:Բ.M*7:#}WԮڨz 6+O(}0hY$5kԵ/wpDuDu~;D~!2#B*dPufNڵk}v$&P8^ #sQI97A 4Y@=&aHHHHHHHHHHHZ^5qEz.M ja.7qX+W`Mߟ[㶑}ѡP|z|qkC sWHD$Z0ĴꋿBqFm O½u٭xuֿ:Q~:F6/X̱7v:"A.ly:O]yeX۶ʭyw\Ծ=oW,G ٽ˨+/6˜ibI|䷻) NWz}Q^~8zŶ3oGeX'ﴗe}yjf8 5zEXfP3%m%:pQf֎p4Py( %-GzR2 OpesqEAxʨrR5hԹjAl<4'wnV]mm?ѧ6.x]8 ]jiG=t<rQQ/f{B:ύbլp,eےж_]F__van+VUK2oF=X1i\5I>8}ɣBoCM˿l}#2mbZ>cW{J*QB`Q[f٫-CFH<D4wC0ϝ XWS{q-Bxsš0ɉмKwԮNq>PK/@fݷWץٳgES Y 6j ]<菍ÇѸq`           * q^Y5n'pv|+G;ҕjֈq}fxqNwp{pEZcQF sjl8/l1d#!4{{ǒ_ qX7sE z\ucG$Z[7']tN$N*P2їr`ӢmṈ wR_'G· ,ǰr6"o$צ"gǎ;![^?U>66IN{1-KaS.Jܟ NPY!fM㶛o]on߱= luy(@y9!3nيj+/#z|_v"sjw\p[kǣM˖h)S5S5uTFD6bm7wZC]0[G/W%#|-@Z9PG<OV%D|;;dh. ێ ;y9Z!nnZF#n?nDdfhӮ\X\WGZ=/fq*> y;6S &>!OFCgJ/U w]l>p);~.~K]O+DDRG~\GΕ?`RoM0B8Vf8fws?uT;Q/~罔䜔sSQs4V:8zY\)iu/?TJC4J$@$@$@$@$@$@$@$@$@$@$pJԨirZu hVBUQ^ZمVvBy'q-pT]\ReF}ɍz?+Kuz3IqƵ~7FVOH zmL>x^3o%?AϚm`'c(L&?רOwl9-5CHf:44 ӰhdԲTp |Gv). W7?^aQ=aQ`S?:QX,OQ3`ehٲ%;:1:ǜ,ow(TbCXrI{P88py T X.e:ENf:Xt*-J? P̮͗\_2GQ3#^j+a?⾻ grGXV;B9B+)3M5ŗyYJޏR*@hh4z]q'ڥ!aꁄ;(˹*lݺu=*De¡.}jq @Ыk(i :]PRrLձ*5֝vjIǮ,iXdf{;šy)ۑjkip,sXf :w yWv!11͜ǏCac85S~{Ĩ#FD-EL I@7o>izyՅ9ԬYOkb˖-0`[a            Z*NQ[ڊ&vR:m[Ӓ2e:oeAl{ NeA_5͝%oi}]u^uZf2m qs-ZP謹2E$@A@ 6@7/KPKBҗ%we׺,o۶-J[$@$@$@$@$@$@$@$@$@$@$@E&q]&6tޚyAJ0;ֵ]WIYnNj3UKXjN뮋̺2u6бcGHNW۷Grr2tR|jmLa2FՃdfHHHHHHHHHHHH/VT26ځouȋ9E.6LultU8+a Zb vY.O[999͛7-H$ ,/ptttNJ*+ y`8Ef\vȻrѧ*c62t^f]sZc)gB@fnaaa^4(&8 9+箜 $@$@$@$@$@$@$@$@$@$@$@$; `[2|-32'LrYY{y;u_tfճk5>Wgȑ#ƻ$$ sXe           8 7,÷k$Z:r}c_s|;诞y RGo"i/bô,=tPTV$eHL! 箜Ë-2?S~ @9ŌYz|)Rϟ:p-]Ẕ">%a2s,iߩHHHHHHHHHHHHHH %w!婭HmŦMvy-7ǒ֛i+Qf5-ys^8ԗ:fٞA:o3M$@$@$@$@$@$@$@$@$@$@$@$@$@$pk9/is̪oc+mKLyye6H_ry%-{T#             8M :mZaK.*Q!Ye82ioc5y-EHHHHHHHHHHHHHH'`(ܜU˭`N̚z]r* PdfΛec|;v IIIAI"͐ E $$ժUC۶mQfͳkp?>`vTjEn*+qȠ6X輝Ȝ6sLW2tlݺ7. rAa             Lۊ+бcGԮ];0gOXdVs^SZ-uWRtL''˵#yo2]cmqرcᴯU贯lHHHHHHHHHHHH$ 6ɄYYG,:m-zqhG}z:m.uq(((RUM >2j&voe:urK+c32-@;h7fE7봎23TY36!           8 M|p e‚Cul!]i-swuRYe;OjA`N[cku]7oZΘHHHHHHHHHHHHHH&`Fj]*)ޤ!ii             RF{իWv;Ԁgzvڕڿ j.3ǺL+t-`;8kHv:2sNWdZGZOM">C[n;T<|^n]V΢2Kb֭8x^FТE 6dSN_'N9sj*$%%u7o>} /DLL_vD$@$@$@$@$@$@$@$@$@$@$@$@طo6n6m&M[n()o8Ŷ,/u{7o6ݹs`n 9H_'֕ٞ2na~ԶXwPW5[:/t}k.3Rf;E׬/jj}ǯVqvڋc;66O"Iqj //pk֬'|;w"++K7kb ԨQ/ƺu GGGb޽hӦ… /cÆ ѱcGc̓l5kք8 (5k8pÞhF>M)Qi(NKƒ ۖdĢYݸBTvDqxDmayu:l?F2@,u)V'U[ Hڄ cK5cΩQ[ےU NgHړ(݊²/&#)* zk"ڠW3~"g>~Mt=:U?`tks!Uo1E\\^ʆU0}cf~P~ݵڢE|u]|bu鈚޾S9Տc8ب*iS)>gķ!I'#lTMb+yFƖ5c ]+_'0mwHojTyvV)r5zCE\:<}*&Ǻ_`y~}thXb@J"kTGSr~=fs$F|Zͯl8ꈮV\\[w%"%; սQY @Dlޘ]##'ĕulȗ9NUwl8XEHIE~tJ9̰^{dOH, =έ,|􆟺ek\{O&uۻ'JP/Y[ͣ7ٍ=@IDATcPMއ?Suؾ{̜5őUqmv.t?Xs*94ue::wh{|u/۸|ކXW:'[8 0RsCU؟ﻴ=f$@ P̍عq3vڋCDzQ:v;<2PjC$@$p6m =z~JU9~„ رc0]s9~;r_zޔdrq08z-ohٲ%ׯ_!/Te &z z+uc]&? J K e9-y͛.2Ky%ؕ oذ!njWLUN9y/q0gދ믿6:أG 476%K g֩HN-N{ϸf/l/~;?׾x1:u.ޜFGkk)Fɛv F^qDs\wPܷ^9N-J^7?^k : {w".m*Z<3}i# Gha(jiTqj8?O@ƹ74HJ .s],S™3s]%Ja4WՍy9'^ __-7>9U{/߅Zt?k_x\sq/T-Ωb9/@Xu|EKQlupmsi8o&Aޛ!eĐ8Piن?\#]Nmͼ܌'7mGl CqCG|3HŤ^bu` WM'5yxٴᴗB5pڿvBo1)ي[m8/ ➘%J[ G^&=-,1^N i_1Ar$FEG7owMQ831cHQ38eۯf=WG֡85vǟ~ZDHݞ~떭ys䒈pxo0Zc|O?z'Ӱԣd&cگ6+03s\UUq߽QdU5Yb˪?(POVvH|vAرyJ넚^>7?\ލ#hxqiJka7c?}\Si;~>UxNyjCD\{S߶`cjjcS3Kw#<2D$aMO[([gnP?RN{ [7=V6c&i?>uq:@yW"em~ iqaD_vP~p3?y b B0yC'e`;E5xGR>z^BD]tr#İ~ zNrWՓ?=)?O[2;ihkmy2O*,98C9;)2ӦS>}<'ӧS{OLܥO)UСC*,/"MA yiƗ̮=_fݠ}oHǬ%uy/{i;yT^ߗzMed̞=۸L{_At|AHy.YE6⾸rl+$w^[~g<>_;aNxo@KcvX$]} Pó_EbMpgXK -#]m47S6=ŮYEj!^ +1!XCsňǻ/} ^#T?63G68~r%qZ o~gc(S?+'kX+:/OBh3+e\Li)uID}{eG+~Y]]ntـ_4| nU|*az&1Q tދ[[+fEHZ>~]jKq >Hhe=|+.ϓ_ WeN=ݛJW6W_s=KWS,[0ǵ_KL7߫/s\ 7 }^/ʓG FwQYq!(c.FZVtpab[ ?!ߨ@~TP13Q5x8~ӛMX(?F|7W>Clj+e|+²2 dU 1/I˜R=$꺙Cg8Y'2G<-m.+ky6Y?c{k?5Rׁ#wQ`OǴ{,dDFEC_h5x0j/؅{le5ݲٸNnzJ=4Q'e9{诺[s8#9ݏ%/RO12w>w|7*׽N%?]uTi_9gvXPa/FF=.ĵcxǔwQ: ˸/Osϱ13'nSyOpOƜL5|⳨Fpkp^sY]#ROqy<| yro.uylVMzVʋPЍm@լc)smS}o_~ ^&) -7x_:mDQzl<>Ɵ-TUCje,63 Ӗ@|NͶ_B=vn[sVa}}Cuw͗#~!H6>5:_.k5w_^PVL3⑛;`_xo=FU|)&HHHt# KתU$g:ufS] %2+WLd4i5k&ME@,TfYsK^Yv.]iV~%ioҦupղU!]˯fV2Ik[;Ovk-P<]ӾªUлwoL{ݎ\d3y/W6ˤI=:G)gg2 ɂժ&J+aYSYň"tzx 6>2JT`8<%9خ<קSŸ]?5.QciR Ғ1RǔN6聻#:(2~Kۍ/W&tqDtȵxW?ʏG~W ka>,PO{F;>[G7Տ-kgW?GV}w.VGd$:Ĥb0}gIEK9;#/fEbo0mrʩpxR^b+>y)~YODF^|4z5źo?Ƽ}yX]ש=r/: 7=m3?}6V?G ,o~퇍Đ͐}!^tsǮAX~) x Qز{fMY~⚙++#+?USA͸,uL5cnqح}"3-gacގ9bÁg >SѠ T,HAѣ1SC]7R6T45ƭ`ݿ7DboNFǥ# ,e+5=Ao{(.m>C܂7ޝmi4r$E¯$E9f&*}zdj6lV3+ʌ^ |0KXuF_Ԏ/}G_ yxs5{BbcJ4T̺1=eхWbMj,Rr,ڳ9<"g9g, a]cԏ83܌k7\phRO7ft,7 eP?zX-]Aξ5x(NGCuGsPG5f9 9Wb'$=ӎvwQn{i"mxol\:Rp/uqz_a+x?>Ɲ׮L_5?(e:&ќ謎mkf5=Ki6Տg!I=hk0( 7VNbܽ5K_*eaO6NQahקs{B, яkx]6_y/~P-:C[c\ף5?ťb]9MYλӾqAjܝqw0qo}}ujr/5D}cG9Jwf  _~&ZQ:Nr QhݮBRpL1_? ˶%#3_04&_8_h>a,HCރСm+ڠX:j5yF-ljqG xlz(8o?{(KuhP7sK]c$?wn8t~lacuGLC_~Uطo1+)kJ*w;iǷ_f_n۶mA׬*kժ娸Gј Jjͽ|pWOoj[W֣OMLڄ[uM`_L\Vz_3=⓯FawoOǷ;f`SWH*xj;xRzcu[g}xM2HV 4V^73)%]߽?"F 3x wul ]Ӷ2WG;ZXQVsSlx$mI?m-M3ԶpcM Lլ33׸;a,X|KK4lQmulG>r1+wBBtZ#vٌqp3YX0bQ\pg{&1!FH>-ފī=:#Gb9*‡bNH7ˌј&b׹L{k:Ogfy K GiҨW?tMAco"W M{2weL7D\L)3^BhCP?Oiw2^g&&೤X^Ԡ6@g/Bj]w?n ѦQ5]`߅i^ Zh[@Jg2(x!ࣺc_3b̀N+3{׾ VcF1xO3Mv% 6C J pJ`0̐mҖޛ6G%GѮDԊsW]m]J^6+3U)}I<"f,D%6,S|L瀬߽Rl4q}ݛ v)n] Jm+m!4&@g_ȵq"c~ACL7K;yfl[bV;ԗяޘteؾsn%j[@ĔG_sbe% K7ɭ _8%AiWg0s+e { )qum{S5OTs789#'L[ ]qfpfr8)^'8H]dMB{e+eyLeX+OStgw;O0v's~;ו_[GX y<+rI@+cdiSeE~6eǕ[DxkכKlN퍄;G{lA~JQ/Oo,^=zo4gsOMP K~\GWX{^{wKQp~yt;Kv$> t_G|!ѕ3#'ys %l(1](sly6)oB.+-T^ȜZpc"S[/eU02ߢȬYX Knz̠Y<2CIrUeJ})X;s%@WY4Cz8bF߻Б[eד- @!#SRTP,2;$hsG}ovڅ~={=}yeOE]Le1xQ^rJ;&*5GuzE~JA5~DmSBYRDt27 j|=oW/{gDؿp!GSUԃ/t֝4ϧ#F{٦(/fwv֦35WJŪno=W2XQpC=ha[+JyLg<O /Vb}CiTT=$i8ahULٻK,͋,+F`W!_`L^Dw9AS?~~O8{Sc$#Ur9k-m*ufy'? MnOY0姓ѡd'ЭQ|\LˈkjG 5j r~T&'<|]dɡ7ɳ9V,ٍb XY)Æg7HZNh\zof+3"_4G] Y ;@O2%ȍup <<' &@ɠ;5QV;*?7[2h旲[{ YP+4k.}+=}y"sۀ$^,!D:QƴK6tfٔD{~ 6ciYY@W5݅B,omF>Wn'ÝpfΟ;w:j2B 9A*UEjֽ(ozeV[n ; ㇆(?aMd~R QVC:+v ngz7j{.΃Dm7,oD_G}7?ix: -f2YgvkEqٗ[= nKx甗:SZg[vet];50=GCX:}f鈱Bٱo[uh:{YCNM6YǞ_ycE,o0{&l|HfGkR[tA dET// x._E*f2=9SbK7)#2ZwMT=N!;#2Q-OYL3?3;+%`9;@$V%a{gS;tBWǶ)oEj>Z=M^XA߹H^(i8YGre߀J8#阐e ~W,굫0j̛w8Hײ8hP3 kʮEFZW]b7?*rl;Fˮ'MeygiP4Xh.]~\R=ׁ*mLMoQZNn *׭Rk5TZ+ɬ8诡{sٯcOg:x3"@8ؠRjIZuwF bʨ{ţdjɓ-ݱi|Er1u+d Lb?^bڽ\/>Y\άY[v0_>B:&:p{6/ݟOh,f=!3uGOZoN5ѭ0tPL= ɠaY!k23gD!s.&([1eĢ8)d7t݅(M|S)6+M2O]C7Q/nz/ƽ;ƤOy՗cGwcq*hVA'Y "/ ;5(H Ԟ,* zJfi:/ð“۴’ut]!+aw+VFRRI/;+s3SyOhU'EyՀ"WgheY9SD:k)3˗rudpwSxS"Q )79QԹXy-V`-ZrZ4) UfZDI~,_轋C~3<|ds-?IGw@Ysq>,ըS#>/4LZb϶ȠYrSK`#\s_r )xoe&j:^d$@L {䣨o옋6G[nG,XU ;Ԏ]-Hr{S+UQTunOIKjooĸ| {boאީN]*`W2j֞ԉҡ/B#1 \-[4QFAu:3TfJ\B^g'%%oͨWUryqBBr.˅ڷ[ ?ﻈg?;\-V8־8nD߽{8ߕN WS9uM65y湚z\]vfgYN5ot,^Qf)=n{[ =x_{`15 ]l#2(K9I㤊K,ELiɀQca1舵kӈsGW1ik%zt {-&N{Ue=UMścg1oPLGE'YD6ʜUq[ʘbNٺKjy;Ncbkn! b"^ׯñd(ڣ#'B̅y?q{f}{<؋&—~Jh^;el4()sVk\7sd{q$7;d b<ʈ#vrJعÿ;,hXQTv%N23r} VIIqRa灳hj w-@37Ht㭳O{Qn\X~r 1=dOMD:+"bd((=iܵŰo5 9ݖj{նcH څQDF[HuMѲW{|#ڽR8*6EY+j;}p7WBkO-#`_* ײtvX>O,Js(F=2'v2aʕ3ܲUfL䭥p u]j.jNYGU;Ijy/3@fYt8\)\ۂ#kyޅe!ndPҰlN묪s9ڶ<=w g Flp7aZV,tHwlQw3O( [xFĆ4KU%cuVoڟ'msaUwϙ|~ks ;kn01c_FAG1?0m!7BU`yvgtx˫s+|J[^|cn֪ΈtW˒ڦfGfCǤkl{]c dn3?abkYS;];*ɋV ,;`ڏi}FE,{U5+"y>syi$v_gMdófĺRkWOޏ2c|&=e($\uGzխnh+X򈯌HYhՑ~eW-kj7?{$H=yVzX򓼭vygO"`ņQ%܇YZǗ`zaòT TrH~ʆ2;+Rh+RDj;>l4SZpQ-d衞ݡWȍYd`$߹O2cDnCruʇNqydcMcTwl(Jd)yN'r@o~^IDC~ZKwKQ~r8T Rْ}׵~?ѱ:Y{YuAˑ "sV)W85D!s9L~g<~O8#"X2 &a崼ulL:TĮe X湲qSsZ.NoTWxT6/[)2b)|ΔYhqh_$m!hRw>q7,Ue"&ӰUnn]'U4/ :IHH@w}Ƅk&s"^'. u/[,t}9ɤvxu)aÆe>']\DDD^ǷUǙiجy~VB 4„U¢ksΘ;w..]zM6A$''0ٻwarro߾ȿo+Qځ^}WT>tJbCqA. s?F>^!-Y@-_O1ۤˌQ7BQY֖XC<=Iw2[|csZ%0t$ZU7-?} 3 cӱppv)\2Z-{futѰa3xITOwTC%>CbXh<="w/ě?,SnnUMaaf<֬n}+Uv-GCK֤ #9Z Tka) L `=&#Cr~uc4zk:KGg'cI"6chjUo fEgA 8w 6e YJʊ z5->=~+ˬ1y*r@.bc'JZ/&rbBO< uG5b"^+K;N4kF7uhC,gF c}9W*=_/'Ӱ;ni;b)QIF~ubjV'ҡ^ ~~ZVC#!tm>> ]Q{ۙ[e6PwAFm-3)g#bв^K\!Lt(1I߽ſI~Q`j"I?ݷk;Q6~uŸeÎٟcT4;]kW"F闥ݛEn_o{0_g?-kҖbw Qn(!L^a続*{KDL۾k_VW=~tQV£ lۧ|OŐ?`.Nۊ[[pbm)b^Vd|;4~nizM^TkW1>ΰq\ĵSAz`!M5$Ы ڍ:XB](P7]zð.XuIb#zkƗB iSl~{,Lɢp_d-}LE;< jC5}ό_Yy Eү0YNe'zC˰dwwgO9"GFמgS*@IDAT㗓,)O5.'yfMl.PHpF̱Ηaz5..Lpco@pVE u&:x뎜C2xVv)˓KUQfJ- k"Bď3 Z֤%.J.4}w\~Yb 4Y]8ψ/J`Hʀ".*玝@& Y&!5_Y'@) :0|Wm~/lj {WaŎJ*%ﯓ7oQ;b*X=_vkӮxgX 3p?ɫ,"eN͇cu4WM"BkβdJUX6CDlj)arX;vKj󷰕,ͨB(=f-ۄ5Bck@_@h}ء$@$@$PH ,~3g4 zUj_gګ֬Yt^j9-Ν;@fӡCsNd+<ʔu{U硳Gf߷'t( v.v\h}~(3& &YJ|]bɒ%o&3G•(QCᅬ{OJFV}0{B3KVd͛_?zBU{?Y~ Y_Bw-޸+AO/`⻿??z^%0h,?:= jNy 2V3/271 zF6E/fUdW܎c1Vf<_Q ٤i@Ee, ooKSa-~7+=fnŠFa/iGuubUgoF޵K7l8ix.OIY1 [N\klz&ʒjh[_1G826'3P{6Zžeci%c9NHޯ;>b6IDl("kv.{0vl|n/U3nog*|T8C9|?F QTݲp+b◣͵UZ{3ڎ 3?K&R9kzT~gA[x!Ķc7r2RҼ>v?4$7 ܆>գY>y͵Z˗QT6*8z'5yZN/c/v*ܡEu }z7/0Z+Q\n7tmܛ+P ۂL*"gK4[|B+kÛnA4i_VE}%P. [qK{*5r`!uUK;O|g%MI&.߆gbʿEG2IKVYnu 8',„n $ ?E9K\P05_zvށWK0Q(% {V93a88 ,9kgzʬυ4I0>MO8+Iz gS9 Ar>?x]Zv@jCr;=vڋ<6gAO5Z X ˦l@wf B~wO1q4 }Wulz | rHzN2v8ߙv9SUбEilX[# O8y8*kN|K5ꄶeV3oX]{]l+na#߱c? -R3Ɠ|7f@|>;,yx3qdmy6^ү?Q ZuiYSd(SN^wX#qN:  (t5\c~94hQګi{uw;Vן&Θ1C/1kS^:ɯ&s *yG:w^}Nϣ|.; cu0ss~om-sz:4ֱu6,+;v hڠ ۷gϞ Ϛ1,z|2>93dt?Ԍ̐Y 93{l9<ڶmڵk-[:ϭ8~SܳWҎsVZŢrٸ ]e֓/Wb edJ($I3];ĄZ ~됟MDžx[7d bf.%ͤzȑQ ~ ,..MWñfjO'-R݌TɨrVwa9e;ټ8S*Z>l=Mέy=m8?G<~*ť {:uA[H2(jȑfY1 S*HsJ??:5m){"CG_~ta?i> T+)g|&x w}ψ<;ަe`O><ʚ'?*QpzZm.mW>_; H"E ۻ G5|\f _ʗR.uϼ](?_y8ԝ>I!N;| ȜἫzZAJ2`xo+?iqPd2i%(_&X_p#W2e.ugӭ֙C_c}=W9>#  "C 1&sβeܺ.3VZeֽWeμ: _˞_{P>`/^lV͚5CKaϴwdd\YT ]reӒl8|ޤ~:kl4kᢴ׋e9 /F{1d]26moMS%[-_^vshտisSv'V~TEĉ2PfX60`q8ks:5/T]4NL󯌜mXg\Ui}e~4CJPj3 6'W$c/bqb*?+]i5o~ĕ 2(".h]Д?Vwa9xB޻Dɚ(ʵs. "sxxwsD C(LyLPJeC]y:qv嘾]#uOkJGDn^b*?V,],S2+l~IYs|$׺ުAs_:].%EO4_/,~!0'弮ׁჷPg5Nrb벞9_ܩ-] Qr_dDQȠ.2ggK8#~Jt@,Sޥ{#ζ4O]?Rg̐$@$@$PN}bbbY{/Zl*>b?P0xW|S޽{ʕ+ xMnU'iMԾ5iHoZ"IF˖3㾀d - \:լfyz5/91e\h]zQ;}%VCfE]dʧ3d['bp ٴCX2g:~YK~Bt'Ԍ8 \HgŬi F'$+ZEB\sw y)4lзӅlKI;X^2Sn\R~[O$@$@$@$P@3)K@`} ̸]G~:Pg[UoͼwW?Koۏﴯ~k=G0ws۷i:־ <Ji]Tv?X^ ⾠3=            K@^)/fNa(-%ȷR[[=o߷)6k_szκsTNpd8              M ;-RfŽPpفgk/Psb8q匇e'            lPݛ ; naWya6FIHHHHHHHHHHHH'p+V/e^‹Mqݑzĥjժ$KY&            C_~A "žFvt+_9Y*?g*WʕCBB,Ygl+1             .ƄT8+ʬW61fHHHHHHHHHHHHHH.wTZ˶CY7Z0fy߰/TZ9# 3wj_m&uI˃Y              ˚MSgmη+5hTdTzeԎ/[~R>Ci9)lvべCƓ7nO JGZ7 d]Cy7֭QP4i~i3Ӿ];W)t޻6'[D{M^gHHHHHHHH#JO5FgiڠrlW|q&|Nb޺\WּSx9ec6N]u~qp)3+D###\;:;+i?|:NE]5kC<5:[_tXl  <\U>({a~f@Q٧Q9-'ODѢEmҋELLBHe˧lkwLy"_`Ԕ#bHHHHHHHHPPϢW׵AQQ͸ ʲoU2Ě8g%m>LX͢Ea]^z C]w݅{ [l Yeѧzatƫ^ݦc8y ~nVIHH ]G0uAoWO0ƫߛwV 8pwy ~ H@EV%]FQ_܁s8'GpKZm:        C@kkS1e 1]&-TT@Ïwvn7? 8ԯ NiiiGXfMA$3mj]R~{UϔQ4-ʗ7v'ܙ%Z}8|fz]Y2$@$@$@Jt90i9~Q`b2^?$Շ dJJ :v//"Ν ]Ӿ0w5BsTf+UimPfnW@K"m'N_6Ћ$@$@$@$@$@$@$@$@ 6o6~jTc7+|SqND)?mPxb~QV-r-0b={g wJمv^;]cI˜ bw=mJb}Q̸:v:'  K*?_ǯ`:,T+@V̉'DaqO˱3R[J"/,`bp4-|DM_[C]곈;C{{r V]fÕ5c 3Cdɒڵ+?0S8k\槼7)J2mUf 'pEtƚ#'5j<&  t$kڳ) 5zdƈb׿y]vbp4W;Nxohkf[J?,qۇVbYhP6-%ÊC',amYyHHHHHHHHh$1μ-J' J7kޗ.z2VHSޡbJcXFD|Ō 3V!$vpe{ڨ߿?bbbf#Ky?]֔י^eB(5.قShG:HHH%K״o'mk޿ѥa^*UKd`!o @V+ę~Osv=DOMk9gQ9ZmOo?Λ0Y~{/dvƛNyaJmµ*_UbuښUP$b޴(5+0א \NvH啜*sB$22+쮰 nGG$@$@$@$@$@$@$@$pq.ع01R5|VF~b&5~BYp @N=%ݭ+?ޟHHHHHHHHHHHHHHrDFA4|3!9 W(        'ͧ Iq_H*              < \3{|S~sJ$@$@$@$@$@$@$@$@$@$@$@$@$@yDW)ը@DDDc4$@$@$@$@$@$@$@$@$@$@$@$@$@$@$;J5^M$@$@$@$@$@$@$@$@$@$@$@$@$@$.yŽ*ꩬFHHHHHHHHHHHHHH%4O%~5D$@$@$@$@$@$@$@$@$@$@$@$@$@${>PQx{HHHHHHHHHHHHHHrNW+*s@x% @/fN$@$@$@$@$@$@$@$@$@$@$@$@$@$@ \{{> @a P0d @}APf$@$@$@$@$@$@$@$@$@$@$@$@$@$@%p( IHHHHHHHHHHHHHH Pq_ pYqA%KDƍѫW/ԭ[Xjf̘7̙3! CТE _l&MEzҥ zBy]vjժAd<}HKKM;@ETfHHHSpaTV Χ lMa/$@$@$@$@$@$@$@$py>DLMbΜ9شiQljЕ+WaÆqIlذ(@CD-Z۷XbtbccxW??~{ͫh4`~,se˖QFU"SM-wekŋw̢^Ŵ{[rӸ' !ɓ'ٳ>e*_+Wl"Ef5+22۴iS(k@kq*`ټi KU>qDx꫍L,tmp<`ރZ+]X0$@$@$@$@$@$@$@$p>DK.5J{\v[(=Uᩊ 2 LǫzzL2r=ztФOؼy3>,ߠn{-5C*qnHHH 8UҎ9(CwA%}֢j֬5kք%d;<@/㥗^2x^'t1cƘ:+LHǒ$&ُsc$       wT܇@\vm3[;w:#JgiGۅt:^;t:r>#̟:uOqxj>'95]I#@ԁ GLL5PqZ8t1_R%(uf8k\n;fr9e9˓O> p\ùaHHHHHHHH.Y@?R^zY]g#}kժ72vi]fF?s*i^[TYN;&MOV:k9ھ}{MT} j]V_7˗/7J{͌~oYTn&02O;>O5?:A˜_yXD5\cRW)))~q(n5F{֍`quƙU>]T_;-*b3y 'q9   PK@;vΝ;:j)HjII%8S9PWD׳w\lÚioOUR}=~ViE%Xys\ԩܫl֬p3Adh6mf…|zQbbarešseq(g7 ۟ʣZnTAݴiQګ>ЁV^4n)nkO$@$@$@$@$@$@$@$pa p}ӧOG׮]L&cuj'*[l{t"Ch7"|;ڹnpdhtJ\SNŔ)SO={ywriQ &UQn9dPU۝*Y eͫNWźiõ}_;Wgwj"_u槚 t: ՎRT}vajYXSu:kN۝<8tWƚZP+ r~$@$@$@C@U6UZu_~o{1DUfҥtZRU/*+4jȜ}y֬Ycd0+腐iT蔏Z.eK :<ԩޒXgk9U*Nt '2Nz.--_ ={A۶m f[ '!       PqT٪fuƏvl墊\5ueԙ>{5{!˷ѫV{ǬiWZkj`wZ6]/tɦX;jGi̪P\0Ӧ:c_9iz٨Qz󺆽AkOTk||3ʃn:ՁFg_*5ځ,žu^;j-W6@CgdV˫yAg7p;kuF5_# СHHH *Uz@?f #lek׵՜̙3xb3T>J8 !ӨܢT@@2ys쫲SNmt>}8փ&Md4uPWt$@$@$@$@$@$@$@$@>*Xͭ{ٝ*a*wnf NSN;#N;.J5d@7oW:;^g隨/v{F;ppz5:8@g7~1oCUKXЇW0׶m[ :4Ws_״״XM*K-}Ѓvk'A> ۛ5֚G%hXu)))8xz4uýku:   C PR,TǺ^,YC ZK5(zU~ե,B4 @|#sҥFgRR4 #&k#MTx&}!4l8U U*5ku>o0*@#       PqRځTO0t| NH]u5x@g#r=Nкٖ}fvرc-2޺Զ‡յ5TgЫ2^:kfR57tƽvtMfƽ8kUqNؙkէZU6m2n`^gi'ЎpL2)Wˢ땗vxѩS'NV538k'v2Kh;|$a( Vu֪ںցբ8_E)(*{vH^$rssors9\y{wX#   Poh`fې,Hou$ǒ ng$'';y{lwo96ʐnɝvmdn:wS~JZzn鬖/_f+тVf͚4$)^lC4QSwfg 4.h璜K_3Ma`{ij 5u(ҷ^},    _x|thӪJwNp^r)#8/l뮻ι5;^ې얬'7K=Q셦M`vm~wH|;֒ﶓY{UW]hfdA{ (?3}qNo|o Ǔ j=%jI;;֭}|ݳ kx; &86v=>~'ho/PoF繬 ߻wo6dF ks|q]W{ݵkW5n9CDDSﶿrC@ذaSz|WW_\YcHK65Դ%7Lwu3{{=gs=Ȏ'n;:-Nރ{OKw{ߺўx f#bYޭ9)_~Pov 7mitksHN=h# Q~_g3A@IDAT;#-\~ i.g#֑nSAXѮ&m7%    @ȏUuwi |<[;mq7]yK[Osj?,[T,xk/)텯 Oߎ"jeF7H]{_vOvoǗw;}j׷2q.%޽`8@(MhҗV X@u;vLqu%S]4ѽVGO ki"wZIhy%9)m7ߖl׋s C{(j }ruw_Yzt_%w˩e0YR躾n/z|@@f TwOYu˻{~Iu4q_R}$@ɐ   ^NB@@@@@@@* p_E\@@@@@@@ p@@@@@@@P9M0*8@Ll7̩ P+އ    "@.s~DQR8^0C>SeO  PSጞrI!5 j}S_1   %@>(&2/1uQM_| U%puYg򄪺[؍   /"u I=^ViEuߪOdY$e! @-vj1JOS;z\^y*@@@@ XJqG`[g%pd릸@r^.bɰ*n8."   ǃ@G5kqK@@@@Z$@ҥ 8PԩYz,[L*Ê9rDΝ+;vKttslVV̘1C}JY>rj I;PKrzڗ6hܑ^"Wy;3Y=p4kwr@@FfȨo7˼SϗNq 5⾫MRf_   pO?t1b >L49 .ѣGK˖-eܸqO>YN8f1mԽ XI2`iP7tb2YwW_.m;G6WA9" -KӾPz^I[/}ZNFS@@-]w;Ȱ=Pb>Ab iPs8#equd Ud}Y߲e!@@@@}-Ln׫WБW]ROh/պl?C~84J((}>.:B'_~LҡOjMn:AŮozU)]}<7i{L2 9%gί 61e.毵G\'" @u3;o;'x{yѾwZ^2>y.פ~Cr Tc>q?hSH9V;i8PbV)    Qrוx6,g.\۷o\Rli&O~BBlܸ|EjD$.SHNst=`s@)Vdδq8$Q#]DSظgGΑ\usߧg\~ ZY!޳R˯۟9lHlGʳbgJb|sH^XҊc/7\)ҫHD){Mr)>l" @MpqGg򮻥IN[mqPn[*k,i|^Nc)+/Gtz)Kqw8GZʵ?"RV 5 TDz2l}+>. :m/m[^&-ң P+Q@@@@Z!p_x?/MSz>쳾V+zGtiݓ$'~s jwD6^OjdH\n,:5֏^GdIfYu8A@2dEv^\o A v.OȝΒswD_&< ry'[C& >'J?ʼnEogY.wK|!^b[oqz&AV [Dڕq$Oa+]#X|=l" @uxԞrmזNx f~ ݹ-^}> l tt.ZYZ7zOAu#92=alN; [/^ߝ5y=*^O)?[ۆ{#nY5 zohկSTu_=fA~6}e㵮ƦYz&AcG Z׬-Itz    @ǽzg3<\yxt7z~i?ҩS^>:ft:'O!õ}HJm}Zeܧ7Wĭ2P{{*v$Y9' PϞp]wD󟗇W"#[]7gj}A|w^Ȩ]5HjRhz/}o2Neʥ LG@G D6^'L\9Y7zsXGL|/"|HN^nϮd Y@{؟ܼLݴW2Ki ;aH u 2ecܡMgj;"<#NS[ T~*_'DO,yr4@u,i /<[n_OIpeiROWu$DPoVl5@&nqk뵡փe|>2Am&mďxݷHG*|k9 6ފ>l*re"?,ٹG6,Iũǹ,@@@@)@{Ν;{BBBcǎ|c¤m۶>%VWƔ Yy 9]SS\=+)-ܒ-yc*{Z4s$24\ƷԹ5h~ʗIrN mE U.^"8p՗?s0CV$e5:__Z~Of?R|G7Ck>[){ғ{ P k˰ƲW{[/OC֗~|IRrX֨rO!ye,Y[ MdS- mE6uFarz~Na%}K&K_={qm5`o=j]PV >Y@(KJ['֞15_i]z?@@@@!?wx yBb{7YͳWҖKIPpșkC]s֫'Hh) }SӇst%s3Dvv^&fhNIdߣQBܧMkPYuh{P݃텲h-o)!-Qfvd*ֆۼ)5=_[si"ܙ۫=7ٟ-?M0iA{ WR ƃ6?}IFMܨދF9= =r'}YtTVwxVPWW:ՠB~# ] .ײko)yH{Ǎ 9eS;%9+=tVtO/nV\u7K^,2ȳ Oqi؁   hw}lܸS ɓ'{zK,˔)S$**9Ƃ)*Wt&3>s79d5gԙ]S=Z|ݧ zB==h~0i. GD3:/VyK-IB4tw%]{hO-dsߨۋnYhj핟.g36C yB#%o˥e6pϯS.Miϱ"nҲTǸ.~\@@z ueE[de%'w n埛-FM g";, *p?Am"b^=߲CXoޫHka"d#-@5z;:{ɤ6] :bқNU:'^<91t`<\.)yG#KUdW   T/>Gjj8p{p~oꤤ$qgt;eoKwS@U_l? ɑN՗;~_ Mi۹tx7ؽ t^,nK7~n'|lo$H{Md'-- W:~.B{nɎ/hۻOt`}uOŰ zK3e{S$O5kdK9qNke6$(S^mSAI1 [흏o="nc&ho )e%{_@ 5MOWצrWs=s>v OӺ`#Bɷe2HOʧ;~a:эܺIiNtfN|u1搦eo5RgkҔ=rnۡǦxwJ|ҟSa    P  إuwi]P|<[;֭.<省qKgq[:;?lڵK}Qy%22syd̙͓g+,ƴiӂ=T2+cu.e;G&h_bKQd]SϳIQ@*~eձl_i=+6RR0%QKJ&    @:K`߾Pޒom'''KVVlB{}ώZRANqe"/M<;Dо$!# p| TuоS    T/<n-ݏ]]wpwsvy/R ފ#@@@@*R[?בNGVrY@@QSOBq     PQ(IA@@@@@@@ ˀ)       T@@@@@@@ @ h       @E (IA@@@@@@@ ˀ)       T@@@@@@@ @ h       @E (IA@@@@@@@ ˀ)       T@@@@@@@ Rs8 yݒ+ĶMCY9=rDn:.ͥaH=٘!_8ZO"p!)$`f<(9yGd\&Zh7  Pyֆ=ލ#olyS:1.J7/ׁ:]JJo~h?cgIJsn_LC9ecg?ʁlg}}gv%IͣCdpr    @u p_ݿ o}Rv֪#eG=-c2T_WEZ2{mE5\M"Y>bN97=u\չyG_ ֨ $i-m:!X*+-COzӂ1'V^^YBymX 6sns 5F`$AԅF7ʒm_gK,&Ru?5RnBsYYk^c{ynk{wgؠ}S''s4 P7۝%f] G?>;{jZyfyҾPl}V?Oc{PG֫'ghM36c37۰2sn E@@@@KFM]`':+cItHhPoȌz;>&5i(a!7h -YO6gd-7RJvdڊZV\]5/o6GY/5m<=kw knyah' Cy3Ȉf[ _^8 UUwIͣ4pn^~' _h9L#P\-ej=FiP6Xq #Xed~(fP;pPlI(6pmXZ[kq<    p< ~eسe'VcӋ:s4u3,!k%[%Z{?ի { +Ŋlw",kjƵw;+m(Zbp5)=u:uV >ٺ_^\ B>m>X>߾_Y -:"A;mD:\iyyn_=USSz"=[K]]7gj6 +jϨ+7[@w8M]36F߼|f`1E{Oa~?r'ts d}])]?n: Dž@g zJ7*t Qݜ4t,p/rrhFxsdibjz?uʤSǸ'vL8è֏RY8Yr0E~DVk!awٽzі}q_/ug4p?{G#+ɜ)r-vi=;e:]q4dtO@livM:T| l./w!r{U_4Q~)N5Z-nT$?NWo~$۴nGV24ZְU;%~=S6UGzϮhg;zYG@@@(U<5AL҂_={Dڨܲp8iḰ3W4 Pfgz9/@J>ְ`|-Z{mHN֞jRG]=%_N=G^ٖ)/,'kv?GtWw5@ﰜ1{9|7Iښ-j/*KFv29r᐀[S;ûHO5/͠,i§ lkЫqC/`ՑR.=^Z^S'RνI!}p},@8~~,Q65(Ztˀzqٛ, qrWq+g꛿F\*>[S5}ۈ o_]d嬷5~\u+>.>$ouGM2irֱBm2ypGFQ:@Q  s'uh578=m@VpA1/թy*?ohMT AַZ2uZ?`[)/tak=tnb AvX ?#?X=WIm6V-T0     p_xxW~rAYv$$M("r==)5 ڶsY^@tNvMmՖOa7b5XoӞeMn:O:GAo#w.֗nzU_κ#y%-{3$^P!Wi]Fm|i ƮZΚV~};| [{K]IF'3wSZྒྷɖ^<2.VN.^}uxxc$>ڳ瘫ϴ~{m`֕'5/X"   TG-&L Yzے^-ܽJtFtMɂ}wY]PirUnü􅫛vjSϷ4V_/UvC{J8$gM>ZH{3\rRwybgBeܞ&+lxuI!hKM:C}7,}Id+ڬ`Z;ۥWy:sFO }a(?O=[nԆ2Eh%Cpz6̩\<w`-\lUlK m(IGJ1@8꿁 Nέuʣ&wʷђHǒ/k Tg T)u^%A&m*n/E~է|?E 4/):e}'ܔfz-m4/uڞk̹d؞[{oj%`b^uݤ,h0ڭPWtl*˚%VܝV?:SE(Y=*[~'kS7YJ>O ; fJuѰX"   Y]q|yرcsu|ժUz[ٳxb=uڭ>Er :vOv$ʥW*}o2ڄ6rH7hŪjC/Eu3VJy wv䣵{G{֗xF ^vPqɆgC YwX҇:mcѳ|ö![[ '@Z.0W{xE'MްGNm_ }VgݶdK5z&H:ܿ dy?2]G &ў//=׆hOO.wv:gi"tzKJ,RgZkCqciKx~( ?^٫!-s>?:;BGxCGBF6֣Zc\v:W-Z7F$@@@@}1cĉ={SRR^s>l9Ӝ;^zI22T+:셛'i 9}t,)R{1b4n4Pnoz/РxkϋBlsjHu_`^n!ҐNHhnlQi4tD˵:j (_ɋv$gwrU焭;'ӛ4pun-,K}o$:la6(Y>O}W!@'={JGjo{mu`rvO=Φ ^6%ۃ:xMɦMRG(tʦP-QG ꬱ$\^q(aZGJY#TkHWt m>{tO@{zg ULT[LuǴ64eaa-=ޭ/˟ނFJ$ߎ-zހ؆bBB@@@8-1y<[.ͥﺛgKcغK7{i qK}eE7n,uQ+&?_gz?3fxgz}ڴiAF!-E_OZ; ֞JohPV9s^s\N֞OI6yZ+tԀuTS=gɆ==˝^_pH<652&eٰɆ慹V꾗 {lЗ>:pa\+ma/˚l~XO7k{ DD >b'DihlJkxWW Mwp/˾_+hO#id4gͻ^J{o`އ?;&PeNס)| a[PƵeMSO+JcWks    P^яҰ^̾Ks?>ͳ]mXr׽|瀂c]v=+Æ +7,m=$(СCM;& (to`%C /FKs-ȥÊrf&rEɰ Zt b4]$P@AXTLyn/X; O:2wE+2SFu)~NZ4J{owAV؝)J>FOYSyvV7R;!   (e՚͛y`{`ӦM},@@@@@@@$@ޏLx_8aLcɻ{틈p7Y"       @q::tٵkW;iNN=L@@@@@@@ ޏƍ䊜x2j(a}ӦMȑ#l#       P{?<˖-"{&O,olذȾ9s#@@@@@@@͕^{M 9m~ʟ>}X       @i>套^nI,`o顇*r"d        =Q?/K.v-SL!h:       @q_ٮ]7ߔ HӦMСC%n@@@@@@@J p_sDffܹ3ȣ9 @@@@@@@*?8'B@@@@@@@RW +"       8 @@@@@@@J p_)       @ps(@@@@@@@*E}R(        Ή@@@@@@@J       '@>8'B@@@@@@@RW +"       8 @@@@@@@J p_)       @ps(@@@@@@@*E}R(        wGU7a3n c7[ o 7T7V}<     @9x7{Q @@8c@@@@ _mn @@@@@@@x p<|<#       @ p_mn @@@@@@@x p<|<#       @wV nM6r;w,o޴iS˝,yWr    PSDF-e{<4Fz;    P{FEEIN#,p閭 zsrrjZF4u/1;E(cOt['/#/[߿N"՗aM:K]_oށ ^wrv~@jߧW""'Kw%F@@@%"8 ~sDFFH yB]# zO=ϕ~1ܳwɒ%rJ˖-eN6SS~dɲm6i;hoAzGgcʒ],pǓo @顎9" hOr+6 UN:>{tW~p%TQ6S2enAN=Tg>$կ~b[oɴiӜ]<K{j[%*4X4'96Ku渿)6}#mֳ][IOΖk,Epǝ+@z@IDATBzϚ5PƕW^T=';;[,HnuK?зkbb_~Y}[n7|S5jc}yҭ[7g߀owyGN:$'?8<5E]$6[瞓~).;i0: _s5qO?sg}7l wu0)F%ݯg"jrHCNoE|ѳ@@@@J+@ޏX=e<{!Zݒ |^u>ީqѩ[ k4 RlF\{׹n\x`|{Y<6@@< m̂,#@O;/xoCO81h+mzʏ?^/^LձcGYpvi2w\ݻ}Q9s7 ȷmV222y.G YXeos*SNQFI>}SKٺus6d ^6*opUW-o;ߞ./}N~5{lMDZ5_O@@@@(@z۔uN_E:EL<&3dšm:<hՌlٔ uYGzKv2+ J_Èzu]=ϑG` 8^K7?*6l{~ȑ2{lg{ҤIN|ر_;=A믿. ,ӧ'|"^zy晶;` ~״iSyeɒ%;۰6 `xoﭱxe}N#;w:lv?M4q8p[?CÂM0ZQȿw4@@@@(QQ||gO]06Lƍ=Ìzӽ{w_/*ϭ) zKOߓLg\6r4?OX{~JP%uLs206^ߵdJuNY ~P8{>8:όTG}$SN ׭[x}wڰdC%Y?P*Wx- M׺B     p_Zxf[`7mOP4{6hZOI}ܵ|.ퟑ- 2Fz2joi "PDbד豺!N@tW\.>waei @@@@ p }Nw ;^ko~x's, mi 屁^7 5D 5M"( [VVQWg#   f>_|!ڵ+"֮]+~3Kzo  5M^-(罿g2mO<@@@@> [leΜ9%~@@p윲mx|iOо&~3    P%"  @(/D@@@ }DB@@@@@@@ p_U\@@@@@@@ p_@@@@@@@P}si@@@@@@@w@@@@@@@* p_\@@@@@@@@@@v yo|0 @@@@V8Z+B2@@jq{    ǵC_?       P}ژ#       Pi؁       @ |c       @@i؁       @ 9++tȜ$%7(5%uL߳ғoeHlGլd;[*ct206^rm%!3Skzv\?ZC#dUv{n@Ksf%H? +wm k,sw٤DM_fmW;{`WɅW#՗;"uԑoeI;       Pe@#0y=L; {y ۺ%Gdcِυrj}?Q]|s<}2iwϾڍ76Β7|/vnQu_}OJ4ho¶7 ^sa>**s?/{O? ]#yyynJ ڨkAFhc+ۏ:Aj.n?RCk>6@@@@@@ /GRV2&|wLh5@ב)A{lٗ$X}[aMʑ#G䎥h4S4pi ms=E?*~5 &&nWLCotjRjG^*cdWF62 !P$5߱asiR4iHh$)+ M?B|{?묽qM7oMPǂn'Sv=&ɐ]:uXBe=UD<Poy߅^* 6 ޲K˽3{O,@.pa rϴgbb+s9@@@@ p_”_#,7 Yxtjsux.ضokoq-O^xpS1uD~C/?-ybA8Z,VX/A:t~I)n=N.=S"q?=vZWsU72NX'9Lm0i 0C;!s=Β?IKm4'`筛y /i6"}ڨ윥 skbÝF^AOP'N=yde²W7(Nʑz}M%rz\ l2sEoA.z: f xPD*L`߾}vZ'а0VZ9wL0y$dr%sJ'HNO xYf믿.4n\NKK[oU&O,<;@@@@juq!`lgKNv'JLHIe[dW~,!Yy:<sҹIXP'H.Z]Kz{ԕW7t}64gKtw|'Mqlk[P=[;A=o~!:):O Xdk`=$o[oB~?}+#Pc,5mn/ctlA=uth&#%+/G~+6γמ@>ht'J \*gi6¢8:2FQ0>"b:8^l c~-}gET̙3?.h ޿Asss%''G4h{n/5b%u ظ=ǖvY%`_hh{H?/sqm=KJv ;z[~εcׯ_q2"##K*    5P} Ҹ sq-;CUo`١T E94zZp-A+Ɍˤ}}έ=RCNoNi`Sdi,ԡ'jo ۍp=-ًk gen.o#4(o=+n %%m #>T394!iIXF裣M|#;ma}=:-5ethC2V~~[? m6l SaDeoiؿ0gah$ڣߒ5,` @eL4 NݻoVǸ{ X_;=mu&QQQ<}Æ E,0m= c?{lceiFnFy%&&FlĀ[nEz-kN֓p|ǞFF/Bo۶r:Nl$9xtW:eddH宻rL,5#3^ƌ#vAß'>|߿_?Hzz3,~RRyҭ[7A    @-[ 1^ow^VСܿ^Rrҝ}wENsA>^ycKKgo)#7G^ܝA5[{͵׻Aþuq̻HyUgHl0'}.^9C+[{:,x[)ޛfj>)+U:|ݖc$3XJЀګߎ90lo5Yw/ui K=\ SRçh{Lu$GvhMv icXP=z%mn:?oy)9Ҝ3 gjCpc޿ nD*R ""Byg8|rJ}wޱc@dԩNޓx۷^/_.?cNJ [owQ.\5w\ݻޮ/:[P܂[nuFxꩧ3s=i0gͪ'ߢE qyy'W_KJrrq78~IF46裏+V]駟aÆ9ep     A|ꫯdSN L) t{ Y4m]mjKj,5]ҟlCu_ǏvOɒo-չܵHu=۹np؃tqnLm{ ߬¸ѲD{龶Jˎ L"KZYrF2J:rNb@TD=CQ CE"Q2,@rϯٙezqz?={[^m8v*Q2Җ@ǓYt݀WY@ѕQ.rf)ָi/~T gVS(`q`z,|idi՘$bGMYKCI?Y끟vqv]` 5 '7h.Y7nג w=m(߯5\ X+Zݬ%JX&M&woթ~{f+{R k[n*Wl_}SJwu ;@$pI2a;ݠ^dzI}k֬QT)+^uj__ ~ikҥAn!!   d]ʏs3_[`OҊ?_v^*} f^|vL6?0SKz&y/vC[jYyL`l^y>>km%{sw}o+zt]J )z.nV~f{ {#pF \x'}ևH?cWKP֟ܯ^WV|?C`p?[]6A'M+o#)-HO* p^^˳k̴v>=/S[ ^Skz-KIj MwK}p~sي+|ͮR$o { > K:W:uz'Y]-@Zle@^g@@@@ ;O{<-E+=fxu)h:ڦ/_M~p˾ Ҥ$hUHt~6^Z@tP^{iY% @\ݻ.xg{a5jpKOĬQ]v,LUf32fb3k/ %즛nnVZ%@@@@@ @q_dIw9rd@>#pqf˘] qZE~쎇̞iDgF)@ ;ׯoKG׭[g^{FiOFE@@@@ d}0 vYmfz]@Sl„ b +W}׬Yc{ɓ'Mc˧IT   +RO `'_٥̮̼'! P@F%y͚5;wl, 曶|)(<}t{ɓDRu%zq=C{ Aʚwiɒ%ku?\u""עEرc{VP{$@@@z3q>فXv?)O~fgc{~^{G4عsX\\zݻ=7o?SBlǎDW8޽ kr4Z?ڶw:+,mףG >pǪ˛ڏ>t0PbŊE5 =)?N׽zoyG&6ulݺ՞}Y7B^xjժ,##G쩧2_6iҤxN~HM[Ns   &RFO.jivu?(6l6' @fhc,]1g` z|c >#ys?Zrf3냖͟3gM6-xor٣>jaÆnk׮AYL6m| -W>*ZhQf̘aj_vUVR͒V@_w/.PlY<gM'8VU۶myY%L+ܟ?=.hݤI0` ^vmVfVzv/GcԩSݳș3-^ygo'0`1cʕ+ݳ˟?nںvl7իݳSpZyvժU6|pw^1bm[`;@n2 ,hs&~i+UTt'tk[YͰWMϱ_~k|fΜ{?o7 Rزe;UBlݳgO]oFWޕ,Yڷoo+\s>xm@@@233sQ[xWQ{FXw]sY@-Q ~z?K]@;v͞=T@^zgAT`VAUߺYo .\Њ)bs-[]%ԩjK3U^z7l`sεqƹѤ|%\ *o_|S=n:#   >˹N[է]  g}^yw+)}:`fkw}7nfd̨Q\ 3\y6~a l͚RzU^Ͱv͊V?5C|X]E'Ͳ׌{ZW+[n V*U亡fNAY۴ic]w;V?4<\ҪW]uխ:e˖^(VP[m .PJ@ڼysW\ hin3sܹ1?Wl;˪E._(`{Ѐ.]*T0Dm_{zƚv5/4AK 4׶ \׻Kyy髯Տ!C{EVj{u+ +Z 4 wFncÆ O.] ݻwVg@@@$3ɃYW`Zz5R\:H >̦3  bڃ[_r֠AVc0C)ʔ) * ]U O(%ҿ{jskf9Yc]ՌŋG,'Ŀm5С?Ux+%hpD4)z,6EJs[wC혘I~ֳU r* L}}Ou8N@@@@ "OSɸ>2YJ`Zb;f3ZABg6}iPQדJZ<\0f}k {͖V%^\zڵ]S3pxy Jkƹqqqnv͂L~ jyB yUw .P_UU3#% ^I3z-7[+X))@,cifkj3P`:Z-zf+38p[@U4]} |{ 6k`'|ZA,Զ)PҬu%oH6 w\;\2T]ܿVgOZeY;;+KnzNi[{mkܺ(   #p*JK+dw}][euߚ;-SHF x?o̦@ (Шe5^*Uشi\}]v=k,7{]Ē\sRJY>}]"%eϲ_~apҥKz뭮zx,nէ W`:WlY "m6zr5P/RӳQ"((qRԼuY "@ ,i?*^N g6uej={D ~^mE;[l{*0œՌe/)-A@W=m+HСCmf`iT׾fk)SͧӶqܸqn @{kyhߴiSA:BڡAHG/6_c=}7SyGj|@@@C l^ڋN/s<^z^޽c}K;]?˄;N,;g̸R$<(V[^y-k7[F3J4SO?uK&@@8Rֲ 4਀xZuosq}3fLEIk@ʧE[n`iWFԷonwyg{ =I"D{w_6[bǑCbp@@@_} %W^m/ZaIlZo|AZF@@ e=}_wך^)IUVѣG]`3Rtm4t:N:%Y    @vr05k4-qF7^AcfשS@@@@@@@d 0>2ءC袋oqK+ߤI۵k[δ> @@@@@@@ BNKtwyԩSmڵv[˖-"        pE{5j}oݩ ̝;ና  @8rvmpIN2Ŋ)4y     }֬Y37>o޼vaS?i}Æ UVVbE>#GEn{@@L'ʕ3۷vᶀʟ?mڴk* @@@@G}9gΜֱcGkѢܹ}Z /ҥK'rw۱c\~vAS oVXazKXi@@ ʏ;?~UTK,~N8     @ L*T`ڵ8{饗lҥnGg}f/rpy|sځԩSw+b?5nիwJm@@$w5TYtI^     ̸ɓ1kѠAl͚5駟ZLLmeDk7`vw@ .u?lv ֗ώ@@8-[J/K.~?qiIQ     pzꦗTԩv!kڴiοkL$sA}p  @f'ڲe\^Vc @@@@,%@>ǩ \ Q3\ںu>9@@ZQj.h;<ݖP~D@@@@8}nmԺuDh_;ʖ-f'Z  d?&M7r)SXѢE@@@@F}Uk9;G^jZ;v/l 6ڵk{EL?.byo @@*pI5kif~?vDf e     D-@O~~GW k|-l /O?J.]*V(_B?ŋۉ'Ƨ   )R۶mW^F@@@@ [ =SNʕ+݌5kpƍn~dɒ<Ld  dri_~}T Zfwjժ2-=@@@@0Q|;O*m޼"!  p& _~o?p[6m+V,^@@@@@ mܧ+"  js{V~…#    @ L@@2@ X^y1!   d9fgG !  ԩS>wf+?#ʏ#Fo@@@@4@@!pI[lk7n .B %)رc~Vti;zxݺu~{lȑ?iZ@@@@$3Ƀ  ]pϷ۷]v @yѢEӭKN &؊+?8d?~iˊ@IDATU4(!wnӽԬtweŋϔUFlذʔ)c;v… ["E,399E@@@!9 @@] &&*T`3f̰*Uا~j=z0;)ߨQ$m֬iwYқoi˗/=ӧ<WD,8T]]Qt=޽;]{qk׮1c[o~F2k# '@@@@ S ԏ!  v jԨasUV:d[v3Ӯ5ܹ4 W\{m>͛7x׬hfJ{|\\u<M?vi9hRh5˟:,˓'?+x4bɒ%v`~N_^G{_Oj!Ŋj@zwo~zyGs/yVn]{ꩧ[ouՄ938F@@@)Rs  8%K]w58#ݓot߲ekV+)44C}֬Yի̙3]^Æ ݀}Ǎg_}˿ojB   B1s  Y z?K]رcm.Pꫯ@ffTU]ߺYoo.\V$*˖-s-Zԩjg5W~۶mns@+Mʗ/]r%.@_ؚ5kT֭ɓ' Wv U2e[;,է۷>i0_H3l/:ÇCMYeFJhІDV f랗.]j`ؠk:u'Q^7ĉݠ~͸zze}@ bP*wP[5   `}8@@@ ۷}w+v( \O0!5\3#%-+߸qclwQFz6l~RzU^5]3ցm,X VPV},{͸z+[nq34iypL2.X`fRWPi/q,k_i{-ӮW=[^35\KGtW`^+IA]uH:tǻoP &E ZG>l}l{-@ͺ{m@B@@@B"OS -g@@@ @"׬Ēf}k Ufkyp)&&-^vmxp/?OKk& *BQn&f{}ҌrzBչ}֭נ͈4(@{Ň& 2E:V@]IhO 4] ,W{hyի%;v g 뾵*Ν;]OជV)Pٯw gWV5z;㮋  kp\r-ŋ ҠA(zl #   @H8%k/w  P@AR-Z~ڴi]v=k,7{ݛ56> +*UxbAYefqqq)ەjժf}>- ߿>a-ۮsu+O:WlYٳ kmW3o^z{ߗ^z^"(>@I=G/2d >k^@3=o]ꗖj4"Y{mOIA޽)=[ Q0ҥKe]Z@@@@ { D_2p^޽c]3C<{/ѱַw/tinp TiQGC.KAH%Gkx|@ fҡL-Y?{e'3f)8@@@"eǵ) x*XVAq9͙3q̘1:iL^^u*Э\p:hV;LPw'WZ?9).\88BeR8-O{@@@8gO   @Zi6S^{镒GKSt3fHѵ.`{,$;ud }-OB@@@'!       @  xE@@@@@@@@,~un#=͞ϝF@@@@@ pRllU\ʗ/oM6ƍm׮]Q\M@@@@@@@" csM7ّ#G7ߴf͚YN\>elΜ9vСS|F@@@@@@@ *a+fժU:uX]'Oڎ;V\9ƍĉm۶05       @_͝;J̙Zha;vB f?'!       Qh͛bcc\0@@@@@@@ pcBlSYʕs p  @hݱ}@@@@ pվ}M#  N &؊+?2Əo9r;wn=[IͺN3ɨ`׮]Vx4{aVZۥ(    @ g2@@@tP QFIڬY *%5{?7|Ӗ/_;0}t{ɓDRu%zq=CܹmСv KE@@@ pg@@@ `\r޻wo{-o޼*Tv'\\\u<إsr8vi9hRh5˟:,˓'?+xzaK,*謺+ hCI ա`?+VdSO:~WLmƌV`Az~Ez5#   %R%I=   "Kyۼysz[j>kݱ͟3gM6-^;x,ue+W}Q;t 6w}] d 0oڴ '.:ʗ/L4Ɋ-fv}.8_~eWi*Ulȑ믿^Z]lٲ.x3o<䓂_m ,ϛ7J(aZw&M؀\n5k"իky8#GพEΜ9m;8~;c3V\]uֵk`NϞ=mĉ.=cmꞿ{w^x׆nZ~'oիgO=[~֬Y)毽ZoL*rE1Ϝ9ӕkذD , O@@@@`q-  f}4ifW;fϞ{.A> &oux k߾-\v9[lbѢEVN۶msϝ;ƍg:}4)_|v%J_|ak֬IPf[&O.^+(W P`{ʔ)n\{R O۷ow}R@/v$|>d/|>lǏm6UP=/]>S7XB+Ŀk\ ֭#2>Ay;*|뭷s   3S[@@@ Y b+w+}ݾ \O0!Xeke7nl4j(PW~Æ sܼWW4]3u ,pǝ:ur'Ͳ׌{ͬWp\A+n7#_aRJwu1"^u k}6m뮋WF .iUʴkٲovvd_ Rk0JI^7onpWpgڭ[73իs=]{ժUN'x3[MjVkwl53_}=Z@3,/_ Qxq@@@@4 p&T  ZjƵ<ʕ+[ Y  M8/S k }P[b_[z]˴8ps=疣|l3l{-$@@@@ "OSI@@PU'lɓ'-YZ~}`YvիZ=\uZڵ]V$&i dWPZ3PaÆY5w35f+H * .P_WX3#% ^I3ٵ޽{Mu4 @`[ =@h ;vt3f}kU;wߟ=͈K{y{A;j سgS(ifR48DQ\9ƒϗ @@@H+SQҪ%E@@"(e5^KkiӦҗ]v=k,7{=euݻwws}.UG"%efqqZ-\uKv}Jjr+>- ߿>a൒su+O:WlYٳ kmW3o^z{ߗ^z^"h`Th'h@D.]~o5m/P@\i |͎W2e$ Z>kKm+лwoUC'p    pZW{yz^;5?ӻRyrdDkm+_@:tihO^Z]+|h:z;{7n l+ O >wlӦM U>{Avݯ_?7HCt;t:Z@@@@7w{u8Ғziiwy/}^Jޱ Y&qby9c}@@,Z\˺+8j7*(̙3q̘1:ֱ?yPY`\j{A{ե@V ڿz鴣g3h ۾}y 5DlXr6pAΤʥw(9   G}y)  g@ZSk5RVjGNɥ)FA3fHi0c=t:uJLb?X!   g'!       @  xE@@@@@@@@        3@@@@@@@ pw@@@@@@@  p4       {       d@ l@@@ UuzW!    q'w       p =V`A_       {o-66֗aٲe䑁       @j}M6nfΜi+WL4@@<>y:CO@@@@X~THNH>g_\9ҥʕ˺u1x#GW˩SS  d8{ZF@@@@ )ʏ /_>ѣĸ^~VRx|@@@@@@@@ a4k׮VDxgCE{̯UV|@@@@@@@@ aڵkgksƂ_r%ֿ+_+WfͰD@@@@@@@ 1Sr0ei_WFB ?~;x`|>        3Iƹ9sFQ@@@@@@@'@>S@@@@@@@l"@>9rH @@@@@@@ }'۱cœI<+&&ʕ+g7oN g@@@ ?nbŊZ]ѩSlϞ=g=!   YI}9s0d!  viVܹ o޼VT)+[i,#I&v 7:?llQխ ?on̘13g/Dv!{Lɕ+WTA!@@@@#/tY}'w}qi:g} m+ړG5vmS@W9po={t=) pH }չ yG@@@f}|ɾO)?ܵkW/J@@ISNgَ;¶!Cڿ6}tWzGM3ɇ f w}7l;|gbŊvW>iԩSȑ#vw~WW|կ_O?mf ?SVHiK믿ڶmRJmlΠk׮k>5lxݻ_F`aРAVD {o͛7oF!   d?@@.3 xQo[T7o3fرcr.ꫯ`*Xzu(=g/ݞs%K:rH[\} M͸ߺu WZƏo'Nz(8+k\\r%.A%͖?mʔ)6|{饗駟v3{xW{g +k7N:n~-Zd ?䓦UZlifr$!   d9s  rU%KqVJ׎Z>\ڰa=n8PZ5۴i1믿֬Y.;~]f߿>|ص}5\s]tq+蜂=mڴ뮻.At^UV%K.W`_u̙j֬f*U }:/%˗/!P^ov_5w P=$@@@@-@>{?@@'2əiy{R2e\^q9_B ,pA|-{q3Խfkz5s^{GZ_}ѣ+Aŋw^3۷ou'IW0|rĿW?w+(@@@@'@> y  d3ͼgڏ>Ih_~UTƌfkYcu v3g}I+[Y wo0`;Zzn[v4P X* h>o@j`kuo B3    @ p=3w  @!*֌ݻђ}fR  fk6u{ʫ{^{w]ݺu ྂO<[j_'Lp4X!… {תy/[q?x`{5/_>3zh=OI_c@@@@%?/ܱwڽc=/;Ykmzy޻qlU:0{?)?3g@@({ѢE(Gf ]~T8-ҳ-Z^ߧeZKk6}h`]}йlۻOM\@~n~Ç2Ky|&;䯟c@@@@ rS^^NyWR9?{z=ܹ^ޕtKs.   p:ցsmұׯ[m@3CV 4@{p'O    X*?=pn@@ROjժ6gΜU'Ok@@@@ k hy       d Y@@@@@@@$@       (@>i@@@@@@@|@@@@@@@@O       ;       @ @|F@@@@@@@=@@@@@@@2P}4               3mF@@, 죡X~T@@@@N9Q @@@@@@@4 p&T       @t,SllիWJ*e111{n[jm۶-)       @dmܙ6me]f9sCY…W /Çy        ho={رN:e7֭[[9VZֻwo4iD9       Y=#شmzglٲeqF+P%Kث*UyP   \8馛npT%z#    p& )b;v+W֭[%~'6l}7tR;wi}˖-8@@@ #ؼylӦMvQS޺u쫯_1W     ܇y@͚5\rY&M,w h?{˗/o}XWCӦMD  D#m&L`+V3gرc= lȐ!n Lv4F+-NK]vegԽ뻹zj;~xRES|^~-s!   <ҥK\ , +Q 38@@@ra5J٪lJߚkD{7m剖TPxɓ''d@ݻwg@)oRUV Ny!W8q-ZdǎsƌcoVH)>"   @v pi{ۂ… 9c_~i3gN˗/_B@@vi޻wo{]P!۱cGRչ *ꥸ8޽ "֒_i/uYUm{Gd;pTh=h^ /?ܻ ׎_SX[D/ݫ6_;-N~/ժU+n߭A$#GSO=垻[o ^i+^|@@@@L+L`]?L6L2o߾y@m^y@@@͛$ ڷj}:tZ6Μ9s/wf++W}Q;t 6w}>VbE+>sA۩SwyM<hp_jk㏻`0`iohR믷m̛ۚ7ϴV'mnգ5kt[ ^zYv~m5k^k|] ZVYuwxb{wlȑ6~xꫯW_}x^5k|ʕnEuֵk` ggUJ7}=\1b|m۶`n&}͝; P]PYթ^]ZU'ŋ%CM(is4ivJwKm~A [lq紊h;p={~^z%?a5jp(P}J,i۷W_}Օ5\+O?}C3   9 zt=z/īzֱcG7FBӯC[9>#  ~-BWJRf̘acǎٳgTз^zfᇫy.Ps_~iy} jqƙiѣs՞7^~ `Ƞ| PVJP]uhѢr׀=#%7qDm7n~>zԩ kCo?y4mE3w@Av=}4{„ m= /x |,}o0+}VL~Y{+UݳPA +?5c@@@H̙Պfsf$Ý@?hfX(i& @@PP_~nffh߾}ᄈW^yݲfkotɽN(f{VZzqnֶF~fnݺgֹsg7cᬵM⚝*+-Z|AA.]A*Tp+ݗV+е確lo Lغuhm}mfyVCJ\oEyEkVj{uȠtҦ$䫤PhR=$5TR6lfҥK] ݻwVg@@@8܇yXf+'^C @@8] 4hi?{տ7L{z$ ׶Jlo/_:tp⫯GWhU?ns=,q8]v%(M^Õ~;h@ϰrP.HTtQXĸ*fw ".*&$+(.0 b\A% I=Z sھ}nU=g)W@~dֿԩ㫥5@H})ƮUϚ\ /jkױޚ8~t`IVZ?dmYch׊rm` jW.*xu@}X^ LkwI[=e-lVp?Wʾ [+U.^%?Cs=ek*|Oַ uOz~!՞mi=*[A!N=w=}Z/~}97m ^y F   EN`(En;o@ ޏ1W"1_q}  @~ (ȧrH]ݵ(T +ܰaC=z)+Ǎg@o*ٯzTʦ-/UleXVruWXgϞv5 4J@ڳ]Yz۵k*)Kxֺ^밚:zQCCݻ{z89ܗ~'565 B)U~8E]n2Kh"Rk#Gz~,O}aܡY}(3Q[A hžyVp]w| }Qf+Q-e{P|&*h;&ر_ &_&8   @V~D%:^j-w5'8{x2 \]ٯ~I;RԻRO;Lk~  k (}zժUt)}cu;?PVE{[nVJ+gҥטDܖ9;s{}:\$^ hZ4VlYK4Sn:tﱮ|^?a"FGP@;2umۊ/ٱ&mhAsHV   3=ٯ/W‹׹ ipNs=XR WNTwƊEG<   P p ڧ*讋LZɬ hPRe ̧.c߇&(#<EZb ֭vUGT^E+MnJteydu=N6Qt)ժt   EY0 @IDAT@@<੔ +PSLÇ{{We-?nnj:O5@)wtaG/:@@@@` pG>vn@@ [ϟ{~>̶m7lJ'3b\    ䷀   @i9s}kV0@@@@gV3(!  箕OcժU}@@@@vϳN@@v38j֬{oٲ9׊ 6X.]L&dffZ*U}9@@@@g Js  QGezD)Vխ[zj˗%Ky     @/gzA@@((?dϰaì^zv7z~6|pۼys/A@@@@`w(   6nhs̱kӦM/,    +@@5J.m 63fعke˖}K*ҭJ=@@@@H 5   W^ֲeK 6Xݺum8w    @`}{ @@Xp Ҿdyo֭[} }!    S<  @i6%JLZ6    #@`\i@@"/e7no޼y,=jKN{e    -@>m**"  { (pҮ];޽us     ]a1T@@S@{7m>Ckݺul͛mRJgw    I'4  ֭[mf0`6;zhV6    #@`\i@@"/PX1mվ}W\9|@@@@ XxO   P5k+322,"_)     P8/gzA@@H 5ʦLش^wf˗[^|Aqی    Nwɽ   -[جY~SZJrRTlȐ!ִiSYmܸ^pYƞz)8p/_>:@@@@"   -i&qb S /_UV-!mݺ>3g?ñ}aÆŢ %Km{|v~5?`իW/L[B,^j׮mYYYVreR1Gm9F@@@G=Yְa|jf@@(XҥK۾kcƌo[ΝMA. ķh"n[jJQ&L`gNiY?CvM7ĉTTmw[n~2~4={7|cwy /cN樈   +~el*   Pp _{olSkqa+W&(Q+ZaRket5rVS+~2e+ڵks> Jq +##/wDmil]vŋMmݳZN_}/uw|?:_TڨV6D7nE[W?#{lٲ^%~Jh#   kN9  {mW_}߃V@ヒuߣGkӦ۷z~==ڃ ^}U_ɮuֵ;|2K/w>?N?t{wGQFnݺȑ#=8~7&(hM6@ɓ { 7x=~oڵ3%I&^{e.- 'j[t:6ݻw /hƍ Hs9VkRؚ{|M8[̜9ӯ?3cǎ~|'\ʗ/om۶BΝkMгjР=?scߪe4vXoyv7~}ҥK;e23/!S)U+IaBW?M=`vay;PWD})Z"p    @nXq[1#  @ hRgOz jq*?Jtӧ[˖-aÆ^eРAb;Qŋۀ<༶ЖK,~jKtiNתrWZj?3|շ_|dVY/vym7$Yhyc9۽ |uj쳏O4UVqjWp[!(RkVWE41޳SO='#A[ hC޽=Lnʔ)v%3;=A>Ynګwq&K\|,kY*3?ׄ (Qzu^mQF^WY4@+Y)C@MVfϞ/4   ӊ.X@@qYPE?{YfSﻮ ZIԮ]ۃ j^_ ~L+WZe?< WJ{۵r>% /s^Whߟ5뮻΃?%F_i:'tXՎO/MPV_~'.<&' Zj TzW%ܛ&hR-ҹxMPBR@@@F 2m!^@J.@@@  *}NE)зlْVϚ5S]`W DE^r9kZŮGyϞ,J^N_YYY_5vz[i۵*\+u~tܴiS_h<:+>$k[4fA6￷8,WB;DϼUJN;ͫh{۶m+XKAq9+WR"zyZٯ2m4J*yp\84iB@+ZjuϩpzAY(    ~G@@M@b*{~)+Ǎgt:V ]{_^FvWnsKUU])b[=ٳ]s5ҵ_&^5Q@]zz?ڵk+.m&M> 2(}H߽{wO>߻>RO>dƣ&A{Y5A4Y⢋.r7S4O>֯_?1b_;x`RTU_AҶ=zzɶ<Dq{}M,Hԗ~3    @VJ:s9Z ]͉?^c {8}qFfvzG$3)V}VrecV(d &c;t! <VSƪNo?(v\WAtRSp\EA]VmQtWpYDwwmWL+[%ӹdu4Q`СѢg>aĉdɒ&LDۈ?zek\p]a<ߜJ@@@O o[[Z^yz)5c΅Wnk䜾 J8~u:3V(r>hݺy?X@@ B@iЕ]p)WATTuLѶ;%7SA{tm_*+WܔoS]ÄD JWqkxG@@@r#@>UV-'R+~(   Pxt/;)؞<3fLv]wݵmvaՅyj@@@@]I}Rj6jȴ7S@@@@@@@oq x6m4ꫯ#       +P<[ӊ{k_tKn&@@@@@@@vV= &XJ,++֮]k#G͛7{z*T`˗/7w6m}QȰKƵG@@@@@@@ Q=|/c5,Y;AEm@@@@@@@HGT(Q@@@@@@@ p_@4       @:OG:   T`zAI @@@@Y9Q@@@@@@@ p_`4       @s6       &FK  ((8@@@@@ mVܧMEE@@@@@@@_}"       i O       7E@@@@@@@ p6@@@@@@@oJ   G˗[No͝;7q9    E[}~>@@=F~ۤIlɒ%qFӹ ̙3W^v=ƃE@@@sJ9ʝ"  @Qغuw}6gE>dž fŊ+Jk֬%KZFFF Fz4cŶX@@@(V+"  @noѢEj*OYrʱ0a={vڗjC=d7tmٲ%um;ec[n1_{+Wz-}/}    P S@@@ K%Jzѣ|Vl5*UT7otK/ r~joC)SLlKU @Νmii[v-kjľHpQ]ZZ7l`ݺu#GzpoUM64'OۃLJ~p Vs>]vB{ҤI^{ DR'j[t:6ݻw;.zy_qg9ok_߳5>&Nh fΜןyֱcG;>.˗mڅ^7сLvj<1u]޷=kW]uϔ~ݤIӘG[lO y>De%4@+ bO?Ǐo 40y]}pQGyZf̘aJzjG}rСC&~lVpTRpB+ylԩcjO4u}Wz e3x`;33Ӕa YQ0^5aBpYgy[AmYNӊ+|Lp '*O?]uJSk~c&>_6mڔmΧZ #<~g}K2}_β p&{{R5jx}?{d]իWM   y`W!H[jUZR@@LFy@9ܽ!=~8[f͢;V 9h%yRvmk"lw}+믿A:VR\)DDЧƤUW+ +P1^wu\)-!=O:$Oݟ^\/O\xM&=Nd- 3 q)Jw]ueWЪ|mm@R9R@@@@)@`? Rчݻw\[st{^'|]QMP:zded.rzF~qԯmO@@@(hDusz/ûVsz/ѱ[s=8#U3;oǚqG)$J宻U3eÒV|G2ʍɓ/@@VjtK)}cU;. Yt)8ү_?_[#`WpYADwwmMV~5XcӹDu4Q`СGѢ5!''LDۈk=} e o#/Z@@@V oϬ~~mԌ:8wJ=|^*89 It\Xq@;rFi͛A{}sG|wM5SQL(   71WwpC07-*WATTuLѶs ?޻wo:֭[F~GzOqa>r;&#   +@>C+Vڃ2Kf͚ߥVViKT?~iG   ]yahAA1c`4@vtaG/#   S" ,:b S*Aٔ)SbMJg>˖-3uOA@@@@@@@ 7hi駟+uZ2*0ׯo5}{M6wy@@@@@@@r#VjbA{^pa[3WﵹM|@@@@@@@أG)׭[g8طŋ-[E+bwz~nݺ:@@@@@@@r#@֒%KL N39׊|zfϞm]wURx ;묳7&9D@@@@@@@ Kx>`t%Yf~5b5;t;ܟx^W)       F}ܹsmΜ9xb{m֭^o{~{[n>ڞy۷}ֱcGܹs\|D@@@@@@@ llbcǎ:_)?s{wߵҥK[֭jժV\9_ms7nuŵG@@v PnN@@@@ k}XiJ*ek֬ oذnw|v[ɒ%=G%hS       $ U~bٵkO?d7o jղ,{'mӦM@@@@@@@r#h}|zj[`Z*@@@@@@@H-@>Oo _A{)@@`gmgJ    '0!3z{@-{C@@H(?p@@@@`?@@@@@@@"#"       P [@@@@@@@`p       @a /lqC@@@@@@@ "@>!   l˖ߞѵ@@@@(Y`-0   @P} fo4۰1wc*[Ƭfw4+Q@@@HOD-@@'͛7ƍ Sɚٺuɾ%Ǯ3{u Zo@@@@ ?Xq  .*rJ;w,e˖5jX:uXb;|SN#Guֵ~YjvpݺuֳgO;v(Q"a˗}}»Iת{     @ $\wC   PLb?|!*x裏& l_)j=Zʃ~6d{ktjG+ämnS1-]v QB-~jWO\Y\bomM; R',    Gyr@@v:;cYYY oGvW_z;ÃW_}5n{/{P>~e˖y { 6Xo>ܹ˳k']ˎ:(kJn&;^hB~]}úuf-Z-{wzm{W==lbRU.=lKR^Ɨ    +Ik  ʕ{߀ 㿏w٘1c|EO?m*U{mmڴZ>j(;[ SZj3ΝլYWke: XO,ИԶV׫W222lRgO@V_~)5i֬NOXժUMCUϱs16n8۴i[> A2}}tz5o{})@@@@G}8   @4xr\a/YJu`{~<W ^۷ouEӊ}7=R뜂 U tV_wuq(E~&ԯ_fϞhJ^ ?6uS~.m+G@@@ȃm^;     @H:e~~m%΅Xùp^\W]p^*>qs;c}@@O{gѶ6l`;w-ZX&M_qFn_t^iB W(3||֥KP>ٯc[-[iBs@@@@ p/gYf?ɴ fΜ9b&wP@@@0f~;ԥV+*5NQ%    \JVZմgݺucWjͧ~:@@@lVنyP[ŵc@@@@ ?RSNŋm„ p\Bu@@@֮3kskC*6xF@@@\<yĮx'H@@w}ho{W^mھH>b   \<ի'a 4/"i@@@vرk=A@@@ 6'sڦ\` 6#8cv6@@(2Zy#w]Cz"   OVXю=X3g5oܯWӏW^m'ON5!       +%(hWo-/r֬Yc=)xOA@@@@@@@ 7A+kժ5"      (njcƌ7       Oxbׯ,Y~58       @OaÆ$p@@@@@@@ U~Y        pk2.@@@X|uܹs kB@@@@P 3   @n~7!L2WZeժUKǯߗ.]:e=}f+YeddX(Uzyz;~,+kР*U@xb\UR@ڧQ@@@(V3   @ ķh"ڭZS@wԩv{={ڏ?cQaݺuhRA`ȑ#cǎ1bDҺ &ٳ]]y-.aKe[믿Nw{&n;^x!먀   E[}~>@@=N`ʕU%J{{=oe<*UdYYYϩTP]oݞ~iY=ca~lEuh/ڨPB|>~m{衇Yb':PF>Q&=V\{"z>GYrʨq'd51=Q[9^AW_}O裏d66l`{/n/8Z%df   &@B#@@I@[mwŪ*hߦMܷo__JsѣcAEÇۻg;8+<W[ƍk/jl2_^x=SDm޼O*P ];wm_:uXvkk^zQGeJ=-?l7tx^/ǀb^|W4i^lѢk&Olw}r?p<ۥK;蠃bt䔨6n8Js9>cobŊPQFs)^}6qD8pom0sL3jG?˗mۺq1D)@.wuwa^+JW?9*ЩS'}=x䡺VcǎYynۦ?ܔ@EDc֭vh[aj/ҥKZ⋂t?ߍѤM~{ュ}6~x guop7zֵDӦMA@@@'gO   ¡DW܇s_uG|S볂a2V+|'&]ݭ:jղgy s=իWӦMI?c ;} pW[l jSr) p^u#IߎW_pgP[Agm5uOa"@>`4B' $nҤOhXb饗^N8,X`~g8-Z^{5?Vƃ'2lڴ)ecM3f 2Tu2)h‡w饗z]\V.Pfo_=[o/ $O<>Շ\N;=ae˖q@ݻwokշ2e?#=_>l_ R@IDATG5IB 4@_eРA>A[n=@sIV fR] k}]zuomvfM^P^R@AW;(J:> zkNDvq|z&fiBφ   ;W Ҕ;&zG@@=X@ǧ~:G/PPSN1`*m7ҵ#Fxv*8!⫖` UZ%:J箕ZJ V^k%h%Kl7I@k5:ٳjW[E+ٕ]uu:=-K{*D}ǷWJ뮕*^٫5CAe4Ibl/ͮizasЊ^5k-N/Ceг3PQx N+ ~zZ/#o[{+ uO2}hzWHW:RM6H[Ե_~sWYYY zύ"u@@@(V+"   (zM7ypW{+ѣ5ⵊ{ܸq6p@FAa˼V+`=y?}U*W$ jLѢָqc<@V+P + +5{tsX1ct^yW\AhQN:{UWAd L>ݻ{j8YY B O]uWD[.ȃ St_WWZ+'7(hrfOqV^#և&hlȑG=jMGmiWd+QIC['DX24~S:I_RS@@@@` lקcIT'z.q8R8/2Kut\x:~Nd{?|Q*'O.Ja,  iZ*i3学􍝞~P@ꖺ ߑosSmߥKzQ*׹- P+x* 6תq+u>Ap^?ߎ8e~4A+;wlǹyXC=`z|?rȰ'z)az5D@wyN:GK~sxh@@@ )ΊK{$8 iϿpNs=XR WNTwS   EG@+[`oL96rZ ݤI+(M cs4lL{'cn^zm+Vnݶ<?nJӟn$DYt}ty%}j+Qu.s(h@@@R O÷   PfbC([?>97 +~aonj^"~GKvRC@@@vY        N p@@@@@@@ w       N`O   6X.]LJɒ%-33ӪTk!    @K@@]+fu5^ڲZjV|y[d/Sr    EJ}rֲeKT-\>ۺukWS @@-!C|Æ zٍ7ӧmE&    4~gW\q+Wk//Fe[lI   klܸ̙cM4 XWM6q    '@> /0: kӦ  K ڌ3sϵeJopBfU     #Vj{WiܠA9  *={D6l`uֵXFFƮz[@@@@"-P(  n+Vn%KO~-/A@@@@ ~z/CݮG}9N   L6os%JLSF*     <oiAקV+?p5_#  k lٲƍ7oK믿Zҥs\gBfu    $@>>/7y?Nyك>hC&@@]]@{vYwa    <ŋ[ǎL2^M6 kxֺukS:Q   oڴ}s*͛7Zw{d    5IHZjIt-oK'@@]T`֭6|[f 0`=zty     )']vo?]n]T   + +V.b[zp/:_rw@@@@GnTrҾ%J24m-*" uf͚ RJS@@@@@ XqtҥItVV@@vAQFٔ)SV|Imsq?,_zo7c\    @`}1o<[xqow~cqp  lٲf͚ewm4h`r.]*UThw=x`4i-Y6nh:pB9s׮][h#@@@@ RIttС2e$el2駟~  J6m Ga+V0/B{m͚5Vj[}gsWÇ~8O>6l0S6-h;zժU9f7Y4"gWdI E~Wg\P#ӕ+WZ}rIʕJ*V\P   y`} ,/2鋠}|  K (ژ1caÆo[ΝM* ķh"ZjԩSϷN:YϞ=̱¨n:&$*z#G;kĈ@܄ l.[s)8ߥK4h)Ýwi/廊9:~@@@@ /zτ!  4kS Yi󵚸0V1kA%;nf+[llJݟ@ӵ>hWo~j֬i=X:{X*(EuMHF 6GzR@^*(U/-U{.q{w%Yu>ާZj9NиݓN]k/S?*DŊ{﵋/ثď9Y_c@@@ؽH{?_@@\ vWuZI\E[mwźUоM6o߾v뭷==:]ǁ>|~㎳+ƒƍc=^~eǧWm*_ }SO=e6l͛ѕ^ TY:u]vv5lիuQR]$֯_ig馛|҄%+c|-_ܫO4k/S6h5'O~p |:(-AMNʋ/hƍ>s?o&mԨQ\/n|M8[̜9ӯ?3=cO>qDTtcǎjuֵ;ʕ+g?ֳ^9,]ӳS|ѽߠ~[&M/-[Cn   +wG "  k hEs(\_>3{G{?krB  4xIWwNZg?nseffzz~i|RϘ1Î>h{WCI k<[l jSr)M68Ο?Wy>߷jfJ*e .,`0oq^ce<}"9ŋʚ>}lٲeܕY?z'<>g}ǩ* + ?~.5b:F3:&$K,C|?|F@@@=Ku-  e:ꪫ/&h&([z_kyhu)&Iz>ae˖q@ݻwox~ݔ)SugKG5IB 4I@]EGJ TGz_/ݯ2(&h2CX?x ΫdAY4DM"ma?I>@@@@` p{=O@@]^@ASCYvm,5y8{;z.ѱhUx( j h  BXN}7}xZVaÆy`\SH|Zѭ sNbi/7uڐJJs;餓^W;蠗&c(+%Ъ{eAHԮ]ۃ ?MrP>UWy+kA@[ {S9µsPB&8   {@){s   P4URGH?SL)ص[/훮4cĈ]p&(|!~OzoݺiV+ 3ƴZ_)DJqWdɒ& (` Ƣw]={JAܠj+h%R«SǺGݟe={Oşv}nРiմ׽m۶ Ic}iVtm;,~֬Y@w4AB32_qZTe66u9UI{Hm%+C:[vyG@@@Ss@@eH馛<ܕ~~? kql<Ս*(]vWӾ X;]{ʕv|^uϩָqc`GWN:{U[Ao Kwׇ{ge%%|O>ٟƣ"wMPJ{MdPOE]AwrOh&b˫+?x`?VF`W|o޼?3m УG?m/?y/?2J0ְ}AƗ/9D@@@!zkxOW2m"   ;dMS}~~m=u}qx_89zp+Q'qs;҈)@@@#J宀l|7QZ=n9 A-ZX&Mt7/}C[c$(O4ܜӽVXaݺm?y$땦?ݢIYtmd}%Wnۦ>   >wgɝ   f⍖-[ƏCCSwaZVQgQ<+um@KLBS1Stbe|FyH<xB * ܫexgfzyNYk=?{Wv1cxK.mׯƍ#V 7 @ @V@,7 @ @ @ @M$ pD%@ @ @ @! p @ @ @hB&5 @ @ @w @ @ @4} @ @ @;@ @ @ @PUk @V7GnOy @ @4F' @ @ @^@zW @ @ @ @@ 7: @ @ @ @@q_+ @U_G  @ @-H@} z @ @ @}{'FD @ @ @-H@lJ @ @ @O@#"@ @ @ @$ p߂^G%@ @ @ @' pމ @ P"0}4`tQGI&\K @ @`_=ޣ @ Z | /LƍKӦMKOqnʔ)^H~zVg0 @ @-WU}tON @@sXdI5jTzt7xcСCW\XcsuYhQжmۺhgϞ:w\c ,۴iSc8gΜԪUԾ}mN>ô;ybBԩS[oh}Կk @ @B@}!aK @@@|^;>}POGyd^Ȑ!i֬YseT;wnĤr%^{m߿Wnqߟ?6smBfΜ y4lذ駟&I @d @VIFZkۓN:)}٩]vϴ3fT״~Q"=\pA뮻Rn-R\v[d"c%F0j):SZK/|t 7__|vbE"۾\qOg+N"?Ul|UXu`EVTK7ڿo򗿜ƌ:vX cJaU|qݖ @ PWKUL} @M mw}8;\{믯 Wϝh磌JO?t>s9(m>~X(6~?gDc9&y?OkTXm׿NݻwOp@:Sg}ϟ~i=H i͛Ygf\?#FN:*o}>}z7n\` RFPZǧ_90ݻwtg4(mv%<_vew9Řq00w_L2)fK @O @J(͆.͸ {%tM7Mzgq.]*'DtdatAfwG 70}9|뭷_i9p'x<) ?sk_ZzGҎ;p,^8#mF<ص)={L)孷{t?14Ӻu4eʔ@L0KGb2B M @ @- p_o:7 @ [mRӱ|<~imYx+.i0wУDP7HW }Z{~{#8X+ȁ6%?O8"c0`@i.uh#ĸ>8?k/&cĪYȺUjS6hI_Lr$PXUTWqwiݪս_bՃ3 i @ SSVU @ @4뮻{w,U^zCҿoX=2ߦڣoQb@war+E|d2Qg̘1)2#;c"G~dGiӖ$XbE!Cq,A(}UD&{,u9c?1J<_xe|Kjok&ۿ[ߺ@}l1"$qs7fΜ֦Mvک!2/O?4>oEf~Lٳg6c(j@Mce@=OB @XQ+*~ @T guVƷc)믿>;vlWL~1 ǒw\>KGo[zꩧN8!o#fT Gݪnmmb9ȸ@u">{;w\tK]8|/s?>KtS?#-_W}8U R\7bj}DŽ [m#ub±N @CTAo^o?/~+7s-KU8~Q|:k:W\KJ-#KKi9a"[}Eg9s7OBJϯxڵMi)Jk\7<  @ @j+ p_[) @X"[>>]G)u\~ @ @@ RFjq @@KXpa5kV,XϯcV{[Gk#Ӿ.uKdG[  @ @Fq$@ P_ziɒ%eXc5FmzZ?N.tUWZ+}SOMW^yeҥK'!CO>9me{7?<̲׋sM#GLQ?[l;/}4X޾iar2 @ @4@h @ ;闿e7DK;w^n3g 70Myz~WymM7l'&i&EQ"߱cǼڶ{2f̘Ժu5+ WwE=EeϧWlNyKN @ @X_ @ PK/1ܠ}4A7;:3V[m:tH^zi߿7iҤtGV Çx__neӧO1Ѡت Kק1(Kis{ @ @4}0j @@D'Xm{^]΢=3=yYȴ1bDǷ_|ԧOEyE{tK.$gG{w3뮴ۧkfK>`;6c9 /Lg}vn_~yEGfmn馴I('NLzʓ[{" ܞ @ @C@hn!@ И/Ʒ.xoϷo>{>2rp|7L|As}޼y)Lm&/ŋ.vvFK/N;t}ShK7xc6mZHzhZwuR衇!j[aVr )eR7QD @ q !@ аE>Z}s&{m3KGF@7ߜooY|_|EewLlAsAec ڔw}7u=}_ϿȘN;ZjbA|+5\6P޳gϜ?9}gi뭷qlWn]j* @ @h,ez. @u}|w7MǯAwuלaYQ"x;T۶m#Hu6xGF{,'O8_X>׿ks=#k׮y)GX?Ώ%˕vG7ilp @ @( ~U|kL Т[ozޯ}kQb!Cҩs{lZgue>(gˏ5*TJÆ KY\rIjӦM:s矟ݏ#rq_ҷo4a„V_ZPf,W% @ @ 쿔-h:b[bF\l_ԉH)\6W|Wl?Ŷ9B j ̞=;%g°wd~sٙ?~ ǵȀ|'r|jU)=il?eNkK?OiN^|錋R?yg  @ @]߫Ttp3蟿eqE_Rr8۪ŹKZ|ltdWR!@ @|M rZm/ۮ˴9?{N @ @X @ @`X\1]ͫhK!@ @ I @gsSڷ&ڈ @ @ `F@$ @D:)?R;u)iAhcMB. @ @@ko& @@Z{,7f @ @*# pʼ*%@ @y_[C @ ""_&@ @ @ @" p\ބq @ @ @ @@oC @ @ @ @@so.o8 @ @ @ @E ܷ  @ @ @ @77a @ @ @ "Zȧ @Z@ ZSzD @ @UU`bߑ| NA @O5wbD @ @ K @ @ @ @ ] @ @ @ @/$l  @ @ @ @@7.  @ @ @ @@! p_H @ @ @ @&ot] @ @ @ @B@ྐ%@ @ @ @M p$@ @.\f͚p `KK,iVYq; @ @Jh @P`̙iҤIU[Ю]ԵkԽ{k ̙~޽{:Two~tgVWeXSw5lsMC I7|sZk @ @r\M @X&L)ok^hQ/R۶msӧOOrJرcj쫶ϟڴiS9 ~V] '5+wou,X+squ֕c  @ @Z@ælKOO @`ׯ_ΨnБe?tZytGG~4|_]_W_}uz姞z* 4($hcI~i8+T6׿5}80}GJw"cks?˕?0}MyZxq:K/;6u])5jT߿^Il*;kB @ @:d'@ +,ȑ#Ӷn[+w}73&]z9;#miwΙ55{g}6WyrO>ISNM]tI1/3f?|'3?>/g},I{W{D\pau9O @ ,x| @-GNШk>8qbmҖ[n9JG"{뭷NӦM˙ovn_s~7S 7ܐ7o^j6l;s{\;ss=L%2篺YnݺaÆ7Rp@of;3 >%mDYfCBd@IDATݻ{-##\1nL",r%&*r!}qO>oϓb ]w]zGSLh׮]^E {왗}ӦnZ  @ @(`y\$@ 2"x_:x㍵^T&_|; E]n*mڴI;SarлSN9P{;E<2#1G>x"ɹX>E?㸧mGSdG>0eʔg׮]b|_x_},9_x/^&L{'6&( @ @ ȸ/ @(X>%LgqF='|RME0.vmu]SS?dȐtꩧz(7sǦuY'gGe]ڏQj*_5Xb6|[J߿> oy^2NO?t߸/#W @ @)=Wn862b[NZŹb[+~_>mΈms.Ǐo36 @2{][g°V&Y;+b$},xQ>lrZc]n , Z֭W)l @ @@ſ yE-.s/sV/U\תc%ts5߸C @ DFzZc)2+5]  @ @Z@d+ @ @ @ @@ 7n  @ @ @ @@{@ @ @ @P@ uM @ @ @ @ @ @ @M( p߄&@ @ @ @ @ @ @ @&oB|] @ @ @ @{ @ @ @ @@ 7!  @ @ @ @ @ @ @ @ _ @ @ @ @ @@ *owd @ @j' vNj @ @ @ @FoV @ @ @ @ I- @ @ @ (ªQ @ @ @ P;9E @ @ @E@QX5J @L>= 0 uQiҤI+Ҕ{  @ @4{V~H @@ |iРA)JVѣSN]ns_|EKSϞ=Sns_SLIsIwyg:Sm &@ @ MO @M(k=z~'iƌs9 >mڴ|m۶+uK,IFJ/rv~7V:4]qy'NL0۷oQ5T .!+ @ @CR= @&AlKV[mztW38#cѢE+m_#^Qdۗ]\/Ƨ?4q駟^*_㙣ݚJv1W:gy&=#W=..,X`.W-SRm+Ƕ8kUS]5Sڦ} @ @@c X*dK @ D|-L=\:s<{ߺu륂 ӻ[Uw| pEs禟g)=PIwISO=~ OL^{mZ?M1 V %{왗?~|/~"@yKM(z G8mƍ6` X\ΠAvmW<+;g„ )$=cdϹď ʕwnc1ų|͹'fs_~^=?=)4o޼G].,aҤIiٸt}ݗ&?&ʽr @ @1ZӘh @f'X6~vctqGQ5T.2£Ҍڌ'&3&஻ʁ;#miw6{h;>l>I '|]tIkv4GDpL1q`/^jtA)qobLRu &Tv}9=z|_B:ꫩ_~K{⋗9/ ַ< &BT%}d*p ybF q<jԨa7g._y;|LF(2GUqdDiz4mڴo"s8~7sw# C=4u9w8g}w5:#RXD{R]{w~_G}t㎕Ya[/3|ݻn´( :S$/_~dAO,V;Is9F΀I aA6,I q_8^|dzyEbAԉD~>սǺN @ @`Wϭ @Vu'x"g1>G,=]Ye̲>c .RzjbBxre66d6?c9葱?{8G89_J@վbL|ԍyWF1'?ɓ2:t萻- LN`wiz\zt~Jn?)Ebs+ <9Az\\.ﱮO @k+ @L 2ǎɽzʙϑi2KXcXb=]Sl%ף`[ϹN;v!;u="=ec@|SYm۶M1 q1F3c?1q ={{d,ߠZk;ńCIJ^򗿜bbBW<_dT"+O?t>~X6Ąӧ >}Xor&Lֈ>#K>=ƹo9i73G'Qj8Q0=A @X2W" @4'"~7"zYg,82_}S,14w8\-I?䓗%D9m]/۷o_9!CSO=5˾[{,1X>{NỼƍKo}W]۱<|XX~?gM+&T}8&m7$&O׿_|qޖ/,7tG;QĤh3&V~||^ &PDҗ/?s@Сy_W /0}1ajS{̝ @ jת \ss-~Z_l#~q./~oY+Źm췯u;o挌6+  @%˧ 4}& <5ةM_}饗rȲs|}yŘkOQۿ9k{oQ/#2xq!p+ĥmǵ껴Ȃe~JVɓ' . rϽ{/L/bAӗO*JG>cQǖ @hZP1*~*~ctů,Ŷ8.VݏE)K?ۯ\q-ɸC @e D[o̙FG{Ν:2{ֵǯ1K`r_M׊:ݖA:G@-oXn&U>WR!@ @ PkR @ @ @4}Ûj @ @ @Z@T* @ @ @ @oxS- @ @ @ @Z ךJE @ @ @  oE @VP`i騣J&MZN @ @y 7ct @Z_|.4nܸ4mڴ4L^xt駧>xxP @ @#Ъ<'%@ @ ,Y$5*W:opС+HkF3gΜԪUԾ}VCpmuܹNc 3gL;vLڵT&@ @2W7 @BիrGܧO G:2U ӟT[c 7ܐ:무xk5o+=}z8p`>7ԒҶmlVSiĉO?jV㙣ݚJ'=2KW:[gUZaҡC2Aqޖ @ [O @"߶#%p@mrvv1?s*nytG!Cϝ;7g?KÇU)çz* 4(ms19qL+Kͤ_`AwI q`~1b[]۟y:裳a裏{p5;<]wݕ"K;H[lEy睗/(gͧ{=O>$M:5u%/OQ{M\pAKR[nL"KO< zsAǽQ"x?1fw}w0z+ T"3LW\qE|GӉ'X-Z8z |7x<"?.1}|_Iv @ @j!1  @iw`2_?S_t殺MnG&~Q;kYXz>2r|ȑ# GzĈ9zӴi䉷~;8{ 7|3E;}͛3=GBg}w#?E~]tQ8V ({=.;cdzmݖ[o<ΘpPZz왾oL}Yg,zW馛sqmСyeX'L7tSylN=_dU4q'?I|<_bDL>R߱.^8>`mɟ9"p\Qگ} @ @ T: @X=3fN8!<;zDeחWj_/bG~-Dv))2;u͑)& ķԽ{Զm E_T|=<@Sd~c@OS]ӿ+\C_}{/)&&Dr%V?~|ΰ k޽od$x'm]ޏ 5\"h9Ώz>b|z: > @ @˦N @hF9E%#peXϏKGرc矿80q]O>y)cՃ`G@:wuԾ} 2$/Cv=ش:tcE#},w]G`{ܸqiҺq\w#Jҋ/t??2_O?=+/WO֭A~}%V' s;Nv)6 -2BW @ @-Q`Z}zw%U͔Zqm*wo]5F?}G>|xV˘n#8]zm#koĵ껴eG17&drc7o^Q @ @1߼ߢƹbIɹ|l*.kU׋R_ӹZq_Ia @@g"%{4QDw,k3_c5][1?b@3c7R]U  @ @e"k]!@ @DkÁ뫮*͙3r rs 1cjwZ @ @M@}s{#C ТΝz}/}_:g}:vآ}<< @ @Q@V= @*+ӱ /f͚˾hN @ @`q@'@X{imN86xԹsc; @ @>ϻ$ @u&L/^va̗q`A @ @} @{ @ @ =! @ @ @4cfr  @ @ @VK @P}G'_Y  @ @&q$@ @ @ @}!aK @ @ @@@ uI @ @ @ ߸/$l  @n=!@ @X:= =  @*,Vg @ @WY @ @ @ @`_^ @ @ @ @$ p:MB @ @ @*  @ @ @V'mz @ @ @XWWf @9xq5{ @ @UF*3R%@ @@KR )}>nOݮmJNSZ\M @h4z%@ b-Zϯc0ZK,Ifͪ_uΜ9i޼y(36G{>z@mȼZ @ @&q/@ @̙3ӤIRV]vk׮{i5֨t{葆:w\8w4dȐt7Z\eν[y,?O;=q-2^oȴ_~͚kD~d+ @ @^5a  @ )0a„t}d:_|Ej۶b2{ [o.t-SO=~wj?QׯX%~ʹ`Ժu',m6>> Uˇ~?<-q^z\mر鮻ƍ /LďY1:*&/#7pC… ǩ:=  ųs1O?=p~d0~ʱƤxzҵ#SJݻ֫ 7 @ @4/> @@+,ȑ#s6{wӘ1crF}]wtw.]}77Y]w]:蠃fG|ǎ{wf̘> O>~n=ܓ<@ߔe|cԩSc*=\>b\SN֦M>t _29LWI'ONـzuIiT1k^ @ @ X*#"@ ${O;,A5hL81nqA">#<2{o؎'M֭[6lXs=zpkGo}|C=xo߾yx`[sF/뭷^_~9h(??O6-}Gs1ֿoi޼y):@cA>}L dyr0aBTKO;s矟F'!J܏;/_S_&VL* @ @@*їSz~q./Z+mdW/ŶE؏5sŶ8Wn|emeyxF PF I׶0ľ#+ekn5__#1KMU|Co>wM*Qӻ;;)}U_L7tqiW  @ @)P;*7蟿eqE_Rr8۪ŹKZ|lt&R @ *kRS? 5]Xo/) @ @@d+ @ @ @ @@ 7n  @ PV`qjmF @ @4{f  @%ܔmD[  @ @@hGh @hIIx!#>ƚj Om @ @@7^  @ P@Z{,B @hf @@dקD֧? @ @uWP @ @ @ @s' @ @ @Xa& @ @ @}I @ @ @VX@~ 5@ @ @ @/ p_;w @ @ @ @h-h @a'{o]5W @ @@-{d @ @ @h>]  @ @ @@=2 @ @ @4. @ @ @Z} | @ @ @}yFB @@ӧ:*M4L  @ @V= @ !矧Aؖ+ZJGN:u*w}K/M={LݺuK}L2%͙3'yO:th5H @ @`e ܯlq @hkFѣG'|f̘:wӦM۶mRFdɒ4jԨ/_i7xcСCW\Vy;-J1I-eٲC[nl?L믿 Y.w* @ @T+`ji\ @ r"p\rIjR޽u]tgdrzܮB<yy!CYf-ϺV;wnb[o>:]p禙3g.s93Ϥ kU  @ @z ׋M @VOX>2\_x r6mZkI'>Ԯ]1ye5D92Y^{m ]wݕ[V'Lk$7>|{6kOQPWwou竎h'ڭ8_ο\h[ @ @@C X*EG @`[n{t`nk[nTм1^xazw+ ;\{믯 Wϝh磌JO?t>s98(m>~؍G1c  JrJ^`ر#8b~;LdDz'OuGQoi?An!=䓕%/{,_]ۿ҄ ҼyG}v.郪}q/<8*Np ~_qqwVZ"aU0nG?R}iy@ǎSIf݋:uJavU~B!ﴺos9'E h+>G>6p4nܸt7u]bI> @ @@#+$ @@\O?nGG9Hצ(t-Ji}qc=7tSo~}m.]*'Dfu|ࠃ*p@r~s8;s?~|:ujޏߟx3gNk=ܓFY:?# _?8=#\S3f;3?umdoy}z&ć'B3&N;y|\1a$~*C @h,%]Φ{Xǒ=$[IE))TJ**-?Ee_Y%BT"Eʾ0s;qF.<{9]g@ X6 nH#f3-nAطzFH; ( K-dgV_ HuVߖCfJoAb ֯__͚5~/]ҥemm`9眣 x#o߮+ʂfd[ݰaʖ-cuYzfE^Ec3 tY4z7fǙCYZ-Xolfpxu4 ے7o^;111opz#-ͥ^sze۔nݲeK/ŋ{3gf$v̈́+hѢE:svСwnj׮;N˖-f65b6mxJ*y#֭뵭ZjW1عTT`e;kҥKN   P} q@@::Fwf 2z92.?=~x]Fo༿OynZ f=zX@UVqYH`nݺy#'L `onb+aÆP_lo ;v?~饗d@M9om`kժի{]'}m-0oӵ(}+笳nSǏny[S-6A2ecb GZvNl|]ޖӽ(޴iSZ}VXnm6/Y6uh7nVc,poicu3fWu0W{]6-ͮ 39FQΣMooVH)R։޷CX.\)!   SS@@ p[n9,MnUܦ׽X F[ wޙTY ѯzo-hb o4mҥH"^9HκX5kʦη6۾[,|W{Z`ߦiQ6ui4p@/lݞ,9زn:VFx Jg%tȷFϞ={xBfim|[4i):Xv b3'#˗m۶oFmky\2ojʰMߵkW/s /;    Y ҄ooocUoufغ z~)]ƍw֍! DQ9>ć221Yga_~e6(jժU heZ(feeժU޽զ9]l9=>hz+Ǧz}No@IDAT7ɚFyfu Ǣi}o-D:֮9i l{e:Ĭ߶y6g]_o6qA   X0vɒ%69|QŊ tHmMnu ZB.rwe;JJz`ۨ~#`?2"k#/Vӂ^+?6w2tѶF@@@-J~  ,8jӞ{5-H{?VZżvMdB-?xXA    aY@@@ zy#mԶ6ҙ@@@@#)9"  0`&N 6ڶ3U    “J@@8P={h֬Yj޼7~ŊQ&M… h    0U~68B@@&;wNSʕuqǩcǎ^֭6ڋ    ! pH)@@@4@@}J,oSO훀-     pPTN2C@@_.a9G@@@@ Ls3@@@@@@@@ ?hd       @܌#@@@@@@@8hQ  4P·-Xg@@@@ 0> {@@@@@@@S       Ga       1 psb @@@@@@@@ 6A@@@@@@@ cNL   w֬Y۫]v_NV    )@<-T @@@jj|I}Zrv)۶tR͜9SwyoF    G@Q  G@ZZ^x͙37j?|A=sؖӕݻw{͛ClܸQŊ >'f֭Ssd[Y>v.9昜@@@8jqԜJ  !`15Q9k&MҕW^M߽{wmذ!k{ǎ-(tYd:t~!C$HZ?_ޑ"RA;VC t    Q'@;4@@ڵk'Oʕk}wU{˗Ѹ… 믿݊m}Qx *] >XF6=>>^vɳ[N{G6^ %H펖ә 켄Aro+Xb5Aֺ@@@8g:!  /ަG[sQ Ceh/#]Ǝ,+~i۷o~jԨuhҤψuFRrr٣믿^gJ9rqF962ަծ];/Yj|Mo b0 b;ZޣGs^^fh2j(z^ݭsaڴin,;f33xmo߾KoXY@@@ yڍ  ?DPB5:;cG :< zodɒjڴwqԹj:^e͘1 O2E't1b-mgyl{NZ>{ϻe/6_6uxwQj//hG;.bZuk{u ~͚5lf[oiܹ^ &hٲe:t^yo??@@@@@¿Ѵ@@Ln@_^@/@׼E4іo_J/GAo#ׯf͚yx+F[6?3msF/X@Q*U-mjeҥ^ʲcֶ͛kڶmf͚% -Z {nKvy[ǀƍbŊa]wyY{զW\qEFVǧz{5Mo'?ߧAwoͬZj*_VZ .:XV+Vhĉk}"@@@ yڍ  *p 'd]nx`ZP^zlߐ屑Xڂ{zmuV2vm6bݺuF[`ԭ[m'D^c#Y6ucXY7p& lAԩS^{jժ%?'uR'    G@)GS+i   c,iy6b>Avӧ 歿K߼Mgo#m`-\zu/mlM?_T)o$M om6-|r … ?z[m-6-6~2e@ciǏ92SgKgmyM>ݛ: 2{5GN:^̬}{:،dW׼yjժޫ>/ʕ+= 3W lқM ))N6 ƍ=z4   [~o   pD{eoӮTW7 (q d;i L{{oA[o՛FҥKH"^9|oc,]fMo|o#ORTPA:t𦋷 VuQ6i4p@/hmӳe[ l[ۭ=Y>'OʲYnfuY\r^{ݻwo۶om*1c/M۞={7]m:.D,    Q&)MH6?Vۈ6?mNKo S .x}{dG2nܸ#z @@ w]M|(#-Xn>gƢ}t bSۈ.䶑6:b#sA֎ `#U07   ڻ>I;c1z_Z6κnc%HOi=m>1>@@8ly:ߦqZ_źˮwvd;-*hoehuz    =  "~+aV'&%    aY@@@@@@@@0 ?L       :@@@@@@@@0 ?       {@@@@@@@ÈO       @@@@@@@@0 $Ʋ)@@-?tm++CھC: D@@@@ 6+"       H} &!       q%W@@@@@@@ D"@@@@@@@b#@>6       @ H       @lƕ\@@@@@@@$@>@@@@@@@ظ+       b"        pWrE@@@@@@@ @L$B@@@@@@@ 6cJ        pD       F}l\@@@@@@@@1@@@@@@@+"       H} &!       q%W@@@@@@@ D"@@@@@@@b#@>6       @ H       @lƕ\@@@@@@@$@>@@@@@@@ظ+       b"        pWrE@@@@@@@ @L$B@@@@@@@ 6cJ        pD       F}l\@@@@@@@@1@@@@@@@+"       H} &!       q%W@@@@@@@ D"@@@@@@@b#@>6       @ H       @lƕ\@@@@@@@$@>@@@@@@@ظ+       b"        pWrE@@@@@@@ @L$B@@@@@@@ 6cJ        pD       F}l\@@@@@@@@1@@@@@@@+"       H} &!       q%W@@@@@@@ D"@@@@@@@b#@>6       @ H       @lƕ\@@@@@@@$@>@@@@@@@ظ+       b"        pWrE@@@@@@@ @L$B@@@@@@@ 6cJ        pD       F}l\@@@@@@@@1@@@@@@@+"       H} &!       q%W@@@@@@@ D"@@@@@@@b#@>6       @ H       @lƕ\@@@@@@@$@>@@@@@@@ظ+       b"        pWrE@@@@@@@ @L$B@@@@@@@ 6cJ        pD       F}l\@@@@@@@@1@@@@@@@+"       H} &!       q%W@@@@@@@ D"@@@@@@@b#@>6       @ H       @lƕ\@@@@@@@$@>@@@@@@@ظ+       b"        pWrE@@@@@@@ @L$B@@@@@@@ 6cJ        pD       F}l\@@@@@@@@1@@@@@@@+"       H} &!       q%W@@@@@@@ D"@@@@@@@b#@>6       @ H       @lƕ\@@@@@@@$@>@@@@@@@ظ+       b"        pWrE@@@@@@@ @L$B@@@@@@@ 6cJ        pD       F}l\@@@@@@@@1@@@@@@@+"       H} &!       q%W@@@@@@@ D"@@@@@@@b#@>6       @ H       @lƕ\@@@@@@@$@>@@@@@@@ظ+       b"        pWrE@@@@@@@ @L$B@@@@@@@ 6Gs>-6d       p? E"       39"5       UA$3@@@@@@@r&@>g^F@@@@@@@ ?d       @}ZH       8bGC?)?z       (LjO ~<5@@@@@@@ȩb۟ICR+Đ0CrR.lR+WV|?/D@Q!      ^ '_?|ky%9nf׮]4Ο3_d@@C+`[/11Q5kTҥmᔆ    #=pye?6m P  (-[h̙jԨJ(q$V:!    '0K;.؀dG9ICKI  1EQz4gΜG     pD $VGb>( R  (\vu D@@@@8r?>GR`p>q۵i&%GRi&mMs?,u2s&WmTvWM"徟K^Վ$MZ7m/s?jl2A<T>IHkRq"g]%E]Q<"6o[yM)nWΒ[wsjuڷFL~$oo{b >i~[;rvY=;Z5s_~;9s"`#m|@@@@8?|6tu;TǪpa F=BW [245.VJW>^ Sg _8C]Fz]9|oew;x_set|Y^@s^أRdy_,R7l5׍2Nek謖}5u:y\fZ\*ray9ʖ*}>lFq69n4 y^Zu plwzpɇ.~돺߈hYm /٣m]x>% Lϱ;R8@@@@@o A&۲ _M?߇;p tEܞbT9[H-5٩QZ)7niz jq*uzҾ5K|'BP'k4Uos"UV}@M|2mO%`ws}zKV#ڎW{gʔ40G MnȜmn3WKVҪT/1Kn= 9O)P}rػ!HZf'@}߹ o{T`}39-G4kT<5,z10>u_G{/awR#X6jëP,#KK,}kV+QyFD/kyCz7:v㸇SF$@Vv$K^۵֯C{=]Yiv|t5y{FuH7Vr,a}XQJ;_':4Vlix9^,/ovmL DuOIֶ=$p8R5q:ZJ|4 @@@@@@+?vZv«4]1mp! -rv߮g?MiF/\@ɥukY"5U?=٪۷Uǝ}I^޶,ߡ7i) oK7Uӊi?t|Z*lIݪN*[ڔ ʜϿS]]s}4[T$i'KhXpzSTDq%$Vj\~*/# HC_Uj!dezY)-~G;f=F~1BQ}3}jk`c-Δqu\7.HWE/NK[Z\l_飐uKP:f=fw]x%jCtG"^l>^M'/V7x3ߒ1Ff<7ܛE!ZY ?yW?O:ƍtihtWu /kkׯޑw_fSVL|O-#LA 52}ƈhIZ8aHVkvB}1Zwo":k33BWwu߮=Wt7uEy~e¿F o̶%]/׺+sȬcw̟Q-:iܶ7u Ůzf_h\gWvߧ꫻/Uusiέ-K]I޽͑˲/>(u+5Lݜqo2c<Ы\Os$Luç%$p^yOj/_{)TҔoπ7ќCX~hǤ3k>cVw~yﵺo˜Id-]S}cϫ+a+ݳvTw,ٿ-%S3O+}ngOw љ'kGXÞ) '%] WޡS2|6/Q:svUTtH=;4j/uU3fɵmv_骾3xE5:ݽz<󖦿M} i#    yOl{}$>R6hAGKFUZI,>7 8GF^ԍDu{v+-uJ顋o\˺~uDּM{̧@tufcdS,z[Ѿ'_3z]vzgue&j5Βo\j\=R__@̙^zИ{s3W)d=|zyrW([L1u\iOݦy^TM\yLW%INS6gN~:!If נkM37Ao |?B'i'z7vϏꉫqSS{AOLf&X?sͨY[E][R%ng._I =<>ܰEkfЈnλC+wmV}W~ 65I~KK3B,ŞU_+Qٵ?1;HOW=K{yghKԲvskN围%ifQZmO}\So6./{j'‡h^OpANc~MaO틔tP=sm×]ufwnnzfyĶoۦ16DlN,8I]6IWѧZ9}=EqUkx5X?N[R/V_WtJ\͢_/.|m٥7l~(֐7ethX;jLwAhm^PO&kc\G=ylD.Z2ox7wǮ3E*UIUIuV)иnvfֳ6NJzWPGi}zq:I5vzPHv}ةww.us=Cvn҅W]EWؾ/ Q\jXut~7}Wg׮|{W|g+׹ ʇ-))њqYkWJ/5OȭT{ U8zUmU͛9=)bܕ9z L%M˟+5WsC2Tq%…ң*m,]ST jXXǼ+35:#a+sT|vJV6a~OodM:6!E՛ޓLm.WΏ>[N0T5b)ΥnǩmjfE4>;,8K߬٪2_֭W?ߧo eh}SZ~vrpO4suj:T]'mSRy'zR/|u|>\ޒDEi}pa3=KʻsgD3Z:e\lxw!=z϶oz]VZԻi7ѯ.UEyJ;-`F;Ν*om*F-o7ܦ{yԺU%]&pFͣ+4ҝ17' Xj>wνA -_U]k<]X,ƗyzU"hRXSWn%]{ <έ|>]:w-O޵^ Η35\5nIo tTYHg鈶~?Sz (ZsZU).`mORʺ|vzlr_%|%Yuήkz6{kK5wsZ?~?S?'րRgT]g^0{:(=~揢|^]mr:ܮ~݌!wqDbnPquy]wxy{*K]ܭ9v <խ u Bn_.@~CJo%F|%I g\__wt|BoR7pI6MLXz'˫׺cnS{>*[CŻ4ۣ^׻Kջ\+C.I) MW}7ګFH_ u ju> wcrf^w,{~FojXe~@~IS;usv)תIj}şZ{=:|C]9_gf wti-))UE];T״Ѐ}]Q;I lkm}zڠn| ;+qqyzJkSi.B WK}5uBe3=DFuG{];}]ÊL꿷N5oI{%ؓΉVޝZP\ǯ Ϫ뮕ߴ,w3*WR P     ?[_svyGZ>k >#ֳº|"5wxyy(\>cԭ%^^/5mXe!8kIDAT:>ڏdy7MB49{yE/{i{u B7ϿQrߵƍY]/=YqUi/S^v28!=N7L1{꫶ʖtuت|u [n=qZ1]P)W@]խٳG;ܚ],^p}۲ӝ\,M>ʣ"B8sk[rF+قQ.IFW/MRg!hAb8Z>]Di \GڕUbEW]_]Mb{2swSmOsg#nnq;3^+My|o=>_-5q'b]{隰]b J_y1DhObBqMjG7e rY.h{M[MInq_4t͓s*Z~;)͵ekv₣PBaQB2T* WԔ)ߪpw> EOKi;~Ψv>V'V]J{}qwnu%>Rܕ/!$tӶ+45jgg*^AQbiTTkWT$$Fuaom[^|=7dVMt멮;G6G;]\qiv)5wr#×PڮIp~a ]XfOirno1UG% ֧l;ӼFzL_{V7IwJj G>nܧR$S]$CO4=좷=l7nf5*=*uWޭS?hgoz3k,i֝ }3ǥv5@T5VNQAZk!!OPA/v"}[R݈t߉S3ɩv-ڽl/\ni_j]XuVp5ow]Gek)zyG/,߬UWazɊ+}Z]۹r,[ 7R~YTR.D=ɽ%T(ϭ ԠgjWjd:j:3     Q#U/MٶC5U"Ϻ-phm?V = u鵴|cÍnS6u 7XRhӦm=~>Z?)WEI5{x/r7T J(REN?卮 7=t#닇UڳZ݅*S4/]{qH .pk?qEN/ 7jy^v1GN٢skUڒ5`'/7mUӵ5> )i5v轇;K#zq.@)Y0h:a]sy%@Muh7VZ^+prSzFgH-Z4S>S^7A{!ɽWV˹mϝm~p޳mNL]Rzyޔ߫/8~Z_ޝTӗmۇq_֞kSvv҅!#s+zYy &rO G+wl iJTЇm^߾tzf*Vt]eNJp'ڹo)-Z蜺!c-O||ltISj^h+ȟ͝n0),SÊÖK/u߮).B5|}եI7׹i{A(_W|7ppiʧZ^rx7|/n#;ێ8Nx6ޅ\.Ш{s/T<Ԫ纩.떺a܆¾Yz:~E\ݓPQmUut;?"ޒf@g{N%i.tYJzAXmL(TDuӦh-yJuzV"6G=8cG:yv9hO ^; 5S=OZ*R\vgmkg32.5E6m!:nŞU+K~I)J.^&-޶k^}7,W߄+լڱjzgh7w !յ?o8^~Q/R?͟SIcnդ5͹V.R*pN%+~o*]<x;EFJJ]RyvUw*AznM[SQo k{@{J]4rR'h @@@@8:Zh-]}YGJ=ߑ3r5ޏ"FIyzv~;zUCAԲiވ^[nqgşxɿ詫T:{{5¨.hJv|k-h*-۪㫜NMOLR\纾f!횿7ћ_^SJ`u(Up2+7Ws4o޿؍\t˷p.[_z[Mׇa\W%Qz#t+6/uTP!3լ}2.?,RMSSu=۽hNMT^RUܤn$t:κ7lԺ4sib3B+\y~R݊6.-u܊{}-q_s܊OZ>Qݹn:J.w勻[:mNp)jtc?iRt/EY]lj>TRυݜhK4#EiϞ[Ԣ³n*GuɓuH*,J[lbmq?NTST3%uF܆rұm;.Wx[Un}y;j]4й[NtӳڐWW Lӛ"wB_J''"sZNYqQ&>Xt '/PNVZ-#TR]FTsgN?=zK]SeW\͟/:?}\_{~wo`fﰛ,w=eX?#y ?x׾ ?. @ @#pߩc[OU|q#מYOz}gw_W_qh\/R[~ǿ;?~'Nuo.~\ۭo|_׽&+i߮Kox77zgy ?Ӈ |_=縿{ @YK @ @e |[7~tWo~vh_§b0>q|j>Y1q]uū:8^[3W1+847sſW%EyWz3_n׽.~\.ׯO/{\ڽ^_~nךO*^{x^>MG_?PҢ @ @ |W_t~Q :,Vcܚ~e}]Wo{zעq7Z}٧U^?k!տ{ܩ_k] @ @ @ BiK:{7oN>=Zg{׌sxx!XO+yjk/'S o5oH{<{j=bU>^ @ @ @Dk>o'|j}+Sso>[=}]~57+yj=k.מ|֛S߸AsOcVϋb}I&[<~u*g=:']>UK=ybݧd38VqSuPiʸb]=fn#v>r |#Fk\_d}s_뾉}WOՒTz68W"@ @ @ @-tvzqf>*x̫?sYT{꽕kʻ?ӗwgG}z8=`u&14ljJ%@|־^׸-\ߪוytoi @ @ @1v|%_5S;Hrq>r @ @ @fgki]a8{?Z37=}PRkԓ?H98)'oYJogs=. @ @ @W g}kKsgz8so$ڵG Rq>UڕXk3W0Ua}ո]ZX|S^u\›ZY̾95 @ @ @>mqԘژgc猵bꉩ<=[q|q'=eXs^,qϗU>㣱WknSXR+<_9ך8Wzkϧ @ @ @%uGWٸǼO<^YǕ̏rj8}{/=L=ygM=r0?%?Wm٪>{==co\gL @ @ @/P{Z,ZK:o\Ī<}56OKWy]OX~TZz]zpBUȸbx)CYOO>ƺOy>[T8W㥫ԣN @ @ @) ƾ>{|ϧYoO,W=Wzjqjkk+{^{ g`{ke{\}uPƕ+֧\qg  @ @ @Ltz^k{L=C^OXk+Z~Zx+z]=7s۟Kwnyp_/@yo_dm^[WjuXZ]YzbU^We8GRǩ  @ @ @trc8笵_RK\5^K^1ylmjk?K۷y[rb2tz=]13uq}9zW{U}ތ{NOW^WϣY  @ @ @ p@QZ|j!|Ɖ[}~q+n]I?4!0:B:+s'f<S_!ip+|WzW^Rs7O  @ @ @ pD g5\'ŪS&c?O>=OO8\=k5+<:;B`x驸CYZu'坃b]. {-Z>qu;X=Ky_{\]=<>}!ԁsb1uUmAu֤o{厇U+>1O%8,ژ8WE @ @ @{,uܻgyj=V>^ƏUy֧XV5ޛo}p_Cyɬ{3ޛfl{ZvqG3q暃\^7b}9c~]*擞gbU׬6xol @ @ @@Mr72^5O3yA|'ߊ}1Uk5~k"5VۊE~_jɳ_4|g\sum󸠭x @ @ @F }bS&Oںr8_YZbzU޺\up_/Xcлju<:Lo3zb}9gsuUgXRוc8G173&@ @ @ @ȹ֛.,O☯jn<䉽?g-_gK}@{P{$kީ/ˡ|źz|q6yb%fu @ @ @D g}Z%qkTxdzײR;k.퍵.WS*98$1^꭫kA}U~P'22k=\8g{u @ @ @|9zӥZsSϐ)_Y^j}̥G$@ @ @ @zgs6˫,Sgz7qkWޯ>ROWfk}ܿhǠnvH=[{R}mj}\_dk}ko7Ixzoz=V8>W  @ @ @ p+~'Vo=\}גֲG1wzj.Xӳ.^^M^Xө%X!X9O_O>Nkcf޳5{ @ @ @ cl~e\q=k~||g=U˕|k}Cz셨/.}M?^;~j^Y^/η?{۪ @ @ @X;s[yͧgsY[[}^j==HlbK}.!SK^1{ޫ~8?:{SkY2,ژ׸w陯T%@ @ @ @Y`y묧fyj=l\K>G^}<9ǹ{L]~3w_57fKwc޽{*ǹ. @ @ @X;w8X=/M8C2U+ŅY0}Efѩ/z%+{Vϑkv_{e+Mbj5zY1q]޾jU @ @ @<8`{mc5Y_מukw x}3}o+7n}p_v<_g!Xܞ{>3kUyEjkko6z=y~gUܚ{g7LX{V'cM[{OzzYk=O_9ywֈ @ @ @ lcҸדWy,2צckוy4̥go|֌^jkƹ>kMWyՕژK!@ @ @ @sKڱdzj84Nkz;}5N_SK̺k=92{mP>;lSֺvcjuxo-NƉ'V=׬VsKI}=|?ȮYkRXWϣYlK^O^{d]R+9WU* @ @ @8.Pg[س4䳸Tʯ;{޳#e|jW{yz:X{׺SR?T8yX5kkm];z;qqޘ @ @ @ skoq#8XYOjX\'gY;鵭K @ @ @ \r(=[38yb=GYܪ=y{S^[k{yo嵇[gcgyjkq6k=/ﭥb]Ys5=W^f{W @ @ @|J(֌>3cVmk>>7R\ Y?k}#} @ @ @G4zҸד'3'zf-z}k+x=nqPwYX[g.^ ѸgmYǹוg:5  @ @ @W`z6?x+-lmU^W;z;qq~u|8srg%|;5 @ @ @/Y`@z[YZb$_Zו=ϣdzqk0y^K=c}m' 'O׏y:W?꽧GZ9 @ @ @=p^{|'޳~iҗz^}nw~˃{-qZk{ꫫqk[Z @ @ @x)[ҳZʯ/ǾǞquqo߸-\*/WXfެYK1G @ @ @K.=t^Z7>E(>87WqݹϽ}*8(޻R߬>8֏sR @ @ @xM[Գ6;eb>-fMK{G\ڸ`l|VkG @ @ @RwOm㞗C/clT[xgu|dߥY}]3>6㺭z~K @ @ @KǾ>yqN}ֿWzgsc R}mMkػ> @ @ @nuܬ>n=.q6{w}@|dܞڭz:/s{^y @ @ @N#GpkߥY}z6g=K5<#^@kKsڬû.y[> @ @ @'uYZ=76sVVH޵z]Z{.d @ @ @Kn'={/zgfֶӗx?v:>kk-/ omn/Mֽ쥗 @ @ @Gny(ܬ>/17^4~Kfm~in^ks{׾֚#@ @ @ @zkRl|9\{Kﷵnmҹ`OOGZ9 @ @ @^=k=Ε5K׭9P̗wϚk;^WN @ @ @OAaV彵;dlݵy|UOAk7;ro @ @ @#pUa޳uWn}(}a޵q:c @ @ @|,x]w뾙{^U{ >ÑGz hU_F[AJ @ @ @G*Hzٞk/gd%k:^r @ @ @fk/Yɚn|K;x\5k/>=/}V @ @ @8>5fm[쑽/V˲ @ @ @PV/m}:ؾl3|Ͻs @ @ @/IVwsj^x}}  @ @ @ @I^I^sJE5Qh8NA3\-BJt/ZD/.ڏLc`ƘbQX yX VUbX`]X/'t</7z4~_ 4>I`bB9a0 ;݄wD"A$L$&.#n&O;$IdK&EؤUƨT*U*TU.T%NU-P-W=zIWfVVvDZ:]A=J=G}4H\"41)=Ρ/蘭wk5-5Y454fjUhb` X8m^]}Y(?NN5OL`,U p=z39kgTɨn61w 625df1>||}پL~[g` 8>3pn ,(4$=X#8>xcP١'aan XV5oOSc7?G4M@'zHHadCbEmD8̉iN.. nEܝxxi|KjAe]Ic&]LK$7RRvO vRdœO2szS:=`*!51uOgvݟJ۔ qp{x޼2tg3zr~ PQ*3,skԜ#B at3wlEŢ\ܵ}p. ""iӄmR+/>f$88S}pf,YKg=-)m6>3es}2/m^|E.ؽ0kៅeo%.j*2(ZP_jU7{-޺_"XҾi醥_K%JKK?/,ï\}-+++]L 0הyv[QIuX߸l 77^ۤi/oR`kOnn^_iQY#Ǔ ;[szޮ]_U]cvvޣgE Z#;yoǾ}vu~翧~@kt~UojLn<2HKW?Ql\qTccE?!:{2䣖i-wN%zz3gΝ 9{տ9s=~6yݵۥq.^>y%٫E^7nro>}w%-vY˵胠mcyy''OV?s||C֗Jj7o:m.vt)ӁI5A[̖ ` :LR(r7P@"7!S[ P'6$t'G/*> 1/;a8Dvf#Kt?p M pHYs%%IR$iTXtXML:com.adobe.xmp 3054 1718 )iDOT[([[@IDATx g9eoU*$x$Dj<"FM&k`ļ#x&FP$AEE@@e=U=S;5MwOL,z H>gjE8@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@JHilo/         yL@8Am\|B@@@@@@@@@J/۱%C,Ky@@@@@@@@@@SG֦zy#|N            Z?y oVs%rD@@@@@@@@@h7w.)؎ L@(D@@@@@@@@@/(/f 7v}oy2@@@@@@@@@@}Wb}𽥸{xSy@@@@@@@@@@@Kb~/FwzTy, .@@@@@@@@@@(o`o8 }jY"          Pׇz5)UPޛ          EE&R^\o Gqd          @CH= =+/@@@@@@@@@@g6ޗPOIqrVD"         }[IQt,'ٟg!@@@@@@@@@@sQLxxRX@@@@@@@@@@XEu5}y33          $kSEiC?w@@@@@@@@@@. z߱܆jPc&@@@@@@@@@@/P jG#@v,Іdؐr.f\m!)@@@@@@@@@Q1kC".K ]C1;/>ST@@@@@@@@@@DBL !ǢAt͊=?#P4rF@@@@@@@@@7JyYէoGZc^ŘSwH@@@@@@@@@@]ҋ1'9)ּ3Lu؜!b!ܻG           Cz1`[>vnEqMuPl>O}Ћ          @qWz}^lYv ɋŦyz=w |OC9           sTK~K;{Ir(:{+{[>YҊ          PPjA1_A(No|5Swn*@@@@@@@@@@"|E=~ OAu~>?Z^k@@@@@@@@@@-P|Ϲark "i50s? )׸@@@@@@@@@@(А k׼a>kv?6׳k|̛9~s9          P|Y 1~5oOD})q|q-:A9Ї          @ \'ι' ~kݰ?Q3ǹf\s5CyM          PSu5yG+짴> [q[q7+9̇0ι̜QŐCԜG@@@@@@@@@^!ü#qe :z\ڷ>9Z/yer9O          -8/9'%\| ^b q=5|zSLP__vL:'xMD@@@@@@@@@@z;wwONv8}oڮ43M{>3 rW$^3,wnQm߸(:z=z 'Ny͏I7          40]v;iҤM6 vQ/t6q7_7s3L󙸰 n`_xtƝWf돣TN!C K           @=̙37^x=j 'WW=|?hM;\g/{ś":!D3S|P6}^c2fC!ڵbY@@@@@@@@@@ȳ_|f߫R.LM&atWl߯/J{F9@|Ǐ6nܸ=W,          ^ү_ RիRj\{{颶1isޯP<1ƙOԹ2EikշEunt           P<;5NzU.H*JϥMM9gP{0:>r\Q+֫0|6ęO2yզa)@@@@@@@@@@Ue'CtdwkΠL_v\XX}Pؼ{uA#|bڳmH9|LiF@@@@@@@@@@}D@E=wܯx,w^ɥoIknӗi5=>Sn^cbm* uřG2yicp! C@@@@@@@@@@* u᾽㾻 }k j_ǘ+O\Qv⽊ų(AqvLqA~}^6sewܧp?@@@@@@@@@@(vpk}waz{&X5abž+iqĕGy2y^e}Mȁ          -,D=q]^ehM 467g3}o_^cvss2s888߳>+Z;<ö{Źۂ5RqwF@@ϛ7O<@4h4nܸ"@ߖ/B,@@@@@@@@ +T.ݔbtZm>{6:FQǙ~s=5O8wx9ǵvy2GiwڧǛ_}`8yPB5km&F@ OsΕ-[Jn"        ^@vw^Ծ}^~mٴ1phM&&}]\x. Ksk#SWWp1}/9(6*v_ @Yfɉ'(M4iXɓ-        >'`wܷ km`>;ufl"2kL7u6.5b8{ -B vDZv92{n}{;־ft&G9Tj^{}ݾ~8=Nqz55301&~s }ccͰsdjw5;ݱv_k{b|o Xns̑O?ce@عs̜9S ®&.        #`q.Ps3=l8uv?WLlmvxlLza j掱5__P3;+.E`Ŋ?zYE@S7ߔƍK>}✖@@@@@@@@$ q.Hk8(m~]{ I.莵)ε+tę͵>FsQ8zҦMȉ$@E`۶m/СCQ#0@@@@@@@@ /`;ۅNܛvc}^^m9t9 3Ą=vqvw[{;6k=q@ 65kȖ-[+_Jls2 -k9_H޽{}        *zvܷ\ku;.̽WnӇ{DkgP_6qy fe`\k'(Ưϫގ֔Ϝ6k{+_\dR#ukvV];wD-ҧ^[JɆyReV[JnR۶Lj;VRԜ>ޱT^~#A3iJl?yuou^]`)++={{)G@i-;k         V~Mǵ{^Fkg3D\خMplLZayۂ1mxyFϞ)۷iq@ng$>m6˦3̶lZJhfg\gεem"vsUdʶOh?zJ]l~SnٲE>#9r3@O{N'کq         P@Uu\6;žs{}-~AcŽ]u0bc1pVA_O=.;wi$dZjm dۺ)ƚvaҶ*k8:3zDulYY6vRJzĻk_7>(:wT|Mv}w^S?)௪#mk:\&)w}Wz-zhdD /tROK_R3#        Px\~ҥK+پvpzf/)c&˽1/?$w<6O:uj:X.2;dx߶{Aҗȯ_(m+\ 3/&J;־}:lWMpϤwUi_ ^:Y'S7VVʊRҳgbnTdrPR\/7'HYv˧+v{>Dt.WzҢw;itZvn~9&tx۹b[v-S^q~[F%e?=?֭[Ln6m\*^vY] Dg}V $-[q         [`{BwA@}rߪsڤv=~qSt?{:˺ª#NԬwL'ޱnb0+rL9ur<$*v6gv>mAQt>5-QÌcϔGa@knk}ls״w!{Uh}~"M;2LѾY>=6*cDt.Yt(oI%sLruqR)]rqCNy>m^D}i} d ;e&9HxOLt?Ci߾e˅珖?z '}c܌sv2i@@O}߬ 6aB;        `?>AFʷz˓oNc:%7Sv=ɞr2j΋9-oOJΙ8KQޚ~yN?Vzb.O*3߹_nj{ OW3Fq߮5欓js]/k69L{}x{{a 掱ﳽgYۛkRW^^+ >*+_Ѿcj27G5R3^_ò:-yH:h+?g|:|H냳J ZZL.otKH=JbZǚ JڏV,斟3ݻ7ߔ#FHf_dešwdڣ/}A]8v›!  ߾3f '}z{'74ԣqRZZ*=zΝտ8@@@@@@@@ Sr嚯M5XWu-pjWT쪒&ͥui󺸨z} լ}]JՁv}o_clcX}w?xL1Gj6Jk0ńmke{s5gκzzpގg._--,14GҾ16ZH\N֝2\̳ѯMN[V] *715Z_LYX߫xݶ}fY\GGUdgӻa,٤H*/OlT~8S#RetRiڴs1YMrʗoKƌ~}-?z(} _kf@-oˮ]C =_;JnB)ٹsZQGUl)       D*o~DYp\Y-3y\ǷZHTWƢ<6~D>,_/M5ң_9poZUeMjҪ]GշGIjvmUj 1Ҹyٻtjs@*Z6Vvɮҽgi\q_AvZT&If}u;6J_0&϶݌gv_I[S*kL{ickmeg6l7mgbY7;pIMEZ ssgXKķwo=Y% &K˥eD.:7?WK_x:>%;vʊR;7]6enN^Ojfw^Nxb9tkwk`nu="N;MZg8 ~4nCɓ&{׳Ѝ+='> ^֩GU5d4:IrG0<*d)wdȐ!ҤIPkrGnx4cɒ%ҥK;ߠ)x@@@@@@@@~SNF針=FgyE_/g42A~iUۖGrKW4?J /{[~{r3kk`}ۦlWpoZ9›eO'}Z]Qb|9{Lxn"cL)un59(6lvߛ|t>Qڜ |0}~ar ;7.UCqfv6cA}vuP[>umfu:J~rjl5hzqw]F-+wVJ-/>HI?k_ͬhr)/@jwkԜCh:^xHH+3߹UVu|y7xV!7ܿ֯R>[39oƺm.[^[uyE RMO.;U&ʹn6l}j}^f91~8knU#׹Ì fqmp5-.37_uM]%Nq9븀Tҫe5"Vx^yrp_U8 y\C*׿eYv)9 ;:7}GZI7jvs93D6ԗZjŮ -#S@@@@@@@Heխg|OZ"Q-3'#W?M^&u~p߫p?}jy|˙2 OR٪vOΑu'~7VUw\z%Yyr*O8B.~ͫߗɗwL9<~u*oxY~0rKMxu_A GEMZ79X;&kx}w.ӫE1^0kx l\a8<3׹ÌjfA{smΙL[6g=}@~ 6'?Y^?䓁_~r q#ʅrEDUyt(˺b+啇Wn9ȣ5Ant"o'ài]2nR 7PbxWcǎr#4qbo) &M\1 ,]vҥK㏗Fu'&5@@@@@@@K Ux.2yodu|<62k g̞mK/}C^Rw]7Mze'qp'"G3isdЋ?&^6U^t-M猹aKr8:ϋT߾ i7?-yJmz7a$~o9D39o_sZ_tu7D?A/}1.\As}YnۗNjsmbg{}w_\{a=;slu0b3(&}֜l+%?Nz8@y3GB|Y1>#iw햕;+Ww˥O=RLEq︯'qf&6;̗5dYF9&:WYRs9&LK+FŘe2/[޽{4[U#VuD@IDAT z7xC;8ڵk.ӈp_폟3gN]}prWGoz ckNrcrf%ONХjg];W-k:'N_FYg O<kVz/tzwK "w^Ph辵kʼyN5O>P&,e˖9ϓ QH@@@@@@@R Ux.rwdT˷dK*|\ ۇ& '?8h\yN!7"cEW?Kn84뚚midk:<yL?}L~1{6+Wsi/>:_-ĻI'k2쩔;?//*%3&/?r~`Ժ͢:Fo{])僔_j>3&*k}]ѪsMlDŽ}0$?bqacc{ת 8oGsm=.kq-γ.3/UqܴQ^8<5}|־\(Y3]Z.%-շt.:7?Z'ۼVy)yv.u펝m~3j)m2p3`6w^pb9tkwk`n,ص~zY|~qa:݅?7N~8%ٺukݽ0jgL.Ky-ܯ,K/kqjڶ_6GnB;KVvޢ}7im_S.,\*9\7r{RB7zۦiݹXK֍߾\>YlkISԫ )oT;wIrۙ}WO#SP;;;KeQe<Vƹ5xY+ck;MK;GI[`E.0~x7JP)گpvȿ[c{^xA#:u8{O? %@?ӪU/5@@@@@@@RsU?-9k@=x鐛dˤU]e}sEteϫԝHztvדi3^Ejm_66* [)[~:lRߦ8Pz1T!}@ta.ׅf=WѸu6avs3DϫJ=kV _yH~8j;)77SpUX /P_-e(s N..$#o&NoUAie܈Vʕ i|yzMAΚnUfor<{(2jy^^ef\U.7v$ꦫF / c!Y-/tTHL[oa_>>dLGʃ# J/M+v4:0?ʅiqE.`1W\)cw1DŽwߕmJh hɒ%tС!@@@@@@@"*<ׅ;JLyY9rR鿤&SWI.7c o?})UMeȔ]Uo"&H~J^yT'vcR-5,XͻCty>Φ/SW6}ͽfYL9s=֥:;̸w^?;rn {oΦOo ̻r48AzGW?sRdZwl5R3^9~o[&%>;5:TnNNN:t:f^7k5huR;nެIZR\X+9y9v*ܯU~k?Z)} N5Sݍ Ƙ/T3tn599ui ' [f~$ㆦьE$T#p?.VyaYbr!^ mӦMe9ꨣd$       ,*pTˌJL\5-&ZA}<=_ݰ/T(5);éHM\UOis7%Zï?޴Ƹ2k6]#ÎjwmL_sW}sHӎ8mԊ^D{6l9Tj׈m%n-iޡu]Pͩ-wSIs9FjЅŹ>m#wݷrIQl$'V)Ie1.޽NYL'Az>˯}]W9 ho3nyN H[͑F?kϒ CFcNX#{|&.UVDo'('U6?\/gߐMF'0 uyL5٫-߾6sej^\^~mA>k}~ٌ񛫮ݔ5xaŹm}k6wGT}&%$t9DS /dLTWVʊR 8j}*z9w )i,1.[Hg];ECJZ7*R{yrzҢw;i4[ZJ.sf['RqܹS,X FF[f*ܿd?g]u.ׅxc\ysιک1:?U2{09nu>UKJK9+N53gvWԫ1N~U3aʼn վB S=qE~pʅ[eOvr򈡮qk!Vxyl7m#kdk SZR=KYY,ԗ ^t3篕'NJ&Q̍2{H&O윟^Y{ |@}4wNEzg>:T15kdݺurAıvZ!/(<        @ Ux*i/Rg8vv7;\"g\WKGUoxX^ps{o50m򗋏[Qs >* kj.>ItG ~SWo?Ew>'|{I9^:\g{_H*?CM^ũM.gS}m⣜b3k{6v;F_e3y˖ud3w1A1\XsN^צ}6}v3z}%iҺ*m x_G?QT.GUl[^6SNMvLiE)'EJ⯟d^~LWlYY6vRJz|#<{ҮsGŧ~M'xo5^2Ǫ=ye2~#GI۶m#mL?7N~8م:ov+//͹AvU~:hѹMpeS;^!C]SEvq-}S> 221|f|e܌vO˿o.M֨bb[^T9VEFޣMJU_S_\l}a! +.'9s U1vmۜą1=6m~n@}lwڷAoٲe 0nVx7`ӴiWyF6F+͛7o8)       @u{m_v_6$>s&Ěs6cX߳)Y ȡ#ÌɶĚf2a^1^mf^O_WKW^.3~Li^ǷPe#Vo%c u;+eۦͲi*?Sc4i1iӡvޯg-KrlݸM6u<_>rki2eӎ_srt =6ޕ#={\U?rHi, "p'H [RH_H?eƸķ 3'pW1s{qpQJ$|\W.+ g*l4Y؞[#]NT&L1E6ݻ/Z^)?c@@@@@@@@ ^θ)g;ϓsOTo]e2瓛kr|]Kj'=-w^u3z=ߕ?ˉwqmOIc1 [gQ?6a~bCc~6ӕhsM;iΫU[;ES;kQzaѱDUmh̯Vvo!6HIozbܿaͤ+L֧VmS~n\9C=˖-sv?b S+5oCƸ;c->O.5t#'Q<p]\.7@P˫k jG+ԎAKxbxWyIݠZ=}]$zR{)﷿`9-S_]+dvc*e]E*7x{ D.;룢ϟ?_FIʨk.Y`va5>c^hb~KSCH@@@@@@@؏>7Y:+#~ۓWB.~_ ruH~! @JFjrύ#Y9S?ˤ'wO=\L=;1{*#;{7„֝G^~ѩ$90)ybVx~[ȏ/LyE.M>y-?K%5۳3cvҦcnfL|N)E@6scG6&r{6wc_8M_뗪JjB+WHϊ,/Z-Ta\Ӧ*iTWEQ;Vm;D=Nj5JJz.HۖIK9ҩ}iY\DJ;kT~UbT%%HMHI ';5O+HU+*_*4T)'"v;OmYtNviҲwd*oӦңgOEW}1blݪስp_1~cj!3p‡I㜵,\+g߬d;%/d?_Utj|wFbۏTlS_:e}frTrX0yKQ9_"Hڙ3\z,W*_&;Kv ժpߣ$\n0HU3Fo t @E^{]wU;vȬYdСumbE:w֠oر>@       4k>/&j/v,Mtyl|GϤR5=tS:IԔV7fҲ};i\Zl2YR6VT-D*.QjRm&mRN.07EkUumg{>Ͼc]X0miκSf_W-ʽ5gڜL}xm^OWACe·dGjGR,.Qҹ 2H}O3ڭKd<)ٲXj+H-%JIi7m[&KIC YKuUDŲsټ'_mQdhүegg] w,Eq z~SE/7 lp*tn˒y~;|sbU?$Q?L6?#ۼ dr*N7pòɿo!鯑ۇ ȮpzTe2meD/kh>wY{%x9 RWv[f*?UHA; S63 N(/| Zh!zʸeѢEή%ַ3,”;wʧ~*z8URC@@@@@@@@pq_篋MyеWis}}mdj{6}J >"ܼ1(7 BG.sn L_Ww ݧ_vӺ޻HU\G <AtH/bjIU1늫b?5 IX1J4h(B#/y F׹ݧtu۷_-mSu>;[7X8x`j۶m7Fӿ>~~+sb!s=݁VOz֍4ga\B-T1:i]caʹ%~pz'ƱgtYK.Ku%&7 xFtވ#ck -<4I=}$tƾ<6EЬKj?kaGiCmk>̪҄'T7D{7?1@7001޽{iɒ%4pPus6J7<ј$                 `W~p"Hy2ѯ]T}->IDٴmGD1Cl /em<]]w&n#6].s_>L )ovM4dȐl#p_V鑇NU\CGt3-IZOjzew>NC*Zt{h'5OS M^ܹ.t~thtC{'+lImEODw?*f_wN#Jt"?i.u7!9{ <籸qF?yJe' Q3Υ"]D^uUܸ7=hԹ^K=~.xzoV=j pX}TQQAZ;ڵ<~qgk{שCT\\J*++N3O+j$iyӞ={_?WIgncɎXjc~jQx1J]۞N]Ǧ*?ʦ~ei/@ZVXA};.lppW?\=ge[6{?̚|O[>:JIfE4{v#O9epjhŬ;iO!!wz^Dnp6X67 foD3~>Qxoi#O/v]7bQ-?[u*WuEzG`ܹlٲ@Ѿ ZQĜO?UVQC{yByLFD.R]NeKYr]+N]3${ƍK.G^ZbŻ)J֮YC:w^zؾݳpWæ̅iRꑰɃF?7?OTIC'VSSA;^)ݻw۶pWp b> EՋx}^?lXr+о_yZmbK!Wkia{jW.;i'οt4 95mєjjٸ3-sUsEԦ5ik\+RӦ5tZЉu|F3@#$yf鬳J9o}]ҥ j*e|C9^ڛ˖-1F|uI2Gy*gՇ]廏m_:u*Mr!eKYR\]~mӱvٮk\ rM>#suBZ/' Y˔o~.JzlItΙ/~=4w4e;i|B$@(/2qԺuv"~*%|4iҨ$X                ](3lVup]ۤsNkT}a#I+ut\P9>DT|Կ )g6,mvٮ6~M6@ xbٳgN/puߣo.Jx{4쮿F+F1}U=s=$}?mZv;$ڃX~'ݻw`;kzw<{S7Zns9 'M1Fp6ut,&\e|FrX񧓻b˜dv9Lc$~&yObRY!BT ]vme*bӹ.nvٮp}Fkw}[mWgp`ڿKޢN;'l}}&ز{챴xlfU[;yޝR6N/  9$P[[K-jѢEʞoNtI'm(| QNʐ1N|/tu9h]wr 'ۧmAT>uIM<ȧY! W.S~qxX]M]IB`$a*,,>}[g_O<8^gH,ĢtsW'Ѹ m4>]7zuKlVjյ+}tw/A  uO?*ѣGʍ +Vb5k2! 7oV?(m#A@@@@@@@@@@@@@@@~0k͈Xy~Ș"8x?bK'wj9^`/v-ObRAj F}+&MyZ e \~K_.^q}&3,\l]r%Vņ:ZfYωmg?>#p!zWhԴiӔlB,vرc؆qFo:4!c                P(fp_ EL.eX8Kj#>݆}T}\F,n$w_<1QyEm犳mu%qJ/ϦAek>ȼGrFł_*n: ߳ȹP_67|FҾ9@";GMݺuK90sgJ蟲z7ٳWF!@$`יp"*w]6~\1MA˧mv9 \I2m)" eGv8T1RŰOʶU6شiS A ,oC ݑ@@@rC-o۞?U[n :SS6?_c] j bR$1#}%mAuerMںT6s~r+m2m'bp3#U k_:eչ.3W]۸lץmXۮ%F%3\رcUUUs%Xd nݚ:uꔒ7|CV-Z אQGEׯn <1VWlV Ae?>l㜓dR۸l%6X]δׇu3#U;?nt=Ħbvݎv p o{;   |g|r:s5駟ԩSTdH`ǎP3@@@@@@@@@@@@@@@@TF"r#}-J.LssNOPlXMO2m xw2#U;?mk_ulPd6mz*] H`߾}ӥ^J|9%c@@@uQ+ЩJEEE >T@@@@@@@@@@@@@@@@@ 1 ͊"\^Y)~sŖNcÖ8WmdZ-"LyE,y{}jAus&9Wʮ<xKT>@EL*>u֍N9TdI`ƍe۷o=9D *,,q휑iĈMrKYrM|^//ζs 'Vo*r%v^kuƞimgZvL$FC,ƷvpW2dD?>FAG-aF]@t_~C!Z @@@@@@@@@@@@@@@@p!cṼ$emxɵ?>NveRp]lKvoK=v^{Kg_uǮ%6c]&1.WH91"!gZHXv-oߞN?@C={6DM *9wu%R$m–'I/u;O㥞i;ʥLLHumTe_l~̀@YYlْAk4ȆUTRRM7h                 p Yq(].tm1s/8M]62'ŋ/(wm;(>'bcLpsd8.mu)Kb b.s=K?y@A ,N_|1VMbA@@ G7uYލt9݀4RF}3T+Yx.s)KԤ,A6ڧ˼}I6gk*^ڹr׶]qNĝΐLpsd.mUϕk[2K#u'җp#@:>h2'oӧ5m4!܌I_-3p @@@@@@@@@@@@@@@@Ʉ]qE"4at|t]ڞNYbrOtǣ]g&m\>MLy}<۔iv.X퓲/ce?&>elR׹{߿                     x {?0 Zq"._Πl_*헺zbsleNvk_i]>MLy}<۔iv.XI1vٮKunn>/ 2˂}p}Ƃ                    @To> Cm"H:VxIl$}Gjq!tnu]f$-/\yD<8->ROy~umw&%uu9ߎC2Ϣ|NOE+? ǿ                     3s Ê/ۦ뮲&+6]m˜_#A>x+w)U_VQ+M*6ȯ}k%Ħs]XmegI]xeb~.pW@@@@@@@@@@@@@@@@@@@@@/p_|s3D?A6qI#bqtIL*_:}ؤ2 ijMa}Te_l8,AT>݇]>?                     x x3+{3 )۹OS/9oC:eѶr*%fabM8.q31labl{P],9OIʒ6rm]ħ }3Y$h}׊,(_L¶ՃbO/]8']ï.~e<*s ϝΐF  c1rĸrmv9b 9amz#_J'e>EubeiIKuN\첫cuv6nY(m G8WL*헺bL^ FVQjqezPI],}k[P}tmvy8&Vfx)la\1-}R)0+F۸,/ۯ.v;v"\ŧmRp xիWSv/pg1IHIe(lEE 8,$_.1$۸K:Mʒk؂rOr+mvv6nYm G8Wm k%yJ9L6.Kĉ(_sQ~ ͫ1>R%k.ڻw/s9j{xwޡm 'Y'h @T_fy||Wg-m"rK;mgcN2FmsƹƄNgHSsضIyMuYb.l_/.#@c%S=Cu@vM6l}f @'`7Qn0/K<ӗirM|sAk]SwŰN]n: ƳMaKg꺔%IYrM|vι?}K>6X ,[?|jѢEc"                  қoI̢4O *O> 9\ʶslK%FuRelc_|f6/8&VfAx)lAqX]<7)۹\6.}<?q_1c394ZK.Ç7ab                  ?> 4(cF^q=%BD-}Rr$ؗbi6ƹƄNgHSťӱۗmm֥].rC{ 1IȊYCB!g!y}ndtl:u$e;gmVǺ|bG2mbe O2]vgẼ_Mn*s#\/4?xbj                  #$23jbH^1ҏ/~m6]K.6rM~쪳Mݏ9e":2(#(.e>eD_~%hڴ)nݚ?xjٲe¬ӢEh޽^ {9EM)SFi0Zb1ҫBo6 IYrK.}t]0><, i GP]ʒ&v6RDXu'ҷc9_Fj o# 8o۶mcFRx'p u6| 7mD_}|Ml͚5O>.7mE,g>>k.o:PϞ=SN cc '?3B/peT,+ұ\g~i%bwڦˮILje ΃qβ͝ΐư}Ź|.Iۥ,y*I.R\_%&v-Ɨfu~eiyyԗ_~eziС4l0[K|XUU<, i GP]ʒK\PM^ xms]~?ݦ^ Y'ZI?ϥب;vs1P6mbTN~͖-[B ?X/2رcR|\ Ykџ |p%_ݴኁ @@@@@@@@@@@@@@@@@\{9z7]$[-Idx/7+ R'ϗp=W?܉8 6+h"|NJ?/"=^Y̽Ń:,O/P_^Ns$>~Ygkx>Gbr~_arn)L+.Ȧ}RN'ױcbew٤MOb2 ųMas\6KYrϕk]vll9Erm:ƼzUkÖD-8sޘr~t Hj}y2!1bD Eo?I?j*6c.p@"P[}m>>Ø>K^ Axojέ9:fj@՗[&is?,г8-D:W9^cꦶ<ͨOc+_hH|Ckdϧk|oC^~5O>_ch?uE-_|[W\vgUN hBMᾧRM5^&j?5Fc !_–A uθrp'"Տ(4<o~ љg鉝y},xZ .{cO9w}u2&ܗe,_}dԤI.O<  'O7"L6MKٌf bѽK/6vYɋ6]w|l׉i'Mb|y8&VfQx)lAq.m߹*wqʤ/rO:$ڵ>ߜuVO۶mp/ꪫvQ|pVڲݨkQm'VEѫ Ɗ1٪Ug;BQ։~+/H6VDCZ)w/}mAںn yjv,u;#ZC[?\F_2{B = =5νwsvfֽ:1Ԫ"~f5 _.LNZ˴`{=XN=:CQ4x7;GX(4*APh\)N^]V,{6璘E=aU<]*j~ z"BP?wմy z߬ʩent9Pϰ?HF6 ktKʒQNKVTܱmOUm܋sa  DB9;7oN\s 0 ) I[x1\R]T/E?Մ )Mo m!J<.=6^]5t!d>k ۵kG}m޼oN9_ԬY3g^SOle!'gq8ŞIM9Nץ&wI%]1ʗIn+? s?a}>85D̙3D,ˈf JtWlChffrΥ!M_5c;1TiQ1F=} 8}g$=4剷 A!}oϹν~>K ڝ4g3i3V|!Mdzgh^hwf/mx>q"WGђ}T4&rZS$AخsH=_m _&vr+˖3sPb ZvF{apo^2zmTF7J=k~ln({vD=xdE<<3 vKg.?J6=I3t0>bGd*XKxVc<¬c0? 'X~9rKcХ Z繴`ϕXɅt5Pr=ģ,*OjުyOJ}ꂧ PLTpSXdiᾺI6?ᅼN y( ׳Z8_3|GpޘMsGOIQL#& j?s{Bp'"*ُΡ͞*:~qߑ4~!OG?^U'fߧKtP/| #z7|@Gm歲j>kDu뭷R=R5W~~0&~7ޘ`G YsV]*((ﶘ? | 1Bo퍟mڴ O72s&2 ⺬[l۶mL/yEx^{-aX_|1vpZSQ~+ӷڦ'u]6y'1F&Fb]O]j`YDA)asl]aMr-c$Nsň͕GL8mcfg:MGh_@7$/}/R4hTC=Yϫn&ou1EWM֭ErZO. ]^Wv.z: 'ާG%XIOޜVzo7NJwA7ͥWxm[?71Vv]g{h{~fZVptMOC1+'tBk5!>)\7Z~Ty$C_HӡI7Nk \AN)b'ӯ9%]޶Z♻HcUsD+<&n7ˠ^~3Jo/4;3ܩ3hefA|M0(c ƭj|\1oMwp=kЏb<#~cn⿶ ^Kw^ji)$AlV27,`Q:zmka?wA`Av2+WÏn1l# ]@"?luiAN­ܞͧDұ1_zSΠK"c'9xe8TcͰۼ5;r.Kncy;3؈NKNyX*uu|RfLihxXfn?_|g[?S$<+?Kӟy +i`"sȱT܆?k{J!Ou5 '!;*u-~{X5}Q>o̶ sdoh:)߳>>#sýR^(/ܙ *SzQS؏::,͔4f=<~l Db04 @<,n2/e.M˗/~ gI6=qz|;wz ׽JO},rԲeKoy } hʕd474mj,$|^ع?\.,,N:q筺v~qo}[^OMM rٲeްH_~pŌayչ-Ʒ,2_:ƸαRֹ2H]rM|^/FI>XW{eWXfqx)lAq.m ov N,ڿ;r&<1>_H=i`o3h|pӇq뱎oؓZ̻]OEs?>@ל"ւ 3++Φ֦3SoO.죗G#^#?nzdh1MOt$x wOF.#㩡nnF#/U埢zԬDАߤE?=/V.47;tR7;WsvW*3'C 3V6? R.uT56*fs ztfȝ.G'K]3 `vO<ɖ 4Tڎ/kj۸,9_B?6"z]4F[=6rҟVu$uF_~;܇eF45'~AgVwG%q_{>aϒabAzFkuT۫ s jeȴ9-_2.Sk\e-nGn bnTu<|??G=ߓϱFc:5LS.A5E_qvGCø^~y,Z.ڹ"ڿ'K.j3_t=\%5#ԻЌsq.LK+7qfYއD~y{欌5>7B`kAux :2_7$s8&U'ʪf9Φ2 RN'b;rgp'"}ԟ 7'HDؼt^ˍpEeO|']U|4Mz?pGoܦJ/fU`wjN<;qv`h|IZb7믿 &L}h4s$7!t5uXMm6O-Zx΋@^a[c`:?,///'^x'sXl^/6KY}~Ht\W%F]msƹDNgHSŹ|MuRu [8;Vl6lQ>m\~_R+Cϻ$1wcfƌ85{p/5ڷo`w\(O.8&~'~M[_1u9Umb ͘ޞ&Nzسo=0οhZyK?FNƍy<9::}FfRd+DQ$Q[)|8z݇uBSijtj$}˧Qsu,xg53h 7?!в3V7dPKlkc#6fS#L1tG-M޳0d۴^#ydq˺?@8XXN98E+iCi%ߗYЗ&Meױ P /3g7G׈Hh:;O=(&=V{~Z@'NŲ4y91O {]Mw:CDsvi{TSZ2mfYdg ~C y.|IŠ]vR\-g~UU}g~֭x?ЛYpϢ|ܳȟu.]<֭[$72g1m,/΋@TwTȊZdm,vWc/}Jb׹˧m/>/PŦ&lW~y8g{g6]eK9Uq+v$ᾫ\o GFWvfGj}v˿{1CȂ]pE7|sl޿X.sWͪ *剛fNWQ1Q *C}V?FE}+ixUǖ- } Ñvϧŗ7FMudV_6f4۠KR+酛ֽ˻aTч̸+AbfW9{ W-Ǟ}jZIխǷLUc7mzqA cK'y&{-0ݬ[j һ^ cf|@O|fܩK*/z<'\]Iv3R4N][Օ;i2Uu{v'Pnoh]T[CԤu4=PAek>̛NهGWzH,Ryهn.:Ь5kڂDB}rue9gOִuRgڶi=}1@%Ʀwb'ϫu4wffn;3 8tL5s~û9pC4x֭ [>̜x&merH܃z۔j|S榎dLZ)V;d{2Z_O= % @6Zn}VBSk֣' WF'fvǟPqmU}g`ss nq*j ni@O{cK3fӢvc*2:>YK~+>'޽}lCfIͬt4g?$UWih銟B-QzDܼo4V;Qq.jb"~㻝L{\LܘbGѦpL%oq 4vD.\yȜyO&h-#SK%^5!zq d3ܴ=u)N>VxK޹;&üSu>q>F*׬]"C-yy ߛ*s̜\Ct2ޞgf`>Ϯn=Lޖ vy!y|]ʝۨ nӂhqF΃KN?jP3s'߲ Zs1%}؟O2>C2Vs]˟>~̚;E#z9&l;y9ޒ??һmM9u7Gz9/EF .˹z=4Y*Gw븎V+'|.u|d_LN'a%qk:zvz_Dlg)Ko0r+f98aҽ}|j<̉|#|P}zOXZqGXu?rojV.a߼Kq]kG|Dײoj{uL/>x)6'c+ޓvzcZ$P龏g]<1}J2u]g*_ 'F{oyxy&2J%Х8Da[Jo ޺}y?YO;=z>}^kUYTonwlpj<Jo&1|{||]bFijtYN}oqM&p2w[o \hԤ Q ̏ݾVOIwzٔ'trevm ު|1Eii}{8<~w@{ kndۋ`H;'KGG~FKx1}SR9'朝8dgK&Qhr)N94)G9x6ly 7/xΜx;vxeip ^Y?SN0;wVZy1z?%%%r)g$/f6| ܵ"6<7z7|>}kx?s%u31k./Xf"2o//˂qcJCpYH.B{.ۯ #uŊ]ru)sΉc8u@IsŋMrپqw8϶. u]asi㹬:F|:Oױ~e$1"aV4߿pdQtRzWf}<> /x~_ ߳s~#qJuCGxz4eJfGEۢoYG77;~yptj蹛KiTd{-vH\w'ŭ{n|5~ݾhh#(~)tvoVFp?A?q~=eOh/+3U:֕{Q͊KnA}E7S̱ 96+FV?ٶ*5+DϘGTFxYݚj]xto{'/-"7j[D^UFs?<]jRBp:ilͭЬs:L5-}[~TlԉW 6ޗ}.7NaYKu7(Y-.9F+˖9 (>ݲ*H/.巠bq%IsgxGQ/3Q s5?hݸBٔN470-K毉Cc_z0n+0sc3/8&\{tH/߭mF/̜E;[s쌽jͤaVŃaޏ}C}fB`lVRF89pAIgD5c8_+iA LcҹQc4ʎ4Ws||oΡJ?x$:y+4{qV*.AQxYdTc-Z==1΂4Td'0c=fbz:#n煄ep-<мhnjɟϘ~3s#'X#Sv]~N9l~{h-^5@1yFḫ-M1%<6v" =uX5Ⱦ׹5\XcN:xӏ:*2K}CPHp鹄ۦ{}WWrT:|W|sBM.k asy&PisjZׄsgWP4a|FYՖ[1nnȬA/Lz[= KN3DKgtR7һ`ټ7)~O|'9"3>%C=O>-٘s]߃YA>̾+2nk'^B͚:±4s 4s}t5nF(:5*5e&7=>~M8N_"gƹ.E'\E%r _/`=h%gK @`F$}W^y% 2{EE;)q%bO#u]`  I'OFÇӥ^6<W}[uٳ[I&1-"voߞ?xoy&  x:tr>ny%ʛdcea'H=zc> /iÂ:N8O7|tbj*̋QQ>眤rc ?9\b.>X.sr$la|ùަ***8(lAq.mu2T|asilu%IL\D8ǒc+}[5T3gΤ-[xدj:lU}v}\sSZzrt\>omdira@ntkznB/;L.X:͎$5Lq!a~( U|5?0o8j%#i~ʏ %?tl^h$(f ̺I?UUܸqA5uj fU#Z X+&4I?E X|9@IBgD͊-3;.oبq6+jGʹf"8ր GGObz ^׏& [WXlE\JZ}9<+:[% ͪf-$I̸~FsAޤ@{SWz69Jxto&i^}_IkeΥFtp9WE_Ǐ1! hĭ4A]KFk"ޏywa,IhyOȇ\]|!MpA?Z%{# scEݩ9CmŎ^6}qԓEt{)SۖΡY Dz i䱤?SbOαFNՇ:H~H't>ͱqAHW&xO\p3>/Mf~mG!.z1Z.>횚]lXJuu12\y>63oiQOb1NnWih_]}}4P})>MVTqr媹4E[OLoGc u{kNey3wY}~Q9ཡNJ/ŏ̾zRLg><1D|q]K"=u{QZH|K~%ud=wa6-FS)1^U7#nJl9d_As|['!>^q&dJ%#&Z^ [JN[|K fG&]^PѵkW:㼘M6kXܖE5scNjY=<_e˖y8p ]~ {JKy}^A #k.sG1K+I6ijMasly.&綺_=]A-ױ.w>-Zd64tP6atyZw7X>7ݺuk&7A~ꛝwPxZn?1;.|W^M/:5kB#e[3Z^&6Yg%bBPR UBMm DZłj/vlv eQ[PYŷƊ"" 6%@$}s{9x W8qo>jõoz ב;g@bc<0;ᚫ!`-);{V{BO_D殕"Y o }{BjcG'&I=ʠm*,_ߋQZ5oPo 9%g{G8t@Ѝ4 "|s{,й{Armlmo":|9*lr>~#L$|[xy"`8}5>r4gi/FIC?? N{ܹ~a8v tБE]_!!|%H6#|jkȌy{̕?AxHʼ: EJJܧt iȘ -" ;J2t-М9s޽{ÿVJ?x#o?Ba&l;kx*G|tXs} a% n"yUx9F3nIXUHZ!Y*>44ImHg/|piٵ=sjGۮD0P7cQqb%8,7@:Zp[yFnGiB:V+ᜲU?>^T7RҨO QC`* m1XIԐ8t}&qp$ԊtpWg /m|G^:ל5=KW~w#Q0\yAw-"ŗ[r>Vn8)Ȑ E0wޤWCI< #u)[qt˴:HU9Ցy;zyYmvaʩr8UDt=%ZkCK[P v.8 7-"\3Vq.A>wbEb'pܧ]äY Oqss;XoxkB7[~fm**<>AbWMfbi*ׯ]+<(]P`|&+ʁK \7M M꼙_W5~lP*A3gy#E')}AJRp(bz=p//4/8twI3F6?+V=ÍW{@ٗuV=Ol{rߌ}.(}fpm!K>K˔}$9rq)סFGy/z;jk&bU[&v:~;ՂؑҞ5 ձoxOc:O6N -D\'C H'ڈ$/_q|MG[>9q&Od}:@7'PI4Sz୷rT^/t3Ø1c|EFiw5h" m555ܫSq>|H:"Ώ)IjX?!# {'ɒ41)䅟xEFq|;ӚiT?caO]##]n0;qjܧ&Hg:SN܏CħVη|NG%A`T,{~ FYȖ9"Ynzޮ$p+˧@|Nk[ }n+Ԍ f}s|gǵ}=d$!eR3e>rey❋42K / SʔZ5.~pe_ljњIS|arX#Xr^6ADPkJW,̓5_RY$j-K%}\0mfgvǗ8s]@.0}Q5"K< X $qSaqX,Ke`[H\0f?8J1תH J"yQōHb9˹;$vض| luH[y㶸RMtކHnh"kž6 94y!WRvԖ|l5~7jvttP5N a~[#[2ۇa }L6`sZu?'Ԑ~ވ}4ޥ1j}!20m\)NFP ;T0j1Na1}ؔ.Y;~%Mo샵R wHqC?tkڀyGxn@6Aѳgdоg@]gGV~46 >´2~jW;#ks'~",y]48 ĘPqc.A$b%6w4C+J5/Kq^[= "c%xحM`A2)cv|n PߪKOPHS` (5;` NeCܬ2Vao4ǔ=öƴ ~FXQJmdMf7m=zXr֕T4z?yp/{I}y%dk~ҿLk5Og7xJqN9]ކ7Z1*UQs|l޸]'υi#@ݢͺ-Gh'T I!kJ~pʕ+:>7,O?p@G>ibOk:/ʬ#ޓ?Ӹ!C8vA'C`Ϟ=^lD'?iO~_oCܧg}6\xPPPIs?0†"+‘t9Ɉԉ8_ ^a#Y2-ٞ<'œ {'jWMF¸dT9ǷQE=?O /n:xW?ԩS}>|J#ahUTT$'ӟ}'߿O̰kܧ}VZnl}C|\1e7fXk,$Z"t7 ~ 6 ?;%3`D2 OL<_9,pO1|V=æ(HnhflGr7,9٦eS8XOwu^n%fí:26 "XYǿ8)#hdķ6_#4xp[:^=Za}+[x}x 6ibs3r0$վ ϦuPŁK'ΆnkkQ.w7Q/AgAKIR±P^[L펶vln(?,-yl-m(/$gTm}e+岔5/3a M-H/n5m01I8M1<8Rᢎy7z%dTԆҭG뱌0q"ۤR\U qNۇMb8$=p.Y8gM2Viݳ1tIS8}|/ ߀7\›_eF_$]G r_+gψ9 f&c0/>`-"eX*{>p0abn6yU)k4Ik9]s уN86cn njpUr!C+dyG{.xxP,R$v1kxI;s>C%y!sS䛸߁ !~R{}NpO\veydO}ҜOItpRO}6l :W} gyF*5\_as=wB oӹz#[_ V^ $U8_s^~-_핏}x/CmTii&#/\uh~^||OWc;oQڹP׬pE|c*ho@PtM"Mz!?horMt߳o5[`ˎ7joWNiS]^^i3 oDV OFyfWN_fkӒ'P]aD&vMQ 0фxfk1fF-EpK᳗_E^Yʇ}en$)c?f.Ƹ HaGjJX9R"=iZAS-"AII1u?\k:84CL2ޕgr-!:; 4Bk6mЏ 1\E@QC|djվ6,kBf2SzM/WRi]nߍz-P,! x!Q_yfk3(c36üg#1K| xL>Q q:'-!eFgW]?DCZҚ?#~L$Jh(WFs؟M4kM0W_n d 2pzXYk׀m|aaAzlL(kjɞ5*۵eσ`ݒZPr:V:6FM}a\9LI׹ɩ!43ۡ(>}+b3}ߛjF7GPP L2r7$;4Z-hWl2&!HbPL)NNH\ qO SF7`K€"<|==|ݸc |vI?퇿]-!Nx_^,\6Tڋc%nל!}S tb5*k)v ye` )# RvRqYa\aIK (>4ؗgWOH>|L")枕wPd2+Y/\Ww`Rvuc G9}o't, ^qǀp`y͗7!z';ah?kXDx&c"s:$/r1cFԨ'T/V׽{Š+||ԭT9AT' '2{vDb2N@MܧߟgvڹsSn"?{h'{SO~ mO~Nzguqa?/:+뮃=L*LN\qs :şpO~dtaO4wg .0rp]aa\2H`F.Llv]=_] #7#[%0&N'O}BAo"iJJz)ȑ#aڴi }WF;xRۿ۝ k648{?;zh׿vH}'V[oo3͋kaѷjszX?|po'? Op"(:VC ': xo{.3fXV̻X2i}Ă P/1:/aʙPCs)Hgo׎K ?qǠb K_άpab~)Ü@]ߘvEp֧ Eؐ%(oԨMW PhZ "L]t'o c>fo& lwz4k}HEMLsO6Ò?z,Z1)Փo,Rmk؆׌nC #mp#PGK9!dB \M&BqdyvT7L!ka&'`xɛ}#* ydighڊ^aNe>-gK{_&eh^k-'Cw#Ih&Gn{³!aݒ[=r&@) <y]Tn ywEۯꞆ_nɱK`0h8NL(_ˇMm" NT=£;'i"w}D=p$GzM>$cJ$W/$To) ˡzpjP(6YMN>q}3ݰ "7Lo_஗ᘉDx|:)Yo`F|5{#8I̥C_d9K`w+ɎrDIVr"`yժUNLW+++(}]wL} |[?я%??$8 ;QLT9mZDOk& S;]'QuOUHMBM?LN(q*dl*iJIe8}5 R%)qNrw}NftŐАo=q"`ӟ0Ğlw>v=ߙEp~eӯFqே\XdjvxudPd=\G<%9^J.u~J|1? "GOLJ)GxeOCṡ&LM<2śaǙFz !1ec?Scx+F RmtQ&†,pm5Kaweq^(֮|ap2 ? o?lu3k#8{p`V:&߾~eJDԶZi[J@v,l? «z;g j^\m&_!䠌Q`Q(зO;}& vÖxs}5 $r ϛ}۳n <[fT;/Ikxq8..6 }(u6KFC4l^^}< `CQYH9t4Uă9~<Ȳ;ȢN{mh~Bb8̺m: L0b.a1Xr4ɞ?t܈ʭna ;y"_ӯaay ]{}[+>}{;7H,aAlL5Kߕak*{'9jV#y[9^)YKH\ *vBT"C}`?i.er^yh}w9#)ƨC3^q.-ٱWdL?(j#qEIq 2z`OXN$45{aswQ5%ҸOOl~V> QyBT1"m $u';}8{I~ߦ尶e.k w*};C7\2_t$}_f_9}Yo EXv!vMNX܌=”j0JFq?H3J9)ZE"} ?_K/Q>Jg9JZ% WUUAdx!Yfp? o*0)~6@e$D|'Cu:Ĝ>ȑ#o}"^ԁv|:@e)w4q ?@qHK?㯽ӧO圀$ZqN0q}ӓp xaaTx\Nk'xZ509]"\<®{r?ծEZ?"ȿp)>OjzklȷO>A깱\7; 6 H|;/fJcȐ!0{4EO̟?=䓍`ie˖Aa! &qFx6'.t9F||C-jh 0x xQz-4=4V9ÉȢGN&وH8֣6{#~"a\] l8a8=~o;.G 3΀ax5o;E2J}5<,pYA[@`ѡl2^kش1]Nz2t0d7|j,&`x2e#x}M%~%^Ko E08hU`ȫ^Ʈ.qy=B_ 3m-`uBaP>ޗZ3}kY iS\ +7α m%0[a \x8Vֆ샐_ aJ%,Z81a A̾s: %E:yjwڨk"8 oSf xxnVaqI-΄t]{m8_VaՒ!v]r`x 7jk6 J`_W-8NGgwu!AǏ>{ /|+IsC?x¼y_KۇMbC] ?#+W;G]k:#nADsf%K8\/t5?s.͘T_.UysQOyY_~s m"1Zjt6UEUt|(hR5ú%+=Uw#쬽;|&/D,csm!yyFzq]籰k†'@NHRƧCjS )6QHsV.,CuxXm9R7ޟM\I0ְRSxKDpĸaaAlL5'= _m7_ sǖ=l帟|gS؟y N;0چԗ0uRrKWu;{;\qOO >>je[3dV^}cw?)/P dxy0O\kQҦt1IzgyErlT$ 5klITn9f -<=\zdxkomٳ= }^O^7`tKٺΣev;eÍ}פֿ;c^1OG˖u',=m>ı-MGIMӨDmۂm2ZgBxq)+pL9nAM&"xe|X^N |_O37cO0: ufbuz"+0xj%ߐǟD)++Z, {x V3yN"w:^uǟѷv[$H32O\ҘO}޽{СCA2 /;7x z?'S?OWeՈNՏda~Nr.yOF0rq]@*< .QjW" /SGiaMN!S-yfIV[z5Y/|F%Dꩧ8f͂ .w˒OSb;`G뾉dO;(믿NsD A/]cŠUq0zqmÜ~#- ,>9I9aWtt~›pA;yp46h{h:" 2ΩpOM|7D6E2r0дsw=/Go.$޺g=N^~|rI&ڴ1TNm !WSdPV99Rt>nM-ò:ѫs܅n.@ ?!;>|CoF;Qx]xfh*(,?vVyA \T /nx;L/rmD=N;>U6& 5*;xcHYVլW+sUuekmpp pG:=.ykn܁>ܴ5w\% ѳ`Ry,CYW"nw4š{VlLPr @r7ގnic𑂤ho!D%5s(rxiC]{$wpX?V0ڿ/=H @ \|+tk _5G|)!Wi0+w:'[35,|k[k+7EWn6.]ԑM8>8æt(w+4'zNwpB![ y i?4Q]`3#Ro Ā4n݃AK1ߧk^یe CHko;PU͍xXb{$(ҏO*!kNZ?P٢C97]vn(ѓ>< Dci傴k a}ׄM4W&K=l~ $\+_G5sI唏 n,mX ^+AFV4'zO#dd!s?) P dǦ6 ~pi]+.>)],DcD:բ{+φ=TU@A\=qbSh~u= ݴ}m͍ܘpyA0щH;G)>qHtKZP:}~ୱ R sGbK1T륮;>=m}s(% wƾdӄq~^Zfh}A"].u _9M}zdwLށRI:>x[Fj:'UqH2bl7EvW ;!>ntgO;\l$ 7D|_b/UV_-Tm۶e'رc0 3&+ʧL),7qDo~pTn SɏWT$KO!wE9Q>Oi'Ё TT& y'ᥗ^N}wJڿ+뮋5L⾪u5~{2}ݰg'~Sوj+헿7D\& Yq/3Y}wW\k$G~p!㫘s(aٜB##ujyaUri+"8h05Ö;*`6 ̤~}-T yzq-x51W&T"(8W4iظ ]ky4r~ nG~-"s}:/7肒[˄ٖ=PQIM =t#lR)Myi3%"0&U~hm_A 66-ƔO)#Wf՛v>s ڝ]A1?f0bdOJK̗ar,Y\DB[c:XQ_7(U3aR)mk`߯jb;-լĢ/#Gϰdk|mM΁xB7+w#Fy> Q`Qd4;˿4(ɄjuT1jۄ45uj;~3:+Q7α}PCJK6za|` :JmMA[gZe-#m$J҇RtQ&_\ 7Mjf|!/@yv^~7R̜;JY}fZ`գ93|)W+k6H:޼Bl{X L1F7}F~Gu+an1_OauIt->$ WKsVX1=[ä\R}S1OL',,Ȇ eMH2`1mhƽaCTtKQMuPS[w#%2?kz&[f} |WlgҚMd -6ê۝%7kCJ4+:pH.8<u k}HyoOqЎju[LǒRz pVX*BW|vtP{ۚUO㍁6x8)Ӭ[ؚq1;9tyEмgxk|])v 3$yO0!/uW:IS AL>U_P&S[g'?2lO.fWMF¸dT9ǷoKnF.LlvnzRmyX] #wKKғCr*DgSEXr%߿_8aذaCaobssgK>No>~)io~L}Af?O|>-Xk.M6>!W ~.uZX8u,\uX oC#eSzC ~[?΂[~HP~PjxT6蒦y=qPY}29[Ckon$ֽS/`C[`\x0ڏ97\$o{]<,5x~I&KZ_*@R%ӻNK' Ozr<:2p8o#w΀ `;H:ux\}p1%kɡdrP o uzy߉Z=t#lRjaHƾWIL;z9}ш>.TԀ}vx(飢d.FqAGOf0 Ceҝ9j tಋ#M¾&O4MR7x8b||yT\$αC ܂b(>8H3} #/XQq*ᣫCυ?wp:e „ӏCۺ}|J Bנ6}Xc>G c+ ƍшW`26ÒۙL $M,FhJӇCf1p6 kVoWƯ+h9R:n (c`n YxP˿*:|wW[LyS"oz_]?U̾O]#Yɽ7P~4\L oꡟhc  )k47>`\v#>$ K#ykKyڅ+(Pqaؤ^69Yуt<0͎YɆcv&\,\vOu*OecGpJrD_ ÜUgpEҬaҮaӿY5#[xb aaA|\SgOSx.ȭFa5fXd~R3Aj{?%BsRN19~^o F|8!s}MwJd$363E>ZϫɌr|[6I7ԛ!QdD"` yVl[/+!'䋸k'0D|'SҼfI{D7^޽{ñcb(PܔO}OO~ph7O<<3R9*mOo/Cœ:nU>ȇ[g'?2|N*9{f'cV^c$Q+cٞI~W痳P/}*0<<OAd$דw-̄|?M{'~QP>n1_O(*Ɲ?^x}4$e{ p}3!CsYkleO<ם0z"xj;N(AB!)%6Or$>߷o_8n E$T HOhYrТEڝ$CMM ;#?" 7ɋ'0VejPM&,lj*v"5QӅ~ܝ.“`kxRJ^\9'fb<d^`c/Z$ϋJ7ǞxF1G7uOM!^*؎8Fi60FK#㳫#Z=Үq`m'2ވ֕[VN_g"wi h{)mQR5Pgon1"%Tt6ص oRMM%O5X1=˅kkش{QF<1hsj;'{TG>/}4]5z"?(|wRc_1/wz:IwfV?^a9PYwt,9*s&n}킗tld nIQdIӇS"Щz\(~!kaKVHg|'ʖtPc ~a 4s^bQbӭm4(7Ø4|v?C4/H B~EC᙭x೸l4\*(ퟹ%XC1ˊ Y~bA$X4B"T}$IEƩ)s?koH^ 2OG$zܿ&Ϗ#' Bݸ` x'1KwLށ~h׮ޠ$!6iNvjV8&wڳ5EWr}>)e_)",GOmX8]SO!W_ _${.&Nh2q"SHDzZM'LH={;Dx\)_QG:7~hjjrS8 Cv3)SC'~ģp"`8Gq9 ('Hmeɸ[-iYοx(\0PwA;a`πC>Aв (Q`0 % |лo[쇏{ g||,pdD6lm-p#(=G/?&zKhZ.:[O!OӠ4QUt#/Ы__۴+i*U;4"481ST }&aJZO:8݉L>ߌO7PkK"DxOkYL6 Oѕp}pHY4ct/vM߀3ٻɻGxcx;{2w$vȅˁ E=V| (C$x' *F7kA$p\`(Ym(k+<1c[:-o۾MPΉVX1N*$qMZZ9>P<6yki O:/({s2iOixqhj6^v`s'G~|L.sy9\9.7Z7O1\BN>Q;9 H,ftBs\kX99BL{ GA^>5$߸\$?} }]a͓Q'}(~|&yG/Ad`8G/{m^Ӭ[B37mGਲ਼g^Yh:&z|nT\F,}8{ɛRQbMM#W{~~)JuAx~n<gmoUუ=GoKJ`ps*_t-@NP_~9̘1#'i'Mdʕ;/RGRb<ٳCb 'q_4.Iu"0>OD0^FB:p Nġ*)_(]v 4ȑK 9O<9Y^'-R[-ieGiO b1k:I6tKZw{wVB+swH$vf=G;WvJs_*wrt5~KaN{U7ܾ.gS5.FK5`DS -X 3+՛-4ѬWls_ &Xv5{m.T'%v sR6- @Fl- G7N86CE"7yѝMڧJ~[3}~yyyzܹ!𷵵AMMMa$sB{X(766:b<։Eq0-|2i>j3"ϐ4#*SDz9J/BH7-B_|)W^ ]wSήG߇堏D{nWI0_uv.=ɓ a&#¸dT9Ƿ)-ͯv;~;L*F,NhwTS\7|*:pj_[z} w_B# K 떬ݤлn7ӌ\Vl3~ pl( pX耖o¯xvrk酟}rѩJi]vbKur"f<9klKmpR.vmoknX `IPq,@EDlC꠪*qy.[n#F@ ހ O( I}"vz!s9!GMC2!~ɟHd  yHqE]ii5@ܧud|US|AX0Oav5dDK?,KFq|;ӚiT?fq\6Naaf,Or Mk="w{l-1؅ڗw/PJ黑iٵ=.鳊9Z۱¬3ap7@eg{_,\ZZ#/V>jHO:k l\ Id>T͂[$#Gt#NdO~ŶKl[sZc[n@4؈:ucm{[sE"HcX,'''"s='Sj/GOr;v 8ocԧ>׿8N֪vrg!T2OS}E\® "<Γˆ0rrLXUQӅ~ܝ.<,ٹ~)\G'?'}Bݚn%w&CKs+@J% B4<|%˚ԋFޚ@#_P'u2;+uა=T{@k@_ g:aۣ}3>a*d`jVn׺[$vp"'~]cfcXBH _|1wyгgO'>Ajw`HOD}խ!?ӟ.>ɒ1w {'fWMFuqɨrDa2TK.'[%y8av5d&Dq|;ӚiT?fq\:w?D{& 7=-q?mϵO ,qh&[HE"`X,E"`X,E"`X,E"`X,E"ЩX~o3?AtA>\SnaOqjɄQx.GK4tawg8O.Kv; HOTeT7#NôGYOk,KMk+fX,E"`X,E"`X,E"`X,E"`Xr% JPF?bvôa&͐e=ɓ a&F scGq|;ӚiT?fq\:w?D{ʨn}BÚSK?%V"`X,E"`X,E"`X,E"`X,E"`BSg#$:½ꧺU>M2*ŏ{'fWM&tv*v"5QӅ~ܝ.<,unI^EʨnNV>`MG_1c駟+kkhX,E"`X,E"`X,E"`X,E"`X,8z(9ɞ^SB?Us.LnaOqjPM&,lj*v"5QӅ~ܝ.<,unO”p/ԧ*t(,qA#sN:t(}ݿE"`X,E"`X,E"`X,E"`X,E"C޽{t[}s_!mk+fX,E"`X,E"`X,E"`X,E"`X,1_o3τs9'FL+j8?Ҍϵs ٫~[%}j\Տ=ɓ a&C40'sF.Llveɮs|''S|խY}T@Uo 0,yTht[GE"`X,E"`X,E"`X,E"`X,E"۷ӟE̊XD$znFV&?!t"?8HiM4tawg8O.Kv'ʓupg~E"`X,E"`X,E"`X,E"`X,E"`X,%K{Nv ':N^gT9Ƿ "509]"<Γ˒]6 (ON&a(E"`X,E"`X,E"`X,E"`X,E"`X,}"ӟI_$8UՏ=ɓ a&C40'ۉDM#LNqw6d׹M~B>ʓGWvgLபSAPPQAy4554sN+7+{+_jikiihfif8!88%(" 2nw3{>k{{w@C @ @ @ @ @Mp_11~,&EqV)œ0f})mjvX'rEG:&5϶m:>˜kZ_b槔11ØR"ܯa  @ @ @ @ @#p_>c9Z` s˜ծmaryl<&U0R c֯ek}bR>̍ØRp3Og4 @ @ @ @ @/?ßtg}-U@ŪŵZ@H9T[GX]~-[˔6W_Ran,ԗ~I @ @ @ @ @U=-/xX s }&$TQ-/VƬ_2;4?T}1Dp@ @ @ @ @ @~ ߊ-:bXΖyMn=aQ-/VƬ_2;4?T}1D_J@ @ @ @ @ G+VDom_ uLͳmr[y#jy0fZ֗)m1()X|ejm*Du}TˋՅ1ײLisŎE1O)U|aL}) @ @ @ @ @ A[[nm1k-SlV!zHZ^.YeJ+v/i~J07cK z꩟qh@ @ @ @ @ #Ç?ßtg#Br-ŎEjqV?2LƬv=mSėCαVgۤ6B1]OiT:s,:6yMn=aQ-/VƬ_2;4?T}1 @ @ @ @ @ [[noQk-SlV!zHZ^.YeJ+v/i~J07c#ܯA  @ @ @ @ @+|+/:[6B̍ØNenCx=ڻ'ViJ&(Zt|ÙO @ @/K9sS(@ @ A[[ndΖyMn=aQ-/VƬ_2;4?T}1۝p`./x!ܯ ) @ @ R@߱o3ru @ <W@~QLX25϶m:>˜kZ_b槔*sc0~s5 xqϺ_?JQuƙhU-aLH8b> @ @ho73N^ @ @@_!ȷ"zk X25϶m:>˜kZ_b槔*sc0~6xGչ==,\o Me? K @ @@'xծqjt @ @ A[[nhΖyMn=aQ-/VƬ_2;4?T}1ۥp_sw}qI7yּx[:LP%l&$)=B @ @~W8yH @ O+VDom_!uLͳmr[y#jy0fZ֗)m1()X̍Ø"?k 7veORǣQDV} w++co + @ @JAq}' @ @`!pBoE֖"bΖyMn=aQ-/VƬ_2;4?T}1[\/"C7?"~Y=/E;LH4 @ @ 'x߃<[.}C @ #pBoE֖E1y|ejm*Du}TˋՅ1ײLisŎE1O)U|aLWdPܝ6u[.Vۗ߁A!"n\@ @ @E 0.ޢxۼsp @ @Y ܯ[uΖyMn=aQ-/VƬ_2;4?T}1[]`ɇnЯpGN#Ǻ3nV]}v#&(Zx~-˗!@ @ Oq]P@ @|+/͏k-SlV!zHZ^.YeJ+v/i~J07c그p_VVaϾNY 綻f|٦rn 6cW s`jۆ ƽ7 @ @ oRg8yK_@ @ кWrSB(70uLͳmr[y#jy0fZ֗)m1()X<}ybݻ)W.p78M~k;O9 T<*'6-3ٷyowgʝgfV׹xٹ=eC+d3AB1 wK8!@ @ @0.`7OqfJw @ @ ܯ[~QLd,_lg @Fjbual/S\c~QLSJ߇xSU >=2{ϸi'|}uAĭ?Z?l'//yf"sLP4 ƹ  @ @ Иo\g8ys@ @ жWrB(74uLͳmr[y#jy0fZ֗)m1()X<&}y6DNfnʟܜ~^uQ<:ɟ8hs/8@ @ @1 0.ޘΊq"I? @ @m ܯ[&~QLoh,_lg䶈WHZ^.YeJ+v/i~J07c귙p_oN劈奁y [WG|VD&$V[C @ @% / 3Nn @ @  ܯ[^Ŕt,_lg @Fjbual/S\c~QLSJ߇xSͅW33oe%nk;)k"anܖ}y.:^F]3޽2+`ŢE܂ ҥܹ yc5]t{衇ܹs]}Bb{ulO5Ͻނm @ @V 5.ŋgLv:u԰|'O쮸 Zk3<ѣaϵ։58CU?1sod@-껭nh>{~[ Y'/m;s9ƛ}}gfh 2?99]X9 @ vC~r?C(>uLͳmr{ys^lQ-/VƬ_2;4?T}1T/;> /{ .&o7L,"kA9$f\Zc_tW^y2eJi裏v#GGgN&asO/M.'$M'7zke @ @p]PwSݫU8q_}|K[; ?~z޷2 ^^%{ u[j;x}Qw5׸^{[n?x7p`|݊Vto|^>;Z i\~Wnk_Exq^t?3ӆ>pu/"??L6?e3eՄG9fc*8w2uL֕|~i(a5r! YC_Xu̜S!@ PI`1[w_ǔ͕yG-W8bz3bZg<&+Gp)#jy0fZ֗)m1()X<ߦ}9{jd~sdriX??eX?E__Y|]wurX0h]QU~_b;69FOd2U7_~>qAӕYچ @ @B@Ɣn>pp5]IybT/^bw_&)^ޏ>k~L؋̘|^^,J#iW0o /{w/pB[j\\s:Y~`d}9N=T'hqr7V/b)ze+JiVyE^lX?P-Ͽx{f݆#X? ۼ[֍Zi a$O w z/JjGڊF^qqt).o }޻W,Yb@ @`e$^}v]:~mwmOE~^]VsO9zˤfײ#ܯP֖XŊk<,c9 *R c֯ek}bR>̍Øm*ܷc G4ww\3["\Q?ڠ-5A!1k,w'K< >O.]=ն̍C6[̯#_2 &^}ljp_Wg=wwmc,v_]H8 @ @ >=҉(KWx_vw6nu4<=vw[mU7ᨱؚ̘|iί?dA<ۦ{1"bEiqz]p=:ϛ7vwӽEl.ׯ_ LƂ jڮiGdy?_;nc76/园R^*hs0t-gn9 <]6wVX`~z'G(VOߴ@sؤךCF_ G~M7czEDH澶nh37OrK @+#r~Io--h_|3]ZD_!ȷyަX25϶mюGX]~-[˔6W_Ran,oS~s _9lPlrX]qY^{N:養]|Y[lxb[om:uYg>ϖ~-\0[{]2#|ٳիWgHoQb}i'"kzhZDϡ%FI}nt"ۖh쐁$\.d2@ @ XV nVk~Q LjGs eS~5U4Ҭav_|g{J]O6?M81N;.uK^,vQG8 WcwGXc ׻wP뵔qUVwnN2-]vh^s~enjy^KsvzݒEk,Zk!W0s'۴W.݊.6}m c?mO#ܯB(V^a7)EO"V!f&'z3dƛl Wnx}ê)_ok'2Ѻu;ٺ @ @J@WUJƥ1p!h։=/r_&K7p_緶26g?f[%OwW59^zo?q^# , maNk-1..:,_2[^R+#~Wb4cb߿gd<3pӟ /4d{fmtlK_uce/HLu<_Vܗy=^uwE埡q[?ӳӘeŶk.E{s v#n7wj=ߩ[}gn#mK2~{w}ӳU5"Kwn>WwpdKlc`s_';jGףslݮWNڏϗPV݇~]+YW{F"?k g9// [+[= +\⾍ˮ,RHwm~D3ľ=#3\ww]zybߑbYC'(bQJܝ6~?O}r*`/V(Lm7r['j}k`?3/?jG= @: :pw ^폛z{pBoa[[nAvΖyMn/?JW%}TˋՅ1ײLisŎE1O)U|aL6OX7`ـQS$o]wuѺk2qyI&ɶ{oa&lMD^LY~pW={t?OUI~[Ch?|L6p @ @ X2۶MG5}gf.{A|ӯ-M9D +eF7 ?,\\hldEK>7Np/b9q#>[2Ro~NDrzNyj]ܹs)d!{2dHVXΧ;D?=zy3w=+wO.FAyQn5MU~Y~xS \{gwv{6[N;~V{ES2wHk;$V;D[.vkw/ޟv.?!~MWN~[iz^@ @5~xkk> ܯ- XQ{e0/*l\Ejbual/S\c~QLSJ߇xSMW>=e0@\|[bB?駟VR_JYu^V|ݺ뮛Xosl!u}k_V0aBҏ䁬#rH0f_|1[Hя~6xpnwtc=#<~g}ʤfSO/<__&Kp_&RfHgҗdЯ_@[7^{ ͶGJ]W~9e&Ju@2 @ @@'PM^|G˵}>rBg7쓭d,3+V/dW ?9ǃyb&h#3%"~qٓ8;6woNb+mW o6[j\|ܸqN!IJ,l馛:Y0&vX=ܓUz[s5e|YOe3KLvU3d,[VUWUٲ ',XPѧk{'kZEe\Y緿ǭ7;a~! e_`Hv_nϔso{>5W.%u3w'n^p}9F1~O^~ٓ:a B˾S]m ]]d T^~ڏTm+Џ E]>RUYvkU;)8Y!%/.BA77K!}YwRw.t~7%;߁ WKw\Q9rr>'"/<_ @++jIkWzX[b_+j"_#jy0fZ֗)m1()X<ߦ}Dŕ 7mfIBÖS:#쳏;mwlke"K/4P2I_"JV+>d{z(˗l+$ۍ9r9LR|s&$+z*"ؗ㳟lvv}?vmQ#?:̗ yy%FNN+~9dc7qI  @ @bRM/p?%ٍ?bH6E'$9dl9T++ W+f`v}Y_yMqxAllaW[ E~gg.w٘/r3"_xqjoW⋝,v#~[TZkl.]d9Îy5Rg9#5 {l'[I;*{de:y @++~k^ ܯB(V^a7)F@ *R c֯ek}bR>̍Ø2,#~t9Cwt׽*$*E#-5AaYVꪫK/dù-$$[tI ?ݢE\ȐUd^w}U!ٳg;Y5H6W\qE׿V~9DYz߾} +܏>}ϗC#sG#LH\]<:#Sɂ$wdqޙN[>'(8 @ @ ` /W|ub}ãJa=VPz20XDvkKĖ~aLدDBKɛE"?"a'ڳ5Bْ"h۳ue .1lYI~sR[.1^D+7x|' ⊧^ͅ;kEYe?Z"eL~?NȾ3 ,\t%tll?a&pnCܑ~u9D};Ȯ Czw[nx+XjsMϾ2Rp?|yrYm[۞Ҫe/0}7wUg[F6>?;‡"z.3bvC^òo셆jokȇ. ;պV7O[-c;dK2p&e@ -t_,`ߩOvk~ _%EXaN/=R c֯ek}bR>̍Øm.ܗRݖ$@ʴkܖE_y'+ą$n+/~@_J+ܗ d9sfQz>!'ܔ)S+Y:>¶-Ud'Rbϊ0!i *)$+at|W 78 @ @ ` 70JE+^p~Q専Z&j ǫMWh/ݸǚ8 pS!G [2>n>hӯg 3~462 -$?d"zdeWY;vuE-6ᎱVea'V[-[FO plXvB#YFf_쵅-owC%ʀ~CgZ$w@" @ @JA E :x je䌻H0-Uߊ&UHiۈK\V@ǯ޻wr.[$F8b\|ҥkurK@ǑeE>;'#ɘAynbj͏=X&ޗ޽{O?=SNq[fˏH.R׫Wp7g<'>}qn{/kgb}@~Ȅ/U@_VVNzׁ3~"%ݗdQ|r=;yy3wY -{2zgńʷw\(g>&w,Y_+T 1y]kaWE1p /O96r\$;sۓ杖ȁ @@{&"km> A\ܞ/魌k-SlV-hHZ^.YeJ+v/i~J07c7p_O->62~٫ڱj6l v~Ϟ=g>l^{s9縩Sf}_}ճ{ebذam߻n)? 9_'0j ϟL\r%e.1{l?`lBV$BYਿ=xqG5/mގdt @ @%PM/1w^U+$޷Z1bʫ ܲxƪ~LSV-Ӌ_e~={ ;5:̏I?; F#K?Me]Yh9˜kZ_b槔*sc0~e^Wv_~leA]mL'^YUڷ~kF-w cܹ+_J6/[D ˊ?Z&vm6q o~3[aHV+ݚk勰.r>`F- ґb5*ǔ)SՉ _}|e]_bv -A~ ~S| @ @&h!OhQVP+gD1:r'7?}?[_xR ݻd&Ke;mNتis~4kEOձhձ[b\_w2-cպL?&l/c2NxLl!O|n+ʂ9wyBV9ɸ,JGLOs=7K0` End]u|_7gu]n<;e0 O5}ٕc跬߭_޹~+o#FUe A{}Qᾬύv 6Ѿ.WyOl c.#xA/b>?sy+rNk)8 yo+~ڼX\^~|ԙNO>'o&<_k@p_b!ϣδne(k_+_ouسou˴ @ Lhܴ3l6c Z}|+ܞ/魌k-Slh16R c֯ek}bR>̍Ø !?wM>==dUjaCMrZu-1An'dࠃr;s6O;YG吸n{}/8_&;d3fdmy睬k_=z7n\Gcƌqx[<_#U/= ;#3LTȊD2i!'!QeF/] ⯳Ysxp Ue@ @ QCVo9"?/#V fmjcͶZ1)+ܗU?zXre}=}w_wV*g {p/8_Mgղ&E%^+}M鼇cl/9Ejd\yB4<@6f|O=T뮻fzfv߾}x_GXs'+KӧOw26n+p_OԑO>9k&;N<9%({-Y_fwM ^~+d;Slop|y=h‹I\?Ƌ뛦D9=:ID.+?* s!t3;M(3V w[}n ^.߿rؗu&5֭_4CVnNܣXrrՓ_//\]ԫ\~AT8Vam^,nc<ܞ>wUYEK:u!/܏҆"0:?ݹAwrK?r+=]YEz_.`?U:mU<~ʼn@ @ ȿ=|ܳiv/;dQ?8/t{Gf '̰fWzX[b_+jM#\I}TˋՅ1ײLisŎE1O)U|aL6W09o7FJ:iw}DJi ن_rR&DzeURy&MLH_|EwYguENFHs:uev#~؆+lyNV%O:養-(3m)aBB{O?.z"? I/L~A=ps ݿŗU% @ @@H k~LQW@J\͓̊;ʢE:+BKYe[enڈ?5 3~~= aWo[j\^r_Wc*b=zԩIjwH4*2EĄY?|+رCe%~Y_sEc2N~[1:D?4Y^^v\l]r~ck׷8zwbl;jG'߹V/n>hӯg>4?w*YJ^1@!=Ѭ:e>[/CXA~xqVnbz;cۍ*>V>uMj?"8/QQF//DvC.<~1_}as_iw+J9׭srgȋC]w-_ ʚRfpY @(b+[Ѿ^o})`쿪_2#ڡuM5;_=&g:gvPRHZ^.YeJ"W@IDAT+v/i~J07c귩p_%"x}gk> b 2GKMP5xsr*JYQ裏vkVE\zk%A&?p[J\VO##F8 ?ݐ!C-?|7ql2ᢋ.ZN/nlKc]a_rGuw}%WVAeyn3l'R<>eBBke[vor%!fGxRB @  +ޏDw>[U{W'f7k}{-Jء@6&~bnXI?o7 ?kas( y힍m޻r"?_n)U~gڣԴox4{@sڪlqYf_sx}2f|aeڅ_$O/2w=T4=lY+ ַp7xc6N/u{wM'W]u d7ݞ=?g58SLh&;.48%{ ulI*YE_&ۓ;k w]ekesoh?+v+hѫ [)|KVğ{]dחN~Gͱwxuڔ_yW~U=KY]^^pNvѮ%X-d_ @iz @Vvtw7|zlюh_˰e۞v*YqB|oE_[:[6=%>˜kZ_b槔*sc0~ iS7v^~˻dϡND<: [xZ,%'(IpW_u~ҥK̿YLիB3gN6  k6.a~_RlFk-}OĠ>n]+g_0ufB|?q@ @ ZD(c| @p?m, Ptx~oa~q ܯۛcm_:[6-ca+zQ-/VƬ_2;4?T}1L{fϜO#1AшQϩ'$,k˪\2i@ @ @5 0.ޚ[}h?䥂ӷҋ1~g;^l܅LEH^wz@ /+VDom_ uLͳmr[_Gjbual/S\c~QLSJ߇xSEeuM{51wRw߫ 9]+u e[oJͶb^%3ATۮO&$ڎ= @ @ TY2N^/9A f-TȣqXE  @V+VDomyB(N,_lg @Fjbual/S\c~QLSJ߇xSń"ؿx@VmBGS'n=`MTVO!FNs`B9( @ @ Б w9;:6 vb"EݼK;su @ %pBoEv_Sα|ejm*Du}TˋՅ1ײLisŎE1O)U|aLWs.o?Nps.PRph @ @ڎmǾ5>q֠g@ @ 'pBoE֖E1i|ejm*Du}TˋՅ1ײLisŎE1O)U|aLfoZ.27I5 z̈́D Q@ @ @Jqq%1K;} @ @X ܯ[>D|ejm*Du}TˋՅ1ײLisŎE1O)U|aLfOm|;/ɏBHk $ @ @ o۳'8 #@ @ WrB(5uLͳmr[y#jy0fZ֗)m1()XD|ejm*Du}TˋՅ1ײLisŎE1O)U|aLf겚zIܴ&$&(띋7q.D!@ @ (ŕD,' @ @`#pBoE֖#bΖyMn=aQ-/VƬ_2;4?T}1]/Q?՞Ym5ݜK:&(-&$*p@ @ @X!P;b @ @X ܯ[ >M|ejm*Du}TˋՅ1ײLisŎE1O)U|aL˽dϡE|D7yּh}G 2AёsLHt@ @ @OqgH=2NHws @ @@_!ȷ"zk /͈k-SlV!zHZ^.YeJ+v/i~J07c귘p_>vXg8:wی+g0A$:FɄDǸ\ @ @ ro93p8@ @ W:bzSbZg<&U0R c֯ek}bR>̍Ø-*ܯpMX u?@ @ @ 0.LGnp. @ @~+VDomE1|ejm*Du}TˋՅ1ײLisŎE1O)U|aL}u˜kZ_b槔*sc0>:2ME. @ @ bP@ @ @ |+ k-SlV!zHZ^.YeJ+v/i~J07c#ܯA-~ZB @ @(&p 5 @ @@_!ȷ"zk /)X25϶m:>˜kZ_b槔*sc0>:2ME. @ @ bP@ @ @ |+ k-SlV!zHZ^.YeJ+v/i~J07c#ܯA-~ZB @ @(&p 5 @ @@_!ȷ"zk /)X25϶m:>˜kZ_b槔*sc0>:2ME. @ @ bP@ @ @ |+ k-SlV!zHZ^.YeJ+v/i~J07c#ܯA-~ZB @ @(&p 5 @ @@_!ȷ"zk /)X25϶m:>˜kZ_b槔*sc0>:2ME. @ @ bP@ @ @ |+ k-SlV!zHZ^.YeJ+v/i~J07c#ܯA-~ZB @ @(&p 5 @ @@_!ȷ"zk /)X25϶m:>˜kZ_b槔*sc0>:2ME. @ @ bP@ @ @ |+ k-SlV!zHZ^.YeJ+v/i~J07c#ܯA-~ZB @ @(&p 5 @ @@_!ȷ"zk /)X25϶m:>˜kZ_b槔*sc0>:2ME. @ @ bP@ @ @ |+ k-SlV!zHZ^.YeJ+v/i~J07c#ܯA-~ZB @ @(&p 5 @ @@_!ȷ"zk /)X25϶m:>˜kZ_b槔*sc0>:2ME. @ @ bP@ @ @ |+ k-SlV!zHZ^.YeJ+v/i~J07c#ܯA-~ZB @ @(&p 5 @ @@_!ȷ"zk /)X25϶m:>˜kZ_b槔*sc0>:2ME. @ @ bP@ @ @ |+ k-SlV!zHZ^.YeJ+v/i~J07c#ܯA-~ZB @ @(&p 5 @ @@_!ȷ"zk /)X25϶m:>˜kZ_b槔*sc0>:2ME. @ @ b--?M_>x @ @|+/C:[6Bek|V>mSFM34K$@$@$@$@$@$@$@$@$@(܏g         HC A[HvOIV!zH:GP\m,P;ΧIj!v׭[W7o.Gy&MȮ_-˗/iӦٳeylB~pQIHHHHHHHH* +ޚHHHHHHHHHJ|+6ot!CgqvLd=ra$#[\v.[6v$ؐiԅ*UM/~ iٲҠA!c mٲE OdŮF o3Q *$         P3:HHHHHHHHH8P!ȷbdkߎ2ITYGTF9Ņ|m粵?Mmcaq>ORޏ }KU~j7tAZh!W%K8a0b}W8ٺu\R^z%7ol޼L)O7$@$@$@$@$@$@$@$@$@$KX4          T([o(^l4ΎlGek|V>mp}>X;0^̞=ۉ׬Y#7ndGQԪUKvm7iݺl2'w] ,P_D$@$@$@$@$@$@$@$@$P. P_.'M$@$@$@$@$@$@$@$@$P P!ȷ"zkcvOW9}NgD #GF9Ņ|m粵?Mmcaq>ORޏ }KM_n]9C㎓ʕ+˧~*/|>_J9CcFO?ZJ6mT`LYpP_V@$@$@$@$@$@$@$@$@$PP_V@$@$@$@$@$@$@$@$@$PP!ȷ"zkcvO5}NgD #GF9Ņ|m粵?Mmcaq>ORޏ }KM߮];СtYz)1c ͛{q }Arg{!/˼Y,U9 GU9 EgpX:ek1Bȑtlq>g۹lOSXءvO*cC~ߧR4Hի?h_UVSN9EZj%k׮w}W{= )S5ej9x2$@$@$@$@$@$@$@$@$@xx$@$@$@$@$@$@$@$@$@e|+6ot}CgqvLd=ra$#[\v.[6v$ؐiԄ&M>L,X o,^8e]\C=TZn-L<9 p$iX$@$@$@$@$@$@$@$@$@yuymEE`۶m2aYruY>5ud̘1RfMׯ󚨔_}zRZBEqXb̙3%³6mڸs;wxp4lذP]TC}6sLStA[,e ?aV֭-\P~a9CSOpN  3VDom,ߎ҅I.1I}4j4>I{?6}.5>^zIm\FJYfҾ}{9_ eqUxN$@$@$@$@$@$@$@$@$@qx%MӡCwqryu xO?}d2vX_~t=4.Pn]7n YZE*z}|a2D.]pWk!     P!ȷ"zkߎ)P:i$#[\v.[6v$ؐiԄ[ȶf͚Y;cA&O?]^|Ey/@ K6E$@$@$@$@$@$@$@$@$P P_WVTV^- p!S4S gԨQn_egadٱݗcb:wuW ϻo?'ܿkerWV1Tbnp οo߾{ԫWig9Ы겾7o\Ab–%K_=H,9=6HBWrevEyHHHHH  3VDomߎچIV!zH:GP\m,P;ΧIj!v 7[F9~=\{, p$iX$@$@$@$@$@$@$@$@$@yuymEIU|;^ǎwNo=ժU 괥Xp!.-q"y/:(/xGq";SHC(Ǫ??ҬY3~M:@$@$@$@$@$P([B~;Χ>['c";~gOvP\m,P;ΧIj!v _{57oL6M n_bEx^dhժkN:u>{3"KE~πHHHHHHHHHbpb#lX~oٶm@čYs(B&o޼:hBnPQ?4n8:. N\L:J+㾲a_jY`AWp_c˖-.? fOel:\ M6 Qk뺢?t]}7o s~7mTn 5,C ɚqFqIƍ]X͚53~uuR[$>ɹ{}իWOwΡvuXzؾ8[y_|;s/M ]}$@$@$@$@$@EC A[vO&}NgD #GF9Ņ|m粵?Mmcaq>ORޏ }KMx֭+W:=n_Gu|{ԩS,*<'         Hj<&?ȹ+"3fȘ1c"!sl2#B?߭O/t2 ܵ]tE`ڶm)"uq_i@GݺueܸqN¸zȉub\w߾}3~vy3|I&M4oا(AC^F Wr-~.'G9?ɡ5qOO?1{__i~(guׁy%!̉/ ٱ̅nΝ߻je^0av}hJ>[o-:F0}]ԗ5ݺusIꮻ:i֬cQ/7 ?i[c=_/ŒNvm7޾ꪫVZ%+}_|,$@$@$@$@$@%K A0[|xu8;&!/lI:GP\m,P;ΧIj!v mjt8dΏ+CȮq,z|:6W], B_+C yN޽{0Wzc^a}{キpC(Wv"{׽a;Xj}sC, H*xy/ sNF~)! s6q2;Vq_W[u\5b=Pe]&;v uE_~Yᄄ2쵠h"F@\=rP,|E+Xa.[n׸o9K=xY$TpNv4ku'LsϮI{?6}.5n{2k,?tYFp.ȤL$?Ѝ9JO~IHHHHHHHHH*2 +ڊĥ*bddq/r Ef'!^^+Dr̃ C?{lQX܊!߿׿v{GW1\ݵkv1'$ugg+8/Șmߧ"eUd$, odG "5XvTz~cn+pWɓH)c~/D yuڴiŞWVtqlQ EVz|M;TBqÇwYQ |}7tcOwo^_,r~(ja<&vIHHHHJ tю-w>!9v(&[%w6:>V;ڎf}hJ>;&i$#[\v.[6v$ؐiԄ,/Ap{ܘ/D% nR& j+~W>(/#         ((/K (V\H !Զev~0"K[a9ĜGv"L,d?~{Yf!1Ȥl8Θ1 y:H 1>'|/~SqB0r7 i^=|X:l Z윺vSa;]o_~k0gqtM G- ҩ] qmIq*dz<--m~*xw8=%q7ipS:a8l{m 15^t$ } ̅x':u^vx6nWo>bĈX{5ZA۽&Q>FO4Ix _=i՞~YAI;X}qZ[ֺ>|{녯؂;w\_5ߜdNX+v _ 8ikn{nݺ>`z/q]#_9x {׮aM$@$@$@$@$P([(~;Χ >['c";1+tlq>g۹lOSXءvO*cC~ߧR7lPw_ B˗˲e\8[7f͚IVq#ouq)O,(K<         Lz<"`ť*l%tRtdXƉջv*zʘgPUԉL[!(K8h\Dr~Ggu͐ _!XpaK :"wEs1q^ڔ;]p 6-B (Hq-"u|pV='=.Vpc4|W˂ ^ ڎk_XwqSXᴽ6m1k/C_hoYZ~yXQ`gूۻ,]_İs~'r饗9/ #l&e3a|_ژϿV{!Q=0c qŲ5K#bJ;:sܵ#v= r/an |2^QVߋf{a:bHHHHHdJ̸3j+6"vOg k1 xaK9Ņ|m粵?Mmcaq>ORޏ }KU$BOr!N7߸Ȱ}}M@$/vT Y)/ HHHHHHHHHD(. TA|:$8 ͪ\+bK_d9t3$s<#Bӧl^G{ʔ)L(x5p%觟~ 4^4uKmkS!>?S3~@cI /Dž1ZTm_PwuɿvZ 6n:kSvqWZxA* nU|Nv:j\ 5.rrҘ u8/tzMzI2,,@IDATY_.cuO@[^Chn;VkqҬL9X;urwB\*ևV*U E~{ϚHHHHHP!ȷ"zkcAvO/}NgD #GF9Ņ|m粵?Mmcaq>ORޏ }KU=>./v|7Ӓ$lO!B܏v[vçΝ>_ eax$@$@$@$@$@$@$@$@$@ay M $.M"KEVkŖup3cB}$hBgdׂ8ט%$ޒQFt!&u;AF~%*-7h@zuͥǵ|)?f݆k9r% -z>qs}V}<ׯ{5k&sKu 7/q| {m^.XyھLᄏ4j}L^QV%!G(pmvoRzu6M ժU˺u?/cz٠< ^evo GNofv(/    (voZfyڈq>-}NgDw"Wj#B}϶sڟC8'U|džOۥ.]RF Mƍ[Ȧ مY6lpqhCrGO"{%_>VM~iqIHHHHHHHH* +ڊz@H$nيC"rcE\_JAσlpg…( ηs۷o>[ bk̞=[;E2l0'v< >4^CY .Mqt>=\J}X§aI[oU\ xSN=z62uO6z.yz(i}i/ kSvH$O}av6m9 م^X;e]fOSN1cƸj *ooBh_տ'wwxz7 jժ*P뾴/I>Ǘ_mۖwB^Chn;׆Q>iٲ9آ{G}`d'  s fbG^>euϚHHHHH)ۊ譍BgqvLdgȝH:GP\m,P;ΧIj!v)aA$'|jʉ['ꩧdʕ. n(fp4_}U7 qNN;dOf#Fp7C!шHHHHHHHHJA,oBRU)DV owxFmZa[BḶcm@QN:$_lg8]tw<"#>j-*GۊV2l\ṡ#4^_-W/Fs>قDܷr@lvwqrypWۯs㐙}V]jU/6| >8ݗ10kAI,qIHHHHJIϸڈq>-}NgD6-I}4j4>I{?6}.}l4dר_ [ nFK͚5; egv_j|q _u 932,Ffǫ*ج3|RJM3'7Lǎ~wx$@$@$@$@$@$@$@$@k=y5C N\j͛7Hx2rH5o0׊-Cup1bOJnݜ<~mAt{nhSNc3wH~4ydy]]29x>v<.{)wZ0.Wݤ; ]8wŊ#D, H{ė$ϓWZ%_]ֽ@ 7FXt\v:ǚHHHHHP!ȷ"zkcAvO/}NgD #GF9Ņ|m粵?Mmcaq>ORޏ }˭p 7 qNp o n>GiW\n5nizL۸gMоҬq}Mݻ5J⎭7߿ Rۛf8g{\ϓHHHHHHHHbpb'x^z~>3=_$gABrgg 0Є/{:pnذeVQ=>Dxia{Ų|Mek%lg+7w70MXc`\ܵڗSC9 u?!sN_~`קi廎XKI0g׍ KqW^/3hcY︿u:'k     #@~ ߊ譍q>]P:i$#[\v.[6v$ؐi\ pvdf d?d/Rk}Y@1tOfڶ7Wjܴo':woo\^I$@$@$@$@$@$@$@$PP_6SBA_ v۷g'(9l0={v4 I&.3#LzL: Țm6u \CDIZY(5 ycN?2>ҥ{p#~ݺuK'^@tdLۘP:PuʭO5đH M&VD~'DskAyd*Gt<ú♙g  s#Fdd.L^|E'|mۺxnxcLUVr{\|d8b#:ͮMH/8dmߪowu|%i̙Nw/cvm#Џc!ߍ‹g|W=Ol,/Gyb__sopd?@}dZ~ۧrCs5pwd0ؿn<np}5qDw,.g}"[Vu~CR:ШQ#7?{?^VF鲞9 /d > Yw=zGu]^$u      (i;71?C"zk#otP:iջѐF9Ņ|m粵?Mmcaq>ORޏ }+pn*#.Mz}rG !w޽M͸2w\yeٲeBk/93[oU>ObpÆ f͚k npْXv,/ҹҾApM㟸Tӧ;~>e=6SO=mD?lYg Z?OO<ݺ'( @)p'8'DߵkWիWt4j=\ٸqCR~ L4)^t˖-]O?4(? %񲈖&MHڵe…r/@@YWLR+B,YFaxy>D7,B$@$@$@$@$@%M A[|xu8;&UQHN#B}϶sڟC8'U|džOܖ (3fȈ#r@vd,?Yf圣]vrWxӯ_?Y)@(c?tP>\^E>Ҷ=?a/VWlݷo_~W'zrޟ|I>u7q7͛\+$@$@$@$@$@$@$@$@E"zo4tO#Cc{1ygNp?='|R}YAb[p /#<Һi@1cvir'/{9 H;c3"E]$͛7/G  3VDom,ߎ鲅IȆx%B}϶sڟC8'U|džOv_kF>g^2zhT IKjd„ S:歷rն_\Ӑ~m#y\K9s >\S=(ЇS:i>ÍZ,Xt uQ<=9HHHHHHHH P_:dqsذa2{lԩKf. G}}F{73%-Wgj*Gz>d<*WÓ-w6mmٲkР4nܸ]OHHHHHbp?CoEƢ8nP:i*DyI}4j4>I{?6}ڦp?fHI u&p@$*g}&'N}>nA8-gu}Ѣ!4CN9 ЦgϞRF wS_|Q Ə/k֬bpm͛7>Yc `):3ΐݻ[WV۟H5uTN x`v{OƎk c03 .GuTZUo=#k ' {F+~k5Kw] -1$@$@$@$@$@$@$@$@AҠzoԿ'#v*z!be( @jg|xu8;&U90Α-.l;ij ;Ԏi|Z~lM~5͐97~zn-y睂X-UT|e)Ae]&˗/wݘS @VZN`bzq17p{1!r0X!AM7$=TV[Ni}H) KZڴiO~3>UxhrJ{Eǎ巿̙#थe˖.3w}W_k"߆ d/oPA$@$@$@$@$@$@$@$PJ(/%9F=Q;$pE.Aɺu\ )p&7&        ȟ|+68.F(^l4ΎlGek|V>mSFM3< ^.pdDvmҬY3'4h|ѰΝ;駟.׏|ٌp+g C\a Ν+o'㠁>.j`9r4mTã/?L2%jkNpK xI~, }M`//hp_I&       (-{Doծ]r-ҨQ#u&        ("gڠ|2xu8;&)Jtlq>g۹lOSXءvO*cC~ߧm [MW_- , 2D:tZa]5lPڶm+z4o\7n]uR>Xγt}Hh"'>+W$5tPmf#)WZ%x)b}do]VYfE ׯA wuQ{Wի!IHHHHHHHHD P_LˡH$}|sCqUV'Nhm         ([ox(^l4ΎlGek|V>mSFM3_c[OBmȑHv_|yչ_} 80 ?|']s/Εt/YD.r풺uʸqp>rdDGJ>\0gbWmڴ &+":3'        $@~qn7ڦM ?KP|Ujlj?+$        F A[vOqIV!zH:GP\m,P;ΧIj!6yl4CJZlf|ǂ,Z>(l}+F/߰a;tu>}K.Q\FaeևS:>pZj*GvAɶm09kpxe̘1OM9Q3HHHHHHHH P_̀^V\Y>]vL'O &!ׯz{~j`6HHHHHHHHH|+68S(^l4ΎlGek|V>mSFM3لz~w+7g؍7ҥKeΜ9G/_UTqY}hAq9t}ʢwXdڟ9se֭r!RfMU-~ ( W:5b2{j66  Krc Ȁ-Z">~]v~3{~?$@$@$@$@$@$@$@$@$@J A[k|^xu8;&w5je$#[\v.[6v$ؐijAM+CviӦEyG,'cNeqW_kԨ!6mڸ]P:i$#[\v.[6v$ؐiˣpԩ2f̘@odJ^x!r!c>|x wɃ> {SNba̠A?wpꫯ DB8Ll߾]:u$mڴ&ߺue-;vo.k G|}38Cw~?`oN)6>Gv=dd׬_~e4 $@$@$@$@$@$@$@$@DRస8yd8ql۶-cD&Mܽ}'Ï1^{̟?_v*zgHHHHHHHHHP!ȷ"zkcvO+}NgD #GF9Ņ|m粵?Mmcaq>ORޏ })cRmӧ@6 /Pڶm+Gw@a~=O>K/4o߾ v5rr}EBt<6l̞=[Cd]wK.DedfTű>3袋 -[ekdc^r_/edʿ2D x\qExdoР]?k֬u5g2b [v<p?$@$@$@$@$@$@$@$@@R w.uԑu릜$@$@$@$@$@$@$@$@$@M A[|dxu8;&U90Α-.l;ij ;Ԏi|Z~lM~5͐(!cQ_*#~̑br[ٕYϺtG 6۾O>Yz2Xh{{l?iPliJرc^fcmrM5)$@$@$@$@$@$@$@$@NbGp56n(5Jeڝ/HHHHHHH 3VDomߎIV!zH:GP\m,P;ΧIj!6yl4CʢpѢErWFawّs/ k׮-ro!G-[XwF֥ѣG6`ݺury+2wɞNVp һw16l!CSi&?[s==4~k^r сxQo >2b-]u1Om        &@~Iv&oCW_}.UV.yĀJ$@$@$@$@$@$@$@; 3VDoml >['c"[##B}϶sڟC8'U|džOQ )i7(\g+C[h!7tt?q.AO?]?kMgxڇA1}jC#ȬYStM?G ك W!;^F9rԫW/?ꫯʽGt@Ƣ_|]S мysQC+l'4mTn/L0A^z%;[)hʕ+ 2a11$@$@$@$@$@$@$@$@$PH @ s3ek|V>mSFM38iΣȴfw]wU4i+:c!pKq8w={8^Qvmxf͚ux@3(URD=_fG$@$@$@$@$@$@$@$sp^^}Xl˴5j$B%KYIHHHHHHHp?CoEr8.m(^l4ΎlGek|V>mSFM3\3cIHHHHHHHHH8P_T9gE$/~Dz 0eͲ`yP ҟ8qzrI'ԩSe+4$@$@$@$@$@$@$@$PA P!ȷ"zkcvOwJ(^l4ΎlGek|V>mSFM34K$@$@$@$@$@$@$@$@$@(܏gP۷o[nEZj%\"*᱐8>*.oݺU>3i֬yWwߥp?$@$@$@$@$@$@$@$Pq P!ȷ"zkc8nP:i$#[\v.[6v$ؐi)$@$@$@$@$@$@$@$@$@$ A1l&mժU."?;V 'ܿ ~XQ_ $@$@$@$@$@$@$@$P! P!ȷ"zkcvOI(^l4ΎlGek|V>mSFM34K$@$@$@$@$@$@$@$@$@(܏g͛'/6mHV.g̘!{챇qNudPaHHHHHHH*& 3VDom,ߎF k1Bȑtlq>g۹lOSXءvO*cC~ߧm بiPcIHHHHHHHHH lCEE"yHHHHHHHHlp?CoE"8.x(^l4ΎlGek|V>mG.]al6iI^s$ X[IxP_<\9+ 5gX6%k1]*sd >ek|V>mSm1(/HHHHHHHHH`#@η'@~3IHHHHHHH4P!ȷ"zkcivO1}NgD #GF9Ņ|m粵?Mmcaq>ORޏ })cB~Z%         x;p۶m_;0 4ʕ+Cb $@$@$@$@$@$@$@$PNP!ȷ"zkc5vOW>}NgD #GF9Ņ|m粵?Mmcaq>ORޏ })cB~Z%         x;pr7ʖ-[z/_.&M>ޢE ֭ŋJ*p x`p\"v,\P-[&5k֔>Zv<8^2e曲}v^wq*U#S~Gye޼yҮ];ڵkt3gΔ^zI6l(B~Yk) |+68.G(^l4Ύ;;tlq>g۹lOSXءvO*cC~ߧm Sm%Tψ#HHHHHHHHHHx ԯ_XEk_2yO9~XAާOٸq.|^uօ:g}V}`|޽N'QG%]tu _tǩ[7[N(6mRWT׮][F-jՊ|e~/#TVMXZ֮]^x~K/̘1ýdqꩧ I A[tvOW"}NgD #GF9Ņ|m粵?Mmcaq>ORޏ })cB~Z%        BbࢸMv~\1cƸ,E1R?tPޱcGѣs=b '9r4m4t/l޼9ѲeKկ~+ի뮓5kDc=x]C~W˂ }˿/yݸ:Ȑ!C9ʺk0a|'geܟ>}뮻 ׎~,$@$@$@$@$@$@$@$@|+6ot3IV!zH:GP\m,P;ΧIj!6yl4CKK$@$@$@$@$@$@$@$@$@*oذ1"#K]OpXrRNoupǕ+۷owo8 ޽BE-/ѹ^~s!Q7[nu< _J*?Qyx9_57t\:5j.W+G\72? gXNӥk1ȕH:GP\m,P;ΧIj!6ih         #!keP@@߾}{5k5ʉ5,M4Q۷rGc=֭+ƍ}!@##}۶m`L4Ix ҥçG/g+뮻wޑ .˦MP0l0g#kڵkA[n'>e3dp饗W2p@E3cŃcNJ~I}Og3>#         (([R~;Χ>['c"[##B}϶sڟC8'U|džOQ p? -ƒ @}嗮ݱcG NF 1gX5k1Bȑtlq>g۹lOSXءvO*cC~ߧm بiPcIHHHHHHHHH "W޿ZjFfK~d˖-8DA y_3[.W\q޲y漲?s2qD'G|̉b`kd>|n q~Yx+Vs|첋\ҪU+*sog+{йsgԧOW:Tڵk ^&@yO$@$@$@$@$@$@$@$@%E A[|txu8;&U90Α-.l;ij ;Ԏi|Z~lM~5 b, ل*]EǏ/ }W8Q\v~5ͫ@(:uYnwy|{rA L<,Vo3#/^9o|c㼐5RNv @A5\#|ptDO_u         2H A[+|ʡxu8;&U90Α-.l;ij ;Ԏi|Z~lM~5 b, pEyyGk׮ҫW `#>W^yo>ʄ: OYp rbƍkO0A ":tK.p &gxAOxa/Hp_=`_A&       (([~;Χk>['c"[##B}϶sڟC8'U|džOQ p? -ƒ @< qkg~v"!RbuL>K/Tm&mڴqǨTd|=W^W^4/hf/8d6mE֭[롣nD` ^r!MHHHHHHHH$ 3VDomߎ:IV!zH:GP\m,P;ΧIj!6yl4C(OC$@$@$@$@$@$@$@$@$@$O}Y6~}dG-[H-\FP~}7NcQ#d̙ eM?qDyix1"[~\h|o*W,wԮ];P @p?CoE:8i(^l4ΎlGek|V>mSFM34K$@$@$@$@$@$@$@$@$@(ǭ}w?~ԭ[Wƍ'VDzj0`5J7n,WoܸQ/>@IDAT6m=C0'2uT3f;/mF۷˹+֭!CH, 'O,&LpuˑGD/ D16l?q         2D A[+|xu8;&U90Α-.l;ij ;Ԏi|Z~lM~5 b, pE֯_/s;v( U 2_uUfiڴ~N2Cpoˮ+Wtƙg)ݺu\&z`gPPVo}N:$ٳmV/YD.rwÆ s_ @ܲeܗn*#Gtx$@$@$@$@$@$@$@$@$PP!ȷ7=eq>]P:i*DyI}4j4>I{?6}ڦp?fih1HHHHHHHHH l}d@ΌSL|0 bnIZlr/y)H=\?W_},ZH0~ΏyyG}_sΉ /5} W\qvaNЏ/)J͚5݋ "{-#FH ?$@$@$@$@$@$@$@$@$P ([2~;Χ>['c"[##B}϶sڟC8'U|džOQ p? -ƒ @ZiҤIuEb x>(`g{,#/@~G~>\}'ܯW^ԧ:tk.pk׮ҫWȟXz@Vs_dևp_qXn;n\ dg!        N A[|xu8;&U90Α-.l;ij ;Ԏi|Z~lM~5 b, ل$2{jժm6SNfg)+}G*W\JgS<ݼy{Qׇg%       (+([\~;ΧK>['c"[##B}϶sڟC8'U|džOQ p? -ƒ @< ٰBR{'xƍO7}r1e֭2c B1:D6mBW_ɓeڵkxO W$)SҥKe]v*Uȱ/nLȏs?:#$HHHHHHH*4 3VDom>['c";|.Nd$#[\v.[6v$ؐiD[3 gǑ$@$@$@$@$@$@$@$@$@$` ~]d^h)K (M˖-G}T Gڵo>^z%9sfO:urx7n(Çw_PݪU+ٳgK,Y"'N,ЇN;49 6ѣ݋~]t6^Bx]Jq] $@$@$@$@$@$@$@$PP!ȷ"zkcvOW5}NgD #GF9Ņ|m粵?Mmcaq>ORޏ })cB~Z%         xdza (щ}A~ݥm۶&/v~8g~'6m7߸}ˉ~x5*W,|#]Q~z5jl۶Mj֬)'|`ܓO>)}TTɉի \Dw_y]}8lx_A$۱55 T$gXr>['c"[##B}϶sڟC8'U|džO%*ܯQFsѻbŊ7|cwK_g)T< V[p#wʕe.1C TpW W^yE}]7W֭eժUN !ğ5k{>_3o][I~ݺuN[6mZ:^uy뭷d]v/Xjժb͛7['c";S-SI}4j4>I{?6}.1>>qz9HjՂ[n6(zh07WM&<`뮻qr7mYȒ=uԑ:(_h7V*o]]N4 ͝;W݆ &U1^;YgSgKw}{׿vCj'syX_# TDWU55 2򗿔{lj}Id޼y,x{vmڴN;-桇.;S=#ψ=SJݺu]{d ! նk(g(DWly#*&*8"8H1a8?《BQQy+ٝ:E9䩵k׮^]oѣG{eпk`N6h_| 4hp?$ @ @B~ ?чn['o}a]4.m):GT_ ۵l/SS<M|Ǧڍ&ڵ` #wu{ᇝguVޝr)> >vU׃ojLCt6p_U&O>Bv5L>:x`QGfag^mPFeQƚVZC,M6}3¶+-\jP֣ɓ'O>mf f믿N?tN:={m{ꫯgܴiSoSq-k@ @@@9BH@EZӲSeso7tӼPgw֯wJ=6lȧ2+(~?GkR&}Y`fۿ +|nu֩跆+T.F @ E A~(mq;gO*ºh\8&%Rtjqk_cey>/R>McM߻wo׮]Ƚ$t׃~UUz5 s7֜s^4p? K:rHKq &U}i;3ͭѲe˹rW'E]`RnYe xa,z 2`7a„g%yy9)S~wӛxw׻Zo Uې^~c[l_,vm۶~b֬ J}YF`@ @ =^H \Yz)c"k|l¦gzC c=vz/2kO% C`[o+ݠ`qW@ @"B~ ?ч;'o}a]4.&DuE}ame0Vv"ؔ?Y~7j! )7(#Gaͬ63LmXЄH^]_~&P=%yy=w?SHئe$֎M|[nYM^{5/oҤ1KpV( @ @ @_ _~eww;S^{eX=p?O __s:Z#.E @ @~JWC}h<x q̞*ŢsTKž]˶2u+;Y|qlp?hLଳΚ#Ӵ>+~-D3gٛ7oT^}Nek>eU_u\}6I&7H\KE[(s=].]B=]1I9wp}WC.r]+'&NXZSMYlӦM\) E}&K/yx=MEgS|hXO1~6m2{52kPM6٤p;z~WXE7s{ @  ܯ azY4?OwM7yZ묳;si"5!EI @ @oWC}h<]TuѸpLf=saZ\/ZX٩v&cSgFKм;T-$0a[r%gEy>cwyya6lijns?xklᾲR_wuN"g+&tKL bae5+=܎!nfKH[ou/b!(SOY_Ŏ>{]~;nV6wwˋmqڵ_4Xmռˎ+.ծ~mw6|'~߻>;/(|_w[hNr믿OOJ/jM_**?GWY[ [ht-vyg}ij踣Gv~|> F`ns-]yр @ @A oPL$gbE|ꪫ34}{.LV=s<38Nm%36lNyǺVZUWCϖnh}unaa^{U8IH @ @~f?3ޘo?'!ԲS<_5U}H0.m1Om1T  d 3GF9ťb_خe[:j,Hm86}n4D:ur?3ǭ?^Khy{._1qP`k_cu K{a ]% ֧ \r55׉'#}ܔ)S<mXCA޵~_ @ @#pޱdEg>ag?sG}tsT8(9M$3^I9pC2Z2+HI x֬YY*zֈp%!@ @)@_!E[ nvI[_X d 3GF9ťb_خe[:j,Hm86}n4~ObHu^ %/3fZB-&tzL8Agȟ*j#|bGLH B:_#ܞy/^Te׼k~woIyU˸l7m0T*Hk["*Ygpk6(3:n&~hW_}7hGq򁾸Aկbk6=-mW@8^|:J)v⭿kن@ @!pp /=g&ܷlz|J~s[o宿Bm}EWϾXcdZW_Q%Q+O=}A:ӳFF @ El{C}h+"nlTuѸpLf=saZ\/ZX٩v&cSgmuܨe4p_ޕm^bveCitۄp_kkl`n禇&8/" ѹsgp.˜ p9Cs[l}D!Fй\vơ\qݻndfE.ƍ_0lͩs K`_K[@2)SpӀ-L/8J cq^0;\k0i$7yd'D[fe^ e},u\tq&x A~oCƩ{_BoH/"^;o_V4_-ᾍ5(СC+2Ňq7x`/:f@lӅ6B6] Z CwƄ}1x.m`uK<5~AU7֭[+@ @|&p>_s<ᾞ J$"ƄŒcȧ>{]*۾6\z/p{xTU_Of f,q+zfzzF!zإKw}?Ӹ6>ڍ?{nVLG@ @Q "vfK[_X dQtjqk_cey>/R>McM/27*2"K`"͚5#^g%vHTEُ>`׮]9bPu}5Kc MgMt \ؕ|7衶Z+kkhVbZ[cǺQF9{|zkʒ bBй\ӹ 0)ݣ/>Sw1 >U8DY~%d_BP^4/X~e>>ef:+2[jK#ѿ{gT E˻κ6&4رobSں>M7߁Zsx!/.whSN^6غڽ묌btNoԾVƜN:;zo%OЭsٜqsyۚ'B۵5,^qRcRƎP򎣾TcD֗7l񺵡k_H/ytgݎ1>k/)yX k}lE6ah\^;6&^Ss5j%[gVm @ @hX/4 (zO_";I})C_y-͵:J=^3mYi%!S" %P!R'x=>Jbs?$(F$׳EXj@ @ (@_!E[!nI[_X d 3GF9ťb_خe[:j,Hm86}n4~޽s3۽OJt޺uk y_;CfmcY^!CmK:p@w/;YӆsOqӆ @ @ o<  E@_6m+cJ+TPz78=ӳD=I  @ @@q+>4n ~*ºh\8&ӰsTKž]˶2u+;Y|qlp?Ƙ}ԩS]Ϟ=6<3"AA2oN üϻ?ߋs*y90l,xw^_yq~j`7tۺº\alh 3vXHY~J aыF}NX>smͩ:6L2 ;v3)q1"Cb12 u֭bGضcD֗7lnSOMomΑ@܊2[e`y,^v/+͝zy#^O}㫶cksϿuQ+'ڀrM _}U)'>0&ˮ!ocw6)cquoc_߲0L;:A @ и7.o@ @ t ܯ" |v/ƅc2ۄ虣R}/lײLN|_6}>k#ܯF-3d~ ǻ!CT,7"kmK,+b+Ѭ2O[Nٿi۔h6Z`Cn=缘\u]צ"߮] 1Ld-͛7Ɣ+ycS}#N8[Vw7xËu] תUl̻4Jx-oJd6ȹSN~GvF>nc.]8} Š8q3 SyEUlRМB]"h-;X4^hCF^)^mӧߴQp?{lN]oS!mߝO>eV֟217ņDzoc5O>uuYn 6P/ᆃFI_)˗{|ٜZՓ 栆 @ @<1 @ @@ A~(my>Ü.lg:sTKž]˶2u+;Y|qlhC= 9r{駽2`H)iRa{Y3G#S/>hv928]Xc '_~jm]6GZ`Cn|N?t'a˺GYge"?swz(?ꨣܯ~+RKyQpٹ\:O`80\c=mU6~*l;=yd'J;*4)q޵ѽϵ{{f?cnĈޯq2gd1Rl닅֚"Qq_Hh+D/qJ|yY_~tϜ9o8po?0o߾B0:xRKZ&l5\7_Fn93Ck}ڗ8ԯ/+weVXAaŎoBmL|?ItD^w_ =/5W99;];mfkѢ=46XUImP  @ !pa2+ @ @ @_!E#n&J[_X dqY.R}/lײLN|_6}>k7pUW`e}ˬYĉVbLeȺYfqr,1>$ܹ[{ /I2KXإqfv;P*_,DUּFye6ϋUٮ%|-[5l(U@h&{FZ8#gw{G&7,.uû첋;#+B~mw'VF&M]vYa\lr̘1n^>|M/yBge ?裳c1Yu?OzJm 1v,v5.@8m۶u?5k~7Ͽ"Q6e_q?{ǫgBԖ]su}gtɢo/tcnqlGwkV_:篿YBʹ瞛}ɣڵ{E@ @#pޱd&@ @ @`&pBC[7I .lg:sTKž]˶2u+;Y|qlh:ĐK.At,7&2 ֧⋳l)Vw}@vlǦbTvǗpZ_r-}_¯_(/;WAC%8ѣa~F>a„>eWp} ,pO=TVpeWF|e_e^LM53ἄx.H__8餓_W/֦ 7к+2+KVG:״iS"}zA^=|n2ӽV[y!v6mСCxWΩ~Iu_ K[*&נ1e.{_Dwg EZs6${57p ٦G;0ԮUiK_裏kY1DݨS?_#MnQ[UW]}iB>vڹ]:mR8޺u>6 @ &p3= @ @ 3dߘOP=YBYeyj~V=a\ fScq*Zc^),4(:GT_ ۵l/SS<M|Ǧsoyѐy΢^2KLrmxI@pc{b%]r%،Pvxm %WYz+D9,^rez}.6,EKHX:$=ҪUcPǏ)SDt=¢^zy0.)ijJ/%m uZZSP^TB?qyŲ @ ,/W @ @5PD|vRE1mBQQtjqk_cey>/R>McM/o:.@N8=^T~V];m$fV߻4iv[?bzҤI>a_C pY0? PFq^T)q~F w{@^_y0@ @%͹B @ @ I~ ?ч.AJ[_X d 3GF9ťb_خe[:j,Hm86}n4{vaȑ#݄ P|^*6lPx≪1 щp!2'~ƌF`۶m}fw}7uo* @ ,j/jW @ @ A~(my>Tx q6!z(:GT_ ۵l/SS<M|Ǧڍ&ݻk׮]{unׯj:O9_C=mfU}Yw7ViN A9!%Hz;?Pq/;cH*:h@ @ EEBs @ @@@_!E|vRE1mBQQtjqk_cey>/R>Mcqp -b!# ѾksJꫯfϒPC @ EEs @ @@@_!E-q;gW*o}a]4.BIXtjqk_cey>/R>Mcgp+B @ @5!@ @ !pBC[v.T*ºh\8&M90Q-.v-aT;gEjDZ)v u_wz! +W);~mݶjc=ƌS5!:7U @ @Eū9C @ @ A~ ?ч<]TuѸpLf=saZ\/ZX٩v&cSgFoqnJ_|2dSrG6(?G}qu֮W^neIO>]zO7~Cen@ @ @`Q"pQڜ+ @ @ АWC}h<]TuѸpLf=saZ\/ZX٩v&cSgF~h֬[eU5f͚{=:,+[zCKgU4iڴiSɓ̙3٨5F @ @ 0?˩A @ @J~ ?чIK[_X d 3GF9ťb_خe[:j,Hm86}nT~B?B 9@ @ @`!p, @ @X ܯ"uy>'RE1mBQQtjqk_cey>/R>Mcqp -b!@ @ @φ@ @ @e ܯ"Ҹ3x q6!z(:GT_ ۵l/SS<M|ǦQ A_ @ @ gC @ @ 2WC}h iTuѸpLf=saZ\/ZX٩v&cSgmuܨe /CX@ @ @糡 @ @@+>4n *ºh\8&M90Q-.v-aT;gEjDZ)6:n2CE, @ @ |@ @ @ PDB|?o}a]4.&DuE}ame0Vv"ؔ?Y~7j!" @ @@>l @ @ P A~(m!y>ß.lg:sTKž]˶2u+;Y|qlpeh @ @ @ |6@ @ @(C~ ?чz @ @ !pBC[Hv/ƅc2ۄ虣R}/lײLN|_6}>k#ܯF-3~ZB @ @'p? = @ @@_!E-q;gSE1mBQQtjqk_cey>/R>Mcqp -b!@ @ @fA1cuݲ.Zjf\P: @ @ @_!E-Zq;x ԼaU{^2n {*ºh\8&M90Q-.v-aT;gEjDZ)6:n2CE, @ @ |ϞsϭXD?C[iܰaRK-dp?cqSNbs9ǭci@ @ @@_!E-q;g#o}a]4.&DuE}ame0Vv"ؔ?Y~7j!" @ @@>lWI=H_b>}CCA@IDATM7- 7|{G6|swI'U,51-btso=3o\1 @ @ 0wWC}h rI[_X d 3GF9ťb_خe[:j,Hm86}F_ǍZf2 @ @ O~>3j(7vXm۶s,/w=Q6md1p^?d3}-"ǀ @ @ PDڂ|vaRE1mBQQtjqk_cey>/R>Mcqp -b!@ @ @f~|7k׮nƌ.M_ݻ3g=uź\(ܿK2y睾r;s@ @ ;+>k#ܯF-3~ZB @ @'p?>}Ki;&? &N:={fq&o߾+~z @ @'pBC[v.R*ºh\8&M90Q-.v-aT;gEjDZ)6:n2CE, @ @ |̏7x _|qwWVZ.+>|zkקOЅ @ @ c+>E=n /ƅc2ۄ虣R}/lײLN|_6}>k#ܯF-3~ZB @ @'p?y7)E#Gt-[]UW]>צM7tPbzMJ^ܿKG @ @ 0wWC}h rI[_X d 3GF9ťb_خe[:j,Hm86}F_ǍZf2 @ @ O~>S&رcݨQ\?SdM|6/ǩqL@ @  ܯ"}|vϤ/ƅc2{^<9-:GT_ ۵l/SS<M|Ǧ[a ÕY!@ @ EO>u}7^d߱cG7h K/N:={fqw}K/uv/ܹw}X @ @ @`@_!E-q;g'o}a]4.&DuE}ame0Vv"ؔ?Y~7j!" @ @@>lG]vu3fpl;/̙n=t]tLߦM7tPq_4F嬳rlA@ @ +>;n¤/ƅc2ۄ虣R}/lײLN|_6}>k#ܯF-3~ZB @ @'p?ܸq|su묳NRm+p=6lHߊ W^ye7bb)SM?[|e]VXaB @ @ +>E:n쪤/ƅc2ۄ虣R}/lײLN|_6}>k#ܯF-3~ZB @ @'p?O13K߻wo}_iW_|IM6ĝvi^oM 7~x7dJ+Ç%X†Q$0}tM.,Lэ>uTQc饗_iP?k۶[}e+N,۷oϦʰ@ @E~ ?ч.ZN[_X d 3GF9ťb_خe[:j,Hm86}F_ǍZf2 @ @ O~> /gK8\?'/ROFp_}7t;egܔb̙3A͚5sc=ܭWr'6lXUz ;]-UW]?M<- dB @ XWC}hr<]TuѸpLfϋ'E}ame0Vv"ؔ?Y~v 7pa2+ @ @ @^~gJ׿UH wm7wa+b6mڸCV%@߿8qtg:TN@+I@{dy)r4B?.zSNq{PB7 p&L_رcn, @ ,WC}h&y>RE1mBQQtjqk_cey>/R>Mcqp -b!@ @ @fA>}ϝʮ/q8Y\wunܸq/}W\}Gn_}lA0?ݒK.XcDŽ+1bDŦ<>dž @ ,\WC}h<x q6!z(:GT_ ۵l/SS<M|ǦQ A_ @ @ gC~u洉bvp=z._K=x`/oҤ|wnƌ~E m,,L<k#/xsp^r @ @ PI~%ZH`{^}'6lɓ'{ǵniӦK/Խ 8:(;f>[nܵ^[h8 w)yڶmmu}~?i$ׯ_?׮];w9T쵮=6_n:wg uo=t]w~^vhN"Zp_Ǿ[ݘ1c*Yo_~ {1?}Y +v7 +x }W-j@ @RWC}h ]TuѸpLf=saZ\/ZX٩v&cSgmuܨe /CX@ @ @糡F@%M6zVNSqmիW& 70G+.ԩ^,GTic2kSbWYegbx תU+?ֺZj)i@L ܇ eW{mLfm:+sZu#Fp-WoIPǻ?8:A^;m+&[ne֭={͜ ~ .@ @2+>+nm*ºh\8&M90Q-.v-aT;gEjDZ)6:n2CE, @ @ |>h~r/ܲ.CCY%8Wy%|ر_uUСCo}ZgW~뗠^XbC qǏs 8o019rkٲϜqǹ>~vi'1ᮻr__M_ovwq8U my<@oK/:vi$~ZcQرcvr!Yf>3J9@״Be7w|򉋏!6<өS'w衇u_s5ޯ3 @ $ ܯ"3ʩx q̖x|nK9ťb_خe[:j,Hm86}F?wmk @ @@A "l' p?`+]vn%%ؗX_E۵kII'~ۋO=T/7aCu[O1~ᇊ9%޽l&۷GNbO=_ʶo;ww0Yv0KOYx ?6uŸak Eck,ѻwa99׾}{/K~S5y7^k iӦ>cmq1@>!l@ @b+>-n q*ºh\8&?ªE}ame0Vv"ؔ?Y~[r;=Cf @ @  P?{/<@e k>k%bX\sHL~7|g>|3ꫯ."a'lʊb&Mc*#CᾭKQ6{ 6hG1_ Ab~;a@vY_s_ZC[aÆ6mTL5k,wǺ)SԦkSw}k4iׯXM b}56. `C @ @_!E-lq;gSE1mBQQtjqk_cey>/R>Mcqp -b!@ @ @φT# A|7t+Enȑ^n"jOBXǏwC q-/eɏқ^Bue˖%ś?nbHێtE662|>^T y9M| @ PD|6o}a]4.&DuE}ame0Vv"ؔ?Y~7j!" @ @@>l@QKTCLʮ*dye_{}pNeş1cx3>cd+||vkks9ǵo>bPnǨGgׁ6mײ_On2}{-AW\qEJ+_oy9 + @ @ +>E.nr*ºh\8&%Rtjqk_cey>/R>Mc][c< @ @ P[ gqK/o~P?e׫W/Ovm;v5jϨ?bĈCz{G~gqFE~cP,^{^kҤg(1*&M|*,pc_|nUW86MH/;wv3f=z_] W=Xg_ J?l0oN]nܗ_~W@ @@D~ ?ч<N[_X d 3GF9ťb_خe[:j,Hm86}F_ǍZf2 @ @ O~>z `Ə qF8&;o߾>Owlv׿.q_9^s u_v￿;+aPKۮbu]ƍv[/QG{.]TO:=sou:mpP>ťV}ia\=*y뚨ص뭷8p`Emn 7|vϯSNgϞcq( ܯ@C @ A~(mQy>#.O\R}/lײLN|_6}>k#ϽMyÑY @ @  @m=`ܲ+n6mfΜz)_3h]y^lݻwwo+ǎ /&:Κ5 ڕ^E|WYepÇ},?kstA>Nx!v}ww} 0M>ܕO>>2_tE~~m#~MJ/7T,rK,̸sn^zt m\=XvmՉp# @ @9WC}h^TuѸpLf=saZ\/ZX٩v&cSgmuܨe /CX@ @ @/2{ h](_ 'r7i$ׯ__uUne]cƌqGv>b5pvb&_DK)ysu뮻V2kc}WVZ ~[k,W}6)ē(۱%O<1hhu"0j ܏Є @ @ A~(m1y>㛊.lg:sTKž]˶2u+;Y|qlpeh @ @ @ }@bO>ă 瓛=ʀL'mw}}&$Np{ɾ[me _}S ׯLZ7o޼AݘO0 ?9+|)SCzow^ Ǐo^|{!h^eΗwn#/|˖-S,J擡y?9= 2۠vڹ]Z\Ng^uסC7`vVӫ;︾}:e0^jFފ ] V[m ?z Z6"<$ח礓Nr_3<6pì @ WC}h YTuѸpLf?BjE}ame0Vv"ؔ?Y~r?FC @ @0p_b u%Vi۶b-^{ewǒh[B 6ؠ;t7tSGye]N+A|6_H#@<,K4 "F,rNbhC}qb3fd1yE͚5.:--ZTØZg8)28 @  ܯ"֍|vS/ƅc2ۄ虣R}/lײLN|_6}>k#ܯF-3~ZB @ @'pG/8qׯtMa5P~?>˾k ʢ{qt&Mu]^EO?to++A.r{y 泖zSVw8mwuÇw|+S΃@ @ 2PDںvnTuѸpLf=saZ\/ZX٩v&cSgmuܨe /CX@ @ @[o#GfM3͔n7o0sLwGx 'r,O?us]v|ߟgl;Ӳg͚=X7e׹sgfsE^"W_tEʤIGtS~w__i8 @ @ @_!E+|vSE1mBQQtjqk_cey>/R>Mcqp -b!@ @ X<#*+#O>Id.a{yK/q{{q/Ƿj*~[8CK߭[77uTwg:ʾ?n8 70΍3ƍ=}wq7zƎ}ݝz~unnV2W~9V^ye7bbzUrwnmo>; /dZۑGvqnjk։@ @ A~(m]ɸ糫.?̚uE}ame0Vv"ؔ?Y~]jA" @ @@5pD1?mVN>h_+fw_|٫fpnĉJ-~0$jW}qW̥5H0{&V5k^"Q.M>? ]ynWw]t]r%I&N6m{!HZkO>$;n޽vm @ @ PDںq;g=o}a]4.&DuE}ame0Vv"ؔ?Y~7j!Ъ/^ET˖-뛄Q @ @O`Q^ve_akvM7; ?>3[lq]wo_5_7tr8{[x[Bݻ;s\pG_ZK߼ys?~ɐ!C3jn%XX^m?lz:udMx.{iOFuYsdZ=ʪ]/7`X+ @ @@IӞs^3|ZUn>ܿknȑY"ouQnƌ.^G}gW#~* \l¾ж7|-^s|cv֬Yֱ5__%o\֭3R%sum|yL4g3b5{Cݏd@ @ "pB C[vϮT*ºh\8&M90Q-.v-aT;gEjDZ))ܗxmqڵs?RK-N,}]Oz+[녌2_`LGzS((;^vg-vAO;v\P˺ @ @Δ %ZWz=?Wˤ&炋-ϸyjeϻl:=Ϧ%z袋\6mCm-T%c =TV}[ >gWmBظ~G ̯ ZXtE\=l$"y΅ @ @  A~(m]K.lg:sTKž]˶2u+;Y|ql@ 󟻝vɵo߾ЧxuM {qѐk eOdW&nݺ9}ꫯZq?^vy68 ܷI @ @}eڵϸjMa%4 pE4kw'?u 8pz߷o_,[1Z6ֺ{.]d]vJsqe^ 4 8%\gؾnРA>Sū^q}Q @ @ @_!E|v /ƅc2ۄ虣R}/lײLN|_6}>k/0}e{ウ,9e}ZwNYw)S;h؜~N/"O,:eAˠu]wa?y~{e#7 @ @ id9r3g:] S_vl_l(2k^ ~g;#Eڜ0/6E^5m=nذa>~9`ĉgLF_K @ @  A~(m]ƸK.lg:sTKž]˶2u+;Y|ql=߅M4q|qTkq}Qe|l5p_/^|Ŋ3ر l?_~{衇رc+bZj)7j(' {/ , 뷗]69}#A @ @ 0@+QG3KD9aQG}_Ozg|=W?<ݐ!C\,Ƃ=zK.cc2B;︓O>ً-[a=%~: ߧzТE 2dB תU @ @ PDںq;g=o}a]4.B-[tjqk_cey>/R>McpCumYv#}Ng]vp2g`ͅ^"`A( )ܷOϘ1#;C9>YیI&~Yk۶m/lh^eA ~֬Yy/2Z?͵澔5KRꫯ Jz,ҬYdvZ鷗]6p_/>3J2NAʰ \vaY}*vӦ  @ @Op_Wnrwy2g_}loܸqn$.*%zJӽ{w5_;,Kg:{=g<J0g/l{j29c&㾞skC_=YEz'GmtXeUƌr9m=>|)%'@ @ E A~(mq;gN*ºh\8&M90Q-.v-aT;gEjDZ)|o>sM{o߾A#k*l}VnAhh^2腅D^{mrS0aBv{[wu_ysdW֭:XxVLngߘOOBYeyj~V=a\ fScq*Zc^)lZ\/ZX٩v&cSg&ܗO>"e%^'y2vXwW iw5㣗 ͢l_/B?n{b4wq% Q>kV $mưҹsgfgQq,+A{Kk\k M[ne8u?ZV9:2M)kJ~ot0N;d͚xoN:I+c3=#@\ /PzTRzB7$9s @e,b?v4Ǐ/s?`&]w]E>ߗ3pI:˷Q4f̘Zqɗ1VƲ;NY5kt;ýW']kV\ 5tuڎ9Rk/k&O?tN=6#`SBLta=X5jHL"]vY;:6W/)،t]w%޲b4EX̣ƅ,p-?p߿_0n8[7n(zر̱k㲟}ٜ06m+*j_bM6-gP_ HHHHHHHHpM)oHHHHHHHHH8&=/goE6 0VYl$BD>2/bbkt,VYb߇L"?G,k3g^zĽW]uU!JL>{6tMIS 2X30 [ @:A>$c3駟GJk'`&ؠ }5ν2&       ](ܯ]ɻ!        >ަ1Aa>L'3fu6jg$i'%$.V|[[c2>e_x.N/QְaBM}矟E>S 4l>=\YBnݼyUVI5}һwo&ɓuzk=P5\#۷W2-" J}"^-btl"A1N_~ş ?ًO:da3|C8{ &M:u$'x }ր}')8&4h`|18)!}<#9뮻ΟĠmVqcq '5ڏ >׾9 T sVDoӘ0V:gmt2).*|v "˧}Xm<,| !:qpʔ)SrLQV^ 7 yZuWp7СC_?}{:hz҇M6v  mڇgw-ٳTg}&sVP0o>2/bbkt,VYb߇LU.oڴ~p7 ۀ_>ۼJU%ܷ73dĉއn4<^8?k׮&Ы~ݺu{zJ{dH1w>~Xg'IǴLn&Gy/_d?nx(`N./$O~fL\o7;L$(hu"\O=$@$@$@$@$@$@$@$@h2y+$@$@$@$@$@$@$@$@$@JA4(̧|Yl$ xyC>2/bbkt,VYb߇LU._gu3ȼVn6/@C5@g5p7??.=\Nc<Ν;W\[n&O^x*^xt]N=T}'.x;J x`2T0! }3L7fu6jg$i蹏@IDAT'%$.V|[[c2>er~;_^=k6G}T پ +S/N 6Eĭ*oVRܳgO9 .@&LdaODFN:T~(*s=ec9&޿/7Poۡ{]w:*"5?|94R~d\iqDl.pW_}%cƌ#FK/ 6 ZWJan`?N:UN;4k.m۶Zl5kLQcРA^+9#mYb_Q$@$@$@$@$@$@$@$@oNyG$@$@$@$@$@$@$@$@$@CA4&'̧DYl$NL &.V|[[c2>er>|VI'$lMϒ(Ud9ceΜ92ڵr'| 7L'妛nRSXoWƲ_ z cs}6m|"~ڣG 跢ENFb`& L*رN@C׮]墋.9q!u8aȑڅ˳H %M(hf5'       ~Wp$@$@$@$@$@$@$@$@$@9|+iLvO+Ӆ:gm ѓYg lPZ닉-ұ|ZgU|2Wp^!>#4iRb g \r̚5+yUp?c3Z*s{_~ao`xi2oôiG /⽡;>B}}ꩧCLXeUp,0 X6zꩧw;SlQo#gyfoKM㴀_o)S}bByLa0XKjߺukc=',d cW^yt){bNP֠A2snɑG>8㌜ 콆@?_6xα1ۏ-gHHHHHHHHp%HHHHHHHHHz P#ȷ"z$2И8m!/oG>X]XfZ_Llm>K6ViZz|wj$1uuC |~sC&Mqy .M `޲eK9쳥}^?~xshiڴOa\st?ꨣrᤃ#8Bׯ/'_ccOyǼ YBx9'` `Aߧr??;9堃e'Nϛh޽{#Fx&>У4J͛'_ZG .׮ݐ T sVDoӘ0V:gmt6hbMd#].,Bi/&Hiej%V}h+4_-}x=GW+?L[h!_ϗx׽G|6]W}[nNj 1+"wygBOC~Yg_|Q*/S a利vZi `W1|)'꫚M5\{݆ƍ1W+l1λKV[m545]H`M7V` w_'[x96|(gy&fac&       (ܯȻ         ~ަ1Qa>L'5fu6jg$i.V|[[c2>e> D[.f N;vlbנAꪫ|Z^/RL_ve9 Xv; cF~e<'A`=oQos-=^> PPaɞ{YdyyѱN6{dž0`x~s,7NnƜҥ~2qis3pYwq7@!gL$@$@$@$@$@$@$@$pşC @ @~ ߊmtbcZgvMNW'&Yg lPZ닉-ұ|ZgU|2Wp`x֭[ޅQp~Z ֮PU}o{vIC$ ~2p Ɨ`f͒-[z[z>ѿm_?|/ PNÅxxy0j֬~ր6b~V[U+5+;z8!:j۶m={"6t-/63fc[;)~iO$@$@$@$@$@$@$@$b6mbGM$@$@$@$@$@$@$@$@$@59|+iVO+әk6IZIA }䳋Յe6_(X>L*mcaM!/7i$u 8P ԷnZN;$& [daUZ_-7ɋ @p $@$@$@$@$@$@$@$@$@ ަ|Z8mUG>X]XfZ_Llm>K6ViZX#묳wqx k& DO> :4:3W'}^HHHHHHHHH6p6&HHHHHHHHH: P#ȷ"z2Θ8mUG>X]XfZ_Llm>K6ViڅX'8##[RdgԾQ_Yd/ o T sVDotbZgvMx!kbuaJk}1E:O+S,CXyX!Yye=Kz22~xyGe޼yU!UE!        (ܯ3#        *ަ1a>L.fu6jg$i'%$.V|[[c2>e1}]/ 6}ʖ[n)-Z2… wߕ!C̙3ה kLp$@$@$@$@$@$@$@$@$@+: WIHHHHHHHHj  sVDoӘ0VS:gm ѓYg lPZ닉-ұ|ZgU|28ᾮB-[JͥYfҴiS?|w-Z56pN F$@$@$@$@$@$@$@$@$p0HHHHHHHHHp?GoE6 ie:1{qV;&I=)(!|v "˧}Xm<,|~jd kpP$@$@$@$@$@$@$@$@$@+  WIIHHHHHHHHj$ sVDoӘ0V:gm ѓYg lPZ닉-ұ|ZgU|2S_B- Т- p? kHHHHHHHHHHަ4̧)8mUG>X]XfZ_Llm>K6Vij1M(/mIHHHHHHHHH lXC$@$@$@$@$@$@$@$@$@p?GoE6 a>LYl$BD>2/bbkt,VYb߇LPiRY}ЖHHHHHHHHH@ӦM+2wRNIHHHHHHHHHp?GoE6 ie:1{qV;&I=)(!|v "˧}Xm<,<%,bP_ -ڒ %p6 @M @~ ߊmStZcZgvMV!zRPB"kbuaJk}1E:O+S,CXyXy KX4,~1c- ׆Y= ަ1Ua>L5fu6jg$i'%$.V|[[c2>epZL E[         H'@~:֐ @1([MiO+S1{qV;&I=)(!|v "˧}Xm<,<%,bP_ -ڒ @: ٰHHHHHHHHH!@~ ߊmH|Zk6IZIA }䳋Յe6_(X>L*mca)/aӄbhіHHHHHHHHH PΆ5$@$PԤaet>Ie|dFv vL$@$@$@$@$@+: sVDoӘ0VK"fu6jg$i'%$.V|[[c2>epZL E[         H'@~:֐ @Ei1` ~ҼA݊#J!09>*n^ӱRNIHHHHH`E'@~ ߊmtIYl$BD>2/bbkt,VYb߇LPiB~1hK$@$@$@$@$@$@$@$@$@KoO;n[ʽѬ}cwr;J?{?++nW̙IHHHH P#ȷ"zD28m+_kYg lPZ닉-ұ|ZgU|2S,IP_9\+ o@uOkȇ3ۦ\ҩICG'Wm^j@'Vr"o-nYC~(׫#_cD<ы|!p}` VW" ~Z,W#֓&N`_Bz?.umbͦrٖ][ 6k2^ѽVv 9 dђJCڬJfP^mǽ3ca/egGvi32}_ &^>'޻hz&?{FF\] 尮meG9W[~pmP"WnԠ.HHHH~(/lYu+R6a f#].,Bi/&Hiej%V}h+4O~t9W\!ǒ= Tp?[F~ :kyY2yޫg޶ˬA4B0ύ՗y_ĮtJܩqpϿuw ah䄪ۮ [I:J([`?Sgmzkʼn~+lV#λ/_Iާ) ,''~p7tkj}l*Ja+xz[&6sp}Cg[u[=f?d GchNأS+ffw?v붦\3U{aU%Q<7sku i)&&YEwצͪȳuVPA;T!M2ݦDa7G[nNyX?),֑ ([Mc|Z.8m!/oG>X]XfZ_Llm>K6Vi)/$@$@$@$@$@$@$@$@$@$@U ߐOݝk5^ɔ?ɘYdg3eSp^}70$hޡqbdsu.C}ﻭs [:(Wa]MW,`a3 CU;h,-:hCp2 1t^ P8xhysR>k7sCM'*hVe1xΫ;\ΧrLJSqY^caۘۿG~NTvLʔ;K+6` p}+B_1NhPgeݦMtx^[w x[&_Jr/5/DS i7g Db};=;:GXS~Zo40Gym^*T6l͛zU;wOgfZׯa$@$@$@$@$@U@A#Mc&|ZZ^lζIפ}䳋Յe6_(X>L*mca)Op$(ܯHHHHHHHHHGsk"I\r_O 55mM,խÿ:AOճ6=۰I3G;1!;=7Σz Z ĮOeδ=]#`<GEU쳂kc B?_PT&RN΀M[7}/`={71[g8,;p븥-ORX!y~ 2CƯ筹[˅/xKr/xf-XzK6H}TF v&w91~+Нİ㲓ޘ O8?šw|kʿK}hlN)uT{,vɌ} o9 ^l%a>li븽8֯ϛ?k2kbuaJk}1E:O+S,CXyXy ,Ȋ,=^Lv4"         N<7{]{L8 Q~=ېO!v{!84&Ʒ6*#{*,7K"'yc'Ҿïa&aߵjr.="o '<K}!l6 hPai({gGʼ_~{3J8Ѷw{j9{)?Zc_zrbS32ar{i.9nkU: 0o;{ѺUv|n\EgY9|7Nmcgy/҃ݨ~u!lǾvz9NNvQ6iyljg_g9oǽ2ދ;vu5ޱӒ4 ݚq T/\}iYxw=F3j7~ݿ[N@XhƚTy}ǴwMef޽aƭ}\ OL.>A8ƮRYݸ#KcwZ+y,+ c]3֎pK?6D}taz|c6]S m>:azaknE^k {׉EUp/gZ,6A BkP cn3];wwjU>?Mo,yZz?w&Ɣs2}3^6x?ĞmɿS]zNy&Rt#6 6b^n6)|V r`Gt#7wg>.s9IdQ\Qv63Hcߙq`     |'<lRP`ZZ.:wVԨ@a>2/bbkt,VYb߇LX学pٞHHHHHHHHH >Dh/W1d;DGX]XfZ_Llm>K6Vi)/$@$@$@$@$@$@$@$@$@$@U?{cǐvJ=-OZ^mNE<TQYlce*8EqW\q~#<<̳+G8֗t|xЅ|k[)[_7 ;?''~{v>B?ko7UzYᮝZӓf2ƶ2o\OxYfãu뵚< T=] %9 '&}lN9m-+xп}"f+gz!sc-ϗGOF+x#XQn[#yIXh5eƂ$Sh0=:x? PO76kĆekaO'G8O(x7ڡ ~/&]m*׽KsLqR@xZ T sKM$̧-m:yӥpyYg lPZ닉-ұ|ZgU|2S|UJJNIHHHHHHHH~B_XUd FGPdku*|ŷ?8b[Y@*XG<3{=zE~NδŊUX5t'Wf_UX0-uW7YnEю~]8'&x'} b1xxޗb)eqr/ڗeJvB 1\ 7'ȐJg'$!nl} ,9wq^:m9w$oT/T<{p<}XvgNjz}^ c3<6@06^k,?y#6&x0=o :Xn;y@ɸdl`,KY_h}k95KOI@_9'Nߠ~]pz6l";AP3kNкbq:Xn*Upanxܾ7&xA:`~acǂΉf"InQ=6s?~ll}N;']׵+tce}fa z۲3eZ7{o1L6!pCcC&s4>3pRN` T$ sFYO+Kka7IWĿ.V|[[c2>ep?uIWLÑ K׀T,h=H 8wm!>qdAOEF>9BT4p;qʿBo '^x_Չ G9n`u}ݦWjZVT ^^z̆kyO}ldPo߿Y/VazI.5#{l$9o6#VƜ=sn~NK'tC:\qz0UkW)ϊe~6/ykٶE|*wJ>9z2{8 v[xnXu~f1Γ|ߛ7z,뻨1 mQgZg̙ulqZdi֠n]:yGrysy9`[&|W7l'mnƩ_gUNᔢ/ENcsv1}s'wnHpİ5 A7i'*t2\3 uᱏk6.Nkr.EBlY6~Nڍ0K?{N?Nf†n Ƅm|9k~#,O     "@~ X> %Y}䳋Յe6_(X>L*mca)/-ОXM$@$@$@$@$@$@$@$@$@ TpB08}W¶,_ڎ?&&{@nXVŶVd Wbxn"7qmi/c_WFH>*N=y'9:th ?Fn߱e|ٶ<ľh 8A=ûe9:;:o>Ծ}YzX+feƋz-ݣm_Uil ]V`q"B6?*E36 ::5ȿe }c6rkA }(fF;w> ~{ ~V+>ñYN_N\ڝRL*G9] N(q&Z`𻂊uyv z`k_~'*u6]^?KgT)z]kyܷ}rOp_g׍KF9ٰHHHHH|(Klea>,q&5xyC>2/bbkt,VYb߇LwhO~@&         Ba3ahJyOKUUI ;v&{uAw'.@"&&GŘ*RxïJb.ZD}#ٰ5M Tv11aicU1%Y+%N e{F^/ߦoH/'P:NGrp_Ԁ %<@>/?pvsV[<+*Xrrr+f2?*' "%W^xp|APXpPnqn Ngc6rkf t.p} wru?n֏8\ދGm?6<xE)n6*gMBlcm~r_l۵Σ _|+7ncŋ;yQ[Ɉo~-Z&O_pg'\m?S u(`Y}|ulP:64pQַMcm&+4 @9|3JM,̧0ڤ+KYg lPZ닉-ұ|ZgU|2S+^HHHHHHHHHH*.vf^a\,5Ovr"k|ҰG^NT  8 >/ ?8~l޶I"^S^(pPoU[ut\P=a]i%uA| Gm|5.΃7:WMcbؽ_d/^_ y?IA"Ƅik-3"Ζ'XjLϣzpr'*ީ} uUйGV -13e䗾˼<#LݤζnוM|q`oqىx<.YKN6<6ױeչHHHHHI_'v"|&ee}Xf.%m:0ζjg$_L}䳋Յe6_(X>L*mca)ϴ4K7ptvlI$@$@$@$@$@$@$@$@$@@u YDiixH>Qޛ9mmַC/Ğ8H/&x7=Hϖżң>ZPw"-V {>MlgzĒE*Cێ5&&ݻ['w_S_X@8#!o7)|8sԾ}YQj-Z&>~6ֱKx1<&ج[i! Yo}\(,e}1\c2r!lmLwMdVw4N8;kl{9 ~b7ҡ?YDOgʱttۀa׿}l±i}UʢmfSI/9N;AᱏioLscm}pRl$gzM*Y{_7m/gD7Ui1%nEɼvLByRkh]V܎N9{ =.Y<$@$@$@$@$@&@~\`( ieiX]XfZ_Llm>K6Vi <&ے r%_krvk/Ծ|DKG4V}^_Ჵ״z؅hakW#?:OqyuX|I| ѿz׻{ mĶ/iޱî22w on}*@kAD$񟻭)WlvNGawM4]ճr }VxjO59!06|"9q;nѹMΊF}Gl}EU쳢bV~e{wD mƝ8A z#x`Hfo~'C7N.a/tqژ_\r+a"7qG Ə.8ԼA9}g 6'8ok{ VׁbN|&̛=/0 8C^րSTpbJ!>s .ZapGOQt `L@IDAT ɉɯx޿ki~P>5tߛx͒Lϸg%}* ֬SL\7}Ɲޭ]=EG߳vZ6/C ޷N@_w x>p掁HHHHHP#?44|ZYZ{-XMj>YSYg lPZ닉-ұ|ZgU|2S,ŠR_D o@u 7\]i@F;Ӿoޣm$ۮ,)˗G}œjנN+H4H Ą(k7l'9ѻ1Γ]3>CBTA~#}q;k/wi!+p-8.QNݤOW׏G'Lߜ4C44+vobV96^wqCd\Uaw{ ƖR;F^b{wW+̒l~/^cwE,`}#mA(WP%&; Nd9c{vcZo߱teGˠoBH>b,=ž ڵY';r{[ ޲0߻ 19=xv-IHHHHJ'@~ `( ieiep?e1VT1E Tp'b}VrɰOo۬/Xu>2u~įah<߰o {:/muNQ3Q^ u@\:a =<ۀv}h Bhgm{O>~~T cT7oV'bؽOac9{60;xG_Yo}=$W<ܧ3W1[aUx{>w$O9:ƒ=Ծ i1k7&UL*mca)/([M~y = ,%PO_ DLQecsw*l܅2a|YyڅNT١rZ_oߧ /?.Z!\"6U>ON-F~ubNL '۬\6ts[oU%Kޭ3Iú+9/Ky]_RX "܁giE <+|bCUѭ N{+;=Ҿ< [%a3iN,ۦL':fu6jg$ҔIsG>X]XfZ_Llm>K6Vi5X9 +iv8{l?ҸqcYuU~V t?sΑɓ'9׿%M6-Ъl5裏Ey;}e-kVɬYn5`-van%sW4 MO8@͚5'|Rq~/VWk w^::;eԩrgK޽ux6}*Y55Y6˿-++q]wJZM!/s&@$@$@$@$!PeiM#7wÀqfo#۹# $P;oKsӆr.=uHe}^*ܧh1HHHHHP#ȷ"z2̘8mUG>X]XfZ_Llm>K6Vij1M(/VB ?,2kCǎc.]bOojJnYeǛ/\FzlٲL,%nr o~7rI'y8,7{vP9Ԯ];~WΨD~'N;I&u)K$@$@$@$@B NV03zpj`SW+܅k /L=fu6jg$i'%$.V|[[c2>epZL U4hM姜rlVjc#H>!4h;e=iL:=zo߾$o ?ujq ̙ep@{ U{)wh{3f\}ղh"/|W}xՠ;GZxg+x…~^6lz <]509AOl sCԏ#GE N'HhV8{aU> }qjd`>T2?N)М{Lu^3>-)kg "]b[Ǟܨό2ֱ͒{ d„ yf}Nq-P^2kO{~ eil})i7Yю'X{0]}:`{waO}rUgxa ֽ&$@$@$@$@$PSP_Sf         X P#ȷ"z42]1{qV;&IW-kbuaJk}1E:O+S,CXyXy %\9 +k)KN8 ڇ4@B,}ꩧz1o>}䬳J.;JEn0u]娣JF^{?#rd޼yrw;3t9}C[T@x{_e77l[n-rT9DD7t|ЪU+g^zInV{O?->_?ZѥK奄m۶Z$&MC:/~9mV?x\s769>DFAh7ύƢ.HƏO6MzdNb?ǵ^+?6dYׅ^wСe*){K+,7`}b#6 { 4{G>s,{W3<{Bo1]vEL ?y;3#GFX7xL>=6baK׮]2#NcNJl?ZD6s#|n:L.8mC-com4me[Z_:uy`6$sk1ƏwB1\%Jy/Æ ]g?3=??Gs ^f<=>mFzYcc~Zk-#2#Iܱ͊Gc9&y1~@ z?O^OᾒaL$@$@$@$P P_gc#        X8in|bKHieʵB l^ӥĶMtX<Ƙ6Yl$ xyC>2/bbkt,VYb߇LwhoŁLտga3T qčmڴ޶z凝 4py晉21 t^B:ĸJ0;l A0gv!ka[=C< M[>_5IX3ZT@d oۀ z+e3H ]Zan$x'p5[u]jEsnp}XOWlͼ_Un٢]FƋB{ }?c6&]5Qn~lM؀o}16E ]dž:{>kqrwG}K!؜FbZ7-$1a ׈i HHHHHHHHHjpoq7q2kC9N!=0xN6|~?qCP2Sq !b`î'{ah/qrAiebs_{d|* yu}! "c= )oӿ4xb3{6!8<7hcqy(p]ܞ/gFpqzI&`c N _ Kq]ZϘHHHHj" kpL$@$@$@$@$@$@$@$@$@+"upYM"̧io1{qV;&I/W)&EE'.V|[[c2>epeZ\ U?<39» TAζ "5\3]Z!:D6@ q)D0pz(~T4l:ǘoQڴi>i6O̰?Ozpwyg/p C!:Ɔmۦ{uܖ/[nNal=XW[8ƃˋCڇ]O>Tl H;ACEX#a \O0\8bMyCū9c`Cs88l_=<66s9~M=l }5N49rv]wU:ꨜg"܀0ɓ''оb}75j?xl5kx~e]#dvHuϐ5g wƾywDy"aWu.B/K {<=NNyq#Ƴ fY^>åGx-<#.&L7w?3UhTk0O$@$@$@$@55i68         9|+iLqO+:gm ѓYg lPZ닉-ұ|ZgU|2S_B- Yv}aǥ3b#+Ό 쭫XC^wHÃ-Ē©W[_EPq2jYL@<&c*vs4񢽎]brx鎅Kx|Gk_uUҾ}{1 b"ekpgK޽b`廷FںW;XT ;P}@ 4q [zd~5sxNm&3{>so;|_xEƶNv=Yj׳ <8uMBD WSc}2Tcq)iWC{ *dT4PrT4rD.PI.{;wn}Zzk}׻ ^zdsd~z 8{*"赊.M!C={6q隸2e^ցe^yd}a̘1#$]ܷ_gt%Jw ;}`+W 6~k7&m$@$@$@$@$PQP_QA$@$@$@$@$@$@$@$@$P P#"z]cvq6Y>iy!/i #t=,Yr틲g\ڤN~IWmJ SaC=d|Ao4]= BE"" ȴ۲eK3do4t=6 P%'dtG `#豥]PQ/3hZk֬i4h`yk e/®o۱(~7l0gZd*ŜvKXO6WG#ȑ#+bMny=8Q|~5o/N/B$>&6{l3mڴsc Z?ɲ.'mSD&]Ѷ0袋F5jȊnd^ϚŸqrN {<:5p3#pMu38n_Um wSUgyn^x v݇S DTr_1N_y|Aiӟ/Zi!qD8E76M41K,(=^Cu9 TDWħ9 TFE>E^ZgS䛷(q$]^S6]r>TvPGRRDeKBH6]O+K{\?$볻6S_Uҟ@e,5ٴ ߝ#mƑ{*'3@55#(СCp__[6m5>n?>s߉Xݺu3uԉ4},diQLE|^X݇}Ȼ <(>=~j.bw @ypO$@$@$@$@$@$@$@$@$PU (0^l2_tD⪢):F͵zZYڳe_=&!]_ݵI噟#q+D/-8"M ^PHW,;-sYCݶm[yjj1 w}9sQZX[j0"jcc7B$"_-ڵA$xIhld}hGDoudžC=Th+}Цz,'|ugƍV<m|y7oFu]XH߈2- BtW^m4o} Xn$ "vI.c(k_mX"Z ]?' KYo߾7YǮh[&+_N ޳_g%ud<ܠM?AODR܏>hsG(z~'.R?N;i]wM_ח{&H3f0?pu)_}]{G_[ [»H^&t@O_[n1{Lլ]>%e||qֽt\e<_F>!iժ=G_k֬Yf̙9"|.|'k=6$@$@$@$@$PQ/ׯ_Qy @$@~ _u֭dM~OTx)t$?_kgɵ/ʾzMCr߻>k:%]))OT͈4.kDӧiР#F}+Gm6mPo/4\r퇶h`,DDŒ"/"#AZk?3 N:ƶM Qx{Ϟ=ۼ0$"_\[D #9Ĩ^{S}Yv={iXIߵ?q,֯G˵U +ݦk6q7k̬Z~>CtbΈ[<>ׯ`<[7|!vg4\[?+Vn|v#C4{kf]&!jFܹ'Z}qBo0A#GFc\u~-sMKw1/a {[/h &g-Ql?nyzG } [{.n Fx]Mv; eb{!H_[ Ip>6' 2W'L6;1 ",pcʳG97lT5k?tMs`7d|E{P|^{߸F>ዸuנoI~;;k'S}v    (ܯOs          (k.Q8, DR6,i6q)VD~Ez? (j+*A #D$ԑ'lZnݺ;bok?D%A!QDZX)F=v(z>Ž h~WPIA9jDqv*q˩B` rq,Ŧ=&ȉ`A}ǎ\3?yv9 X{Ό?ޖ <>}8OiyE(ksmV,EWH.{gwmRxmB&GM XEJW\ 49s][ZVl AcDwz̚5ˎ ##ǩUVaqšǚxy.cN$@$@$@$@ip.$@$@$@$@$@$@$@$@$@@O+Ac7oQlIv+-/sm.|r'춡9ƥ6'O[Ր)s!t$?_kgɵ/ʾzMCr߻>kz#ZlP_ Id4ڨTaXR6ݪU"'#z;S#"A[zMr͚5fʕVtnؼyx"mVamAhrtl@bBoR̺.07Ƒ?K,C "icaせys]J_ ג:?6BvWY%!RZFkC^f͸X;>CXH8)WN/Fyy?]< ;R'w!{0$g&KqC$@$@$@$@eE@ H%? TZO2~\҆Rp"z][h>iyKC%:F͵zZYڳe_=&!]_ݵIh QI%.#~jl&MKak#?ZϙH|6>;3)XkH| 8N@4z&(M|&ME$@$@$@$@$PHZ(y܏+86 'm8?'[2.Rwm&         E@tmu2[2kzC8? 6fSV- mͺu\s)/W8 E_6Ǐ7}]]t1rd"%fs=^zDҧOӬYbm4@iHr     B q-e_6&         0뺼@un=&M~OT!zdȣ:F͵zZYڳe_=&!]_ݵI܄ 4jժyʦMĉgmvigŊg1ݺulnb3g׻Me^p̑$PjV\ie0Qc=JO>lܸ3~gCeF2C d$'ܗa_lIHHHHHHHHH`[& E}+wn|6-M|~޲ѽ1|mMҞ%׾(q6E|M&?cLNb_qiܸqtR3uT3t+L6ͼ꫾2Q_y1         *L M_oF$@$@$@$@$@$@$@$@$@J28<3f裏SF M l+(V4HHHHHHHHH(k.18<2 BmI>IHHHHHHHH MA2[#KCt,BȐG!t$?_kgɵ/ʾzMCr߻>kz 6mj뗺5k4OxժUfƍZjqƩtشi/k׮] fa{5 ~4h`jԨ^Bk!ty     2'@~#IHHHHHHHH( sZDxn=&+/m:}#C1|mMҞ%׾(q6E|Me.ӧi֬Y(-믿nNzB9P_2vΛ7[ 8s'uzhp歷޲2bH6m6.[` GjҤ9cm>_Ob[nŜb2|wfȑB.,H\]^suK޹ՠU@IDAT>YdI4(6}٦E-g}f^:ժU˜viff[6|MԆw=bD(_2<\rYghs~o.렃ʱK7#4)Tȵ{nrUNӥKӜt\Lb7Xh;xzꩦe˖n$@$@$@$@$@Aq$@$@$@$@$@$@$@$@$@9|-eQ1|mMҞ%׾(q6ɷ2볻6paÆJK"\tfO~Vb[Yo߾^Č_ov(*-^ 4(&C9\uUыſ9wjݺk>Uц/^EqX}G9d,ܿMzȊqvnVLc㿕9A;8s9J/:N-~СC[BD-5⮝.dIN7t 'p m$@$@$@$@$PIP_II$@$@$@$@$@$@$@$@$P i0MriϺME?oޒْ2VZ^tI{Mt]ORmC sKImOE(ksmV,EWH.{gwmR/S>~(->.6j(+ p);Q?;<3Vwy癶mZA魷j6l`Uf5j԰ /ƍK/Ԋ~("1}۷RzBЉ&zfΜ9橧]ӧO OWx#Fǀю88BnX͛7 LNp7/x 8O/l#}WV|{+"z UVlԨO^;x{j֬iw5=-k0 8LxbS 3 TNWY T<﵈^zM_tDeKBH6]O+K{\?$볻6p2o U!"}fƌfСA'?Jё`nܸt ;h 7!Hܴi>|/i C~K5Zh8q;wiٲ2d  bڵk47zTB}Qs-Zy~?O7!*;6'ą[}[!.J.!Dh["q3ꫯY%KA*??r >ʕ+ X+qi666k]׺/s|nRt್!vxsAr}d>v}X>l(0'}8Rc}첋ܰ5y6\ $IsI'^okޗVz=ze7>ڴk. wSQ%">8~dB8E0b\veO?s7S'>XЏ1Nvu}DHЫ @plyj$@$@$@$@$@$@$@$@$@U@>^-ex86>Q9L{ c$\=K}Ql]L 7ܐԻ E1p?@XQax+b=srD&ˊ Gz͈#lfD cǎO{iE"Z$M?H^{!&Giw>NMp"vg. ׼ l$撊se̊Cx q%7e#ƿo>!+"P>s5͚5(8Pͳ>3#4GqDQ{1#v݈S{6[oe#uDFs|򍸏g+bz|̿K.f}f- ͛g^|E+^bf$l9sf6{=CP'x"$'o~M:?Kby 0qZ4`-[`4k,M\c݄>؜S= cmfp|;餓BMfcN|I"9Dylr}R/Vlޑ$>I)5W]u6>c8 q?b8b8|^p⎼ 9*EHHHHH P_y9         *KHC֧E g|ҦP?'*=2Q#t=,Yr틲gEڤ^f}D0`@ oCnTdsCO\DXw}wHrV۾}{+ŬDHHB bRuǏsboFRN@˗adžY \^jU4K/HwdCqDGrjK/ٓl|=#oiqN:mre'DpH{>(xsޅ `&D?6 a|aHSjpbM9r>KW_}m{Z"7on%'hZnm[^V Q76b#ww愱 F|!G_ s[l~ю K†͑x„ Q;1NV@s-DLJ4 q= g疥 &W/aӧO)H`{1ǘC=4e3j><`ع3_Luu;O?9aDFn@^xc-ex86>Q'ZTͫ:F͵zZYڳe_=&!]_ݵĪ:t0|€}eʔ(IF~iB$ꫯ5jب<Q]DqWhhQ"pk~6ml5k D'4@H;h +fkƊr!OCc4|Iqƶ^zv?YΘ1<#VxDdG$v=!{&DpZ]aÆnf\;v(]+E&l:@Di[q7NkK yZX] Ɓ[s -;;{p&BDظ&"#!>")}!837jPGw{0&+܇ &<ls=9†+6ǻ q;cQ ƔSN9׿.VlÖ0l S@nYW>w=lFs")xK6/%Һ)}K;O Qo*) p?3"}Y>3Q1'    X(ܯXσ!        to}|ZDpq6/m:}OW!t$?_kgɵ/ʾzMCr߻>kz /b-hz#FZjiSl3gƶ{ Bω'zK,#R="4k M QD⅘!k D G4c.n_l맟~zye˖HLD"pX |`SOہvȑVL}A?"շ( gIx%1Hi\W0`}wCN.: Q!$sؿ$}O2w:n ( wa$!8>d "col( :BsSؘɱ /i`F6l]y9 ;E$q7J ֚~&2ŸϪ岮#4$ӌM)m]OS:/l†-_WVl.c]/Y8]OeI׎ٳ >Hq'|߷iRI7A @p\$@$@$@$@$@$@$@$@$@U9|-eQjɭhИBҵ|mMҞ%׾(q6E|Me&܇xe#5 "ڐqiB\KՇS8BPO#r3"jڵk ļ6l0M4!~"C;i$mi.:>B\-'9D?|-c.6b2Āŋl#}s9//"{o0nnobvHDiE]=c#ȋ`VD#0Gu6]ss.iJʽf/cc-]F<9O-,ԩS'%[i#'+mYAvF|F]0w:Nkos½!CЯ:xy… n1cG{DI*XoR"5\KoTGs }Y KK{=br$JM(H'NJD Ǧ>;g|6N|ד 9-OZ^;)Gm7O=|1ǘC=E&     JHJ8e         IA2[sKCt xISI~6צieiϒk_}8"w}}v&u KjS<-ssaX_erZ~ꪫ_|a#c2Xu)/5ߍ`/* ѣGGH4EFGߟqJDxcǎ{9s7o0a#Jl@17I U)Ir8 qwO"#2="c$[ID kOIgzW'|)l\yF72o\ri"c= Iuֵ{p_ O8ᄜ:W*}k$%7zoIqʔ)_[n9ﳒ\W y L 4Y/'>cɚż?|{Leqm۶6;^kllNA^TkG>G`M x?&k:y,,](Bk/ lmRZd8psر9!CnLFYD/pJqw}wޘ#NHN 8Nx7ܛ6mjO@t^yOZ<:b:bn %7 b7gy{+ -ޖӓ{Hy$ %6|AoNnz!ߍ/QK"F}$!Q\tM1qƙnsϵ"m!p\qygj֬)MQ~xO&p3-kSNpq__c\1%MR׎L;wo%62⋖'!Mp7蹞vivtibgQ;"m\ݎgYY']ydqd()8ă۰v?=֟$@$@$@$@$@Yp&$@$@$@$@$@$@$@$@$@9{-eQy,2e.ksmV,EWH.{gwmRp?2ցl[̍n Z1+܇0!wYJ=zsC a5ĖJ_+sE$k$_ HJ$k-fG4 6?X3B]Rpg5ϷHX ؇ :ؼRV-ێυD Bgék׮Yfk) cboD[mx7?nY1piL|Ygmڐ{ƚJ/0X>(ws쓳Arlhnw'Ʀ l$@?M$RR2Ʊnf09B`M^~i"_\3gyl4}Hiy!/i #t=,Yr틲g\ڤN~IWmJ S4#D?lm1B?FF[(B\ /lthuB 0AE'@4?+̜4iȏ֭[ hEHԈ\zu3yD1P3Hx&g}bXc| Xp>pիWgQ'B ]ѓ1o7R5x ݻ]XC/D"k1c=P~zSOYa5<#:R6gap' ܭS?t>Inݬ5y{h-bC+ކ]5 އY"}7#^zYQҥK_W+(f:L!. (g$}ecy7뮨F czoN8i&jϷK/skq\sM$lB&]rcMTl@ H)S)."C_\$|F&f0ӧۡ}2z̞=ێ 4]7nl݁{챶,k0'#|NZGlA» s}}LS;4'x"z'; = ˞9H$@$@$@$@$@$@$@$@$P5 i/ҢuE?~ rڼ%GW%eϵ麔uۆ:tP?'*C<^:F͵zZYڳe_=&!]_ݵIڔJh8?HA`'|bms?>| q$DI }$j=Ħ*CH"p'NGbrt-D>|x!a Es?\uU0WN!>FbڪKL NE}cx.Z/Txm[wusj58f+ 1m_~gSC9tі<={Bh-k_{MGćuؚ6mj,ѮxZ c1 _ܯ]c=f-ZGCD~!5jTΆ؈Xv8a \Zq;B lx-nhq%><$ob C6M>xF+W_l#C kOS!J 렌;$ԩc`cuꦐ^}UkT猏G8] $~\}w^h7vB2|Wȑ#M5eժUvsEui'    (w^HHHHHHHHH(Pj.íd4rO]֟Ak -&     K8s         EHDGE g|ҦP?'*4t$?_kgɵ/ʾzMCr߻>k:.LshoŊ6˺hԨQ!*"#I_D7K;`u ؘQk >Ʌ׮];BܓX5 d{A㠃2ve01: .J#>7nhkI&CcCh+!y48|P">lj^Sׯo#ʧGNIzh{BL(rZ^[٭lO$@$@$@$@  '$        (4 sZDx n=&/m:}riJCH6]O+K{\?$볻6pwf}LRa6zچ+t"> ^py  3go c3Dq"37|cƏo8ݡ]vX%'࿇q{Q S&    ؖ P-?}; @ip?GE n=&/m:}#C1|mMҞ%׾(q6E|Me&oٲ2I ǧ~,Z(ͶA>5.5[։& @iG1Y^ҁh:w,U"SN(N>R9͡@S-a_~t7)9$@$@$@$@$@$P V^̭_tDeG< c$\=K}Ql]Lz](ܯ7A$@Yfuۛ_LIHHHHHH$@~؍HHHHHHHHH^Aͭل_tDeG< c$\=K}Ql])cfB~Z% A`ӦM6>իW7Ż       @ 8         *AA2[ɺKCt,BȐG!t$?_kgɵ/ʾzMCr߻>k:y,,](B$@$@$@$@$@$@$@$@$@$Ox6l!         ,(k.[ ~k:y,,](B$@$@$@$@$@$@$@$@$@$Ox6l!         ,(k.[ ~k:y,,](B$@$@$@$@$@$@$@$@$@$Ox6ղj*vZӠAS^ T0^zM_tDeG< c$\=K}Ql])cfB~Z%         xM?w\3uT;tt%˹e֬Yf̙,.bsGG,lڴ|g믿6;Y~ټye]LÆ sj6 TJ^lzMց_tDeG< c$\=K}Ql])cfB~Z%         xe!_z4h)*~"E-h?1c>G}Qqgw+R7=z06l܌7lR(y=f}_m\`_3m$@$@$@$@$@$@$@$@$@^Aέل_tD`Gn1|mMҞ%׾(q6E|M'.ɒ7R_rHHHHHHHHH@,K,1CgϞIz2ظ iӦfѩĿw}/17n M6+4իWiڵ3?ׯovZnGe{/ @: sZDl/m:}#C1|mMҞ%׾(q6E|MPtp? - @<_2W_}u$bZZli#ޯL}/lFe!C}' k7o0aBԩSǞ;f܁ Ǝkc_e{y1uIHHHHHHHp?GElT|ҦP?'*=2Q#t=,Yr틲g\ڤN~ 5K Т/ (k~5w}gڵkgUf'VeYxϋM.2۷Moڴ+K.5^{mQ k6ݺu3 4"^z̝;Wyf9(R(;*p2Ͻ        P(k.[ ]7nMnݺfҤIfYvW^=c! ̪Uhذ|ׯs} /,&_b=!,tM6Tj˗+2ow7cƌ)F"N6X~_~nbK\Zs/p        r%@~ _uȭyM~OT!zdȣ:F͵zZYڳe_=&!]_ݵI<j.gE_         'Pho C}wZ6I}ԇ fQwȑw\?:@e˖[oլ\2 =zXa_njժe{sǛs9'3gQxaϧ^za^>>}p_8餓gQls8ǽ]wuvHwK.kz\IHHHHHHH& sZDxn=& /m:}2%Mc$\=K}Ql])/MO~ 6 @ 7S8 6;~ԨQV Cp?7|pTGby &̭so[d>Lݣ;_ޝZ2n-;#8?1|phѢhjժ{n&?INJ H I~=y\o)XrjEI&[n٘ᎣJ:w=.$@$@$@$@$@$@$@$@U9|-e<|g6>QY!BI~6צieiϒk_}8"w}}v&u XYP}IHHHHHHHHH @EC(ݳgH#{۶mMBx-H}f kC7-;_==QG|ӦMN3~M_C@ v7_v#<]A>"Cؿvdkr f23g)iQ^5jșkdflqkL8F:]2 @$@~ _u߭dM~OT!zdȣ:F͵zZYڳe_=&!]_ݵI<j.gE_         'PфO޽ƍhW> 4?_~>.6oݺC={l`vT|PwԮ]\vefw6/bNDEGpA^̺u&=)wW;z' pI~˗/WXQLkaCAdvabBzE]d{o{ᄏ.I|y_ֹqY&       (k.8,QY!BI~6צieiϒk_}8"w}}v&u XYP}IHHHHHHHHH @y!N2dH}\vRwZ(k^nݺfҤI9bzqg>co>h<|'s:J@]u)diӦE6;D!~!>˽ `ڶmbN;w'IwC.`N$@$@$@$@$@$@$@$Pu P#"z]pq6Y,>iy!/i #t=,Yr틲g\ڤN~IWmJ SHHHHHHHHH p?pj^ r4?:ʼ!]o$p/>t8I>n7nݼew~p,B!~!>{?իW7sQsҚ5kL޽m4h8qLCB39VHHHHHHHH$ sZDxn=&/m:}#C1|mMҞ%׾(q6E|MPtp? - @<*܇/iѢE]!Z(/ڵ9{Nd3pȦ;;8x_4 UphsPŊup饗#8 CB|pQ~v}w3zhv&7oR%/tz\IHHHHHHH& sZDxn=& /m:}#C1|mMҞ%׾(q6E|MPtp? - @<(СXf͚& P'4kz3(6.\hF莥C ˣ ~WG2'|hz\ߝD$@$@$@$@$@$@$@$PQP#"z]rq6y>iyE(ksmV,EWH.{gwmRp? YhїHHHHHHHHH pI&_~Vajժ]wlb*Bx-w謅2XٳʹiFGy_1cyᇣ&=(pfWnL?ۣ~(1":lj-[f ܌7.'J;u뚉'7[\xᅶ;4/6N{z>йcHHHHHHHHp?GŅM&>ȓ~޲ѽ1|mMҞ%׾(q6E|M.|(ϗ @. sg毹Bx-ލ.2" Ŕ#6l$뮻L^ @IDAT:u" 7n4=z0K͝OY1 bҢzsoӏ; 1ҥK-7moa.U5 1M֭niyE(ksmV,EWH.{gwmRp? YhїYzw}MF*͍oڴ`Mley7QY_? T4! CBxW((hA+F{ 7`b~w>|uJyfӫW/3'nݺ?dk׮⋜6lv8#"6>\~s/KZN]vc+`PpW0aQFt]ݰaCdkϝW׮] 'hs΍l!G@$@$@$@$@$@$@$@$Pe P#"z]wq6Y+>iyKC:F͵zZYڳe_=&!]_ݵIh @~a֨_„/0vi'Sv|)/7׬Yc?pwe0̗}5+V07|p1B;6#DBd6|*Gu%_Y^+e}IHHHHHH`[ PՄP? r>kxbV 8zh`?SO5[#<EaNQQeq皚5kM >nn1⮻2uF;vl Ic'{l'       (k.A8, (p_vHB}§[797 ?1/s+XB2*K1}Y^+)2 F:Q|O\u^\\>UVE~1KDzfG8?OqteСA.W%wԶm[;D |}E`d&}-sFlaEqf̿o_7ks=ms8qbBn?$@$@$@$@$@$@$@$@U9|-eg6>Q1|mMҞ%׾(q6E|Mtզp?P7d9Z_T]x_lڴ47|=rdwf%ifN? :k.6Y̙3GOX駞z c+B= jժUlJK6i/Md$_6Vik刹˗!_tbMYɗkN$@$@$@$@$@$@$P!oٲ2dH^;wN Di?c ,7nP'oI&Emn-.\h͛g~G;]vŴk>vo1 u0`aNN F'        m9{-eg6>QY!BI~6צieiϒk_}8"w}}v&u XYPVa}Xj|iu뭷/b|W%*?td}-ܿÇC@UWerwm͆/!3鳢#AP/cJ,#=bZfuEEf̘a~a[8" }>Q OQFi2`u52¼1/Dao6;'^Nl}#tQl̙cGd2lMk/38*=.5_>8lFI8u밙4>Qφ-$@$@$@$@$@$@$PUY//q(7-ZHWEDW\a;?VJ}KC?nܸbKHHHHHHHH P#"z]Pg>iyE(ksmV,EWH.{gwmRp?K98o׺&o}Na^hhR:ƍ[7##2"!7DQɾi+NGf46@}WD5|ذaHj0q$}\矷Gcua8#_NnQcƌb|}8o[oYa< (Fpk s 7\8pK#-h7|pepmڴ1 aKKqr{fL߾}6"ٳgO/qt_op,91XpwGGcN@sα>/ NU518QLA*3ɈȔJr( tP3D&t蠫HD!ʔˡ(~W{콟yy]Z^:^ϣw_Nᾐ`N$@$@$@$@$@$@%C9?~4mFǍ? ~^”- × !A2 (<E($#͵z\Ye_=&Ir߻>k:Yl4](OC+ĺ+V0q/S(Wzz֬YVЫ,'#1ҥKM*U Kp$\, ~ nMm? |q#nCϠ֭kp+%dǓHHHHHHHHrK _uzM^_tO 7%#͵z\Ye_=&Ir߻>k:ݵ1)܏Tͳg϶B8>pۮLr}}D/Z))=E }ΝV~2[(Ct17!*'hԩcǖÇ7-Z觟~{_zu^#~38@h$r4E43OK={.]{s=f6R?ns@3Yq })bmIOL/^lYV*& V\i! iNK߿mnvŞXP|#:N~Ż>e       p?-~9It(J*C8`/ܮo߾G̤oHHHHHHHH ./WEp]'G2ehJ;sm.lr'SmC kJt~OP[4%.$#͵z\Ye_=&Ir߻>k:gvg-׽ (w͚50XrpB A$D({ lLHsI&(CT q5D־4l0ӲeK$b|91vXk}]:tD3Q|sMh~sϛ7̜93ep!eP. B*Q|q6^Xs֭y衇?IEn+ɞտzOn-Zܤ sJ.wW?#c0'      / 3-0W^1V2?Ompmriܸ^!2@ %x)~IHHHHHHHH (﵈^zM^_tO "D Yt=,ir틲e$]_ݵI,6j._9sXvuCԍ&L0r]ya2em'*'a=Et/81yd[u#K.1իW=8w}w(Xw?\s56(j׮m~07%;ng(/wuYf`KZͥy8дknf̘ay=}"$SO=@zڃ䳎Cx8죓\vIHHHHHHG$@$@$@$@$@$@$@$@$@?.ZDn=&/m:OeNjt=,ir틲e$]_ݵIژ*fRQ!n֬VGR+j :4Xy^[ha!3!_tRX]w<8$ Q:1j([oaHYЦhgϞK.O}9`pǦML˖-M:uB=̙6R۷p{%MYq6nhWP!v|^:-^zs[+ >ͥyKD}|&%]~ rF>˗KP̻k.Ӿ}{3`q/lo}B yCˁIHHHHHHHH~d( ^+zMv_tO "D Yt=,ir틲e$]_ݵI,6j._DD~嗛jժ:DCh AqLzEW Ѹyfs饗~h0a9C~,d&;[n:q5jh֭iӦϡj#תU>7ll݇O21Ϸ&3%&}#Ŏ;m۶ (>flZd=2<όf,\2qb|`#cǎ]%}⥗^Btt2Zh}/GlIHHHHHHG$@$@$@$@$@$@$@$@$@?.ZDn=&/m:OeNjt=,ir틲e$]_ݵIژ*fDȿڵk+Ud 6`_"lCܫSp>Z|w}A$uxC<`Hgu$Jw}3qe]f]Hp/B>_=r ̊+"pg;/O(FXnXf&p+@W_EqDʕ+n+a[_7qDQ o`LIq= ~dc @nPHHHHHHHHH( ^QzM6_tO "D Yt=,ir틲e$]_ݵI,6j.U2>#fܹ!>fG~(jD_\9+4ZjصkWӣGP;+ @>@COj*… "C v347n4;v4{w&4P3}N;ML31zG @pu_ ߹sg9W^yu+'txǡCmq\ {93cƌoiӦj[/_O[R "+(kIxc??2>7l_۷o78DOY @Y! ?;HHHHHHHHHH'@~HE n=&//m:O\t=,ir틲e$]_ݵI` @~~rT          |OL$@$@$@$@$@$@$@$@$ZDˀ֣l|Ҧ~OP!z`ȢtL~6צqeiOk_}('E|M/GcDF$]vD>޽{w۫tP_:9+ G}HHHHHHHHHJ!A2^[ɋKΓ>AY!B12\Ǖ=M}Qգl$볻6pns3M41/M:u˞ڶmYly|`;i*{%\ @%@~}q\6 @p?$ׂf]{sQ6y>iyR?'(Yt=,ir틲e$]_ݵIą?tP+͎;~ǎͱ k׮5g6ykS_*9) >H}HHHHHHHHHJ!A2ލ[{KΓ>AY!B12\Ǖ=M}Qգl$볻6pQFfv{lذL4|嗦CN+~}g3Ϙ (Iɇ1IHHHHHHHH~(1u>3 @>Pk.[kKΓ>AY!B12\Ǖ=M}Qգl$볻6p{-[c9&-f}ӦMRQ_95 >E}uaHHHHHHHHHJ!A2ސ[KΓ>AY!B12\Ǖ=M}Qգl$볻6p?>o6V9̡jʕ+_܌;ر^F K8#        W PY> @Ip?$"z]kqQ6y>iyR?'(=0dQH:F&?_kɵ/ʾzM"w}}v&C`sϙ={쵕 ?Yge*UW;"O4`N$@$@$@$@$@$@$@$@$@ | e8^?\N$@$@$@$@$@$@$@$@$@M _uЭG}MIt,BE!|mMҞ&׾(Q6O] N||駱[rʦ[nV:ϝ;,\5xG IHHHHHHHHQ"ϗp^Ə×e; !A2p(<E($#͵z\Ye_=&Ir߻>kz 7l`رc-TZ5_;wym۶!ۗ_~infj( % ӑ DX/Ἄ0_v          C|-evQ6y5>iyR?'(=0dQH:F&?_kɵ/ʾzM"w}}v&cM41}1۶m3_}h{?5Ç75k ٟx /l%]ps>         }%kyN$@$@$@$@$@$@$@$@$@"@~HE n=&/m:Oe, IksmW4EW\ڤ^}O?~o[N0z2v"}kTqf'?}֬YcNJN~`$Pswo˕+gΝ;>`-kc.bsAڸغuZٱq+>+V4qB]_\wƍ+U޾}o˛5jLk-Dx_HB ޖϽ%ٳgO$@$@$@$@$@B@q?d?n^ @Pk.[ɫKΓ>AY!B12\Ǖ=M}Qգl$볻6pn!VW_[n LÆ Qᄈ!+D~2pvXiӦK.J*A ĭ om~g7oϷ74O>b-[\rx?܊?xSv>t({ 6Łݻwxu,R(믿6cǎp(.7u6+W &ӨQMOnpD8t4h@4y_2=PpӀKϞ=c&Ӓ!_z饗 Ԯ];?%wVZez){I?}=MzPCQm]v5s: @! |BƏÑe; @6>,UDنr}([&Mi~MץMd*m#aQ)SO 7%#͵z\Ye_=&Ir߻>kz I=P'ӆhp۶mK>Xm!b0` (܏C ZAƍZ|C6j\uUQſ9Ċ;SPӟQn:sW} fEGT/F'C8_l8UjUNwٽk֯_oVo޼;w6&x;ZaLMՃT裏 H?OMZVu1}Z/ϊqִcǎ{n-B]'[nm~ض+{KGqNXn7ԩSR;[m$@$@$@$@$@>_y?nU?n^ @i0(L-ex(6'}2MIksmW4EW\ڤ^*l6J~-P?{lkS)܏}=[!o!;ͮ]L͌3L `߯_?+~Y4h "CwꩧOD ۶mk֮]k&Md׸[gr B_ 4b೪9l#}[p@bܹ栃l':+iln;/ҬEv hDGBs6~xY 0Œ%KO?mWrgf͚\2]6tP.K|?lywi![p3fNwA0O\tO>ļVl//Š; mx/H{ev|֨Q漧|HX}e˖9sزf=[@ $'$ G0'    (,"dq5ܼl'         \p?$"z]neW6'}Ccd6]+K{\G?I.{gwmRߧb >< B|BP={L޽@ēO>9H~f?mxQ!"Ethqʔ)}s1fȑ0@0]VT)Ԍ[Ў_A Ğ[f38#C܉g "Gi =pqk0|XF>?և1Ba>Dg7 Y5\;HcǎM$ǻϬp%*ܹFaO]`8mݖ3>63ڣ=@[n$w  WXX~i/A#љ>^vm답aύ9px O\@Lk'?ps>sCϞ=>h,fqYVI/Y?I8|z+b/{9+@|n7Zli:rpmA~>%    ! | eqHHHHHHHHHrEH ÈE e|Ҧ~OPWcd6]+K{\G?I.{gwmR/X>DXU;旿 q+ΗĮc=f^~em*2qC\CYBطo_+> H/6zz MrJsuH'N4|[lmTv1q74 oڴzsGaE_B@]s5 {7 aiԨQ7ZCQ-%a]t\\ѮY9A\ a0`9#>nQYzȐ!] w9#JQ/pa ,́gm׮A7 SO=eDN/?N6D(8 @ a}2~ckyN$@$@$@$@$@$@$@$@$@"Pp0M֣l2_tO "D Yt=,ir틲e$]_ݵI`~{H-)p"͎;!ٓH!XtEQΜ9 qO=T+c A %Ć")[7k Dh$?tDί_裏qg:w< Q!0!$p%A?g[h[vm GN,dl֑myaÆ9%gi5kf7h  `1~Tґ+&16"C4H ?!aKkЎJԑ=?9h? Hz-_'aʅp_G Q@1c={76wٳ! /?ۺ`k`0/a)o{ іT{ϡ9JN"p 0t$    ?K8/=I換$@$@$@$@$@$@$@$@$@$+Ez Sun=&MItj-fUH:F&?_kɵ/ʾzM"w}}v&3TPa_7njCdvJB~rþ#mgDwF$vF(D͛ۈȸW^\C0{7ZQX#Rq#?.A4H+VE~UP|bG !q3,CP|A3w\;>iX( 9"?v툠^jвqXQ!qDׯ^;t_8>6`}#4ʕ+gӦMo|.#aeO`5GbJ*Dߝ?[>!qBDؘS~эh0S OppBy޽{۹PGw{q0&+܇ ! _~FpqNDA2p{DA{}}0嬳β7_ 0 ߑqHߨ\أ|g/ʎwswn;wQ]?k>~ԇJ=\q7|e~%w:N8d߁s?#s9{0T| >rb?n|7/IHHHHHHHHH Wt2A{E\PͪtL~6צqeiOk_}('E|M+܇'⃘zΝ{m0 Ga8m˖-V J@~rZx/ 2e^nidD߳g$#5qeDk5KQ]8YBرcZ1o8@@`w=g붴epJnzs" S {[)bpDT}9_^gR(%KA_ᾌsY;lzlAu7g-80mL1"l( :B]n-zlQ8dϸ̉eN p}5 @wH~(N.kȘ>˾g[vqSZ.5F/ퟤ;؃Y=#\.e\qjW|^nZYj=<4| O HHHHHT >_?2_v          C|-evQ6y5>iyR?'(=0dQH:F&?_kɵ/ʾzM"w}}v&?|qDžA㏇l%]p?9q9=+~ףر@Cjղ!f"C7uT+GĘVp6o<+hFA!H&_ʖ/9ШQ#3zh+6,_|ea- ѬY3{K2~Y%.{ /Yjmۚ_ڔubٳgGBw)N+Ϫ2'؈]H>/myB-,2T\Y"Wȅp`=`D<"?7 ˡq@7=I!l<^{lذ2 ֯ Ǐ7`Uޕ>?Dk$+KTyKs ,X`aDxV<#@ GB1s#2t}>ir#P! 9ϋ" zI~{iN:)I7  r2~ܘ?n^ @Pk.[ɫKΓ>A⦤cd6]+K{\G?I.{gwmR/>"wyVȤ /;ġE#qi&z }DC>Q 7+\uUfƍ6 U@IDATȑ#䥗^jD_zu3nܸ@ 1ݨO>˘Q9|O<6ӊU"zY.7p,>ܴhBw3#7E'DX(IGE9*>b 23ϴ"b}C w׮]}Җ"/^$<8A q { k׮-r"|.[, Q+ćQ>묳 <^7*8Qq+*U,Z:u V~w/cr7ں'6}{+{ ~\sm2?kGg /vaYODwk=9/8<$|$4=pF>IҏHHHHHς%:_v         " Ec}X竢?: !w?(QLv+./Ω\K9\TvPGR6'sJ:F&?_kɵ/ʾzM"w}}v&RCٷo_q"Κ5@$AgAuXNg~Z_A\\ZEAĉCQ!CDk֨Qc1JJd{X ܹ9sZ˜9syǀ(v_~eVoz˶A /k_78C,#Y 60aJK$knwРAV !+s/~Qf0h<^DȈ]B76֊[)lb=P{ 7 (qIr?TXQ!4z,]-q psC}|a拸/cɻk[#Y<8tNz=yNj߳wm/YhnH_?;Y9J378c>'kW\[I܎C_y?5ܼl'         \p?$"z]neW6'}2MIksmW4EW\ڤ^})] >L:5c|D`"B7^ڊ *D~7 |@{7kfŰp!C9;YI9SO=kb wذae˖V[.DdN/#\qS߸ 7%G~Mc=r`QFGk`dQ7|&ܢ#:pIq"D4»҇F$ۿ/m"Ũ3Ϙ7|FӇۉw0f7p ܄ =0Ջw0v,pxM`Cc v FƏj{ @ iaqX֣l2_tO ZA IksmW4EW\ڤ^}DG1bMg-_ 7md#o-4EB aBp?[@~H;vѵE_ DrD "| ?sUWڛn XZ #"K@LME 6@"l<'"R֊xΜ93SxF;]BRkW֭[B ]IXksP @|% )`;~Y⧝v9餓Ν;7+ƘڵP֑1>> pg[p} . qXcܹfÆ vlA |ovsIx:i~}%!?Q|6}0}GQqhꫯ>{71?w!I(!v DxuA5H;4۶mN:>SӼ vNs{5ׄ0'n!"]ڱ細Aʀw^-tԟ|?$|F'!1j*3{l;6O<h8 o k֬i8t'O?ݖe=>[p?z?mv$wu݆99}7S`l޼y$gg?     ' z\7f換$@$@$@$@$@$@$@$@$@$+E Sun=&MIt,BE!|mMҞ&׾(Q6O]KU=A(5='"" m$ DBɓAB,)(B -"Jc[B|":7"uڴi% 2F_؛Ǐ\p˖E{UVCKƸ--gbMGć]DzYKkq1ާ8`A$#D9_<l]SO=e.]G!"?uqC?oJcC_!:sAčt]wt$e+Q>AwMƍJ@rh9; ;H7`!_&HCX[6uC09Ϸov -,z|;[gp3ޟDҏ_#ڲM${>rE<п;TP~0o"j^IHHHHJ}2~kyJ; Ir8Zjb**A3&% 4;j.íGd4<E($#͵z\Ye_=&Ir߻>kz OjD6A<7nvp?VDF`Vuj֬s_$BVZՊic@T+N܋-뮻` Q c5*OF!"+վz?6n3#>Db׮]V1ײ QuQK2I": r 'rm T6&_8g "5Nu|FF EӧCc=c=zYCy;L_W;{/ "Uqa[mrd υ\`(_w;w7ȭ>8PCp0W s̟?߼+#;P_[G 1>˹H:"b^p߯MZvloݘ5kVȆJ8>[{ւw&ב?nޗsG"}C+K, u3όwA+>I[TҟA`-rCHkZ4Y&    (DX/ἌG#_[V&[nސk+m;C-[,%q%@3USN.$?Ϻ$ y6=Wr׆1q 3> 4wCQkڢMbڲ>7gϔuvIHHHHH @QסE e|Ҧ~OP΅j4|mMҞ&׾(Q6O] B]Ĝ?8Y1_KӵD)OHBhC#3~/%5 BU}`c_zl#w_4#~p}""UD|/+Mւ#XcXzb?~Q9ɅWT)3E>>qǛ38#C `e+8F%>KA ώ./{-ӡ@ аaC{s=ƈL^[ /p&"N:8T;Q䌽n'>oO$@$@$@$@I@qO-+̙3g3LJnuo-gB: ُm-9n\hQ3#FXx! tkC9Kbm֭3W^ywIYȑ#PJbmE%0ڲrJWQn0M4jHHHHHH@L -ex(6'}r.ԣIksmW4EW\ڤ^0}I!r F%DqXlA?<ʭ+HHDAƍ[17҈[]3V" 'ٶm00+V/Y cǎwA[I-4aֆ[2}]sꩧn͜<]mNL^ڂ SJjmpcs &p8 An{\j_$@$@$@$@$@$@y!@~HE n=&/m:Oe, IksmW4EW\ڤ^,Pup^ D$@y!H%A/ /x-aN$@$@$@$@$@$@a}p>d+7hԯ_٫*?7uֵ~!zG4鲖Du'رȻN:Ͻ}vz!ŭիW7db%`ZjYWwڕhm٬MOSς}g$MH"E GB?ܐ[ ܔ}nݺ<q;uwA=v]w^zɊ§O/\Fs|cǎ\΍]pזYK{m8PѧO{2p[&nu߭( : C|-eFeW6'}r.~RtL~6צqeiOk_}('E|M[8? Õ @!/b~vHHHHHH 3 狳~?n.|v7|cnfrJ[GnDF>͓&M2#j?| Uo;Y)%OLIF?*!,mmڴ !ҟ1cyv ~;me{o 0ygo>`5:N iֆtMfgI3g E i?oYI˖-3z' yM׮]: _|af:t0]t5y= vI`}9(>iGƖqws؛};7onS|^/R3Aѣ,)g9%\b:ƂhĈaMyd<,=t=ϫIݺu"t?AopܴOq88;Zז am{gϞK.MwH͚5-3tPps0'     (|ZDxn=&//m:Oe, IksmW4EW\ڤN~5M Т/ Da}.Yd|_E/a!ѥ?ϛ7/$*~#7hVXa}ƍg .IxW-m7@5W_}uI~ر~6{lY}ѢEfĉbO?ݖȣZ`> Zg0PL!ڴ[n^t6H'QZ5{6nhʕ+gM: ž=-V2F)/Do֬}`qDHuc*kΜ9s)׼g4i"S\ߚ6lςC%7|pC‘G_k &)ھ;{S֭[- &C9Įז ]i-7Y^*Ud[j%&$@$@$@$@$@$@N _uoѭGMIt xqS12\Ǖ=M}Qգl$볻6S_]ӟ@l&         DX%O8LCo~w%;"#"6nQ!nܸ>G}t `vwVO-Җ@~Y!@W\i:[MSwe:t`."W#]}'ZԢs}@m"ǺqAˁ.ג^sGۂ8,qSN:$ΛG=X:Ԭ] 0c SB`(> xbCwb&ep_n/4_C]qǤIPk\ >GH Sdͥ6YCT^k&k^n3f.zqDRM 1'     (LZDxyn=&//m:Oe, IksmW4EW\ڤN~5M Т/ DaO8+y7;B?uT'm޼Dm-Ch9rHSJPH}ͩzbSO=U7[Q4D@>3x>cpG /~kBϩ١E$YC ,[]vO,`Gw΀1@ 裏nx4?SJ<0nP5˸>y7_X;;,_ܴhN @p?$"z]sQ6y>iyR?'(=0dQH:F&?_kɵ/ʾzM"w}}v&u بiP}IHHHHHHHHH }^[d!\Qrdbr-樣[Nv>SŊ\%3u+0؊(bqf4CKQN:^zhaOrNPI6 ^iӦʕ+n4h`g[qwrxfI9n3h֬4EiGLʺ85PȕW^iG G6lh dh fɒ%v\w' amQXkûТ}wZKcm2w\^kK-?csWX6mGF$@$@$@$@$@$P( ^zM^_tO 7%#͵z\Ye_=&Ir߻>k:ݵ1)܏f         HH@>|!2}CAj#O2Ŕ/_~y+G"C/F /@HFֶb{n>*U2իW䒺M}gݞFYBH :.u_f"ySӧOǷr,| |̘1TP|mfܹvIr{Wk.c,%Yn`M&~t- @p?$"z]{rQ6y>iyR?'(=0dQH:F&?_kɵ/ʾzM"w}}v&u بiP}IHHHHHHHHH }^[dQ"rDF_^C!:(U}.t vr嬭F{UV q"q޿+1A"D~ҤIc zߵk{~"̥m;'뾺ūI&g9r}viذae˖@^=k6ϣY"o"cY!$y69c ދfa3p@;ET/};ӧ|໨P&kyI78wצĕKzmieZ;>b 3b  C|-e1e6'}rB12\Ǖ=M}Qգl$볻6S݊3R;HHHHHHHHHM@QґƉf{۶mZ%\b3"Q:l .4'Oe'ѥ5y6T ]nTv09sfp+6_5?|3X/}RG6Y"5kbl{'zLkjӬq f͚vح[V </x?8q!ݻM.<"q̙c~aymM] :Ԭ][+Vh)Ϫ%6}cCݺuwa߇^[.&ڲ͛7K/"|~  C|-e e6'}Ccd6]+K{\G?I.{gwmRp? ihїHHHHHHHHH >J83Y5?cEjqF;<-Ze-Gxx rZĉ "𗵔D$ #!B;C #a@ǍgpAM6lhVZeƏolbj߾0`-3fgyOAY!B12\Ǖ=M}Qգl$볻6SFMӅ4K$@$@$@$@$@$@$@$@$@DX%EƏ4M0GqYlY0lL޽qC$!ERi/ ~h#/cZ:n#@:"Aغvjz聢MZrF#Bk6}5GUfmz,}!N裏vu1;wfCw"!y š ZqCyd|,nC Jͳ75`<|!8`kg`/??kso=O[.N5ߨrm?&n=y6fYFك-r @Ap?$"z]ƻsQ6y>iyR?'(=0dQH:F&?_kɵ/ʾzM"w}}v&u بiP}IHHHHHHHHH 3 {ǷqqC,ofh(ng/dEN 1 l AX%B=m4K/mȐ!u}(xr9ꨣl&`P_a7 ?ߜtIAD!=zBσwz_|юCX˱kjmpƴc*K!\ 1|^eN+W6vQ)W^9Okʗ/oOn*VN_C%7Wwlצظ-\T2ر㻘HHHHHH Pk.E(t<E($#͵z\Ye_=&Ir߻>k:Yl4](OC$@$@$@$@$@$@$@$@$@$M@q2I:?۴i af &fLzP#8Eݻw/rRJ۶m3￿TR;шjժsUfmř̈tss[^z\Wږ/_nnFsۃGb:ٮMw6>ˇ~=Ē!HHHHHHJ!A2ކ[ɛKΓ>A9'Kl!|mMҞ&׾(Q6O])܏ݖspx؛HHHHHHHHH _\ƏqDLӦMCb^D>|ꫯAdNjEeB>rH'6mژ ¾K܄s      J _u׭Gd+MIt,BE!|mMҞ&׾(Q6O])bB~Z%         h"ϗp^Ə^-?n^@Y"a~>}lD:u^W\q9䓃: C3O?U?~|Noi('*Yɭd8s      p?$"z] pQ6yY>iyR?'(C<^ܔtL~6צqeiOk_}('E|Mwp?IHHHHHHHHH !K8/-'_v(Kva `뽖~aÆ?~6J͛M i?~rK$@$@$@$@$@$@I _uέG=MIt,BE!|mMҞ&׾(Q6O])bB~Z%         h"ϗp^Ə^-?n^@Y#ߚ/Šwevmj֬i6lHxY{\/ >G _uݭGdMIt,BE!|mMҞ&׾(Q6O])bB~Z%         h"ϗp^Ə^-?n^ @Pk.[ɫKΓ>AY!B12\Ǖ=M}Qգl$볻6SFMӅ4K$@$@$@$@$@$@$@$@$@DX/Ἄ[5ܼl'         \p?$"z]neW6'}Ccd6]+K{\G?I.{gwmRp? ihїHHHHHHHHH >_y?z߷kyN$@$@$@$@$@$@$@$@$@"@~HE n=&/m:Oe, IksmW4EW\ڤN~5M Т/ Da}2~ oqHHHHHHHHHrE _uzM^_tO "D Yt=,ir틲e$]_ݵI,6j.E_         & | e|ߒe; !A2p(<E($#͵z\Ye_=&Ir߻>k:Yl4](OC$@$@$@$@$@$@$@$@$@$M@+%_v          C|-evQ6y5>iyR?'(=0dQH:F&?_kɵ/ʾzM"w}}v&u بiP}I =ݻw]v0+WyQJ{gnj>hSF]LXk?p'=fy\rRJYU~|c5ժUJr\i[O:uLFt/ >@@q5ܼl'         \p?$"z]neW6'}Ccd6]+K{\G?I.{gwmRp? ih-[W_}eo?sA)qp*7ol&Ol .ثW/ӱc2#{Ȑ!ffذae˖89{l߾ݴnwK5:|pfsYgs9߹s0aoB!G&Mmۚڵk{|G!_nO9唐]޴i+͡jxkڃ~hpFۤIl믿TZqlׯoݿ̣G6۶m33Guuy'<`>`3qDM[/ɽRscGyĴo 0 mw q"ϗp^ƏÔe; !A2p(<!/nJ:F&?_kɵ/ʾzM"w}}v&u kcS!H}ٳͷ~ZGa.bzֳ~#[ZAϦSD:xv@㺜gyhaoD17\*D/^x`_a+\Ǎ9ωbСa/3_{w `rdžyN=6VGʷ~{~ÌkxwcGM@IDATT?eʔxBk"罶cΆNX / s5Wan&#q}N`+ 3_XoFܠQv BAY {J8o㷂Sou]@wpAE ^f[ϫ>EQZk/ז|Uޗr^f3*Sߜ=Y]ZKTt#>/ʏ!{/I&EQ. ?蠃eD.<+7h/9昣o:ãF p nanD<|5ꡇXcX=^~A~a]uQ'e:_ĦcW{ꈞ#8"4Z>wÿ3/ ?Ϣ٢3 6qɉ޾nMDgH#'?3coҍLM%tCO3>6K/};,=kmMܯϏ5Iޫ &ϲ1c6TMk;ҡoub&S8Sĉs.: " " " " " " 6~+P=uVUt ^DNe6SM^(T_-zɽ/\fUrߧ9{jm,:]댓nrԔOr\i4^uUa!,L",]̎cǎQщ. r1U/'`#;qf̘rs#Queiמ[H@~Ó 飱eײr-3\jɚtlXuU _:jC=7PNx{cXs;Y {J8oSou]@wpAE ^f[ϫ>Eل腡B1R*[{Rl_%7}꛳6KBE:zE o%,⚐s."RoS524yTE[nevm;={C;} ^0n׵wpߋDNs8IM"~Ho$5jT`%Lcwdgt>m\t'`_:I~lZk?07vj]˿@ K~nj6裏wy'nYq= ;s__^9,/.,E6~1{v.7ޗl659kyU?ߧ(#j:F3\[jVek{_ʹz&O}sfu j[p|G1k+?񏀈ű&Py̘11*\NE>}z8ADGDEb_w}wl(-n`|D]C kF0AFmX>ll#tMB{l.A@z [l Ή)7| ^^ Qpgaᓽ3C#C5>( D_im#xgz饗~GsqjL Vz녵1>k9mZN?lӈsqLޅ:N _߰攀4Zm\ߏ|~"ƷSN 'Np?|J>o@`j" ~ ߋ}ifS6W}rkYZZ:F3\[jVek{_ʹz&O}sfu Kc4H=: bOij_[=p\߄k(L . ڨ+U'"s"jVǞs(F\O Fo?6x &j;?OaqcB>8F57INjxᢋ. (}fQm$ȵ#ܷw5'M\ލV}6n1&fׂ#_~9au6r\x| {9v]L7n\te]vء4&'6JZUsVr` 3f!:4 _]]j*kXW\qE7{ߪ\O6Y ~Rո=uVUt ^DNe6Sw5U_-zɽ/\fUrߧ9{j]]-KLlꪫzQ?C9$F>3b-ݼ9V]:7l"Ļs !^{+b'G#Fx>sDwy1驧 SO=5p_ ~xW7p2djgq"[b%\2-yp?Cv`p#>;aС_7eً<ȰꪫQ}zÇ9:ujhƹ;Yg`0k {~93zO׶] l`H9"V>껐_ߣFʞ`˄3<3r4hPXpGDGa']C}#\D@D@D@D@D@>LXߕc7#g7󡭧j" ~ ߋ}ifS6W} Cc4˵6_oU:̿Jn7gOmVpZuh JzA~zU!{! v[m6N&,;‰jBXl(ЧL[u<3:3Ƕ1?؜(vZv {47tSDj[/#×m:1cN&c:\L:,(x3fLqޣg=Ɓ>E.h/~Dzvt( l3K,D`O>>=ӛo#çg}6ә!܇,qMD,*~]sƇ_xn0a„`Î;pb'Y<#Y~ndqt2[&)Ἅ PO]u." " " " " " " " " E@A2zͦ&om>e]MUhkKmުlurK9W/oΞڬ.~WWm4 !(W_= 8o~3|EsNKwDKBHk}ThNqDGPxs@K.d<=08ĿnjG=FXڿy{.\r%W6f؉v~|l<;`e.e<&6!ftA@r}E4{>3'358} *'Fxsʀ>e'9Vʮ63tĈM JZ%b-f + p'M,וb@1'iC7ޗ^fY[ϫ>ExWS1R*[{Rl_%7}꛳6KUۢ-f"vaQ4j4hP"ط{ 61o&sDg}v@\Ԛa/Q~(ryzD_z~FN@}ĉvy?#¤I|fm~ӟu{tA,7n\<nFqYdIiz(g)CDӧO/lDgs \m lM'7N5;43:8ԙ[N@N ?~Eل腡B1R*[{Rl_%7}꛳6KBE:f/+2\{1J*·#I{;e"6Ky- n-Eo`SŞ{niԩQTe}De{k (Ɵs衇Q;ML0!\z σ`:Stעe -!^'Jw]3u);V#MOn8eލ_~x^;P _|qeȐ!av s1G#p܈)ihډφ43ZG!'%*눶N;p6Ω+u({lD<0pƖ3cƌj]v- /a}rkߛo0ÞJ7NSH#>p]t ֈ>g 4*Ê =OȥD>FH9\nc;.R[iVNۨDzԬe]MUhkKmުlurK9W/oΞڬ.~WWmԋC#w 瞻HfNW7_`ފπ> &ч}_,"DGޟo~arg $;$o{/3aif6W} Cc4˵6_oU:̿Jn7gOmVpZuhWD;vlꫯFo. ]w]4rȦ{&ua$[$o{/3wif6W} Cc4˵6_oU:̿Jn7gOmVpZuhWDoosEk{aE >{݇.," " " " " "  g ^DLOZ/TU|lBFrm[N})e6󯒛>S{\ƥꫯӧ,w E@D@D@D@D@D@D@D@D@ \ND@D@D@D@D@D@D@D@D@7 ^DLrZ/ق[ϫ>ExWS1R*[{Rl_%7}꛳6pرq]s9'w%wS$w$o{/3ifk om>e6 UhkKmުlurK9W/oΞڬ.~ N ВpZD@D@D@D@D@D@D@D@D@D ^D Me6ß6W} Cc4˵6_oU:̿Jn7gOmV.li޵^}̬H?3iZ" " " " " " " " " 2 gճL7ޗ^f[ϫ>ExWS1R*[{Rl_%7}꛳6R/~a}iX_~y8qbmfV$ܟu-YD@D@D@D@D@D@D@D@D@f& ^DLIZ/U|lBFrm[N})e6󯒛>SpaС K'O=T-H a:e~H@~8ie>I@A2sl69kyU?ߧ(0Q:F3\[jVek{_ʹz&O}sf>)ܟo1Ӱ&Ln[Zp?%"~g"Wי}57ޗ^f)[ϫ>Eل腡B1R*[{Rl_%7}꛳6KBW䶑|q&9I- 7ޗ˴^fy[ϫ>Eل腡B1R*[{Rl_%7}꛳6KBE:+6{/}>~o6|J+v׿°a'(}zaq}~s 6tOb;=0`@X`\׿`^{-A`aƌ᳟lXx4m"-ajm=v\|X]@D@D@D@D@DWH+uQY |/ef>lU|lBFrm[N})e6󯒛>S%oc"~5Z}(TWb0fAxuׅ{,#Xi>~EA*b5\3<<ëň_/޲Ħ'|rx;uT65^ȥ?|Zԓkg _}䟋_zK{sTq  >۶r˰+Mmy7ޗǴ^f9[ϫ>ExWS1R*[{Rl_%7}꛳6;>v嗇'6ffEִ;bĈGV]uՆ|pG6جo~3tA-WsĊ{lx; |&?o*x}!EHܤ{#G8J"r}Y~?ާu Yv)Sć\r%믿?iXn.cъ1Dy -P1~]c{4sE]`K]wݵm=+c k^} lv?+?:!CĶGOD8sF~ 4GہM6b۟k67|Alq`;/FFع^{mѡ D k}޳N;-Fp.~8fW_=|G Qe|p}Uɓ×b/1836!*v v>^xa=zzpSO=ؐ0`<UW]˞>-sbsf lJrQ." " " " "зH߷Cw#" " " " " " " " " H "z_fzC|^)&D/ m/ז|Uޗr^f3*Sߜ=Y]6j.ߜ|vy(GkČ? |ܘA#=#"%: i;smV^y0zOGTwD M᭷ފC8UBx衇MniхG3/: &'4bB"7 *D>3s*P0u`yx!+ǏO?t'8HrJ%>s+D!5'6ӧl5wߗaK6~x&gmc<~^xRck -R|10{ E{AAt1!z:'˽l^3kq}JDov/ơ~ _BinjlðvE}1cDVU6-">g[Ć[o5{qrKemq3gO彵vusL[HSqE@D@D@D@DwH;uUY@F?V/eEµp--T_-zɽ/\fUrߧ9{j˱{$oq(VO~ EnEGCN8!Fg~.p{ԨQ1Rرcg>!yذaQ<Ĩ ?|?b_5lpg?Ym @?؆|Bػ{Gq@pq;Z-qKUѮ9s!D3 !.((&>(cBV"P1"ΕhO[n(m]p{ wqG5x_?B}GSַ6h{챸7h輇Fg~O81Σ焊VZ)8:7rwG2"f;mg W^yeg7/GE}7DpD}!uFK.$ cPA,ϚdӍOl7n\ᛝM= io۸!YlB&iiʔ)=#q3Έ N_il[mUlƪ6a„ܱu5gRwmyAh?W\1lv+1?ON%ipJo8/c F}66ޣnDD@D@D@D@D@f2 g2p]ND@D@D@D@D@D@D@D@D`%Сp"z_#lSM^(T_-zɽ/\fUrߧ9{jz j K/fsLC9K,D8ڈZ /}ˣhffYi#R'R=k%ŗzEE!nE!FODm^ė %{Ygq=g"BԿzEQG|N}l`@JBⳆvZbCu/vH^?g1upG N.¸!77W73 ۭ{9<;ج:H{Mq]t%)!dA+yqO[OX;:.2^Dx26W}UkEB1R*[{Rl_%7}꛳6pDMC R,bE =Mn٘Lr\7Max0\sӷ~{Q;ıewoiGhp1"½E#=#(DG蟋hH&MjoU)2OL(DYFPW\qEk-Ұ]?Db馛A}om6+ᴉ-B -pÏ|o zpA3&4Pf}(> yXÈmM0Bo6^,?hРqq_߮pk>.,YD'MMXk@x?p<;;kQ';^6"Y1Ip!:Fɀ91de)Tlg DN8 =6 Ɣ+_Jv۰>qlC&>#[%{g΍ܜz 'B0|f9i"G!o*vs[M߯vUv}0'<#xN_X_G XrC@3WSMCw!'SEGZ/h9kyU?ߧ([WT*T_-zɽ/\fUrߧ9{jm-q:+/^:9Nnka2?%EEL${#G -!'jqjVe]8 G##F>|xW"(QdX&gDܿ&MZ;5"#=S_ztM `o68۷-NZsݑZ pM,N(K^o EzQ)$#Jdؿ+}v>: ao9ŸjaLdL9a |~i M& q8A[vM9mi{㎋Bp?_>`_"Еd\Xk~NlL[em]nKS]wq=͗R~,|/GkuVsitWzݵv++줕gy&nnn>^% ~E@D@D@D@D@D@D@D@D@f!7ޗ^fՑ6W} Cc4˵6_oU:̿Jn7gOmVpZi!4^o!<'~.]ti1%zD*GwF1=m1/[/~>B$ߎe6 ㏏bs'|f~}# X}&UW]aCߟr([up by̚z;7]Fy嗗gmqsWS+=5acbvccmsO^Xl1"3<6Di;/rl &'+ؖDa7ywSxܻmjz+Cq?stSO?L:52ąN '=Q}{#8I̕]oT=qqK̳l 'M(T?7F6۔a}D ?q&V!şhQsWS, 6 n֫r7|s|wZk*#" " " " " H'E$" " " " " " " " "/ H "z_fnzA|^)ʈǻ/ז|Uޗr^f3*Sߜ=Y]M­v&g*Eӧ:(k1ѣ;ETG0^{ŨiDz{&/Ba̘11 Ө¥^IDocD>묳bvmEן*w饗b]GqD,za5a"p,>a.lXɢEF\qDk7l3~[nY#VJkb21C=xbBTODz,/u>Cd?w1:TJdaS9,;Ex^?tІ\s^N&M.'<7 '#|Gv}u" " " " " " " "A{;QGqN9W/5XKkzVn'}6$,5k}>E\eU,T_-zɽ/\fUrߧ9{j-e$oΏƏE .`'g#;vlCs8'"?#ǂ4,?#s7<'?Io%\uUQܩ!1ȉ'Yf)SDq<}؆SO?M7pc!b38# - 7g}!+?G? _җogE9gxBy-RQΏ#ӫqA=k2qߢw%II͏z+RK.dO7o Gpܒm}a€H#ܿ#<}k񳆓ƍ d\}^|͸cKtƍN~k9ܳu~߇;tVYџ<|fQk3pf:{mɍUZ;&RnB9n]D@D@D@D@D}6#N+s c9ӥ7dm~FGKs #'=U.-6}6u]gFї_&" " " " " " " Ut|#'ޗHe6-om>Ofvrm[N})e6󯒛>S%ܯLup9/-i?a/р) qb-spna}r!a5׌f׈0Zkx."Yux1{cr~H^N43fC?V}~{s}$Dw|ͦۓx_,bV[mEMNy-ŘoN*̯Yncb{n6l n\a%`2?Vٴa̚j\0X瞋=ެTm}`i b kG6?pAWh~l +а |{Dh?)0|F⊵~esϓrӼ?|$ +&g0W~׃#r?=Q9M҄ ƒ>kw2'tR\laY8!Hua*oUa*k6ؼul0X+rz!>B`f{:ExWS1R*[{Rl_%7}꛳6KUۢw1j]Ċ]qh>q0DHX?Ccd4eD;X:uQA9 ^$b1 F!:2&?r9>܏,QQ6"lwÀPMtfƽ袋<2hbg?qr|Q.}(h D2}=}QιwM)0@{Fx 7~ w^ NZ+L>=|QX͘Z{@IDAT~衇p7G?tx9qa^s-xO>f KD'jO@ώ~V*vn޽ɓ'7q+=[\q1[!9$pml?a16D0"rOu駇z+s/+ v[^LP~ _E1>[DczYs~? `JeMIdPK<bTD$ľlk"zs8RK7_|XN/7a*ѹo?"d="K1"F?XvZp۶~xe͐8z7e/ď6`B윿M}-QmsI3^ A%6(ymc>&N_}xG }#>S6G?6$ Yy8~lRGQ |n^6}xeƵ <$>kV]uN +a&`{+q<1B]ڏ:܏_[W7뙈aVda~xkQ3SXl0'S0I,>3ůGM*k~䇲/A}6E5\&i焋." " " " ";#߾iGw,M:ӥ >wS΁_qJ"PFSMn~|'w};3K#/u L>E@D@D@D@D@D@D@BB ?EGZ/h9kyU?ߧ(wǷUhkKmުlurK9W/oΞڬk#8X@'~ً1OD&j1n(Zpn"O=8G1 .X 8+I10?ih`NĀ|m?jԨ=%8 dS{1o癉(wN1pCKN~P$ ? Lt‰q5<1Ji D*GM/}K[C~M7y>木7+?р"^Տ7.nfjozboώ&?r-LxkL7a`D_2^oN(nLWނQ>Lj:)}GDbZy>M6_|qon\r% 6*e战/U]?v=' %ܹ-X\l~6fOz.>کa>V;b'$>Dgn)_3[)F G|ɉ{w%m58|Xt'ƒpߥFovÇ8aA}xE]2?!Hrcص|+wvfCӽĂ>ƜkfB.[c9g\bY7?޽p{&>`ޑ:sWCv:p^Dx26W}r7օVrm[N})e6󯒛>S{M_kecg O?pL2%F~ կ?ٛ?{ىϺɳq,qzȆ_>`Q"-x7 v*?6#dIpRZkʽV{OZ7Eg ]bԽE@D@D@D@D@z@oٴ 1&ȆD?~| _+g]wHGPmCymAx7ss"#ˉOp k%~%cor^sGa18B:.g! x^0`*};0N$Hߐ!C):ƶO )1z1}€S 'ɽ, l ѷ 99ği3ٕW^LTNG憹q.kׯp|;/袸HxÄ Q 6Xc{ \HyL9fv(ee~E@D@D@D@D@D@D@D/>LO&ċ}^fr~OQ6!zahPuf~^'s2WM|Ptp-@%ꪫF17 ATtN4_~#@:+ 9auÑE a=r?~eO3#Q@̍p"#@ϥZ&va ECR@$}G7lG<a)&Mj^$3q23<ӴpFp# SN9%\zYɝ*sj.1L*cφnMLo[Ss҈ i6X,bE뮻.\veEUa |` <0بa~>;!"s%>prLome9h 'pB{'[nvN2C*ObYVvׯہ6^[LsfN{{'_ׅBaСԄ r^' ~ ߋ}yJe6ӜSM^(T_-zɽ/\fUrߧ9{jLz~重=EV㊀@" /DEV[LE@D@D@D@D@D@D@$ׄϞ{YldM{oaHwWFV_}h+#/| _' 2$<Qχ+9{ ,@Xqc۝wO+; Dc=B -x(Ǎ#ߡDkxD-6ml,/"{|?p6OJOC30 ;Q[D9(n `xybv?>n au ?`YXR`N#qD3/Ex{۟| QxUWcxvN<袋F|WI 8 K/{`+GQV:Co,N{pK/||&.>xcF\qR9'՟pygFZةip o=&82ϯ!:)'gcȑ#套^ wꩧZSaqGI&~[mUfmzY!kv.0㙚%6FpذaQSs?~É'p ;CtM-,`Kfr:ٿ&wG;CH9\nc;.R[iVNۨDzԬO-L UhkKmުlurK9W/oΞڬګ` ,6z^#}Gl{.\tEW^i`? ́DOv) is=7 S0b?3:ujWاvZ@&"s:%/<{91VZi%>6 >sO83 [( Q9s<` v#3~K=3}^.x|LPDcAiz}ǪynN#F)SS2LٰvTw2 ' ͭN:),6Dٸn7|3ֹ^ՓRED@D@D@D@D@D@D@z {/ef&ls~OQF~޷="qJ y*&BK'{3fD9"z+L>=Fe6 UhkKmުlurK9W/oΞڬ.~ N В!CDan<,746|y晧p?' sR93\r%t\2~Z~B_]>}7kM˩:e3`3mf HrLJ`>7)W^9=S_N+`-{3Bwx2z:nnc=1g]" " " " " " " "Й O,m2gf>~roUhkKmުlurK9W/oΞڬ.~T#|: pE |p+{2%X" s n~7 tn4(Q[mT,뗋?vجp?7ֽǙ%ܿ;YgeHbo~3lay l8p`8蠃›o{B_s~\G&M- _B\髤o1\tE+9)1Sx饗~Wk-} {bΘs8y!!l]kz6" " " " " " " "ЗH "z_fzͦ7om>e6 UhkKmުlurK9W/oΞڬ.~ N В RK-ƌfիT uR]Q[|:uj\ф03-W\暢؈cUsw>"^&LP[oϧ> aƌќi޻pgyfXdE 0mڴX~ zj-(Ç\RY}k'”F2ֹ'挍 w^4^{ey 6{G:]֩z6" " " " " " " "ЗH "z_fzͦ7om>e6 UhkKmުlurK9W/oΞڬ.~ N В ~A[HO>248/J%lHU%_ [@m)#ݜ[nuﱪй;}Ns?Y#sNXsl>}zxk6|sҴ̆? >ַ'_{z3p*oOcx?#Hu6SlE@D@D@D@D@D@D@D/pAE̔2Mo|^)ʈǻ/ז|Uޗr^f3*Sߜ=Y]%oH" " " " " " " " " "P@#=#¤IC}Qxc^xJ4{$q[̉{H>llࣰpꪫg4hP5jTXn%n馆vSqv6~\hw7..9#e]MUhkKmުlurK9W/oΞڬ.~WWmfH? y$x`ŧ1#*iZj' B~hXi}C-uﱪй;}N/)RgB*n6p+}Q(omzk[U>siTVᄌa_c +bCSy=1g6v|6 kᖮtmclE@D@D@D@D@D@D@D/pAE̔2Mo|^)&D/ m/ז|Uޗr^f3*Sߜ=Y]6j.=%ܯsY@o ǎsL[J##r/'O#GaBp~;z^+ [ou?czAƮ"n&:'NhCv\pv@*N9~fa~]dڴif*wqS5\NswqaO*՟~pQGҪcN]w]o 0#9l>r" " " " " " " "H "z_fzͦ8om>e6 UhkKmުlurK9W/oΞڬ.~ N В >ѣGhwּG Ǭ.hC;wBT_^^>k"3&6? tNop饗}p"/rukyᮻy晧aT?jԨڧTI`kr- / ~czv-^eg3u԰~}n[4C}Xn_~y1*Q,K{sCks9kSA\V[M6$ 0S{{.ȯ'D?[nec9nsO83\T9Kb6k|w$ >тyg˻eÓO>e빡*" " " " " " " "GH "z_fzf6om>o sB1R*[{Rl_%7}꛳6K_kwp>3!]l3fJ8p`~G1>M#V' ?"pB -T=s<HɜMjxw"ge x lXdE|!gRzKYz.om>e6 UhkKmުlurK9W/oΞڬ.~ N В'S@wh&5J$o{/3if#om>e6 UhkKmުlurK9W/oΞڬ.~ N ВpZD@Bp_@D@D@D@D@D@D@D@pAE д^f39kyU?ߧ(0Q:F3\[jVek{_ʹz&O}sfu XuH_|E@D@D@D@D@D@D@D@D@Dl""ɓȑ# ;\U |/e2[ϫ>Eل腡B1R*[{Rl_%7}꛳6KBE:+" " " " " " " " " $/gLove'$o{/, n|^)&D/ m/ז|Uޗr^f3*Sߜ=Y]6j.ס%_(' ~9g>0 @ |/eȥ2Q[ϫ>Eل腡B1R*[{Rl_%7}꛳6KBE:+" " " " " " " " " $/gC@A2HzU|lBFrm[N})e6󯒛>S%oc"~ZrQ! ~ ߋ}ifs~OQ6!zahPuf~^'s2WM|Ptp-@9 ٨ED@D@D@D@D@D@D@D@D@pAE Ҵ^f39kyU?ߧ(0Q:F3\[jVek{_ʹz&O}sfu XuH_|E@D@D@D@D@D@D@D@D@Dl"" " " " " " " " " uH "z_iZ/SM^(T_-zɽ/\fUrߧ9{jm,:]$ܯCK" " " " " " " " " "PN@r6j:$o{/4 |^)&D/ m/ז|Uޗr^f3*Sߜ=Y]6j.ס%_(';p)Ar΂ "HV Ŵ.ל]Wwu1aƀ9qW PD JEɈWo_N{nL{yyNMMOϝNQ̆-$@$@$@$@$@$@$@$@$@$ 3VDo@דl?m6Ogedž ijmP=ɦir!o:L|P- @2 ٰHHHHHHHHH!@~ ߊmHzMilBP@!Bms='?M{7dmZpO E_         H&@~2 @>([-_O)<U (#_ͷz[_C$U|M0QB~>K$@$@$@$@$@$@$@$@$@(Of         ȇ|+e I66} cCcd 6[U|rrdS4}ߐݷi&j>](χ}IHHHHHHHHH lB$@$@$@$@$@$@$@$@$@p?CoE ~=ɦCf~O\V!zl(vl~6fڞOn}QՓl&W6S_Dͧ Т/ $p? [HHHHHHHHHH gޖԯ'_l*D Ҏ/l=WYɭ/ʡzM*}Cvߦu tp?Z%         d'a C A2$k>qY象B1|*k{>E9TO\o۴N~5.C$@$@$@$@$@$@$@$@$@$Ld6l!         |P!ȷ"z[RdS!myZ?'.=6PH;F6Po\em'(I6O })/`Ӆ|hїHHHHHHHHH P̆-$@$@$@$@$@$@$@$@$@$ 3VDo@דl?m6Ogedž ijmP=ɦir!o:L|P- @2 ٰHHHHHHHHH!@~ ߊmHzMilBP@!Bms='?M{7dmZpO E_         H&@~2 @>([-_O)<U (#_ͷz[_C$U|M0QB~>K$@$@$@$@$@$@$@$@$@(Of         ȇ|+e I66} cCcd 6[U|rrdS4}ߐݷi&j>](χ}IHHHHHHHHH lB$@$@$@$@$@$@$@$@$@p?CoE ~=ɦCf~O\V!zl(vl~6fڞOn}QՓl&W6S_Dͧ Т/ 5k\r%R~ФIꫥR%ܺgz뭷Zj ~`˥sbx$@$@$@$@$@$@$@$P$@$@$@$@$@$@$@$@$@|+e~=ɦs$m6Ogedž ijmP=ɦir!o:L|pKժU姟~ . xrJ:uK8+,ע|^}ӧOzM6;C6 ^~e:th|]v#@$@$@$@$@$@$@$@$уHHHHHHHHHp?CoE ~=ɦCf~O\V!zl(vl~6fڞOn}QՓl&W6S_DͧKI ɥ^*9kJ#./h\s='s΍&,_\?pi۶^. J 4Gr :YyY$@$@$@$@$@$@$@JR̓ T`gޖ1zMgK_l*D Ҏ/l=WYɭ/ʡzM*}Cvߦu t)i5\#'OOP~YE0!B%@~}x$@$@$@$@$@$@$@$P(/QHHHHHHHHH`"@~ ߊm3¯'tilBP@!Bms='?M{7dmZpO UW]%SL,LY((//OHHHHHHHJ% lB([-cF$Ξ<U (#_ͷz[_C$U|M0QRQW~A GR4nX܍;5+Vŋ1ЯN:RV8W_-;wN +We˖fm&UV5kjSҥKʕ+Kڵ/DlҤIԧok֬UVE#kݺuSxW. 4HݿBx}~p[\':9:MzPL㱾Oׯϓ_~YE(1 HHHHHHHH 5 S# d%@~ ߊm zMyil^w)VH;F6Po\em'(I6O }+p"]m0 ym[i˻p…裏ȑ#!(O}''sr'c=&3g,ܢE 9裥gϞ=r-2o<;wnFFI5 k/93!޾뮻dرvڡC9Sbau妛nJꫯ/K|+"z2xL_tvZy䥗^mx D~ٿ0`qnhڵ\pGy$:^=Pׯe˖rJ6mG \F8k<q)GT!b|R>/BpI {.]~O.s44#w}w@>wqoȐ!CX        H$@~"6 @^([-_O)<U (#_ͷz[_C$U|M^!~'<2bĈhA~QGG}$/_)]ʳpBds%DݏnO>$ҽ{wBgV~z:4/'tR4k֬Ht cW8C7DGjڴy睱GNzΜ9r%<_鯻:i߾}ƈ1qNwqG1A|.??;bqqu38#Z᷽k"ױٝ{2|}76lwOվN<;qu {챇uY3Nļm۶׿_oh,֭`q&;ƜHHHHHHHH ; a+ %@~ ߊm8zMчilBP@!Bms='?M{7dmZ/}Dw}6CH?1[oɫZ\.-ܿꫥsYO|rE>x cƌoOBժU#w*Ub>@nDk_bV"|!GT|Dkϖqs$>x[8SXBkHAx9& >"kDŽ mv[1矻/XժU*܇UW]o>M)v}5w^Q%C@oի\|QCvH; =itHHHHHHHHr(}Mދv6mZ; 2Qf͜J         (Igޖ$\!myZ?'.=6PH;F6Po\em'(I6O }˽p?x/:7|էK[衇J_ ^oʾw] N8H C=$&M8ƑG)GqDd §L@] p_=nr-苅*U!CDBpuµ׬Y#7?/[7jH`O{ݔ;cǎr9D@ 2U\Yx y_3lْ?dܹs"pLd:oFڿ@IDATR:  3VDo@דlril\@Ҏ/l=WYɭ/ʡzM*}Cvߦr/LpPZ`x㍡Rp~|ɿSNq[(vg͚5c ԩY#'G\sL<9sG b+@T׿U 4uT˵q8!Z<*lB0:mnL_.?_p~XH6#uDzE-^׵kF!!.vE!tI' #I+ZҳgP^KAuYV[ϟ6n͚5/Ckl׊ev,^8Ocǎv7P;^#Zl1=+5沶1'       ( } !nMg.>  3VDoˀדlil cd 6[U|rrdS4}ߐݷi8}37,sͰinȈ8~ڈh+W.QW\KPބ#_uU?:aGvک##G}T_FK.ҭ[7iӦM$. o>!wH/k4}bpC Q^TRE: !>Q"D)B7o}Q*?hoF"Aa #z_} &+G \Q#FSN9%ǭйξȻm۶AଳЀdu,+hGM=pmqcO k.z~ޫW/7x?۵},=I&E|1s=7g0p_ˁCD$@$@$@$@$@$@$@$`lL>L2Ŝa4 GN/ftAHHHHHHHHHJ|+e ~=ɦ/Y_l*D Ҏ/l=WYɭ/ʡzM*}CvߦRwIN>du}7|#vTZUZl!ǖCt 6"j{2gYb-O#&;PIcXgɧ~j׮\sL<9f: uFƺuqlBy˶],{o{q_H~Ea]%6a„h+/w_G |&v1C(>/vx 9v"0CtիK5E /?4 v.X'       $ y{Ÿ"cKhD3 ofiӦM7fy3~jK+v;wwy8s6(VƍV/&oǂ[\ p??FLtwgرsI  bv^(;SZ[op-H$E:kTL9c="xkbzHU&?&0`@/66~]redkk|ѣG"_lfbN$@$@$@$@$@$@$@oUGydVDߥ7DN~}섹6l9  P!ȷ"c[;dS!myZ?'.C<)Bms='?M{7dmZ/U>"#RЖ[n^s婧#GFck.f|J< Homf`B$({}x}aCrna4Dx͏8∌Cp?o޼p.?Yf1hp}x6~hPq\&1wۈ/v!V?sヒ}sp s='^ƍp:uj$FQ8@jժ1QB|MVPbqH_tE8{7^.[a>0\sL<9:8(zՑ[cp!ҥ'#FE|<tꩧʾ~EWʕ+G!FAd=~xu5k ׯ__Q^1/>#͛7Ç 斟|A&pG\c=?,b&ϋ{$mG`F_/c]݋1><ԭZ9<6y\^+鿃tkR'g?: l?Urܪ\ҽI,HQpϲ{z;*x7U?Kze?N$PP!ȷ"z[Ƌדl:Bf~O\I;F6Po\em'(I6O }K]ߣG9≃[o ! Bܳ:Kb،J 8 ?`;"?:*r @I g8>;CF\y{5Xe/N}'cúB-BuDѷnݺrQ}bi?x #&Ip} 0X'       J[њm1Ҧ}wڨ]wzz>p6M};eB^TzQdq=vp~!w;9ol!72bŢљܵwG9bv׍kl.EPBE[!pGe_>tYrNVБ%`7Bgkcٞ17ic,/-X[7G/ ڗto5뢜whXKS(6$!7&ɫ_}jxk ?6"zmy p?Co̶ X~=V6m6k۳ө1 ܳ{&÷z[_C$U|M"܇({ҬY3iРAi/Y. A _ц}]MD׆ lv(E>v-hXDq]mȱ` ,nfiҤIF;D\pA"ѫԩS'bZq1|Q=^%'=TժU @|A?es,B2#'\'nĉc}>"E?F֮]+ 3LBvжm؊(xl -ʰ~9$(^o,. _r%pщqB](`ϕDl        D-ܿwӄ]2{ٞ10gza'>A[&<9rdQ35X{`"&pQ}{nlۻ#XHۭ@sʉZj\w{C]*{.̵ߕ\M,  3VDoדlZilBP@!Bms='?M{7dmZ/9#ڵ Ngy&Qh.BiݺV3\> [Yp4ovY@Pyłno馌:ܹsh'Z D8pvahmGr(9~ !Fw!j:t|'bŊxC=T=ظ/R?(`w/[, @-[n-vMHخDZ9sB ?Ss ]w%cǎp5 0@<@9"p#"s̙cŽU׮]3Zwމ#ʾ `xW q3׼`AիWcirwG z6\'ӧqxͰ[Kc7v*W,{ԫWO|{=v /.dHHHHHHHHwq2eʔ< ٳg\UGsE:t.]s*}nǖ Z,nrz !8iׯ)]VS8ЗW[ KÓڀ滨g MizwZeN@I={l,`llm])nkGGȊLawA.on(MB#݂*&(i* >8_gM}T{y\d77ϲ/ksޣuV[5E'c?|wu?|x!rC>|-MW}kVPG%lmOZ?'.WSM ijmP=ɦir!oF#B3Np?+ Q9"C a2[lE?Ӛv|s,?~ NժUK=nذ@4߼y뱃}lWJiܸq?^CZjE+D|+Nsv|ʘ_XQRhb~NoY&Is(9ά`8׭[W0HHHHHHHH6  &#O/\Pw\cSO*b{ TZ퇿4NFhl}16Fg?̊;Ɂm3wcn<o<Ut^M(#3F>Mj"lE)ߋn@:vaN%J@8H]ذk~":K%uLo٪NfP=2<8eᩑF"@~Ɵm_O+6}2V)Bms='?M{7dmZ}DFl3D % CT6-D׷z5*?^>ฎꪌY{`~UM_@$@$@$@$@$@$@$@$@-Gt_E@6#ql4,6Yq+Pi?+>Zg'3yזu"yoqzu>VRE5DDwYEh̉>7! YdҤFU9G"=erZ-kd5#=וV;QE"Bh׀ݡu’׾^L_"nX06:5Yvï%!7e5c.`]ҩQb L#@ FVy3ޝЦqd@a_Tҡ=$/wѢ~>W^Pf,~(דS N/{o h\z4ͥemJuݷA4ֽW~TԳ0i2}c׬*tBNed}~nhǡs?>{WEXrtr-+H R=޲(#M8v[T}_䢘 >OM'~[*z~猋w:}4}?Ysa*{==7&>gXGYtkl.ߥR)`.G<;JmEͣ/g:ox}}>vV q4 ^xnw3|;)'yiw6{|S,Nwx}P`"(#D-דlIq}zѓbscd 6[U|rrdS4}ߐݷiT"#>#y}s\GkFjԨ۴wL:fS6O?_l[kղrJ"6AߥKk*e K'       HI 2nj8p?FQ6ukD ~9[A;uN\WEpߊ>mHٯ֎oZ(. eq t{C /jo^Y>?i7'hYB>8! P~,*aN#3!y~ZDX&Qwj|IfzE$K~}zʧq t"A{vyHdeb$k;lUt^#tg>z^?rSv,+ .˖pE|D:VrUm.Ý8w_t.S[/DOE?nH;s=~a_k +e@I={171X/)^[ҥq>?tvYc&Jx^z}>qӨd_Gz&=a>C#FQa K׬>!{ѳnB}͢Q,d:2 짛FψӾ!l~(ale,s)o!?,nj4y ~?U47{&;Zl ^1P}"E/VkwLǑ~&X@-5r>8Hg64 P!ȷ_&mï't"il؜W!Bms='?M{7dmZ/>f{Kzw7~]wɗ_~lc^z&x#Ȝ9s~ׯ__9ޒ%KDkזO~mY(CJ{Jr~v{s5~;|NaA}cn"G>Zg"9zƸqo}ՄO~b;{Jb&y.psjۇޏ.:ww .؈xN>X4v[ ;;|V=9؝J[Fg<9Cl:9 ֦7G}ICq=S >_wp-{ǿXskUz-寻mUd߃g|fv'8]tn?S e"P!#&[ͯ'ْC>u|]ߔvl~6fڞOn}QՓl&W6p_'GZnN^zI}B~5kʀ{5ʧL"sOlidhgϖAEmg}mVgh[ ST%^Xtx2}N9w}?eu.G}_veңG w-?4x`ٳVs?c931;t CjZԪ&o;qQ!̟CɊ+!S׭d'GJ'b} p"cBjGi|w¹ώ; "kzEu>DuE |,PPў!nxA1wM~ _4$c0/] qtVT͵4mV㋄yΝ܂VIH#I>֮Qt/6u's[o3suL3Ӳפɼ|¹4q!&i9\rvx(zdZY~f.-[=<2rt:S PRvD7m`9:6>wt{F>?/t K xe|,3Xþ u;Y{Uq OpF֦^uAr$D9%'pHټnnt;;99b xНqe ާc@?Fr3"$#(_nE9TO\o۴^?#jVyI5I&~[vq2k֬Ȅhʯ }[n&y'eԨQq4 &c͟?_>C0aBiӦۖ[n)lw*UF` T-ܿ룝.I'!W{Rp u!ȕW^7ՂATwD#!?kzpiQكEB56;n]}#[4'F57"X+q}%_2:Fѵ2D992#B0/^6t`"IC Ujp.Ұz^sy|݊plDqlg; &?~\d6zZk~*Q]!Nϓ{ٮ޿uoD>9*~&Ei2dbg0_frBK{vhqxXiU}K9KˌvV.mgiK_M`hij-dD\=4E7tQ l['xV@\^-+3FBEbY]gj֝[{zvi4q;#?zsRٴsPr&?gD7۲AaM:q7[r7~/gj>m3g}$ߺ~ow!}u~xtXg''_ }'վI6-gɖaIjиOb_Ҏ/l=WYɭ/ʡzM*}CvߦRo^8㌠ ?ɳxb#Q6]w]?4\qfogJF~I$@$@$@$@$@$@$@$@$@W]uUUV / Y߿{#Φx?vc_rA} +W_ "t?%qDFkM7}-@dVńvN'+̀{ߊ?j8]?wp|*,7>g+kzx(r-|8٩E:j"yY@&˂ _~4hPBrΜ( -[E-XdI$+-9/ g$@$@$@$@$@$@$@$@$@$"P˗K߾}_9p ʆ9mذaQTkoSȭxNK8YU.U7$pY-Qb£i|DEq89b:Bc?"4ڏ=~E=r-d qm;^^LBb4 N/+62NdF㢏yfÞv;dN7~DHi,k&=]sqE 龗*mt6uv<ׄf`T7f,YE\ga;NhcwCɾ/4"sG>zްcs߶% X-۟WbNx} 0= B&,4&>{1.R+=vx93, -|.Cۅ sV`'>v=D?musyS ^VϽ/4]0ޮ]q͏2qHd?ҌiL$P P!ȷ_m't҄il۷ؔw!Bms='?M{7dmZ/U{~M&Mʕ+ ݦ+VȸqCҰaV<a6l#M6z:t|'؂㏏ʈ7ް(2%         DpXzycˆsϭβ: Ȉ!ȕW^.tnbVlE[HI\$ؿH*̰'EM3"XQb]\T\h/MQ&uů3t#9S M8#;'M~BgDɅ03 pQdQC[9FZkxtq;KUmרtZ9بX:"9?sP7٩Y$!^K}}Q_fg) PERA~Bl sswrzHmFٗBҽt}=lf,:-:꼛GI~RleOq |(~1f?k TLgɖaIjиObmҎ/l=WYɭ/ʡzM*}CvߦRcxW^+DQ`?em3zgdĈRFH߮];yGe„ rM7eD[-A$&M~[H^z)WjRC TpC0NvX o_|1c~: \aD+V(f6'DmIvvQgM>qHg ([I} X<n\67ѥiy/kvF8E~\ |1_&|T}5ͰqW[ H:#;W%in" %WS~+rVv-@:>m e^>z5 VD۸>1eH(O~cn\ޑ=]ڟ尗E؅#vsB>jbyz|y eG'm=IyWܟH㖂}_賋D~|֦[&~CIUUZ?OBITsy=5vhWtu~?Q"Bl+F>}qLZLֺNMG+s9n {]2<Ǫp?iV<)$ۓvxռtjT[N}cRn49,$@ 3VDo˘~=ɦ3(m6Oge|]ߔvl~6fڞOn}QՓl&W6pZjҥax뮻f̡{GL~|>ƺꪫ5\G㇭" *\ %/ѿI'=h y3O:$933lV,C v矟a۔+V($6P}Hp-=Gl+6n_V$@?6"3V@bEqv\=lN DPH??p<"QB1,AN؊hL^ %ܿ1*9Eȯ挞G(Ίk:DOtj7Ѻ5$BS#tK >c(w;iD6Ϫ}Ȃ>7Bn!۳;]`:hE,s~쁝E0GY<|@G3ҭNE4Uid{ek-g T1s;?!HIc?ۣ4y%y"w4>g崈hGG {zYBw{jt,\ESv^ڳF Ϸ-&vQ1w疏gF woY_7 ^oО!4a\7> l(C-דlIq}ĺ%!EC1|*k{>E9TO\o۴QG7AWO?lav֭[KHo[۞{)T/e޼y2k,;v%q_* HHHHHHHHHH O%%׿.㎋ͨ"cW'""8iC2t|Vc^TzQ#Lsx޲UQY(_;Ҕ׊1lioNLX'=L@IDATԇu4FN,pbwW^uJۿK~ r}^0m\V8_(:;;7ZU6'!ѱ%=#\ӣE#Gm\\0z(Z|">4q\hۜ[ءLNHti)7욹w%{5!{Xԁb]{,Jx9Ţ߀1Cb8vyrT3 \g>F4Y5}Uԓwޜ,9z_X0S'`^3/sfW7 "E- 9VQeLJ?Cݼ͛4"l>f1plz_2Q.51@b';?쳴j;?pO=ZÉ_9luxqa#Vϸ|n:uGpk-(Ґ[Cs[9~>O/fk߱X8zEb_2 󽬎[lnMزA4lgZoٲӅ\('>!2ϳl l(#G-דlIq}z'abb ijmP=ɦir!ozWREZlOe˖=@/2iڴh֕+ά^zpB(QSI K98 AS?}t9ӊiժzү_TĆ &<̞=;ÿN:r6la+Vd'FI$TTߊG//vyCYzm (|ѩ=W2N8:>ѵy|SyEILT-׍;EFn(vM}ϸ>0=I$GÅ;&Q**wG+p s  )\~Xv~PGcw-be짝T\$WC"j %{:TPs[ mV0ww&;96 Fܷtv'z}=Ԍa`^=ݣFd'3}(?>uD}>c*N^Wwba:!uw;z{uX8P}q؋d9Uhg%9Ͼaɔϲ]+x]6,OMkvŇcM^V,]|p߿/)1`ۍGwD.R0q+Z׆:v- …lE? Fxd˰$[Ryh\'D ijmP=ɦir!ozgYk֬)]w@Jk׮"/]4\6 K1@$@$@$@$@$@$@$@$@$ؘ} ?~\tEhwt?i# E[h̘1Cƌ#Ç/&G_oV޽;L9;=a$@쾕\k7u֎ _L?E>k,3R;i^9%HA*r{Wx&Lvna#k.{}_x߼tXռ^*>3@$<[څszeiQOWOut϶v^c>9Os߃>_\.vQg$,Lsq=76??2#ㅲXn"Ykv6 nA #bMn-.ly]$#P!/[ů'يzqm{27#_ͷz[_C$U|M^{H7nܸܣG؆}ݸ^ K6E$@$@$@$@$@$@$@$@$P ll>"^+S&LY:t0~@8FFEOvW1kW_?->JNȇLs{˜8O?U47'ֱmE{I>q9]vkYobv/)쁾_*klv?a Kyߝ$OY@1ĝqnqmg K|}>KjW~#A0li[n!*3X~X412O$|w|޲u걻ױ10_hm.{w jク'B-n{cgm$@|dڵzJ[ $]M$@$@$@$@$@$@$@$@$)( }=h yǵZP~_PMDC@+Cfpثc ~/B]dUxoQ8?cDYb&<|G_ʻ_/D|E}`7q?_jk#>~@WٻUì'bfh~K_.8k3Q1OV,bss}:wncBh4 8#iQCG׾^.`j ޹E?bf4_{U![Ѷqb}[7rp[Fs+=BwpP?qYcLJ?.ũVzL\CH8}Z2}tnT[f^g 졗Es~EDSsw wrs[Ԫ&qr$=c{۹ hOرw?GgvMc>c(*dv`,|9s<{fu3b^dykVb\m};H 33,Mߧ̓{?&Y'tsT#D r A2yo;[w^ɟ~/_-^/N ~78'ح)۽ xonESv6Pw3$@ 3d˰$[Ryh\'oJ;F6Po\em'(I6O }˽pJ*һwo=zYS7\##Gm;A O~!؇HHHHHHHHH(K}#p̫*kX*U$tPQ*'b 4`2vsiՑ  m>X0 5T(זqO+e_sAVN?ZY_+6?pEboPSr%NsMk\mf (浊/$P$=tܽ>-iU(_џS֡hA .Ăԯ!u։ԏ9 X~hyY^Q~I49cJYvkFó]}OTsѭ7dsƆY6Z~XB~Z(kr}[nҁnnb~~=7{~/=Eq<^ȳ;L$@$gޖʯ'`G d/׺چ^1|*k{>E9TO\o۴^!YFA$@$@$@$@$@$@$@$@$P 5]|{2vX6m̝;W-+WV-iѢ`vAcYveN$@$@$P`E֤~Ďe4y*$@$@$@Xle7 (([-I6 !myZ?'.=6PH;F6Po\em'(I6O })/`Ӆ|hїHHHHHHHHH U~HHH(](N}cRwvQx A<`ѕH` @~ ߊms'tބilBP@!Bms='?M{7dmZpO E_         H&@~2 O ]%_-^ѹEj2>R @9%@~9}x$@%F A2$V!myZ?'.ooijmP=ɦir!o:.%Õ lz(^s^1 4M>>L䝁=e5c $@$@$@%OG&͍.涾ƫ   P!ȷ"z[]dW"m6Ogedž ijmP=ɦir!o:L|P- @2 ٰHHH0/&Αkvji]f56{ i VOId=֑&56/˓# &@~ ߊm/_OK6} cCcd 6[U|rrdS4}ߐݷi&j>](χ}IHHHHHHHHH lB$@$@$@$@$@$@$@$@$@p?CoE ~=ɦCf~O\V!zl(vl~6fڞOn}QՓl&W6S_Dͧ Т/ $p? [HHHHHHHHHH gޖԯ'_l*D Ҏ/l=WYɭ/ʡzM*}Cvߦu tp?Z%         d'a C A2$k>qY象B1|*k{>E9TO\o۴N~5.C$@$@$@sע *("*TҬ,5#+ ffjY+nZYf⛙Zf ( ּyw^k=c= @ |P@ @ @ |/" [/6mB,PQjy0Z՗)}1?/fEJ߇x3~ Leh @ @ @ |6@ @ @(C~ ߋ轭HC?/fcVˢyMf= aZ^.ymeJvϋY~an,G_B-~ZB @ @'p? 5 @ @@_!"zo+ϋXho&DuE cޯe[}b_4}1ױP4A_ @ @ gC  @ @ 2Wۊ4b?ou,d ѳ@F>˜kV_j)M|a|u,2Mu'=z^{% &r[ SO=%K.J5k駟1btСVs_򗿔.]șggh>5K,IyȐ!2p63fȄ d2tPc=Da̘12k,g>#;C:2C @I9\4 @ @  ܯ{|lbVˢyMfo n>˜kV_j)M|a|4Ʀ/_\J7os92hРEZJ.2YhQ*U1>-[&gSq5\#{اB_|;h;u$7pmwlkk[[nI'ϗ|38#%ZѫWvQO>].ڵ\~f\a'ׯ.H^xt|#tP3m!5׵7O[,w%@~"%\7֦gs='Ge:uj0`\qVqAGYOZjԨQve3g|_L{:OL1+4@ @hic @ @@3$pBE֙ r,|Y4Ϸlg:}TˋՅ1ײLsՎy1/R>̍ØXelJᾉ6m<*>J߮Xb#/dKb~}+_>x:kZzurLsy)%?{fmEtPﵿҡCqq ^z%=+Yܮ&Yׯ_#ϟ?_s6-s! @ [Dr @ @f'pBEy i,|Y4Ϸlg:}TˋՅ1ײLsՎy1/R>̍ØXe4p_ǥ;lC4m-e͚5({8ΡkeϿnݺtwjcǎѯ +o|#/%ס""akxbQ1~%!VolrժUQ1u :o:z]tk( /P 滮wE̓EֵEוНu Ի-[8Yflvtͣ _k n:o>t&X\ԾQTkAy9OCgҥiyׇ34/&yW혟"Xzy={vU^x!;Hw(*N4)ey[mV.l2ݘ7)SLn-c:seĈY \Ç˧>) M4;=:S=緾-5sw-ܒPu*ֵ 7 ?xS@Ν;q=uNGҿNҾ~_f/hl3?S Y`A֝>_8> ]7|R_8S7ȯHJcg?rͥلʨsoɒ%rWW̃=8lvo3E}\?+:+ŀ @ 4MAs@ @ @[D[v^rS?3 ]bW29ezNƼov=oSCǘwTm6E cޯe[}b_4}17vh}XSz9Rg#3mL,90}kTV=GޡkEv=תo5.aT$ƽUGU(n=lqV\s1΂QOjk~{ K/C|K_UE_+?y[Ž*W!qx 2$V\8_0 m5:lorPAg?롿uhu˳R_$ꪫRqɓӯX/yΓSנvv֥U-;3}I'bɭޚ$ssڧOLx߯eHzjU't@p3@sO_їDy|t3%s) @ ll76Q @ @T>M{[3B?/fΗE|6!z(GX]~-˔>W혟"X )n/H^J @ Д7%m@ @ f6 M{[3B?/fΗE|6!z(GX]~-˔>W혟"Xd9cZvlzo}/TTw?蠃5nV塌TlZk]<2׿}hMdYe ǍΓ uLvսܬ18yU1~@EK*dTpmQ\x ]\ߍ^ǦA/~tk[U(snΛ x4ׄV+miFnMn洯E\e}BE_C ØvE/_]еgڮ_ןK2~\vZgסYy#,М\Z>˧?W{^_K!C_S>gk,d=bsXc}`_zp?)!@ @ME~S< @ @@k'pBEey1[2|e<&k+:\hbual/S\c~^&sc0f>q*6p_E&VѨX/^\ cp_gELw4iRDnW_}lViĵ^D\ X؎j`Zh /aÆicr?O>Y=؊sc󪬮TqU}Ȝ9s4;sXh5Yf`9szTc`爭9緾l6nekY׺]v>}H=5nck0J!/| inmc}];/(?/}ʿPo班k2x/["ڷ?:w> o/c|[l@ @@S@9 @ @ %@_!"zoR-Xho*oQjy0Z՗)}1?/fEJ߇x3~cWmCCZp}mS^z2~x9r|_J~i(*k[nXE֭7x#}ݗNjK XmakW4}Ov}e˖əg ^& 6jUx/~Q=P W*W!C.Kw>cbw% _BǯkիWK}{sϭ8:E<8O.7|s&ת9A(0ws~Xm=9s7 5kV1&yf9bVol6ng{޿ƍ+,kP8+ϰ,z_k?vp]yk^,_n-]1>lϷ^磮v~gm1[<֗~a̘1sv[a> @ @) oJڜ  @ @hWۺB?/f%ou,d ѳ@F>˜kV_j)M|a|u,2M6p_OOӊT&Vqݷo,WŚKidrWB,!0LXZF[ǎ~9`Cfq ^\jּvZ>G_~(#=<*̍Øjkߜ}FiS /:,]v*wewWU*:ռ/}K;~W;LXZF[z=*42eJ*KdvK/N8AN<4E>رcKILHdsmwwĉ E3ϤicTxٳg^˂ җ#T(޿ q1ǤץYk^Z.ZHT/kUX|駧"m}!BA>}u/\wuiQ]uho=Ocߋm&hsBu}QCs9G9ѵ|7lJ;G,[?6p}];wVG?yM-/H|N_pL0!O4wr[o-3gΔg†gڮ_[:5ۨ3ft}j+?va!õ?xڱ4@ @ؘoL@ @ lWۺDB?/f)ou,d{Z^.ymeJvϋY~an,GU[}S ݻQQU@}Ǿ1U,^0 UګW0Wʞ߄ֹ UT/0Q]z}LCŪ'|r/_<{v|ͩ8Q_;>5oЧ>Omba[/ ?lذt-P]KƌΩ:PgczvUmBg}CU;?e?|@ @$pcҤ/@ @ @`K&pBE%y1[N|e<&Qfn]F>˜kV_j)M|a|u-⍚Bbuby_;[\sU~QG[<\vm Ycc1aUW _}Uߍ||&-WN󺣺FJw9yرc.]G2ǍW!NW5k_Z`^볗 *W"Dx̙3'^  ~-+H_\w /"yDݺNe`|=P*_xq@`pq1\cܹsS 2|K/TƏ5:0 e_DP1 mxU/\|Ţ/\{)gXih~8 t?x9餓Ү]+sOv*v _ݽ^T} -^l5>]Q}mKخ՞L/*WߡC\3 OӋmX^Ʈ7pƩKW/T|k)]u*:ظUĬBduV;T>{T$|tp7!p@u:EPadkIh΋Oz/?RUp\GqQ$Vv\ʱzR^ЯJ#zm74ת {/~!K-Im=`Xw^۷o/W^y/8]w]c U\{(o.cc(C@0qM {eҤIWT0_׿^kr!@ @hc @ @@"pBE9 o,|Y4Ϸlg:}TˋՅ1ײLsՎy1/R>̍ØXe /C0 hݻɓ{쑊MLUlFCw䥗^QF駟Gé!P?]7eԩi'zb2IDATo2ds)!@ @h @ @ &#pBE],|Y4Ϸlg:}TˋՅ1ײLsՎy1/R>̍ØXe /Cy>_RV\F-wmP9T&~я~ @$ŋu]'>-e;OA@ @Z/wn2@ @ @i ܯ{uRB?/f˷:_m2ۄYhbual/S\c~^&sc0f>:j&jg;u$;찃o߾yQAXb̘1C֬Y#~>}J$@ @j@_ @ @@_!"zo+ϋXho&DuE cޯe[}b_4}1ױP4A_ @ @ gC  @ @ 2Wۊ4b?ou,d ѳ@F>˜kV_j)M|a|u,2ME. @ @ |P@ @ @ |/" [/6mB,PQjy0Z՗)}1?/fEJ߇x3~ Leh @ @ @ |6@ @ @(C~ ߋ轭HC?/fcVˢyMf= aZ^.ymeJvϋY~an,G_B-~ZB @ @'p? 5 @ @@_!"zo+ϋXho&DuE cޯe[}b_4}1ױP4A_ @ @ gC  @ @ 2Wۊ4b?ou,d ѳ@F>˜kV_j)M|a|u,2ME. @ @ |P@ @ @ |/" [/6mB,PQjy0Z՗)}1?/fEJ߇x3~ Leh @ @ @ |6@ : 444ylrwk޽fXիq[ }m-;ub @@q+^Dmy1˷:_m2ۄYhbual/S\c~^&sc0f>:j&" @ @@>l @uXj\RerGc_ir?+VQ>$;0`@ @ ܯ{h ~,|Y4Ϸlg:}TˋՅ1ײLsՎy1/R>̍ØXe /C\@ @ @糡 I@)O<97fϞ#Ytk]lq1@ @8|/ [/6mB,PQjy0Z՗)}1?/fEJ߇x3 ۷o|,\P/_^Dz۴MoZ@ @ l9o9s͕B @ @`S@_!"zo+ϋTΗE|6!z(GX]~-˔>W혟"X<"ݻwQFҦ^ŋ婧~X8if fϩ!@ @ VE~ۻwVu]\  @#PM~zYnk̙3W.Y*˒tAz![oG':OKoΓ˪UEi۶3JJL644͙,xmY䫪m۶ҭ[WYvs?Ғf8 @/|/N`lcVˢyMf= aZ^.ymeJvϋY~an,oqOF [2e\}չMYp)is.@ @ @5@ߚgk @ Fp_E׬_Ǝ3fDd=N;({_*W_>'2M-Z%2d`k=d=msL~F&M"N=kCwM^lLR @@&pBEI Mx,|Y4Ϸlg:}TˋՅ1ײLsՎy1/R>̍Ø-JaGGyDT,W혟"X̍Ø-B<ϗ~5oqoP,0@ @ @5@fk @ Oooq~dS_fa@^Nf!}INZJySM/9qrAqGtv| ;MDyd uu ]u==K䩱O89ro{9XvKDno>vCӦ=C֮]p̤ @ fB~ ߋ轭y1Xho&DuE cޯe[}b_4}1[pĈ?O.)Q,!@ @ :[ݔrA  ZZ|rRɟ<>wHK{\ju"_(<'Q.^.͗ !iץKgy%? .w`QCw޽{I۶*1y2cL/w+T  @- A{['5bbVˢyMf= aZ^.ymeJvϋY~an,orG( @ @ZnJ @j^&[I'';vLD숿jժTt?n[+ ?y2~yqdYȿn]tQ&wM^|%y>孷ȑG&CwU#ڽ#WAϐ?dUc":P @ 4'+^DmϋΗE|6!z(GX]~-˔>W혟"X<"GyuQ%UM?d9cdرFo_M}  @ @ E@EL3 @#'oEg9GIݥk׮i˗sdG}Btc?1,?>t7ٶ6n]6r˟nO#!}W혟"X<"{y5w\_|gϞ`ĈinH>LVߔ͹ @ @ L~k]  pd|=&LxWիg;$>7[Ɏ/̜Fb/[>p{Ew_Wۮ:;w|cg#@ fN~ ߋ轭y1Xho&DuE cޯe[}b_4}1[pW^r%T]RSNM>gi׮]t+WbnISOIwf+ @@%pBE -Xho&DuE cޯe[}b_4}1pSN9ET|o}+AKK@-ZTND @ @ @< @r 8~E]w#'$OΆw֭5k/˳7ޘͻRAȮ}3N/LyyΜ7]۶CwIw?kGa/ّg'&?K'_W>*'z}'dA[Dq @hW:U˷:_m2ۄYhbual/S\c~^&sc0f~h_xǘ1cDvt!UKwկ~%ZM^p# @ @B2\& @/|{ lU~}~C"_h,xmY|\*(+׷K=zt޽{e/^Dd;}!ͻHΝgyEիW'*w%;o}/I,K~lwҹKgyyXC@6p @ @@_!"zo<~^̍ØJ_MӴi+l6|?F @ @ Pq @ @ A{[~^ΗE|6!z(GX]~-˔>W혟"XW혟"X̍ØM.g}N˄~<r9ȀeDz1)ŀ @ @ ( @ @2+^Dmy1c˷:_m2ۄYhbual/S\c~^&sc0f~ ? 1cd/}I ."׋AN)A @ @h4FH @ @R+^DmeykN2֯jjRʢ}TˋՅ1ײLsՎy1/R>̍ØM*o׮\zҩSl)444 {Zh_/~6 @ @E~ @ @@F~ ߋ轭B?/flcVˢyMf= aZ^.ymeJvϋY~an,oRᾮ;NGGkE"܏N5A@ @ @ / @ @W.b9ou,d ѳ@F>˜kV_j)M|a&wA:,2dHi}@ӌ@ @ @nFGC@ @ @W,b7ou,d ѳ@F>˜kV_j)M|a&رy晙x___2w:Mnpy @ @Z-g) @ @ м ܯ{uC?/f˷:_m2ۄYhbual/S\c~^&sc0ff4hC&N( nU%V5\  @ @  ߌ95 @ @ Ъ ܯ{uC?/f#ou,d{Z^.ymeJvϋY~an,߬.~K%@ @ -QfYYv]M 1i۶o.Aڴ_Ԟg]g劕~zҥk.mU{4d@ @ @- A{[7bbVˢyMfrdhbual/S\c~^&sc0f> ߸<  @ @r $ᾊˬYdګept:u([o ~{̍ØXe /C\@ @ @Zp/w+m?b?f~V}ҋ[|̙3W&%gƍ>rd'5*sҹsgYn}H^V @ @@'ВOp$:j&M-_n̝;WX:ݻvmTf-![o[n%g-vXc@`cX~\s52aI^Z. .޽{ʕ+eԨQ2z荍 @ @@ =PQnUWN8С}3T\Iwܿ?' w_f,]T&N|Qq.;i߾,Y4ݩ?!,;Kp|s,g`a2['ZZ"flNec ؚad=['cx2![+ ~H`K[+mڨhiyJgYg]G(R혟j)s0})}jvX:ƼZoS4Ϸآ}TˋՅ1ײLsՎy1/R>̍Ø%iX"̝ǎC=TN>dѝ[ñj*g?+zvl6rUW gЈPnl˖-Kݚd3=*o ,c1uToGN3 @ 4-I?n;e]l-5KRxD)0\;W$,̛7_'C"f~>׬՝_O7i;=^\'NݬB7x(rhڵk:d/&iGΖE@okEM;vL-W[>u3E_T@ZZp@-Pgx Z?WڵkwV>[.-z赶Ε\+^Dmϋb[/6mB,PQjy0Z՗)}1?/fEJ߇x3~ LO4IJ`?okٕ^w>' ..qrWC&<3F[7*?@ @6$ŗoC+{gl|_S49̙婯 Ɏ 'x'6D?i/[a]ET6ٕogNJ+g߽ +,boIB˗/OǪ/%x1*nҵ"]+9b)]':u wNԵIT##AYC:뤵{Y;wzy81|/`lcVˢyMfxG>˜kV_j)M|a|]5oj9ss-,ڷ^x2l0s[l___|q{= @B @ z $k͐OCߕoĈdd}=Kyz|Zロ/_߿K.W xq{erԨI׮]ek&w)tjDEKE7їT߭[V/DƌTkE^W%KCVt1)]'ZZADi`ْGxH-Mwq@ e7џqp@- A{['5bbVˢyMfon>˜kV_j)M|a|4Ʀ.27n\.GNN_r]wUƌ*>3j@VL1&"p[@ @ P@K/X y},9c c~*/Y*Zv2paORN2U}SvulM\"o@ )O=VϕyɊKf}3bKc)sE }D:1jxTCb$(kC,#|/NYlzcVˢyMf LI@IDAT}{Q@*PHbQ[,(b%"*%Q,K5F${M,ADTP@.]3xֹ{6}s̙3ϙܽn"Od"4Y m[ȾrNu۵]F}4lqdu1VQ(_5odС_ 99C ӧOÇk_+GgEN:ai޼j6,/A_͚5zen[ׯw}g:tBW_}%+W4cA'iSF|Xl1[haXB/_Xl2.W<'ou֙ぶ!կ__ڷo}1uﻺu=ܓހ/]1~]֌ycE׭[gc6lȟ~\|F_￿xq D"@ D"@BA)0k֬?D&Nl =R {=ˎ; =S2a$9lAoǾC\x<Ȓ(?cgn_++0&»F}T`4U[!;`Miܸτ:"`~<0|pmɇ)\[  ,LD >/'C=  &ω|YYr9d_9IO}%5m;WgU.&:cRWgjg`yg#4Y m[ȾrNJwm}zWe)\9BeO:$ _4iRf0 1BL]s5һw︬G &*;w,rlN'lɐ,{w}Wd=ztmӦr-ylW^-sĘ7Nƌc^7pt#<"O=T:7?1^n/˘MI 1?rL#/ׂ sD @~&2"햓t:+|ZgY6 xyS>\]Nܶ+'>K{֧wuZ&q6}eu]x>6w믿.FJѷ A?DO-Hݺui.r裏bG-4ez衸K/8zAxC>Γ]wݵL~H deT1`C&H vcVzZz!9d{^ 6Hivܹs/؁rg1M:U.2O\U;6|\' O}߉ c>%l}>*=XZ${ Ƽ=H܏@ D"@ D@)!ҠQ_Y!R1\[cBYeReP􅸶tyK:|tH!$z[|pI:;>{vvXy)k|u.Z_HnBtj%Wkӻ:-_YҾ28 eH $bwm2gIǏ/_}Ru=NIlBsF_ ORjA,keĉ6a%rfJi߾1I#ϛ7Ϝޮ̀&qtWH>}bs2cƌXEp ';`!D :4;>D$_q%>/~ꩧҥKc {>/2؟Hf^x!nΩ"AH+z/6m`#Jք`ao@iD~ў"@ D"@*Hܯ*_DXfKks ;ɵU[I/~\[Ǯ6R]_>jSk>/צhsDt q?omvI: >{vvXE Ygsuv9MBrS,][ijFI!D)SqDGV[meNI O>Y@r^h.[̜kuKhVC{K׮]eѢEұcGg}䭷2onN(9\mze)q$ &hsc,x'ȩflJ@gjѢ|r5ğF.]ȑ#cIꫯFU@ǦZ>sbnNP#$_(s̑>[39bΜ9SnF*;a<{6*O.&k:u2_ih۶SO=eW {yFӴiSCnǜW^yef|o߾=T\uU{6V_Ϟk'ptchy绷{aNb-رc瞋@l/4߆!-x7>T q_`N D"@ DEDDbG$0}"6̸ɵE$|<BJK#N!x@HC ܝLH˧׾暶*mnH1)嫳dFm\,JG>;_i۶}$gɕ|N$5U7L>𑳓~9 ^m|MC2wuW>AdKhC<߲eK:/x|wJvb+eM}{<@mn_~\W6޽{"=ڬXB CQm1_W ANG kBgqF%.^œ:j*6@DxOQKG;lK н;r 7@/կL=~=4_#XcCF ̏Gu`Ç&ܓ .(7n8˨Q.#€OnM` _HPCֹ+͚5Sscs΍u|!;=} D"@ D"@@HR46B"Bx1 #CJ>\f\B"?\[Qrm ! rQD!@~&2`tI:guvn 7e#4Y m[ȾrNJwm}zWe;kSW6q={!@CvۙS6ln5]tE;k1g̘!d]B37ttM.3\M^FlbA^&%8_K@5ս_9p~dFL֯F _ל/F\zҿc1=:n>٨+#x`N诉}E9 D"@ D"$^D0W$׆|"6ז#\[ˆC)xA~)D) I#D5D6ޖaᖓtڛ^<&1&cs|v:Wgd/$m!I:ϒ+޵]INŊSVqނ|oȿoSбcGs7h{G}ٳlf.VFNbݏKh0esA$ӧõʐN.a&.;V~a5O )='&t'tR\DXG;=oT(_|g^>x\gC?G-w<0_ۻwo֭["w/aNe.6 Ag ؐ$Wpow {?.< D"@ D"@@`X@"wHD/&!zD~Q 'kÌKh^\ZDkK1 C-!D4| q4|^! 4H!$z[n9Iγmb}չ:&k}!m WNҩ}\OL~ygmJ"n;|:u4zˮe=#FH&Tt"#G:u0=Uw]2+.99q9{gC)4)ۧKvIn_umw!۷w/kড়rJ%:4;Aqgwˮ;x@ƍ' 쳏7lȔo{sϕvۭ na`_ԿK|=L'n{챇:緿m\7VP D"@ D"@@ H ,7HDаAZ\녅<pmbPPHAX# D9|Doˈ[Ni}ZgY6DXQ|v:Wgd/$m!I:ϒ+޵]I/bҤ:xhxG_WNs}d<^zu]gN/vm{ }W^GܿK̩:{} /hUnӦM3"6h9 D"@ D"@BAP"$"dHOƆ5\K~HBm2\[apm J q??>>/%"@EBMe-'4>{vvXV"z(BG>;_i۶}$gɕ|N$1Q iR}½nݺ,vR‰민J\ݯ_?=}\~ҵkל㆖ТE %4#[]_@>Cw=i@|5jle._\p]|! "8r=餓rNW[OWK0`\p/E`^j:䘷͓>|Yb„ 1vnuսp{Ng;{l9slsԩ &4jHڴic6꫱}-G/6"@ D"@ DT$W)$! VHDȊɵYv$3z-ŠVpm}1/v$\ks"$m-#n9Iguvnl$UG>;_i۶}$gɕ|N$NT&q駟1c}2p Gkdذa}-[oםq,.g\BsV>O>dYtL.]Wu]eo߾qYpl_uCW|'x"&}7i\"@ pfm]c>#iӉQn=zmVF 2eJ=b;Çˌ3buEcwL"@ D"@ DrX IDPk`$VҐH$`kX$ְVpT5\[j@h$W52|^A@-@BMeY:;jge%NJ"}չ:&k}!m WNҩ}\OL~&IwI CXޡC2. rY:lqǙ/,wyg\2$9s_WYzYFvi's:>}}GX&%ab`g{wwߕ뮻.֩ RNwg<̃ 46Y v&O,W^yM oٌѼyskgu9^u[n\{f ,Xf` s矏U.q첋wy9~W@7fLTpǗ~bvATG?4kLw2}h[_{/a]ҳgϜ~kܸq:©~U /D8WR D"@ D"@@5"@~5pi:s`!$U1$PPȈז@r3-|0| yO$m-#n9Ikg2MYgsuv9MBrS,][iڔ617ŴjAܵHGuVZ >)x!aJp7{:t۷.HufH U4s5x/KhV|:nd-}'C=To?=2 >9'tn>n&޽v޼y/_~?'N4z^(%\"͒%Ko \>}]/~ 90z!Cr0~xy衇n}k/;w.,&cLO> %6`&x74h/w} jߜ/1L:ՌK ;lT t֯_&& WΝc|Af〻X D"@ D"@@#@~r$"d&k@,ډɵ3B=΁,pmɂmYrVhG@u"@~!&2B䖓tNyV;M,<^ޔ|v:Wgd/$m!I:ϒ+޵]I/Mi_}\| M w5=s2zh-I.>H^x|gek|}Ts9mXp ۸ c,v.SHr 1?^{̗͋_]F':i ka׻]vf.|tMM`2b&;]s5lOvm {vvX Wr-d_9IYr%߻>2OT6qDdA͚t"7px'xBpzZYk={Ʀ TpfI-[4D>Ǝ+?pܽK\FH{:y{f޽{T[ΐ`ܢE CoڴiN(d1cƔC _~<3obq?#_8/./1|p1cFbs|I7^}lIK.5|/8?}?v;W^UW$ _%cUɳ>+{$C96u۶m+ ,վƿ{/hG$+̉ D"@ D q?^LBO$׆м"6זc\[BBi@~i)/B iCȷI rN!kg2MYgsuv9MBrS,][iڔY )ݤVO8Q~/mA&:tn9' @a|̙n!u4H8iܸqN=guVL$ޞ)GN;|2W>h8por-.ݴb y_vLy}\KO+&l68#=3/8I~`Sqy>}d=0:˃/ǝw%c^zꩲ.CʑAGѣDX81'p<ٗ&Ol難X9/n|K29yXiΜ9f{?0ˡZfȭZ&n[n{2uԜ!$F=zȰa̼O?蠃S7"@ D"@ D H&#$"PPȃyaU$B$&Cu"\[a y q?/<E"@EBMe-'4>{vvX+LB>\]Nܶ+'>K{֧wuZ&q?,ި!ijf͒ŋ 삘ݽ{w/YrywqwGh:<@w[˒G.\Ln'u(#nnJDEYgsuv9MBrS,][i"&j!M_op?Nה%{̜jv 0zծ|R>"@ D"@ DaD I .$׺CZ*CkK>tXpmQ$!@~BWH0'D dH!$z[FrN:;jge%NJ"}չ:&k}!m WNҩ}\OL~&$Vʹ巿mt" 2|Oʌ3rl?p9#stZ qT#G D"@ D"$xC"Bx1 #CJ>\f\B"?\[Qrm ! rQD!@~!&2`tI:guvnJDEYgsuv9MBrS,][i"&j!MH/i b7,ovvQF%&diӦɥ^ˉ')"@ D"@ D,!j.ի_zIzK$זbԪg-Ջ\kKD$qcP*yT"E?@FBMeL :;jge%NJ"}չ:&k}!m WNҩ}\OL~&$V͵ygy&u{キ!7h նT fϞ-sN~'C  D"@ D"@@HςRڐPxH/U$V=xEkK1j3זſTεT"U~_1(\*Dv#@~!&2&[NkgIJcEB>\]Nܶ+'>K{֧wuZ&qZH A._ܜ?a7otEf̘!:t.[@YFnݺ5k52X D"@ D"@EC"Bx1 #CJ>\f\B"?\[Qrm ! rQD!@~!&2`tI:guvnJDEYgsuv9MBrS,][i"&j!MH/-"@ D"@ D"@ q?!/뒸_ZNoINK$זNBkK(-a'$H)aC؈9|Do-'6:;k畕(2k|u.Z_HnBtj%Wkӻ:-2)[M~yd{"@ D"@ D"@FHo&^LBO$׆м"6זc\[BBi@~i)/B iCȷI rN!kgIJcEB>\]Nܶ+'>K{֧wuZ&qZH AD"@ D"@ DdHOƦjHD.K$V[kҹ6ɵP<J$kK ;CFؾy9;"@6"@~!&2rI}ye%5JG>;_i۶}$gɕ|N$LV_^ٞ"@ D"@ D"Û $"="q?Ĩɵa%4H -"õ%!זP>_q K>/@@$m-FS}ZgY6DXQ|v:Wgd/$m!I:ϒ+޵]I/bҤU!Ж"@ D"@ D"PnݺR.E+JqwJ"B p tCrm-r urm)Z،Z""c3"@s6ޖγmbY豢!k|u.Z_HnBtj%Wkӻ:-_D- E["@ D"@ D"@jE'q?A"Bx1 #CJ>\f\B"?\[Qrm ! rQD!@~!&2`tI:guvnJDEYgsuv9MBrS,][i$חvŋe͚5ELkRYL D"@ D"@Hܯ]D|N q_`ɵi\yP(\[ Evsmq/f$Zlw$m-#n9ISguvnJDEYgsuv9MBrS,][i9X~ {!ᄏtAԩc^,X@Ə//_iVMHܯZy5"@ D"@ D"@j.$[‹IbT0W$׆~BkKQ( H/8%C} D s6ޖ[N)>{vvXV"z(BG>;_i۶}$gɕ|NA[l){lVhܹsmB q?("@ D"@ D"@j$E‹IbT0W$׆~BkKQ( H/8%C} D s6ޖ[N)>{vvXV"z(BG>;_i۶}$gɕ|Nq+]vMBK.믿^V^j[]$W. D"@ D"@ 5 Ë($DH1*aDrmq +kCHpm ?F!xȵ%($FB!D>"9|Doˀ-'ryV;M,+=V!d#4Y m[ȾrNJwm}zW/<}&N(<@f6$q D"@ D"@^dID/&!zD~Q 'kÌKh^\ZDkK1 C-!D4| q4|^! 4H!$z[n9IγmbY豢!k|u.Z_HnBtj%Wkӻ:-E܏aÆM#FȒ%K jSU$WҼ D"@ D"@ 5Ë0$DH1*aDrmq +kCHpm ?F!xȵ%($FB!D>"9|Doˀ-'ryV;M,+=V!d#4Y m[ȾrNJwm}zW堈۷wO[>ÂUEe^"@ D"@ DڀEDbG$0}"6̸ɵE$|<BJK#N!x@HCBMe薓t ^<&+Wr-d_9IYr%߻>rP}I'Ty'W^)]U4 q*P5 D"@ D"@ ^ID/&!zD~Q 'kÌKh^\ZDkK1 C-!D4| q4|^! 4H!$z[n9IγmbY豢!k|u.Z_HnBtj%Wkӻ:-EڵO1cȄ  nW Hܯ y "@ D"@ D"@j$e‹IbT0W$׆~BkKQ( H/8%C} D s6ޖ[N)>{vvXV"z(BG>;_i۶}$gɕ|NAի'7tԭ kF,XAZ_`RD"@ D"@ DhH/$"="q?Ĩɵa%4H -"õ%!זP>_q K>/@@$m-FS}ZgY6DXQ|v:Wgd/$m!I:ϒ+޵]"cΜzꩲf>-Z\7 5$qPhO D"@ D"@#@ԒPεI/XU$VwJ$זFBkKH-&4H-"pcCψs6 ٖ[N)>{vvXV"z(BG>;_i۶}$gɕ|N۶m+_|4l0u mSmˀB%D"@ D"@ D!@~x%!!F%LH 3.yErmh -(҈S^y9("@ q?om0$B:;jge%NJ"}չ:&k}!m WNҩ}\OqfrQGI:p39=2nܸdjH t"@ D"@ DᅑDbG$0}"6̸ɵE$|<BJK#N!x@HCBMe薓t ^<&+Wr-d_9IYr%߻>rPK^ 7c=V:tPf*-_\.}3gʗ_~)8?D~h?D"@ D"@ D*$9‹IbT0W$׆~BkKQ( H/8%C} D s6ٖ[N)>{vvXV"z(BG>;_i۶}$gɕ|NA[h!Æ Ν;ifyꩧ7ߔ=zH.] 2{l1cl62h iڴid뮻dELkB~a˞ D"@ D"@]^ID/&!zD~Q 'kÌKh^\ZDkK1 C-!D4| q4|^! 4H!$z[n9IγmbY豢!k|u.Z_HnBtj%Wkӻ:-W;q>[pھ@O YmݥgϞXBn$ D"@ D"@ D q(* oJHM#~YM^Ҩ~iXaX/@rmMpŏ-{\[8"@~Vhe"@Js6ޖJӰγmbY豢!k|u.Z_HnBtj%Wkӻ:-W;qo˟'e5hIܯyI"@ D"@ D"@j$$V‹IbTk/3NuJͥCͤuva_B^\[B ՚kskK i JuRHH!$z[FrN^<&+Wr-d_9IYr%߻>r7n,W]u4lXq'Ka,\)XMHܯxL+˘1cdΜ9r '[lQݲjD`ҥOs?,ѣ]zɂ1m6Ү]y{|eCtwJ&MSN1yЯJW^WE=W;ԷFgT"@ D"@@-AM"Bx1 #CJ>r6kdWd܉f [DҼqKi7j) 5:ZB h jhV.\[*ߚ;5);>/W.ABMe햓tyV;M,W;2k|u.Z_HnBtj%Wkӻ:-W+qvc=6D%7N}ي\T&q2j(IᬳΒnݺy}Cu]'˖-3޽{{jrԩre!^2lذ47?P.x\5?RnisϕٳgE]$;s<.ZJN:$)ʻ[Zn:{L}QcWJx:ԲeK{N\)Okd>W-B D"@ DEDAxݬY ='ң @~yЫ]mk vr2a֛!zߴAsYaԯ@Wh="0cXz)kKm[UkKU#^#qtcW՞_ՈzD9|Doˀ-'4 >{vvXy)k|u.Z_HnBtj%Wkӻ:-W+q=ܳL)S=SF_$+cW^a~7K/myga=h J=+(СCe͚5fMkժUj_u ˶nڦ* [nE}9#ȹ,_|tEFY.r&}@IDAT:X{$I>9# O`ST>}2zA3"@ D"@ !@~axU5Ur_ҏaUk^Z/+s}!s̊No%,])_]7D2ҷmA:,:}at>~eJC4X"PSw\,W,\[*Ϛ59;6>/W,ABMet(yV;M,+=V!d#4Y m[ȾrNJwm}zWj%gE+V'Wt߅W}%PO ,xZs%D)c+Y1uѢEvw%_W>d]w+U]6CIǎn+ח4O>D4h ]v@\ qė >#]u n~{kw|kd _J@^ s6%t&D"@ D(E>k?׭7_DE֯_/ z/?rgX&gͷQ ;uF7#֭3vkmW/^{<2A%qĺ#)_/N۟&_Z,k+\RTZ(3}*iְtlIR5jn7{yIѭՔraEy$!zEˊs"@BFBMe-'4>{vvXN~ Ygsuv9MBrS,][iZ8m۶l Uu$c=&g#T^Z?5o޼h2 y4li=giӦnժUFlҤIѾj_QF>|r|MxyX;`5UTU2Kv icbӞ8_~v9rU?faoݳ9s IYsG{@YN=aNO2>Bk =X+$|ZVh8G|5* sr95֛{Guv_is5 Fckg= D"@ D6Dǻ̙#3f~"D.]fШQCi׮t9:ܦKyx72c,ijj7۴i-[o+:Py2,2o|?QlB:m1^wիGM* 05bIfͪ n \M!.1^YnV7T:4,"o}#+Y!+]!̟jJiݤ9ct~kXd+v8$V,ԆXUT'umK+^-}^CȷI 8rNkgIJcEB>\]Nܶ+'>K{֧wuZV__.rs96|pC gSuUMܯzt|iӧS&Uqz{?<ڍi>>hQ\ GڜL}¬VGx2jԨ/~_i3:^{L81ǃ'l~[eM7G)c9F>2s/[L_sc5IJzݏ?8ufm&]w]O!׹{g^7cݻqO1<\6?CrBC?QD?|3'Lrs#0c}o<ԔA,y= /BtTGC1N3Ds=Wvm7CY\tE;6K tMҭ[7S(gq-N"OK O)_c'Jk 2$k# [6dl&裏 99 {sGR=!sMz2k\\%\Sǚ%_twq 49BOƏ+SXd{{sQsIN9%ؠ0uTsR{AX?cNdWF k޽7߼tܓIQ?cfXGvm=O3˚>l곮1OR_8)w ID7cnuȵa"@ D"@jD_gL>b̞=[ݦtHH_}T>H$"w[DnQl6i y N_plEԜoKi۷INpC&WOא-ļ Y(ur-6W߰^.B^4Xv4oRٸJqYn ߬]-KW/%E'/uIs- Qڌyɵ"PkK}qpm)؊pc+"@sNtiџU "sȾr.^JˣKkv.\Ln'u(#Ǥnnq(!k|u.Z_HnBtj%Wkӻ:-׍1>[E[W s[ '?lJWtD.$[%P Di$wuW&$`q5lv 8>^I~@h̛:Kv}wW^1'S>)hDo$SA " 4Hld)DscMm2_~e3Dz|8A[o1g6@Z8)+0nA"6vToao/D 3v套^C܊yX|q'c>xu!(nk֬1c8#S4?76:|{x7onD_|ѐ}?R~33QuXȌS1nF{ lz$y#81|Wm=ϨB~>}_c40W#p|%Ɏ5 K 8 l|cN&X?0gpb1fi_|`cN6xQ{SsL7qKX|\}k7ѩvWe6 D}\SO塇2k m_e_=l0Fl/)@9ݸaÎ;h-0yd5"6Ƴ:wM.ot@y 3W^3jˈ>RQ5aHD,dkVxWF~͊ieɵ vYL4N߹Ҵai /\,^PV~BZ6i--7nPmPYL$זLqז`pmᑸ_`\@a"qX$z[[Nio>{vvXw>\]Nܶ+'>K{֧wuZVСC 4E$Tnz+_7UE)8yd, &0GOтhng!+q&sj_ e4]vŐ'9%=TS;n8C +Y tf;ل[OCOHz$& oqZ6 Ճl@fy„ l( jR4t)ZoGOT|MUr+b8rXکD%< xo喆Ȍ% b>aďL;W7bƯs7ӈ lNO{a5{L==ڨx6>CgoA7_ݍ #vOnذ$޼kz:{I@0?x2cQcE&mfظ8BusӾIɞ/w5טSZosʳ:5{Ǯ룍 #iM! c†>̐k)`[۴=s"@ D"@}qF9G;S۶mcz׆xO  Sɋ/*w}Vwh/Zc~#>TthN>jg^ ): 9I=Doبt qDJ\vZb[6G,<"޷:,'I߬::uj9]gfWmMhCVD> --AkK16$θ3j>/"PCȷI$guvn?UcUB>\]Nܶ+'>K{֧wuZV~׮] oB9(m)6-p{<4`^H(dI |$u)8aD[ "uRR>q24N޽a &Ⱥ k#a,8QDMJtֱFDON;4sMI(9Nbntֹc[e,;qݗ>5\c&Fk[q?i.i6d^{tS_qcF!I}7;~>G|u_\:<19~ᆠk:ꇛϾCOhO˘1crv8Qz)BcGl1' WЏ{O |k+i~ƌrEԏ:l2 i'h`_Ǯwe~x9b;l|M pc|H  /344_D"@ D"Pk(% FKۼST=&Mg}Qvq9q?mڧ--KNٺn:xW2әސM7hNܟ?s׮gp<+m۴66mbɽ+BI"B&$ 9dĺߤvZv72}TYKEMJv[J 5뿕E+Kd՚)Noְ4m3שSWl}kW"vŻ"F[kKE`>ڒ-6"m+3x>/s"P CȷIP$guvnJDEYgsuv9MBrS,][iZ#'|p|Bs&K/$cǎUg$!2D~_oHJiROZVaG&z/b,:5Nڵ k(![Om6 .38C@?A@T֓5qGXkjʽDNSN9S)N;yj6IxRɭI$bb}ƊMB}4h <8u|wk-2_O6vQk"wZR\qs\}M4qF1k$5Sg|K56 N ۗ1vb߾}}|xz-{~ڶڗ}־}Nv,?_:*ŕ{u+| Яh;>ڲ"@ D"@jDޕws#C$a;'{Rcsb~HĪUeϢd֬ٲ]?7׼y}lYxN6meznM;v\PQDBfC~͎oEɵ_Y-/ #}&m;JI?|֬[#˿YfNߟ#Iͤ}{{lh$BSHjKrmF.]WR]ђ_jW[>/׮xsDT q?omuI: >{vvXNgWƦB>\]Nܶ+'>K{֧wuZv>fH8<;Q'y mtWʍ7ޘsZmS}@>_}Usr6N;m۶O n6mژSA661mg裏C=Td}G񵍏H"Sk[чqB>ƈyM ' mΝLn__7kvB?:%>ƣk>lhndE  qW^)Cٳ*ixfŎ_c# c&{5Zu<7*whoo#7Y}%i3С]&RK-MyһV}^ 4.$Kq |Q_c">Qs_\AD|! Uz*ՋGۭ]ӎ4:%S7|A]v9}u_GM̆VHmuvҰ^BŦ"q'1W{ ȇ@-ƺCkKaY{b"I`Ԗe]B oω<YY$H-lj]٭C %|uvvvXU7k|u.Z_HnBtj%Wkӻ:-A܏gQ .]*Æ 3qV%gz N0`\xᅶǏ/_!L^Ɗܹs?OJf9Iɢ>bAQN3/F}.zG25k"G)Mɕ#zm]}f#>i[c|bc}8%O7l{!g}+8~}G)S=Vss_,aSu|Egyd`H3X#'Ʈwewh7[MK.1e_A\eKq=M.vZ3tyij_3_￿g?C|y1>h?v[k6Sbrڷ%põQO˘1c%%$[ D"@ Dv!PJ}ǤdaD1 /‰=ψ}+@= eeE֭[Sf3{n~{;>gg>wp/Nk]wu=H # .wY:u 6Q}r-`8zh v ȭ8_Jl\ǦK?3}͙{ͯk=V3-buŌڴiq~l.w)۾LC^{e6݀}ƖZ#@zoڱ<&S!`k?bh{o„ f?y}K}@R1&KHe޼yrg>X=X#/s9lڰx_~[|>h7v,tغ9by'%k/]qҧ.2ׯ^ذ}FlnWXVS&D"@ DZ@)'L$?>֜p_}eY|#E._B&||1{vb,Y!?s;ŋCX6 KMG :ԾD}HJ/5mѦb|\aiӦ$W 5\<)5"oWȒU /'Sw첓9q?kqmt>N׮E߮f[o!u~ͯk=mi|2}n0DW%6hпv.>= ?&Ol0;];|:9)QDq 'H;V>CmDn-&z:.x!Aǘ8dbԁ|%pM7'|!C<sM6f.bs}g1v[#'K3я h#{!XqR8.+bRk81ƞZ#:؎X'18tkۗAwټ/'MdݣG袋̽1gIx]1&Kae8sIl*Bc ?ݸmִGA}ZE95} T3i|%k7`XN9唈 Čs%]xo4ö7h}`oCbȜ"@ D"@j&xOdH|COmstGz/O˔>aw3tؼ<ڼ`BiԸn*zRAI3At$;8:a,0]Mo$7b#SO?xc9ʕ+!,x@~Z:» {k\AD|}%̓R#__>Gf/ mپҺi߆|dխ]V--͑y;L6;HMaRn =?ir-ŗDf]kK͈@ikKi)/($!$d'D $H!$z[FrN:;jge˛Wr-d_9IYr%߻>2坵) ndJ\rM6v;R~Kt%sj[LQ?4! bnM 6lyQo~٤j k$j@$9x`5-~eTqG? v`#}ֹyu)|J ^F D"@ D#PJYwO uhG٦V&F -wOx6[ˏի@O鿽l]P,z6wqSo˦;/3gΊxKve'q>鵉;_i۶}$gɕ|N$5U7 > ƺWRI6V4[o5>M:iY Μ93|]w5/|n'<̯̀kݖ[n)C5sNI-Z| MYge8' $Sqr3 jf~Xz)UDO?]b=7neA' ;a^%.M pay7"B {tnݺ&qM|%7ވ)'g@8(q?L)HrK /P ! 7'?hm%~rGڐ_x <]t1Tbp֣O05ب%'k~=]Ƃ6AںSⱩ1JG{y3D{ 6^#O:ׯߤOAX}Y] Z]=E?3?|.\8'J@oWbˎxPBA~ ,;tsXetBTnx} .B?KBxt"#w(3v'ĵITkK0Ppm!ʱcb ĉ\˫4dTu˾z18ݧ֥O۸ק[mk){paG8SSlTc6ս|2ަ{=}q*9LF'ҋE|Cy+,&C oX' "xf |XCG?9a0>}K_ӵ7n ̂m6scYi=?<uqQszo༛~9OUr?cT?*Pjf<ǹ~zǽ .ϕSgǐm?s5<1(A@@@@@ƓۂHO!iϟt*ҥ ?+좳~>}^yb;;&|zU,15D|^ =s"?wV,TNW]7n}8L6MD;kyy~@0(A]ŵ߻-#̩ϊS>]d<9H<}mVݠJ,tm˖~J5mS'mJ)cM~'1Q%ᾟB` W$ٟx//UY8 ݃Awe3 /yo_x?t=Glo?SơA@@@@@@ r$翛ѣtOyr"7CN.WA{}#V«/;sQH?;wBvǹghqqT*;PtC|tD1!Oc?b+A} D .fIV޾Sztn7XjmNyjο҉4M s4'GqmT3ܸxm זͽ3p/ɍgQ"~ _ѫ6T{dMM-m}\[ ]GmLmOeReTxRX_:}LT?@d~駎PXRXYYB@W\.GLGGC[='WU{#E//A=3xwu}[E_: ptT=!܏JgŵFwmu^_x&xbP?ؽG?#Z*8fc?jO-`ז`GG1kpQApCUu/L)^mkK!ð[M^lSl^>oSJk>YpgB[oENj_M_uW[}^} @+a, +՝g~g~gT7lp-!% p'ӏv[jxܡ ̜q m,ny*25uj*m:Y˖~J5mS'mJ)cM~'1QZ>|H%$3x-YlF  0dVxJ~q̙Pb=K IG~1EQ\{_o>Bvb'bta2O %zFwot~H<%bIx:(kÜp-זpQ2A?H;8;wUjsON SlSK8uזBtчaG8SSlTc6ս|2ަ{=}~.X&7Z D| ~h(1G>7HKSTLVegU%+eŊgi>b,ڰf&%4wdon}f- Ɖ|UDڜr/6Nǵua-Ԧz/[)XMu/)^5uCD ~h!@@@@@@@@@ @&"B|9hkě>X{޾zvy:)g~[ý5=vEQ.=EdbBo0e#cֵ%LqcVsN8q* Ə|UDڜx哓/6Nǵua-Ԧz/[)XMu/)^5uCD ~h!@@@@@@@@@ @&"B|9(kGbv޽6}?kߠV_D,:WNC6*T+VibU8^}% ~:"?ĵ`Atm4ז'pÇp#~(/G<>L;^y6u/9x٦q>-讣önq6ݧ{ٲOƲm{dM)zɯd>&] C          M}o6A@hh+FI\[oHߢ.<ɯcV{h>틲ѬS^?bfZE`Z3IfI:9@v8'(][&"!!=I\[B &%CrHatpCUu/kmjiڃC[M^lSl^>oSJk>Ypߝ1 W          0y _!D_N8"Øp)JZ?Hwzqe\8G-jT+`oMm/ba.|NO9=:R3ĵC;F2if&C" @@pCU^?'-iM эN>řtZev?˶6&u-'gaK@';y!B1@eQnӍB~Xa2̜ ʾQ6ʴUޠ̓BivN%2OMl~fb%~cU?׎yԏkKYGyD9{;~9A`r@!WEB{16Sqm)Dw}}t3>˖~J5mS'mJ)cM~'1QZo{ BGG+_A6JbhN$a=V;tm5/.>KB*!{ qmODDڢ e#~(##CMA*Wm׽|2x٦q>-讣önq6ݧ{ٲOƲm{dM)zɯd>&] C          M}o6A@hh+FI\{c }ha$=D@IDATM K7cj[o(Qtd2EqSC9SkMTF Jזn灶e|ǩw)=//z ;^^ĘeZƩ> >řtZev?˶6&u~vp-Ă7!BPu\ GqŝW}DXyNw إ>ٺIhNeqψh67Oxy~/ĵg:=F29,c#Q%@A*Wm(z'')^mk۶nq6ݧ{ٲOƲm{dM)zɯd}w ǀp8\+p?|9!|9 cV9(k*6wO/#Tg8y~>.yrDXΞu@oHCCqЎmQ--JVCp?D_P0T`wUj ^>9LM-m}\{[M^lSl^>oSJk>Ypߝ1 W          0y _!D_N8"Øp) F?m:3w^Z}%@4VEV?5֬-O8bv)1D@ĵCJwk̩T>POAdȤ &~ _ѫ6/6Nǵua-Ԧz/[)XMu/)^5uCD ~h!@@@@@@@@@ @&"B|9(kwU)oRYS3g ,?656頺GeA *o#^}ڑ<µ%pm$ 18 8wUjL^>9kLM-m}\[ ]GmLmOeReTxRX_:}LT?@bA@@@@@@@@@lj!(:.Wv[?3Z,.RT?v^v; 8 sTLSQlS`!# זH8זp%p?Y pμ`T  "zfhz'eZƩ> >řtZev?˶6&u~vp-Ă7!BPu\ Gqލo9_?Y Qz!Hl}&ޚ1=_;4[3%:5}z cv '(\[&*!!=Y\[B &%CrHatpCUu/kmjiR:0lgj}j-j,ۦO۔R|ǚO!c}?           fT Aq!܏VmŵGGGh7=z)g^BvRTBuFN{S٢:1D,Ny~>=ʈa^?#88_] g'|mACז"#p? p\`$  "zfz'aeZƩ> >řtZev?˶6&u~vp-Ă7!BPu\ Gfq-(_]z[4)kޠ|j*Hd?6?p{:m\;Bfie,-h67GXy@\ 0_[%<H {3>/' 7;^^Iئx٦q>-讣önq6ݧ{ٲOƲm{dM)zɯd>&] C          M}o6A@hh+цY\l5CzFotv^\}\BlRQjj*5ś x%X,&VO1:D$c)!篱k\&k2jxt~ts7~yq<~@!WEhO/6Nǵua-Ԧz/[)XMu/)^5uCD ~h!@@@@@@@@@ @&"B|90kk*ڸJ֬ⳔNDc :m<:m֩$DuXZ2!kLY +w"k# 4ז@@pm&5OHpCUs׽|2x٦q>-讣önq6ݧ{ٲOƲm{dM)zɯd>&] C          M}o6A@hh+цY\{XkІia$-W(O,2>ךb~ձ~~8jR6wVӜx@b.Ȥ=4 %401 @ojqoSJk>YpgB,xpߛMP-"E>ZDžp?Z raײ,VƷiA,@'.:,nTo/ثlvySl'D $s4?ȟIf)%VOSy >dODybaq {x(ȞդGB?3ql pCU׽|2x٦q>-讣önq6ݧ{ٲOƲm{dM)zɯd>&] C          M}o6A@hh+цU\:j A.}?6v Z.R\O_I.>: !oVo֩\/%JTK{t BfyBafo')Gk˨9x @ߝZB՝A+@8@!WE^>XSlSK8uזBtчaG8SSlTc6ս|2ަ{=}~.X&7Z D| ~h*˴%VZkpVո}~*ߧnr$*TY}D+FDfs4)8D<)u a㔰@?c%c!] |UD]{dLM-m}\[ ]GmLmOeReTxRX_:}LT?@bA@@@@@@@@@lj!(:.W Czmߦ+W_B,[mQE)=!.oveSR+SRWfOөӴ<*E a?> E'p?XQ::QVcrqt;wUj3LMM-m}\[ ]GmLmOeReTxRX_:}LT?@bA@@@@@@@@@lj!(:.W UZ۹MfYe*dD5qǮKtP۞SjP6T2M~&gT@Y_O6Sa A"~@kl_W>03;^^IЦx٦q>w-Ԧz/[)XMu/)^5uCYc{B3Xp D! 'oCõw39ZŠFLZ8whNbՙs2sVgl~'$(rwH ז LEOP'Tp?T`p`p O @!WEʹ)YclSKSj{W{w}t3>˖~J5mS'mJ)cM~'wop 07 D_N8"Øp)]]ycznE:=wY=OnQt@!%ުRYoD,o "34-L`)*zmQ3 A"2# !H Г{UDQ{$sSlSK8uזBtчaG8SSlTc6ս|2ަ{=}~.X&7Z D| ~h&eؾ7蓇җ/]Z|V+׭AŵrH$aTe:#,=Gߔ0/ޔX\*?1>I lזp?9@?*?CL;^y*u/6x٦q>=X>řtZev?˶6&u)<pE         GB$#p?Y &=lTT;>mߦ/i:7 "pnRՠZ㐪rkV1-h6?OsB+g9灌O ][t ?&  J1OAFBA*Wm΅^ɼeZƩ> >řtZev?˶6&u~vp-Ă7!BPu\ G6qvymߢ}2s6HD8 %7anyv*[ܯUiF4Bfr)!R*T"lb%~|O lז3p<:pTdzO/g^qV 0n "zu/"x٦q>=;V>řtZev?˶6&u)<pE         GB$#p?Y &snn\%⳴PX ' ~lթΛeM_}jWx,NE!.N-9e2S ۵e|IG ܏vF9zGI;rуpCU^ɩcmjiR:0lgj}j-j,ۦO۔R|ǚO!c}?           fT Aq!܏Vmĵ?l~+T+,?}}-ڭl(lk%j'(S.-T^9ʦ&ʌe ׁFkKDM0!ܟ}nvĥ' $~ _ѫ6V{<06Sqm)Dw}}t3>˖~J5mS'mJ)cM~'1QZo{ BGG+_A6lZtq2MeNdDc 3#_[YBXq( !m6h"xHcfrs\\S(Vg?>#kKNƈ!ܟ<,!˓g%D|UDڜfS/6Nǵua-Ԧz/[)XMu/)^5uCD ~h!@@@@@@@@@ @&"B|9ڰkYl7߾zkKz鱏+OWᯱx_P۞oOPb%DvSlSK8uזBtчaG8SSlTc6ս|2ަ{=}~.X&7Z D| ~h"?w-zi Q tX8qTeaѪSMGGGBqDI*i!PQldY+P3ar85QM| ?~A$~ _ѫ6gH{d6MM-m}\[ ]GmLmOeReTxRX_:}LT?@bA@@@@@@@@@lj!(:.W vN7_Rm*]X|Ya=H68OJ# `ymIp %Zte*f)R"x,l<>A˵%q@o QDc-)āIA*WmN^teZƩ> >řtZev?˶6&u~vp-Ă7!BPu\ Gq;ڻBx,-Wh.$[!p}^q*V6֨Rͱ5GYRyϋy@syg%~`@X-#>m'}p'8>O>!@ wUjsnO/6Nǵua-Ԧz/[)XMu/)^5uCD ~h!@@@@@@@@@ @&"B|90kY}s*}ێXT{*H48B (2d~^mytVOƓbL?h:;+V/R*[R'@.a @-C8-t9`w'wEw C!~ _ѫ6^>'SlSK8umLmOeReTxRX_:pW#~r!BrAƬsLAkY>jѕG?o_:p^b$c*>a &~MvKkh6_rDt h_Z’SΊ̫M-#:M ?&  J1OAFBA*Wm΅^ɼeZƩ> >řtZev?˶6&u~vp-Ă7!BPu\ GnKtŅg_  m &axīk%?ܡ=Tz.on;oo>,e9zFXb'||I k } c;n=C?n~yxl3@!WEO&/6Nǵua-Ԧz/[)XMu/)^5uCD ~h!@@@@@@@@@ @&"B|9ڠŵ =>xDvѽtfjHpl W8ԛu*mvy+T~^.@˅UZ^qV a225\!8cǾ#XGHG=?GG|UD X{d2LM-m}\[ ]GmLmOeReTxRX_:}LT?@bA@@@@@@@@@lj!(:.W Z\{Pݣׄzj*L 6p0db?ϯ'۾fjbd˖~J5mS'mJ)cM~'1QZoQoimA9T*EӴDOP*XL~myvͦ>ݺyUHiXseY<ֱ:lWӤGA?3ײo7ѳK/l~ bs|E`X<$R\/Uhթj:8(۔+<3OO9bpe%ܣ n:$${B$eI%@ @!WE)^>nSlSK8u6Em2lgj}j-j,ۦO۔R|ǚO!ܷA?;          *( Yl_+W?msN'I=%z")T]ZQI?U5Ghaa>ٗ4??O7o:ֱ܃0 DkC!ܟ< ŵ,s޼ Gů8"D,,>l 71j[T6m˖~J5mS'mJ)cM~'1QZoQoнkt=}.+㯜:ݺ}W ٳ̙UW]Ǐ7i{{YnnărH”mXpBc"J\ˢrޣ> _84%V66{W>jPUZ㐪rkVE]lG-J{r 4' [.l27$DHA]["i Ok[@/O;^9z'nmji,?Ƕnq6ݧ{ٲOƲm{dM)zɯdCA@@@@@@@@@@wޣw ~٢/~Uz8gxcSmmmS2F 7oݦV,sD?tOբsBϫXpBc"J\bi^}}YiW!M܈Uqpv*[]ޤ]QjB1rDәYҴX2ɉNR4)OP SIp%p?Y pμ`T  "zfhz'eZƩ> >řtZev?˶6&u~vp-Ă7( ?S3bUZ:\\{ӵ7O/~;_zFssŪ4;;K,z)Vڟ˗/XpBc"J\[kUZ{l> QZ I7Mj4b5'بPpdoSJk>YpgB,xpO??~PP|>\ޠ}-__կO?Ypr9JOoܤo~Mz/%:α 4; D%EKbbv?/W!7:&WJvbU ;sŸM)[:1"ʹe:L2v71vPז<&' $r !p<&ipCUg^cmjiR:0lgj}j-j,ۦO۔R|ǚO!c}?          $ޣO+ }sr, ;?^oOlRZx˖~J5mS'mJ)cM~'1QZoQߥN_+~~!?MFmΜΞstfͨ -$5٣p!Ckcq<ك@T@!WE^>zSlSK8uזBtчaG8SSlTc6ս|2ަ{=}~.X&%?-g~(Q6uNE̥R~wڗ^x, jZňW5~mllR\+iwo8Xr<>|* urJlvA7L\ysK|@D*J$ɘBۮlFiܢ#z~4qpxH+6;xjQ!~8\/BFYIBy Ql4*U;1>qmY4YgڒH$& ֚\=xy2)|LxcdBLA*WmΠ^leZƩ6Ǐ[M^lSl^>oSJk>Ypf$%^]/ɓ 477)A~z~{꫟#e11ݓxeG25s&ݽ{\FCu}EcuCⶲX"dfL \a>?NS懆X"8so=_FAdNO|0C}`q-⒯)ہlſ5 siTߧVIY!ܟ.<)P*v1!g(QA\[BCA)ymp np_>=8p]L2۝ {.M RwUjsOf/6NǵqfG8SSlTc6ս|2ަ{=};c@?@@@@@@@@@`DImzPS}E%'i[; ֜U_B(T%d"[[9%Xtu" :sz ł^ៅ6KD6BL|"|>1GѰ ϓQ >޺N3yZ1cPM m0,e$,VQzJVI)*oC̥Oh./1Gסwqm = _k |W繂xe&/D@@!WEI^>9LM-m}\{W]>řtZev?˶6&u)<pE         G JMqݿ>Z.^8$mgg>Sj 2]8.^jGbq-_WxB"o|L,@g.R2/ĵKwr].m8o7~tvsbˈS9J%JDF3F}mޙak } 0Ixo|@ &wUjsO/6NǵY<~܏mLmOeReTxRX_:ǝ=p 4%( k#Tz}Tfi,T2)K/X1GWҋ;!ο}.ݾ}9嶏('a1+tZcY"!BOD 4%0JqQ[<@զ7}CztqY!FBT|JeW矃fAf:5V\+QOځZ:I eQ.S!SGC:kಃFMQ ܏nF=r/8 ;^^4eZƩ> >řtZev?˶6&u~vp-Ă7( Yg="sr24Х(I;~]IoO3\tbOn!~f8e򒰧ucyS!?^ fyR\[maB?]u|+taAcpB D{;W٦]Q'SrM(#V璷X?.P˖~J5mS'mJ)cM~'1QZoQ˳`rޠv%_Q,R)G ʡS.ucr܏| I1'.!bX >" xPg8JqNe<[7qKA "i׼ l7Ū]ڤ*,_.RqWL2KbזgGEvpr:3Ȣ_ApCUu/L)^mkK!ð[M^lSl^>oSJk>YpgB,xplƣBaG){nm\j|{qYZZc|&>=BT:[{TkTުS2D<)g|@Se *A?k賃#"9@?9~yP$0 @!WE)^>.SlSK8uזBtчaG8SSlTc6ս|2ަ{=}~.X&7Z D| ~hG)p=B,yp|Op8rDkh(StVWfYZ,,;o R?kK8QC~M>Of9k/C |UDڜ)46Sqm)Dw}}t3>˖~J5mS'mJ)cM~'1QZo{ BGG+_AvޥnI^ P!]tA?mG};NÎjB_W%!/SMjPEGGGlSDL< 3M s3Q}Fym98'kkf^_˖~J5mS'mJ)cM~'1QZo{ eRG⻺ W*~M~J1wGo~7賧_D,!)>a'~x3īWwiA!Th>H S'iDsžQ*X,>UGqm oV02[ےB&~ٖ@AA*WmN^ĚeZƩ> >řtZev?˶6&u~vp-Ă72B)啂ŗAq!܏T(ĵfM ~@<~ts_O}NNH?# |UDZ{d^LM-m}\{[M^lSl^>oSJk>Ypߝ1 W          0y _'Ibf!%g`^8OQ1;Cd.| ш Q2B>QkqvnݭtgBNS @B7E_h*]2E[.=%~x?Ɵe,6jFqm &0^ E^&~ VO@IDAT|UDڜ@66Sqm)Dw}}t3>˖~J5mS'mJ)cM~'1QZo{ ezvwUc~] *8.HS(9 qfs~^³:{6ApߎSXM5V]l y5~z(۫ #_:IS˴PXŃrr1b @|29I@%~ _ѫ6^> SlSK8uזBtчaG8SSlTc6ս|2ަ{=}~.X&7Z&AbÃVvw*b-%I:5}+tpNW0 WiF`wõw)~".ޘ1KKw~j۰2,!>oiUK]߫B̦{U^ˌxM&DoSJk>YpgB,xpߛMP- D`Q͍+ѩtq9g`~t:j=@-Ԧz/[)XMu/)^5uCN+z</*D`1aYG{xX/HbaYe%V >lTu;qVӳ眕1+/Ã8 S\?vn<Wg|R: ޓ#aL߱f-7,o~:!VOxd<%V8}Oe NdnG浥q-G+_A Gz,` @!WEO"76Sqm)Dw}}t3>˖~J5mS'mJ)cM~'1QZo{ e\M^u~pi}-jg!LuUwOO9+ϋ|G$W ܟ;akML*~+ޜ,~+Pp?i v+۴QzLic!:fEfU^^;K3y*ffgזFc@t:Xr$~ _ѫ6s^>/6Nǵua-Ԧz/[)XMu/)^5uCD ~h!@@@@@@@@@ @&q"T%>߽GuU~3ɬѴNe)V~9ەk%z 9b/OйKX'=vg6LqmU!:=عKwn꫃>7rHQ{ Y~T[Uۗ71W,Mf[p(!V"$Lym * c   INs]|UDڜ9Y66Sq'w˖~J5mS'mJ)cM~'1QZo{ e\-Z۹M+Er/OU{c'^y[˛#3bEٳTHO;+w{|[!̆)ޥzfwLKŕAG9h~y`.EH|]va2Μ䝭tG4_8IS'Xx:;GDl!&&pW~޾3~DO>y !|Gl#fxƎxk?ojS!ωp?%B(~t ped@`r@!WEB{16Sqm)Dw}}t3>˖~J5mS'mJ)cM~'1QZo{ %Bh>y>Ueʧ dX+XXVC+4?) ~`#wa Ao_{G7 ު]|Gl#v<|ǿy-8>p*{4BKӧhQ]/_9QN=q=A5;/:B<@SڢmrEN0oTzLe;,g(peݤfl| Oē!aQg<ǃp?ȣxoSJk>YpgB,xpߛMP-Q"?{ktToXyw*]tDa,ԇכֿb}+:{vVpP3jpn:=?w6oRQӯ:':gxugp'j2UJ+T~n+uw3g꼕#Hr8˒Y(ބTrޘp[mJ ܟ<,tOLكWvvy#?hǢ}^}uΜ3OMY!Ԛ"b}~AuJ=:R}Wx'fCTv[N{դi:5-6eN&#]58}@?yYF~y>@IA*WmN^ɉ`mjiR:0lgj}j-j,ۦO۔R|ǚO!c}?           fTKmR+ʫݾEU6:) A^b jb퉕ΊӹY:Y<%ƲT Gr\Gy,2 ~v@oxS\ 6虥hXyYy,MI@?I?)ׄXEvX ~=]YXfba~!SVſ{~:ˍNU~"uy#FDy*)ބIfjI>Ŋ?&qޒPTxLJbCY}+L 4%es@p_'/#6g&cևg_-Ԧz/[)XMu/)坆k>Ypf$%QB.ׅ`$VqewVh==s(Uc1*M! DjC?ʈj}]yŃ377m$b 6&pO`ҏy&WmKz*??*2 Al%@y  't6>E&||CfVGg],zw-K,WdI˙\=n(B=QYY#Wd1^xd"(Mi25MSN[N4 DNNv#~ _\O]Dxզn>M[ ћ. c3}zڽzئOŻ)k}~.{Xp&3A A9f񱕍U$]Yx@5r=5j,ܿD 3,r=|{-ܗ-//, 2}] /ދp4'6iimi?(?S4Ɇ<&I㓆v"yCѓo5pdm^XyAѼ0 Xo J$c>MNrV}ɤ 1 #kS9 2,M8 :WYY9A xwm{=a}x  ~ _,S)^8O1ř>V^J=VlSɧݔJ|o5>Upy c@W          0~ 56!­t玕VY,V3K&aʲ-8b`PmQEe,>oe ݸp zsʶ`1饹a |!ܒ> 66oo2xl,8o7{,,3,lginIzyސLɷDGbKf}eKom@9"1!቟E쏲^2'dNi #mK>+o(WJ6壢5Yp&~yFsW @߉a}YJ @"E-u'kWmz6NӴp;F8Sݧ;٪KNJm;TR&ݧwqzZg;Tˠ1ިav$ji([b3g) v9K6m6leK76dȃ pg9tzzE?3 ٟVo?: 8 ;rǪ0>>O2',$z.M'e^j_OF[u׸~\}g-'LD4a'O?)yp](9L#e*?. KV~Y- @# j=NS47 ٯcԻ'~ƭ_7ޘ/@w o"zO-)^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ @fP-"TGVkoOgh)Yn)YQLf_++bwʛ}6-+oXpWm0kަ?y/Ѓ+k o"žęwtyN$s4]CV~D$oXD,9*m^J6ςuK]8d MK̞U_/\O"m:Oyll0kx}qW6y"h29M %Zȟ~[D=8Am'ᾝNy :[^SxMM/}7]nhgjz'[{)XMu'wS*=T..T/] B          L}g6jA=KUZi"glvgO Z=ػʚ<ްupVdxϧWd;~F77gߠs39[tEQ|Fz9^ Ml:Y4_gvF ̈́"oYf4(_eίOqD5WbK|.$~"T7u[7Bvq%?ƙ,Ηd~dsIh'P$6T'IfrKMeYa}9kx@?T{{o:]\^@bA@@@@@@@@@l2(!d}w]B/nϢ,~ՏdCƒ;'tmES˨Ny7Q@WzD;7K?Ow8:GRsf+5LUkQSs KA.m@u'LM/}7]nhgjz'[{)XMu'wS*=T..T/] B          L}g6jA2ˮާ"gg|$Stz2E6L!GxpBGV&]Ɏ5:7}qTE{%=ضoxaUɎ+ Cz@ta%Wo98*D2hXo9F#E,.Ζ_LG&#Φ$F<D3ȊRYb|ټ(UfۑoG9|4:"#FJZy;BשxPjE,&ϚXrI%|.oSUg@?~kr~ MA.mHu'LM/}v/Fݎ.fNjRbN>T{{o:K}bT#y?"\ᛈ%WkY\Q8Sc;Hg{Ӈ~[gMXrGM$~N+y_JO}C Jo(BqSڢc(.o.M[ ћ. c3}zڽzئOŻ)տcM~O!B}/           wf3?{.N|n2,,ZbAͽd-V86۾e%y`j 1N+ܗ>KW?7./:4!'ĵAa=3Kwٰ'0߯BUvYtoֆ7RxSiߌ _ySBD"b&3O.p&86BX&#}r a CA}~ dKަz|nT㌶]:ݎ.fNjRbN>T{{o:./n @+[y C!d/g4 jZi1f.O.h.hmdHx_2a^: EL)?]~uK?5Ki 8kO;.0 K}f"?oyc>jĖOo֗d4eE6C3npF~h o"zO)^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ @fP-~DI2GXԴ;C+ :M42Y渒I\65lGfW;5\}F9fq7TܶDWـ" 1. @%1"e'm ƄIvKT6WϞޖ?C=.Gw}~9x '~ _\O]4xզn>M[ ћ. c3}zڽzئOŻ)k}~.{Xp&3AJ jV-d~.%N%&߹CG% #y,KS"ӵ\< Ktg놕X#+N{^ĵ=D s9ͽu\"/U-~rDG$iͨPo#?ϲ?C~ލE✅?<T[UFpAW/  0< o"zݖם|jqMM/}7]nhgjz'[{)XMu'wS*=T..T/] B          L}g6j7w?+3/٩ ,؟N0m4'(.P2C,CyR?*ܧ~D!BM-|E4`lp-YqM֋gq:_Y:3ur)ހ~~*!u0@p @"E-S)^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ @fP-"` *Lhfm?oe# (VhJGE:bn泋,d4@?@#v oo~M~3tyuI3#Fۉ@ŵ'a?f{do9~R% Sz*NNˊ(iJ߲+ryf9Km4єn(!FeP~pEu[^we3ū6ti"?Lmv^dv/+SnJ%ǚvCګC;B3$KP} V8҃{C50=2)' t: 0B o"zݖם|jMM/}v/Lmv^dv/+SnJDn5>Upy c@W          0~ 5VY\zFKMYEiJ{Xj~ɛ v[T>*ь%gעC oh7pzٌKtg}|=_Ww)Sxզn>M[ ћ. c3}zڽzئOŻ)k}~.{Xp&3A"48c~@k,,'t|rLK:YD(I@xtE<PRdVLV^J=VlSɧݔJ|o5>Up KB,8pߙ͠ZJ}Q6g[ J3ta> w WPަj/X%K>[[>_%N-GAk] C$CyBvo6aLi2%% MggDXx7lvRmEߗ;:Fw o"zO7ū6tiڽxs;F8Sݧ;٪KNJm;TR&ݧ7/a QA@@@@@@@@Ə÷nwnЃ,ߦH8BW毱h3(4^8!uKpJְf.S ]~WƲSm'tyKǒ8Lzĵ|`-'8>m .[ZJ=*F!ɳ^`Ek̏_e!@|!~ _붰ם|jLM/}7]nhgjz'[{)XMu'wS*=T..T/] B          L}g6j1 D<~Ҧ]2V,$rf>9~LR?R"g2 4q-)>~p/rf:[^eu'$LM/}7]nhgjz'[{)XMu'wS*=T..T/] B          L}g6j1 DT̠?5O,$:?sAXpC Hbeͯ $>cyu5i}0hu>o7K?栮Na׎9SgO3QX٨柶N]lu۞[ߗm AA.mY,{ɧmާi+!zхvvq6OwURTwx7cM~O!B}/          FI/uoÇhPbdM.The bq ԟ Z_HWݻ^SѠH$B9pT{{o:. zN`"?:Sڡޞ5D"N3tez)Q<ӧڴN_|}p_DEPfg/yu6}'t-,JHBas,^_x^~5DP9P"DKx9zKM(˜P qVvμL+)[+N1„ &U_*y_6\JH<L`ĵ^#T=Qțlޠ_mT%ٻt!w"W!?}oJYzi&@eKheqmpVafhנv-l'oYگţ=evEDzxaAC /0!~ _붬SW)^8Oi?nhgjz'[{)XMu'wS*=T^CA@@@@@@@@@%Q߿>״"FA =3L76?F#tUzCҹ+,3Q&,M5g?LnݼC?{陫O[)}g^8NoUr~봵A-*׋T?nLf !u/Hv *;wq\i>ĂI_3Cu h^"w͛R.=MT6Qap?h+|po m@sz#͹鋴oNR.d4|P{+Zc 0 o"zݖ%ם|r0ū6tiJtta]lc6՝|*MXSuPtp -Ă3QuOfgY쯰~a~Κ\\Vg˯_e"gI?WYO7Xӿ;?_}M7O s]ی-`?y2,M&YIJ?E3Lf}ee.m,g(7(k}o\/}OJf)nH#Y1Œ(?Kd:B%@IDATH"T\ @ߞZp_5:ADViks3%|NGjc 0 o"zݖם|b0ū6tiڽc3}zڽzئOŻ)k}~ǀp@@@@@@@@@`pCe weYEVkO|%ZT >ezF"^[[nӯ~!YZ?_?M?w._hW#?YeA<,іcy5:Z8>9 gc)o[ ,|v]!"%._9Y>N% k]Na="~@| [X{x!o yFSMP,cHJ}7]{F-|]D۲O-)^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ pWD_D?c͌" Vӟ7x8qm7Ɨt}3:H4?əSy 85 n"ޯ6Tݻ跮3kzJ봾l俞Ћ˯ZaAC @o'@-5~ޓk~wi߶kd"q :p 47 @D@` @"E-+h;jU^4^+1ř>V^J=VlSɧݔJ|o5>Upy c@W          0~FIgO?k,Gh?~RDAzD[vA$G1712]xCa* %I+O]k\m{,'Bks|Ұ;[h> 4|vR'o^ h7b۹MhIZʮlz3o/f ?N[e/# rlm>Vσ;|?z`eۏtqi%- SLR͍qykFD"0dR?۲C\)$gݟNR*d^a=E6g˳-> D@keӾ#!oF 2TunN>uU^4mvvq6OwURTwx7cM~O!?Uۡ?@@@@@@@@@\5!WGb-}٥_+/ijj.r Z\п3/ߣB 4əET_ݻ-J{X*$ruKX}g̳feNHMFo~B?z8+ (uU^4mvvq6OwURTwx7cM~O!?Uۡ?@@@@@@@@@\%Wzgw9c){T_SΐЏ)H&Ga͛Yl---ZcK筭mz%r,Ns:mllZ_]zRNSZJjGed t!䘎+oS(?ޤ 0sK):v77͸_ty*-R&6wvyX5+ y ~Ws Ej =7L*gyZ:Y{6#"~է)!O`1,@O @"E-u'ZSjKqzMG1ř>V^J=VlSɧݔJ|o5>Up KB,8%~NVY*59o_|Dtrrb}ݸyqn7^^|flv##CM6f$suzuc+-On GOO t3z5ʱ%=2Lţ Mȟp_ɴ,1^r,Jufzҗ?7..=MPT0cQ:U*GVV~Ʉ/{8' K(!߿MA| F|jF%}^k׮63q:׾G~;6YeQOn %UDpm7i0]}f V6n{&ng7||=s^;}:?s7+>O?X&,``߳{,-Vi`++l֔ps7tZ z|s|Ggp 0 o"zݖK^wmާi+!zхvvq6OwURTwx7cM~O!B}/          FIEnߡxme!,!1g?sf.^8O.];wyU?? ~-+Kl<k`"3<]%S V-?-T]`}ʩCň0G.-|v\&)zm7mMeWiy2ljv׸spD9޸[ sumߤK4T,c=sŻݳۊc 0 o"zݖŵם|B0ū6ti"?Lmv^dv/+SnJ%ǚvCګC;B3$0J#݋Ͼ*gүkLC0ŢQ:{vYt:E/~w.>Gp& P8DI6 |Ιd &(¼ey҂p%4T)Zޣx4N/lfE\3g gdcpQ%?X.]2-1kp{6e{2뽥֨Q6ʿ{Mgq"ǧT{{o:j;p 4K$ܗ}yPأbh4$g_^>C/],qK_C7nަtY*tm+Do<%UU`ݻѣ5>%O$|f>}r_Wb/V뇜m5Z.Q2x$zF5n6gS6|js˔KN=q0qZ^^ x~oiwJM99+,{K0p=qpܯF-|]D۲O-)^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ p_Bj=ܒ=?YbߧRIrF~"6;M jlUG6  qz or| F1 j*3-Hz)L39דp5t#t#zte:?s!){v`ŵֽ+"qpo!j,pE  {,³ (Bp1;]@BE}\ @A.mYJ{ɧmާi{Wfצvvq6OwURTwx7cM~O!o^~Qe Jv7]Z[J7h.hess7i> O|铇;ަξNWX$Nrv'p'?-.AL-K{m=.Tj2Eo;-) )+@@"E-a;ڙU^4m%Do:0܎.fNjRbN>T{{o:]\^@bA@@@@@@@@@lnpo£1gKNtf.ps7!l'ܯ5O~H9uGʫp8>p8}-߅,>}ʛܥKO9J20&d{0M{CNA.mY{ɧmާi+!zхvvq6OwURTwx7cM~O!B}/           wfw ~ V" jJLz.ͼh0e;7`6M$/ha8mC @\g8X>LB7-UyVizq}b"Dxʾf,gޏ}c=|{8={CFA.mo;ZU^4m%Do:0܎.fNjRbN>T{{o:]\^@bA@@@@@@@@@lnpo£5B}.>Ey GY5S{2/Gk}yۥM @r/_ <]{@ >,#x}Wu(>1驅g)R, E?a{3G{KA.mY{ɧmާi \p;F8Sݧ;٪KNJm;TR&ݧ{DCz&*AΣrQJ=)oZS MfXuʼep_vGG, L9Z/Lfph (k>N }hh[/fAE~ tZ$)˴}SGZA-c%~ _ם| )^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ @&*YmξY\l"Osp]2 ; zj3Mg.ӛ~HPg@\;~k~CZw||rLFTiVi6=o=L]F4 ]6Cx&~ _pם|j LM/}7]nhgjz'[{)XMu'wS*=T..T/] B          L}g6~@7­m-J2K՜S< Ţqd2 ɟ0 uuzti*uG vlgpg(=-ޖW' z\xHwnSx"LHfs4Y8dM}o8GC?ΫpEu[^w7ū6ti"?Lmv^dv/+SnJ%ǚvCګC;B3$KP>AԀ )E%qJ9jh=CsLS6p? 4L}o6huٺosH/)` q,Ґ"C Cz:x_ި[3#*)ҋz.HpESJ"a\<'s]pV  o"zhO6ū6tiڽxr;F8Sݧ;٪KNJm;TR&ݧ7/a QA@@@@@@@@Ə[s~Ԏ\Q`[v,DB'aLM eYJFS65o>ݾIۥM:8*әɳtyjV yA?k3Lg{Vcvp`#JĒ4DYa?}p~ BA.mAe;/Su뛚]:ݎ.fNjRbN>T{{o:./n @+[y~?iXR?_҃T(mtf[ysgh&3b=%`GSExK8b"qh0-ð ~ ?ܣUξҋ2u7ޭC2C#p"A o"zݖ+^wmާi+!zхvvq6OwURTwx7cM~O!B}/           wfw ~rԏT(nyvTkT)P3b-E3L$L~ONL9%F68kٯ@/ң}[N~'헎UZ7唨v\T4MYٽlބpʸ4 M[^eu' LM/}7]nhgjz'[{)XMu'wS*=T..T/] B          L}g6~@7`T6mk'uggpg(MQ$Є q%`˛q޷q/rIf2J}3ޯF1/+ֳߕktn撵iSX(~%}o\-|]D۲O]&xզn>MORnhgjz'[{)XMu'wS*=T%?\1*ppkȵZKTmT8ܠZJ"TdaJ\fYğg0e̡Kp?5Rf޻ >obG| ڠd~XpoUj_) tX;tb~4EFKZ ue1/[^eu'@LM/}7]nhgjz'[{)XMu'wS*=T..T/] B          L}g6~@7`_ש\.S(t:m wiumq)Z-s6)(MP<6;t~4Džtg놕iŕ׬3|#cEڱZL` ")oуݻ{E/ 'SӔe)}#%V62A[QIA.mY|{ɧ.SjKqzMG1ř>V^J=VlSɧݔJ|o5>Up KB,8pߙ-M8ۅ'tLF*C:%.oZYϳ gb] 6;t~8[7i}:JXz;q-' FjT:ڧ=Jz泋Vs ; ~x8-|]D۲O]xզn>M[ ћ. c3}zڽzئOŻ)k}~.{Xp&3[ pǷ %ԏ[ڤMμJ'''KLrI+z6L"G ξ GU7% )rB~L5[VX؇ zZ׺Fo@K [P:]<m*X?ӳMgfi*_ޤ7!PϯE6xB5Ō@  o"zݖם|21ū6tiڽxjr;F8Sݧ;٪KNJm;TR&ݧ7/a QA@@@@@@@@Ə[s>Gn'ܗkqo꜅EV~ze]}fYgshC@i7v\YyxSG!&>Lq^~wƭ-<&ZJ{hVުkАpk%(Gp?(+y@ @"E-S)^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ @& 3/YYXwiK1δ$Y!ɾ?۱p|賱zgJHƩ6Qwnw饳|nֽ3G@\%!9@{KV p_~GBJD~-;?E=)Gp%(@F-|]D۲O-)^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ @&j*CqܡcʟKNҵi1B2+X*p?Q޻s*WKKh)@\{ xc1]xƽ#MzF<_?@eٯG0gp?ˋɁ@`@"E-m;ԵaWmz6NӴp;F8Sݧ;٪KNJm;TR&ݧwqzZg;} {n 7T8ܡx^c+kEsE++kh"YO_:%ܯX/Нtkʫ4{Da >Tqo9St<햷hNR]\.1?g XG}W{4#Bԕż@ X o"zݖEם|1ū6tiJtta]lc6՝|*MXSuPtp -Ă3߄=~7}wY̵FwoR^YZ:Og.S<#&O_*%ߪNej%Gty%y{K U>qo9=^t6Y)Di<%Fb͚bc c1Kuun2N>uIU^4m%Do:0܎.fNjRbN>T{{o:]\^@bA@@@@@@@@@lnpo6TRhJGE*WJTrəs=C3,fgwnzy2,Mf8 [݀/POڡ^<9rYpo%?,~`q|G%ܿ44e9/M D! @?2K&~ _\#O]Oxզn>M[ ћ. c3}zڽzئOŻ)k}~.{Xp&3[ p?pNGD\ۥ Z-<wi6=Gy.djgOP,#;CL@ ?ߥ,;3yrIk=qj}$qmaPd!}->0|NM(>G8D3YYz- ȏq!58pEu[. {ɧ.#SjKqz݋r;F8Sݧ;٪KNJm;TR&ݧ7/a QA@@@@@@@@Ə[s>GpbjJGITSE\g.R~fX Eplppx@"pz?ҝҥ:&ϛĵ p+ǽex-ް߬4I %7] C?0#w`Gnp 0 o"zݖk^wmާi+!zхvvq6OwURTwx7cM~O!B}/           wfw ~iI6gߤZJyκ/®|2OD޲(Ep+6}=.ݧ.S?=';k|/a_&{K_0{:15[,;7i3Ow:=CXoXp2u0c< [^e=u'Z{SjKqzMG1ř>V^J=VlSɧݔJ|o5>Up KB,8pߙ-M8-ܯs~uUꇴwKhpL+,~: 6nF7Z!EzqUZ:a $qm/iX:v?%mzQƥP( <[y&,C}v oGm BA.mY.{ɧmާi+!zхvvq6OwURTwx7cM~O!B}/           wfw ~~ \VVVJfQW<29dg$=;kW7y~%թJH._bo(!qm`opoG@ ~^@̗&os)ξD~} g| -|]Dr N>uU^4m%Do:0܎.fNjRbN>T{{o:]\^@bA@@@@@@@@@lnpo};ڡuM%cL3әsI23\z94 -NXB:K͠ @\;C?zk63ƽeԻ;mӧ?yu0{x_$nP kC! !~ _붬S+oWmz6NӴp;F8Sݧ;٪KNJm;TR&ݧwqzZg;} {Aǜ~wVzO)Ljf2}/`pf/o=p.]\rTA@,c_'~_qpog:ɸU\u-K'oY<3,g-Kε23p+!~ _붠ם| )^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ @&!ܷ*mc}^%,Y:7s4EBQOkSŇޡ'ƅ/S4c!^OgÌ kGe~V7oե>,Q׎ ! :4-#XS=Me~RM-oG)~R:6g擓?[}bUF+#aX }#8  7@ @`@"E-f;U^4m%Do:0܎.fNjRbN>T{{o:]\^@bA@@@@@@@@@lnpo؄㆕R;{E;MsVp(Lfb~r,  l3{۷hI{]<]q$qH.@O22KeV^J=VlSɧݔJ|o5>Up KB,8pߙ-M8p_>999:gA r)pMqFF,p@opEu[^w56ū6tiJtta]lc6՝|*MXSuPtp -Ă3߄= u%3dc;ܥ,QW,2=p*b.|!pgkz۔dLƦxզn>M[ ћ. c3}zڽzئOŻ)k}~.{Xp&3[ pfNZ?g_=ZW)41A"$M8# )[quzLr}&SMr8ĵY>N>C2‹woZ޴$GtX;GE_M3Z"~jF"Ȏd\aHq\uF-|]D۲O]xզn>M[ ћ. c3}zڽzئOŻ)k}~.{Xp&3[ pι pm7m%Z-3/Ѕ٧Pا 8nP~H7~ыoP:D"q5 37Qqo ڊl"+$"cZd}k6&,W4Z}wx> F-|]D۲O)^8OVB Lmv^dv/+SnJ%ǚvCŅ ^h!@@@@@@@@@ @&GQ,KU8ئJBFO)<yϲxk*=CqƊOwdViޣ;_| ]~w8Ļ5 }ًHŶc3/sęg&syI3~3cI8'~٬D |UUP.p/$/>VԧJWu{ڞYM~Pz -^==NkjL}ֈZ_܍~c 'c O+B @ @G9cwNpSQ+Kis]JJlOcձXaBN a P(Hn#[FkF{sm9i}. LJOB~&mol.ۻ5ۑ14>8)g=8|x@@~ ۶fakH٭o\;6BEmQhU˹1og|֮ն(߻3>6ri{%H@ @ @ m3@IDAT ߿pا ܷa);\YR'VaL AW'? #0vW~zuݑSOH!SN~0ĵl%֛\[zs̺Vߒuu_#+RPQ2Z~Ә|6/LSwC^E~o7a%pIom[/V՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ p$A4t6SW+[RZʊu5IlUFJq- .qf=ז\8U) Y[_Ql>#eD&ST8L UQT) p? 7 mma1k|&gQ> cܘM>NkjL}ֈZ_܍~5NqhQ @ @ @ p6Ig'M8MoV[-YX N*f*ci#J'헾#s4-|nWuKQTꅯKf7'r>ۤ%ĵ-@B!\[BB V}%YMkUYXV튬WRrS~z"n/g3Y%*Ӳ/^i$p?ʜ >޶»~Xl_m:OƷcܘM>NkjL}ֈZ_܍~c 'c O+B @ @G9cwNp_kv}[7ˁ}4/cq9:rB.<)c0ݬO],ݕ[reS79<e9ӇpsLX!׆!J~(- ̖\.XQO_ҭ^X/'2-<7V W'dPݼ͝-q$C||x M|[Doz?~X_m:O6BF#|97flڵa1S5{wcGF~ZB @ @'pJ~ܜu#\>asDFgks)ssr]ޮe3)222,yY^^{5sp^<i$6  Y\ZKz>m?2~t믭Mx9xRAyaw[0ĵ QD~\[B~+ܷ Mj"U);͝l_Nr}Ydrү#SCC }}6Cl#?ċG@@$ȷEw՛F4lQn#QhU˹1og|֮ն(߻3>H["' @ @ aݏ~{r-wo.N8$gNgyJ^z)JïJ ݟ?i j20/N_կ3xO/~#?g@m25u[rs\?;~^<~i'튺=)Gd8#NIVGߓ;"ޤEOU-lEDgZ 7xQ7.ޕ{E2J?]<&'NS2=|L%φ E@ &pIom[79ZgiFt`DU/lmqZV>?,fꣴF|n;بq ܏CZ@ @ @puuM޽'W]˗d||<\Ryu>1…rq9~w׮ߐ7|'gV":]__Q"\6Us{z/,prpgwGʛ^]ʒT6^ߖ;3rLGC.O+?Ҝ~\ƥUC\viGDtc/҉pNܯfY6ضJ~vwG=Q?m07NVߍ?Z!?#t#@ o"zbfMn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8$ܿu¢W_<7~&+y ٿ/ϿuIʗ_R}%n)}}] }}^}oGoK.EtMnܐ[+7y9=q^ LN2G2nߴ'ˊ˳*GGOH>/Ӷ qmPS>$/pǵK {`N>,ۛ4/ )DUi07MSGU;#¯}'sO_2yul!pIom[rA79ZgiFt`DU/lmqZV>?,fꣴF|n;بq ܏CZ@ @ @pOeX쬜;wVN<Lnmm]^~Uu7~i⻻C|K$?~A'ɪSD ,++2N?sTG!0#@/0TUo)VY_QEܕ|QNɡiMx_} o_K@6ҿR=_@l\[b#\[zr;t;uu XjNmU6?7An)CEP7|N?4\OGGc;A@$ȷE~X,6jݧak^_QhU˹1og|֮ն(߻3>6D @ @@DIO CLCC{%/ʷ~w(k7QY^N"%eU޽}啗 ߫C!`G"psLN]n/_{eMH.FNDqZ 2Y%e/'.dODxM  V8ĵl pms!LkK3pAOO&Z,'-ȒQG #`~(xbQ>|_껣@pւO@$ȷE~X՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ pI[ȟ/I5ʗ_?o>qjUS'?_~C岌˽{孷ߕ_W^pGXT8T{kw%C}}HANVV?JįOׇߕk dh`X'X=/ĵ}uG\h8]i5 זئm$aJJĿV]tAQ??`&Q?ɜ$Oq cujY 0޶5>ԾzۨuvݍKuVuviZm[닻1#old peT@ @ @6wp_C?{m&~?v]_/ʊ' ĉ 7nޒ}/ur7AJ~8)-ޯ֥$wWoɭ2^Iu>~f:?O|+?O(ռM ̃' =k>=GE:=õ%=kL$I7]cpgwG3iY.RyQ7eKЯk3'df$_ yG@ >M|[Do"Mn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8$'^}F~ @0" y_oK$oy'fkrS^ '''رrv|%{~/'/-.bm%.uߔ666ԓv?lhzOz<`-Bi. c_P'S =xãH] v">_9E95vVk+w2|}%ŵzVT^hEkK+: -m;!У~Ͷ'76IisM')|Q#~#\3ߗB/׿oJV] LO?a0O x:BB~ ۶^u՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ pIߗs_+p0MYZZ>H^ y/O\~C~wޓ_WeULcnJEɀK"ZS lB8-Ho!PE+-{!Ӻ](ߗrE69=vNΌW',O<)[MyUyė蹦+z4qSWZ\n h/"rC),EZ1'˕E([ ʆGex\NgO9:(9CA]^_*mt)}%݋"uL?޶~X,6jݧauVuviZm[닻1#m~@!@ @ D$p.]'prb\~I9wv6ʪ|Eu9SZTO&"D-e%:M8NٟTcSN?' 9'C 5J[M׷ビ2=|L'dx`7xĽV+˲XWd${ANnZljMHp<8PK\[Z!-lYnO}uVRu5-חcY%dSr3^I8'o'|91N!7 mmurYS_m:OͣѪΗsc68]m3QZ#wk}q7f|-p? @ @ $ܿwN.^Dݻ/ (~iޕLcɓO>K2==%CCߕ}/'ͯKA ~-)dnn>{}-f}j@ahh e^<Z>i_N܏Ͻ.r{Lgdv_ \&';"e)c3O74VO gGzVl6Op pm9s`>זh>A]w J5tEJsǟ|?W $4)Tr{ݕ[Piy{?'F (q#CqDO]Ymk7ck[i׹17v'ݧ洯_3Z>Q> [:F:_΍~;v}~XGiޭݘu׶p  @ @"8LJ"dK/_Oӯݝ@<25=)c|o|MΟ-wϿG:yR2zl'OVEu>}TŶ5%)w-|/odC+U^N D\&oGT}ec{2VO cd0kp@\p(-hHXX00[8Loբ#ݮWW#1)[Ηdp_xo.] nͪ~CSRJv87mmu zۨuvm@F1Zrn&kb>Jkn/ƌp 8 @ @ N0 ??_z=8yqiIVVׂ ΞB!8!~G77|D*@O㛲|㴊!oE\;'Փ/o(Z#Getp\Á+JH>ߩ~W~vu9;bg}X(8"4jsڒ,ߴε%-+<pШ*&/幋rr|VNtp#eAܼK`z>eU['#&Z'NːA?+?7wwU p o"z\?,fMn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8$׳J*rYj[5u~-\:1?I0 šI R*ejjR dyiE u O ͌bЧVE~{3"p6q3EuqM:_T^Jm#L7/F|k8,DY7}/ڲzӗkK^gzO'}QݑbpTqFM?|w+7o^%W>O$3_}ʾ~RWYˆ#pIom[ =79Zgi[HG2ѪΗsc68]m3QZ#wk}q7f|fE;gGO@ @ @6&ܷ?aϏp?9U)oƒ:Q&T}`1xG @}B DbU9~MW/|]?-zt u%-" -lpߝͥrovp>e}bxZ&d|pR~Nwup%YV46()gS:"p}@$ȷEbfkMn}uVuviZm[닻1#m~@!@ @ D$p?"'Db'{'ԂxnZ&_MɅ'Yu44KX 'J<~o1Z/ĵܶED"m@fϪ:}_o[+d8|OCQqPׂ~ W+et?x±r^=U!nO;GGbIAG o"zֻbfMn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8l OpGhw{g[6+JD:Z:DC2^$Ghn,K.<%ԍZb.ĵ.v#D^>J }=N]F}*BiNw uЌŨXx:eZOZ*/菔W7NʱѓOp z&A-m+\?,fv6jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ @& {|Zuo|:wQzGO=N|B<էrS>^vZu|L)GKqK-Hp̷nԪrCh[oha\L 6SG?{P7srr|VNNF8z&A-m!\?,f66jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ @& {|چ յ$eG_23|LՉ~ O8880}Oĵ^,k m pmiEk * ֪~_*[]B~PII214uG!_&,=Qdqf#;ޭca/adCw o"zbfMn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8l OpGUߒKW rKy NQ=%FOH6l_6hN7^+P~ɩW%W~o֋Cq--mQpmaD%6;ﻫ7e*r"OxN~F~ɨp;VI ]r=h=uy{V ~R%n>r(-$wUEi6Ի17v'ݧ洯_Z>Q> '|97flڵa1S5{wcGʨ @ @@@kpا*u)ֺllj1֎#;|`}r]D޾ /ξ*}}}ʇ_kfBakfB5-}@k ;!* +ZYV?+Ner~ VOlҧ#ޏ[}חj2RUk3Jkn/ƌp 8 @ @ N~83&'we o>ǥ80N Z%OQUd޶»~Xl_m:O6BF#|97flڵa1S5̭ݘwQtA @ @ gt~҄=>觾%ZX_*IDYNSٟDYBfU˲PW⢵T 3O솸%@\VKkK\bYϵ7׽Yp_?=3n6ޑHR":S})ܯ:,ݕ[dG I+Lf$}!܏Kz&A-m3WorvӰ:F:_΍~;v}~XGiޭݘwQtA @ @ gt~҄=>[ۛJ_k~N@+ۗ˜Fex-D}-;)~)8Tz|Tk[!ĵl%֛\[zs;um6utE*ߕ]q8wDKx%_WW++<a|U7ێ*~~X6X(@* o"zka1O|&gQ> ;ityȈ:F:_΍~;v}~XGiޭݘ? @]@ @ .}]E}:;u-[MYXr{z'dv<6eb ON˹' h mE!֐JkKTR]ǵ?{QO޿-ƞp/%YW7PgnG@@$ȷE7&՛F4l-+|97flڵa1S5{wcG]ۦ?6HC @ @H~DP !Oj pp,dmldXU-frW@ 4ZYa׋N]ܒ\'%(_ DZhꅸrZC6*-QIvז^8ESP'/?8Jkn/ƌp 8 @ @ N~83&բ,-2|:wQ.=/L?95|4tR^.ve(jCZCĵB%%FIu*چ-tEN>&y)FgI{۩pn-ˇwޓ!'N+951HMnI p8 o"z֋a1|&gQ> cܘM>NkjL}ֈZ_܍~5NqhQ @ @ @ p6Ig'M8#?뻩YRpƒ:E[vOuqP3}O^۪NjDÅQ©WZo"5$h[@\ۊ9->*\\[\"aK𽰦-ryAM;>~Zyj|MqecQqO߳ 268!#үrnd,N޶~Xl_m:O6BF#|97flڵa1S5{wcGF~ZB @ @'p?MINӱ7ʭkrwSgO-$Iߑ>ٮzGJk2>4!<-"#ĵ+Iqm҄7>זi3ڒtpy]h§r_ 7+2U<&O6؋]ѧWWzݕ;-99~V> d t"'A!p o"zka1zۨuvm@F1Zrn&kb>Jkn/ƌp 8 @ @ N~83&c}u%_W'f98mb g?>̯ߓLgH"M^Izk&񹶤oMז$sL몟ȴ^]W?t^]'2<0ܫ7}}OdN}7B3y.O|t̑ϟpMzI p8 o"z֋a1|&gQ> cܘM>NkjL}ֈZ_܍~5NqhQ @ @ @ p6Ig'M8#OkA}g;cV/9EcʇJ[gc2:@pԎvkkq pmK7빶w2k~jZpZYV'ߔ.Mʙs218%cRF?ጶ5o]XKdM_ ʴ)@'M!p o"z a1zۨuvm@F1Zrn&kb>Jkn/ƌp 8 @ @ N~83&k}wwwe{&ZU6)%%_Ҝ G@_ N[frA ĵײXosmudvvwd#nWt_ޖ1 214h+~ZeE.{?o*quÐz^ݧl ~҄&A-m379ZgiFt`DU/lmqZV>?,fꣴF|n;بq ܏CZ@ @ @I:p?i~z׷YJeYZпN["8@ڨzqmo' õּ#oONywXg22QQ)%LT+Q> z2ժ,o,EuTrZ=@F y27D#pIom[t79Zgi/i1Zrn&kb>Jkn/ƌp1'ÕQ!@ @ #pO;#O*砯 ZUNX]P(R]:cgԉEgOq  } 6D: h&{kenn Rק?w@>#Dh6*p~\8xZƊ\y*ySQ?*Ҽ.M|[Doz]?,fWorvӰ_cܘM>NkjL}ֈZ_܍~c 'c O+B @ @G9cwFU6lC+ɫCc6^B\; g֋=w6g:W*KT^Muڼƃ2Ƃxx2Pl&;-SG~B )޶5~՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ p$A4tp?!&􎅸6k̸$E6]rmIz&917Kroے'9uZ_V$ӟꜼ}dk]kRZVߒ ό?qw̭ܕ( e|pB=i`4) !7 mmrYT_m:O6BF#|97flڵa1S5{wcGF~ZB @ @'p?MINӽݜnLXkӻI͌kKRd5.זtgAw 9:6 gc%ۗ>%3Һߣa[ݤnL>En.\fcϩ7+ҽ!5@` o"za1zۨuvݍZFU/lmqZV>?,fꣴF|n[8~2\ @ @=o434⣙G þsmy;rm9?޹o֪&kY,eg.g㣧?,LnoO#Y)W.IicMj[292-I-K!WL&{`nL@O"pIom[Mn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8l OpGvfzB\޵Mjf\["qk= ]k }9=y.O NJq`XrrPNo5lKV nBKפo'#lA.{JGbr =o C~ ۶^/՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ p$A4tp?!&􎅸6k̸$E6]rmIz&9ݣJ^Y{]q%?6zRL|{oHUWŻK!_1?RlQG&e0лmX{Go&A-mԮ3WorvӰ:F:_΍~;v}~XGiޭݘwQtA @ @ gt~҄=>to7g4;mR3ڒt˵%]lwlnWeY*/SPLФe;uO XƢ,d<'Crj|V2;9I^$w\FD CN~ ۶^e79ZgiFt`DU/lmqZV>?,fꣴF|n;بq ܏CZ@ @ @I:p?i~׷C\M qmz6qmIlڒLr6#5u:m%ʲ~B;3yɩ7\]Dn/#cSRT7'T+UնE@@$ȷE~X0՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ p$A4tp?!&􎅸6k̸$E6]rmIz&9Iޔuzg? ddjL#үzS;uvGKys][UslpRND$r,zp~ D!pIom[t79ZgiFt`DU/lmqZV>?,fꣴF|n;بq ܏CZ@ @ @I:p?i~׷C\M qmz6qmIlڒLr6 @IDAT4fI>-yraI95>?|VM7o]{C>Srz\pSi4!J~ ۶^>՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ p$A4tp?!&􎅸6k̸$E6]rmIz&9I|l}/m,Ȃ:^bMɱ2_CVekCV+2~OޖL_Fr&d0.ÅQ>&8%pIom[JMn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8l OpGvfzB\޵Mjf\["qk= $醏}yctM;J$?N,NK^u#-YX MzP~H~#b!0޶~X̬6jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ @& {|^nqm7iw,ĵ]ۤfƵ%)kK3 OnU?+˪]:yR.(>~({]_OHaL H6U7 h/3!<޶¹~X,6jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ @& {|^nqm7iw,ĵ]ۤfƵ%)kK3 OniKE[+/rf:yF'e W[ܜUIys]JrkTjN!0!E~ ۶^3՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ p$A4tp?!&􎅸6k̸$E6]rmIz&9Im=[Rݮ_-ɡ)95~Vh=HlI r%ucL  ܏"@` o"z֫a1zۨuvm@F1Zrn&kb>Jkn/ƌp 8 @ @ N~83&{}9;ĵݤޱצwmזȦk\-Z$gp?In]i7NM2G2x|H>_>%3col&%YX9ܕcgdJ?RLE{!܏Ɖ*@` o"z֋a1zۨuvr.QhU˹1og|֮ն(߻3>aw˓ @ @ %pO;#O*>9 }4 =+??זG0#זøjw]zp=rCI:YewDK䢽ܔk BiN*~R LN.xq _޶"~X,6jݧa!z#ЁuVuviZmҚon/ƌp 8 @ @ N~83&{}9;ĵݤޱצwmזȦk\-Z$gp?IVY N_XVI dx`TT)Ła%|{jeYng)*akp?62:@@~ ۶^U՛F4ujtmQhU˹1og|֮ն(߻3>K@ WF @ @z[s#hN4}7 D?j!pߐmGqm;B5ĵ샸%֛\[zs;5N=>5Y,/n%euGSɱ ~pI޾dr214)a}YߐJUOȫ'z&A-m1\?,f66jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ @& {|^nqm7iw,ĵ]ۤfƵ%)kK3 OުoIukCKE_S~>ӯN#gbN]֪+XZS c2~aTo{F# pIom[̪Mn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8l OpGvfzB\޵Mjf\["qk= $vol-ܿ4KYXĸӓOK/+;u%ؿ-oȵKR?N۟Rf Z@ @$ȷEbf}&gQ> cܘM>NkjL}ֈZ_܍~5NqhQ @ @ @ p6Ig'M8#OvsvkI3c!M&53-IM׸\[ҵI~t7>mE孒T294#òb;QuhaB~er]  o"z+a1Zzۨuvm@F1Zrn&kb>Jkn/ƌp 8 @ @ N~83&{}9;ĵݤޱצwmזȦk\-Z$gp?I{C ʋtrc:URFXgwGg'HXp? t&A-mMbf|&gQ> cܘM>NkjL}ֈZ_܍~5NqhQ @ @ @ p6Ig'M8#OvsvkI3c!M&53-IM׸\[ҵI~t?v}.}-/mO %ۗ'A!.@$ȷE~X̬6jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ @& {|^nqm7iw,ĵ]ۤfƵ%)kK3 OnrcE*+RUd\?/&jdep@K7 mmkڮ3+79ZgiFt`DU/lmqZV>?,fꣴF|n;بq ܏CZ@ @ @I:p?i~׷C\M qmz6qmIlڒLr6~e%B[FG~ ۶a18zۨuvm@F1Zrn&kb>Jkn/ƌp 8 @ @ N0 @,--9Y_/6s9q|>'dW3ާ^yytSEYY]ld||,sѦ~QQ(QF~.ĵ.|ĵ>*ZҊ9Ck!Aێv Z@ @$ȷEbf}&gQ> Qn4ѪΗsc68]m3QZ#wk}q7f|-ޓΐ @ @ hI+;;u;'7nޒ{悅,S3OK/ bQ2_ZHT^Ky˷[A_r|(.]Q'5n"'җ^EGDQ!`?DqCHx @!ԒזxH~Fk [!*QIQp=޶R~X,6jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ 8L5{\v]._N֟R'ޏT2N/…rq9~ ~TN'W? _(_KM#O NעQ) A '7y?b{q#ڒLx\[h1 3< ޶5ku՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ pI/D%W$?l07~&+222"O=|᳜;Erj ns:GU5z睟ˏ_Wy r99q☌%ۜ1::*Q Jw2{-P>\[zo;1N^?&A-m3WorvӰ:F:_΍~;v}~XGiޭݘwQtA @ @ &ŋ?˰:UY9wLNNАwܸAqQo@onEqm+: ĵmT\[:-qfp?ޮE!pX o"za1zۨuv{}EU/lmqZV>?,fꣴF|nkGi@ @ @ &B^{/7kQ)ceeUC[^ U"~ŏ?ooW?!%Ja #&\.'@xn&p^8ĵl|Nq,SWqm}J?M|[Doz1]?,fWorvӰ:F:_΍~;v}~XGiޭݘwQtA @ @ &o#ߓ]^o|/~ _K/މZm[hgwGO}'_ѣ32>6*rYvwvM#Yy_NG] ܏2um8駅 @^kX R \[(0@ &pIom[jMn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8$ޖ|_PN7'kQ2;|˯?WO?iM}J'JVΟ?kDU~\>LqLq+&ݕw/oȅ).]{ʪ ukh&h@BakfBakfB5-}@k ;!*QIQp=޶R~X,6jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ 8L~Wgs>#Qe`?/W^o'ne„Νr )ԉA.ʛo#_]kćMj~o 0(7xնd-|^2 ZN^-/loׂ)lWB A>ѭ+}}O߼ NkK829 6~ɩ@'ӗQ?N0x&M|[Doz\?,fWorvӰآѪΗsc68]m3QZ#wk}q7f|-p? @ @ $r9}Uddd8XMu Ҋ|GoK/}QH J@ kJt?C_i#VTT*5| @ @ F_"7T"L~ ۶^A՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ pIy_Nĸ [:F:_΍~;v}~XGiޭݘu׶p  @ @"8L{O޽Tgx_[JU gf '%ᢗOf ?wdhp08m[rF/<|;6A@ @ @w o"zbfMn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8$ܯT*OֿtR Lpnpѣ3Sӓ26:*O*' wvvD\T}{߂舜8q\fϜgc @ @z&A-m!\?,f66jݧa!z#ЁuVuviZm[닻1#`p?-j!@ @ 8L]?W^N_\Zյ`r259)~P-|EMy4oNCMyg r]rJsب@ @ 6M|[Doz~Xl(_m:O6BF#|97flڵa1S5{wcGF~ZB @ @'pzZ_TT.KmNٯH.S) 5N_PR,SSR,yA/zIdxTOܒzJ9It}6S/@ @ @ o"z[bf;Mn}7QhU˹1og|֮ն(߻3>6j.Т @ @@8& @ @ @K~ ۶^$՛F4l#Do:0ѪΗsc68]m3QZ#wk}q7f|l8]ǡE- @ @ pِ @ @ &A-mb6jݧa!z#ЁuVuviZm[닻1#`p?-j!@{>9n+_LrssmVly$qw}o^kZ-'A3I1D?Fh˨N$88~4 @ O~>z @ @ !pJ㺐fy?Ⲩ_|NCcKemq^=)c_S<[/R}7eB~Zeh @ @ @ |6@ @ @(C~ ?u!Ͷl?eQJ=+*EǨvz/Sƾy_ oʞ6) @ @@>l @ @ P*A~,Bmˢ~9zW TQ/՗z_}UOlHYߔ=k m jS/ @ @ |@ @ @ UXDׅ4γ)Es* D_/k꡿Ljق2ﳾ){2 /C _@ @ @糡 @ @@> ig S/.TA^14P):F-T_C2U=γ"eg}S-7eNA_ @ @ gSҥKܹsnnرU ==Yŋ#koowcFvƍsmmVu  ݙ3gK^eThwuuV?;s;oK_̷ō2n{z6rtt;OXikksKQڍ3lj'u8lLgQ-!+tNv'tӦMu'N]7bԩ+ Wb#Iυ Cs;=ȝS4 viSBqxSinR}o(&y7N݀}Lt/мr )--~N{擼9EB{u==sNu{.W}Rof-z ?>cyE9ݟ-mOM/yCŌERmb4cnQ36 3}H1JdžC=\WZQO}H=ć!yŞ7\:hϩz^s[wȿϞmOݓ<~gc|dml;N8Ο`϶S~ԝ2Gbe$/9eѳmU(4Y< bx@*!`ϵeeA\m|j"luC2>V=ۧV_|NQJ=U UQ/՗z_}UOlHYߔ=k mBq'L@ @ @11Jŗ-[}V,_Z5{ݮ{LtE'Mr-pk_ƙDB!!|>c/ӧOsk׮vg>:$4uׯ]E5/p4Dw׿Əc%8mr)/PҥKI9'ɱc~)BJ νbE㍱񡘔ws=};o]7@ֻW=[ozu #Sv"iL<ͳiSXI %WܹNJ?),6' \cE~y7Nн ׯgݽv3{VkhN ȑ#beŊe>Vޓ^?܃4/.#hV-m4%khN9tG~И-&ֳd%~h[pZ@$˯oz~zՊ؅z40*V6}ErV l?Zf*z m$l  p@_%Eq]W9γH,SK<>ܣR}Y[ܮWeWT;A|MٳF?ܨs>: @ @ PnJ8rDʌ˯&O~XJ< ;@"J&N~VV\fr R!iQHh -=&WA+ҥbGo 2q_-3g[h[dQꥰʼnD;v^z͝;?%ɓ>NuVl |.j r lbi^z۶p-NΙV_Nq{ +ICG8ݸmkoB1*V$PT;~^)ߴ:Xb $~dE!SPG {R 4攽{9E1f¦^'.Z]o͚=shѐ}&^⼉Ǯ_z_Qdܮ Kc䜲IwS?[ʸoYW^nk`Y͜[$v{h um #}NZ~&ȧKXymR=oaȒFoܢh} hTv[9sϖ/_砲6k'=jǞӧθ?CE|r-<_ah-YeB ϶GwӇs;HQ5ާ9Eci^|g[-ּæٳW^`s?qw~:9DUuv~N3ރ3f{F7 /\W c}\Uζl!"R/.T(:F-T_C2U=γ"eg}S-7j뜏p !@ @ $p K}eX_ܝw BN8&[>~[ktw} PMP/M7^x%gY?qO=w!Y,Xk%FQJx?=>{SOݲ^. 닽P0j}^<)_PV;w8Q]rU2yZn-*VfVEle}dʔyQv??[o볞.f0/c"mtpImXRE~C6B||X+++ϟ<t_`ZL)z۹JBUW؂yUo"E6}=j+=kG=jnvv3/>{oubEd./F,5F>rgy)Es*uLJ{_/k꡿Ljق2ﳾ){uG_ @ @ @_Tn};`?dϾQı@,AG;wkLL'=cYmigOYfKn rӦ-~< gΜm|_f~N>;uuu@Ӣ7ltMtww-7z_w0y?Pn4-&ħ4$\hD@bO?VUHO+NLYLQ&j+*N:MĨXQ0ueV婿y1Wz SVLʶXQ,MJ$)ޟ|fY%◸߾-?! Qbe~SݶkJ|-3㱣-4F])m5AG-Ecٲ~Ŗ 8QuYHzݝ:t5hN3fSZYk6+.B!Lś6mh~0a_y=巿[}ŋ>>lĬ&?|2q4@}, β/^nYeY|߄}hG)#۵aQh޼96xQ͘[tW^y?*cv B"{Kn=wK?ی($pX ZD'?yEtQuń/i=u0a_tcݻ4?>C+nϪL??,Xo+Ŋ-:|/ZتC _sm%7w'Ь [ms~#͜9攅~~QgoߗZC 3enAv=Uemq;)sjճ}j{;jϩ%QtZ~-n׫2ezg E Y[h#n9~@tC @ @(H~AP 7 @$𹧷=܋^B$>{ϸ9sf[,ktˠ:iV% Xh_yv[c&̣ &T?/^1!VO;`ce?/^ӟ00ɱ'\]1p{ƲD~nzڴin.v-KD rePW+'M"!bES*C[VuϿhӵWÇXvݹs} iw bw' ak>PlWk!{ֵuU̱,WthC׳"v6w4짏YFܡq4HX?~ʼn2kТŕ}6gR&\4ޣl>vX%7{֮]DXDX9g/+'OrfկpbE tƛ)S>[-7wdz &~=݇G '4cnCW(֖K'qcʕm]I>:,Om Cbo?#Fs˒%3[g=ͷ"Ohg;_ӧo =Sl當6?]k=bs|CڡE,:Y+Gu7ݰ +/sW[[sDo4qn ,NZLh XV5^Xю2E)3(I=vj. G 4kn'B-Z\$-m^o؎ j[m˾7}jW;[^_M*f-a!ΠgʼnWL-0AޡE@_g;m0=ճ~qo>8zf!QM뻯g݃N1z^|簿G=)VtOQgX-bgn-}F;wEϳgXY Shc 4>lm æhʼn#GسNp_Ryos?@h*A~,"mUH,S!z@R}Y[ܮWeWT;A|MٳF@9~ZB @ @'p?Mٞ_^J?5kV&&Vl$%]xᆵ^_J#AKgggېPEeuN M-7X&Q:dB-FMeb6o~_&d߹^~խ]ڋwQzŊ( VZnINJH*C"]MM7Ynea"={yĻv{/_Wq7Wy%KT߿㳅ي(V'Zܣ,jKI*MiH$mN9n/~sh:敵vg{^k1tx!DWtu"ŃbEb=E;v/bm~mY8|͘[§TL)J\xN/t,~GԩSIhNҽK#Oōʼ2q)G@}-+X9f׻oZ6z՜|߇p_77>d_m/׳Cg0p[x݇v$-&}(uHXB =*N/Z^$Qk_p?Ef^Hq"1v;SLAB 6QB(K~ ?uaͶlC_\ϩԃbhRtZ~-n׫2ezg E Y[h#o P˜p -|!@ @ @ϦlOJ~Wl㽘HkeV С#>dGg !@IDATVMP-Lζ?=|q(/ڎ1%-,R|Iyg~D2-]زOwӦNb`jM#'zܽ%rr$0up钉eu;i$'Zk4,\pʍ^?Yaeb"&o %V}1c4صjyڧկeܗYGN>cEӆv]uneZK89%=E?ƺ>C㴵@n֛͋/1<+B4/Z1b⭷5<?ol{'~p?mb٬EI+>S'D˖-|R=L6v7/eR}=_7{W^;>{%?7O更~ZY̓-˖.,ZCw̞? ~n'o)'\{G-b>E~(!%pJ㺰fyp R/.T_/lSJ1j]˔v-)>뛲gmpt;~9^xC @ @#p?Ly{q/atb7<ƎrMX-vJ𷿙|a g%=|(ä2*k<cYM0ZFveܹs϶-… |K7 cj ׿eޮ /8pMGeߪXLzss[fI{[^@;yd/SS óϭ;,L˄nbW_z{/R&kcĵ2ۉA|Cqde߱s&9e-!su@X<1stT~OVi_^ŵuv~j?̰k_?;}(Nr7Vf"wm~Zi}M̯ly8}K0#0sjK+9GK(>ޞyAq2ol#uӧM0#iFbq~I#=ZO >/,6}GC"6EqDD!-Ե? %Av JZp&M([Xi3/yEϵ+W.;isϿ=ێ0Ξ_O߇|b&E|l#{9St]uQl3~*VNYo bd@j"`sbotCӃЍ-N^zm#>?nz#e|NzOm {ϩԃbhRtZ~-n׫2ezg E Y[h#o P˜p -|!@ @ @ϦlOJ ao ܸn?t;u{}V;nG/+X壏>u.pYi-p~v/>9zOݞ<˦>}4tܸn/TI'''݆7tZ[֋TǹsLhròo"ԛi]w-ZxmGu%`R)+>m۾Eggew )ϛnz 7vXޞzIl#D %Rj]/ʬ3}?l*iS_2c +ڽ!{hzDSlabE}eyb }kӾĵ<(Nv'cLChPxM2yw7r~rGbgq8|#9(+vh)ѣl1ݣg n-;-*Rln3MS_>k200wz=|Xѳ!ӂϷ= 3%~xckNQ9-N=r;`jvpZ?vӢD-~kZHh-kw۞YOG0uPhAbEg슗CGҭ4# !*},v-F?eQJ]pcKemq^=)c_S<[/R}7eBp @ @@A *"|dا*;~>+D+H]c||)*ʆ{'N z|Fv O42FꐠE2Q>#weT6~S,_.<'-nŊeKd/VHxbeMh[>V/aŀt ^zJZ_B4IH̶{vjuRq+q #K %ݽgSXm}8q̮2U9e+sƍB& i+2iNYh} t4Z'"yW_c6S4_(NƎcE; i^yo|ǐ#a=~;?+J>mx~'?F#5)s]{|iqXre;݅v;HT;v esvY]~am#5[{[:O] M_N5o(V6P٦9Txp_5k1%.X` '=(3v~w-|{\Ew;Ŋيɮ]{}wc^C+6{?s϶!c#G`~/?z֙n.[lvf[qSv_֮]RFzUL69 \ln!9uydy0Z?eQJ]EǨvz/Sƾy_ oʞ6FmD7 @ @ U-%Dؾ}{}FrneN5OH27iYE%pI 핽>tӖrWʜtHl)/dS6A4)e '|ɲw-ʕ]ȔG-8w{KXu߭bEq;{6! Wh_e>zot.'&5nogXU"4] 6mwH 9| n=uׯBzΉ'~]~|Lu{hok<ľGH^P:>+zQ(N\9elN`}zmA7i$Wat@j&`qc}\Gg C_\ϩԇJJ1j]˔v-)>뛲gmpP-~ @ @ PZt=Itlp=zHd ,^䅕 ([o~}5Wvn2eβj'[fIjN+8QvQJ!̙^Kȍi.\8~o ޴ S:,VZ,;{|H #%LaykXP4įdX![}e?o[jfo+~n9e˖?BYCO&IJ=kp4@v eXs[1a„` kyEYvy?u 犕= |,Q-M*!KBnpx$[ x!1qϟ?.huvlƌiwvq>fg?#J`e \c_J[t fDA1_l+wםy"zo e}Hy݋4?0m%}Hu;Hg7=gbsJW-^П'-C9Rbu E@|1 F6v[oU *A~,v-I?eQJ]EǨvz/Sƾy_ oʞ6FmD7 @ @ U-%DV">g!^eNVZbɖoQ~O?c^h+7-φܖᇷ&{߲+8&zM$'W({U&wО2qD+Xvj'vqX^rm>N-\nf7g,+~^Os wqaߙCٱ5WHP=$c9#5J`$o=t; EdO =^p+ѮvvXm]ȑM[{M[H;kL柛oM +^7RsvqbC =6_cܬGŊ5h6#2kіA-=A~l@sfv]wͦg)Nۜ ʼnv=vj#-m p/EZܪXy{Oś3j~g͛?+| J~ ?u]l;B%Ⲩ_|N IpR}Y[ܮWeWT;A|MٳF_8<sD7΂ @ @ %p?KDjYg8@D+ݱcǼ(e@YJBѣ`_%䗀vӦ-^䢬L&m&Uv<T`,W~ž:ȸj e%^ %JD+YNcFq:u p+XgVl߶5QSK˨_+;}VZi4 $S+ZX9m"%e֜ n-q̙ӽ8[b~-bE}6lK44[h,[Եk|1" or\ju'C)ʀ9E(VtѼ{6mehXٳgo{ʦc ~ '0sG[ʢElg瀉5^4vX%-R;cFC~cǺ 7?yţi?#5hNСE1pv9rɀnV H=vZгltx j2 >R}}O=A!ݗtqnEw݇Wd}H5:u)gΞ <4/(V4L>gW:RR~F@Z b@~'kÇyE- Bv=OsbOm6y* p@_%ȏEq]?γPI,SBR*\):F-T_C2U=γ"eg}S-7ƍ @ @ d  @ @ @1> ng "Ⲩ_|NCcKemq^=)c_S<[/R}7eB~Zeh @ @ @ |6@ @ @(C~ ?u!Ͷl?eQJ=+*EǨvz/Sƾy_ oʞ6) @ @@>l @ @ P*A~,Bmˢ~9zW TQ/՗z_}UOlHYߔ=k m jS/ @ @ |@ @ @ UXDׅ4γ)Es* D_/k꡿Ljق2ﳾ){2 /C _@ @ @糡 @ @@> ig S/.TA^14P):F-T_C2U=γ"eg}S-7eNA_ @ @ gC @ @ 2W c}\l;C_\ϩԃbhRtZ~-n׫2ezg E Y[h#o P˜p -|!@ @ @φ@ @ @e ܯ".v-O,S!z@R}Y[ܮWeWT;A|MٳF@9~ZB @ @'p? = @ @@_%ȏEq]H<[}qY/>RB􊡁J1j]˔v-)>뛲gmp@-s 2 @ @ O~>z @ @ !pJ㺐fy?Ⲩ_|NCcKemq^=)c_S<[/R}7eB~Zeh @ @ @ |6@ @ @(C~ ?u!Ͷl?eQJ=+*EǨvz/Sƾy_ oʞ6) @ @@>l @ @ P*A~,Bmˢ~9zW TQ/՗z_}UOlHYߔ=k m jS/ @ @ |@ @ @ UXDׅ4γ)Es* D_/k꡿Ljق2ﳾ){2 /C _@ @ @糡 @ @@> ig S/.TA^14P):F-T_C2U=γ"eg}S-7eNA_ @ @ gC @ @ 2W c}\l;C_\ϩԃbhRtZ~-n׫2ezg E Y[h#o P˜p -|!@ @ @φ@ @ @e ܯ".v-O,S!z@R}Y[ܮWeWT;A|MٳF@9~ZB @ @'p? = @ @@_%ȏEq]H<[}qY/>RB􊡁J1j]˔v-)>뛲gmp@-s 2 @ @ O~>z @ @ !pJ㺐fy?Ⲩ_|NCcKemq^=)c_S<[/R}7eB~Zeh @ @ @ |6@ @ @(C~ ?u!Ͷl?eQJ=+*EǨvz/Sƾy_ oʞ6) @ @@>l @ @ P*A~,Bmˢ~9zW TQ/՗z_}UOlHYߔ=k m jS/ @ @ |@ @ @ UXDׅ4γ)Es* D_/k꡿Ljق2ﳾ){2 /C _@ @ @糡 @ @@> ig S/.TA^14P):F-T_C2U=γ"eg}S-7eNA_ @ @ gC @ @ 2W c}\l;C_\ϩԃbhRtZ~-n׫2ezg E Y[h#o P˜p -|!@ @ @φ@ @ @e ܯ".v-O,S!z@R}Y[ܮWeWT;A|MٳF@9~ZB @ @'p? = @ @@_%ȏEq]H<[}qY/>RB􊡁J1j]˔v-)>뛲gmp@-s 2 @ @ O~>z @ Kn˩wv0Ϝ1n8I}8 4ދЅՔϔ." p%@_%ȏEq]8γpH,S_YR}Y[ܮWeWT;A|MٳF_ ᑩ  @ @ \{_{לO @ k3@3;ܷv^HDӓDLzrm8 +*A~,v-D?eQJ=+*EǨvz/Sƾy_ oʞ6) @ @@>l @>-}xE7IJ+&uۯ' l8׍ivr_ᖌo߼A@6UXD1γ)Es* D_/k꡿Ljق2ﳾ){2 /C _@ @ @糡 @!0` !-V˨QtotLn rdf6S ?;5\tf=-nc؉C 64K6[GK^,o'VcuOꯕ|a+P/`WE*-=ƹjAcBC|6*uK:C%]+]7Z_&Š5_{Ks~:z9Mϫ|/X"is}^OeџFPe(bX>zOO3hci'ߧu>}O{Xc=ctN[mt\i3\b6ˈbI~rhwǙw-$TǛzV7X5uv2&yDٟpZεk;{Z!U>@e(qދ\nnj;HXj;G>mjHE;Ly|wIs&l9vLnswNU=Sl97Q]w ]n\eoBy3]O ;~ÔvMo_wYEg:h.3M`}hk*Fa_zšc[Ssd@_yhܢyD"}qբ+ sw#K''$7ҮJ}8 +*Apuٲ<[-Sf}rۗIR}Y[ܮWeWT;R-@y82  @ @  @ p%WW٩%Dv_O VY%be&]c|:v;{ &mqwMoY3w+H `W?;z}|롌:BN㫬U(=iG1VYc&:O $4G9w/-g]S[g|Hl8h@ $ܿ> pe@_%Ї.e\%γ }q7Y)yG1j]˔v-)>뛲gmpa[{ @ @ @(EI@ |rel_i"LpDŽ❦|PV%Uw lNw uhߚw_ߜ$f_?G4nײI|e翚r2Kl{L,vlC5:`&_dBM /.Z(> %LgVϪ1$p؋2aS[ X11?`lL.!~yB|X>N4x^^^2,8тMre\T/ZءF)Q_fH_7'gz=?g[jtD{M/ZޓJCs<-s(@ +Z{gwl>l<Ɯk " ܯ"kmBC_\ϩ/[tZ~-n׫2ezg EJ=R-WBxd*G+B @ @5C @J$Y&PD-2ux qq\"L|Vu\Ųa i%υJoyo%xg6gu\ QwhLy6~]+e ZǧQ}]I&R^f#3ʈ.T9xZ;:p-H[|[qeg?nL^8gw[01ʏl-ݻ\;Ikl/2K4EoLjG%lEWeaA g$dWM0Jk1G}-LPI]{=kKv8h{K6 ūv7G 嫬ʪ/~1G4zj ͵6ٟv6 oܵî } pE@_%m%q]l;ϖw~gԸY,E:Q/՗z_}UOlHYߔ=k mE"s>S!@ @ DG0B @\5n?d{eАHe%|%ʕYXap~, ;cݿk;_1q,|>r֮=&H>cM\pMiv !v3`[L@C"l7|վVK^bsˢVNlu0!; B* -x6ѹÃ..ᾲ?eﴬZKz/َ zO~0֙x_b>E KpE P|m!$KGwzoB=ųHcaw{f mA ߝۮYf}-7~]gm >̴y]^,Rɿ ܯlW9⺌v- }qY/>ROEǨvz/Sƾy_ oʞ6JLpeT@ @ @#pڻ|b@ \|_Ȕoo&}D6Dmo;hK :8y}eWm}ڄOYY5~<ΕȰ{|Y>CʞcbH{M(-z-U"s"u\}W c}\ׅ϶l!HR/.TA^14P):F-T_C2U=γ"eg}S-7eNA_ @ @ gC @ C O\p^rsz{;L2: >m}+{X lz.e>mb%fHZ-T˺h CZanNڟj,Kbʿڮa*tMu-cDE0Xea''l]{O'}(KN3Z\(Kx{[dޱ+ͦz/h8SWe{bJHxv]8sE̲- ⓡe%A⮌ZLq{3b׀@ ܯ"˒m%L,SkQtZ~-n׫2ezg E Y[h#n9~@tC @ @(H~APA @_* %Ց7ijdStM|քR),_/$T~ L5tElt L,}Q+{D@"6 oخsMƄߌѣtwȽ2K.%XkgM ?3}idvuSlV8 |'Z Wvc~[@p {R*?99>j "_8瞴E鏷kUzR}olWwx@_%ȏEq]mBC_\ϩ/ǣF1j]˔v-)>뛲gmp#SA?2\ @ @ ܿ9 @W"<}QA9bW}:g~M-A8&_8;Ke}?owM=}t[1յ:߲K3̧mn1[" ۖq_S+k:{ %7 /zqDvΙhE(ʸ 'mQ`13`A 8th D1em%WDZr|}XiASP꽵4e_n)ѽ2+_9ۂ 略{[i L+ӥ.`:T;&x!Kߢ~ɳ%QtZ~-n׫2ezg E Y[h#n9~@tC @ @(H~APA @_*}M}>0a7s[i&Uw _71@.}&B2Gc+6ZcK7Η c_}ߜCX|n_qv4ȋy{Kjkv|CgY%&W|Jɸ6{v0ٮ\k,>} pE@_%8d\%γ }q7Yx|G1j]˔v-)>뛲gmpQ[|u @ @ @ A@ |\ٴLkzoZc]%6P;..Gcq42zK,,n8_*|<>E9+xA \ZjTۥ(V-x +%۩ϯ3G.@IDATcWaaWJ-Fʚ/1K )VOԧi"&z?j'&u}b[(13i%WhцngsXlovDˮ1 XD]壸ܡ]tż4?5iR Pt䍓.pShgx޴H2 Sex6e˶ly{Lm_ٷR}Y[ܮWeWT;vcg}S-@y82  @ @  @ @'(vpew?hY۔Ҷ6n43ZݍS 'pJfypR/.T(:F-T_C2U=γ"eg}S-7j뜏p !@ @ $p ( @ @W0&?36@^)2VOlssǶc$ W c}\l;.A?eQJ]EǨvz/Sƾy_ oʞ6FmD7 @ @  @ @ &w;?plh߹h3hOjqǴqRs@@i>kg Ⲩ_|N~9~EǨvz/Sƾy_ oʞ6JLpeT@ @ @#pڻ|b@ @ @`d ܯ".v-\ˢ~9zW TQ/՗z_}UOlHYߔ=k m jS/ @ @ |@ @ @ UXDׅ4γ)Es* D_/k꡿Ljق2ﳾ){2 /C _@ @ @糡 @ @@> ig S/.TA^14P):F-T_C2U=γ"eg}S-7eNA_ @ @ gC @ @ 2W c}\l;C_\ϩԃbhRtZ~-n׫2ezg E Y[h#o P˜p -|!@ @ @φ@ @ @e ܯ".v-O,S!z@R}Y[ܮWeWT;A|MٳF@9~ZB @ @'p? = @ @@_%ȏEq]H<[}qY/>RB􊡁J1j]˔v-)>뛲gmp@-s 2 @ @ O~>z @ @ !pJ㺐fy?Ⲩ_|NCcKemq^=)c_S<[/R}7eB~Zeh @ @ @ |6@ @ @(C~ ?u!Ͷl?eQJ=+*EǨvz/Sƾy_ oʞ6) @ @@>l @ @ P*A~,Bmˢ~9zW TQ/՗z_}UOlHYߔ=k m jS/ @ @ |@ @ @ UXDׅ4γ)Es* D_/k꡿Ljق2ﳾ){2 /C _@ @ @糡 @ @@> ig S/.TA^14P):F-T_C2U=γ"eg}S-7eNA_ @ @ gC @ @ 2W c}\l;C_\ϩԃbhRtZ~-n׫2ezg E Y[h#o P˜p -|!@ @ @φ@ @ @e ܯ".v-O,S!z@R}Y[ܮWeWT;A|MٳF@9~ZB @ @'p? = @ @@_%ȏEq]H<[}qY/>RB􊡁J1j]˔v-)>뛲gmp@-s 2 @ @ O~>z @ @ !pJ㺐fy?Ⲩ_|NCcKemq^=)c_S<[/R}7eB~Zeh @ @ @ |69s۹kp wV6;zܿ~nw)wJNݨJKK&L&O:;;Vy=@ kK=t'Or_p}}}nj&N&NYMVw{snnرUY;s]]kkt&MrSLeNNˍ=|'ǙmTykgw~s1dǎY>Tp ѣܹsyq)'a!6]M2uwrܹs^[S*)b!L\ӧxR[[|Ǎ1֚q}g;E3b^5}_7kkO߇ ĉgt'x9??4h0q4i4yٸayGmVuH'ȟ @G@bq?~y~>UTJ,ܻWO3|栃F8+? ?|ʌFѧ2,\ȉq%ҥ9@sLS:qMKtݺv1y霆lEY,]j&1s?Uъuy~}ȃ4}Ƈ<K/9s9ʗhC16K>rtqZ{r /Xrz {i `ܻXNx鯸^ۢK%h:r6Lum6 ^6Ͽۀnha7Hñ׷ی )k^L>æ]g|a`1fxq̱vZ'n=>|sȃ_ vC?m{Y-Zl%mbw#eM~ARY1>p؛ ܯ߇"y>R>E17Y.Rk>^ sey>_87}O+ں '»h<g  @ @DYSN7_L'[3>m_̓O=^A^0-F׹JPE 8zn:}]˝CY!@ `ا@-V?o|W)?IW^cm:tnmĦ*zeˌ<󜫢ɳ4C rc4O:͉Ua_fUWU6&A>/JSgyU"g}LsYY>Ckb>?Zrz q\mo߿n)!ܹ̬YsBOLPZsjE)S9oٺHlа1aޫzT{t>i bڞ $(Xm/^m`w][kaD@' gޣG7w}k?;npUVnm [luX#xim}l'f sUס~Wns/N…5,1~ck]|D6mڸ'tմ0j߯Emh{pw+f+>D~/TmѼpLfw9b/ײ}LN|>Hqn|~wppeV@ @ @`#p]M?p`'M[] @x ė'J7n2+NCG}Uo޽1t9Ν;UЗ(+B^l7|n uH?kl+^ǽX3l~Bv'~g\qU5;x1Q{^:' G8 Q \ا,ZqWuu&p_;vݕUٟgϞgM QF ̙S^vO*y*c&{#qk a%s uׯsq!ѻւs]\S ܀]?z2JrPTژO}+mNҘq[t"#?mlio7Hz)P}ml b!6v<]=wu%&mxQ#84R+EA^=ca[4/^90Q-/}ae0WvEZ/sSXe /C\@ @ @iL ;X˧m2su#U7ofbnVѯ_[qq ][QGCCiU)'vmۚc+ዪ5-\dVYQV6mV[lg:wd!WMS5>bJ0< 4j @x (cO϶P:^{m!OwBg a N"YOZdF7c` 3Ͼ`Em}~,O[n?sYzf;u}}vgϞD ]yQvyN/W|Uv0t *XQF?D}-#56z=jƌ=\b9 %!!oW?:'=Au+OO_2ei7^fK4}Տ^"wOsIXbifȃF85IH㭐STOٍ$8Ugϱ{Тu>q$Cp_۬(=y9Q[.8$_k嗧q?~o:"<]1ӆzb >'u7 ]O#Xx{h9K.}"AZum{Bcރ<|NpWC}hU99>yxU[E稖ž_2m+;"ǹ)}]5#ܯ0 @ @ U2 Uecg?fxjj* }| -$UBaںei}68Œ:dgҥŗƹ+Vt‚͛V/qK/5,uŒ޽{YǽeW-P}ɴhm$_8 @ usЈFO`+kcZ{_G?Vm]qwqW%xmR޴yx!TWW6i Z ܡ.fkCUǎw1A%nZX!kSU49{3OO6hbϿ黡#6s{%nN=$mڴnc7lpY%J=3?v9c<L>3nwmRσǟxrwgE/'4=!G5kO9/ʑkvVp\v=m8m[bafѼpLfߌZ^*~-˴aT?^|gKxwWf @ @>w= 6#8I U޽#5k]uI .ڵkk֬"%[UVNT*|V7ƨ>ĉleW864+^Z`YbfoW| hLNi^S͚59P @}?dn6sGN4{.=JUcXJ,7|ສB v9xAfР.O[UFZ%,4)*̇zzks`+yuG:>]/7j,YbNIfA{Ks=஻1׬qnw9*t"V-[YU[E%xfZji_wY~.:vt+h.̯pn{^]lU۝.xwU?Ůw]ʁ#sw7Yq;}OOkR_1m:A{򔩮"־-'wc }hйs';[1s{r ?yYOkgIWDsOAlgϙ/%2ZڠCOh{M ] }(mǸ^ sey>_87}px5 @ @ P"ܷVw"-Vh GcwVoUSu/ZUpGfĈ`HI<3qdN Lk+jnEثWO'~q>[Am]lľ"hNi"6+Xb?+e*K!+ȑ@j_[+W>2*s@ @`g_7N7Q/ צV %os>ӜP@4,̶a}U"MwUm\* %8צA[~F"V$ +ד$sҿv}'rBhGϫptkî*еOO2>dȠҲ\po7ϵ6>g<7@[ %1W~}lC>檐5z2H,Ku^t," X_,;ĮkAUs/vyבG8Nݿ?V'-[mw8ma*x{;ꐃ}u7~=Գn}~bvCm`{)S̹|ܜt.y~:\~{yww}ȣ~nwhC̎|r9!@@_!E-Vq?Xئ U ~sTKb_دex6̕|~֋ܔ?> ߡ8  @ @؋ )-[ fc7hѴibӬI3'/;K߶m[s*KJCf+G ߦ͛~^H?ak>}'-i}s1GUob(Kq2/< ?i#v%UST} 4ZAͫ :W+9s^/ @(J@rP;Oݴz3K  ל:O{3&3X}}TOӡC{'g9joO̘1~^k}=)@Uϱbf}]'ܷ̗,]y}U*_n>pҤ)vW+ͨQ'|=nwN/y/%\&3fbID.Qİpd?|M p_]}qvhFp@+fH㬐ɧ1ا ; z۵vc6qK/1)̙֛- [S(G]9f}ٟ8ýO׮p!emP ^u_?7,x3n|w}Z?7m};N"s>6+/iC[~otmj0^ՖxG9b/ײ}LN|>Hqn|~cWmk" @ @ @ =Efj`|fNPA2u6]>]M}&s9p+Bie}5gh `Hs)oUN0?T*S,}8!_o xiG2G^tӭÇ3g2MSO9 kU4b @hUӿ[ghTOұi&G7wOq+zy{ᯪx> G~YgΚcLf&Ob?3SO6z׭7wOY"swCOeV?^D(^ۢE*:ȕ:$[c%≧fr6F;K}ذw5fϰA&Y-p}T)^ܻwKyM={LW{Ľc%}?~ny˖۾nެwa7.dֺ sw%d]RJ`Ϻ'I Mf^[6rk7pn g?w|=}:Bvm&.{qGO?}OM׮~~^^v\̵MƗڧ4km4h>= BOMsGpy}9/@M+>,ljhӨϘ}[nfXσA}WN7VR)*vz]M֮2*͚555{tsU92Gn'ܿ[3Nasah 1 /j{PG fOB8nn+Ym>yfHʚi @؎IPϿ;N~ֱv:|rYȣӭ[Ou fN:miƉ*}>0Ws]MmuʹzUy=b7LOC9i2W}Xhj>_] :qM oܸ %޴iޯqOgSq6mZ&M:/A1cI6ksOXC_}<ínV/>r"/gn lhݮ{H(/z{iR6^̛?Uצ>UN}nǟx<`׽6b~ !\Ow}iw6aOu^Kc=|{ޕ:]֧/4s̘ͺ#t q;m(Z n#}z91@_̆ m1y>7ca[4/E稖ž_2m+;"ǹ)}]5#ܯ0 @ @ |+ؿfY2cxAɴ}Zk:Ōs9b{9՜^?߈ÜO^d7'pBBS1VСl+ ߉VڵkgBkF>Ui?Ԋ}ǝCZLs?a\ofX[⚁8.[9>cfS\5jF  @!'N=hӧw/ӷOo3VVk-6ӦMws{̡v"{%8>O=>7~ѽ(볳6>3yUZuKͱN{żj?;YsV3]UVݠ0oz>=LMkc77khsCS[a\#t_=KiN;K,um~y).>>ѫ{ _0!s3O>=c6뻐փifΚKߥw_3ut%ݫ{A~}ܩXqcM#֕6F44lvk]+{}J6no zzX{M+VO3m7PL]tvk[0Jz\&<ɉ5;8ԍphϸqܚ*^uOYG,|nw?Ta_k}=9؍E߃/I~ ?чnn-l{Z^*~-˴aT?^|7vp  @ @ Ss_ep?WOkݢк9ATONDp8h@}U<'J\.@ X?a˶reTonx;s"ޖʕ…я?Ku[n<&Mff6;K'?G[:V^kDdqM;yfN{ٿ?{?$⁇1]M,zzth隋}Yܛ6ma#(HO+£ki~'-}v!|)l@`7"pBC[w4OX d=Q-/}ae0WvEZ/sSjkG_a@ @ @ )Gk,io^o tZVMvVsHwx0Bx;aP[[_ulڴɉQ$QŽŋj r*~/MK@1VUeVWuRi3,n^KOR[rI  ]k=> 8[JB$Z1cۜݧoon`wn}GTu>gY6H~(]r0濟zᾪϞ=̞3, SS9x_OOw@Pu{m$)^^k>uzZseϚ!JyXxaۯX{\ _= ܯ"͌y>S>E1]>s2Q-/}ae0WvEZ/sSdw 'n. @ @ @SWf^?۬ްUbK8TmWfpKܖ:c,sosNqN8Vן$XEE9 W_)Ss;ACTي%4jc:t0Æg]͋/5SmUҥ6&ᇄ}c.kYgD[l~Uܥx OHU,}  @@:M4/ͩ/vb} [n󮪯 S,Ѳݧl5P5vܟ݆W娂Dcg'ԫZ u'[}qUlzD:/mաJݺv5#G0Yq?H̵Aקl _:?r䁦k;v*a'c}*؋/uh j#F`:$,ʕz"/!6宍cz?ĽVsB߅tBaw:t7VzךRxzrkSO]k}!Ær0f8s+k>@)q?hK7nOxɌ?}O}P\ h7S}1enn x< yϤ#^ sey>_87}pZf2ȅ @ @ O`Oߴ,]جݸl"AH5h´ii۪i׺U%t9NH߯oWr믻*6nrФiWQ_U%dUuQ"UPlnE,xb*[KS+^iѢHTl2/8H K `I S/_(`V ;wvU5m]"ȁ @@Jl/1bmD\=JU%\Uu9svt U}@~sIJ^k볰>[Ok>K+_<ΞNCrIwGAm ![Om[]קAFUuh  AM\n]mWYlݢjZXwu/]%h_v;/V;g+>jirw1{1Kn ,tPU|w>J6ć~utRw^tu7mm}}T%:{{Yqwmq}ϛ'u'&y]z-,s6g7C[VFR>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O`O_!@ @ @o PDںq?o\*¶h^8&=saZ^*~-˴aT?^|ױP A_ @ @ gC @ @@+>4Mc#ܯcp -r!@ @ @φ @ @ 2WC}h iy| ۢyBQQtjyX l/ӆSG_B-3~ZB @ @'p? @ @ @e ܯ"ҸS>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O~>" @ @@_!E-q?},lc2 3GF9b/ײ}LN|>Hqn|~ eh @ @ @ |6D @ @ !pBC[H~OX dg:sTKb_دex6̕|~֋ܔ?>:j!" @ @@>l@ @ @(C~ ?ч<ǟ-l/DuE稖ž_2m+;"ǹ)}u,2CE. @ @ | @ @ P A~(m!y>?ca[4/^90Q-/}ae0WvEZ/sSXe /C\@ @ @!@ @ @ PDB|*¶h^8&=saZ^*~-˴aT?^|ױP A_ @ @ gC @ @@+>4Mc#ܯcp -r!@{@IDAT @ @φ @ @ 2WC}h iy| ۢyBQQtjyX l/ӆSG_B-3~ZB @ @'p? @ @ @e ܯ"ҸS>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O~>" @ @@_!E-q?},lc2 3GF9b/ײ}LN|>Hqn|~ eh @ @ @ |6D @ @ !pBC[H~OX dg:sTKb_دex6̕|~֋ܔ?>:j!" @ @@>l@ @ @(C~ ?ч<ǟ-l/DuE稖ž_2m+;"ǹ)}u,2CE. @ @ | @ @ P A~(m!y>?ca[4/^90Q-/}ae0WvEZ/sSXe /C\@ @ @!@ @ @ PDB|*¶h^8&=saZ^*~-˴aT?^|ױP A_ @ @ l֭[cU  @ @m q; A~(mяy>R>E1#~]tjyX l/ӆSG-c 9\ @ @l-_#W @ @M@}I-9 @_!E-Tq?'THUz#~Z^*~-˴aT?^|'s"q,  @ @ػ l-Nߴ~@ @ زe7m}{u4 }(my>SR>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O`g 7nKO@ @ .|myf˩sWC}h>G_B-3~ZB @ @' FU5=6U?^@ @ ]6VΧ;X$ ܯ"_G*[E*G.:GT,Zi\٩~i>Mc#O.DX2 @ @ wG܍Uu8ᾕ @ @jVW@`PDڂ|},lSiVtjyX l/ӆSG_uY7>p  @ @l^cÆͮl@ _ڻ?W@{&M-Y@WC}hr;-l/DuE稖ž_2m+;"ǹ)}u,2CE. @ @ |op_N_aSI @k kn5 @{-Sm/\b9+>5 HX dg:sTKb_دex6̕|~֋ܔ?>:j!" @ @@>BWo o@ @h.x[I~ ?ч<| ۢyBQQtjyX l/ӆSG_B-3~ZB @ @'V uiSo?!" @{,D{ @`/"ФIӼYS*EK-G~ ?ч<| ۢyBQQtjyX l/ӆSG_B-3~ZB @ @'V Y~m3 @`W'hWC @ w\fMS"mW`<6| Լa-xcsTKb_دex6̕|~֋ܔ?>ƮD @ @@Aopੑ@ @ @`"pBC[4OX dg:sTKb_دex6̕|~֋ܔ?>:j!" @ @@>l@ @ @(C~ ?ч<ǟ-l/DuE稖ž_2m+;"ǹ)}u,2CE. @ @ | @ @ P A~(m!y>?ca[4/^90Q-/}ae0WvEZ/sSXe /C\@ @ @!@ @ @ PDB|*¶h^8&=saZ^*~-˴aT?^|ױP A_ @ @ gC @ @@+>4Mc#ܯcp -r!@ @ @φ @ @ 2WC}h iy| ۢyBQQtjyX l/ӆSG_B-3~ZB @ @'p? @ @ @e ܯ"ҸS>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O~>" @ @@_!E-q?},lc2 3GF9b/ײ}LN|>Hqn|~ eh @ @ @ |6D @ @ !pBC[H~OX dg:sTKb_دex6̕|~֋ܔ?>:j!" @ @@>l@ @ @(C~ ?ч<ǟ-l/DuE稖ž_2m+;"ǹ)}u,2CE. @ @ | @ @ P A~(m!y>?ca[4/^90Q-/}ae0WvEZ/sSXe /C\@ @ @!@ @ @ PDB|*¶h^8&=saZ^*~-˴aT?^|ױP A_ @ @ gC @ @@+>4Mc#ܯcp -r!@ @ @φ @ @ 2WC}h iy| ۢyBQQtjyX l/ӆSG_B-3~ZB @ @'p? @ @ @e ܯ"ҸS>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O~>" @ @@_!E-q?},lc2 3GF9b/ײ}LN|>Hqn|~ eh @ @ @ |6D @ @ !pBC[H~OX dg:sTKb_دex6̕|~֋ܔ?>:j!" @ @@>l@ @ @(C~ ?ч<ǟ-l/DuE稖ž_2m+;"ǹ)}u,2CE. @ @ | @ @ P A~(m!y>?ca[4/^90Q-/}ae0WvEZ/sSXe /C\@ @ @!@ @ @ PDB|*¶h^8&=saZ^*~-˴aT?^|ױP A_ @ @ gC @ @@+>4Mc#ܯcp -r!@ @ @φ @ @ 2WC}h iy| ۢyBQQtjyX l/ӆSG_B-3~ZB @ @'p? @ @ @e ܯ"ҸS>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O~>" @ @@_!E-q?},lc2 3GF9b/ײ}LN|>Hqn|~ eh @ @ @ |6D @ @ !pBC[H~OX dg:sTKb_دex6̕|~֋ܔ?>:j!" @ @@>l@"0o<`wnZjv @ @ P A~(mQy>R>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O~>Yv袋ʕ+[n?iD(~lݺ\uUfرlܸ71:t(>n9k,}tѬ_ޜx欳Mξ==>}z=~u]gڴic A^T)S~ӦMͯ~+3`O @ @oPDںq?]*¶h^8&%oQtjyX l/ӆSGU[c<C @ @(H/_ %Vv(~}CgϞRҘDWCU/r#Quc͚576mr4^B~Cu qI'~ǶG?2&Mrcſ;az衮d|%[#rr) @ @0PDںq?v*¶h^8&;KjZ^*~-˴aT?^|W]"olߥ @ @؅ ܯ"y>S>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O" >܉4ѯ߾#>E ~p_?;tݺu3/W @ @`#pBC[76"HX dg:sTKb_دex6̕|~֋ܔ?>:j!" @ @@>ZߪU+WM裏6͛7w'f*/\p`;o##ܯM?fppߓmhhp@ @ @_!E|},lc2 3GF9b/ײ}LN|>Hqn|~ eh @ @ @ [-י\zFhÆ FuZnm:uꔚ/f uY׮]s/ϰ}͵xl-thcI_rvNuhGfҤIc򓟸*.?9C}VLף={w=u !@ @^J^ҧk?Ug|T?WڗtžzpL5;CwTcc27֙QtjyX l/ӆSG_jOF_# @ @ x!;Eܱ=|ݱcǚK竮?aZ'*W~Ldo3~g/` O>dd篍on^Ws1zv2}a_ԴG޽\`^WGN-[פk'x"Ĉ??D|t|0Z)b>O뮻u]u?|dKV2r{m;< _m tn?|31-Zlͧ36mژs=h|(׵3j պoE38|uk塇RJvD&t-|0'xK̸qpWֽy$| l@ @ 'A E},lc2;,\(:GT,Zi\٩~i>Mc#/4OB_?;FB @ @ ]+UEqK$ߧOzw?~,7og$vhm'REˉ a~h/673橼~#H '`fΜiL̗󨣎2_*G1cƘg2k?!IV+mX0aB/qZ?{]a7-b~xn\°pŠ;Gyַ׵k:7X=BSG|>yC @ A~(m-K)ca[4/7(:GT,Zi\٩~i>Mc#o쪭1~ @!@ @ $ cq.#{APupU??sV󪊿(x,BGޚSG|m[9?/)}UFkxc[f͚^f92{5kָ 躊͛7w)1P(ohГǙgVࣚ~&`Zm|cCu8oV ~VR'4u1cFސ?>dN@ @ ?ч2~ϖ-mͺuE稖ž_2m+;"ǹ)}u-gE& @ @ jv5K_ٴi;m Ê^_S޽͇>!e'Fg?*ͫZO?]~q ޛ4ibNswWć {}]"o߾3_}<_ 0Cѵz|Eu]oF׷b bܸqnkSN1f2W_}uj'?Ij*fٲeYX_ 4(U3 6̜uY-b^xᅊi{,G̿o׏?xE\Մ~"UWjza{1s ݻ/#_~eW?=tkwv\{ 5__=\⦛nڎǎk~ӟf}z .=qbڴiuOt @ @CoPDʈy>?[*¶h^8&%oQtjyX l/ӆSGU[c<C @ @(H^iJ|%gy&sK )>9'a,\|_p}3Ψ=CFP{ uDݺus[l {W; cu,~ꩧ6C|WUV*I˄PR\k_Z6^>/~1mذm"P{skSN>d|b6/̏=<ƍ9c˸k+6_כI>=@seeބF^|Ɋ|Pmxz 8u>!8O|n!WwiBO*fΝ;!nGɒ1 @ @PDb|kNmj0^ՖxG9b/ײ}LN|>Hqn|~cWmk" @ @ @ C/E]Pd3gtW_}> y,W /ЧW["?Om +_I'nJ~C̭ޚCt,E?|;|gƌ3b8c\sMA9Ph[CGy$s̙ct+6!hk ^W\qv:r^ƹ'Nh~g)o:b!|)juFOP,wy .9Z/u>!81pL8> @ @ ܯ"2y>R>E1-xcsTKb_دex6̕|~֋ܔ?>ƮD @ @@Aop9t,J)o7_:!tg7o'xw׏EС?UoҤvP5*ӉQYfe|bQv(j}w6S~(06:Ue׭[禪&צE9ڵk]EիW ɓ'gRM'tF .BԟH:tp3Pn|xixB>kH׳-B @ x+>+Mc#ܯcp -r!@ @ U,?7C 8X+m'΍D}1>b*7vP y C#~<|ژ_581y(]K.,_\Cj)y5&9Wp_|wׯƯk璷!" 1?u:C?!ůb@ @ @_!E|~5},lc2 3GF9b/ײ}LN|>Hqn|~ eh @ @ @ (?y睗ǹՄqPЫ Skƴmv;z(ʎwl67\|Qp~dZy1P`Y<4.=SVˋQߚnݺmw =~Mr%OZ^k֬\5[l1_WS'Χ@ @v+>L~/TmѼpLf{!z(:GT,Zi\٩~i>Mc#ܯcp -r!@ @ x;<6)?TW^FB⼣ZxxP_~N3c |'sct(P-q77oKڵ˘ův׈sצ]qI)ͣ?ϛ+WfS:tiժ&qVˋsꪫLǎKfw rj4?奮.3=zóV/i&'KĀ @ @pWB0WOW$sV#K^ tZ^*~-˴aT?^|\!ܯ @ @ Tx;ljʈGm$HK,fӟG>]_fY7{,E:7駟S/cE5vg旾L4!xMh  /|wq/p=/V S">O|:s̽3暈 @ @F~p>ч`<6| Լa-xcsTKb_دex6̕|~֋ܔ?>ƮD @ @@Aop?%&/x&ix盯}knUC?*|O=͇΋/Uu/% %d^[V&4RbQ},~o[?FHzn]lܸqNKFu,ÿV~ocfPn$̛2e &y*"|XG S*tOJӡC*Fo|fѢE/fWbx<EQ+k5w}w8|uk;Ǐo."um|>A: @ @~ ?чVJU-l{Z^*~-˴aT?^|7vp  @ @ ؓAK/V8'|=*}u&Mkp_]|+Gfر檫2 eGX?S"hUt]yk|;1 p"'K/"糟X]G){-q[ ׺uk3c e˖SvkRߟ'`fϞm.nݺr cJ~; .tOt8Y5jK/xq @ @`o'pBC[$JX d=Q-/}ae0WvEZ/sSjkG_a@ @ @ }!(W_ 2$Kgƈ#O~Ur>%5\Sc7-[4ǯ; lbկ{׶vp_{=aOfjm"E|_ z#)2cɅ @ @{PDZ q?M*¶h^8&&7eZ^*~-˴aT?^|׵TB_ @ @x_~q믿>V+Ϝ1ehjQk>UXQGs*a^hW2C??W;zn:_ <8 U%܏Y<1NFU7]_yeX{?i$cbߛUV9ʕ+׊ U߸q{b1[Nx> p35v?4&>D<3.O<> @ @ ܯ"2y>R>E1虣Rk>^ sey>_87}pZf2ȅ @ @ O>\tEY%>2zhseegFbZǺu{Mvvmz9su]gO?tsg&Mg7 6fٶm[sWofmW_}9sfrb3<Ӝ|ɦu͛7*-rXެY3Cs /pM άYwlđGiomwcD^zi%K+L81xc:ud.ӫW/ǵO9sy9[`WUgz*( `fbb3S2Lf-8+-"TD@EgóYgkXu:goV_d}wNiҤ+{o5ss먁^c=t5\#;vLs_x4|u5t/PjkN߷>-{ҿe7>}' @ @;%|DzyfTHo=w̫sd _5B=b]ơ<5s@ @ $qĐXyfCzc^;'͈QN57[j5屚f_~j)B @ @ @ N~ |[ L4I~_gu'\MV4huY%5@ @ M0]+0? nHo=w̫sdѳBA5B=b]ơ&y~rJ * @ `7V~zWb3g*kӅz~+/2ZCyf<}m,Ǹ_ŅZd "B @ @sʐ!Cҥ{챢;gsŋ~֭.cV@ ^{]V  @ejпd|5OҤաժ촯/HLsLi&ҷ޹Eq_*G U:h$-c_fx1MMnX\Mum9wN @@~!5ѻ^ ~e[9Y\-ٴ t_sJVP>h{_51\[>噲" @ @ }}aС'O8ӧO l'JK4[N-[ׯ/'ϱzjѝիWcS{T:uꔼcFjJI&{=6m*zi\G(bܷJF+Y#ޒw?_"o%$6/W]'76aK>VvۼzdYVŨzKZ(ЛtujKf3|-Rv-i܄3mΎ֬ū֦jPW';UӤ^miZ\}݉q>9aS}-竟敍}mϾu~^5 ĸ?㾏 @WJ~!5ѻ~F~[9Yﷴ<].kn^)~jc5|kCuf9ॸKV @ @o[۸_mݖsO9쳃X5פ&z_F#FKiFKVj.5kz2ey~ǎΓy#<"UO8묳2ӽu]=3g秹{-z#„ gMoЦ'GuT C%Kd2c&[Rn7&hM~|W r={Cf˯^~Ԟ|qurgޑs7s78x_6Ss5kXbwuW]8cVޏJ!aq=b@ @60~~[9Y\\(ȻF9]ܼRl"8j3׆~r.bř1 @ @@ηq_;nܸԈWyj=;i{JwoРsϥӝՌf|ݭNbDOמz7\uUَ7xc:G_OݻEg}>@8kܯW;vL&^VXk .}MƍL=z>-@YLo(R? dM붋͚jն =iմ|f/0E9jf?twn,Vmx;%wnW@FX8;}6wn\_?yЬirǸF*s6y+U=;ɗ*|8'=}z/=/'t!ỗ4_G8SeGi:;G' ty=zB<~_36_Vq^vd9)`\DgQְ3?\~㺵Ew?] askӅz~+/2ZCyf<}m,ǸWm+ @ @ @ 'm7yE jr{n\sMj<;29ڵk_"5F޺ud}I ZCo}5uY)Sf-i6oǎ+{Iu_~؍LoIz3Coh֬?3f  :O.yn<=p8~K =lj\&S:換HN}||s4o~c=7Y SS9w4I]_'ᮙǸuM}>sF2Mn4nOvw5++=K &w=g3q~}SCjԈOrl䦇#c}i7]nO;uմ?01qW_2ĸ%r|='Oe8y*TOxئq`n39ܘ7ha,7> Ӗ{c@ @_%|gn5?bu}M47#zTwrPϯyEFWq(Lg4 s\#9 @ @ @`meww#ל~%HvJ&믗KJ޽O,1nj_`A $ЎkXxtMO{-19RFHݺuM#FI&sf:_]57qvz>]@o~tQeMg\Ǣ>#AqdKnUeqOatwzirO}-|IiXGtFp3/If^D~ߔ0»:{49~qDz# ̠cM7jx?`h|\_{~ ZI݌gVn>Jý7{su&7C1;yj4^Mn>܄o]#4J>Ws 4J>$~E:Gwό4Ftw}{j=[ 97\F@ @`9؏Cyu=ܵ6T?ꂳoIQN57[j5屚f_~rrE[%+A @ @7m^iӦɰa]uWy5mw}A?T9n7=fϣױvoV0ib:6/tڳڵkkܜG}T&NavԩSG:u$wYDvSS?~"CK7fNW;Ɋ5g,])'Nr&pjWu7/j/匧&1"6(C5\67{̸Goc&6߸cB=J>3m.# @ |u0v y 4Hw_D $>Ov|~ZJvxΌ%+將w!nzԅ˥NJ _uzbӌuq{bW{r7opؽE#YvQ>;gq  @ o4%|njv=sǼ:wN7ȻF9]ܼRl"8j3׆~r{Vq  @ @rYfwܑ,'tRt7_ 9CO>СCSci۶m_/K.޽{ˉ']mW/(/Lv~( &ȫ+r~:?;L!]t-\^zzK YVrjײA7?]B^$snЬafoRwQtw~ww>_"=z:gyvwworA)i< 2zb;87Mnxp5fuXݭ}=^I3z>;4)Kp2/q~oO#I׭}f!~ɛr"4't:$ @ 5"qĐX?1? yu,. LV.].kn^)~jc5|kCuf9Bhq1̘@ @ @ D`k,-Ȃ R\ :uq*<#i]M'pZJtwK:묒ys9GvM }ӧO{'=JKދ uԑ}>eenHyҭ[uF3gJ 䠃J?k><݉_W^yԮ]lkZFlt? Fb>?*ycnb>w͹S.ܷ]pkV?|V2=jX#="jBgG?{[ JM<>R~`R9ӝ}iQo&8iC~n[.}=y⣹rD~ʾw?r蟚2Oic쟓}^0v3?کƸF) wyf$ @ _bwMnjsǼ:wNMO6FwrPϯyEFWq(Lg4 k\[qd5@ @ @`%J>x |q%G}tfN_d3FFհ~K-G76{SO=ׯ/NM_W>@oBXbEj'Y&}^s=Njzu]'W.]iG)FJ>cCM?Ovh"iݺ\ve@ O{m.j޵iZR~w Y]pݑ{˙{>AĝL Fz.M˸&=teYjmEꯓؽ,_N$yzetw{q_ Cߛ)[7'vOwj7ɧE*sJ;ܧsjR_0dtEf{,4H%=o]}w?'zÅW7 F?9e{x\r&=1/Inv?y ~GvhN7)B @ CS7֚jVк&o_].kn^)~jc5|kCuf9%e GV @ @ -JY/B p5=]Ո~ק:u 5nzzC y>#gqIKv0`@jʕ+ku֥7lRvZɣtaÆywz~С&1.]߅7:ڳs+}2c Gv/No֭7(E|Vg6пx}y92>ҹE#pai٠ncdWWɘY e҂evQȮr&72M4~Ζ_ {ʁmɳ!&;T>>9_uj?j46=_gr}{77'ѧ'{I3ONH_=jn⌔s<@hnڰS3 =2B @%qĐÍZl1mj].kn^)~jc5|kCuf9\f"ճc& @ @ 2kGI 9hr݅~w[{L?h y睳.9sr駗n<7 .ݻvܞ>}s=Ν+Ç dki{'6~xyev /05k];_}B.\(w̟?_x OҞhժU;w# Pqp=厷?k^8Yx`;ٳU2+nhcdwW{_+սw+.JbwӝfkS;oW6odf;ҿIV&;:S9.r{Y8c_,-աuādgU*1_eƧؤݛ7=~CS+Ꟙּ n>[IO_*O!o'f{ݥ^<=am?/zT׳zK}k_xъLN> ?K4IzB8 pNc=D;OvP7h @K ލX>ȐzWb}y( W_dtXyF3PݯYqs 1WD @ @@NҸo4gΜ\޸qt'}5k\P#SN߬YJSŋ 6mTdR'7rիW˲evW^.|blFL\.y]9{yKĨݫms617WG&F֍ة_n@C Wz/'O [;Qv;5k%Z%O#h)wWN%'d}{Josӛ$֯O Лԩ߲gj @K ލbX.zWMȆeQN57[j5屚f_~v oʪ @ @G0oyg7S[Q.;lˆ@ @؞ `/1&z7Kc5Bzc^;'͈QN57[j5屚f_~j)B @ @ @ N~ @>+}Ll,q^*"A@ @Ckwch{_51Wqq- @ @0Ё hjPWZԯ!@ @`/1&z7+c5Bzc^;'͈QN57[j5屚f_~j)B @ @ @ N~ @ @ @E`/1&z7V~zWb3g*kӅz~+/2ZCyf<}m,Ǹ_ŅZd "B @ @gC @ @@K ލj?;չs،Y t_sJVP>h{_51Wqq- @ @0Ё @ @ PCkwcE籚yu,6#zV"ȻF9]ܼRl"8j3׆~rU\E`/B - @ @ 8q6t @ @ !qĐXyfCzc^;'͈QN57[j5屚f_~j)B @ @ @ N~ @ @ @E`/1&z7V~zWb3g*kӅz~+/2ZCyf<}m,Ǹ_ŅZd "B @ @gC @ @@K ލj?;չs،Y t_sJVP>h{_51Wqq- @ @0Ё @ @ PCkwcE籚yu,6#zV"ȻF9]ܼRl"8j3׆~rU\E`/B - @ @ 8q6t @ @ !qĐXyfCzc^;'͈QN57[j5屚f_~j)B @ @ @ N~ @ @ @E`/1&z7V~zWb3g*kӅz~+/2ZCyf<}m,Ǹ_ŅZd "B @ @gC @ @@K ލj?;չs،Y t_sJVP>h{_51Wqq- @ @0Ё @ @ PCkwcE籚yu,6#zV"ȻF9]ܼRl"8j3׆~rU\E`/B - @ @ 8q6t @ @ !qĐXyfCzc^;'͈QN57[j5屚f_~j)B @ @ @ N~ @ @ @E`/1&z7V~zWb3g*kӅz~+/2ZCyf<}m,Ǹ_ŅZd "B @ @gC @ @@K ލj?;չs،Y t_sJVP>h{_51Wqq- @ @0Ё @ @ PCkwcE籚yu,6#zV"ȻF9]ܼRl"8j3׆~rU\E`/B - @ @ 8q6t @ @ !qĐXyfCzc^;'͈QN57[j5屚f_~j)B @ @ @ N~ @ @ @E`/1&z7V~zWb3g*kӅz~+/2ZCyf<}m,Ǹ_ŅZd "B @ @gC @ @@K ލj?;չs،Y t_sJVP>h{_51Wqq- @ @0Ё @ @ PCkwcE籚yu,6#zV"ȻF9]ܼRl"8j3׆~rU\E`/B - @ @ 8q6t @ @ !qĐXyfCzc^;'͈QN57[j5屚f_~j)B @ @ @ N~ @ @ @E`/1&z7V~zWb3g*kӅz~+/2ZCyf<}m,Ǹ_ŅZd "B @ @gCXo2~"9M3[KJ @ @L~!5ѻ^~[9YlFPEwrPϯyEFWq(Lg4 PL_Z@ @ @ql@sAON\&691 @ o%|DIyfzHo=w̫sdѳBA5B=b]ơHyرxR$^ւ@IDAT׎h{_51^[<øő  @ @ kʃ>(/:uP^VgϞҵkג޷)[b[d;rK˖՛SMlx/6MuG%KF}uLY~wkגYի;tŃNWq~սjY8CwL92j rVC_I"c#59sȾ2"4rcE+VǫB @_b F}gdg˭qiٴ\5B=b]ơz8yRn.f[ܜ۷˩]v;۷\zt+M;D7mPZL_svOxk9s϶߇woK-HoyC'l'?d/D@ @[@~q5ѻ~~U[9YlFPEwrPϯyEFWq(Lg4 PL_Z@ @ @q[۸rJkS~֭W^iϝ;WyYn]z~#ebRݶ9Ȑ!2o)&LHSݭ^1fyN;MsTj*EǁJݳ%L"1?yɮ_C=T=XeСҦM9+VdkuQ>?rHySýpw K/MsՌ5Jwܴyuץy3\{N__<쳩^ׯuQ5 K,Çˌ3uLGa,3g< VuNneJKGHM>1f2 ;lPW޽IN׾>k>yK7>.-?]j'/1vBIcA|:O}ɪbq__g̬EmJ[&'cV`nbwdƝ^+9}+{v4Y6kW&]lI_vIs% ka4irOU=)CyY9ipZ6rkrӂx?lL~ݯkzSfq?_6%9^KZ7{|7"=tnȤoN!oMOkڳFKwڷWf~) Z7ﷇ\DYjM>aIe\M Os6 yҤ7Zsevqב}NJ˯}ď6~>M-JnrY衇~nru6z%ׯ^cv@ @H /;%BϭGCyVnkUL_57ѝS.{;9yu,lJ t_sJVP>h{_51׸ lj @ @KbotW{wz}?0!qT{wK:lSO=%ofHcf5qڴi2lذln(PS_`_xմlRyyWI&rWtGk6}\u}FV裏[*j¿;KnnȚIХK9s3ܹseȐ!$֧#S8 z-y5IEM}9i5k#4}U;8fLebPwn!O~`E~m^[LKG_/1g$8C+yٗj,? 7;]$L otW}8{g:t7!T>01ė;rOs| GM~r e12}P2lJk=R3Lo"`kky}ӛqԇrę5|F M:a;ty{.W1kU~.r2= @ #%{DyfsHo=w̫sd[xskӅz~+/2ZCyf<}m,ǸWm+ @ @ @ '3A|k9܎jӝu}^'ʣ>ƭZݙ~vO?T~ߧw5_vei]jw ׯOK.MqM .[nETs%Hv5tA{1u\u&W5kȽ+y矟֛6m]UW]d#jƟ7o^E]>`ڵ{ߍ7(:GON8|sVx@>#W^jر^~7J:@`5Ww{Tp}S5[[H j_rq&1>r'phe`6)[ӡCw?81q]C&'t15Mj(}o]㾞MmtgJvHCw}uvtW5L^Cwa]e@׶2jٟߗl{Kws?n./~7 5Ho|ir^zz{%&T0y9We<Od O(kSEz\ OoI 힗eѪiw&+F~ fl7?9e97Lwߣe#ymB 1:gT~7 'tA=qSjԜD mƶ~S~tXzk/uKv_U9.tQ%;u2S3ћ65߄ĸ;' S2iR8f4=T{[dqTrSEϾ^'}Bw'5o<9]Go)@b @ H~Ǝ>DƪXV yu,owrPϯyEFWq(Lg4 70~@!@ @ $u1vݕ^ 붃~eRN읙~ݺuҳgO9S/n-g?֭[[oMw׆\{ꕽԔވx駟}ofw2e`|ر3ϔg͚%wqEoܹs)AoNϺ}r=5O8І0n8iذ{ρDNOvܯty#y}Lry&dWk]ߐ 7ͳ|;$װ7>7-5iAzj:Q41?h]׉[6kη9l4jo["'1tw}0rH5jTKO~[wQ#F'w}2ut]qo߾)Gx/ҝx'if'͖{ޝ!|٨?߫mn3i޾8 zzSokgɮ]'7ܐ ?Xթ}ިNmI_dkɾ#?q_D{)cg/*;f[#z-'%K.,qԇsnI +k4i'%a~^5 \qPGwJ_;)[7?+}ɓG% bhx_wW^9\ysݛ(l^%+v_ڪ]zpF}, } }-@ @_W_G ÍZl1S2kӅz~+/2ZCyf<}m,Ǹ_-["k@ @ @tvвe˭U5/CvM.BYj\{q7|&ڵk@wy2yt7?\8Sfu͸|&i~k}6M&k7%6}}:!CD_=7o.{>}۾  l^(b^o2%>]ծ%G>4V&-X&4̸Mko׸omFůh_}c5Ck}ogQi{بfJ}{]OΩ)=̤5{1,kf|ݩ{{=%I S:4m(=<@J޷{ksw.W<7fא\][jܷ4~ u@ @B~!_ikc|ch]_Km].kn^)~jc5|kCuf971o>CV @ @ .;Y&5Y f^(ݻwa5~u]_ʌ3Dwo۶?H_S_~y㿉}=VZ7;t}eܡCћT套^?}J;uӟ4­C`{';Lv9_۞<'!}vSk'{3]Jvk70 ';1=tzٹv>fw'&tV}5ok,7zu͸S83 ҝ_9Ө3{v6sF-4L`oq_[iߴAkKߋ pOυ @׍C7֏c5Czc^;'74K QN57[j5屚f_~UjIB @ @ @q /z!5פ&;N[<2qDQe]l2D 'x1Bڴi#^z^ZtMݹD/(/rzUW]UNjts禬'(@`;%psʈz֖~{%E:fflwfn]^r޻xCޜXlL8ge;oR~Yݎf]v]Wսw+ g~).6/[οw>8dAjA_ٹqM> MC?y=}-{J¯_v$&|䉏Qgɹ>g>? FH:E\BDE.`K W)RD"RERDDB r!T;a gϜ=Iy|zky ɚ9ECCۮD8`8fÝ}=~GML櫕x~1   *@~[Co>x^+!Uok~̭5.cե✟wmkU9>MiBm ME@@@@fe;P?\{E_~# /9眢\O??a„piOp ön[,)ƍҰ曇O|1/SOkoq5jT9q?a?~|Xwu>x 7XcFA֦N8t,;?رyph9Z~r Zͻ{oa꫇[W'xb1ϫ,"@`ӯoxR'_ C҇ ѢOFOj7}E)~*|'?az};){R8z~_Y-G/5&{=b=-h?5\ :}oaHOޠo39ɟ¤VYs;wL #.#=yj>f8&qo~ da f'܉_-2~9|۟yq޿ᣗtX:|ՋcVBnMŭ_6͗f3WoXlџܕq_fZ,uںu3]I};g׏ts]b77Zb@@@`v и֐ݴ\qʹ[1Rkq;ŶdS|צq4?XF@@@@2fe㾚W[mY\ z;S|X{˳5\Sw1 4h;ZV-\ċۧpﭛ .~h\8h5]_Ⴣ*Ԝ7[Ou[frJ{OUz:].JsZr|P?jmek5kgz셰߭kl=_ߚu&N./}Q>MZ9?faȀ}vhsB k[ľaf7^7PfՆ-ޘ45ppYmZ0  UXx^:n\S9]z,.SlMF_85Y}hqm*lN~p&hܟ @@@@]ݸ[oSO=5L2YMj_k1cƴdM7 #Gsυ;OW™gY<}_GqDlO9ECq_jx۬h?C .ث:怱c}@զz[o wqGY I&Çal TӾTmԇ ~bh}q=o W<'o x ?|yЯ7=a=q_Ӹ <˦AOSצ{£zľ _'d8zǞ?YWߝ>z_]uÖZ.7}9ںqnS]qqsu 竕}}d&|ߠk袭"-54\ oO ?hyrMMn MUk]7R`kD׊0qdž3^$@@@>"@~[C76+ϫrU[>SǍk*j{ZN7}Լ*g95ǵ|9j;O~ @@@@@Lݸ}5?-a [lEPxjSŶ~='П|뮹av݊cqW_ +ry5?`pvUWdeoO2dH5O8xJcᤓN*՚ypTc/YUVY%|3 Cp]wLsM85)RM'||հpχޙ\4yemV\t3:爥Xݖ;unF.k.ZβZO65[nk?6 ˺sxմ,li[7.z8;oAOշM';6Һ!CNm=A+F>n׷([mlհ!QzR_ٴ5=rͰ>un{P}{5[㾿ޘ4%q_q_nj_/;nvm]ŵbĠ_i}*eF@@@ и֐lk1r9kV.O[Rv2uu8b[o2ZũyUsFkkS8gs/ i΍@@@@@X`f7ǯכԩSÄ C ]M}my_O߿l9=9< 4yz\SgƋajoֿ jfVCj?#'O͉ae7Ƨ^7 SkW:Zj k5.{=~_XsNzR޷yWArm/Z{f;E'"z7{u|pB?zǵs|w԰@ά4_=>c4ͬ   45&z ,W 7Uok~̭cե✟wmkU9>Mi//и?s\9*    {sR@zZ~lӓ}[cD@@@yW|Dc] *gS[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m  `q}SaD@@@X|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6 &0wóoXkfD@@@hokM>Y<ʙo[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_m      D|Dcm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @6     MhokM>i<[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T и_mZ7n\w].?s9aСe\_OOٜ..&иDZ@@@a@IDAT@@Z`V4kvє\}&o5-a K-T]lY{W4/=H I@sLxGRNb#   }W|Dc}*gv[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T ̊{,}'X9rdk|g6mڴ{݄oj>àA%tPz衢Vӹ;ÿa̘1EXdEĉz>Oth<~[)c5v=F]]j-y֛Vqj^њT>ٜ^q     @h'GyF1hh &LOT1Sֈ^&rQWZs~)&UW>g6s6q .47Ѣ@@@@Ս .`xwfmZUe<#7uu8b[o2ZũyUsFkkS8gsKx4W    nܗr-N9M>h8ڞj?xpy'?S_|1YnX|{;s|w~O?9r&Mϯjq\F!Cn_wɹ@>JaB aÆ顯K,o^{:thIA?,_z0iҤ<|0`.jd/i A~/믿^,Y׶6c9&<#ż_~sϭ}m}^Sկ%\R_GK9 y㱆   ̭45&zU9TR:O[#z"=F]]j-y֛Vqj^њT>ٜ..&иDZ@@@@@Z`v4i~zPr=/Ӫ9s¢.ZL81\qkk}sIjj{kfi_җ§>pg,z뭋O~r]MK/tqSL _hf?/jz 6 nac{Q~A7>J[V//bjpUW5f~#GT/=vk9@ niƌ? S)380s]wu}-~aElIq.jSn_ңde O1bD܄Qκ^&w9c-߿SnJ]SJu]j_&g?+m_K.d8Ê׳@@@@yQ|Dc]*gQ[)M.Ӎcե✟wmkU9>Miot6/q{     )ոFm=>L{=\O>˖>l8#»[Rؿ=u]Xz t5b?U+lV\As}{<]Pqt'tRKC[Ԅf{*Gm BmЇ>ɓ'[Ǹ7a z>R>qN둏v=7u\QG U'?ɠB|D^q~[`v(nHQ#,n>ѼjoO@@@WhokM>ϫrvm͏u~2Vxocե✟wmkU9>MiUa;    d }56|#;?!E$ jVtPX7ZO6-I^*qczs''WP =ݶ_.iqv o}YQO~wY^0O4hPo9з<_EnVXap'N;v*+s s?bW/͹ R{z@@@@yQ|>֥ϫrvm͏u~2Vxocե✟wmkU9>MiUa;    d }׾ j$O?SwY;xa 6z 7~ >9Ԥ[_>AO 9rd^4?S+,wQը袋MZYgU)XqW0|p=1 .(ؕozjN5_׋? /"^|ŋs8p`ᄊ=_Or2n {xRmv߸o5zSz衇6ڨEN 3& _}6_<~ '}֩Yu%r"xᇋ{7>Z' g}vy[]:zZ!bŸ뮻}ca>hП ]7ԡͮa}NW 7ܰ90"   m Ǻ4yU.T1Sֈ^&rQWZs~)&UW>g6s6q .47Ѣ@@@@.lhlOS~w[*?G?*xo||ھVXWpW+TSK,Q4tU[̼rA`Ք?bĈ޿W+߇e]ѣC5=TJ+T'{ɓ'}٧O?X/㨱/Kqq{ϺA{OO5 >%G}Ǐ/sjMRM1㨣j;qƅ8\Tg*?Qh+mknzqZAܸ'oGzU;}f_={L&ر>hַUk\򊟤o(Xjop&>S,U\TmUݼ^{oyg{SGj륎G@@@hokM>eϫrvɤm͏u~2F2E{ZN7}Լ*g95ǵ|9]\Mvq     @@_mWW^<\X)^O?SSSq͐!C'-|nM1ncT~)S}[-%t:.^} ;|Θ۸rH}+^SsG yl/\|ۄ{Ζ>?lqg#   m ǺyU.T1Sֈ^&rQWZs~)&UW>g6s6q .47Ѣ@@@@苍#G KXhNO[ogF`s=j7&tIᮻ*wnvau 8p`gࠃ*kRg~F^y2    <$@~[C۳Q߯Yƺcdld1Rkq;ŶdS|צq4g^ݖѸ߭!    qe rJo>z7i\74ٚ6۱FTctr5kvia%Ô_~__? jnzq / 7pCy_~6yh03o||Yƙg_|2g^zbs?_`p'5x[lQ7A M6.n7g~g۾o^ۦ8f̘pᇗӸ?#_<@@@@`qq7XWD<Փ5?}DA1Rkq;ŶdS|צq4wq6م&Z"    q?T\}﯌7.peBM +Pi/?|Sҵnhoiլ=a-=^jtt5ۦo~isz#<;ghش+| bǪե7dp9VԩSsӹS5[kN7YaҤI#H{_c? C-wѵkaeΛAz-}[wQRrg'C   C45&z늈U9zR:Oeq{ZN7}Լ*g95ǵ|9/f;и̋j@@@@@J`NjW1y oq6mZxg?eMofoSѪ__p[11"|k_+'fߴ߿lz#W_}u+">:7tSۺ }c7:_."y= ,@;vl~P>_E-\L8uvXq#z!yئo9l<@8JFW_==餓Q,uÄ'=ذaW_-{キuRglIsϰkÇ}3N     0и֐}!WIۚs>enǨK9?z*NͫrV3Z}\9Ӹ۫4wb@@@@|!d?&O=԰4mSѪM= ގQ5.arsT[4 }c]wU4cvs;?V:>}?; jz[n wM; (n_>}s=WUҖ_po-oj;MRקn9Óf%_$    0 и֐} WIۚs>ele uu8b[o2ZũyUsFkkS8gsPB~-j@@@@@jո gVzyU(>jԨr9~ҺsGPmh[{7[r㷦qMjV.}wOxF =v7tjW]}&/5am_"\~=qBnXiڹ,Լ?a„:=}_O'lĉa.% ,L7n\>zᩧ*,fٱ@@@@yI|Dc]*gO[)ckD/]ǨK9?z*NͫrV3Z}\9ӸŅdhQ    T ̎}=+_}f+j?% b!~%h[`M/ۯlHO90|op饗*5+Oqsky}'4> &}#mz_ / SNt1nE^ΥMC-j^xᅢiovM:O~磚5\3 =Qjk{aر=JD;|3a걞yEo\}.|_.^ߞi'5_r%?O7T]:*tSmͨ׳3"   m ǺyU.T1Sj{ZN7}Լ*g95ǵ|9j;O~ @@@@@LYѸy*]; /pPiӂ羰Ԭ&i5Yk>|xFpݜޗt OדgnxÛoY8\[l"d=Y /xyQ_gĦfx_n4=@oUhz&eV^s@@@45&z룋U9S:Oψ =F]]j-y֛Vqj^њT>ٜ93Ǖ"    '07{@@@@m yU>T1Sֈ^&rQWZs~)&UW>g6s68Q~?:s{L @@@@@`V и?y@@@@\:FrUz5}]s>uq6cVɭ5.cե✟wmkU9>M5ҸŚ R!    4     и|},x^3T1Sֈ^&rQWZs~)&UW>g6s6H~k.4JQ     и_*     +@~[Co8yUS:O[#z"=F]]j-y֛Vqj^њT>\#]\и+E     P/@~     @m U9Oۚs>ele uu8b[o2ZũyUsFkkS8gs4wqB~u     @>"    45&z3W>Uok~̭5.cե✟wmkU9>M5ҸŚ R!    4     и֐},x^3T1Sֈ^&rQWZs~)&UW>g6s6H~k.4JQ     и_*     +@~[Co8yUS:O[#z"=F]]j-y֛Vqj^њT>\#]\и+E     P/@~     @m U9Oۚs>ele uu8b[o2ZũyUsFkkS8gs4wqB~u     @>"    45&z3W>Uok~̭5.cե✟wmkU9>M5qQF?H?%R. @@@@h܏@"    ] hxϴ֏mTWvNc%uq-ftU[ݚ'S3;uu8b[o2ZũyUsFkkS%uq{O[){ZN7}Լ*g9oOէ}N~h//и?M9"    ̛4ϛ;@@@@fmǂU9R:O[#z"=F]]j-y֛Vqj^nFߔyq.47@@@@H иv!    4}¾ނ[c>uq6;uk2Sj {ZN7}Լ*g݌q~<1}^ӸD      !@~%     @mǒU9SOۚs>ele uu8b[o2ZũyU}Sqnm6lX9rdXo/ Zd@@@@@"@~_$8@@@@hokM>ϫrvIm͏u~2]ѹǨK9?z*NͫrVoƸ&DZEZ_uԨQlSݷv۰{~[aD@@@@ hܟ >D     :Z?Q3~48ϭΏV:\::|݌~8^\Y5_[)c5v=F]]j-y֛Vqj^O5[qMuq{O[)c5v=F]]j-y֛Vqj$ZponjǸ&q9ٚK?W46,\|64K_ _Wz{ ?     @q~0    q5j(OMe<#sQWZs~)&U35<5k68W4_~aСI     0w и?w}@@@@}}q5ڏ,mSkks>k]+s>eFnǨK9?z*r|uq6;uk2Sj {ZN7}b?Rcպ5ڧs8gsj_eԨQmӚoF;uF@@@@@PC-!    lh z[?o~F5'W>SF[\n݌~8^\uk2Sj{ZN7}m]GqNsk59[KrӸ/M6@@@@@>-@~x89@@@@&ܜUMuI8b[o2ں8^\uk2Sj{ZN7SQqNs5kkf|u~q_2l     }Z>pr     0 thܷ&T}*&8/8:kX85j_k2ں8^\Y5_[)c5v=F]]j-y֛Z|(8W5M*X?4@@@@@}@@@@@`hWcyꧪ*:Ry6Quw3}xMsmg|enߧ-uu8b[f(N-o -4&TmjgϪF:5[d 7Xy)aQ3Ƥ)a耞k=I     6g=/    s{hZ?j>V~R9[YuոchQkkן>k]+s>e<#sQWZs~)nF6 NoOզ\Սjo m -1X6i:pÚ@@@@@}S@@@@@`Nރ'դYNVd~[ܛ[kkVmuk~:Oq[1Rkq;Ŷi{W,&|{m6רmV;7?= + ^rza~Ͱ z"O     @_q/~*    ̉jזjs6Wm8Kk~6o2ں8^\ιj[}XMrQWZs~)QٯcDZy75۾mM3QNIi1x㍕yؗ޿~0ټǞ(z,     }C`niܟ2eJ~4jg? 2Szp7ƏN6l*̔ך[׬45qpg? ><| ,|ə~lGםl k O/bXc5}L5\~_~pΧkE-   }W5:Kk1L>rJy?Oiӱu}M]i͎?}nW}xFty.SlUZ]i^&5>kRvoGN}     @__}X4.bg>cTz뭰>w}8a>яΘGGQGxbe- oT^G7#Q{ &L(^WC?? :0tM6lg=.opRQG?L߬[/GFmn;۽O=X8sz{Q@u]~ӟɓ'nmªږϝ\uU+,t 7,u{;[uͨ9ߌ28    >ZO]5-[ss7ux8X9m:N5͵׭:O [1Rkq;ŶzqNsxnǰz;x5¾)-?yPm]ppÚڟ @@@@@` @8gx3k;j` f ӱ,ӟt}gkunY8裏o}[78nvqDz'?Iky~nX|}vmo[Xr%oY)O}.vsM[/Zk&k7dq3>s=X`}.,RNsfB@@@`.H4ssjBT>ԚեTΎxMsm83[{.[Szr13{ZNۨbqj8v,~&x_O]_SEZ?5 /}7xc]?楰o nnC/px~6)     Lj;vlx VZ),m6U/R?~|2eJS< /V[m5+l'NX4[;0hРm/^z2˴Խ/ vim.hۍVy[nrF5 mf(%6曯8=',S P%Xxo>)^x!+Aja3a„бtz~ꩧaaVrۦzVӾbmkqS}~>isctu3V٩_lկ~n0Z?Sk$~zO~0pkdkу>m}S6]çvZ6lXq 5w#XV)^ұtmеB *Ou    зZ_ WA7X|bmmLj4fy׭Y]jLX~.43=ﺵ뒱{.SZ\j8^}ýϧZX?\p3ռPѼ?p~ۮ>^O~.|w4ˉ @@@@+֤7ΨQs??~Syg?ٲY6n?w޶7dpM~_=~*{?v}r}Fz~G}tX^.ro;\3(˂5XjBVpWujjl֦frN;T< XlgyYg;R娛04l{ݴojя~T7SMrJQGu]L{'>'u-mС᠃ :/m_7⫝̸;я~ܺ9^Knv4W\1l6O/:s9hun $vN+r!np9qV(jԸͮIkZuSS[oc~5w}=b}rM.F۸߿xr5Cۇ@@@,nW35[B9?zjqWfswn]j {ZNqjr|,p>2@IDATO*jsl]ym8.[1R/̛~RCÕ &Ov^.>Ϭ%nl(      0b1cft{j=zt[MͶFmƏƎkb<kQ4mOo=?!\O_r%gyujj6x]Ot秆b;O{J<ȢyةkȑaV( Ǎ&֥U:r,)C#Dl ^cϕ" l.}( "()D (DEx1*\P84]\79]d1;1\^U ŷ׶<ǃr%}{ӟӗ/}}s^>S>Sv__k۪X>}_i~AAϫK=AӁzikVO~?I'+3tV˿tP^߫׼5;}:}zd淹mO??}~}Ǟ!}ҽvw򖷜~)B@W^yNKq=yN|%c…'Lw-R_{M~K<5x@ @ p XwԡzYբʭb٧ZuzqfgNr?UzIno/V)x9w4r{b-uw~8_/u=m.ѫCOv7~uhI~.@ @ @Ń:g?{:TOu};g<=iiPۼ.wOySv9CE__tb}ߞ.OFk{n?cyMWbӇnw>]^~Crrу>Oϟqͥץ֗^4ק-p^OOM_{7RXC?C_>{%N"⧦GN꠿_q*+s/ }}t \fq^9 }}׽ zP򀹼Kg=Y__~'~b%=5jN{ã=׿~zMUw7MUNW΋{<~Ou_-^{?k[֓?bXv߾ @ @8{f;t<wkő8g澣朏ͳO.P]׋Q_9}xDX^b-z^5ٟO[A}1V=iOo=ϡ!@ @ Ol >+͇_,jp}ٟMcC:0'noo"Tls@UW]u W/"SW|<~:}zk=Oge]x = r_|_ 3]ؾ ok{k.=t@O]ȩȜ{53}z旼%kЁs>S9_k/#";{=>{a{/1=_mWrE;nMQo]! Z?G>" @ @@qp?J{z=gw8ɣ+X_\ث+{1Ii=_Z[^{DV=ߋ|d]KqޮKb{u>|y{+ @ @Y}ցb}>uP7|7>>d4ak}>}ꫯ>;N_޽UmŃӧu0X>++\tq{'b3# ~~ls2{Ͻ-Wkwְh?~S)d]>pՋ_I{Ѓ_B$}Z<)z+"Cwd_ۿ}*{ց}:H~NON\/x vgw=y̽=>/5v׻e3A,Zo͡C @ p6 \{pӡ}z={Zq?~r>zުѥj^X݋qgN-Nz^b~幎>{={buH3w YSՁJCkC[~Y< @ @ Yrc@'?>5ݿ]].S_GL? o>;8gvzm܏ӧ|uY̥, .VlW__=9ɫ.[zzվ|p_g_.xc39_3h>|%+O/|G}S>S.ټ '?s=KoUu1ΐC @ pv ;SIt_C<sc}myr>bWuKqG} ?U:zX;~屎bGo+χ?b??}y9/Pzˋr_ @ @$pOkY!}ӟMc`n><~;yק?a;9O3yOu ]{{W~!ގ5q'Mz}Eٗ} ?uŃ?#dޗ}'r|=ݽ-ohwe{A3|;wb_(u~G>rw|z|~Xx@?r|z?{|wkSooLNGnwMQ<|sLo* O|'qի_`59f^mKo~w?B-nqݧ~ݓi/aW^[侣?Ǔ@ @4 ^+rV{zuhu\/ѫ\WйFz({F}(c=_Zc珵\kݱ&p~5랢>q{mgݔoOݫw|^vOv7y޽_W^7O{?is1!@ @ }pַ;;v:`/}ڽꩭOH'ݣݛ2|?wy{v}cw'2|w p~ 4Okvz׻v=wx|OR:LOp׾'ػp'<G1ԥOH=}~iG~G|_𶷽mf7Sw;sю{_ ͻ%_%ӳK̇}\׿Ӽ?M=Џ9_=zK~n{K^u_E /ϚQޯO_ᶷ3y+^KG~G3z{*G|AϝXDYuVN8ԠW~W&Ms?s/ȯN=}9 @ @ pf {##;|^-Ũ[w'uɣk.F4fzߚG}{^bs=bGh._Zs=|>Ys}p4}]ݧ}ڧ}?7 z_>c<wxh_o}ǧ~pA @ @Y#p^w0Aӡ~}KkOW^yt>?q y5O݋^O>C~-?9Ϲde<ħ׬Oۿ=ѕr@y>9L> ju{n:/MO_;8ax}7}>Ng=Y'%D"_Ч7޽򕯜<u{{Տ{߭}k+>G{>vPgT= }cs̼ZϿ"M?w/QQ;>?qӿ;Kz=gO!^?8C@ @$?u(:/MW}ި)e-Ǫ}E]~U5+8=zY˵^5Jsϱq?F#}uܓ x/}"H9uw}I'ޯOsC}>WuX۽8q/|ޏ}^J/ǫ^}%K?=Yy_wYn|j~QAH_{Q}[[c'>_G?+?_G, @ @g_?؏؟??Kȫ&t]g=['kQwc̵[}x=ΣwNsu݊r~ݣ;z\Ys<ŘWyUQu={uoZx9?}Q# @ @ tp>vzЃ&'@{ӧ? O$ܛf|rep3 O>s?DsO'k&^><"';ΞF:d}sOkw󝻟۽/>i&7毺5\3~}?;/~ԣ{K_{K^r>{77wO}S-ď=!69юMt?u,'{w>ĭ#=[5wCvsI_nЧWIQlq<Їt(\x;7-g>??v=_au][.wϰK|{^y^?򑏜~iC{?wo~w??;/̪گRI/ü,sP LnoGGO쯫<4  @ @Gwg<{@yٷf|X=ʺEkc̳Ie=IC^;z\빭9VHObzkip~5=H? z׻_Ojv=яw?oB @ @ >?MKOxuY\U!.u]W^yiݭL[͟Ext[ucFby[zx~o|z[Xl_znuwV^?ϟ~@y{^Ϙ~)w~w͟^kH⊓>snqcv,}mo.@ @W??+|=/DWD}~|_Vy _x_jj @ @gO|U_UO߿7޹A|G(5f==-c|$V&]+^V<3#܇8zGsiU1j9&}͗kև㞨hn_|[\]gE\ @ @8C[W_={ww;iև @  _^+jFWb135J4z~7!c=_ի4=kԝ;sߵbc?4>\ZњwVoJw׭nu;_qKsB @ @$AP p=&w{+rwc!!;ef.@ @ K Mog<0sگWW_ښyGg͵vu/^̽/j=+mgboGAqtGW*Mus'z<ϸ3:T+[yu(V>iu~V7эno:ӗ|>>nwn/B@ @ @O @ @.k=/{ˮ-޳!{Wo{i1Kӕ5ױV__Fz(V{coq*ztGW*M/&b]b#Oki:4|=jGKKu+_핦ȵ*9*VJ}|\Zc{yU*OK;f @ @ @ @ lICKf+obsX;1r/ֽts{\3̕'js8׋W4_z׋38C@ @ @ @ @#у=ߒ^\\ek-G?gU{Oo.{ =3sy\;Zs]Js+ﱮř|Cǣ;z%荹^GzyFu֞"PܮQܞoVuU4H^yj{ @ @ @ @ @@`XT5ZrkbҢު+[C5ϴI;w4/U89ji늽_9ɷ8<[X;w uc|V3,=d/%ss8^綞=:˗iy>?j1GoΏͻ!@ @ @ @ @i=\{nvi?c{ڹc[stu1+j1z??[{goUSiz-ͯ^{5"s};[3'Gw|Kzkz+=Řۛzr>ϻ{:Wc̹<#MW9-[Zzo @ @ @ @ @`Vx<]Ut;w3vsF<ї{lA5uּ?똫ڱܛoE-ϵjho/Μ[(1;'j9+|YQ_-Us|$V)wj9j·{Hw=sN]#7z.w?Ƙ{Ie-繎S_~j@ @ @ @ @ pC!0wyi?c.rkqZyϧ^C9j6k{;[=}kZzԜ;ƾ^zQH]yϚ\TV.8cWyد-{\+·-y{ow/GG.<+qwټ @ @ @ @ c%/#=fQz纚/ͽjW\S=\3:Ƙ{wzzA59bř^2cWywtV\{.F3jky#ϒ_C#jsS+{ZZsZw [zoxֻ @ @ @ @ @u(9=VoWWQnqT_1y>4EO1zg6bM^HҢsպ⎃Rk9Vs83'Gw*Ϝb;V{159$=KY܏X;w1枍ZGjy|ŝ{={G}q @ @ @ @ G{%uhs\TGao9O][%Z\.|UfFv'Gw*Ϝb;V{UZGjy![z3^+s4&[ľ{=-Lk.{Y4@ @ @ @ @ p\U9-];sJsO1f=zrnca5ޫyձ|$V%&5͌ʻO| 1<#ZTfO\ K}[jz}ӫcXy\뵴VH_3G @ @ @ @ Uk.fZ^{ż׳1zH-OdLes玹rkqc+_+}e\߱^8soqxtLjz=zfQSkr/^/W^719Qިܽ9-fG;^/@ @ @ @ @"Jk*_[Ũ)ޑv}sJ)c/}ZřiAѪtwyᆳ^rst?ѼS/^or>̨/-/1c/z!:㜵cnobcu?c.KwsT9sX\WA=+8_곟@ @ @ @ @F2r?gLcܱsQkީ*ͽ'kr+[{g;ƾcnoKr]̡s軸sqf7MaKdǜ׏QZuԫܚwV\?]Q˹o} ?#>se=sy-zkWcO @ @ @ @ Ph^گYs(+-\8gjޮ[qךo;zzź+My[yԢ\Wн{.LܮzZurwս+P9V^ycsg}k==zk{nީXQ9ƾ4]:V]uUio.r@ @ @ @ @ pC"0wyig͵xWyr91sk=S5QwދU/j9+Wz=窸vn5wXa*zYs*iU1j|v>r~tc=?'z b.m-z.wI1s}kUb^UKg;T~_:qPεC @ @ @ @ J`幹V?:osѓH+MJZcs}kKb٧ZP]ۗڹisWޒc.U5\zGOUu=1'k˫cW.kyU4]qA\bj܅ d @ @ @ @ @|X{pynz}Gw^9-s^Yu^G<k筨޵7g_UKq\?]8tv\ZE]u+^o޹8r!@ @ @ @ @i8Prz]=O՛b.wQ*KUk˽ܯ=zu<c=5F{; ykU-mܴokwU-׹8oE{~Kz/Woi6+%^w^G<ѯ\r^-MG}4* @ @ @ @ @=U:"*cgO)ϵUoۚs/7~̣/s݋U/j9_SW3Ҫ+>{oik}[L>flѢ {9z<^zU{WkiyFj91`=8IDATO=]Yu5{Յ-7saBsE@ @ @ @ @nxhy[Js9'zѧ<֞˺iyO5=1y[>q*VgV}`i9X6;\-4vTJ=1ogbJzsr+-y\c%MWr=99rm=Gb{>t~ޛ0=Noqw^E51\?QyL:{ѿ$7G/UҢ5f3\x읋[}@ @ @ @ @ Q Gv^Ey+eG}MޛQoo79wlqIQSH-ǚcg\}պ { 53o @ @ @ @ @Ok4fޜQ?-iYmkWo_:؋ss^)77Ruc}[F;Z\c=W}kKb5z~qzUG-繎{sʳ{[@ @ @ @ @ ._"z;71mc]rl֫zN^goʭ-7j|}5qU}Ԏ-_}F艹`ڹc[st/Yw_1/s8{-=zr8ܱh*|<|g\?z槹{ @ @ @ @ @%W 6ׯzYխ^ԝ稗 -UD^{Y\ǹ*_e*i漪h+'Kvlqrh'K_+k53zõ܋}kKbZՌ4]~C5}~#@ @ @ @ @ p s_Y[RGsGd̜s/Ts=ͽ=yk?TO=yA=jV32Tzbsau[s3zE-:[;wq&/MWc{9{qLo=@ @ @ @ @ p}!@soի:b1j1wMfZZKľXGO[yWyOsg:j]sPۺ{f.my]#-OgW^4Vzẓ{{kbͳ[ZOWOu߷رLA @ @ @ @ KǝWzzu٨\?EQud{~+5Z/Ͻni=]=_~cfOsiy*=kKj{˹cc[3'j#wGsǹj&j9_SW3tQ_{Csw@ @ @ @ @ lr8q-_gmIo㎘>s#jܜgrGӦ07Zǽq3'ϭ;Nr[S+[Zԕ졚h_>@ @ @ @ @ pak~twWs;VzĞE-~J={1b^P_W쭩%~˻b^53mS?_~ Y @ @ @ @ @Xzo*=k:|f1^]*{^3~ΫԋWK壾8f&ΗiN^{tZ`6WH\ͭE.gN}庼PLkz~̴vC @ @ @ @ 5GfZJڒ:z;ܱ=^[5Zɹj]~Cui]yz^bVfD?kw≓Kq @ @ @ @ ܐ ,=v|SsZzInodmzg[ڋ^{#u,\/ί @ @ @ @ @J`AљemIUFz5y&zFO=]qA3>F=N0G[JѢ'ksg4bkg|ΖWsZ+9%޲잽= @ @ @ @ @Y%a%{zު7EO=UT.{Go[-ގ؋-ju=-7x/jG{7Ew(fYg٣\tj-ﴤǽ*V|h @ @ @ @ @,=z>~Dz+xZ @ @ @ @ @. lyy鮖+MܲgoUR~x?ksqjOKѣG/VVbG-ɷs=OGvtg=(͸cu2@ @ @ @ @ Vn[rի9-c$y^,Ek9==OՋZ̫}\S+{j[xv9o=W/c52,ѳ71XFz=Ou,i퐮+bnNw_13|ځ@ @ @ @ @ p)G-Ϩ}z=E{{q5ǪWiE/ɫ+>A9|_FO/oݻ7w9+{gz=syik{zx1jms#4T+{H~=@ @ @ @ @ #cB̷k@ @ @ @ @ pN=oWsZثJɺVܞ?6uTՓYD_sr:^s{zVҳޘ1jVZ?w%=yug;(zfoouON+^<^@ @ @ @ @n.!rsVG艹?k5^{#u呦+?A=|f㞹|>sCyx{yZJڒ:z[~H9FyqoS+ί%Ş9}o_c4}x  @ @ @ @ @M^onճoIs\_qZ-oG+4]ʅ~]#{{q={\rk>==_WY[RGikwr8(-ݞ}1 @ @ @ @ @XsXzn+_bWz9xg\ܱ&3#u呦+r{w}st,Uެў}ڹ]׳oc\rW^Vz>eO[~0zqzZWmZcuzq\o'=@ @ @ @ @ 6GzVs1׫~]:yAbDžm3uypy{\ wb{ޘҼw[SW3tg=(xjd7 @ @ @ @ @clmg4+rw+k<`1kݱVbGkwS..oqs_i\gO^żw-|yUiW~f1x?= @ @ @ @ @c94=2;k<׫c/V>uޓU-My{5s{!]4bǥ[gV3i۫OwV[-{wgOowY[^t@ @ @ @ @ shztk*}D˞^Eo)=1ϽniktpP/>xSoo=g/k,v=O_}[q9?v> @ @ @ @ @8կ-{='YiI>[qyZsG-=kWZ- -~vs++?*.VQrWA歞atϜׯz&Y_ZK?~Cdmi{[z5<3C @ @ @ @ @<TJJ:]:1O.kK֞9Xw/ߊk>j᭞ctϜo*=kz>W=cko|LA @ @ @ @ @ p 9`=2zzY{wDޛ7kȞ8wV7o|~WY˵~YKW9xU\ꏳg:^@ @ @ @ @'`sm3<~ܱ-12Sy;=;=rxXkz>l13Coʷ̭e_*ڒg~ @ @ @ @ @g>~ޖo ڑ1Smi=}7җW~-w0eG m}zɾ9oUZmd.{rMr]yZZKvʫ;8<%.ه @ @ @ @ P!饻G=Oի4l+}D[Y3s3[w׺gs'{G"Y;,5[JR5PՎn8fݏq7Uh @ @ @ @ @]#ޖU-]#c5/]W \7UVigϳtלowD o~FRobډ@ @ @ @ @ cX/^~4=}7җ'^g|],}sˡS~~DV5kteZw1q9 @ @ @ @ @uKCףsV ڱVӫJky{\o/OZ=K-E޳v4g9W\Mo~3U{Fz폾}g8n@ @ @ @ @ `ggJJZ#?<77oI?[_W= @ @ @ @ @5΍z{dWoG|LYgv'ֳ.;ͮMԛ8>ǥ~Uq]~4@ @ @ @ @ C`Kw|{k{fGqsswQ<r>g]{?yz={^onv?O\η7~g^s̜ƛ{F9G}/gki~ @ @ @ @ @8kΌݣ3#9\_o9ϱ}C @ @ @ @ o[^c?;wܽqL姹wUz4{%3#-<[Лjd|KYz86_k @ @ @ @ @.[27³4F[8w bh`Um׋bSˉs=KV.0~j^˸Zb˘R|iKr5-k5=  @ @ @ @ @h]R+5'%ndv)rη'9/ss$ǭs9y)q)1HK9^V:̜K< @ @ @ @ @YK5}ssSSb6ZIgiޞYooOX^sRSRb_ʜ{ݳu^~#@ @ @ @ @XG2wIؔ$SSύ3{CM=j3?kr%Y}KfC @ @ @ @xe욾9񩱩q{9}ι){O8)#ޣGn^N|˙wwzW}|O @ @ @ @ ݥr"n3k|{Do3TSS?7g|ڟ.dnO5R+u&q @ @ @ @ @#k{nʽ'똛w)34yڒ푛-~xsy-k}; @ @ @ @ @w \/-|r;|#e'.Lz>yۅ*9^cO @ @ @ @ @ ^ꮭ_biޖ_Oy2KuSGWm킕/g:纭>G{C @ @ @ @-}|uJJrs/Lm^sTos4ʣޭEWwϿz{ @ @ @ @ @^[4tv>H{TY<}QzUScV~k5J* @ @ @ @ @\`Bw55f'U+u&qoXz-֘Eo. @ @ @ @ @cOT߳v׏}e[Gg~-Dqwo[xWo @ @ @ @ @ޢ~Mi1K΍/g&o[-բ~Zk>#̐;x @ @ @ @ @r -ghQEDZk=Goo\|-{ժ{5 @ @ @ @ @Y׻۪vZJ3z<dz޻uߖZֺ7 @ @ @ @ @[iYkުY}Sk%Yޫo=j^♽SgG @ @ @ @ O`Rx=jn֫1ﷹn9gA޽ng֗}Y[z @ @ @ @ @VZ9kڽܵSc=}{ @ @ @ @ @@oQ =?ʌ]c,[ѻ5|"@ @ @ @ @ p-0kwEevo BLF0ʟ6)}K @ @ @ @ @Qsw"p7,J_sG=~'ˊ3H @ @ @ @ @G<խ2|S|g<ޟ_  @ @ @ @ @>zy4hN0C"@ @ @ @ @ N rz9o*\gJ?i @ @ @ @ @oqD+`͢Ϸ2>' @ @ @ @ @3VY4>gBVDZ 3)@< @ @ @ @ @3W1ܿKGJ̸֟ \YD @ @ @ @}%וfsZU-WRW\u @ @ @ @ @B ܡ.DZ?Q  @ @ @ @ @ '1Òv?ܧ>} @ @ @ @ @oxڂ']`wSt @ @ @ @ @*e7ez,con @ @ @ @ @9o^XܑXՄEJI @ @ @ @x%gn$Rtƪ"Π[sF0 @ @ @ @ pK1عL<?vP|E @ @ @ @ @@e"IۛlZIC @ @ @ @ @=a$W @ @ @ @ @'`Y?E.sn0&@ @ @ @ @ b\xk @ @ @ @ @!Z^ow78~"@ @ @ @ @ T~Ѓrwz{331 @ @ @ @ @s,?lE_8 @ @ @ @ @ #t9  @ @ @ @ @LBMd!;q,= @ @ @ @ @BR,[['U @ @ @ @ @[0UT~ pF @ @ @ @$x G @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ ? fڸQIENDB`icinga2-2.14.6/doc/images/addons/icingaweb2_graphite.png000066400000000000000000007544441501332562400230300ustar00rootroot00000000000000PNG  IHDRPZx iCCPICC ProfileHTSY{@:7A:JJ ĆȠ#:(X "E2(`>` 3gwϹ{=%&rD!~9 YlЃ fC׿_%@L8bv §@e"q4W"(B D'p霰/GY,QOHN@|*[ 8|y,[jq_|'diY s>ͭ%I eH=xaΏX</i\$ /1E}4^tڸ(i 4.0^1L@(R! +A!P4 %@H6AP1TUA/"t B`2k†{pNS,8Q߀><(J2GQ^`T *%BGJQըzT uՇE}FcT4 mvFlt*z=]>nDc Fcq00QL&S\tc1X2Fckؽl+ ;p83 .¥p{pGqpwqOx^o|)<.~?A#a5pBM$LFDb1XF'^&>!#H$GM*#']%>Ȧd/2|J~H~GP )JerI*c!Ðli+Z k !B6KTmQ9Kn\^qy|||k 8CBK TUEeS7QR/SF DccJ JJJJJQʆ d"=_iǝu^>pUUTUT}TTw6>UC-QPۧvYmT]QY~BaFMqM-M?MKZZZZ%ZFڮ| /iJ4Z2NבTtL6>#Jկd@0 vt|4424ld8lb023zbL1v3N56o5$5c ڙL+Loff|f]1 W5'{י[([YX4Y^ f [Y&[|l``cbԚm]a}߆bk捭-v;"vmvE#tE:^Hqtx񳓽S ?͝8/4Z]xpဋ ˥ʥϕk˭;ǽ}#kOKOiϏ^N^ZQ~ޝ> >>>|u}||cw24lF-c,!`]@{ 904\o^_ՠPpK/='O?ep4t~#Ըqu&L[s_-~=tVl9sEsO^Ⱥ0*lpqmeKQ/ix+:<:.\uzӵ3כnhiw-[;;o;nxkanw/w>]==z=<~ͣG`?{ZLYo&5<ſ}AyQ:=T;l=|vw˥/_ _M!GkקtXћɷTzom9CʇT?L%DWײo&Z~229)dXӭ p|<o@zҙ>yZLo?M?L/=-{"SD6V#,23stSx/RҚNNCC z'''&' >L>%[HS+kӲhiTXtXML:com.adobe.xmp 2030 1104 =6@IDATx|EƟ{%"4AW7W}X> VTl XPw:R'ߜwͲ%74wfΜ)߆yvf                                                                                              \;wLxvK$@$@$@$@$@$@$@$@$@$@$@$@$p䝱Qdv}5 @QPons*D$@$@$@$@$@$@$@$@$@$@$@$@$@gRc=}뀱2 \ ΄~&(8cI[HHHHHHHHHHHHHH_Jj/\Kbl%Ѧ>%ٶ1 KJR/KbsUl׸εv} g%k0K׀1QEep6,XYHHHHHHHHHHHHH$/Q:8uцnX$w,E_:fŭoni             8 W/J13.n}s[EN sqK}_|E>g_0%             -~}]^ζ@\o?+\o۷cHHHHHHHHHHHHH.Eo?;aWX):ooGzӖ/7}IHHHHHHHHHHHHHm?qmzŲ-(zSǓOqͰ=eeHHHHHHHHHHHHH |=\x{j];^δ\<*{kxvf}.ɶ:&#            8Mۮ||ȸ\W]ϫEa_wGjנ]d_7"            (y%*2[/WP|.+>Ws]}iߝ]76 [Ա5i$@$@$@$@$@$@$@$@$@$@$@$@$@$pVvggwgy 7+flˬ/ֺn%),Ҷ;_2]^Ҳi!yk:vt[?ϘHHHHHHHHHHHHH ֮lR$7ZS^Y}t[~Z̗K|V7yCPg:HR\ߜVEF_q2             w>ճ+drrԖLe8"[WMֆ$XrX}ob- ؗ6]٭6wy]&}XDDDӧ_[N>mX80K$@$@$@$@$@$@$@$@$@$@$@$@$@$p86..nÿIKK;%¹9m-˻K5XO<8{ۦ+?;fλJ3h_v޼yT]b              s@BB{~EIjX2 _2Jx*mue7H[?k=ۼ f]vɛm9-}i?m} W3h/xHHHHHHHHHHHHHH" Zhjj X#Z#i7X$/A:r~zy ̕.o.Λcٷ0Yvi$             8 8505P-˘ڰNִ7y`naϾOԬˤ[2ؚ} oڻ HHHHHHHHHHHHHHiN7D R VmXƯm2$sXJ_}qm.$6&WE HHHHHHHHHHHHHH?N7X\ V}ؕM%AkͮMlm˛:Cv v~V.ӱNci;N yC@t`;-l;fqnGsUx#e G%6eXl2HHHHHHHHHHHHHHOZձ셤%csZYmF%S=u]2d9 ]]]cN{[}k"5k֘,L @۶mQ\96ɶHHHHHHHHHHHHB vV|ͱ쿝M}6oũ Rh V9oNzM,>MӱvZ UT)fkN$`%pa,X]tAxxy           7Ӏ⼔˛i_vyW6-#;i V9o6wMi]:@ >>7h_vBbƝ>$@$@$@$@$@$@$@$@$@$@$@$o"`Հy { 7kM]P޼#E bӛָcc=llML \c kHHHHHHHHHHHH Uyqik\fMK(A/R(pMv>v6ٮb2mEJ 8pjBXXXHJ@5kb~m yNN 65IKpeeؚ=f.Z|N6w]v6Wcpi8z A˗!xzeo6ө3*VpY׶ (,F@NK)ٕm28ba:l8_Q5jab߾}ӧ;7 ̺3gL``Q߯` t^biw/nl;#Ev6fK[G%iZmkNv6]V两{dvήmӺ*/vL{RTW^'}"5);|rG<^ʹѾFv|95}]7WB~jl~N3e!GAXU sWJ^43egꗙܹ}N<Lک4d#(("QQۿ?֫k $@h^ Zl{ $@$@$@$@$@$@$@$@$@$@$@>8k.Z\<x_H?^w ofAQ{fXqpXݢ?W5.8\9'om/׽ƥB\EڰSݵ!S:3Qj\׵I+W^p׹'rmҏ٦.yYm L¢婮TL2m۲<̴)} EȏD#qXf=Y_fk>P-c/C .?3]2Ga ? qދ}{=X/A4t C?MeK!,< yEfL[&^z?H kTRkPf[h55/ˌYHHHHHHHHHHH f ԏ_`c#ѹbM.7Yy-\F K\AZRW"Dj !J{XfL%%_oSik3a>dvjyk,uf뼶}erP0lv#6A|So@/ʦƦ҆-_OAi5s]hCJ&im*Se|oU5gW}HhU ^ *qSGPTyHHQG7ڽ ?/݅6t$oڎӠ vU@@)%}ZPNʗ/ifHHHHHHHHHHH| 3 G-rCHntWDsu+~5~`wr1Y?|57^imާ]n %)k[緷#)=Lα2Xu`׵t^b7u. vE[4`rw6)3뼎euUjZq(5\!;R Icn~w< ~)@2#†j|jֺ,g;ҎX:_sWl̎wm5%SN!==y@uK~тؾm>c\cC`\]oN+η1׍|'\"EЉs/FÀI/p貃4؆]:`uk6zV1ft5f3^PGglHHHHHHHHHHH  «S?d2 CzCkv>|Nd+.elz,sf}_+'/3FYJ.>7߼1>0Pm^ysB|ukK<}ãXw" GWbg1{ 9r|foBJvqi漤[]sOi ] V]Ҏ.iMlt]d|g]P6j/'OFq\1G]xuwߋ3f@D@eǢΆHjw!8;9V~)oī樗:A.BpztCdUi>⋘:uiy r ٳ4h8::n^a           845 7DzYnjBn9j<4m1.5:DA(ԫ\Zo{-s`4l 9ƆR&t:cݚ a-?JZ7ӎriiO@Z٭:YewGJ)WU\R3LFΊ#BH5 ={E iGFlC{el ۠Ub|i N]:qPF bgx8VZi|#JO7|23\v(ڵ+uGsC۱3z 7 Q٧l)Lg0n}Xw~k_Ʋ[ܥXՋ[&ll}xwTV]s`JcY2}}":AqƘ3gؤSkPDsAwޗ\ߗnHHHHHHHHHHHZnT!qZ%;bVU+Zw!/-GZ#ҩV0/J|eX.AM[@@2w-аIstp?%3>B [/X½hJj3sIuf > nFn2Ҵ]^llҖ!M+d)(8$^U/W-QCJ&im*S. Յ$ߤwr 6EÏXt 5;[@ʕ_1O?,nN\ÍmY.s<3Zǒ0eq9X8ɱC1{X<9?!'{ ~|'/}w=ϖ8BkA˯gcڅ=q.ywi *e{TY6VO u^6'*0kcȘok{9V.Ęl4bܝ+pX-A dz-x䡇ڗS;cf hQ1.Q]raF3!P[nzw~ޏte NoC=k7{o_h FW`5>L-v[mCn}é85+ݗ~Ƹr [E?lN1Zگ=p.k-\/_}ڍog7tSxE{y4h`\eʔ1fg)J2KJBRRRIvöIHHHHHHHHHHI@/ꇆ[e'pC@B``b.j!^|thLO7fܛJWڜ jTFD@24V(.T5H-?$*!fn|Iy,:>5`ܝssc׮K[˒);b7miɛmb7]nt^ 6~{v!X}z<̴^|c#4T:jYp"d }i/@z *Ág6Tj!\#M--fڋh/>[w^ԫWޜ  V}TdT~"I믕[BTO|.qpbkWw: zmJ 4ߌ7y_L݉]'?Veoe\4W/TÆ#Ci#8JyK`:sđr(VTK-p!0//'%2뾉/[…р)Wce]Xz,ƙxIf[$@$@$@$@$@$@$@$@$@$@$o#qIn|c1bG(U;O`(v+!}`mIj-&7WBX-۩u?Z Bͺ/#2(=ƼWy*KeVlߧȪKhk].ymi*U  2qsUnӺfgeX5/u}!C6%gflhOU/36ؿ?Wp%0{D|0M?z417݌ #GI&رm'Mxy"v@}mq7Ʒml2JjzmN7 OV W6JnQwl|{/Äk&̉T94=0?ʙ;c 0uoڛzeyos/ 䚔kSڵk AZ$%%2+$Cz9'!!_(}`$@$@$@$@$@$@$@$@$@$@$@ D.ж$ V =\W6N .Xߵ.-h`Li+uz+3ٮ^AetGVyݎ5mΛ7%mt;f9mni7DLQgϞn Bݾc{\ԩ3bZoO3f 55}'O`/ʹ6`Y}!nWvTt^*S__ۃCr4>]:F㱎ЧGj~s{OU@-{GFۡ7SkR)Rw]\>h0jz襖W+neξ5}Xym3#/(۷oG~ "h/eu?|ԪU+E/2%-܇+f8qXE×ӗHHHHHHHHHHHIKZEi@h\:$:6+Jc;)x򱖛vimؚ6m5a.797*޽{dCѣH~ ~΂TNY}@bRF5X7l0?1ʒ"<;v}AͫOãZ֏71w7%K^lcmWrޮpC:\QUV-"yε iii~YHHHHHHHHHHHV}Q|Zfڋn6I[7=Cjmis.m-5>v#/BZҷش<W6mlni7ѴiS7E(D ԒQK|hX(ۏ #,<ETrPvhO!J*KcǯcFθtHz>8E{ېR]+"d\rZ̺ϗtɓ%'           3oaJ}5%K3KzGYѱuZf9˭z1Ar^GBYG }y'6J΁|;Tm9啀CЗo׬UC^KW Kbӆ8DZ Ѳ^XM2 Qrʵ*lŊߌԩS2%9(ֽ!}2 "W_ךt+i :66^li)s;3^;;ʮ}w>vefNb3uUl>ִXMFڪ) Xz5bbbPKك_~ |>2*5ז"u51M$%cӦMh׮]طo!藤.3F+i3$@$@$@$@$@$@$@$@$@$@$@$PRUՖn^*_vkZ6UTLbM:Hۮ2 njiv[m_rrL؆YYYE9ci& /جWHII~Ao_zu:tG1ejժQ'TE$@$@$@$@$@$@$@$@$@$@$,6uִKlRWYX:J ~vs3TQPi=tY7]&c7 84k̦& s@&MoݷhѢEGFlVr!,L5a            3F KڦX VA^|\.viStZz~M 8֠%`}Ҏ%f,q_NrIMrrr GDDdhh(dc            U ]6]lX%hAޑ;~g" :islLul5u9rѠA.y$p 2]HHHHHHHHHHHH_@[ӲfNm2IKtȕoI z:v7|ћήmKp/s|w=F{\r ˵@$@$@$@$@$@$@$@$@$@$@$@8~iòrDu^.}tߧr.3ћucaD@իBBBLV&Ir5pBce' 6,͘:ʗ2 ./㭟1w?zE1׷Kk9]^lַ$6]f%mR0UMIIE $@$@$@$@$@$@$@$@$@$@$@$@$@$@)K-Cm9j5m"KZoRGuLl:omִAwD.J0E/umn:oy\i              󏀝mzoyI5/eV;s<*/p_/3vғݺsN[cy9< N[c0%m|۵Q,[I֝2iWc5ymŏHHHHHHHHHHHHHH'` [mz/ݜծ˭`N͚~E\d*v7۬Zy?8~8␖漦&uUZ%.k찞n~]tu;v}r@ g$@$@$@$@$@$@$@$@$@$@$@$@$Ds 5WF,:m-~%C;@=t\fg343@ ++KuHHHHHHHHHHHHA@ɗOT36یD4c;Xt[],uRP 5h:@9mnVzNj<" KvpnHHHHHHHHHHHH.xPHZֱfL|u0]쫿N++i;Z]k͛3&             8 `;nﴟ5_mwFm~$vL)dخ]>f$%0e\s5玓 "p)RJ?gJ*|%:b4njXc]&HM 8kHv>2sWlGOMۋ">S[v|xýbŊ ,Ed,Y-[FժUCݺuѯ_?DDDSbԨQ +ߓ'O?UgԩS:t 22ҫvD$@$@$@$@$@$@$@$@$@$@$@$@ 6ԩS( H㗺M6m`I鵯7y*+EmrkZ%֛/yJ2s,e漻%J)h^(E)vVV222 ߌ_z5>sܹ[#o>,_KƢEvZCwػw/6lk?~<֯_ov͚53yΜ9lٲ!]H90D}& 0*r&+d敫a.MHBhj(m_]T;7nD˖-=6^8t*eK;^pT@XlvJDD˲ &cXyPbtAm*q"TDs0wZl?jB@mX0w ٦T}UqWrF[ DxyT/k7ڿj*_.d'!.0O$#9` G*~-ƒ0gXj'vaKz?8W|! Vɿۍ*Yuؿ8*":𪙘!U[J;S,Btf(ə|`/=({˸JSW&!i b&NBpT)eAdFD!8l8|KG܂~}l:H|4m;4+W)8[}ҚxQY[ԈC-&ݱ/t"xΜN%t~z/{<#9pIi*-?ލ//{)z.6Æ8jޙjiF%}N?M @1 L8;v@>}|nItڵk{Uѣ^r"O0+V@zPrb5/OU T[D7ϠyWrtD2h_ht2sޜ6u^b˴Mt^b :v|5UVŭC s潈?16mڠ[n^?p/^lڧx{rzm?#m-7|eBd}8_|3ECg<ݼ}u5c/&4moe 1${^n6~f? wc3Ӏvo?X %m;^OK)صemRưY \>#8vRuxr`O1]mvt=Ϯo1 R}}~nikG U_bۛ78[$K߾]M*dbL+`z,^~nnQP=4^?4ˏՋL;1{G,znC;$Q%C}ݷtfK3nǞ5Y89ұO0k˱_~7FT`C*V^ٹa]h#kDq9i"OvNo*V3b5SƮB0@9'~>ޝW?0bk.Y ïVucxC*){o &\ ;Ӓ3: ߹aH2?.?N;` ^{Mr8;Jn_<{ )^&~ѷ4g[~#yDߛnGϺ(Ov5;cE5}u׎weNKǻBY${ٯ_~W\v,~RRS|Whވo3ғ'O6|)S+%wl~d@%DYb, !0]27_60Ȫ O?y#ZVBɗ0_?Z67Sᕸj 7-/O9DmҜ݄'; ]!&qUW\%tIy07qW:'?׏k0)k&GD{tyի_mގG4h^= :mƫ׿'ŶBll?4FLa(k?[ D$n10#k"3DJ4= [#4!TJ,_l=ǶEn@鄾j&Tlǟi壞&yp9|Cji`ih.4JqJZxį1DFk3"IlrmW<⺟QF2X9$3< i LuѫW/nVAV֓i%}C½Cן"ּt#6nvTnWض[76k\.-uy]eg[) ^i/L{hoڗh/8ud >ƍ3xYg C7}}!&(/ӠsW Ap_kj,~N,k~%r czP{CF"4C<@IDATͨ uݫ%GodVu:_;w i/eR(Ŧ-߀ۮꅊ01Xpy3i^=Sj~~6Bn^U Q Y hdsN=>\R?%o2b+Z|[&>%r ƽ pZQ<4[6[OߨD{ʛ1B YE=oh1~6n/KFOv|lEh/M*6\Vد Px٥W?^@2 B.W?C;;R؟CX+ X>_eش)\ +[![EVasߎ܉u3\"TFACqI@=0k-cxkm fB*b/FQr̜їzťe1]m9>Vc`{^j ܫ n~5/6 oRRZܨp蚿b0gZc,э{+3s2DWQ ݻ`aŞkE5M,6 2lʹfb[b* E>#0Jojҟg`޺X5ĥWD*n~cB/j̵3 F=z?b"Rru^R5[aѼcް ~ 97^`*WsgTc#IDW24:{#(/7czq4ukwW <]wG79حΛLM\<{)~Z d|75){1>߿9v^7_lhp9s罺5XgŨ=>skѤm%ɐMx(sS.o1r\o&6/Ze\5k/Eu/ck{󔺆⍗עr@ fIB*0xG.r }1H'wC|j!ctq_MF'7bch}hD5ǝpTbFb#-?i 0v/Tmy@4j:vGEu^ ՝؃'z)BgP)|af9,\SyeuUuUW޵h~&oY?߾)gW5ƠCnDC?=[/ak6gO3|ib߹.%SRA>P:ɽk0}إshcPCr]:l]*mp}#JF8}.ޚ TSu/Tw}gO3 M`ܹD{'EY^aˬ~%2+Wy2kZPT 5kzQeo<%m>6]nѢG?$inФQQK2}iX\XAs0[z̟+CBBUJ͛<]^i_RaժUh߾iL{̡RJ?c6Jg0oe~,8\I ?;)#xbгX2=՟B2 _hoG  JwLwu W_5h5x7`%\qrQE,<;k) Ko+_?IObO:|7'2b`tTa5kI%g51cE#q oxԋ"&<'3BWZT9x}Zm[!ʑ3#r Tc#?g/KKvU9񛍇E@po<3vjop$0R1W@ ZT(ߔNVi;1szJ=:jPjIK=J^k CM;[w6lHq/#/EUj^j{ꏛ.mVKb%`a7s= qĺUBNOPjeV6j{eI;Sq Lj\Ҿ>n?T=V-߃fܖk>VTs/u|r-؟ Xh=k#MheƹKP(ZwBrjBѪZyuյ;TMW-:a"T^]ci 8|+R+ǫw廟꾺n>Unh\x׮4[ǹKRAU# e8Ll%mYo~w:uNԓ8A|h=Jn(;<ҽQЭu={ϭx<" f.@0E6jLjo?oRd⁸zD?TSWQ3PO"U5`b>/Mj|*?rY^N;J}/?E;qh[Z:'^1,ǗO.Aj0ކw߾+%a'8F•W^Wm"D,޹Y+v1wݕ5oϟ oqe|ҧ bO۱)证88MR/Z4:W^h߰ T=:š>Aus|ץ*8f\ υ&t?.+ m j35ZtECkiUm˸ȵ1G]u.7sT쥻Ѵ$jco<.prZH/G=xzJݗ4 ;kOc mޜ?|:%jVS8k!W/!(`9 ^G(ҹV$B 9>~oսߴM}6kE=إDCع-6>7J.bxu}iN1yi<ڋܮo\SϢ?b@Z_njgD{V6MuAu}V@^r9tF^aL/9J3/Q9%ˉ_ipw}/u6Wcd*,Q/ws_uUy|4Qͦ/{{zVmqpIWM Bwy6ۈ2]UϳΡ.Dq=\}X^ΨУq3}3X23-1A$@$@$@$@$@$'pANk/iY1ڟAږyH 26scǎ5ѿhwRT)ߴ;HdaYtHw|6( cmcӦM0aa%4^Iے]iyimT,fnҮj=՗rwu.C<[c!ZWËrO)$!|6EwGyzzHFe'QM/+{JXE>ÒE;$W^Pr Jkٲ6Y{ ~"%hg{HIB:r"[bSc #LS/,2*֛U* ALMt-Jnj/||n7k|BRY7~c_!j@'Ċ;{ᢔVC1X)*n{ƶ܍+ԦD4C}xch4\~KF}}N"M-GxhFc!h.>tMjTqY8RāD^$i͏Xp-*Gf5? g^4oVUe98zmfMS85lf>$eT\Jмr?m yG=8"R2-j;޾ j3sZCo}q#vLc#hz }6DOuVߞoFٱRwn{򷞃-Zf798q";)‘Q.dކmΡZ{dž4rWcQ7Gժ]$pD=;~Z TZb~c:dpw̙O9lt!|ޓ^ FBlr6nP/t7aZRDت2i{zQ:FQ=A:ڛSiϵgQ6E+ډj~3k^k^lrFYꈨ\Jhr|ڪWu3NT; /UQ9}۴wҜh^Djձ#Ϸdv< _Iej$ k26/ >kR !{ ""(R}E|}Ê+ bA@iJPT t[!w;f ~ܹs;sϹ|i$X$}U4J1*I[QHDJ˰c8)۱\u&Ώ;:ڶkRXτ8[ a*o&JUzXհGmISRRNlLJD)ƒnM>Vۻݭ2{u]bH}VdP(YN6lL5-$!N,P6)(be[$ZbJMxD΍80O= gpo2[n<ȭn?kaq{dHA4\Pa:swTd;#Ǜ<|~?~.QIpzҤ9iXu/~=a{Iz[D|Ǝ{\I˵,VGõw[%:j}JV휬>x7ȪCae:[kZEk͡5QJ1ENy|<(]RJ_+8srϲ̵r[]`ARVEo,'Wp Le::˧NC'h$=!ohp/RF(O35x~z L}xؽE별sB#S}W=(Uuk?~h)./|ʳw_k8b'd݊R} g~}P+7n5u4eK\; I[nqcJ<,[TpCя맼DmC0wծ+ 8ES12uzTv !-$&nްqΖ= ʸjnO u I?Ɉawλ-RYC}kp^D!llܬM .AU??R*,u);f~-7bBJ7v ~I/u:g~{=s-ؾL;ۼ{ݛԮ;LA ˼^gZ̒H^.[Rtz oߎ=vX]uJҝtV43+AvWou7(T~~/VB񻒾sf :@E>(~}}sߴ#n뛤.1v TV!}c)^gI_ajI_e9Rl>Q25~K؜w~\ (믿xn<ڶm&ڻ̂ xsêWnpYLT9e˪VBKAgq)Q S,y gдT&M+}V8VZɂ dժURJiܸW&Ѧ vvkd"{obȑ&Aj!HܽK:g1?| 2g)",o<<2 9%Fϔz`}eZ~|5t_}!aShbH6Rp'ep_*T,,st0ki=xcSw57$,.Ng T:c{T~oc-X@uyzcI[ԛgyG=9;m'K}ރo]oGޒAdɏC-OSOm5NGEk~Y~TY WUbeemQd2vyksۿD:Arc0fTkyqynoy7$L֏yGz;$~~pH''խy^뮫 ϕ&KdϒdžR~]8ROIۛj95xh9Hugqi v_V0N9ed TݦR6K]M EF@eK.RNMɥ|e$LENO? nFOlSX|8}Y@ֆ4cdEãbeXH[~\Mɒi3d`]UsQG]OHwUv^3K)t.+sͰpX`3f[Sxϧ^6VJ5x!4-&|~pɛK%eSdqnMOK UUxUGjK9''Wd׽:9D]hH"z=-e9ӎug$h^.Ӥk{N>A8+eHiUF〿%z'2~7:#;ߥE>w2>nZ,(3>xW5+~7Ⱥ=*;u1^Tx-tz~Դp{6jXV%uU^e߯. Mw.]Nש!&JԔ:.-#YCeTwn&#,r޳M6y7qO~XQ[tt[#cINM²{"!0wQ|?B4Y^.O=۵{e+TS|T)r\PؖT ߘ~JU[Q,Pxnm/Uȶ-WUPmI52Rz[۾NIJ6{U?\Qs7rG-+N{x⺃羷`|oqHHHHHHz)-[{ ׯNgr?`0ˑ_CXVT42ݞ<%-w5LcCNmǎχ͟;GQF _J=v ,i,Umt|L~Q̠ezˎvcqUvψe=utUpvx@sɋmޔ5Lf.tqi8P&} 2U;Y@n9G^7PLp} @3:'*DYVqdz-]O8kDg0^IۚK޲QXNVo}<Q |Ƥ{WC?Y~1yNor.wR&t5)!/Jz> -7;Tn%w\_Ôu)^*Ǫ7jh SNB7QR v|o? @Dǒ ʵJ|Ñe[OGXVFh?j(Ӎ~8QoJ/R%ωtJ{+ciu~gCX#yV>YڞgF˒'O yy *'СCnsg&SZnj])p$үސ'3uvyR:奔Hw=VbB$>'yLP}ZtΡJDT#8 [vAXkӬMM2vܭjN#R׾A:K.x9֞il[ymmϵ2o_m2Ӿ}R٘`K}i?Y=B9Kmxxdhs@(ʕ+ˢEdÆ f{G>qe+=n0˗/7b=*_iAO>#}`\*O_ME7Ԕ K?#}`Z_HDxг* zͦR/oL{='y(2.ߴwɲy?9ZbbYaS3ʸ%a( Tp˶6 l+Rدb7({|XSzĝ$.8DkML=瞖3oD{]>g{Zj;kBIdf)xAWR[C8SVm9`ڨR|:Tuxe^ZDzǵaKIZKny`2P;άEKWj5T~_^mSI~f=#_0[1MQ(Ԓהq}e7WϸHHHHHH2J^  Ub[ n@x(i&dɒ^xmhc4Y`kQ= OЛrȒNx+c.kk˓>Uk k&kZH}ux!Y{/U2+ $U %tx/.۴kZszԁLyxV(Q[-'êJ2"y}p;$-GNk\r}FOtWJ:sdCO/F &moj/5Hl8%VI$@$@$@$@$@$@$pHǽ x}}_]0<,o{ϵݻ[By+}oۺ۵W`ֱ-!f󼥭<XikMKIzk5 F>9            +@V 34Ho ֶ-Z#ߞ湶y qly;ZzʦN#             ңlu^^֞QWscK|IHHHHHHHHHHHH ]AvtjxP6=S/u>Of/ ޖX; \?.W^gx  GM\^ $**ʈ?a @Nv1YtTV-'mGM=XRPR۟VyT¤N:rJ9sn͚5˅$ UD҈e{[?$ː UJӄD*6y$@$@$@$@$@$@$@$@$@$@$@$@$@$@# > \19}~;w;IHHHHHHHHHHHHHH 7 \}&_M$@$@$@$@$@$@$@$@$@$@$@$@$@$@> 0TO%a^ HHHHHHH._|?;HHHHHHHHHHHHHH @ y $@$@$@$@$@$@$@$@$@$@$@$@$@$@/ gǞ \(_"OHHHHHHHHHHHHHH%@s              ++C) \(_{N$@$@$@$@$@$@$@$@$@$@$@$@$@$pp|<              ˗cIfM@IDATHHHHHHHHHHHHH/J%dyri [Y62>v=8qℜȢN]wP~.E|&H V^-o;wZP!y駥v*C1Pwߕ:u Ց җ5(/Պ˅dݱulu EGãw/_>m dYs+?!:/: /4L6?kR!\\_l;,p7w+u_y ד/\ },\UU???W^f;vѣGٳggϞ.GǵۭE"v?ke5]yMZRZ**壵YWofh=z n#GΝjInXay^9yM)6Z*l gR,Gd[L$@$@$@$@WFdMp1xyߍL/ abJ^{>~p 3S'pyywxF4 ޷zK^u?gnE;%~PGnї/DmJlVo`\#{HHH#pFQ$v !w4oWQF]⽿% ~~C{N-ogPP9ZaD~IfI&I*UcǎYӈRzuO%<<<̩^lVوOq[ O>+ʾ+2o<Nŋ?x o0R~2/q<~a)Qo2e)UlذA>3)V˷lR,8\v)/_^ʕ+'Æ /7Wܦ"}IQ.Otzh(Wvc=dy^t;#5pLRτoZ@^c'mu@u}1Wum `tߑ!˛s)7O_\Q / m/GoS?g13e@բA}+OGY|s}mlܭ^S4͂}܅Fxr3b T˧I KMז~KSZջr6 m\Aٸ_pZ,c">[ƿ{r<%    +ݎ|pJzc^&a7.-9NМe^ ,|oeGU`AydܸquV)_w}7o6a4i">۷O|IILL݈{6P^\0J=|=zTwn^N:ܹ{イd1bP@A~۷y;~xZeK>+|qɟ ̞yPm1M$@$@;;HO%0i O{ءmQ<I%캚.-Ãj6|lk4VhA ѵIyEeY~k#b]Ng>=U11}=\": W~~~i`G:j"NX}rpo'XW o_SU9uLs2|k*/{͠|O]:lW~BHt(fb5+v5SX^'~ܑ@ܤ϶IHHHH M]aAD{mփWfY>TuKҡR)4(?񊂇<{K.h" Bُ5ʼm߾4ooم4 uc@PG׬YLV ~6P||4jxc1ue;֠xrgxQ͋>*|rr 4x/[<#֭[U`(ںk*ZzDĦܰmfEMbrsyqE#L .UcdKF_TWW8&k Mt* |ڂ?F#{T>L6(<`{3!|}x\ƬOZXXh<'`BK=któKcd;1;\%KV2Q q& :`n((kthsˬo@^wD{6Kv&Ni     $L,C5k ə\9Ip2e5},חCW77qGn2ђ`i۶Aϒ>-ԇRz-}l !~𒇐߷Z)JE*b'mk˚(b<{DC[UFꕏk TR{<-LYnvܬ>eg; ?ڞb&BC SXq9Yۚ7ݾU~ cH0 F@4G]x&aP 41e ȇ=g~Os0KKLvc7 T6X8'Ϳ{r6"    +@gmqu["1^v, ,*FYA?aW/Nz)ٱc o~K?y򤙯74V|9fႰ ">B>}ڵmQ (Q fPؗS߹ W Sȁ#~vjwᢌkqo#\e;bx.5HpM$@$@$@$@$)qi'xw)֜=f'Mvc9}n~[̈E)&}F_1+ЦLxzxe.^N<!^h$@$@$@ sw05<6={9i7% Zm[0B-FPWWpw<~uC`;B! @p٪˫!i&eƌfpjb*$<9pɒ%f!CȰaÌﭫ[l).\ ,HN0DeB^x Ԟ+=ʉbbtB~a9\ þ^sw).o'K f_|y1)?oKk :k7 9ZẑK0s?\LA sh)r;{R]䢞C (";` UĀ=] |'QܫMvx#z#\rL,q M JFV.cNV]ns5w[WB>s2zxtz KިsԯЗM\|ΰiu}3Ő,Ci!:zh:t9!R^R7}I'Nh"EH޽eڵ/2/e E[~=g1evgަVm_G_K^b1jF$@$@${ s`֜н]GZOTOf<*v$8}ך<oq1~ ktp3?<8|,#EŘgLoGz|Ay뭷L$DO5jHc 00}]g?pҳX̀Mx2 `xfYI{{DeCl *Û8,>񢼷f}sXCǓ̝GdFdj w'[{KdǵzBum;//"sTo{Rʦzx죟 6scA_o9s['4Z@Z Nݯ< 6w1iq?ogoL h8ߟUG +:砅o7gs HSsbNoaoYňֶCrl1lHHHHX5ыw.D{kNvS3b{9Vƞ-mam-觕L[yX[ AVkt))>Vyκ,-\_կ:_׫w}&ehgY '#IOp W#MHHd㓉c=Ә^}:/KwW/e)MH$QN7R/ui$@$@$@i#kJo꿶9q$|PZW -T@ ɧ~B& {TO[x=v'yì~YHHHy/S_t'?HHHHHHJ p Wvé8)?-ZTou'{ra?*%l% O \ÈЌU_޵4q֗ ^HHHHHH$0Y8/V9-t  \(⧴{o6KE|yvs}pDj4~e6?+cjr8S#eIJm驆eIHHHHHH ` D}GnMΙ(,z50ؗ#R*,Ns% 3HHHHHHHHHHHHHH  PAiijX_ECUp_~}-i:1*Q'\Wѵ7xao#             !stZy% H]G}u߭fiqEoꋪP_Twj8rM o맑  k˽*RKraZ:=/bɠE[EX=;>f @np[Sh!csd-" 驋eIHHHHHHHHHHHHHr@T[L6_h*wG Dr᱅rjX^qv7f?$HʆGOğٶY @6nB[{&j?l;,Ӵ؀2ziVy~tw_RjH D*HYJU0HHHHHHHHHHHHHR"@>%29wZ-5jVYjZɤ9G,ۖxtP`Pfysnyff""*t\PvO&/9T UuSγ `Y~kEtO NvMt׺Ӵts`4mE%͕ PcWٟ^1}7)-gB]y{q?6XYfYKn<ƺhm@tp61*Eny"oS~j Yu.dC$@$@$@C 66VBC>͞Xk^!罼I$@$@$@$@$@$@$=vslߝexOMR |Sd=ځw>hPGxvOZ۴n /~y5hnuu  -lnzUiM dzgɬG-K?7Z5D.&7IPuGh}OoTx1M* qӋ} +To0xޣ]OO7Ur E9Z6HkIO @x_SDi p,^۪k             zg _6˫vJCL_{FFW&NgEOQʭ׸Nf bY*@hM:}i+<2<-׾ho)^췬c VU Vy$@$@$@$@$@$@$@$@$@$@$@$@$@$V)tz]HRyJs%2 ?lWK~rP|*h<}}#ބ?]*'mhN &$ufAnQ ^_`tn]]*&1&C oO p' 8PσW”gM NʄGFd8e5 ?8jM&F }t^Ş17z{|?,"}J@olE껲^)ܻx0A$@$@$@$@$@$@$@$@$@$@$@$@$q qvrM*ʎ2k)}*z禙AY~>Ѷȇ)S?@ H %\/6wu A4             $ WT1mW!>xB7UN cɷ"(H?@Y{@dF :g}pVzwUy%F/[A򄏩w>{;1IHHHHHHHHHHHHK}ze=dDMb^ ]]}hY\7Uho[ZwNy{o5 @tfL=+lQ܇Y۩{D&m?o^vLEO8 >h o{S9ܣv>'uB *EyO*V<\\Y}g.lSm@P"CG!$ σHHHHr@ߟzg& d AG?8SyएwW." E=ֽr}mYKoE/E\Bo?gxND怚$@e77D]1A$@$@$@$@$@$@$@$@$@$@$@$@$@i%Pi%EFg:E*8mW ,Yj֦Z[yxɽLNl@y6qGsce3 4x^ykO 0o}Jԍ-@#             tpN`YQ(:i!Yr褼vԟJ^@Y-l?uUנ差e%gyj^LDpˌxn?o7xo];4*%ԃ޲k9|iuV)ܵ @RlrYB`փ%un]*[0XR2xwߔvg{><ؼ͛~h} [KJ#=ʎHpM+DFHHHHHHHHHHHHHCuU2{ʃ~S3 -r*έxcwL?pU6-m$iVbм F}!ZŭHh`>>L @z PiL/˼|eef{\&&=+:{t D#L ݄7fJ|Z<=֞ ,teL0d6nגmɠ(Lu#mf=t $@$@$@$@$@t,YDT")//-ZHPPP2#!!AH"/_VIHHHHHHH'}Vƞ-mam-舕L[yX[ g˳Yy5xSR>}i%K & oafR=Έwm_MKoNJ$@$@$pДy{˖%^#p9{CrЦMg^4hbYƍghc5\*y @пj09':^ȳC-Ͼmc홶tmc ~i_y>ǽ ^ @?|^6{ݙG3U| yaHHHHH U oVe5jԐ1cdΝ;hՓI&ɇ~(5Jo}$@$@$@$@$@$@$@$i$@$@$@$@$@$@$ڵkM?ޒ={J^dƌ2ԩS&=d]̙:ׯ^رCx;+V .HNaÆ/;w={$@$@$@$@$@$@$@$(gUI$@$@$@$@$@$n7ސUV+" 2˖-3N8ato-ݻwѣGQs=g{=xL2E0/TR eȑΪU]c @``|x C姕ˑ xo޼Y WTIj׮-ERJ%kK/$R\9>}`@b"G}T6nh!o^f͚ePdO /H@@5 d9 Y U gҷx9MH޽{yA)xIL#   M;pWf͚s\yV!ɓ'e߾}mԋgcʴiӬ*qsm#*        @);NL ? /̝;7Yݻ׼\ON?x *#;lSO/ls0O?-O< +HHHH u`oij(ܧf}jرc.{w#.?qD5jzEgyFvj~       , %I #n:Yv<8Ah3nr]wɘ1c2[}I&B嵃$   0dɒ1=B#=O!l>5[ >|s;S-Ϝ9c,XPڵk'۶m37OHHHHHHHH 5 !'@_fzCm?#ҤIps̑Zj*Dux7U7^2DZlۺu|~W^ݺu't e,X`@\ \2A$@$@$@$0i$nxܯ_?\4c oMw.}1l2CaoYhh|f$0g5Oo=A :uVfM| 0=귬Xb4       I  \/]bs /[0SL?М1^>sFNjVx*aeywL𦷛o%C,=~mく}ԩS|b탂Lp… ͱKg5=aWaV\h͖hmx'ئ @f XzyxAw}W $x& 6s8ff %D޽{ Ah 0$n͑ mf, <`饗KՉ'ʄ dѢE b>DW GW_}eE{B1X3"zǎ& |HEڅ}J*pׯ7/^1iZ óvm]we) >\V^-G6aSB6/uF|ar J#   $D& *޽{~NK D$ DgB>HHHHHHH yaH2"¿;IaݺuiӦ}իgOKaÆ&5= XǛ¶QFɚ5k~߾}aL-8pzf~z{~ocǎBm^3V2۶m3U PBϟ_ǜHHHH  `eˤy9jkjժyS xp$@-Z'xB9zːKѢEl>mQW,O<߿y@ XڵM{h10x_ïå}xha~o2V]8>pxf h$@$@$@$QH?~܄G[sHHHHHHHH6 yaH ,Y;:NJĉn}>Fxxoڴxϝ;׼T>}tEBCC]ۅsd"? {1l߾]6l`7nulzy Ps[s7o!?CRbEs~ULp]B@L @ nNr=s!4Y{4 @!p7;aOHxR G3;Μ95=W\sBݻ)٘xȃȏzJ*֭;vvZ-,,N: @@{ƍ3U.\XBBB\M65sGDDȮ]ܚ)RF]d!/ǎV$@$@$@$xZxĘj,YbCAxF O$@$@$@$@$@$@$@$@yq$xvrnO@Fxe˖-r]wpߪU+##u5jdLnjѮ݃T?ԩh/{}goBGEEUoCPv-Zd</ (G#   hӦy4> 8D6~IHHHHHHH>zψ=$%PX1Ӟ8{p&M<1֣GyGL"СCubMjժomqD8}gBK/$j2ʕ+WD{ۊ2-[4!~V5^۷)b kA[6;v4}F\\6aȐ!0ԅz0!s S @:_ a eݺuQFV$@$@$@$@$@$@$@$@y@4t[{)+m1p3mam-(-gHES hW'9i/Eoɓ' vz 9GgϺDԋP!nih {oG? CU*5 @@Dݱ훮L  Փn-ot       1ܥ%Nxbei֬\p! @VpDY ?{g/Etw4HE( (_E@E)A ~g]-Gofg{;vsIH 0ee˖ٱWYfpmIܹmڤXWHHHHHHHH* TWEbIHHHHHZ'IΝyww!N#       k#+#     E±$@$@$@$@$@$@$@&X#$p8x{r<3   @t鮺>vɓylHHH,SNray7/Z?wtQ&L({o#Gĉ!z1c88qM$gG^߆8%2=ZkiРA߼ys?YdRL } 1ߘ\4iX>cYvV+% p_T,$YHU4i GE +~WLݻإKPC  =s66evI6-q_%>32d h1Ǩ!SOE&N'A$@$@$@(~w.[RwAWn)njB$@$@$@$@$@$@$@$@1'@>+xHA.H-7n rTԛ07$"1Ǥ3gU^R%˖H~뭷Z !ƥt۸v wvM7Ib,;w;IHHHEcz+W Rଋ,[=Ez{gH?i$sB͚5m:/W'={Zpvd88 ESN﷢ڵH_ێ~O`6p<(Xj) 0EΕF$@$@$@$@$@$@$@ w!TN_Hݿ+!LFg;wJr7{G… u6m۶(!ܣzȎ[`>ũ_1imڴ(-'7iDv%po^gD{!p(  zSLX¦~I(2e>SNɓ'СCƤ,2x +Q *CM>]<ȂPR%y--82gl}E`{7o> θ7191(|7AT{ٸ6P7ԏӤHHH.=? !e=z'A;"c"~?w x_p%#©s&";Ă!#CDjL8ߵkb*R,YU.w}g#ƽ駟Z!=jC?v옉p(R@E b }>޻ Z8lǜk֬%mD#5*Ⱇ9"p3 z |&bP=vͲr` hb`So m֬YW_52i$+>`sR@980`)!cwբːMH 2 `p @W߯g϶}1=?EYNpu {p oD\[K}kg 7pv\Y;&A*.IHH.1~@ |?ygkזܹs[8a7oS3P~xb+a2d~=*UzqHHHHHHHJq a#F"L !_douDcc۶mk̙3b7 kӦ ͘1C~a!x#Z V0H'D#)Rṛ̏(DcD^h30=*8DU`A˿"eLyf)TlٲDm8 :Qp f8;cIa>g*#Q`^pD@W,ap"@*W8S' \r6l!O5t3w~npۣ~ vLm%@Vpɒ%9w6Qg6"HHH%LNpRDT=~9۷o&ر6W9wwIHHHHHHH (Ǖ#kE`4 P ΐ"0 ˗Txa屄> ( E(iG?0` 8м! !;3]n;[:C=Ѐuo +]zݠ{6v~=.U+ڃc gX ·sp۰D`2*xEu~蛗%^@@ { |m'Pms`]|O$@$@$p SAS6qDsdoPy4;R2>.IHHHHHHH (܇(#k@-1wB*"Ge;ԩS!;@ q悇(4Ç7gGxDCAUg. 9R#"|ذaʸnu0 " u^DŽwAlٲa{]/ |8ТuGg^aLq^pJp_q԰n}TKc ܝn^'u/>Lg]t?&>ڈaWXHHH" ` LTbEjl9 cf"2|_X1;wʔ)cg0=Riӕ!P͚5&6dP5koDQwqߡ5R|C$@$@$@$@$@$@$@Is_$@N2ؘr`Gi:R#K$P uSO.\51H A!M;C?P1HAL2>uo`_\:zGj*sF86!O>N.>NG)[?c9p,]Tƌcc#{G)S92!̻hx0/l}~/ttkaŖsɺ[yu \GY{6hh8Lyп~QۏM [7̷$@$@$@QȬ%:w.{I&6>*]߱Cyʕ++WߔpTIpHuSw%D~v9"2*a*#~r {LH=$@$@$@$@$@$@$@$W+9G  ";A sc֡CJ7?]}D#biaHum۶<5j<|&駂ϛn= Ȼ<1h߾B7TǾ|Pz)sν`Z ܴ&M8,vԁHtrFTܩS''D;HSOYp,u{8ȫW.˖-noX^'d p9^@tb6mx:xWN~TmX9½{   'm6~k2[λ;w߄MO~:W !ʗ/oN~#wXn\1[bK/iߐ @\ WBw[u KB n-a^(uL]bPgѹGF%OC:@?!<" h 6*CS, FU޻ϥlՙ"E oN;} U9>*PDhر+ }E8 SL3.m^6/C$@$p j`T`e~nF        C@ue|R_{sA^ sv۰tu ֽv+Q&zT>Z  \H v1!>m{"Pu;bjQ1iW׮]- R#>eYUKц= @LP %! ) HPp @P/& @֬Y/ @`x e"pGgʔbnf \?:C\|o            \t1y$@$@$@$@$@#0۱;IHHHHHHHH PHHHHH*!ФUk\'"       $@$@$@$@$@$@$@$@$@$@$@$@$@$@$VÊ @P/&              pVHHHHHHHHHHHHHHbG}x4 de$@$@$@$@$@$!PHղ aJe8m6I$@$@$@$@$@$@$@WWSgW     *h$ҠHGD~_*wHERlKODNy!:|WKwmEnyi߈4K$y27]YCKGEk{yI9 E>+˿$@$@$@$@$@$@$@$@J񊗕 \wi\_YE-rH> U?~Bd$m;Dn'Xs߾~#E C[w]dگ"MEI䇙*/0֪u"|'>Tp>M-R8 \$ uCa" WN{L~F߶ *Ò'_]dlJD>v>j>>0}H"JLվHHHHHHHH.  @&D{WϿ5ĉ|횉 ~]jVqFkT?3Vy< @ 0>\%mڴr9YzJJrmn*GEjFСCqcDL@=y.]:2dkH "#GjGE*rQobG:~}"ysT/}4        KN}zJ$H`[ǎk"}:Gڟ)V(;wl}qǹ};w~:ez+W.^+Sԭ[W6lpIdɒ]we W$@$@$@$@|Ȣw_/Dɭe!pXt}HJ$ ײՊ.}8        X`d!̻msĉ*D%KȾ}$[lҭ[ }wLLjGN8qAGf3m={6[a$@$@$@$@$pm/OԬ RHE>{|1kEfyW;K">,F *'=!Q~udƈ"Mڋ4}Bd_}lέ"w&RjLz2tva{ [_͛ѣa-;vȜ9sdܹ-.XHHHHHHH!KѳgOKq|۶ml21cڽ{:uJ0T @DmPCnyᇥK.Ү];;%̡ʕ+MG |-Y`"ĉeĈV>ɒ%9``v֬Y3y饗M6?oiT"۷ |[l_ݜ fC6MٵkG֭[' D;g'|R6m*k8ZD"tHHHHWRS#> _z~9 V*knEvQ܋D^xWdA$*ڗLa=* Pȩ"qe"oQaE ^X?3`l޽ҽ{wپ}Ոlh}z8n300 ^JJVXa }7|c ͛W֮]k哗_~Yz-:u)Sھ)RM7$o<&ڣ_pTHȞ6hӐy{XG0 |R\9߭[77A4i7>X{s; C}j " ul{x9r_bNx (axxwG^@\GtIA *X伿@&c X!91#O>z0hC![$@$@$@$@$@$Sx4^G6zզM;9 : hsZ{&NH?g1=a}[t=?A !a@/[="Ct[987쀀?g_r% 4l[\<C?va"=#CgyFV^muM\+T4 $@$@$@$@$@$@$@a!@>#s'ci!"^NAG$|(C=H14dqX\HeW_5~2{l<86&ԋ4)\-13es0`5kVٽ{E\0hʕ+[Pm_p$x->B@#     !<^p7n=?,YDp<k.RNN4Y #iӦYY ,UTlgA8,É/góTtg-dFs(Ñ7KUO>}$LCֶU\L:YHHHHHHH.*reCK]GS4Cjz?"k֬)y޽{Md@R!+VL08f͚eiJAzuۻwotBGD]"M0# /^";f)zב.xL%]PHHHHHBX>bs84cٲed-M\xg̙3F;Y 0Ř yӦMxٲe=Aoժ=[!<혘`pFQ쮻}=-AmԨQhOTϞ 9rZjYSLu       + ԵkW N܉0vR(Cƨ 9"?0x&PٱG$z_~3Dգ UZ5믿]@z@C P= DG";2m޼Y:vh?=w=ooԨ=`y X?C߿=ᐌ.R:c G[{ϙ3=Ӭu%RȂ!#ϔ8~'s.Hg͑#GJ&Ml Q8_F$@$@$@$@$@$@$pupp0<^ #k1vj}ٲevITBc֭W0 Q-c[% \ѬW7<]d冸b"Uˉ?(xԫ*rl\: M+"otNQHҾc?tЇiƦ$CyS`J| KWP'|bч7|ӦkѢM-qhvE4< !ֽQ= ۻw.o޶!3n=!Cϗ/E_|Qz)}[FMO̻n M.X`nܺ["`ۆ{ x}nwdʢ"#uy` Hj!AP/WfCJR8``rW"5+s/)v߿߲r HHH@&zƊEcn\GUSQ/`EfwأDn_+yRMT_.U}"v ֧=BvD:!گ(d{]-;p? hMM:u ~_7)u\@(,ۈG\ek ">p;ډj_~NC4 v      8CO R UsA^(umnێeۦl_{K;GFQpH@zRtS-`A͚5Gܰaך41I V7G +SLba6m43fԮ]FX! @ dRG:uHMH5\۫0[~M#D^%RiuH{D>~])ULq[lY|O]IoҤIcKjRm uO|Q1#Ki+*B`sH׏EQ1ZT5I1Z!TZ t `\ҿE;D2)]T}ǤK#r"eKQ4?5gDRmm+RVE&֭-Q>CD_        &t4 0G7 i{mc?B9"ԻϻD:ИXΜ9嫯y?3f)T6̰oQ:P.k#mCWT為\Õ6dHHH ]Eo&?kSx}K_/,>Ѽfa?Yf̏N$*HD2QO" zވ*( 3Me˕;IY.H y!|)֥m,Q3E^pQ1QF$@$@$@$@$@$@$@$G#8F"߹c;{Wrm˗mʼy`SߵkEo߾ݿ;6mؼ{G5y2zh[/={HƍEv9M/۱cGA>74iR'L`kN;wJ*Mh"ի(KZa O?5mQА eciYYyZy_;"~-h'X}D[ٳ| ue?fAzA<:HHHHHHHH V(  M"wÆ $!tCo׮l!;;vLwe̜9#GҥKKժUm7{:"aH8=rӧO2wE|68 }РAQF&o.ƹ߯_RNm~׮]_[nş~?ErPxaH?w\'2 aic6nhK8 ߳gOs 4   +@;j/}mS(HF:}:45#|k7ei<{_V)DѴ|}ΆRJJܫ?Rr;kz~X&rL#wi.P>{_}o(yEڡoq YoueԹq}-|i$@$@$@$@$@$@$@$@a#@>l(Y \;߷o_9}ӦM`I$QhԽ{:u,n)!VCPPP7dȐ?Og Dp8 L:Uv!G!rV<]:~z mĈǕquy`xߓ \&CToJ##"o ,ʻe**4kϿwEx[˘dopJSڡ"*RH"xe` '       H \ ctDCTЌ4?@,pD vږJCa)!Ge˗uY4?qG> fMDͣ=0d@}wܹEω'G#>m۶ʪUdٲe~+V oFY0lƍ #2ӦM+H2 pweǶic?RCF-_H;RJҥKI(QwmiQp8@D;ѾFұcG+GCA9KN㏼w}ٲeO?5kG?lj7|Zj | M n a^խ%6, esۼK'Wː!HJ'ࢯt/Dyz2 ,!=={=Hн9r4({) i;f=`} eP"}`h uñ>3E*~n#  ]IXg0? :       kjAI}!3^,ͽ\<۰Ͻ./[wۭ@D`Qms(B$%q8W\M!]y CGj,Ctw{tUݮ|LxK(% Iyk     p`w8(        $t4               DefIHHHHHHHHHHHHHH(>               Hs_Fl4Һ \ҥKw=OHHHHHHHHz"@z      x p/#ę8[&     (Pw@ uNꆄQ>    h>yFo-C7D~a'%ݫ?!a);s!hS`b+Lٶ_'m=vZ>~W&{y UZܾO3gӋ9;䞙t9=Wl|s2~>N?G紂WmǤ l/F]B,*هjn:yt_UG#     P'H@#N;vO<?~\zAժUrԩSe͚5熫@[EчY D6BHrw H gf ]oN  oeMXV9!C!_U/PJ `Ɇ* ej` /K?#k;^|naO:6^[[δ!n $\مdEAjY>rAytzyMR)sT?m? '/7"ex"ĵ;42y#FX I&3C0MVg q3z%$UmW T8.vB\9`LbU|xKn=gU>`YUv""3|ymAs<NyD.̾ۥE̒=EI݇%GtRE?3gy3ɬ%\ZF^mrD I DI\yo,CV)$ /w>Cj'HLf뿭JA[1IPNպmIbRu2QK%[Qut77*c΃L~ΨӼ:Ҡ$͞C3Twǥ#enZ@o/{./\"lHHHHH 7:\)U$MT:t`gΜ#FH4iARV-I"|WQ 8p@ ,(哗_~YtSG#Ϟ >}pux'fgP(X*<{3EH"C$@$@$@$p(Q#1DMNɄ{elr8y hGdF:fjV,VWs%8b! }1˓N|}B#[Zg\R@ˌm 8׏1㙈lؗs29됵ݱMq{IYc Emz]j$!]~qi+ wUJ h.!erKY}V6=XYJj ?=ϺŤX:N/jԡ&=K+6?I_Yf { o/iצ~z/ipQVHpX[rɠ[ ɓ&lk5QҸR$*sQG.SkVP~fsGץ[d[ q3FYv=:a_+C~{w+%s]P$zLknqɣ}Ykd_rq\;g8+_&VTr2TY*: =3Vw+<1G9?o9ρ5??E>>7i:3©G*/0Qzִo|wϞVjN\,c75>>};M65hW4zGEҫPV)b>5&~7è/+e:& ULWdt>i$@$@$@$@$@W. ݺܾ^s='Ok ?_bEV zEm8믿({?}Ν[ricǎ'+GҺuk0aL2E&O,ovRLiN؏Hԃ(7i$Ya5vGx!g}o_wu=ڶO>DO']ɧ^DHNoL-2s+VK$@$@$@-hAS~^[bgJ}5wT+_FiA40}"Mt_-哚 =MOqu},9)_}*άS/ڣwhw(X\=p_\xkgPyֿ]EUi#dݥ ǝUS~U'-zL`f*TYLit:ޙqQ ]hvfwM@?qr*6mKW-5"9h6Q坹ɭCJV:Q#uA퇤 ưGU7I*7(-ܜ:,4-])6s؋~F6uE!*Hc*FSZY ǾZj]C1' gyG7ꬃcc+5Ct/8۰/2T!> P<1]C_\uN@Tp:g~*3\q~Ϩp\-Cm&;=Y=~g {tȇW`۫cq?BScztC=6Uwܧ=ul9c,E:9'׌(w 6{:?$@$@$@$@$@W$hٵשEOnR 'HR#B3 1KEk4 sT>:g}+XGttM1_;fB 6MAt bj摧Gt0̆L>NUGrS}~ME*kUŢ<[,׮pD{ew)Op>BR7GzHTd`v>nY#4A)זYw*5|Pg9Y ſrT_v={5U:=Rw9,kh>"@/.-=ƟT}IE_TUxw7ޫLu.ײ`T_m3sB?k5sKYJIuj{ê7[a:8)鹯A-2-_(be[&Ǵ. us4~ՂRa鵛H+ 2D$J ^p"Zb"m:4uy&[@ p(OK0kl îOhVevMD4!z{J^s;ڮ1SUDgBFu?c?$}lEٶ[3vꌔ("!OLLqUHe >0V3 B"2~q@Ïg>䜏g?kc ǽe     BJ_Fdbi] C,of<&MXt> ֯^Zva"e˖v8"!# /YP!PC]NN:ɾ}W^UJzlLg֬Y2}t)SE`V߃-cǎr[q?t HƏoΝ;]3\*|ժSؠt('O95d"c&uC$@$@$@$@u$I~En]DU bxvK9`TflWʒdvϺPC=+7=/Ԭ!*zC|ۡQQ^DQD]J9U5̵עўCҍ#jyFMI|h^1FyÉ2R#ُH};|d3~5v>9Ѳ\iU*=1/Dve6^8HSz.ORA Ct1ۯ,*<l+>VB:jNF}6;vu"o!+dk20W+?J ln"3>.M>,}\{sF41n4 | iIA>7DKnq_%IzM_~Vf W`Wƨ<{PP[눌qB,ht{Q󵋦؇EӢ\Ϟԓ o:~|Ü.vc>jE85j$S$ 88Wk(.=C{=cmk=)tܚ)|Okq=NR4SĴ,Wt/]Tǚ B,9[~kڻ{% Fzuѣ:roRE%ڻޝGnworem߮j'OZ{ L߻w O޿A+tMas@;0A`޼yRvmG>e:i#pB+.At+mS'"FHRGNyR|EI4չfR֪p|I~g11߷{̓7lٵsa  شf:2PMDۦhVҘh_AEɜ%/.MFgR7U~Fva *X],z餋9=zmt) [hhJCG[ښbV#}*K-P^.G-GsҕFXnsh1De5_Cݻ EXM&H1~HU}<ks;k=*\CE3<4ʙV]Ww2X^N"*b\Mcf8D✎D8xI"sbsF!yrjyMu#*7>0 l{g)cչByn\[Mg~'soA2gI}Qu53ĝZo]s{>)5#( xcN7AN4-o%0O>p{̶Du(Gp{5FHN ڱ^f3 2lB:›5Ͼ;P<("CXg༐P?T !ua6-E^*a Lpe]~|0p(oV f4suC3~1MSߋ޷It^^sߏ]]?N!dތ#6o:i |5Vms>U[{#{{{Coh{-:t[8}q ɗ"󽖭u Zj)rM"7ר۶# 𐫑-e䀾eC2 fϰr'"> S^nJ^kòcFDc&}*!$L}_CaՐ \J a}?!}z'K~nՈ?#"Q^M=Hŕ6*#=bKy|9@S-W6)gZ@#lQzL Ѫp b(|o>Q}ߧ#8G[j{Xk8-iM~JbDkW?D4C똭[UO~\ᛧY#lTCu^:3R$q,lJ98nc۹-:ʿ%Ӑٲ!NK'{z<'Cf(W:'ٸv.ִ _)p6UfM2wu `Jmfm07his5g5 zUPW5D]׵^nçomu JK{b ]gCHh4wOA=efI:{]Uwf*%Ҫc:iq סGC,0쫥el2 a#[N̝_(9%C?}r*@$vⰫ˻t3wM_e3Ie~8;_n%u'G^T3ph=)P֡p֠ >Cm~v^Q;F4)IBiwx.&Aԙ*>'D?Qٜqgn6]GT`!f     +@+WT7Ν+.Bs'.z6/sn"BԷ Nnϟ2Qge{q%=ǧ Z"OuUIs3Bm`}]4sSÝtr@'1eQ7fs[='~?bиsaw~Og-+E#Lس;Ad F>ۦmݶ}mO_Y3< w);KokESi޹w}q u'!{Xx\n#IV˥cg<9>]%n~ F&1ݛjbRs a.RۛC{%#˚9GA-j sn8 GLK^VsUEB]"i8'.SfwLfw/{m-]"O;gY_{@Z6(Zǃ\_f&$=E8xI/J+F+ }'>O;"}Yl?Gz˕ZMmvv؄1njۅh}{v|S/؆~?xɒ6j7֧G7rv7X*UmY!'·lmQ3O=_m5>)gNݞ.{W8sAyӏ57?`;K#}~O?r}7C3/XiD&" "<{䉾;-Η1;d uktD;F ]Ո'K10"1್[ʮ^)ii's5#Jce7(5.=>}r'{ ;equ; ٩K;EdK/RNMěm= ` rh}\2QV.mw[5hPKEwr =%͉?U?0~=9e_p8bkCw߆sNx}=5n{]b9ỞFbt禱~*uKgF:>;P]" " " " "g:^Ƥ#/R/) P2.y OTea[Z4eCѰį2>q>G6Iw{QF~Iɓm6g6皵kΖ.]jcǎMFflĉ{Z͚5mܹ4/=}Yrm3~EYI{nsU o\gG-5o ^fcοךl,/w+;ǥE<+9`ٵHP$c{zZNh Z.eƐO2_q!I)Ol]Z;g_1M幰^n 'Q]{լ[ߎ9,\s{{@>䣁6U\z<5ow?k6zXgo]_;sn}wTv鍷nvOqspͥAz]pUp?{T{O[ NݷEyEvkua{'/Ҋ/n/=oB}E@D x}_MrY\'zs2MuSOmۜ@?7ix"ˎ{E>r@wԻ|I ~\u }/9C#/b*ڕͯskk:e{}. 8ALЉNF`g*? YՓU_:^7'0tJ;` ݗkmc |8w&fg11>;qq.EmVfmX¥|%'^rdט}sq:]KKG?K6)G}hXU2c~ؒ,^lٳmsLEu/=jrSb)3:E7vzC:NN(3rw@ ?.^8g%b/_E } S @TMKOvX]B]s6;Ǚ@g Y.]6E@D@D@D@D@D HqPxq_ȉ{Y6&rU.=Zq'jf=zޱa.CTDϞkfs o׸|&~Fg,Gh/D`OX63cNhmHk{Yd57.|鲻;E9C⅛ /Qd6nk]ŋrnb.=~իVY/ğCO'e޳7ԪW?Ozڛm^xUTOuͭmo{đڵ)Y+" " @v|7=WGdsD'_e" " " " " " " "  G"5mІeOu-ظoL[zC3NeM{LhDcD'2' xK؋}\Q߽jձ-᳧OwV],([sVXVml~n9_e+yc3yåǿեZdPczȥV`!+"왷#ſGP}Us}Ϊ8 l˻.3#=̦yʻ9~:tڿ/v[&mܰ%7;/ ;!yνE"̝+R9\89u|k@+__݉K/Gn]zg#7[Oz lm#W6?lMu0uhֺ>@cf?waE\>?f?JGD@D -5+|ouTD@D@D@D@D@D@D@D@ ۃ+sVLM`O;HU dY ]_ڥ <٠}ͅlS7KeNͧ羂g43 l's,);sq`7w >N† `\ưhe`M;/˜3mjJ[FW&MϳWzU]?T{Kη%JXΉ"ӎ:L~z/9y WW`'|aa@nHzf-KX$Uz(c^:< e%넋VԩSobKGI#O Q#GxiOg[ެ؉f~1Iͦts7r3G{}Y#͞|90#Uwmny9W_AC6ffOՇNn3z"{<k::?qm1m_Zݧ{5!.\dS|Gd0Etp/ :!L7K{ܰ 8ķAdHdlCLD@D@>.{Uw Tұݖ)Vʖutd" " " " " " " " ;-Nj{v/Rr[,) ex]Ư֣C!sD6Sb VD@r}Ƭya)3GlR?qYf ߣj1b43; q͖HpDd}YCf]eu뛑.?}y sA TbKڜt[Re+/ZbŝN>dyJH™Nj;նz^D@D  gɻ]TD@D@D@D@D@D@D@D@D`H'2>ѲD롌exqa=,_e!>>DGb{A (p+LnЇ$gN}C*F=msUSuvD@;يJ h:DD@D@D@D@D o?X>oXNxoXJ7\e /N]D@D@D@D@D@D@D@%$q\HKŋ9lQ6?1}/6ߦw"o{g7[~xkhۣ9fmͪUN9VQFehﵶwVXOkdB+_;&cU+۔ }=u5sQ]a܎֯SYһYz ҬoM<ɖ-Ӫ֨iT6VZuVv|W6گ{R={*s?k͛=vP5e(" " " " " " " " " "HsD f֩Ә2Esnzl[/3kdzz]vYfhfFڿ֜g͙>6n`%v Ul bXۥ\y TVNZ2el[O…5@Z.+b͛9X}*Um[z_J*;~*S6V+Ǟ`Niq++'u1G{/>o˖.b%J/W\KunCoS'N.ʔ+ovti[69g4>VulެYVK.ly%m+/¹X퇯>#N=Ӊ)'}{[{(WWVmC:&&RW񜻯Z=kGx~ Jzts=lWսj~78tIK 2yGHmiv=flѽtلmd6W7tdW9ۅeg8~pDH8pf g\>(5k]ퟵkˮe.Ok.{/v7MVN+0b\yUkֲR˸6um-wc ŋ(Gcumh_}ɖ;d캫c6\ܬzS*;~.\$a sX8' \J,DkwBvGz0G߽blHb>:<ڇQEmEV˛26q{|M졞-rn[p۲6if?]|Q{Я{"+#~ğ='WqGqw6?jɪ۫.Nmiћj5Ȫh;8RG5F2= b8AI2mwwýys~nOJQ#{Gb:T&" " " " " " " " " " HH=Q?u/'ij>-/UEP;3f-3+W'JH`Yߏ6{y9q~vtm ݴϵf߬~ϵfժd͘#_Zر]`ŢN]"nO俶ܥYV|/Z:~.WG#c3F|?!~\$uwkܢd_+^s ~-ދ'  \b>u϶Owѷl?"q9l @rw|= {A ߕVr2|8/(S. ptӛO?f57vG'{2kzݣR:,iy~v@6f7^G_4co@}8Rp=fʿ`]3ECs?~c*8=p}jw@ٶv&+Wn4UD ?~g:?OuSE xE:=qYf+]W߹tݼ:E*]`6hŧ;EumD;}K.>Y"0vG7_E#޷l(g.Q'P͞6GWQ-g".:3]7UjpDVe_ڒE ][0ejpޡao:Nj9R4nLF<ϼ1^p˖L DկZ;\pn+h"GedBMhLPeY(G>XM6, Qs=Y|.(6/?|;:dYa; '(Axr%Ɍ1a>Y3}۸1Vj0=A#W[v…l;/<Y5,S!.J~7چ<e" " " " " " " " " " @w.@~!'u2_d.Li3ʈgߗ]|m֓|vnM7#>QXAfuC^n'3oǿeնv߱9$&͢;n:K\}%7Dq)I|m:~)WX;D[Ǧ(eԤg֝q#Gؼ3ܖhsBVޯS^o~HG7@!8 >^'{AQRi=)Yɲe}d:w;;S(#}>!ǝ毴}+ N{L)狲.&߽bpH6{p 2ن.=!ٔ =|@C'o j ?@B.C[-՗LAQc[e. ŊGys*Uvw$zٕ.FY]G~pHXTuj@"ɓ:ވrnve' b:t2e3ޏȘ:1ϼ:ږO![6me.'u{񞨼fujnھj7l^i2AG$&:K᧞acG ѶY>+#boϡC|D'˔HDȲn=/uxs.p#{DNۗwrQJ8GEHFQ?86iԢ3+fmB=!_XCmbŽ35y}p`{Z4\] N ;)&-[[歬N+/צS؈Ή& ;p{-wZǹCS=c^n_&W([m``UZOS@Ƃ C-Q} V8'ls>zXydZ%QnZu\A(X͆Ui]EPG|NTݷ~3y͏1^`~%n'~IJR&;asoda4scϲ^MR#tpW=kx^_}ϸ]z,vG##@O4j7j(yF>;˅/k㉧Z qLc]CθZx).~Z (nַ۶sz!UI_Y 㬱jsIê֨e !zs~دmؑd)@h'?1s9lsFwF᧞Yx:3̙1-VEܴ d*XG"d$ É=Dgcot0#po2N֝wŜ/3v9'&?V~ofZsf uh)" " " " " " " " " " l7q-KX,) %ۆ e%ܫRNZDW&|Gc^Dd&{}Fs=j;iiiEu"zmVťF<5!%s+~"-)curYQҡHuDT6~;v7#pLDÓ] %wp"6){_ş5WNgq?sӞώ"Թ3/|90>XE6n pV_k3d!x]VVQӴ SU'J(赀݊e_|}K/=L-sXs~##SNzpɒ%VME"8,wVL["3~IYxmmex]Ư֣C!sD6S} VD@;Uk Ix=qGͭ=i@Cw]H3Q]$;l8Xt=%[&_/Xߴpֿj'Nˎb}wk΋cYNdH_~#!Q?/,̙!͛9ó.:<:'sCe" " " " " " " " " " ; &;eMjޯvK;{Xt>z;uMۯD@D@D@D@D@D@D@D@D@D@D 8 mqX\9z͝;Wqs8*/^Vao-E@D@D`82|L-C@}JxtI^馛^W]u!߆-?p?m[%'|5oܞ}Y9sf.E@D@D@D@D@D@D@D@D@D@D@D@D@D@ (`5kp~oƊ-귱.]؉'hkl7[oV^+͕:^{es=sٔfͲB YժU9m3f̰{ۊ+tOD@D@D@D@D@D@D@D p´oN8eĉv 7EY ]v{W_}茢>N=TfԨQpBkݺիWx꫓yU9Ya,8醓m=Ν;[ٲS0]֍7h6lݻ1ۺ1'ٳgl<ܵ-0ܯ_?裏C2q:8묳E[Ub88BS\H"bNG@}K8O*H{{{_=PmŊvEwy!2}QY6o<ڵw`XbL?j^uӧwcFm{-[̾K# N 1FO=U\ٮZ+U/r#o nݺeFE@D@D@D@D _XxloFMV>P?6ۅi#GPD7nJ.mSL[$^i89|^`A#*]w 0/ wk: СCw7_}/82J#βw<# ?7}~[L_L[l `FD#q-(j3<߆Rwa>wF:{}_" " " " " " " "3pw6cKsK;Gydl{iSN.څ$]% %z8Wy;8CO}_Z7ްaÆ4 <8$z%NgҤIMNH'<:ޓ\" " " "3`)l1 #"+D{~NTqY9}[lSi #@gΜ6o[}4{H;ϒD=:ՎOzNԩ>gmus }بQc91pW_?HϠҧڵkh@" " " " " oӧOOV+m#=ՐfA8␛p_bETKQ_D & 0h社0ZnmC Q?Ul }Yv@F8p&yTlѢOOJd00e_|sRc߿g'ꍷc"i'p&o|L y?go6f~ɒ%i(Ʒ" " " " "_Ls4β!{4*9+g/_=\iB:Xfnorw[ |ŸЏNwLD@D@D@D@D@D@D@vVFa}eC𢅰8į2>m,d{UԩSolp2O@."hWgȑ:͖ߞp:ޓ\;)vZ?㱁=zw=[K/٭j 2s=ꫯz#վ۶{={Q\KMtaSDeH;DR[;ѻjժ~)x?98䖑= >jRc'ꤐo<eOc= 7tTRm" " " " " " " Nn|tk{|mH,؏u,P2~=M~[Pc{z͔*?B+" "?;֋ '˩3!JԹ5o6_@,D/&cMbS}T." " Qŋ7^p>9slF;q?߽qƹ*H*Uu-aY@pcBz,d!hZ@&@TX '?çe>W1Rד[n?{q _p6~x~ƌקe\#Fg᷿1s9R_ڵcVODzK~~NvG }%%w_ݟIA``[^bs4(Y*l1Zj!CD{D뮻.u86mtғEA@;SL;֬YcԻK5B1-s~wߵg}֘5/Qx׷<^#{V}ن#oDRpB/O8ы>U\7ѧOmҥ3GydI˜ѹhOn/עE2W_m;v;*p /l_+ҧo}#QX1<7R_uU>ZD@D@D ' mjNL5G}N=:裍LD@D@D@D@D@D@D@D $gIިQ#CEk"-s"SW_yQ7={G&E]s=j!|{[z\?Gm6l~۶mvڇH5kC":n6m[`wԩf=}a=3i:uԟʪW  8pN' D.Fskذ7w}g犘͛77~ f߇f/&w/D Hк@!@4lGȿK}6ƍ{G瓺=?2if8Av!'?;qeʔv 0#/9I&6|>r Q(|p۷_{]OD{>:p~0IÏUTG7}9!L =9k׮EJ,V\' > 0uT?*VS##vϚ5GyMzbD9DQ_JKRsEOd۷̙c 4z}DxI{xqv͋E.^7P~)Wvl>?Ǐ H[o%d!!y|7h*Q ,Y{esU/" 9IH"[T6掍!CĢ毽?/®zuR׭[קoժ^'|ŭlٲ֣G_?]ti'0Ro>j)SlqXg >?[Y=DŽF޽+WRCH$& > ~'Њ@O?m&#"l](GE~s/Uaҥ~{s#m-1<@L g"e" " |d|xYjZڐ`IYx eez(s%`Tea)0B+" @]ڀ|K*iGl:D#תUυw8^Fd_T}M&sީ%rVa޲e˖yA9^>WC=xD@D@D@D  J?ODE@D@D@D@D@D@D@D@r&E@rD@D@D@D@D@D@D@D@D@D@D@D@D `x" ~W" " " " " " " " " " " " " " " D@D@D@D@D@D@D@D@D@D@D@D@D@D@D`pip{@D@D@D@D@D@D@D@D@D@D@D@D@D@D@v ]v`jZD@$qF[t/^܊)Yj*[n*U (a[ҥ7+믿nͳ]w7nl;v13gδ?X#_mV^=+_|tSsp0I?5kZjղ#\ٳg[…}J,jwmѢE6eWNTR˗Xbִih ʕuU}ao}Z;6p t@G[oo?_1_ok֬r6"Pv7tP[p60}NlO?s5tl̘1۱k￿gK/a+W>Sꫯu]E-v,[ae]l0|s 6.d}6zhA`Ȑ!ŋ[޽}W^ye髯czGE#LTD@D@D@D@D@D@D@D@D@D@D`(q` ZBb".bߝwi[~ۺvjo͚5k:uz)__F&L`^{5/}'[NN˿>#Xq.=qsAl7={f͚Y5iNzj˿ˋ{Dŗ)SƦOn<__鰩nhit駟~qgCP~}LXŊ9 8K,Yr)ְaC?=@؏we鬦 2ZLD _@xGTd.u` "ҕas9Nj>묳ϧ!.56b6Q-sG#{2v0ˆ'R7dxs*x衇\mpA . ~FfNqAmd(@$E-B}߾}}Zw%Czwh8C {>>)2 mQFy_~Gjwڵ^<\GDw#cμKi)#k{ܣdFhٲqJ?Up\Vup wy8N\ڵk{g}k\30'UP?מk;qsK6fUgZkp5NgP;cʸsϵYmj]DG>pJ% $:_{_py~y+7{y#KMo?Ӱ'22?s&Xt*P%z2Ĩ#.3N<ЧC,Xa/z~Γ_?Wp!e" >|YV0>wqG`8Jąbdlⳙy{ۊ+$~;;ycc9ro+D= AF믿>Wsɸ?8F$iv淜#95Jnk׮1 82eU N|sL[h+tph>g:nh_}Ul <ݶXyA>3c=?V[4 q`s/S1$+Ku<Oky̳JU." " " " " " Hn7SN5WrUmf"9e" |^,GdЏA8D3%=NlxDף|,È:vxbpAl-<3> *38π_$Ow?)[k#z a3ۗc -}TfpsDFG^z<$.{8*W-j .Z850T@>EȎ֑z 7(M qT(|7𿅓 D}oJAc7,NY \+yp#ӈYd `ПksmNԇs}ĩb[{b( oK:VD o;O>! 38>w}Qlx=xG0LC$-S଄SPpR征Ϛ'QxN&.pD0ͬ,?<LP%}{m1  oKL@F`f7+C/8謎 /È 3pr )ىPf- mG`2pp> N "29?_q/qo1m*:u怠=ihk"aTډ"'uk8%S8 (pcܧp#<#>C]:wy1XlA=0 bea7Q}DKB^сk59]Z^S3"f;X%=mp}X='Y>BFPN`__$[V?PD@v:|tsG>O~;8>%Q6?|y>|gR# }廈Uhgc^4WO? ,3 )큨!߃oL|zy s)|'`0 qp ϼ3';y8U4(TY{kB1I3 b.| cl> D~}XVmtd< [23r/ݞu6 П m0%t ?|Ο2`d_E8ۂ@9m0k˹DKb8ygXn%dƽ.Ge0uҧ`8lD+yC_FSSpD@}7T#|FC>;p<gO Rd[>C}Lg>b?ó׶t>G52,s7{'!3 /yy{|O{:Ms(Ϧo*Uk8ndwotɳ }H7#W}xN8(vVw5j0w1鉞8,8rpϔ,] e!/g&8;ǐ,y5 <,~;eU}}EŖz&Ox.!aA(1CQv q *h:=G$&!$j2 , 1€~ATE01m`x3Ȅ`שS'?0 RHGN_POؗD0"X#o&)ebz7?>ߘlQ^CD>ǸW{Rc6-spq_so2(=\DpydC^QMd#`p;X}u?G8$u\`D%c>|^qAtPxΟcii8K!/#g/Bˀ9Zu΁v~D3g0ñC1vouN獃D0g/B#듎q\ܛ]wMh:={؇W>EFxFmq4Ѷ-aߗ.?k)"!@V |~teYg~n{֧v6ugxҿv[{ F#EsϼDL&3džPN<7< <~EH³ouĹ/NB=@IDATVb ,1&)' (_" =#Ok '0q7<l@ B!6Dwq 15Qlg+?n;ʢ ;MƒA0dDŽ퉖k]Oo}?dž:|p?Q۲=^A$O2Ǖ_t5LOd'&s?De7ѾYd]Y" yN8{^W+q$ʼn T?>Ae7!9$Xs(O$WN*`~S88 ADL F:A̽[o5"ɖ Q"A;wn8;&8P7YG]C"1cN3O6C;C|{-lK7 ~}>¹np Yp;~a8^pnV ڥxO%p~ NTOĀO"qn7wKh/]aD`uF ean*IV=\>W(uk)" " " " " " HOpK;`L ŀ'1a`Fe-+bpAB:Dٚ|GD_M\6 1gf^58PD@?ó3D#31s=Ϡd"➩W)#(a~ #EcAE< '8]|'e;#^wu^Dg}oWヸsT#pӐ,^ Sq}ǜ,@d-KenZp\Ƿzˋ};>dFcpY evs is>e:`&nQFl-e܇ܿdtcZ )8LI%[ߤ3f'"'Eߋ[ YC9WGF hVd R'Nl~do @& >!{ `a.K0~OV=DlS0 ioh.' FN A%Q P0M!NODMϋ#~inݺ~qP@Od 6L&4 A #*E~`=_ :3v;0Q#Hb/+ {/! v(6+bAcWwD ATDE@Dy1;~y$777M2s.x1 OHCA6~G;*Z_GOs9̾YHN+i#B&a!荣(C߫a).iw1!vjN|Q'd˅2l55I_A?,M&-y»1uԕG" " " " " " u@!g+\m91 Bb99g9Y..9gy,5z<%UL$0yaK!l!|? /82GݻG#B#JccM~E3H=#"K"q< BE ( m& e<}&yIE;">/x1@0es%`P $>Ν;;hyg&c\jN$ &Q_}aN ]v/L~=y5axk2\ MٷkZCߊFOUgxs uV֞ʞ'؋q߽Xf;Qcr|Ddԝˈ/t)'@s<# /thCegs/S1:6" 8Mj3+V0e,Qĉ璊\eE[y>NiOUND@D@D@D@D@j3A7>5=LZsYSAlusrg&,cU&ru*޵~.0;D0a'cc'R։>ny'Rq^BQ ڈCICAxPg{"gHr`I ^Jw}(x^!#Gqql6&ElHO}gF}OPWx$8\' ')A9^@r E;*Z_s:9Bo>aTj[{*{G.83*9S(lFd=P Wa?Bv.]\D!Y>uUs1$\U3`qƉ*bU~O<ǀGCM}E2l;Oe" " " " " " ~M3\busx,DI'O:D"IWߪU+5ẋB4!hqI!=)1)w{<"1KL@<6a#zH2 l3q,"s 8!d3K'8-w!Jner$fGy ߿$%(CƠ$#p $FV~؏L}^@5JƂg/;uC,Q*qZ'E}]0;zU6g+\m91 \sg.:1QeB b]c]rrRyM*vcFq^06|r y/T?'j?8o+XW&]{WmzZ\*S'߶\m%?Q)?M9Ů/Yw11k22Bd;FED@D@D@ Rʯ+,NoRlN ^e+\m91r3c]!'ź=@m# ᾶ#" " "P H6@qw\&" " " " " " " " " " " " " " "PC4} aE6xkYjkuDb4}xRJp_IpMD@D@D@D@D@D@D@D@D@D@D@D@D@D@A@}1($ D@D@D@D@D@D@D@D@D@D@D@D@D@D@D$Jp_IpMD@j_e&MڛѣXSL ~ [ƍg'N,x1c^pd웬'wU}," " " " " " " " " " "P$W/_." E'P裏Zǎ7|IVygOru?tIֵkלr>ݺuwy g}!bzco{キ]wu6uUX^35\6܅m|vGɓm9_mVk֮JjꫯsJk=uq8c]Xoٲ5lо+ǀcǦ}RK3 h3fQo ,@N x-?6k@ (\F" "iK*=_co'pGu;km 4vב>!z믿Ago6ҩy~LDo&]%Ǻ{}E:+o<쳶z۴ir-g:u6=c.s=׽|g,y aü?!vaٷiӦ9#UB o;D>f-F4?p O>ľlc.̹SOw/p8}[^I&" " " " " " " " " " "P; HV@ IDQc9~?6[k!#7o]۵kg]t~G>=x={zZDo#:5E^{ͣ'M5K.gy~̕W^Çwxwv<ypݷoޅm~XIcƺ-£Ǐ۶m}NDy֭>xݹcpMfmf!#֟wu׉ПuYLfZ޽NɲsBJ9-|~QGbÄHc=ou;oci@hPs֑E@D!9[c5Ot11^]*=Ih=dC'rI&?p$јq[_~y?dgwƟ GJ{8"663B9Kx!D/.6##zs5px=sG"1[q"q1QE=9?2T3hK/d[nJFvOc3N8 dK-ϵGB -|~c~ӼC15(= g#Qӈ!L"&#Ac=5B)+B^U|ָqt48lMNZ>Zk-߆H}f͚_omvmFjyʓjС.l@@`ўe]6nk1 0[nEd_Q?b, D'0lKi85$IOF .qqa`B ^wGnio֯w+|Gs\{8p$62'" " " " " " " " " " "0p?uNUѣG{doMFG,EE&z5׬3hg,wYfb-Zx8ufLa|LϩHm&J`s=N }S9&)SxDHwðpFQFI$?sڇn.?q>a4D#䳎k/vEY$r_}Uw!vq5j(V<衇3<}?p:8q252>$ ?ؑGs8q$A&" " " " " " " " " " "P; h/j@6ңgғ"facr{6&Ocܳsp F|,ɊvP./Y ǁz?e1HO"*mW]upq1x|X}iE]d{6x1p9 0,]v=RKY˜ZAl.MV&.rcr u\uc (%..9gYJ藚=e"PD8Hk2NNuZm{d]_+>f<{# #9ؓO>c!sζN;d+|l.+\Iv%ǙF4>K,_g3N 1R>DW 7!yluAef\O|.Fg5K2G Y:iJj1k'˜u1QeƩuϱyrKmmc=sa|b)>B " uc3N9DcDj+uD{.*ԙ%})h|,`x +*ӿQ_u{=w}kD眲 󬧿"o[E@D@D@D@D@D@D@D@D@D@D@j졔'[l˱yL1'j>s9ED}sD'źeEC\V/(>7<9 *" " "P(>AD@D@D@D@D@D@D@P}v.Z+"PA[<־U[*džnߞbSff-|e`Oƃ@]%@LD _jVY 7v[c>B6S" " " "P3~W=zM:f$ցdD/ׄk67Zzurq+Vm" " " "0o߾6l0?T5x㍭cǎ֢E4h=;aV" " " " " " " " #ұ֑`ǯ.zU9oi]tIk?|^j LD@D@D@D@D@D@D@D~p_@6iP*@UǴYqj" ??MD@D@D@~ɮJ? Xn;믽Z#u}6lڴie6_6i$c[yFɓ'@ ?N YEm9\sT#ݲ[v% ,Q6ovQǘg}l 7n曢*pg}7To9Ȭf_XNY)?o#C +R" " " " xᇽlVpq>'޲w}"_p+eaĉbp쥗^YpO4A&" " " " " " " "P HGM6c9de /~{Y~UW 7"w^|106r-gxYZSU_~e*즛nC: 7egq)SںWm̶i6o^l3ϥvfe6f/Q~晙*MmԶ޹WDQF6|UKy^fgZmeϰ{ܑgy5\Ӷvۢ:g}֎8{n%IEmUV1Ğt0O?_~ZnmK-TE,w-B\wɗ_~W6mYf"[8m۶(ǂK,Ņ\_3f6(mlٲStiA <30vCwiӧO_VZ)w%yp/u].ũj!#D n;^{5;$?x"7~gׯk(?dȐN;!M" us߫a|?")Ǻ #ˤyOΝ:(}?>q#Gt1oh/7|\ƌeo߾??D@LD@D@D@D@D@D@D@DvpZk-W^IGmռPÈ!&3'z; sJ;}JqzkiL*;äԐ kVr|gbKq qslfvG{:ڸYf 7s!!s #r>߶ H;pD!ܓmhw"Gm<˹СC_5!.48ɽcAh?b":Ifp$X!P"d͖ks8,K6h ?XYQ:u"sQ:ED'xcfO=^87|I'3O8s=FXKz&! | s~W{}1ɚW(s}vygXƱ裏>vagLD3 'ˈ^x!iá%a[m쏐w }?3ne݃R>!3S|WFw3g[8jGsK@}F>e?/nH㋈|F}Dp'JԱ{zD%, }Vy kc v2)]tQߏ.|gi WI&&^"#p>1tS J"ۈ"}2{~-L cgM7MsQhj ɈFէ?mRBkT<ϟ7k2ƬUJϴ-6k?)>[g#?4%5/IO1dyMT_YZb-e7C[pHL\_\\Xm\Dr{qgqnCǡh}k3gʳ!'1%G븿[6J.g m/b| 4/*+ƬOn˶1F;^J I@(MG݃|Ǒ% C!~>y{_Ϋ-e,Ldo{ qmqufD# 3 ƫ$h뭷Nex1G9l8/iBcYhx A.D"//(Bю0IWNT4чaSN9ŏE/6x8G! .ȅN:BTЁY"{іz5gu0{ְQӜ8:%'mj*~*Uck׸~taw#y)N8ts ixF~M lDq-#@5=Fy-Y|K WP͆Ch8'~ChƽSj{]@Fy@HN34R9cy{D?ޣ9СC]!%QD#ɏH+Ҹ#b m\>qkud=JfHv'|_{i 0γ6R.?PY7+*/vHLq狎3pF")&ڏoY1)q /n5{ -2"?{.p#bd@#<720㥗gd[ }pڋHy_ }ۆD|8=~7n@ ~V?GT% "6QvCfJ8HN:MR3kAE c>v- gCABD\BC!}'b: ,)37BU":dd# R^L.D5Q^[fSw&ھLoRf 6yyl[lq [MN="+Bi?xzpn"q52’˱y?>jiCXY϶{q‰'}ucK Ώ9Q,LgDq'KCM}m>?]}tY-XyуAisD@:&0.9V2ǁ 3hx GNZdpHZ>^<p4IHQrV< }#6 K`x5C8QRQ|%Voupz8 twS}+.&8滕`:ArՕk=Ǡ>h#C[UE+!&pFz/8ǹRd4x}|lfjN޽{Mṝ@lSwJ3y܈(ԇq #8ypNFdEaKu<y1(ϵ36A~@ xd)ky饗NK sJ!M0$*}cD_.I~alc&2PG*!:lEg6qB' Tj|q3@ϒs՗;p18Qw<{9mƜva\l.[y׬:G3_=P?/Ƴ%ӱ ȴsg%{8i8oeP߅^w(NcFL|3g22D[}ږa>K#8/xO4K~4D#8i^1N&iI] 8_K9DL"1"[IHIpڕMvJE 1aD^hx9S!~?Y (6*-ܒM.gJC5us,IR#[{𞚲٠35#M24-gs"16[ݻFDlHޣNnc;/q4I Ƨ06& F8Ou3d8Rt#rl#{FEpOõ^3o`xK[iN>Qԇ_^44b?BO?Ss'=L8/ l cz8kᤴ뮻d0"&q M7xF4yys1À6v!vvЌ8gؑ!s|繛Ϣ<:[b{ű^i|G PDo|DV Ndh,\ƵCI `F?P'm a#] m;IuNgQ" [~F6}Se @%[MV&.rcG嘣~e.:1QeXX̠Rie^9xE lƴeb8/xF;O!OT Bc.GDifP%ўj1mmrl*y툲)! 0uۖY!v3@Tե;-܈˸K߉.""$2Bk" f-ֶ=/JD6DJMҪC4L˵ !H`PjXJ{K0Pl``A =\1!8a9SUehGǃy\k<Gk|cľ2b;6&IA!R^{aʹOfڗcL!Y"x]~(MƱc\`Z0^۸ح[7>X׶6=" " " " " " " "PojԄ:cĘ,',ۈusrg&,cU&ruq? /|A4hP:e7юz>f0$#Fb>R6i@$geܤL/^ytD.2"4m,O}}m6s\b_L\zkK}.rmCl,T,V;DbQ_DOg31a1r, le([Dep u*CҊys]|B2Lr i\ +0\[:l1:5 @0.d")o9^D@D@D@D@D@D@D@>BBI˶X9Q˱yLa(<%,W(>UN)9DRQ wr9_EpiLێHq_駟ĉmu)2A*T} [na/Q({]R>N88FjVsֆ]" " " " " "PCo߾hB}KL}NUĿr%T5'Y?j  U}E@D@D@D@D@4i +.L}Nն_5|t[!iB@kUԿ)iϰocjYD@D@D@ 7u." " " " " "ǯ 5j9&]c~Y-YMAvյm/NO}WVSWW?_[ʿ8ORYm?U^փFگ~lOD@D@D@hɋMqx,>s;LwuWy܎0vM7u]gOrm2e+yԔd=qmX[ivKXQ;UGD@D@D@; u~" " " " " U&0|p[s5+K/ԧ]wݵ5\v۵^ks]~[lɕnKUv>}_=U}ilJ^btp'[5}?]tQ;?@k_Rwym嗷aÆ:Ǹ>[eUse4hwTW,x2?>|>%+d߶o1]?Ѱa*}Grܪ)E,2Z^`o!|U=:)g:lWO,_XwyF8%w}sgg()" " " " " "0'@\o޼lE\w-[oB -dr=#٢E ;3iӦ6dm}#9'L`D]"ҝ|ɶbyd>8qmvc9ƈn۶!?5j&KA|vrK!ݿ駟(KuYfv@G^~e{׬[n.!.b#K.vg={ԩSm%SO=Ֆ]v:*[>3 + >묳wbmyꩧ|ڵkQhpH(YZˊ}MV f%v.n&!"G}}ltYV7/[mzK/?g8FVϲN:Ygjy+}G};Ϟ˚4ius-g{6v Kt 7ثj};hJK)v"2=6Nȿ(&ڌ/(@C; > @& M:dD~}VoEa .ZnmݻwwgqD#aD̑yvrQ'mǏ/3N<ўZCc=EU5"d D.z6UIM#1! T!#Oc=f'xy7ጀ  #J\`\ܜo\fmꫯVZ i?5qi;_#U3}%8Kp >FkDdTR_}ڵ߃\/ |8{؇gM裏g2pzZo 8gseiKmwJ,ѷo_wOdAtuz6?& pyn;ί|AJ+%2F׾O,RW,K5[n " " " "P>EܗH%D@D@D@D@D@`1D"-<94^4~/R-Ȁ0i1믿G_(Bư9YRk /xToQD^s5FT(F]GgU7tSUW^ylppzW젃6W0 қ󎾊Q0%kB%PDijl}Լ& yImX[ IL>Qž&m+r)## B1\8NCqƹ6:v@bd{F q!m;{B2{N8φ?X}vEy&q6!#}B7,||xV}̜Zs >]Mݻ{{=dc ù,Vji=Mk`-2ky>J$D " " " " " "`. PIT1 83-D(sEm>", Alr w|msd -2z~W#55Z``DZ N D/P%dEv "m֝]HuMyk2γs{]zI!H>|pođ4|BR#c'?q:^yA6YHwE<ƺp=ϭxQ6<9ށ Y >Gk>߳ pj!w s#Kk]J?z4_/ڳ?˓N 0m<=E@D@D@D@ ! J*#" " " " "0@D!41y ,y<Nv(*֝2&5jaD?ը9ѻ!n>DZ˂CY!bTFdk0FÂ[I҈dBPcv"I$r s\gDl3~~`Lzoy CuYk+-R'"s s}k#;l0Oܯ_?OLx#&)Ps,~$HRZ0Bla|hX6+GS`L?҇Dӓ?ѿ70G"t}jj])4cǎ?|<}w8Dkkwku8< #m6ZkcJɟzf80[n9gy% 㭷h|R{F/3}^[R1cҎ r 7x9;?Tٿk޼5~xwc-=SmwJY/۳)O??CEOUzk^cϰ`'OE3q3Gau1P" " " "P(⾾G@|y^nvej>}0)^r˿JVWov_,:,[wuܒ<}j? " " K?pѣJ~*,͎Ym9YYewb}׮]]#Mshf~+Ηqo?9"9m#I!f POZ~#8D TQq;%y24i9_LƧ83((dO>c31 aY}C0a&Zk /FN\A&RK?GDĚ6mB1뢟.+r # SgLGt>DvX<1S9N- 'xoe墟XAA+}3';'Ԧ{T}8cus{6dߍݺu>S5ǎZIi눸o17q_ID@D@Dve+\m91Cr̉\uc gbs4Yʫ_je58DŽW~)ʼ;:UT"vqG;.YED@DfIQtǼ/Ԉ<wKW,D2Eq#sRHno{uG}sYE W=>t}sJMV0侥^JTlm$u{!YYVx|ψd|%˕z*ik8R\ץ8FOyU]lv^pV6 |~&Yӟۭb23;`Ǯ~MEz؊ >AvKe9@&gc'˜u1EĶX<>'|fb99{Ye-[۬AzI " ""B8vR2^L$Nb\X،U>^s>qNl}Dd;d,K\/9UE\!ZxKYoDd+u" " "Pwu}GK$Ve .2љl!l+QwyCUSUu)\gWc&sw {F$H./YUO[}.1|ͫǥT۪¿2mܧ¶ܐQz7N|m`CkP:-O@}9xKis Tus.]<"j2C//sFdU3ʸFN8ǎ#Bz0Rh>szsVuO=חӱcG1b}GvgkJg/l0$M}ݗI)(@ZK.S&#cE2-yF!qG}c_} : w@^ 3alyVw^{6|tu$b2}i&8L*ZzFq?zvj%=R g38)|[eodRRw-~dm_HUO*˟T=P=g\jlq+s[SQVfG#" " " "P.Zha;w:uq䮻ZP/O?Ed\U?j(&Eg$zݵZˣMxDmwŷoq60YXD_y啾rFmiybdZ/"3S>CGƈgLtR~b>"1b5\m?;/\N;4lC,_ޏ}A98Yge~l=0?Y-r!.9o#7pC>oa0`sرꪫڒK.9^/3 8q͛7-[:O0Gus 1=zxD@D@Dhժ1+z⻙wo 3A>:V>1ηS*Ÿ(~TĿfQD@D@D@D*$砇>~x $%5fmfZ[o}"pIaSA{݈?t7Dn&MLO>iD2f O{zH5θd@ =S<削@e p=5ǒ' ɱMh|gT\q(Ϝl4q  4t/{]tQw2@t~I~^Tpw.CZ~_}馛(Re*_8BJ!LE폊,\G]GlWf}A[@]$ >Ę(8G_m ԁO/DBD8,"%DL^zZn|F*%X[_Gnb#D;s,ڎ`JjrmYfGhhK@"O=Դh?dr( cy/9bɡ80:ԑXuiIKfHn^ K?yls~ MY30usJYɶcM>#J?,0B Υ^7ogDvaϹ-gD{d+id:KEf^`GD@D@D@D@D@D@D^GI(IN>Q:UER)(Gp!?Z*&&qvDRQ>v-x|H1Qq1]Sٗ{キ$sm!LHڹ!l#s ǔ:c1pHݻShD3|C6]gGI&~0Eiٟw?sl!~se3g}X^x= 6vqG瞱v#g C`pΝ;~-׼P q~6eF'mWv)((K<}DL4~Gy"1<~l#ek#sNj}⼒u1#m}c2gs8Ȭ+s|ڈs@c|*\6h>ǴAD@D@D@D@D@D@D@DxRƧ)HRYS7m99\3ϱ *m9ߺyCDLK˶DsX|sm.9pOC1ںukIjkR/\FQPYҕ376dQSD`6^s6,4ҥKIE{N?mYfeF(Y2uٖc8N,<yDc]r^{\m۶ѣG{r}89iӦP|&~EM;)U.{=·:tG}=9\rI$ =sE'~[eU쩧ƍ^xaW0[\+D@D@D@D@D@D@D@D@, upRܹ]uUoY^ϙ֭[7V9e" " " " " " " " "Pq_!m9D@D@D@Dmi[lYK/]3 dosI'&lRԩSme'd"U3"Po ԶNLD@D@DN[lvI&0v?5k30aB2|eGgK&M+" "Pep@(${3fb-6d' >;29mml#G,Saqg޴i26lh:/DD@ @=; "" eQ>H@ώA@N㦽D@D@D@D@D@0ƃ<:t`W_}G3LD@D@D@D@D@D@D@D@#izƸ_jn62\s={z$>o}b'" " " " " " " " p_."wݧL(-ZؠA2% >/m"-05Z 5lFE>+$וR;E@D@D@D@D@O y;4,R-~py9r8d: f9eQ`c` 9Py`֐ϬaR>X|p Jի:KeDr7]w]kժ1cF*+F4"{ۅc=XH=?3E%TbQa8~xv&goTϧm+s=El[g'~^m8LW@ 4iI'l(N9`VƀG?&$l!ȼC@LG(IGٲ ~ @ ^tNBOH[nӘ#@&t^xG#:vi.'˰`W_YmĈֲeK;3}C=仵o9ofW^y}z2_|SS&3]ܧ^n=N:ɖYf:tG{㜐 yuy<<@c, 6̚6mj\p-~.HrDuY3$N9/{!grqe=nfw@\9mmڴ!C8s&l^_~i~TO= +ےr+|X?۳{_Y6xc?&CYM6GAs&;aE[{wm;0`=$.,a[X&M Y#hCfgoO~UW95bM6*}4@sq>z66gu-,Z]o:E@D@Dnq>e9 QT=,& 6#MT=㈀@ƤG4;Aԅ1Bt \&Ms9&0;c6tSwj@o?{'8KǏL /Ñꫯ6}:W[m5; '}z!֡Co5=Hk7_w>6`9?D[sFD?#裏N;TmَOnoYY(?[?r\cIvo^=_0v&Ӳ@@m& ~[N *x=yGUf wXY{V\{AT,Weu]e툽#df2I&!$!ysy}sNYf-_VX _ p,TS8VM :;2wP% d-Yc(@ @h9>uڵŜL(a J.QU^{wr#Kh^q-Fr/AVvX:sAXDhUqEhK(I*qIQ;)f벍)&X|VmuOWE">EyE㋍L5B۶m}χWTɉ@x/_B'-66֭vJ/ ݛ#9s~Qw}ΝYbƉO[@ H $E:Q|e ٜ_I%Qsn(Wf+1mx:36^ : ~+@JЗif>32(#@H煵h \[ ~mC}߱}w'2> @ :#p_g(M>K.Lwm7OﭴsL$n<y q6Nڡ!mD|OS{ͧ(ljkMm⹪5h\=mvO$yoZ?Cߢ@+ @@% ![G}dD9 JR"} U-˜fm g9 a ۆsi>a|m9PGNK$ڛZ?f3د?+q@&_gi@Q@Dr0x`R}5$S_  @r" *!TQ$FK=z)R^{K,Uc}MEbeŔWĽ˔R_8^;E馛ȯ%jѴ7^h^"{i=X:_sekP6Ȟ|I;|ɾzÅVAbcau}5 ](.GUq(nv?$gZ\J|:tϯgK93LjFq&W-2A`Ȑ!NnWF &B[-CdM\Ό`sxÌXs?=9gH<ڢ@x2;B&smʊPcذa ]L^opssTEΜ_/?5@!'TL~"2xq̘@L29 ( ҴU@ۅ=;@.?(RNhM@t2n1Cw HNV0@ @ UWg$˲]2yu+3TW^y8_Otq]heVf=:Q~aZ̓1+[G,kmT䷢1sHوF!ek/NRAz&r,2>8U3XXl CXA@(ǵl};556@8q;yzer@܂@gYYdɶ 7 ReGㅭ b@[(@C[A눙s@&P<<}#,} Rm{?YA})D`B`vd"@gG!5euҥΧ Za?<-9Ct:yu VK@Y&om$0Bj @ h DѺt:x '3T8@z>z|@*edmCA8,3@@m0@ @JUX(yUW]ˮi"]X0@IDAT +@ @Z4@Zk:@\7:Dtk :h i&2$F6q djL q @ @O[iu>mm>&M.o?sß{o~ @ @=(\7v@.Dؖ@}c]aYI>4:,zgUb5Ots*Auۮp @ P%m^>}v98%/3f$Z~y!/)K.sM6eYƞy [ni.NvM7СCMW]uU?3 @ @@!8 iG_@OtHg'H9CiH W5:xDցX8淲9!48N537 @@+tGqkή;>/oᆶ+)bsN%3׮x^4">gΜ [Ξx k۶ 2ąnݺٯZ= @ @3QnhPR[xߔc@t63+]Գ@w->Lշ&@tHy˃,8/!ڶy @Jmݬ_~^{I'vj}?fKȂz!<`~=z3<Ӕ0 رr-֫W/~M6\`{.ǣ'NhwG+3+}ۛoiW\qy}ւ4W_}գ?~]x"@ @ ,Nh57@Zk! <2U2  |)><P@3@Zy@1@/,fРAіXb }=_ye½ڻtBK/k?ZVL%%%o +V[meK\osN)_ o=_n￷"[eU\?ý/ @@( wyK<C @hh]gϞe\؟8tTfldU>dT.us_hHϡA @ˆ{ @${}(5xꩧZN\@o߾s熽*)Sx|EKW$"8 %^e&M _~vavmmWw^_~vi{%_)gm5״x^JK.| lذa$fͲQFڔ_TO?s@ 1w}mk6]Bخ!CٹMζn-@ @h`]xA$Et]@"#AQPϲp(+ @q@x.J7(l=I\WʢN%KWļݻky%!?9[j4j4$K`_y=Mƚ:uW.KOIW ~EZ0p@3 @;z^=n삎f)p/M(u "I= @ @1:Ct y Udlmh \V2hz.nmsH> E{p̳ @ ?dE&9Y{ 3gt~뭷h~P.=sO+Kmw1Lbh]vu?Fr%Wfyye9)-撸/c9׬9ze?|eCP@ Ԗt/2+yn8T67*YeE3ˎ9LW4Dmµ.E(M @h2@$|/g5<АO!@@_LC93{TlU:#>lԨQwuwOh?BF3X۶GX4: @͇ב,_`"Sa_* @ Zq:nW 9d+pt`r $gwHe /?V}^mU3JCԸ鶡\E4tqeq!Jy  pk3DuEA]z @@mD9!%gsVH?ת5d%SD #W Z@ ' 4L O?:w Sc Py'|kߙ @@;-[!hfHCl"\p?ˎjEn~2:_[K @M@yy!b-zܣ ŃX% @ G u,D먍/Q?FVo:)g(k=WY2_ @ @XT @ :&P~طSQHJE??H(D|Egt/A @ t 7g˝A @uH`v5حj} a?ȃ>~m[^z%ZpY/ZE~E Gq*+?o*m_ Gg  @ fMY?~n @ȕ 7?O[{e˖o?l_|wY@RZz6(D.Kϟ) }x"{rTB @ 8@_k @QlĈ6hРJ~饗wޱΝ;)Qͳ3g&^6k(t&BB~y,/yESeѴ ϶::Df"!ZsY~.]4\/og!eh5 fͲ6m4{& #ώcLhJє&!#:thY!@ !?x #<Һwn]w-7Iҩ"ĉyӌ,y8Sonr@(]p(m w3끪 @ EK-_F @=zfmfÆ _|ю:(_ݝ֧O?R',??:v("?}!^QJ?oVY~O͟Jѯt~HIeGj*E [-?DF,Ao ɏ_ckf@!sXٱ2$7;E;@ 4al-X }-ZH-o[o9?|?=:%}ﲣ+%Kܗg :3E#WGz@ @@ !@ J`va>c}QH|qzٽ\qqߍ@mE~'"PW"?3]NѢB@5@ @}`f@ @`q'={ E{U,K/UhC=E! ɟ߮,=,"R+mΈ!@ @kJ @ L&"hv8+z?#tE3C#D~[w0K]ȟˈ @ 4( @ &L ?:rl"AܟD\( @Schϟooo?;ͳ_~:wlݻwIgxei^O @"&p3<G?6f_~˖-m}ڵ N֓}7v7l4s￷s9Džn^D9sСCnV5|A @i{H3~zܼuJ~2a?/w,Ko8!W Z@ @@3#e]VL>&CS]oڷoorPRK-UQ%uL'ӜZR2(s @͞@"iYLpd*?" aMcD?" @=@ M@i|AKifzO>Į*+..#8"G3fj omۺxvݧO{<<3M2k,%}^x}v}~mquoK&VO?tmĉv嗷>tHW^{"\4L /؀WOg5ڼFzGW @ 4v-r%ʎ*_}D”ȯzE𗄶'qz\ ^+󃀯 uN :mTO H3 @ 'p@Py.]\8馛_93&nU &ou뮴h/~+T'N7p; s|m _~>31b;*|ȑ6zh ρLA @Y߾WQ {tR+z_bV2wkBQp̛Sv.[_mBuWWľ Aw?ui\eQO;Z;}E@ @=ڳ';S%$*}w%\z! >|pb++BGʖXb ;s{{KWd"{mcƌ֊vמimjꫯz^{e{キNJFWd[y=]ve;蠃O"qZNq/y1ž+^kj梹Fe['ͧrx'x*3#xEx9#mvr,ŦL|urz|5Yfy6e]ֳ(C?Z !NeK v :x @ꀀ"Vj+`~q8oMu-!?Wm0UMGc@ @)F3Ǘ(iJM+Zix,\ޙ&A=i% oVz?B]eWjhJS:WmuZ4LZ`LKS]\O2# 6{Q G1;݁BrP/<(,O=+Bl\# ı78gr @ &"F9ߦK#& @*(UhN$uQU`J.UUh(* ".V[EKXxdR+_K|\,ΩynE+~מ~ך_%L敶]FY{jq=.4qu: ȗ%XbMchVX _iVE+2 |:5:QԼEMMyW\;g&믏ҟ똮_Y^  @X ԥ??l#! :mF[?, @q4G!PI=j(Pٵn qy]/%z+R]}b_{A.]l2xjxJKKdlZ+uG(;ZevۀLc/!ntx6@ǭ 4?`g6͕,O}'{܋L[GAcF8^R@JNr`5a @@3'06QpFo>n @}}6 N@+Mf ؏<(vͅ=ӣJCq믿5w٣%gF'oJBcDz]ѣmvy 8,ldO߯L21p ort8* H}٬J~rBPցO?݅yEKO9Ph[nSˑ@ ]jȪ-W<$'vᇻA۶m} ܙ f0PhWꫯ+x @ P #V7aDo_: @S<8E i%@*8)bUӕj,v$j^xG^N8֍I+ݢh4?W2_cg`W>6CuQ\Q#N:$R[N;4O.!]Pt~ذaOU¿_veF޵~\W]wC]w]/G[o|Lx@1+Ë"<zAhz]xvM73@̄,}6b*^xƳM?4И2Ϸ~낼Rpj+t 7|XSܴ @h :J~M.b?ҽ\Dwn/ڙb" ^{59riwٔ|eHձcکc)[n鑻~m>|xyd' Q϶n2rsєJVyG^4 @bI`aDpmf6R, @,|UW)Sx⊶N;y~UYh\^ꗴ>:/=mon>G*D?ϫ{cV[mi@{Ooᆶx\C vwE߬OfK }+՜'tR H @ Xῶ4D~pg@ H>Sk+E<"> {l:Z^":cSW_}ek֕>W_ݻ{ヲ( nݺ+linzmz G~=3Kۘ1cb7@ @ @ *+ſ%/n߇֪GA(k"tU*  @@@6PTRڷoom۶ɓ'p)J+)喳w!Pڲ @@׮!  @ ѿt^̊f)uq8tTټsጆI_)dkA!@@yFXW^ +O?ٕW^{=E)G=w}wꩧLŨ}z m4Go.wqf3fؒK.i P[|9^[r @ @Qm#_~̚E??DgAm0@ Ş}G;xdn햮-**rut]dGy6|s4iozyb{饗lW{իW:U `뭷N׏9fϞmlIlر0@ @ @߶[:.Q/Rt1?U!G[ CzΩ]4У,jۛCVt @@h Iee:CSxVXyu,9jf,ŲYNvΦ55u.,,cƌ1E׵!/=؊a/79 (u|ܷo_߿ҿ\%o AxGslkf& @Yж?=G}Tafиy@ ''N={ԖFbJS?"%'SЧtt^*Յ}9H/q_B[,4AMw4M@A L6ҥK#Ap Y*Gl<-ek!d,i/?}.{WY?BVZÁ>o)],[yf;C @ @oKQ/__8eQ0}tHmuGiI1{b=$/a_ȗ(c<89C P#~O<)_=@ @ @:,OM:=p?huš_ke)?~nCNuJۄJ֊A ŋ}#~^D7 @ @ THn[()~IIRtY;Ya8jk#@Rw?8 @;sWO?@jG>jǍ^ @ @  ԕ}?/Q?drHdfԝ/Ex{VrP[k q @U@ @ @ P/\b_3%G?BY]FK¾q_eQbAoY^!@h д |WVZZj h7Z͙3Ǿk޽ӧVu[/Xk׮u;p Gӽ?o-Z\/**~ۆ bmj 7|jpN4~G[iLk/m6ɓ'[IIݻo!@ @M@]E{(-Ң0'_ǩ2B)G(Ǻ̹7@@ pjC-@hxGnf{Be]fvBu]gͳ[oѬ1csεC=^{1>|jvj7xV_}u֭=~gK{-{v7skY'wy6dOWZZN;ǼO>GyZk-{lʔ)V6UG @ @9+m&_~ftpLuAs@Q2pZDR1?cfbt JyS@X /C H=:X~] 7EQ^{ ř>L0kEחuڴiHM7dgyf½+w}umo]w]ԩ _n;wo3 ;ǯ Y}!@ @cRK/IE'YJK SfGKu)!K @& 5E35ʔ<3Yh`gqGIgaƌvWIq 'o}ꪫLNkr)֮];{饗_6E4u]A}'zSI'd7p=4Ǿ==nM7|O?~5؇~P믟\[nW^y}3xdҖk_|񅩝D9;8z[feҙ bb0sL3f."[b%| wq=>e?˥Qjp!9 Th_ކYgkСoEKV?>.l>~k\pz_ċѕW^i?c_{a^zgXosoש_yPv=w|_~Y;S-Fqwڿo^GºDnE_q)GDܣX?p<OSO=>|*Oјg}v:⋾~]~|OQMMeshՆ g@M߾ {V.|oۢ7L֫Wf @@J gF+Bvcvu' QgEFf9 >1w 4N*4-QWⱢ8%fϞBs=G}y-!=s/nEOKUDe/W ?ECCw=rH?$nJX{@=~O/>p1cǎHȗ=쳞bOhė.zĉ.Kt32 {k駟sHI!QUZp Jk.X%s[$J . },T¼Ɛh,1Y!C\W_+]wŠ\X,KbAWԶD}aܸq&at喳믗5v 2 A-:$knWa-,Q+\>Gu)RZ 2]c5quHt"5vEWxNEQH-^sYKI gZ]SGsd3Q94g9!@Ν˩p-:y EΐY~͛v:5kV˲4@쨀:#—~:j1hX"\7'my%`֝Yus.U.)/DGG ?p^A/mz.\w:wڅɰ.,>sDX ל= Hx\uU]|U4DzEʾkO}-Q"%JRKtbEGxLu$KVW_}VYeOAhiI&YDuHP~',cH\$*>dK%fZrQhb+Yۛo邰_)UsyB&=uך_4 ݭ[rs+{e{j{1aĈEOsCu͖[nK:Xh>q˴$X~IrzV{9$Mil'lK9lQ@# >~+3S/ @ K`a-W2o!ʿE 8 -+@iNe-R)0YJ@JO(wS⿵R]2EeB@h>ϳN!Pc~ގ_@+gZՠNqe]uURk_xE+BYBH*Si)f=/;)[I̍6m4S_WJ,M1Q@2y%Mb}4ͩU(z[iUZ]KMUed%JVe P2HL߮>4^tjegݣסhQXYnjٮPYDEk{Euw{8o\sgD1[r%}ydS8Oz?[2 4VǏ{V}t_W}Dm-sVeS@s!-^2pI䘦{!>@&ώ- s T|@IDAT՞_~r~K?|/sL_!JrP_E3*` F{z=iL=k9>( cNl%~vTx@5$Ϯa7 S@% WҎDS @zȑ)T5N.MUs$??gvPLl*'S=zkl? @ H Ho#Iw>r(J)B/ߝ9:HvӃM8jkuDQ?,gt][#)o#YۥjN&K@_@KL%Џe%v>S^vǺHoR/눰wמ2Ɨ߮ /לJɯ2SlwtQBw4G؊jSZ~j3l0\)eJ?ˮ>j(s=O).e$P}SZsnFOq%4^?b[Y $^{ղ^{mutJ  W_}7U^t-o#F'njk9~0tPNzb*vqd]'b~Ȑ!i_2E/X&L`\I9A ~9$*^:3k=u>j A<'ϒx(8mC#+JE]{@ךeWeE1Zg%yqkj(g>3?Cϥ\k<@^D'l )Xֶe1GmF?@ A@urjGY1Aĉ:6@1gGc|* /a_%LI@b}aY1@%cXݻtRQ*4BM?,x=Q嬲xR$%r3cY\g%*uO1\\ LQ1r<[}mbr#U{E+2]mgΜirշ99%HX5Ihu&pY՘XP1ǩ*m&ƍ>ڿ (.Lźk9q @ @ Ј X`I~ۗ94[ei"R7ŧ=A"˵w}))k5Xc i֫hN""h7 P!S"a!@ @ ,hdNeG[  д 7A5$PוM]ƣ| 7!@ @ @B> @ @ @ @ Dᾁ3- @ @ @ @@@ @ @ @}gj@ @ @ @=@ @ @ @@@o@L @ @ @ @@3@ @ @ @h@ !@ @ @ @ ,rkײwv; /m6B @ @ @ jG`mUW]ƌu Pn.OCZ~~]uU>on[vǃѣG/ @ @ @ p_jٲwolʔ)ֿݻvG.5ꫨ!Cp߭[7_MN۷7D1 @ @ @ EB~`-toi[b%o߾6qD/KF1”ڴiRK?]s5sϵ_Zhaͳ~4hn֬YֵkWSmڴ~rtMmeO?Ԕ6Vsz /؍7}J,;[fe~b7 @ @ @jM=kN=ݼr/**9s_Q;֣Lڵkg=zO>-v}w7`={Wdwa˳VZ"h@oSZAA;撰/jl饗6_m\:) A @ @ @@ %Xw!^]WE~v{jzxԽ"Gev9Ph|vEgہh+S} n5ְW^y37t~ذa6i$g}J23ϴ~ɮ:C/CstA~  @ @ @ :"p*{EKhoTrP"I$8p/..xՍ7JKK=]ڟ9swuJ/\r=iLS{Yc}ǎSNӢl @ @ @}co裏&ofOW뭷zD*b_} SLc9wze?m.Gѽwޞ_~rЗ#,M0ω3B_&?Wc3|M]v_ u A @ @ @@+aJ+_EnŊZ~V2dvawRKtW?ön;O?"om~l7t˾2S*vQGe{oe*+M袋<` @ @ @ PBvzN:vyg[r%]WymLvM7ܹsmW#Fشi\|WD"e֗ؾZO>FwqGo3zh{Gg}4)^:cix6\s[/^TA @ @ @@ >RK-+"^uk?ڿ2;SUir?V.o{}&\}LB)ݻw?U{﹘]q#O?/׺HVZYAAA(gQ~29ɉ_1& @ @ @ fI>nǴ gyƎk;:uu]Pkb^@ @ @ @M}#|qY7|c#Gl4a! @ @ @vC @ @ @ @`q"p8=- @ @ @ @M}{ @ @ @ ,NZ!@ @ @ @@or%l̙3gc.i{ڴiwٳlWoɓ'尌@ @ @%Vi@ + olMvy睖ouС\¾?-ZX꼿̾ӧOΝ+/lD_;i/c06pCkӦgڵ9sLtvsLA "єlBt^ztGGkߪ | @ @1fud#DlӧO7EwZeΜ9VTTQ۷/֭[8̘1Sַm @֤UeZ_aaa{}©j]va6|sdMxf|괘+yѺr?4֩h &B}\pA{@@s!pÛyI1D(l_rvZzHZQiM.i1%u4oFx?+ϰ_NuJ1nߧmT~?:"%+: @ @@@oL O3UD@ѣG-AXbk#'Ol[&aZc?벽<#W\q <*ouEIL3R+Mb)=TW;E+r^Q%w.[la{ 7tS:\Mc.ZovybO@%+OR@cbnN>e[}s=}q$,ezvʊoA?MYrmK/ ;wwwYQN٬-Yveka6&ϲ)!RJ8O7;Dϴ%i69MB}=Z::ZVe}[{t6yee_@}5koUs1 t}Fm `w{76s!\o4 ~^q+3ԩ󀗫NB^C/| (QH1(D@EEy!T)B("I 5$4L,nv g;9sgΞ32S ;~!`5kVx7coF>|gB  H@Pw}_(\sQc>]{{-U ig2~ϛSg~g, LGƲ$_0(GA~pO dǰ]N+5c$  H@$  H@@ +1Ko~\cq%:V)0| vXG8|mŃ=3puդW '6FQL Ç/ħ똑ǘW\q%L'*R瞒A]w5~:C~@YƛƜwޟy mP.cI[nB6髯)4bD$F ?>'w}@Q>pfK|JMvQ{Ww HPn#$К 8wODZIph#@[!PNVߒTpߒ[bhV wdiĜ;cDž={yu=hРT5/\࢟ /M7ݴP7Ƃ{K|K|ʦʧ%=vPr`IS7G7wqGrnS9ҽ3687￿UbͶ)  H@@G#p5ׄN;-**Ty督%>纵 z G1~ ްN;þ_}ʍzz |/KlRZ>X c @Om>᠃ oqX{\$x p_{T7=Y=_hx @AE x xǵ/P2" H@GofR`z`o7|p|aV9N[;+phR=GOH?93Y|vvQ)`?,C2~gʮG"+Q4O$  H@$ D@}[@+?ꨣg^yaxj2,hgc6hhaN9,$Ho(_o yY(?c ڴ,FuX_x|gAHuR"믿~Y[nGWpΜXD[L`hro?w_dѿ\AQPɈ$  H@$  H@hܷaI &sq TNn?Sy'=߯}k:n.,buw݂k| XxƟw IhUpXȿC=О}gO>P@ $x/'m"/ էYg,oYP4rHʟ2eJ `՞#FDw8s].C51cƄ^{- ?3ό~ԨQ_ ?$  H@@>{wfO}\'3A?GУsP{e3=u_ y$  H@$  41Eҭʝ*O+OiA/)Νsi)?_wNSZLWv,=zsAG F YqqNTfzs3G0}xSHhО2(߿A70汴GI~u`By{9syO9$ 0um7VO>d9rdc5סۙp~6oVU{j(Yn}rD$  H@KL`I '!؟;#7{~,fc$  H@$  HUPp*>! H@$  H@O},#=?`={y$  H@$ (oڹsp nq jSNmsp$  t, X7v8 u)P?ڟH_p?gZx\wo7, H@$  H@퉀~GuT0aBXs5~-l֡_~aĉ'XL 4[ H@$  %P=fj gǔHK➿{a@ ahwf.g!tQ H@$  H@> eaQ;wy'<2,uZjгg0dȐЫW0{ZA)2)?«tF K_Rxյ$  H@$  _ow& H@$  H@yQ`+=#曡K.aذaa Ç'xbfmž{&O\_z[lE{EVuu]7|G "f! H@$  H@=܅y23qϿ\!a}`,3N:j\$  H@$СTV\L>TYg/VX!'\s5^qw[oEs=7 .ᦛn c)S#<2}!=f rKk 믇>:r!ݻ {'\|aM6 zj6mZ{0t0bĈ'_1Z?>/t,w2Ǐo7%  H@@#:ujh[͛kv)EYk׮QhOmfaܹ?r˰>1 H@$  H@@? ']$ܟ 'e~c|fvήRѹk /kPf? I=.7H@$  H@jw X#~7 s9'G0U+I'9:(;¡V\q(Xp }GA஻ GeΝ-A#1cD@7~UVY%? H@$  H@@S=a]kI5323yE}2 憷gOGƲza Hf1Y^RKI@$  H@ &=W^y帧}~v,qI=gΜ]7a]cپ曇eY&|K_J>lzV[m]67O?tLB3Έ}{XgϞ3d/?WϏqθOG ňI@$  H@Z58R{WgN,ۜˢ1C$  H@Zt>_U>p\_wur!íx\ ;~Μ9Nx`͕VZ)yQh/~1;%p@hvmW5`T*W^VI@$  H@ tϟ\랿|9 H@$  H@mpe'<{#Lׯ_fɓ'js> VK-T8p``?a7})?5~[nSN9% 뱼׿]<^Qi{q{ca$  H@$  t0-^j]gn\3wCtޮ$  H@$ (/buwqYg_-wuBt\iӊZ aرCBo=容Bgy&ǚG:]쯿Q(`鏅>~θ_wuèQ> g,q\:w$  H@$  H#=fsg53¤aJLדwLs#ah&_>ޯ G`B.눟, H@$  HTō*O+OiAW)Νsi)?_+>sJ˟ʎG}cv>j毸 /TlrvBYӟFw.B 6 Z쳿}ڗNG{/r(Z8ŋrG*  H@: SFX~" OY H}pA ?ab/Ō~3̭w ez ,  ]:ѰЭsЫsUj}2Nq 1zvVe+7l"Hl5oW ml: qJ@sG+ 0 x&oЩS6?ȎٱRxL<)a[J㜮8_XLx o`u_^|-8*N oгg"85V H@$  H@@]2KLpa&_d k~ BaʼYx?mO$Б-tƚ3tɔNvm~ [#*d]CL釶 ]w]}~>Uۥg vW^ ׳Km[Y>[HT_eRץظI@$  (/.zK%~Loע~I$  H@$  H@@Lr(7ZYÖ́"oM}? z`+W\e7Y:[ 4w>km)7}25gAvo~3W7=t9k>JD-еHo^ SXT;-FԶ32mU.کSa+Z/SZ(\;S.PL^{T"q9=? H@OMFKY_$  H@$  gX/[6nϟV@M&yf 4B[o4VH%d<m۱ ;6Ny?ۤ1eV-dAdma^VSȼO1g-bƻfsB@O 0 ,U[ /wYLG޵ PS.P:@ j zD }7i#ތ3s=VXaxt$  H@@@ܡe7[ڿuq_yʘS  b@M s3eTfQ"zjA_HmEtS.u$  H=Ppߞ?]M9s .袸 Wկ~u{@'2bԨQ-%nЊ@&0a- +o\pAݻwC.u_}ݘ;:Cs%  H@$  4%EO3^M]W<+4T送S<,JW<1 cL kKPN(n9ŃjyBPG$  T&Ee>JC@6oާH׳f4UW]-^$  |{~wϴvs=zWZ$  H@$P W;*L6-|^}հۆo9a}c@wWӧG ٯ|@ Oֳ.l 0lذpqDžcdžg}6N (?x;o.fuO@&s3<jnpG_H'BK/4(ꖶP0@gD!FmfϞƍi($ Gy䮻 X33&{e> H`83%;(! H@$  H@[5E^j .sM/R.XsA (,R-Of/[GiV9`~^k'(=0-WZ@5$  4?%Ц̘1#'?)9暚(b;/,2 ?P+}]w zT;hz fm]#T†n?(_q-ar<~[ߊB{,뱔=餓bz+^c3gΌyX"O.Kް@$n%#7z`Gydis9' Bw"4Ms9F>[9 }v*,ۛ8qb:th+C$~ (ow&F!w(g?q/a!=w\<ғs47fZI0ꫯNѨ4鱘}H*PӧOmjJ #8}`}ྀĈ {#|裏O>`o|u׍x`~`@#GFxQ7|B;8R@9ܷ&fO=K@$  H@$  H@xw;@`EK$P]tKAaҤIrWZ., ^|Ÿ<|G aSەv=D=+U>ӣɓ'q`owyg4 >~Fy\#TG4_QӧAW^y%)\<|%=2$nQn4/ҷA$  H@$  H@:&s% ؓ*/: ?via5ֈ2qOv-S=랽q7\2^>) c!?֔7|hYcǎ{bnq3, n(aaj7lK/=v /=wq8Ob.b/z*>BP<7.d@op|q~*7U}$  H@$  H@$ EsǺ]VzϸtMÄ  BѪ=q=e =V(`=O{a;߉B"^Ai)57m6q{wg^{-CIR^$  H@$  H@$  HCX]Kɧ4頗Og)s:(C)-SZL >7fb>qdM9X;R7ۭ&~'YR^*S& ӊ~n'l\hΝI6d~M\3[iW<.% L:5nyQ}/O#G6( i'N Cm% 'Q큀sG{ ,<b{L6t@1;;s&?OGusJ㜮8_XLx #B+_=Jv(߿K:h/oeId.)nR^~L% G/Blѯ_xf[ $  H@$  H@#պA$  H@I'[og $  H@$  H@ͪ+e$  H@$  K`ܸqG  |r-a3fIB@}>гg/ H:8$Q%(I@e 0۷l hq_9$  H@D`ҤIa饗u8?d>lK"RKUUB;4K@p$ r0fhמҵoO" H@$  (~VCZA$  H@$  H@@F@{$  H@;.0mڴx  H@$  H@$ ($  H@$, ׿ٳWN;j8'x"x*UkҼ6ڨUIo%  H@$  H@$  H@$  42- O?=|[ rH߿5on-s1c 7|slފxqb馛m6Za]vffo _c-5ƽ+[$  H@:ЩSxp |:Bs=zU?xӧbm?СCjP.P #kF/\)|^Pmdر|o1{Q-~^>~YMV`1pBstƔ+E)3o޼pgUW]5tܹN^uY'~?>f[a﫼M2%Uiq Ӌ󊻾/۳g0cƌ:޸o_`9}/9 0 S)/&LP`6|:,yL|ץ>&B[%M_RgB>2&lR(1я~0lذлw;~;/뮰꫇!CO<10ʥ*6a䤓N*8s =+7=2]~rРAqwΜ9uO(O: 6\qwZͧ F0ҥK+xVv̘1U³>0L۷o|>b|;<|ۜ#?.m2|y&e>?W)\mHF) /XڅV "_Wo~xɕ^]yϼΚ5+fK_&Ho[q衇zȧ#W(T^ s)sRK-VsCo?#/^_<-/Yh:θyB_=Λg+Tw  qM-{nXfec,7߼#Gq>~λZ*\:jԨ~o3Kp pwFE^~_384ຼ Ahq4xV$  H@@=EX)Oy򳠑›o?;l?o|֧̙3"kvS_z8^CʃG|ʳx"4 (:=.n+Uxy{"}~G5 '"χgQk`A}J'N |p: ;CȰVj=WcqW.?;/xo 6bꗪ[mu:lSN9%ZŔO:Hzw}9q'ǵ{'Bb|ݦr-ǗźIyS|*xE^&_nRRJj8s!QR^|ʿkNBT?_W_ߍo\uUQ .p@\Ԁ  k)Ar+ƈL^`G]o u)_j\i;෾8?aҤIQ"P>=e>qQi\znS>ŃQ*}ߌTK0b~|7-Nmj7U7g;.t+O_ף=5B(^]Q[W^~Ϭ;16/"GS<.XNݦ`}-3˧ eP K#w绂=Kj3F}+KqHySy>OR<̉rW\ g!oXR(^؄_C+Ŝlxobeg7טK/4(Q*q lG猲3\rIGR>gAdk<A#<{>86eG<0-))\xGy.cyoT(Ur[='U|<p~иA[\?n^xp!Mxc?QXTew]$/ puׅUVY%~G!n X$6oZM]T/~E>oy{Y,f!T`>‘u|]xQ!sʥjXf;˸X'X`T;2k5uK'T6g:H,$xΜ#۴ a 6E;`yo "闹])AU戳Џ@n饗NXgTB -o;6[7,(97k׮qMbߋ|]Qpr^X.TmA(:*"G20tn*_|.oqf [nex<$3o߇Po'o( xMmK[\%yƙ1Y3&ȁh X3`w$>ӑ/y+RgxGza:dY5y^+G y|?z{UU6J,Zxݠ;[82rȀ;CΥ/X:&tRWDh'"m#xebå =zć xǕI?vrE F< q4(Pth@:<<| LOI EJɋ=,`x9Zy /$  H@$ lE2!=Y_胐.xy|5 "m ıt)ʵԙg$PE;J #FDa@~p} &͗i8S,ܰ`DzГ:%ab3 G %#XX*duLKޱl@x^]5hG;wn\Ey=o k ڬn~[|7X4o\HOXNn<)M-7GK/vsauJ,7@zya\~|7pJ͗/q>{x 7HO5~X@ƝqZkG(uF@=Xs|3?}z)̛YXn~K6ތHOx`DWygS(䕯[n(ތ^+N~ O[sJa%Q̵I{39xF`[,\7W: Z|^(ғu>J3#Ɛl 3ORA>XJk~|IzzNBd`$Ǽ\3-/B5un3)ϗ{ :yYHFg5Ao,R*%D1y ƍF0GZ|>G[ 6[³(ͳvn|\2-G{ >(Ӓy㙔g-?RsA~Mlw[sϢf[|;|, LR!)TI x " Z䇂W=ax`6q8h/4R5B˙&m,>燋$X$ZR1Ə/_( 'zs x9v~Z܁\+19No6xo.Me*xWyE$&&nXx E8?< ͏~P40(R;LR/Imx⇥/L,ႍ G&ZVimdʏn_5㴌$  H@Z,Y@XlkE=I̳s>`-" ,FB{|ݖcURywE.77xwDm2ָa(S%=cx@L^ _ߴW+wbbzz\}ur4\#.RK⁥hg/s&f <=8VQ.:!6@5[.}c,$<<픊WTJKJ9gdQxP||w%~Xc q~[a湘u(b1,;PM,[3N62uQuo^= \z-xV1-QEii[om4E9>cEyoA_<$([#~?sg4_xޠX3W1#sRd+#ޟx`gU W_J6yT'm^ME p7#/y@#A(@ +h,ЦAӛ% I%m,ivi3.&I =04+4\yKZ)ݳ$  H@Z+nxNq02dU_~xFo^,оש{[e`-y.^cab80ސ+AX?+,r6J5V /s͢9$Ƃ;?Bh., ) ,,d=˵@{FT<ƌ0k/+);'xEh}5u-d1_]brzᇣ )2 g{,خaFS`,|+eVvmWpN|݆[NG NKQ|ʤuJca`Q={o &faQ{׶R%',JCzJV(xLi 67}'8-y,06JV P.A&BN< K_c1N$8kGkOSR@~xئ#_V1 Yyv@am┧l2B3<`@.G~[Ƴ*֋+Xyb8eх2RFgSTR~+טyTcZeVw>c=S1\\!FYC7d5> XowcU6x農e&(C dIϹ=驜KZ$  MZܷQK@$  H@$ jw{Rei)s:'9 N9 S~Χt)-&Į;)A>[E+J+Tg,=Xtc_'ы6C@}$  H@-H@} ·k H@$  H@$ڻkkͿ #<2>SO=8n H@$  H@$  H@$  H@홀v;ޙ% H@$  H@$  H@$  H}ռA$  H@$  H@$  H@$ "྅ۭ$  H@$  H@$  H@$  H H@$  H@$  H@$  H@Zo$  H@$  H@$  H@$ "$  H@$ !pqUѣGG )I˦<s$  H@$  H@I{$  H@@[s箁]zK5nN:O>qm`k?zk5dfk-Z$  H@$  H@8& H@$  HhNA)}-qn)6A9-Ŧ|7q1]$  H@$V(o+㔀$  H@$еXPO7)lSɠǕޔa$  H@$  H@\_%  H@$  H mYӧO:tCM:5aĈ߆oM1(Ǽ)ؔt H@$  H@oT|ZxJzHtFq882ĻR^J˟ʎG}cv' h+JXpa(w2Ǐo%  H@@PuTq~֜ %e5kBXY,_>K{{3g Æ /<*~k׮Q_\o߾%ۥr}7mڴ +3fp!z5W[ X T驜w;$  H~U~w6K4y1\ߋ%$  H@$  H@m@<ޮ]wm$  H@$к}}ᕞÈ |/ NGcS I@$  H@C$  H@$ Aᴡ4ٔBlʳ1G$  H@$Qt(7}J@$  H@$  H@$  H@Z#SqL$  H@$  H@$  H@$a(07* H@$  H@$  H@$  H@8& H@$  H@$  H@$  H@0w$  H@$  H@$  H@$ H@}kT$  H@$  H@$  H@$  t ;GJ@$  H@$  H@$  H@@k$ྊOeȐ!a饗E=pg^z}X#דּ wrZwqawn6hp/~ ga H@$  H@$  H@$  H@ҥK8Cz:w^|p׆;C֭[@,f9s?aҤI%5W"Ah߿0nܸvmZkzU]ς$  H@$  H@$  H@$w`M7 lA̚kFBZٳz>} w~?ŅgĉO> pWwy'w}Uױ$  H@$  H@$  H@$  ,"}ošSNI%c+gy&L2% r}5ׄLJ}'L6-;Pj ,wqG/a^ +bx\ov-3 ߟ{pǶpٿ&D_|űM\gubފms׀+2t=9>oy,ꫯO<1 /|x衇©yذa{/viQ;? H@$  H@$  H@$  H@(p#O(1" ۬Yª`{aK]eY&]vٰd$  H@$  H@$  H@$  hq_;8 &.>}zu/ԩSU<NS?~8\rIKka/:(|k_ո>s1|ʟ}ߏQ-`_z2g& #裏͸PfzF{… C`̘1Qig$  H@$  H@$  H@$ (M]ILRɓ'G[n-?υ.(H EχdU|>/PSSf̘~1>pp![._-G촑z<6Q* LeXg )ͳ$  H@$  H@$  H@$  ,",О!CCjo?c^,OgX'a;iz_W^o6cc=B;nZ 3gΌiJ_Tsb9S^V͕$  H@$  H@$  H@$>hq_sF(O']72_aqEرcp+{?3W_Pz޼y1r{?d=S=kqG KY$  H@$  H@$  H@%@ڗȎIe}|iw곿:vyh?9~rGCz6zЭ[(|Ǻ> oָ#f͊y7n\3gNk~v ~!MDZwyߎ/q8y=~>JR}$  H@$  H@$  H@:*NUx2R9t@qaȑ-ougv6`(|kw7?|I|z5dBHӁRD#?~|N%  H@@K:uj4hPKtm$  H@$  H@ML ۞cvv,=8$N霋)-ˊy)3Ji)/ e"͋C>T/?H%'\ط5ױ4.$  H@hܷջ$  H@$  H@h{o#n- cлwu]W҂ܒÔ$  H@$  H@$  H@$ 65xW_܆FP%  H@$  H@$  H@$  H>7H@$  H@$  H@$  H@$Bܷx$  H@$  H@$  H@$  @@ H@$  H@D࣏> Z9sfΝM䓦޶ފcYpa,_q ?p$  H@$  H@(A=K@1I$  H@8|={n&Ja]w  *ȸqM77Q_=r)ak ;75s=7L0!|aȑef 'xb?~QW_ /PN;7l_$  H@$  4*$  H@$ F'xba?[o ?ªX$t=VԩS]tX)3Q@p]v X'n(Gr-C H@$  H@$`  $  H@@{$Э[8쯿 .(}~޼yw2ӧO=zKژ3gN@@_@NSƂ@;?O*B2{xM[Q(u#pa_aرcgRQ>+76YUc$  H@$  H@hD MI@$  H@m2,Zk(]{ò.>0iҤ(2G?QX~V[m?EAW^ݷ;Sc=6 Y=گꪀwc\o>)q~ߏpgqFx!oǢm]{ÙgLVYepvgկ~}q?Ob^.3-R?aT׿+ڞ`Æ ה-/ pGpW\qELŇo}[kdzsD;f̘:7zX7{80$  H@$  HChލ;ZoV$  H@hK <ϥl)`=u(OCl\ߍ Fd ?|8km8$.^?nP#3&OB{᧞zjAX~_G= 3fDe/./\?`?zM7K(>ϭW^1PA? H@$  H@$72P$  H@&MOx#ktgnmBw `︕bvڴiᡇJU m"0F(~={F!mV\@wߍ#4뮻.Z?O*Xc%`~5ֈi (5*=QiN Sovb=T&D;NYBh?xzh`ǂ;?q5\3DbW묳Nt7|XGDz̙Ѣlp饗ϴގ,  H@$  H@FiS$  H@@%0a„pI'c~{v)tOwAJ:Bd;GW]BcBr /V]uհ[Ç=3Ɵ}ْ7x#cO( 8'$x;D3 [ouL]>^l92!`/t6yJ9Xs?#O|1Ca G؟m@(?R%:K_ (eG37 fg/~1$  H@$  H}s H@$  HU@\,`}$T~뭷ꔯ״/B# sqYꥴ^: Ϟ^yzr4rw>-q>y!p m{KEʞMcBl@.{xZmK@IDAT~#<p-zW+ 'g)Sy,op9;3_I޷o߰뮻F|*p 7DA:7xWM}sc;vlt"Ÿj[F$  H@$  4- I@$  H@m@9ktO)~h~dž޽{Yf" (3 |>/|!ToaQh o,ѓ{12RҞկF/(zXߣV[~8}{)xH勭Sz%kFx饗DR(nk H@$  H@$oj¶/ H@$  jһ_~!J/5`aa`~%,~7^zitk/nE!uJSO=5Z̸~#Qh1cСCVXa_==c~Οg~x m] \_i\fB{uQGEիW,ӸX{J?㳦,Yg>8v oaק, H@$  H@> NUT.U&V*8R;d]MKKYW5-P<@P?jԨ/_=о>Tۑ$  H@$  H" $  H@$ G%O>9 80`wD=Vzhq;oX$  H@$ !}p}WU}h ${HWPYE`YDuu}mk}u׵Wl*6(4KkB;pjH{̜oN>g@@@ ШQ#{mÆ ~Y*eߗ,Y2KM@@@@ a   p   `|^@@@@@@@Q}64       y@@@@@@@FوO       @@@@@@@@ g#>M#       @w@@@@@@@l p4       {@@@@@@@Q}64       y@@@@@@@FوO       @@@ g ,Y`ǵcG+,..Ί-zgSJ.m?fٞb-O=?E\fKE u[a2'ic?&j%cV&Y"qV&.Po-ޜlwZ>.F@@@ ȸ#  @ (8[o믿niHNN'xӎe)SLuz>c={8vu_~lС֡\m6ӧ͚5P.?fzhTaLcK$Ɵ~#yw~{q䡛>BعQ˪Kբ?/_NG7vM܀    z  0;wښ5klԨQvP ְaC˕9˗9H-P1oLLɓ?[9kiW$D|dBKܱڨ8m=Ҽ\`]5ٵ-.ob{wA;ĻŹb@lƁm@@@8RH@@N l^z~jcmҥ>8ߦM;|„ reqLO?ٷ~kw"E5\ce˖/6x`x\%k^|]>ݿ?WpsVfͨ]{oƶnjW\qY{9yw׮lٲe;vh͛7,\gڵ*Ud6mJs siĉֳgO?y~˛iUƌcÇu1O+b'Kl\@l•ګ/*$O7ِsRiYi~?eZM7E Zb4?o7`kZNdBu.PqFU{Ik6چ)/}\Q37ӔRvY?{ֵ+]_~t_ [x]+zYޜឱ9u,(r[gժ.Yl .z ZrkjY^vSGx2EBl@@@8L\i @@rʖVT+Y~wmvuYvlѦ}&M|ZW_}k랯Zli7tΝU 쫯ut|MX[h6sS_lbpW} i#ѣ^o]7sLʕ+}~ƌj`zP3k 83}Mo? %%%-3~Ȑ!6w\K@#Ff6}lݺTK͛758@V_ ?mr÷vQw_}YٲuVž$6X7}]O3Ӊi+ {d'[Ta.?qff޲@bS[mlՋqۅamn__^y W t 䵘}&,f-ֵ>Wڣ ګO?ͮU&d1|s7lkmەf h=9m}`   @V jaG@@/2onN^֭?VF ;묳Oc@}ŊzO?=_Y-Z48_5e_|VJTQf2۶m?Q.]U > wϟ6| ~S]vi 2@K/}` 4i)z5@9 *x5k+}Uf(Zg>mŊqFߏ9IuR <ezֵfpPosZ%ܫ\ Y>mb6;n^1Z~yB.HףvV٢rĭ>xε,]zvA޻K7X~>v 4`[ӾsRMssVm.eG~nձpvڱ]2?uYտ5ߚU[ꖷ\Pm}o6mfФD!{=f)   d@y'  d +K\Y * 5kw…z *gX޶mVZvWQ\SŇRP!S&S`=L5_np\+hQ}eʔZS^m*^Y k|MWk>=?~ul>P|tA|)5@ ^RR=cS}`6n` |%?@#ъ߯XnXW0W .?(](ֲn{W_]0^kͪiA{y5\b *p 4%WVlµ.5laV._S'q߫)C)J-;wvZÄᔕ*{]ϕ?1v    C6@@@ G 4jȦLהWp\=ข* +Я gT5vZl%K4wwTh֓W&[j^?uU<}O3k~jQjYÆ "_Ϭ{4 |Uϩ`l J0A|=W{WQ}Ju|~M,=2+=ؾeۯʴwk_\M ;Vru7)hҴevk.h_ئۜv?hm\&}oVW!֙W \ǣ Pi%> 3y-.onֺT\*%vy47#@d)/vOby p5v7hj~U4 J!wOlچ->C_4 VnCLLï}0_kկW\r~ziu5SQ;*_㨃TϩXjK|_\aE⦈ *w>^a=י5ͪM*sj\?/iuTܭU^f?h_^ U 緧[V.n/䦨Ϭh:]{RQ}suۮV?K8c]kq6Znf}~ePsu]3ή6BP~gn| dxM_U4}g~-x׏|vk3YFۜm:MA@@@ 3ǽyD@@W@ALWO};2y{:uX۶m~}`Zwq+V׏&M؄ W_TqS+x:ڴic_({k׮iWUV ?0m~kJӪOχgS漮W^jU7KPµ|M{i;uu| ZB@B .#G4 = kp֬WEt_߰aC |^).-Yu̎,]t=y('okgr>>?ǵݥMz~T}4V53<6tW:}Q^ rG;}W}ϨݟP]!0·v[(c^}۷~kZ %%kAS}x,JROywM_M1zDU&FϤ?ֹgq#4u~v4=~dtyM)U^76t`cY̪   pܿ\jպGk ) ou,|9t8mMḿ`53;فv@@@HAsgv2ʕ;YPdԎEYaY۶m_ ^!?}$@XxgTy/DzD i%2yhrYr?f)Д[vG xP7[@@@Ghq-   @uֵۖ,YbʬX/^<{8@V\QY6zEmw*Sj|@@@r;G   -PP!_ t(c]j>9@@@8~~L@@@@@@@)@>g^       )"@E       9S}+@@@@@@@SD)1@@@@@@@r{W       Sc"      L9B@@@@@@@N/D@@@@@@șs^!      "O_4   ޽6md[nB"p q7ze%I'd6'G=A@@@82Gvw!  '1cli`]v%K;{[ڵXb9(X~Y&ﴆ ָD!+'NR+˰ﴶ_lֱ:q4;T!|QΝ _;欴;Ohr:g@@@8Aȸ?A~Qt@@F`>hߢE gϞc{m׮YӓU}6l-Y*-rٽ?f~;0dغ#[6e[cvunuh%!^\Oco{γ5SNnW@@@@ '   @F>h_V- e˗_~֯_oK_~lNxvך,… -&&:wl#G+WZBn}͞=۶mf7o͛[RlСݖ-[\`r 8ДE8߿oO^J嗦\~妙FVOn,>>>#`]{3-6O.pV,h޿к+pӼ8}W!~ZɆ,^oJ)qW-i;ܻ!6e-;4h`϶of8paCW,ޔ9eۀ 1nZac絛\6a{yUj Kv8\1vqc~^$}< ko`g(߾qz-gϩcy'. [Sldϯ]+ݠvw}ԾuY:cr @@@c.pr?LT  '-%%4h-Z~a_`}W֤Iѣ+Xl|ַnj6lo .l]wu{_Ν;mֺuk4iϐuM6oܸB{N}jKmnٲ (`7t7o^K|;7VZ4E]d7|[Ά sxcr}Տד\R}viǑZ Gn1+7?[ְNJسS~au>hk ߎmIJDf} 7,M|}/7Od~IJ c,SKkD =s 'C_mU/=}fu{6jE}6vmn.kY(MsWyh{˙iIֵ>Wڣsw5ϧUi . IkٹYrc@@@?.4  9Q OGegT~WMJ_A[߽{w\ȇ z5|@>LmjL)R_MKڵ*Uo+V0U.]XŊcǎԩSk֬352˕+g`~/T*Vu_kܫ^糘}VҿS]wOJ)e[3~5tfЀe/f_Y~7}~xkߕ1.yl+ni}B)ME.5+uf    p<OmB@@%uѴ 6L֠Zc^̇༲C>?[E^Ay6t_8c;wY+W> `zDf23y2k঵\(ړ-ޜlo;VrA>?`Z{i2e+|8e=>mgYbK;%\ΜQ\ߜvXSzrukKzrӫ pҲ?rx{®Ob5 P_(>Za |\^!   p,~~,j@@@PpY +ݧO)5tOXV,yR|r:u%''ۗ_~i?_>WW)}Q_f (\pZp?z8sNsZT~qWlwMuz!YޙO)3kߛUϵasټvv6aF{í ̭~S]{3wv˨>S-i>DM_eاULMuAsSͷ'v6 {#9}Mskڏ]䟩ٕ͌c_G3ה@@@Kv@@@ G 4nn'O}T~wn 4UV)uR_>dk@(!]#k_e˖PGn?L)_n]?~j_wMXϞ=M]?oe [ׯgm5K7/}{?y>"7@/M:#,2W\h.o]ϰ7)   Y-.eRk"EǴ V~?6|tD ±ȭ O:sL)Ha=SmGӦf L0DzL /Vב׊W]鋂v2#;Vߵ~)򏦨CeSNl.ִDAO<7 jկ Bn]c(jCxu;o8w<6@@@SU{̵Wv:nh[ pNc1mm}}G%G~ٱp-QGA@@y3*tvcu\Ym왎n?sOÊ@?im|} G+=V"~m܏    pE@@@,xYP+U"   @Nt@@@@@@@&O       H=       (@>i@@@@@@@       dlħi@@@@@@@        @@@@@@@ p;       @6 F|F@@@@@@@=   'm)'}@@@NmG@@&n:駟,555T-[iS;l[}gׅ{7K['d6'3IfoPGLcz{zAA@@@\  \{\pO>xgv,+wVXak֬FY\l6i$_*T(+X`ÎyVp[X'R.w͋P(Uľֹk[ [{;f*d/jOVnMq}kuT~n[nS.Kޜvi-_\eeֹZ)+{S   #@I@@@ -[tv-M7duԱCڠA\}M2lDҡC {ꓦF'{oiA/kjeblS.hE{u ?ߺmef}̜LMb䲘yPVq2!^{(/8">``<.b'˴[잱lKк%8}VS?   p }(<  ZeʔrfVXъ/n{V`ASV|`۷o7e_qVn]ol֭;瞳.իgK,۝wi-vvbōlCީpT*rߴ=٢q@}?ͳ笲T7UgϬay ݧVog׶?+|]4dؽڔ-jK%{*ֱr ?쯮K^?̱7]J9u|@ďg,\^o74 |R, B]=ZI]EzܺvǏnṴE׵'^d_/Yo+L˷&["qί`oB1QVzmӺ.˼y&7@a{yUj n;zb$3l@@@Nn~~rt   p(YZha] |`wߵ曭F>pzjl̙~=z1cjΜ9?~WV .ٳgO&MRJHIID_{5\cj>S_tEh"5kVZ5G~-sNM׫֭!CD>.'.}(Sv#۸rZ^וȟRRw[ګ.ەO\Z55g/ldOfxwЄ Y)mR^7ݷ`S>+ǸZ7U )޺sˤ{\:#֟_ɻR ;MX`oZok}fG'- ӶCA[Wvll#q3qWH~ש]X)6ݦvϴ}"noil@~[sf3R$ЙpϹz^8okS3+nè5Z   pJ?%~<$  ֛WQ@^w*T`ʔ/\ϔW˜U&y|2SSSmܹ>^()4h`-[%J}=ʊY_";u6lhժUu~VH7楗^j=cǎ_ ?6?qƯ޴_g%sڛi\F|dQKpVeWG8q5q w_Ri{e7(wFevARq{iV.``Q͊so@d]4@ *׹\濛~P|okPn]z)3{Zu Y (do`xiW7}wҲtiVeſ+{lٲ]˗C +YFNix}'/\|۽5twr.U /즚ɕfwwN-j%,}PvAmqek[ؿ2}bîߪ6MzBibɾEo ^Y3y]]7_M寢\m)Uv`' Oe }`N9!3(Ur@@@$?fe늭nxe<ўuuk@@}akSuy;ӗXaT*~+3^~ ZPhO\|(2Uڔ)__P\]:528Y5v)~Z񂾎h?3ݓAl2V@@@NN߇zS!  ؼyϒW'|bG6?_`A^ כW~ִiS_ozlڵVT)tK.ʐϨ kчcݓ%K_ĉ_ٳGSk}ML|ʉ'@}h2uZe~{Cԥ.]O^e_tͭgΚ6>ukgV맿ٶhs_>_WX]7~Jnŭy $yn@RKnmg~Y2wsz 1T*kg_~+.S&hoi~6]wI}Y ܤvsrOs<ֵFf hl!QQ^C4A~X̎gf}C@@82W9y@@@ .}޽yej=zE@w.]6uT}VreuW^jժ>]2u,rիڿ;-ʘ%r?p^ۢEڕW^iM<ٟ:묳LtN}|wٳlj##fg.~[7 ~`=(_R# qďZǟ?zjMz>G5g<ֳ}v{Dr?W`]M}U?1[뼿׮8ruT \GϨϕ;UW+>wέr;zt,}έ?r hGǺʻgn]{ LP_T>]?ek5`M٭Y ">*gZvm׷*[LD?rH,C"  ῍3{hDi>j#쇭Ǵ ]}|8XVZ~n!L[ '@ȼ6|'\3a„q3  pDV`Up7ر3ˤ?je'''[\\ L|ؽӡgY'8K2f_lɚPiW֭]+@Z-V'iᘶ{6#}DX8疛   @Nz+;?>>>(Ӟr 55K{.K>2|A{=֭'R"sݣݧ˭q;̨lˎ7D@@ZYK   9:@@@r        @6 &xE@@@@@@@@y@@@@@@@FوO       @@@@@@@@ g#>M#       @w@3E%@IDAT@@@@@@l p4       {@@@@@@@Q}64       y@@@@@@@FوO   pr ̛7Ν{r=OsR ̙3~דy8@@@N'o>"  @ OcYRR!ŋ{_|a\"p(zz)ꪫ>7p=Ң:_|Em#X߾}1}۷ov}"@@@U ^u   * |rvYgQu|Vre˕+y睖;wn9h\a lڴ5jdrرþk{߶B fm^x!Y=>]VXa5k .ݡ}@@@SL) q@@@@5kXbb5lƏo[N +ҥK}M6vZ>}l֭~j|O3f?v%C I&kԨa\s͛goyfS0xvuYb~ի}{:t-Zi$Rti^{}k.ի{VN=ֱcG^}{GMY%Jx8>|n:~˭zv}YBB駟;ud]vhFuV6̙3-OWQ@uv[ΝMď>ȟSPO?7nh (8@'kժϪVֻ3w\{WZj>;\޿m۶Ai5{(Z%4DAr]^ꗍ{T4E@( W_}e3[/{wY}5k_t l{3-Y.\h>m֞y[j9Ckf }^hSGe˚P     p<ȸ?ڴ  9N@iӦ@|L2~|/mn:SsڵX.W*WRKek +{”ʨ3g_[[TtW61' PњzU) Ycz;<HNƍ1b+k](3ZZ:"L?~?@ mY->lΗ_~ۭUiP*峿~.SNMՀMnɯAPfM~V ̈́7ظq#ZzW@@@Pq  /Fek{e*. iPSQPhMIIaJsST+0mt}jo߾/,3<ڷolOMTה*^ `{* r-8pwܑ6u|Gw_m(k^XO(z3ozz_MseۣnA }=Gj6ա&f̘au }^Trd;i   @ b`G@@-`}…3;MW/Tqqq>sY>e/B_GD^G v*)LeSP:%KRjW (i5Ի_Sk ;wyoXF| VZ@ B <t 40-Uԩc ,HRϢue4L@@@X5@@@ (9o<;sZ'[$V@_ze kyek]޽{iT2C|xRZ~[^|'VT2*@ oߞ5J(/8F'Wh #GQ[ӻ$~ԨQ>v8*5E+ȭ5>{3[A}e[>c> <ɨM[III~ցe˖̡}U57|~a7eԿe߇z"   duԏ  e*`P n_y2[l5mֹ{IC=\R_˪_{e*Pa۬Y}͛7? >ۓO@Y :~uůnݺ3?ZZ B;O= 6ߣV^GPF?}"y^T4%Ŋ  yG-Zeׯ_^N[ |Y=Y(   / =]y,~8mOi>Fy"sXVZ0t~N$m3k%FA@NK_X,{\Mí^d`Pzg!0y(&CPƸ֤R?i&h[ 3;+egp~Vi-pL=r~_Q qkgv,3(@@@ c;n?qٞ G K#s{YsmF.59=!   Z    'xw|4E@@@ 23   <eCA@@@d dM       'F@@@N% &>*l!Jϊ   hDi>j*쇭Ǵ ]}̓m8~)ݡC~nkr '={|ǵ TN7F@#HLLbŊ܅    \Z}vFX:+E~ǵMS\Ḷ*:J~f9O       _eS@@@@@@@@ g<"              dlħi@@@@@@@        @@@@@@@ p;       @6 F|F@@@@@@@=       (@>i@@@@@@@       dlħi@@@@@@@        @@@@@@@    Xpmڴ ,hժU\r$ٳǖ.]jVXrflI1@@@8ܟrr@@"ƌcGޱcUT.B+VXQ oy9ڪOm=we{>ߕ~*111 8%@@@%@>g>   gɓhuҤIW_SO=eիW?XdIZо}V^=ďr=7o^KMM=֭[[o;woqX."    ϐ   p* ˗~aʈlsK/_V2-663eҔNUJ.mrKԠƍ} A*Wԏ p͛#g mj۾}?y_?rgRH"Qsnٲś*T(5}@9m9azW=ъUTT3=lסvpq{   z@@8)ʔ)cu]e—-[֭[ xkzW_}ƎfknV͜9ӺufF˗)WZeoֽ{66L N:Y׮]}4PgϞ}~o_] ;<V*˗|{=8q?@O?mUTߓ_ӧQD {LԣG~*x3XRw]_G}뇂wul2f3FڵK&V?Cu]߾}mРAiUo:,?^?曭~#z6rp5h{O#a@@@@c\!  '2ΕEבEaC>..Ο5kL+ <(x Get+#\j'|u*_|O(H#ύ1mݖqgiA{U4Xᡇ:+~ nnZg>5S>kgL:Pr5~}Gxӂ:=% iA{ L _ F"11tP^}Pzƌ~P    Y!@}VR'  p111iS+@;|p *[+V@WZܚ]͛7O{n _NV ^+ 5Vyf͚|ֿ?PꫯEkCxڥKsjSxe'~4iFaʕ3eӫ^=u!"3l}&_׫~Ν;[.]|\mkj׮mo.믿0>Cmڴ^ľ Ьf?`0 @A 6;Zf1 Xh϶o߾W^~fP4CmS q?Q(     pE@@NHe˖< vz1Mf]xehk5]"֭i\sk8p?|dྻf_E_ES+`*_hXtK,ApU_f~{M5׳*pv=E]i,X4ˀRY~ 6{a@%,Ou]ݔ77,^F:~'گ\=~)Sߍ͟    p@@@P:HhUBӚ>} 뜲3*aP+>Edp2}[xda?2H(\kO81Tq[եyKT4 @XF@5!L*Z>WB:~\m{_Bӗvw}aÆphb    !@0@@N^e+^EA|XT4ͽuWZT/\pڵ[M9YtN%l#~ A7n׿K2ܦ+ϕ5k׮,w]w)`iuk'=;?4S!?ԩ #|^}۬J*6gS@@@@؛US/   p(x+Vh*U: V_Y_}=7ѓ*k=?cv*2d%5^h*TիWQS >ACMSOgga@j^2])ӗ0(Bu~pָׯ~z.-5PzuW@?: @YB6hѢ    Y-@}V S?  :@ ըQï2CzVGcW^>޼yvצu}VL2>Q2:c!PLkgk`BrgR%J:~  c6mPە3gaJJ`}g&@@@@ _jgOjcqmc?{8·ٱpLI;   @4tɊuߏwQ \cUɮl̊G~$_ 6SA8@@@8Z        @6 &xE@@@@@@@@y@@@@@@@FوO       @@@@@@@@ g#>M#       @w@@@@@@@l p4       {@@@@@@@Q}64       y@@@@@@@FوO       @@@@@@@@ g#>M#       @w@@@@@@@l p4       {@@@ٻx?LT *T7Y檿BsnrARRiP(EE2eHy:O=}sss<>kg u{TX~GKHHHGn+ {6}t[`AXuz!8q?tI6m[&9s؈#l׮]QalQ'7s6m4;x`r_9@@@8S5  W@n۲eK3yd{m޼y)zOE7lw)`Ӱa\Iݻw6#I{kC= )yf[Lvܹ^z%8p'OФI{쮻;Νo͚5[727n >;   f͚e8p tKG]jn0V[Iл ڵ+t|rSLqˮ+\|yWC q|f㓂J<}5;\A*U 4|M7]}Grs\pai|%}'JߋԳ FhAR){Εڼy m,SAwh~򴄿/cF5   dBK   >pKV\Af%=`Թ xA w5S_4hgWP\+iiv.ho&:t}QaUI{G[o' rZm9m.K rmZ@Zjcr}۽B,~툥Z_ hyꫭiӦș뷢ER6~{u̘1niڊM6m"@@@2=J@@HG;t (Qڵk箵D?lSN ͤoJ޽m٦=\X[~}ܹ;PBnSs~~ݺuCZ6~ԨQYّϦ/S͛7ϞyS ` +W]ul?  \A|/bW+Wv*_X~pAԊd'NI)\4&у r-n5-O_~}W]/w5#? B{ګ OU˭W^nf~gZ3t]mk0bĈWC    d%4@@ʕ+ޤI F&]z7n\3^{kZ2]*#=ҵŮ+TzEAҥKO?dÇO>Sp'-k о'jժg5xGqZy@A{n֬/&ɣObŬdɒs9uOY" >קwR^z]yU/'(hz}Q}Dÿۣk}7vO~w;ۇzʕ+gZ_ ρ>?zN¯}>/E^|tߧ={(~(@@@/>I3˓z?=$ȞTշUۓ2L:"RZY믿NMW\#vYZU Sdק>@@@@ !=@@@HfǷjnFM([lW@@@@   p,Y2Y(@@@'!       @ j@@@@@@@{~       Q}@@@@@@@@@@@@@@8S5               Gqħj@@@@@@@@@@@@@@@ O       7  'ҥK-!!!M VXa7oN2# ۹smٲ:yk=u֘n۶vq{GrINsjc$hc#׮]iӦpL@@@N'B'#   M@A^x7onuԉHTf׮]zvnjco=SVfM7rH:th|I;sE^Tʖ-u:GmֿBϪ5j:vhwv+Vtm,Tae$Chճ~zZbŬsVxÊQgWR%{g-W\Z*PY7xvm%KʊGO… W^N:)j3Ǝk rra}%JǨ"@@@TiIa   c9sLf+x;wn7Zz`WWIo֚5kֽ{={gqv(`W_?oÆ K/ ;_t6hzapm޽ k믿n6l /'篽e͚[w}7j1}M   i+@>m=) @@2{1ofkܸ=:-7߭[нO?4]x]r{O۷yLJ.mzUPCF99x1ڴicv jPWp<2,Yڷoo˗w3,|KAc-~W/.\.BShxEtMUjxҳF֭[[r\4Sĉm `Μ9nE|駟nM4qs,A =PhFǏVZWڵk羃%K2r<@@@H{O{SJD@@L(@_lY訥о2Z]3]ߩS'V *+ص͚᮲,O =Toٲ]" kfilnP@LtV@۷[߾}]W@][(=5_Muu}^|Z7J~4A~sݺu.Э>iu-g VϥQߩ<NW`>VRZg7@{k 75UWK˫8p{Ȑ!ȗ8 xWCëjV Pʞ=*UʝQ&*_m.SaE*x|sj>}Q>Xg͚cRʕ+j|PhQJFcR}   4@@Ȥk׮uU}Ҳ[nu&Mr{:*YE :4_{k(A_~]wu1gkԴiSS+G-ZҥKJ*U5^v hڨmﺖpWp\+ hzGa C}|ܠ?:wY*~Ŋ:=%'^W;<fk0ĵ^kZ@خO 2Ν̾wڋ=<,/:t unoٚ-߯$*믷~ۖ,Y*C/_޵M3ǎS? iFZ_(Yi-$+mn&2,yNW7on/v;h M6Y.] 4իWw}gv[4jYmojoE{k0>/[}A+ԪU/3f؄ oo߾n[+f>ƅw@@@@ ,z;D@@@@AX%4رj5h6l͚5skw\ ?ny.]կ_?O+fkvvϞ=m.fָ͚qcH 7VJ ?n\24]~yPy-[tK+Cz> gy&bQ:t0եT@oJ*K[<k?|w?^.}>iVX1rvwľF@@8[h >ρ>?zN¯}>/E^|tߧ=c}@@@OhyQϒJ^Z6XW e%uT8VRjCd))7))+:xcF   d6Z'!       @ j@@@@@@@{~       Q}@@@@@@@@@@@@@@8S5               Gqħj@@@@@@@@@@@@@@@ O       7       @@@@@@@@ po@jr@IDAT@NhKZBBBX6oޜeFm6ۺukdv:ٳgOMρlӦM6&)m~+;vZ]\=@@@@~v!  I ( /XͭN:I?̻*k׮Vzu[cƌ7xÞz)Yf2Kׯ}J*ٳ>kr_~ >VDxw@@@@ _cҡA  K&Olz_֬YO?Jᮀ wޱ={O?dGv̙3FnA޽MFE-2޽۞{9+>;z tG-d0_|4H⭷r(FiSNu=Xh ڷm}ws`8ݤ @@@8!6U!  @lLKwnfkܸq Ν;[n{~i(xb7SZ)rJQ kf|x]F֭[[rpnfĉMKGKz矷_VZPV^[ *)x|hE%;O3K,iKeکj'|a?gv;]kueN0ᰲeF5%ݲeiŃ:X|O&M؈#\ǏVgWѮ];SK,9].@@@8F4   @PYKϟ?^2d᯼-\L\0^zMީS'ײٳgwyZ\Y׌~]6 W`PQɯ@f{GK_|{Go~#35@m^Kkw?}ndGҥKM+"/ݟ7o^ӞLהwݺu. ߉wa Z+%@@@@ p}@@R!ڛ]WZ-Ϯ5{vڦWZe+VpVU^re{H"}Sє(pOx*S,~G9=̈́WXKk@¸qܒ7S4B˽k,5B#Ge5k41#ofݻq+WD(]-Z4#v6!   @dO2(@@k׮uR}Rx֭.ҤInvOGͮW[zU~zX5[4p V [K-gy k9}}Tfl1cWR\W^f(=O;p#G+ΝUӧOw:W}WOe/7SIW =   _;   >خ}2 +0knTbگ<|tZ,~T@e}RX^3<=/6 H?kڴ ˖-s>ȴƑKӇs;j(??+VtKk) Ȉ)%-^@}~7jժٚ5kBI    p ?Sz  Pp.sε{ϮZHUp\|}ok\V͆6lCO>qAԩhNWT3h ?lӦM֥KW ͛7w{=5@7x^kݺhгgO{Wݾ3fpk_myG}rҥK[CĻ?G p %յooѢ;W@WйfkUVJ۷wǻkMR?姥WfG|tTJ?jz|bŊw3ŸHݸq飙zGx ]s5vnU\:VHЪzJMBF?m@@@@{3E{&uVw_Ƥ@ rK$)iZ-|oNbm9   ,BӠkϮs(Gkc n{>_G%)<<Ϙq@@S Z`^w\'ZJ^6/Z75eZ5 =OnJ?Z"^2KJI{5!),:D@@@4k       q p'xE@@@@@@@@        Gqħj@@@@@@@@@@@@@@@ O       7       @@@@@@@@ po@@@@@@@8 #>U#       @       q pG|F@@@@@@@=@@8.]j ijb ۼysYضmL$O:t(j;;VvM6e6Fعsmٲ%fɬ}     >ӧXJE@@2/5oԩ& V]vիo=䓉ʾJ U+ŊΝ;[+BAg}-ZeϞ={ikPY7xvm%KJM,~i[p+vI'E-fر6h w/G֧O+QN6FmP22շۘ1cٲe:YgǨ!@@@EJ   Yc9sL*@;wnW̙3F֯_?ݻ4j(k5kV4~7Lw}7jy|[^~e6lժU^}U7;\_|ѕ[oY.]lȑ6uԨe&sܸq6o޼$gkPm۶Ç9cO=8pmLM_}=K/u6v}Xu @@@H7FK   iϞ=ֽ{w曭q6zh4{[n{~i( xb7S])мr{^dI+]-[N=T;CSr^tE.]`A+T]ynFgW^l\rg׳Z}Μ9nx|O&M؈#BJT` /2p   +RK   IX˖- {…/vKk={gokv;udժUsQF仒z2(U\-u{Jԭ[֗/_nVr[lf·g6le-j 뮻WY+#eٷo_ ݌hۙgvm۶ڑm UUӦMs U ͬ}   Fq@@m{fWZ4k?v~a|Z_;v|>薇W0WA[-=;ꚕ}NMէ:TF2e2dH~Jܹ̫>iG}vrf͚Z_mL*i%4x@ ҳIH.O<}28pNdό}<@@@@ mܧ'!  @&Xv + m֭.ҤInzOG5 H" }Y]ֳJO>=Ӯd0AN4{^y +쮻r'hOy!>x@`~2zLAxFpZեox}zI&4']oذ=^muvѴiSS+G-ZҥKJ*Ό}L.@@@@ בt @@@+ 0%s킴گo}R j`f+)OKX 2Rp`СCm͚5-ImP_>P`\Afɵ̾V Pz顛<2>[nZnڧLŀnM~jcF"o޼~0Fx~ˬ}   Fq@@ j?>}su5s\r /p{K .kFa\O>qz?|޼ynM6w43TRVPZ]{kUfkvf7o/^f+_gF-e˖u߫Wn]vu={ߨQfŧr|My饗\{VV-UƎ늽mƌ6aطo_|Ŋӭ)Og^oے%KoH友>F7y    ~,~  @@f%ct▗oժkР5ld5k1 *k6O<)0YK`TYZ{q(P=.3СlҽYߝ;wvnG ߾}гz6AI˻?nw]_s5v4Iu'͞מŊs&@rJ[n{rvwľӫWF߶9p qWU/s+)? G5cD_vUGLXLRu# -㣩OW\r%*m[n~j?|TYxUsNLu *\>1|M   Z AkϮs(Gkc n{>_G%)<<Ϙq@@S Z`^w'ZJꞞOy)Tݑ3}WVoFic݋ˬ}    NB@@@@@@@8 <"       @@@@@@@8S5               Gqħj@@@@@@@@@@@@@@@ O       7       @@@@@@@@ po@@@@@@@8 #>U#       @       q pG|F@@@@@@@=@@@@@@@(@>T       {~       Q}@@@@@@@@@@@@@@8S5  x u6w\9sYݛ1c}嗶k׮DϦaGu֥g5    &=S@@@mVJ[-K,!={؀l߾}v[Csr*wر6|p˖- 4 (`7o6mݻ\rlz^v5kK?(Dm;tVXacƌ[֬N+sA@@@b /0dG@@B`ƍ6{l1bM81QG;v]w[l ZhQw^|y˛7;:u +ߤIK-W\VpawZjO>MСCYR%w}O$    ~̸O?[JF@@L&/if%Jp-W .m۶ZW=_|܌z?.իRW^y5ngڣjGdR5#]ȴaÆDVr{޻wouiP?׳jSO=A_Lj=zpτzo9g498x`Sޯ9hu}:t.\h/b"29G@@@wf0C@@d hokG}ds)OA4|p\R 6.]fΜi=mݺ~_ֺukTm^w\}]s5nzdKYu4˖-.ȯ욽 -_ܽ|:}WK޶ѣGې!CLde5@@m۷,Y6nh rk|@@@@D`mW@@)꯸ R ^q)g7hgK+I%߼ƿu . -=Z:_+h^\9ȿ馛LA'Wo>GJuuVvm,h+5vC\    &`t@@N\?]Kw}nf\V>k??zꩉ| /G_yzj?~ ke۶m#Lnˎ=mGUI'^5j[?}@@@@EMO@@H@5ܲ/(=ƍZ6֬Y6g_rewr \߿F*7߸@Rmڴvڹ_v__pnȠ{x-yF{?2oÆ n =zXJL{jV"@@@,,Y)ډ  TiӦfM41yu˾q /صS3Vz][n:| n}bl85{]K+M0L>~ŋMv:,X}yڕjժe7Zޗ|]sիWn 'tmlР[^ڵrLA>%fƒmINվ2eʸ{\fSY۷w 4_#To*UgϞ:@@@8tO=?şD<G<[X:4S6l8,8M$2hFSF3H  "yfS`Xm۶yמ2nA5H 2ݻgRzUY k@@@@ o4 Z6 >OQ̡iTgJJ˲RR/"   Q@I        'qZ@@@@@@@$@       q pG|F@@@@@@@=@@@@@@@(@>T       {~       Q}@@@@@@@@@@@@@@8S5               Gqħj@@@@@@@@@@@@@@@ O       7   @&8x萭ߵ/&#   @H@@@Xpovis̱UVٞ={lҤIk׮=h#ܕvSmǾjރm=#aM_CK;C/زӆ.Xcv1"E/-ʥ @@@ B  믿nAPӧݻw[.]l>+Q_~T>~1•o>ݻ}6w\[|}WdɒFR]&~WoeuE) -׫X١[!킏ٶc]~^j2L0b:O\`.v!M;k37nf~ݹ75w$U_ E@@@!=   p (n:0a]ve~*?lg}e͚ڵk:_f8p{1˗/+y&$U_<"k_*VM3̛~=.:W^x'~YZK/Q//Q'ɞղU)JWʙQ׊r&+3mjQײebW)b.:T- @@@Hͦ};(@@@ 4qD;3SN9Zwq3%\b?\ʔ)yo۶ رjԨavzi׿jժ6`kݺϟf̘aGvO>n+Viyw}VXaN:vWw}g݌?ܦM\+3{7آE,!!mfn… aÆڵk]} 6 .02/2X~Zg歲WvX#sffٲ jئθLFb?jY;ZQȾlϖ+xgª-'rcbgYYlu0o[vXyHONg!ggί`Oתn[PL۴gˑ݆^~5X}:crC'٢u/f5NMݽom m-'̷YkuΟ+4 fm %[GَixU+jArt/olA0[fvIPT:_ r0`]SdVPsCjguyoܢSu?pf{wZ[)V} oeiYV2   @r'Gg@@@P:G5 |n:n]0A+X`@kfJ> ÓYl  _.G7Q+Ūo޽%×Wz^u̓l5\co/~2k O-A6X^#S`{}6gĿ_O0}_q̬D J/N Iٿ'2-o땂%}Rp\3c%-ӯ7OK :/X^{ f+w`}Zi}W,z(%K f.V ۹A`/_o>vrD@@@H>   p h__~ņ \k/x%;Rܹ]_Oi{=Y>)ȯ=K,閰גZ_gϞifk5>}4C.?N;4+WcЬ7lR`{s߱VD fky H~wR,njenoz'3/8 l#ىJB!O Z^{1f-=tIBbųk-Z= o? <Ǿxo>50@A V В| XU "Pڸ{rf˗5jdROϿֿwۥ^εy׬m۶uT\r[رnf׫W'+RHT}7xi?!CQnf\vh{5Hફr;w{vVBwΟ!0oN{:[#?b6J3T=&}ªAzFBymege5܏Zw~ph{(ε~{-w/؋>[{sӬҰIA:| #r Wp=WPo+(P+U؝qZIkv{?;e?f}^ΠL= D쳟u| fu醖W_|U;7=:ժc9r9"   p$4ў ϋvtQEyt=lay ?\Ұaa1?隄@f3t͌L2%3u" G%yf+\`Q~滖Ow6 gܧ.wOwU?)Kk9oVn .^оPEeёIo fy }-3 |.Z lR*G֟T2Ӳ'k;ԥvZ]   pkԦ}w}Ï:O <u1\(khI{r$@@@d 4B5]#IM{ۧ]  e\Q9؟}َ=T   @Jmf;vHk)~СC6yd[n] 6-!!twߙK(7Zk…h5Onk֬I:2Rsڂ eJ@@ p9   T@{Zha͛7~vܙ={={X߾}mȑ?VZY=lժU7_۾}{ېT}.4/?iıN_|Ǻt/;DݻQ"ozʕ6u,Sq  @|@@@@ }饗D֯_?۸qo޾kҤv1p@;3ܹsې!CQ̙3 *d ,YXʕ]ݹrJUG/U&lٲڝڶ'ɓ'.FmQfF~iEyYǎFS| >S{oPZ?>#Q %@@HGfܧ#.E#   Ve˖u3,SթSǖ,YrX9Cـoƍۗ_~znŊ_`~ݲZ\35֭[[o-[ygÇTnm޽ΥK[R &U^T?4[aѮ<2vm+bjҢEowZ!@+DK| p&Mܳ|Ih&w6?6a„PqӦMsV2P{uR 2GKW˸۝wޙQۤWUuO3lv\O ݌9re5Ye˖?s裏{]=i${]RAJ*W_U]X]vf>ucY6m 7h \PH,5k悹Z]jsժUj>L}hƌnSh+ JLnA|}/{ϕ E@IDAT~O"!w̙3G7xN7:k,7E~wu`;쳝|M|ouj P=ޓi@M"n_}T3 dUy2(3E F!~(0T ""@0B0(NAP&QD1DQFAA}:Unߡ{sίעyRi{@@@z<*   H@A>m]5Gw9ٯWRR s{WbSw:i 7LO@+B|J+QͫXzd"<{ғŔvmWSj:ʾ'>' (98ŭJow8\\GYĿ:+'4=]@ڧy2{U=^u]mfV[ŭr[A}\k];=_ewωt|*ss!ڊscPץqk%lxnVj;@@@`1 q\*   PUXnd'1՝ثʄiDJ֊e2Xy!A^ǒ+)Mӗ 4J0+UE1ݬ߬{QG;:^nUW/٥휕|^y 쨧xnXd_{ ^0nEUR[O1e]ƗK4uzz@4}IA_9;I{Z[+~4>ZczR/J [o?'sU}%>8^t׽(Ttm]:   _s@@@` w/첤t~NѽFw2+QxZDWTIYݑ+i*ךaW\xNj%U]eR6tW^JyrJet:|;SN|֗*t'R2cOGƩrE忋zF5q@@ ?+nn_/W   Ju eʏF]^{TQIg}~/~q:ޕ0ޗN:$'|rRkڎD}w/R[УV[-?Z^sD+c:/|E6>?>?_Wr\ݲhU/{rRY_dMo_zo+,\sM{܂0cW8x:_vm ][WO?w;@OЗj_ϑ$'8i*Nzw/EK1*m>3@@o_@@@`({y3U p=J^ڝN@VRdW"Q~a?~}wks=B\O;tG.c=]w*J xm]:Cs\ϵx:G?|wnUzUnk<W裏/]^Цoοt2J=#Եmyc޼yN'pB~ot]#Kt:mc:wZoFi7穘ci^;T={Ϣ\t~)3}>_Omбns hfm6YR9Sst/^h>{_%TwOh{EB@@@V`ț jsbvL_:ۮuvL_kb~n?ԫ6&$|DŽjM/x]*  -p=;tހ,fzlxLu=R&TW\IASܳm%Q~|'mkcÞ>]UצryJzD~YʹMI9ćy_6gc}:Qwm  s]ozרi{z|J_~ͱw\uv7ʾU4m1<   VA]w8ZjIMaYZm%LzJXm~-vmmﮱk~ysY  C@wS@@@@@@@@`HOfRIOz,N c9&m{7}_<|e/{Yzs.S{\wu)OyB_]%s@@@&)@~,G@@@`L3D묳a/$Ed0Ϲ[ҿ˿;頃J2@Y?7g|=+B:ꨣe];_8CC=>_5OL;s=i:Ϧ{+^>O;#}O_}?= z_Uf|6(*s|}> =qaK7tS:3@ОJȟviz9'tRZs5Ӌ^twzY1uk&n}Ry[ޒu{]x'χF@@侊?e6@@@f@d)*ļ[neRK<@N?cJ~hZ |#Gydҝn r%/~/c*ѻK/r>\<:%|$~&%'? ח+o9'}tW&=b^_.[s2^_$ qxVZa~xF??p}{t<7뮻nַ@rW{%`V_ a]볟s}{yh_KsߦV[mw%'󞗾կjM/K4]'li޼yy}ס1#tL:'.?Cۿͦ~M}>E Ec~ vq Oܶώ',~O{Wn}>    0_`rO/   2,_ U1WBYEI$헾tYgO#ug$kx[Ľ9jm%Utn:ͮ;򻜿$ߵ/ =o*mVttK;%%s<]p1my]i}9/X~y+1/N=Y]){'N=_{H|pN?3=1@wM|>@@ e7kB@@@`1wGKJ{ĺVbWwi馢G+yo=? =#yJwqMgGw1ߛ׹ՊX0QzTyJ_mo?>?u@w(Yߜ?3O9K+]wg?ˏ9TqTָǢ/hLO7PX~0E82mw{6\rI:}⢋.?;6g\>;lS}sD.|7RIp](~@_lK_Гb Kw_*OgG?-Ϗ Z5>vZ"E(@@@~8>   ĨZ ~J~x׿v}0*zvmW_['[oy:4_~tG~^/'ul]8vag}=z_j?}םz$R+!dzk?}icwogu(qGx =`O~ST@ի^orn>.~%4jl-LykƍdMF5rsiq~bA/5X#i@?{ϑt.' ?}v9䐤߶?5g~ CCz}a;s9cF@@f:|mNڎKr۵^S樭e;ڱXgz?զ 0|GjM/Ϲgۥr  ]$z#"0GtgJwM|J7#oGǹe[w;1_59t}ܻGנRu}ӹ5u<=I@Y{}!y>;z瞛vm y{> _$R#  [v{ߏ=QKSž˶c7oQ@@@z"&l2/kC@@ 7>g8;yA&u N{       4 4xE50ʅ Hx|       ,3=q?7!,b{|wY#ΚsD@@@@@@&~gr~A @@@@@@@E`\ s}W,:wr0B[oMՓ$8]1͋nĄ(%㎴W\1'޴FeYfF+'       8Za{My?z]55GȆL@Lگ*/T}@@@@@@M9সm,^cyqӝBք8A`ZHO+?G@@@@@M|򌽢oCa=>W NA`<-\ҝw_i?[E@@@@@@`b7ǵ=Mx5͍kK$kfSg?;oLJϛ7/u][n9! ^O{ozfp8xQ*<(//7hGy$顇h@@@fsue;] s5%&n ,rP[IOZ}$C3J`WLna]{lWU]w\  .}o|#=-oyKZmc4~ӟeY&,ko.(mFiWzn}9g>3mok%;|ɭg?w~   07Ͽ]ͩ[dEu}?x+i,IG*ڳI`V;-cOy?H@fe][lE?JFp J?яC u.w7<}X<YЫ]'tRz;6mdc˕W^>k9'|=@O[[cVHeA}SOM$I1  J֜pkʾbq~qEqǽ.d-ÝjCcϵgO~8xVM_}Zc5ItM@@`8'x"'3E~&묳NNw⊜,nIw+fm^/~1?v_K_NV~_Ώ~򓟜^׎'Lw}iczֳg>o|闿ez^s=7ukZveC`լFE}-zw+-w1y]<]|_wnHzy>8F:ꨤ/Z&u<}I@U^ϻn\?|Saz K/{ ]v%鳯[*:?xG8|2wyu|+@@@u9x1XmǺ֣أX֓(.:&~? L TsV]u#B>^xa?[?񏹭wx`z{ޓ?;W_}u<vatᇧv)wqnKJ{g>O}7[Wi}9yN;GgqF$$ZhL_"й#InmEmkЗH|~}+_Iu;3]s5Iס/& @A@@]sG|pscۋZ7+7@'z?(h˻M#0]Joo~K@@.;u|S닓Jl(鮻_1Rqw y=&\F% gDZk5{rbQ骫ID}tӟ|WoqZb%O(K~d}CO~6]%ϊQַ5/},n)JZd~^_S>Oϛ:qw$V>[}{T>w2 떇~yo%k\*-r9'Rl&:%wGO Jkf(yk~B(v!kй[_X~˩@@@f@\;=}K]90WPcPk+q Ixl{^ ,֛H ?_ތO~/rO# W]ɵDk9F[Jh?%,uǽ;u.=m9!Ǜkzzqo~󛓾 @Y<=ia^q.jUW}}\UB\w֫(!+&=*?cs9''?яN~חf9q߼׹)cG|HKjȝ{oe!@@@,ˉ{nwx~qS4%˱؏m]K{Ǿ8vN9Gwg 08I3@@` Fz]zy{Q'pBl.J1[q1qzkN뷹(q%Oug+Ǚ+qS2_w;a)a;[SK7gO0(ʻOS}elsݱn?;cnn.)?!6Qi}qEh=o{bx/|5ͩ6F @@@`f wyg]:wvNDc^8/16x|w\u97 ^Կq_^Dُ6穭qz\½W\qŗz;8 {HC333p嗧?.OA@X4J$#4T2Nm=B 6J뷳*zDw[Z;V_QyJOo\/&%cHU_稻C=4?r\VXa }NO-xo_yޗ?]R{ +믿~:蠃࠻ӵ^J7ݥc_:2ϯC^j )qG'`կG{uF   nt{wcűoz}=>M_}e:9X/珴tW|xZEs\b[y{5      ,~ʓrHu~2' sB./1ԏ/W_oXW$:)~)Bbc.ho        0 Kk%vjU뗉Z1~iO!q׎\|u..kZySׅ|c;)vu\ .(D|{\⹫_Xm9e[X      tP1]k~ʵzu~|ymSLvsV?=s'C"q4uZڧW6X,7L^}v\V_EzU\ű؟58m@@@@@@@c*sXKSŶcqN[͍ksk✦vwӼ(h;akOoט_NpVǽiNs_>8Jꫨc;*rM!:sq}q1e*XnB0KAk}Ļʶcu.zic}~>gw\kSsw;{^=/h#      oRqU=ZZ?˶mľeey.XH7NpE{^vZo{Xe^sS^s%c;)]#      PKb[kݯ1vKVZ<kXOmS+MIņM'@{v 1WT uR6']:b:~xnJ/o*q9@@@@@@@`96r^mcvW1ִ4+9xŵx@p-\^۵Z[{_qnӛ⤾j{._^W{SǯcKvS+G@@@@@@/hŶƾqǚ1kU;m޲\<'V\%֞،6̘(. kUXS_qN{b*Ǿ8_x5Jy}ceNO@@@@@@RۮwUyc=򨎻1Uu_[X[E-]tLǃ\vv2!w{t_Jv^WR]&c^q1֛2aN쫭c?k8N@@@@@@VyԸVk/2 ~<^xXoWWv       0sqm[,벭~SL2vyTט׵:vlRuĽZK.z`Z˶bcik\ŵzw\1͏֘PsZc*^;[gS|Vy:       0wMʸmuS/ۮkmQC18mמ3lw.{mc^۴qרvјd=X1kbqNֻv[˘P#      ]?ͭXv99Ѻ]q,ck}cnj776a :ttr$umi닊k+zN9z#zv}m8n -4c=S)cǩ@@@@@@@Q jܳZsVs<Ř۵|ט1jsA6P| h~@uYk1U4%@xL֏ <ʗXVkLE{sǹ@@@@@@@@G-˘muSw<ֵdƛqml~mb.nǧĽ.k9΍m]aBs2>8:=b,kmT7f.3[      ^-59v99Mud}ھQXl9 skcL$qI:j况EoTLΗ%uLm1VW~c]WE@@@@@@[ksbv,eWlנI{>Vx=}I%=\w\Zr)cK{ǘ]8Gmxc-E @@@@@@@[޵}Ԛk]I=h뢌cUw;х:q %ous[ԜAJ-qWwVXV_%s,Rj       XγC-ccmW0mRN4zlt 2֨:ٶDsm-@2.}⫌k/1Une㮽/bLs| ^cy͚gf(=@@@@@@@`x~U\iǸ۪cŘ4<:kĘ*1Ϗ}#M˚3ה.8ފw)^uqM9x֘ceo)ޥcu@@@@@@X|֖دsVM}1V=O}ϋm\{]c][3xۃ&ڠc@'^K6b1+yc?)czXõx:F@@@@@@JyXZݎuv9O1wk]j15Žn$T%u1Z;9Z^^Yܚ1:MW[%,g9 "       .\hRiǸ۵)jOk*]g<M}jjuqb*&ƾ^kW_Vkz ks<˽q       q[_WbA8l}befm56q=xlw54WB IDATciŸ*o7g-c{qm@@@@@@@`PA͵en9ݥ7_S,˶.>˜ںEye1׺s*>_x@@@@@@@`j%ke,=^ֺ2ֵ_[cjx-rr?q}jX[cuqn^fŚzM[ݴ_@@@@@@@aM:7X쏢Av9V+R.gy ,"S(gӼZdhZ_M1]Q#      I_6^].my6ŚzM9STdϦxkDZLv9VZ)YC @@@@@@NAӵ]b؏m9~SW7+KMcxu_ѥm,O9să66%691AS \@@@@@@$~6eXٯi)Rcld?T'ݿm~X-%V#AmZQ֋X       0WMxw]7y5ǨTl&$'{d`?7#,S      sT`ԃw̭]_۳sl&%'{.ìfMĝm@@@@@@@`6 L6=aDɮ{ ݞiQda߄8:@@@@@@ӑ1'(^gjxT5ԛb@@@@@@@` *A>[1N(l46{ro@@@@@@IJ׮i*=k>Pl6$j߁&#       LUb}?4fSzQ8d/"      sE`Q$1&~Dttso0       (08椈g{2z6l8I}X      s^`6$g9V?(s)` 3gwϹ{=%&rD!~9 YlЃ fC׿_%@L8bv §@e"q4W"(B D'p霰/GY,QOHN@|*[ 8|y,[jq_|'diY s>ͭ%I eH=xaΏX</i\$ /1E}4^tڸ(i 4.0^1L@(R! +A!P4 %@H6AP1TUA/"t B`2k†{pNS,8Q߀><(J2GQ^`T *%BGJQըzT uՇE}FcT4 mvFlt*z=]>nDc Fcq00QL&S\tc1X2Fckؽl+ ;p83 .¥p{pGqpwqOx^o|)<.~?A#a5pBM$LFDb1XF'^&>!#H$GM*#']%>Ȧd/2|J~H~GP )JerI*c!Ðli+Z k !B6KTmQ9Kn\^qy|||k 8CBK TUEeS7QR/SF DccJ JJJJJQʆ d"=_iǝu^>pUUTUT}TTw6>UC-QPۧvYmT]QY~BaFMqM-M?MKZZZZ%ZFڮ| /iJ4Z2NבTtL6>#Jկd@0 vt|4424ld8lb023zbL1v3N56o5$5c ڙL+Loff|f]1 W5'{י[([YX4Y^ f [Y&[|l``cbԚm]a}߆bk捭-v;"vmvE#tE:^Hqtx񳓽S ?͝8/4Z]xpဋ ˥ʥϕk˭;ǽ}#kOKOiϏ^N^ZQ~ޝ> >>>|u}||cw24lF-c,!`]@{ 904\o^_ՠPpK/='O?ep4t~#Ըqu&L[s_-~=tVl9sEsO^Ⱥ0*lpqmeKQ/ix+:<:.\uzӵ3כnhiw-[;;o;nxkanw/w>]==z=<~ͣG`?{ZLYo&5<ſ}AyQ:=T;l=|vw˥/_ _M!GkקtXћɷTzom9CʇT?L%DWײo&Z~229)dXӭ p|<o@zҙ>yZLo?M?L/=-{"SD6V#,23stSx/RҚNNCC z'''&' >L>%[HS+kӲhiTXtXML:com.adobe.xmp 2030 1104 =6@IDATx|UEƟ$$;z"(MDDXQWWEum[uՕ֎]Q,MzZ(!=;mInh>ޙy?b3s                                                                                              \ȓ;Ks#ӳݒ 1gAGdΆ%$@$@$@$@$@$@$@$@$@$@$@$@$@$P=P=ӿ{8h"             Nw)^J|8XZ             (- a:[iiDim`L$@$@$@$@$@$@$@$@$@$@$@$@$@Kh\5s06@$@$@$@$@$@$@$@$@$@$@$@$@$@`Z;A; 5`$mnq>;V#            0 K/ YfhôU\K:/N;ַ4 J*~qbṤc(J*Ԣ@8*~`HHHHHHHHHHHHH$p[z:%̀mg[ .I n;1O$@$@$@$@$@$@$@$@$@$@$@$@$@ ߁ 'nlgSt.n߁ `WK$@$@$@$@$@$@$@$@$@$@$@$@$@h{@TD%"@)iL @Qo%-WtLSS;δ\U^2W}co4 *n˧eW]_[WΤ\Ư]* #d_۾게HHHHHHHHHHHHH*Vͮl|R6=)LWyfW)/WQڢ/ @0im*Vf\2Sj[ڇ?o'__v;pou>Mf _JS|mo>E{d#nrgzť- }_<yQhE`g`m >Rח@P=)*3>>ӥ-}_9}Lv8ڴ'_{[&gL$@$@$@$@$@$@$@$@$@$@$@$@$@*@ko~l2yf3=2g\_g]Ҷ/_OeNOI)Pkoˤ3IHHHHHHHHHHHHH\!`ϓݗMrM/>-ev:z͗\vz;mUO|ʺӡk]{}{Z͗){Ǘ?HHHHHHHHHHHHHH X|ھUS?'[>ɐO;B~QD6Ԧٖ([pXKC0.J|=ٝ6_yS}DTTTSРArssk880K$@$@$@$@$@$@$@$@$@$@$@$@$@$p 9211ÇzR¹=,fe2gp,/RE96y;m^DJg~Zj7IHHHHHHHHHHHHH!z/2,]o{]=X'b4b6yL+͞J1L>Ёys}e6y{s=ΜF              s[󍐁^l׆Mnwɫ{{.@<׶Y)ۚ6pW^f;:p}ѰHHHHHHHHHHHHHH&|eFwj:~cvyʫM=%ܗdκLc{Z9m:Z@$@$@$@$@$@$@$@$@$@$@$@$@$@$ppka2r#$7klњ=V u Ct 6_ySfbIcOBHHHHHHHHHHHHHH!:'-n3esx˫ݴc|Łyo=0 c:,o6{G $@$@$@$@$@$@$@$@$@$@$@$@$@$@'Xgi ؞6eNUV=Ŧt; W]SfbI;}J2Gֵ8vVXa0I$L۷Glll0d[$@$@$@$@$@$@$@$@$@$@$@$p!TΕɪ={h$uQR>AiiS1m0.!4\}A5J 8 l:pݤ}ŞS,0T}P^=DDD,`H [.v {|D#L>ZO|rn{Yi}0+c;"EȏBW|2^W[}WbF!&s˕;jpGPV'&&[nx玝yL }tH!I=,!\z?&:qڢHE<pB 7km>OCm\ 6i-oV+}J{#ڗy½S&DM"=B9y JyHCرc>ݵ*U^iֳ'v: ,DDd`ŴiSҫaÆ?H k.ZvkPW;Ö-[aTA n/~& @dfZ yjtasN5ddf!E4=b")M}UW!Z@HDIϞF<1>״nLlL@i½Ƽ=䝱Unfow[㫧 b9*e&?^iommm*r%eꣾ{}=~>?M:Q]}K*j6mH}7'}Xٲv]](s+#}A7W;D>ZGjyIBey05ƙ8K2VS7)شn/j5Gef(W\QW>!!KkPǎƍ~*UTZݰ]           R! _-ND!VIaLǥѢC#kU%O=`\4 [@K],6ڔ7OkgtjJSxmO/[C,Yt6|(3B|%y;i*?Ʈ*-4f(q06=iMX]Vן>}iiiȕ Ş"ysbMȒ-stjPi&_xe6bT x}…6ˎiqSqf+IзqA*WuGT8 S|&t ӽ5@Z+̵hQrex}JEzsΒ6$@$@$@$@$@$@$@$@$@$@$@g@x;1Y8.ڝn?wx S=S{K[%݉M3KD/L>B͏k&VG_%OO=w :)m>W ܹ6ʓ: [{=3֗1dԛ8^\L`cfMĦ+{^^S{y{{SfҚ7i0y_˓E&=۾B2X$>>:wY,\x `"Fv)PQ8q.G&4٦WH"֗Su̙nQ>gZ^_ Qp,%]ˠa#Ѱz4Mh/6W$l^`4i:׿^/MؔMv3>˚m-ALpori7qۨi2[vue J{./kv u|ȕf!WƦWmײKWA+K9"ĠK3v,֩K/ )aq%(/G~[4s\<4** Gc$˾n'֊ w1k㿸&C271TۖOâw؇VAkܐ; ܳ|xOx\Wga=Q]r~C]eΞ6+H)y$/̚5 ~a46-LuhapvZ*Wݰ}           `e4]*8v.D C,!@7iXb mkme:]eEwWroq/ڄ*!V MD灷1~"7ѵI4jz߬bω (G367i)V3,lALkfҞj+G 8dk}nDJq ꣾBvHIV;vm[G}^}Ez.{٥֏kckK]&;齸X8vjo_NE ďqcѲU+ԨQ]V᪫Go<nYt^YSkp[!E,\ ^qjmGt$׵1{SXGiʹy/ O< |o<; z+>C-ǟU7ðۜB:\u5v|؃?$>M9/tG8Sz5޸w(Վ53:m~@Ŋw $@$@$@$@$@$@$@$@$@$@$@ګ_$x0-:2e"0Zed܍߆WӬfe3N[u#*8~yX*ղl?wCr!X5ퟸv+HUeT/b F6ػwnO}<멾W[ג)0qڛ6ۃ)tl 5l}܎0y/;"[?^E{Q_!:2F`/Q-i-FK[e]d{|]@|ZUWM@(i%\#UVJ{G}vލ ",,C/0cc|&~"\,#~٫guQ픋=R+CE0S." D|2 ZPF1~l<1i5r:b,}NJ2Jo {2z֚ߩ2]ȕwi,4.c ZkRMMP{5Uk,!͛7~Jo,lHHHHHHHHHHH;PdzTkɃ7S5QdpUCEN,k=nC[ף~԰uR6qE(uW=};X]oÚO-k7Ƹ>F0X{i9Ղ M{ O,9f₭RΓ6מW56gluڝypݬrn/FUپͪϺk}@܊-&-@Qtlq;w@7O5]-+k|N{_WWwf߿4͙E xW\ò%K1e(e*2J|H XV|BD޽9~W(x$n9SęSGDGǪ18ݟ7Η6M@|:RL##.AYc,R65Ay@&SiG cվLtjzāR=ـB$`_秫5e}3/M>qqqV/_5kj S8qxx8bbb~H8c           &ap\=n6rvե4 Öo])>4kLF,-/?o}k1fHHdޏgs^kǩ\DTDT@e|t:N17>Ʀy6zkY8`g%|rݞ6uf>lWګuv~d'(AWZ`5Z`gЭU4 /ﺲ?|( ͛#X2Fr+eW_f-c͖6⽩rq*Ry|_4=7vG3&xӮfre+nj]'~knc_:Ex7>/\ym(',nw><:FTn[`r{S4v؝OMe&m۷oo,w8pVz K?LS̚; O8=zXrFzuQb%]:ء~{o};?G 2н"ܭ'-o1Z9*?ҴȀfq77 Jɴ,D㞆婲?~;Yu+{]}_\]~Քf_lHHHHHHHHHHH F],$;u nӴvk0vǾ2;i*t`xg}19kߢL }QC2$Brш٫0_6,ރ5V!"2z/!9,aXfe|0ԩDg@;h>*{׵!7,v}q>5ת3*|K;T;++ Ǐ/> E#6$P:}3vԼ7=1xiL &VInM3>S&Xpa軲+~}۷#Rʶ.+[kd+!!muÐ+1f!ba[)"kVglJL@QVZ51+V75]AǠ(~JslHHHHHHHHHHH#`v_7N@L=-'m&u}7͠}SfҞb&-gM,K!UL_cˑ}WvQΝ;W_ɓwGD[9d=eU%#ai hnݺB.^~}TT)֊+ׯ_]議 N@/.ln*ߤvgZ>RT=vMж_eAܮ9wڌ)3&&,Mi*gffKpcy-EiY\r4$           oIc#;y{ڵMc3i5}& ؀X)oRSS-4h౜F s^-^QQQy3$@$@$@$@$@$@$@$@$@$@$@$ppj:c3i挵\]s[ &`b6Lv_{ڔc-gB@W6n^ϿU}O'%}ϼ^z-3 N@__ڰNYnɛ5<[:@:vvЭpI ^z ϝ;2|7I$@$@$@$@$@$@$@$@$@$@$@ Ifv7[kn5__f66{iOy9L=ִ!'NVb              @ .O|c)oXuLb*`3yOLk}AE^Zކ=moO`N3M$@$@$@$@$@$@$@$@$@$@$@$@$@$p=i{pކ=ʋ+h$I;'gϛ3![ã 9J3֡=iOvOmV½sR=mcLv=obc              8 x҄63Kc5rg~&js_b,&66hqa>H=D"7#!            @HHѴiSTTš\fl1BѕMv͔4{@'-mY=ӥL 996l@.]PHHHHHHHHHHHHHF@Ȫxbh+W.Z/Mؔمxo6=oi]c6AKc@]vghޛ͔ش زe%Ƃ.HHHHHHHHHHHH.H fuksXcLZnJ5po&_ԁcڳ̓^nҌLnq8             &__QPhajƞtcc3-_)NmC/Р#Si{j763!eWڟ!HHHHHHHHHHHH'ڛjp taaa;m 﫭Be-Ї>Qv5o;c              ] {sklQ[X{+6567}JncHHHHHHHHHHHHH(ӧO[+WT=z(:TUZj\r{~~l) 4m f{_ $O>2{ړڌc/vxww_)JŤ$˽jժ(St6Ey-X6ljժ8QQQ/ȑ#2|SRR?bٲeHLL4h:u€P;t"            سg֬Y֭:uM6EiXڧ.]~#kۺ p[vBBB^mׂ5mT7Zߞ[v guyYgވ*l׬Yӧo 333qax|r|HOO/0l~/Ƕm۰rʠ sG}}cǎG_~~7tz]`|2R79jұc}ᕫu.[)sl,^@ּ)$n;ur<j+r]tu 6aM8"4ZxZ,Z(.BΧd~e~ۏ 7.:(<f% /_9SXdw-|KGuH݆_80_ e#uqˀ61r6>,Ѩ۬Tr@˾ƌ#qI:!dȱ@ڵc2:VÍ:Y?܃)h{SOf/3{??RH=MpJ.U8&aH^V_%`5_4YSQ[5BGc;adU@Qy`DJX9ԨR@ɩ;iAdj8z>kHJB+VC| k4 "|ӳ iec;E@?5PC169*è\1ZԫZx̟?덏U/曨_>z!k {_G a|=@q8!Xvf<7#z+L874hْ漃} '/$S澥xb@O6,:{7Ojm\}mg[ No,,z.t~7c]]{_B{lڪʮQ?/>/'oŌ-;Ыm3c" O믭3X3vB=4,۠Z?bdj"),[ٙ}gm6WDKn A-&Kd 9*w Eh~04):ςs~.q}ע펬~ ynE`x3H,?>_k.(qr>~u"e/Guec7brN30|h[?}#>z p;V#--!/ 4kwսuxL\}O{=\z|a$DO b֑,nᝮC\53ҔfV\ N.{l{W˧uc1Ν&hC3MF/3v`m%sWʿ5dZG&\PoU ?|?vA<ʐ rN~?АkYGy6ѹ y/f{E\;z I?@x=4巰F2ajKM׃u۲y˽'݉Ąթ뺊.}kXWx裏4߼y3;fdBwVq>&&Lv\+ kZf>μ]T+(㏫-{^}L3ǞJ]Fh@'+iS''SgI7[B4{0btСUm񓓓se@Wګhs5y7Z'ZB=xߢE &-}5.HWT,zf)gS$økvD/aaLs70X4,{'c[p7L,j䥀_y3-#uz.aPѾaעFX6| Z^s3޾ <%5yp%ڷ~;{dDɘ=0m`:_%ڿx7\T9qp{R^H=C@ vEլL K*Tb=q%rBMB\"Bxr=[6 o%{=n`h41]X)PquDJv:,}H%]ul#&=3~ ]ףs`7MENQcHHtpi%oah:6mYq i#\@IDAT?ZkXV ^|>e{Q7?:#᳧_ q,WcؚQ V@x1gK4Yj1~*&OM￴)vT36{di޵j'`,<+~}ED!Xͷ";U݀U!]PzMkJEo5F~bp=[s3&c"2E|?bE_j_֦/"KqjFebѯ30kg[ KecqJƙOdc=˖IHȖʕwyqB^|h!+li;\a2}εau+_١(nvj?3BAANA?Y2m,;tw0W{zJh8uQXgA^C^.|W绿k8m%wq 4žE'Kj}J!y`') LY~l 0dFͪ"N|̞2Cz5#bwcRsn/ !y,;BݱKD ~eSmA`㋷3O$@$@$@$@$@$@ .0uڶnw7fϞmf1ϖpKoҤIFF7"tB ] :jUStiW+RlN'lμWZv6ζhoR uS7;KCOnm+;vUG2eEQa< 6}EB<8<鏘Q<(JzzD͵Q/"=ӹ.o:+* ̀ǧηD{5܀kwDLhah1t8]h_TC{J?JsBWaE=EP&6#GK=(˽hYJLl\-&"{.qo qTemeՕWW0~SWcƪx.ii<{Ҹjh p}Y6v-_*֡>lp&cl Nt,pʸ' ⪻-sooZ2sb`XbMd)YW5{5 q5}QU^.oa*kZ3^[ -ZՊSe2̒Q#QwL5߄~Ɪc+/ffVXl\~h[=B syKTw rW;O/L4:_y=(w9gE=e]9ڠCر%ۅ6mukk2:r )_bVByD|s^/B+k0v;} ݷS]1Ԓ߅{"V~{woŵ"4o"N&fb( {nѽs{g.O\V"H.5K1i%͜8\1LY(P?|}M[]R0u\Cś0kZN7m{Cu $?yփ/ò`={!}ώ$qҺ֯)%/UhߩP>`ңܟܖU KdltnxW\7 VEҏL1 ի+}A5lݺK.}1kzk@i]eێcķۂݿ2ؤܙֺvߙW?hZ%n٘L:>hol~VӺ=Ӿ²eˬWffЕΠ>;vof,|d{iOvq/AU2YUV|kLL—ECi?^:8}Z~S&=~ 9 /"FNUmj_B$x0?u4|YB+x_Rv?_qsdE'%F}.?#=(E{M 4i7M)h~x'pKφ.؇I9pII>m"t/ȮC:Ŏ3p;H~͒K~^#eđBv>\&n-fOdкm0] l=?*װh}zxr@0mu\1+y1C9U}?dU+pǒб{]d܁MY5eQڏ>`˼z#nq,B7hsqۄ9 e_'/^'VCps6#@e}ُSo3^D"2q I0CoܥZO|2STyVNáSǰ/U .jpψ+&ŀi;ekZ")IG"TYUc<forwQ1cj*@O,ž.lcf<.$LtQhi8qz ъ+B. /<+-lٳ&TO hKxy"VE/ELk u"ĎQs`DZx|HKdg 7ӏZmّxuoޙu )"/w/jo'Uro=/O^EM\o?foJGI;{t^SQ~lZ˿B$W/K⨵C^A];偝֪7h%r*)'~U+i`/[w1>.wq]!ɿYQ N?^yIHHHHHH k^-5o<~{(#x߶^Qm׸qcn Lb/V} ؽ{wfu~ @tt_ 4{5RxH6ficb- ~b_J{_@ކyӆr7~wy=}YujժŃ_gCRR{kּz^}|m8M~J+ڵ;OnР%ma.ѾDEd}Mw1clǣuOwkqBl=Kd b"O'o){~G.Қ'ቶ=V3>P0mk]}ǬbmUa X|ͫN[anVjgO,`Vobky x\ss5еt_.A|HXvH]]YuPԮVhˊZ}@Ք;g,fZ [~xW/?}r6oVdGǬGvF*g Y}˫] -ԋ?dw>qrbN>}\eq[J^QH&}i8Vp_s_3RTKDlЯ$bsesder0s%xu/81k6}wq/l,n$Ik̍e;eW 7 Œ&`wggc"_M݌^4a1,!_X;kdFY nC:f/,h~-PqܿXW*oc f5>{_q຿|]!u='/7R[ֶ=8~xk"}mdbJ1\+y%&g:c >Ų*d+7^cݓN,0㓟 * V,+}z66ya7^T}?uuݬ[={"t*X$$e=ʞ8j{"E(s[Ow=z7[+3wkh/q]^3"+zԺ .q-ZC3~5X^} G\*=ge78!½oʭTU~#+AV [q&r߱kܕid<~-B|6;+e'侥? dxo~~ΏJ 绽=Oה1pJB~GjF~ 2_,ޯw|=ok'7YvՓB s)F (󃜃rκ%nA0E$@$@$@$@$@$@%"׬YcѵkWkhg7"Nynj_~ ؃>$￷vVN+W.6OKs-t5ھuU!_}U˦[i|m1lFW6>Eц>]OzfoS;m(vX 0p˝q[ZCZ.2|tnmxVkwM}$˹~;8hs5MsOl"ګSEMǝ =zY){0wEc4]|CF9}Su.^zVykOG~_"fu뭃ѬU>~>'.t{ߵͿҊz ])4cmɫ/ضƳlUf-Bx ˣz#c]X`}]x-z{Y{͕N~+d6 X m=n{\QxB7=^|;xa\e=9ywt=excľcླE3'dW9||}o|!}n}eb'zuW{OBE%/R)؇6m߼+TF)qQmSϼ]jvSX羯~}#>!4͠]:_|B<փ1u2lc ^ES$@=ufha&ժU._җ?mذO~OAN|}g<1w{S}!ίWBѶ(+G:)9)] !o@}ӟ6랞v[$tP 9m'Ot\y&M" >|؅(Z=F]t@ƽ}>&ig~vU'lΙvk/_[֝gOc߲aF9o]]9W9j{I_|7@X~e_kBqQmYj+ Ogw@qv0% Vy xșv[GVUSY|1~oeE{[m-VyɢA~;wEJ})ƶ# r[9{UQB[f=SQm]9lͩk(=meU~_t\Jv…S!eכQ9{?܃1Lh[L)\?`)U9M{YT/yExNEM9iUK>9C/'/[:(37O<무3a1-񕷏,!~hY}xgKx9QtFb喾ɿszRyb6o}ˎtfont!>9?iE;{Ҿ񃽖E`n'mިZj6"d,SY^i69ݫc1Psy{3TޭP\`.{گE]0<;a#{BQcvҥ̷}!,~mF]Ԟ5Ue4=m~ysgAmwډ7G='l:,Y19`ӲYWvm_o{^8Q3?=0R*p4w߼Ӳ{5Szxqvo;7]׭)oFbSN}Ծ^^}vKu,s@F==EX1h#]򯯐#ґ#-L0B转n<^w;fOG\y?P")"ٴ|rbGm۶m/ڵkz'Nu;OҷϾo܌聴{9gzJKڿe~̞8qTjP~GԪG 4{h5֫Exﵧquxʄ ZZ*j<27qv[w ϳ ֠rkj歰#?y^;_ŕ?8Nlv^Pz[ޜrG}3ηV%oU;ܴ k`N0 ۼv5 *߀8g"XkiB{бgB9scfg}*jnaz `XSj襽qUǭ6h,(vAc+cm2]_o?yۯ,wAi???KՔ77ۦCoAmz0ò-_Cl{sz5GzÎb,l Uޠz]SN(蛣ao ?>9x$zCayedðXx;(~3ߵj/"Tv/!T~nfEWaIerXg87peT NPհ|;qzAC(/d h-Z2mZS΋v7Ȓ{%lv>ۿ KG<)?zvxx-\u7 K+yJ#$Jw{d7]ۿ9igښ]m,#WKԮOo \{ֳp2}G[>F+bޅҞK9C2\l6=th+0yo^}a[}}~ uh\zw/kBTU#3(ܧX NzEUiwKS+ |j,μ՞8X3g)%Qr6}5Tڃ xz7Ƀe+ {_wa o=ϟM; 2N0#2=x:++,Kl-C;r:fjw]qhϔ_1~?^{OÒ n ۸)>}1~xɾw;f- 01j[XsZtхP Du \m=1v<\ng{ɘ]{魣"h|Ե7V\8c88[+" " " " " " Kk3׾5Dtf}q4i>G~2;ŋ6/\}2&{5S+rPEo {ToC~kˇʔnn]7akNkgvz;^\o:/~ck~?n?ʖdc߾ŷ5yٗ]bۧWa ӟeGǖZ 㟘j7qI?N/w~ov';sob]i`Ts*8c;yܾ@]};֣V9+r6 W{Kmo^}'ͯZ8@gփ{gnru 0/E6۞qkƞbۼp\K{o;H@ީX{xa3>&6=ez}_9 zti/"+l5PZnBXe\fȳ-0xjJi+ڒ= M_uWx z~yRteToq}rp*okk!䩆w)Vy \{KmF.{Q*Y}6w6փ7Jۼq[:h(aҜE63e+[m[G.c\ a(/ ŭ4Py~h\ag*co?oC1hP]#Ißn.:͊jmnZ0ZUtw}]Y~?mK[Y`=[? 3z /Nɝngwlz>y:KRns9[S7syFg{N?*n"tiG ف6WKO̢de2S "tcY^d?Zoy\j33Os="+\n4;2}~+%3n{.0>Ϩ~69ΙNzֶ;{$=߿sI=i8. Gtϸo`|f[7~~߯xDBqBq]5b+pDVЎM\]Wۃ8jgӞIJߝ._o[W[ckͽ"\.~\(X]}ϮYշo/69vf\MOZ+_Z{λGtk~ i}dSm[ɒSֽW4횖{졍ANiN}B(b;l}>! irM]`+h{@hܨ 7\>C/Cw}X=yWAXYg]5=za_=÷G~lǹ]YkX?6>r&(fX>n{*/Ϸ=yzwei߁H .ҿ'/+opf v϶fx^UW>_g®_c{D=e:n1?2[܆-X;Xv*'-FkCl3wُSϼjy՝K\yM=?c#DY{h}k;c*MSy觃)s}dXw4g=1^b4UPgjrC}v;}N :f^am[e:a;3Xrv}3cr㟣/e>c7]r/e2 lnן= Q. ǺcgHm^~vRy`=;<Sþzd7~Ž~{c=l v}JZ74#;h+l-מo|~{n?ص} ٧^/lSٹŶWw*i>nxx>W)ϰ%_^ d->l=wztm$cviM +mQEh/i56ݸ_?W.v?or!&|ArŸ#>J歴+.n_+cV˂EOZ^ck<=3*}X55?¸1^p\1O޳Y>s^_ˉ+>ws(",wSwv}BemG0u/]ǷZ^zGGp/s1%qwSD@D@D@D@D@D@=/2u] m4X=CS9?xO=Q 0q ˔DO~O&2 w\12?̗ H7 mv3~~F:ƿ-wo??//7?~r"}'Y3Dk IeIǏﳦ`G,x%?G~3z0 ng׻Os{=h ?PkU-ցPYNu%Zg"]NBYBhe=܊==pwN9X/CV %ʭ(xtN/^trߺ}N~ʹS:acϼ3}{I{i}eAEs_GO/4>c+] l^Asx vm-[?îK,] L}ĮסlﭵUքf-|M.pHd. Sb3X҅>P)#qN;i\ktM.~y7\˞C㟩-/e?ӥp7}ooo~z??nO&%y%{xRg<;yPÙb?\$PN|xLرcnsEEEco$=h~OAt't Gqmnt[6~z^^o~zѾ{^}RSO~&dIƧ0~ˌZ]vٗ vyy+*Gm#l /H'}}e-XmsJKg@j aV~)?)ae8[chE@D@D@D@D@D@D@D@D@D@D@D@D`ǚ>QKQm51ޜ9sW_u{yޏ= ڪW^E %G5&W{$WXkrWY1 ي+lѡ1OzٲeVZZ%.cUqo^x}>q[nKL >BzWJ<7cD@D@D@D@D@D@D@D@D@D@D@D@D@y@IDATD`w:񨸟mS-" " " " " " " " " " " " " "0 Hq?kMe7Vƾ}ܯ" " " " " " " " " " " " " " "0ƽ玏$_][D@D@D@D@D@D@D@D@D@D@D@D@D@D@$PNZYq6蔻0:q*ͳ( /2kK)_qL@$*ʥk3/ƿiےILt9T⢼>y-+[?D@D@D@D@D@D@D@D@D@D@D@D@D@D@D ^RKwΆ/ }~K@%;G%v~ySyq$" " " " " " " " " " " " " " I> hVk ]v&s0ssלn6з׫*K큃wh$H@{Oe"VT}϶[jv$N@}>NܩnfN]k{.ɷm_xopۻf'" " " " " " " " " " " " " " X6˲gO?X<=tT;K-ܿn o@mT칫OsKnw6K{Og96$WoKC;C߇KZY1"5$P" " " " " " " " " " " " " " CC@h\ r)Ŷx) (W ~ ߪm޲Y5&dg?5uaDOg-/LO0C9D@D@D@D@D@D@D@D@D@D@D@D@D@D@F?)mD<kS>a/ >x.;Ų-Wj߬c׬OyCD@D@D@D@D@D@D@D@D@D@D@D@D@D`~uOlDɟE!3ݖO]doؒtHP퀥KoRڳ`W̜dw<ҫ+[%3&h% }R#57o8vfS mGOL{3򲇣8@5 k؇v~4|Xh(M|]Vi?լ1"" " " " " " " " " " " " " "0jHq?@Uv_޸׮"dgý'yXc~RS۷ًVڦ% vnE\db6R%uE@D@D@D@D@D@D@D@D@D@D@D@D@D@ (n\XnBoWeZPaQ;X`ִ:+}dÃ_W}_Ҭ,{Dhl{>Z:ЦfE;`c [ẞ#" " " " " " " " " " " " " "RRR+C`ORh1pʟc 9"" " " " " " " " " " " " " " P|P"ֲO;5|SR_" " " " " " " " " " " " " " I> I9 F6Cz΁C;AD@D@D@D@D@D@D@D@D@D@D@D@D@D@D RځCކVmﴯm9`}~W8u$F@?%NNں> ~pPZw?/-"03L# ;,36UYmGQnJseJO18=Veu=fm^ASgOh5ao׵Ys2)Q|vرY :)JPÑ:mg}iquleI*>L8ikZ  Q/yY m)赪VOo,ܓYLąry֮ne X yxݱ;bk_ireH\3lk}5F@~Fo2LNz 3&77fy9~]]_uvw[^b@#m eX;o*s5m,;fgXYNgہHsrҭ'ttv)AWE`&gOuxcOo W%<D9Qf;BsXpz{7j"9lEeY.꞉c*EvcێI`;^q'gK2m o% 7LXvT :H3N1!3;xCva.yA4j::tze,Ͷb|ܛ򠃘c`\C%gy(?= '1k܋s9rWJ`,Ln0STԍ8ST e#" "@Ene'яJ Ov[%19$ !"4RSrTa0 =PiO 4oj8f~L-hP=dPYm'ۓs n [1{*Ĥ#=JQӎ)\t$ %x`^%0oަ>0!B n͵mmVY*Tbu0ը'NAƦÉ"j>'q`ޝᔹ> ydi(SJ>؏D* = C<# = *m3R]fg\`;$-== sF;;*ǰ?"|UOnG; %~AY6FB4{WI`p8V$'DEL"cif*x3qnKKqNsT%{;0`8cTegZƤNkF>4ʦT-VM]]n_) tמ604H|QyJ;P hCM?<86KuPB1e@r@]:4y{:\?̾RjVӖyje{>Ǩ.g@~8ì6|*G`+u_FPD`BR@kY%c^"E$'[0G EB&Ý(XŀxSB e ělyM+ȃ=Sh,la('1⧯H'Rod`_T3AyVA9P]™F\+'h I'dT\\H׉Az XSi%;ϣE;m C JMa)F?R{Сf. }J{u;|T7A\;/,¸bU} 4ZPBhT坬OqOѝcDќTc9rH/xzZƓ8o|ʣH@U9n es*#t@20=J9T}8])G}A6vc"[ywGQJ@舍Jз1Jb`(gǽ]a=v5;;DAɂ7_Cnl4q1 GL?2?" +\7-c8KF3}!iҞy΀W3VTBgqJXQ~!n 7 CEHbTL|8rfk xV.CTz\P)OSDk`=1Zd1?ľ34cC_ \<8QF=[^!8J6y<ȮQPZ$.DKj\s 9z0QƯ=Bksڷqyr4;:^0Gg (e'Rv?F!_uKAOΔm(`z6"PN@FKUm+ΰ= v 4y."0~ {=\\Jug" 㑀a0Ip 1t9%*A.=7Z7P֟Dl1'(>Wo7;T U"N>1|2q9;/,?'YTxbk!&O;]āP^>~r]i*q1*9qˆy2N"YDh Q_k'%zmdwYt3%Qhp4|`rVADUF&)C˲ފ팊c0P |4P G4Yë6מh8ۅ܇~b4^\S}F%GJ(ji$Jo=z^sdÍ0SeƪGFJD,;mF*RbT)"m" '~N74OF xsƾʁ}A,Q9=dD"b=ec?:(;`NU{AaKj&D\Z9^tQxR'q?J+FH*cM%p$Z3w4[Z20g8n)M'aTLCSQh'6[lOsBDxz[=3e^cZY'cB]צf/xwY`TRM(QUޓ!\fkjd{9^{\@ID`bpou" czQfHԉzp&<9^{Bz4sD+,jxUn+!rCS BT&*_55˱`J๘Вw[9aeuBX4PB`.*F6es6WAhNtv\m$ DyJ!==SNJ^* JRQ;pk{<\%kypzq%qɱ%ǎ a;)w9\4XxS 7O}F{0'Yҕ \f*fX}MW^;m96FqOKgx^(KBn#"4]9.?bY;)á F3/B=΁&ZO]CD` {=JY? KWH-ڎN{y=cTVRaDS,p#yS4 d-FS]Tǵ09҆\mPg$!K+ۡZ@wcm2N)Ʉ CtsK 3?Oǭs]P28,R6<OEb|,qoV(+U!<;lǃj%(.owVpCh+*O hqW%ÞXȴ_D@,pWRpGQ]a)~eA%:yJm:䵸< 8^gm\K1`)q[:5i&j+O|( xem[JLr9No#)"02`3K$+Xp(=pH&ckHCC6~$cykmK] =="9_7~1qMhQB)`v&݃ʢQپE΄'*|l/un|(血wC9)D펂*(\p9|d xNBY?jaqF<)9'4`IiZ!!@Cݲ{?#M&Yh50JwQSFyL[:obt;OI{Jd- &ܺ//⦣/DT:FǟF *NJb8l!T?x5 Nť;^Kyn<;3ZU_*#)t[ϕ' 4@9CJ$Z 02ȟ)j.|xb8F EƵ@f{ hg72ax1!X"oS$̉g$cxc}R$ZkqR1L:"4`vi}ڜw_8:D6j=2מ >uaBqmw*—rR~o 𰍳eϺBj="OBYQV xguLN}C4EEBSƒҬL~>L j僊F=蓮<=c<9 M?/9OL2"$j!m%{&~<(ټit9g }(y1{WuJ['>]w z+)2 _3|ZAo\#!략[ ܌ 8 ?{7r\"[Wѷ>u%5yC٭#H=Y:gƾϽK!'@E =pIDdΙl, VS fזPD@F7h^*I'*aS&=PN"Qrѷ9 f\њgۖ67c'𾟑Iܷq pTL8c_4 9(bG}lh>:N#9GFzl3BtxF~, QWOI'gNx\0a&rՄF()/+Dw9KaIhGy%r:VD`dzd{L_ gpyg348fs=PpC9ROCM]P"LJ+1Pz;m!AyhCZ4/ {Aa@Y=Q)Czx?U: ETU4'<^bZB~bFJpT/pʗUPhx]:)/o9Km1>,bM{B}Pn D;Ɣy!:EAQ`Fne/(vJ}FKz{a LU{ 4cOM}0aPR O%~zw.cA C0a)_ QC9+`J ?F&lk|+/Ѩ9>#nRJR(e0Fy|nh8<+s#I#)hhOXe0)jyI # Wozn4a{(D@F>PNyzzyOc!{.ZdG8' A^AE3 FtJR ^P;WeyΩ`I}MdWvzbYQ/i*4~lQpf(h1k|I@ꥰЖ.]j]t͟?:;;m֭SOݻ aD@D`ӻ1p"/*8@vDMNaU e=y.%N xQ((t)|G;{x(6T'2=vbOo$^jNZbdsAѰ!,¹@}R},x]|uFǴ&[ sg*e0o Q?&L()B4F(."V( \9.™r@ʕD ec+Ø(t2@ȫXh||ގ!EiHquQQZ)|M۰aeff̙3sαl۶mQi `[٪I ='~.QyğE0P}jYxzyx,bg^ZR8Չxs=RJ3/YR@E9PfF;9c>14}qhʲmsu&vNhl/ѯۙ'pɃr$˞gkFcZiA~PcL,NgCYOkp2MFy<#wD׀g[Cߎ큱SI;1J`KEmvHpz;^LGĈ0R?(\⻐uz{m%)|UO LZ[w@ҬzWI7_%jXEQG8&y͍ 9N?G .D4Sj!x{I|pYly%qn(] t/H?sƾ ē8^hk&[5mѠ R>/Fܨu8PfAE1'e 1q:4P c'c<)eF99]A1@IRAOf6fe%TRwNwS8 )P,sxkU.Rw  xR9k'G @ìh~a0틖SsAґ1Lƌ,WZ>cT^1$߲<Ȉ͗=hU?8S\A5CEJ 9 Kk4CN&6|&p٧5JCG@(lΝk=X;! ^m!@.>xא tcA3Okw$GVu}2ƒh* (egz/LAxG>Vu{Y9/{'SُC-Q{E.B@vt&'@س\'JMA Q.…t6xmw+Ѻ+pO71el,Dw*]ik=ϧf{D{'N(PU 6K iVƷΩ:>> 0m!qdXփ0 9؂6 je2 'as)Prn&L^m Z`ªenjbq $؂m8 do: i#frd^!+׮g;olNn"g0V,|M,MB{2:^`bNaנg1?" "0 p\~ (OKiq,Eaqb@IC#o%9pL6TYa2TjTlCD 1-tfK4żs(8V̗ }z`zΫ\87O]blϽlv/."0:LGvë=1?ssyn1~=Fn>c\bfh6/*+]lwFͨ`E"g TXFXT=3ʤL3yڗwGo۶f͚<Lxd@!uꩧځRzx*}mm1?JWjep_M@ugex:CRKiT2{& w(kIhn(bt 9H` !, J$N8o^^%RFʞ {D mcdfУ"; נ51aA&'3cWeߋ0lPQ ȇaR z=A;PߕROS\o\a\뾦@K丁#s.g7CPRj gE0oFaXE{5/L2ox4cMJ~a=9~"k%PAVw8J"Na˫Eɾm\1iC7!Ɯ;p;ʱ<5Mȭ<c]ܘK\'/=PbM1*@!xgqO=Kp&(b@|eΰKǮڇfi&_J" ct8wC<۔1{9N2םLVؿT{ uń2H+0eJJ/>K'㢭{V㨼/k HqO>i{-]va:~})O2VJOVJ\/Ra>܎p .GoMNqpl807C!,/\#8hT2݀ њ A|1Thz4(0]30dԀ7q ' D7``~[Ο8'0Ft}9I9|M=f7=x R( gr!4hr!Wb˦I: != z@4  (KFKhǶDL~JqxیצH)@/8ô?#Jc+vTql93Ad 6\O񶇱vn}˗OE✄}Շyڑ{T\Qy 7WE_ Y %|8DTngqLZHo:mĺ_*QF`yoKky#0rJ $45G>^Z'}nwﶬ,lٲeiOԩSꫯVSSclzPy^pK"Z&bn%F*腯$#E׫[Y0Oh^^VBl9Fy1h>0C=UKC+6q YD:E/RD АT8sN  f3'9^B7^>ԣҗ>10-rc~t.VnF<&v L&:׬1A-NDqFcB F"dhxLѐAfyd|ǚ?2" eLЋt!*Q.ԋ(~s=)8܉DTFo R7pNY:{ǿ;/  7`<;vۣ6=ta߿?_JJJ_"0/آ LxN[YBᮞcb2˨'@ϺL+Ҿ?P k+=2[eC&ѓFkEIHY=P|7IAD APqN#_>+ቑ#D;$,ˁжުis^spg|{d 0_ӶBvxC4b|}>'/ò:aӻ"HD8 C7:mҐ7'1̇<:RB0`R}^۟h.9FHUX\1hvFc^&ɦG}sTގ56I:OD O0 }Q F!!͉7RYR^!^Iݱ[`"j#z8eEpUu`y ^:r-0H(4bgޛFwA2"8d29_fIғ%Ye\%,Jkս0]^x+oh!7 HUʶ=13ˑI2gF!//#13<_f0"n{9=wpUnNzXt8⬁,SL? ?oçt:m&ܿzo]' kjw׮];vG?}DefO 0QM\8@ zC+28rc`ș#P]Jʨ(N9'(%&p ":U;v+T4+"r?XXm +!#搌̵اS]ݵ7x3|aĘxM\[WD/1,Qs>yaqb6\R\z\=OwR"Sess!*C# eKifE5 ܗLl)4Qom^M7cNi ㊴9`W70|CB%Fdi!ҋyu 5W\Gw ޜO9M:bJ&Gn!(xxٟYV߻`e_kƜ`i ,:-lyøWlTFYBy }EAFοdAM,^aCTS6;DTT WeHh㍌JJMJ&<Κn@rQ 6ٛ%0w*>iU>\NY#߰ h7e{&g +XWNrvѶ#b+Sr@Ar>{=lk}sK*ȥ{#Ḧ́·QuR4]ZqQQAlEq>5[s]cG9ښ M{DkL7#Aq6|IǓ@#q}Wm4G8x?X}W{i}d 5A(-ZAp#VIEg BICcA-l8(hz bf6H{CL\nd8 D֐p_1rvv?o߾]BIջ/ ǫW-a dYs^rHB h1ni,)\D.q=]$ \N]x'iode"Pv fߴ+ʠs80 qGXt DF#|:\w*s['">JI2mD5OE" %fOsc{ϥl$w}@ +{C㚨p"rlρ# b2Q%u;e3(c||~% u>zeآۣ('p:X}{ċDp))$ݜzl_c,S3Z}x}"}s"p[:9gYC8/@V/KDԶH!{ĘrK~cYӜ9_y?JUflUt8@Z'uR_W!$Շ#/EMc5B11H)8ʠG1nĒb!@*y*ܶOeO+x99И ҞT̍w4qS}s}qmV#Z 13Kx5[Bp.qٱQQoVh=\V_?S 9T.¢8gܢumA)w[8aGXxh1,{\|!RKZVUش8j|Dyh4 T8VNlP(QޠhhF˹9᥄#%/"w) _*2O,́-vuPAp7l3&(E! Kb+&#^7rࢴ۷>8c98i^(%deOp#ܾiy"Ae6!uм^8SwzurrгҤz׵bWW'}(5c]簞dZu J%zB7Esܒ"C $zY.sPHȇyKI Rs&#ߘ4J:4ٌDꅒrV(P=1kXF74ma%)ei 4*E11wMIT B`C;)@b}D{эђ0B(^/u/!|hhilH(@hx"rMh "nir_3巬>K@}.k0E+O֛k!?'tR ~4Y1u5J旕vK묓ok냣-8?-s` YyO-k/Hk c`yϞw s"-!W_cySm*D,1YWpeXym! *N|%YV.qfWc/ D?V 8w*ɼu. A ".t/bj?ĸQ3ֆpvJ 2!wqN8 kb"y dM3rR-ɲ^9p9@ (:/d_dߚqp2dmFozt=7F|?_ߺPtH`TDّS ́k'g熈 T- ]DbG9B-}G1HU]|si1L- b(E1d ?5b,1mkqt9Ўq19QBDo8Y͢9CFG=(q$S0oQ*w]sD%B;;GGlbow59Hυ^BO%M䩳ЦGO ́WzD-%$ 55Z690E|'ZmCPZcJ54dKZHjjzx(уxGq9zgRY!d璷uCps$.wmem;\Õ|'zV>Zx3픁6hYp Qt~9;؟=:\W@B;kc|=֪) KI NQ'%&ᄃuI>] sp&>'d~꒱RuƁZ͉ul_ suP}~.38ǓE@QT͗.]2ϟ?Mtrh/j,lNEAقQnL3R<%uޣʫ[] )逝qXޝjw5Gi[W۴H,c^.=a [Bi8+)+9 cv( P’(q GLP4B t*0ۋ\RcE!1y_ R+Q(|0 dW0:e{-}/VG)`w#=aP_e=F(oGdGaKt>P\I[Ɨ|ij'Xu:̣!mV#oo(C:FkPR P$Jr w"Tup󺌁3Γ@8|s @ G9,C *ҡi0?,wPZ(kD @D*C:79aG34x-%ސ㐿8v_{ E]/9_z3{A_ϽVg/Czv\"9%-}B AJ 8Cp0jѐrcȮH+KVe mP<$=.n@g5W%Ӿ'R8g<N|yTp_&6BD\vZ:ӓQm(LZ&HqiheE\h&#*t!c{"rSs@9 5?0|Ha`{]zg{eQ|M0>T=eQ&_%4Ւ Qc\o8? @ ?"8v*ʮ^M"+2|~qDFiD`B*gSƔ&# ʐu˾z0!~ui|@kvFTtWP5Q~Z-EHo5 ]UQYXc3225 xc~@M!qIt=B`p=0ֽPYSY@4?}k2hwY7h̓@9\0-kc@¡:aPX/#i:|d*RKF#|m 2޵pMeiZO=*ݮ}'8iڒ8hL!\ :(]Dv  MF'/Z 7)"T_>1]fѧ^oϒs5HrJݐSf#й$Xz5}+f;*ܬG`>[†[2!"yK(e\gaz;\-VSv_rjц릌`A|lDb&{OtYF`YYpAĒ8 e_,(LӾ2뚠1K!ca=&!h "miK! |ׯ~N\ze)0ZH]p#W-"AaR 2oEF9ۥ%z(O"(|k-\ d'I? zs~PA;TT9*Z= ރvk)$ywgR{(ﱶVos}!Hɛ)<Y07ρGl1oevnBr!nh׺Cb\W #3!-ƼvS{Fqze!/ͧ[c20`ssj`~>|Ghku)>1tzʽ}\1] k0*ցK`C%nsPC!GeLA ZRBOe=㗱] ̼ l~at"Ik5ڐ4e0sTSg! uauY]޴r% ~Y4"2Fz/D[` ~XI(dtͥA 4z,:7w(FsA4 /dFҡ<,r>sJŭPI 'zp8{A&/(Qˏ׌3@o3G,](k]7O)1%z/ iHJf(D|{Ǧ&79JC)xQ3djZ W雺iCpPبv< ii3u:\|iۺ#e)+Pt'l*9 zV^LS6wAgA;Hh!{fņvP}s? YrX\6B"Aʷz6:Q|&-ka9ʘZИbp$=st7s1w]J< aNvycryWOi{ JG!3bo\mz'ؗYCma# ɩm,#d |lQp=,^HʶI-)NӢ/8B/a}G18Ϭs[<hOrŽ2;=ec廯'Vv_ksS5bYrx>EH7F}yD|\ 4Yg}E}3?wꙿn 8-HW*U;r(#iEV6v^'~R ^0*T8֐ >U "21ߥT)qMϜw"0Ry!K/Kr|aIfs<⟭EzVyE gJ rB08555aI&jz@}uuk(Dg'6%6Uq<9 ^1:jOh5Fx#V|HF 0BN! %8y`P ǍfѬ³!hDl㰐2zQwpVg1><at^T83i+0#G Y3ݪ"NЬ8ͤۋu,H|F2:1 erxRiѾݜ2946iwǬX7c4k]G&Ye.by5\;[7 8s;+ {֙;\cw.hb#Luf=5Ƥ\/Dj;4dCI'#HRF:1O =Dlh>RyFۊXa=`^zcyt#IXNFwNK8z(ϡ]p9H@CEY1eD]߬<)G[ cʫ"E=YwZz„3@|B懏_(}^7},C ȅrCɉ#O:iYQ.gmca_װ\GWv23vdYg^0c`L=䐘[;4nY?xX5xAY|CJP[$e,tEZWYֶqi9C-GAlZ컐n e}rîɁI Im67 ~ F! J,O)a ρ4~}qֻ5'e![g;ךq^#蕃WhݙKxE GgwBp@`.9cJNM+x`jo%/CV% |0GAFZ~g7o_?uy&ErIPOʢ+AnWNxˇoac۔g=0PчPa$b|cpf `Qlr){#þ6@a RC$z!!zu[RYKXBa{1U (C 8|CC hx(z)$Fכ{L[ޥ PzN: =Y0ܖ<3u߆L)U>l4Xh`y+'?;AJ-2IBHLs+N9!<0|U9-MZ|Ҡ'q&aA:H5OcpJs@YyX^o@YQ$@}pu^ }P߷U/%쏐$C0YGce2W 5&ׯ ln ۆLr0aZ6Ӥyh}jp>}@Tʜ q UWuA-:HHƥ[薡zEйlZx! fլ sN:&]BHQ꽒AasLuDۀI9 t%/ssss9 lӐt8o/4ϗMa6V? l-;YgD1'L4 DY-> q80IZs O"o(#3"_c}4GrA r^ovm^ 9~Zl%{`j F vm;e6rTEhZFr,}esBua}vXQ2ҿEjം /W"ʟOfɷƎU&a 0S%FP;~%+M9:.%<3VYm!/UTZ7l^h@>Bq7KHg,jyo+u-@'a@E $w0~i9K.V`̧!,#&v7wr[k)g/JSyQ߀f0g&a iOD]Ge^^貂'?Ӛ&0!I??q2DB.Ҙ($ט>_[ϽІ?|{s3n!y4 oryF,$7z*~,x I\&סpyG2*c=5.q}9g CDo DJ@(t Fԟwb2||.)(!rwZ*"$A |b(ʚg1V=мƱۚ pA&℈y!5O:0px%m;ƀ YwxGZsϓ9㦔;J̹<\0_X?ƵNO%%R<+X6^ "MVD'ρ8c2e+Y5Lz`ٓÛtN/Iu\N= ]bBca]ww :P"v<N8I^ps]ގ3^?8o9^j'c=#=|0D6d~H7D(v!/uιžer Z5/ˡU 'C7I`#b &c%v$eF}"Q+fKVE!aA@qTE: bzo% e濓z%k1mo5Gad`ܷδ7ӘŒP.O\׶> g J+/2s|E󑳣'MURw̏m{Z\Fm@y {r%,8stMv7CeYuH?B, +DX%0iꚏ4<jU9b1Z'1mMF `ШM[bYRBHylYX2ZY!H0XkM>$aF_ l#aRH\ /)GaͭVIA !"W~6:U26q3VY$)N0䨦DȁK}v mw!is/4"_/pM⬡A۶rY&S# DBovcsh2c]CŹb}We@Nn'P=KGB }?V``QPǽqLdB:X)8OӑA_(UB!R&Ex3xEYkC&1s&COjM=\&c Dʬ:#a\rE& YJ>,Tab~t Y]ԓ@60_ */uT Jy\d%F=$F`>,іD,Vgr]euSQV >9 AzH#yU6H|4i? E}B9,% Bѿ+ ;sBr5x;LY"}vXN?~EoTD&4W俸_a}ׄsssssqiXA%pǦ&3/$Od*]8DXׅd %vSҏ?N; C0z!r_!ܳv=Ru{ uN[9oH~' &s0Sr2lgfCFM𠇈ؼ,!+^%>+0Ӆ6ф5Mݔk89cC+![!LԂM$) [}{@"Y@'ǽ#6DɃ9dEg\ jDDآ~|H:yiHq̀#}z%zQժTb?k-z+HSd)NakӠ9TnϪ?Dg٠c(ҢӞyƓ@i BA6yWoZ9*k { 3qBcd}1U.Qw^Ȑѵ*#Ҹ& D*{!ʓ@aϋsO}nw@QaexlW#)f|%nnږ+hZrcTM8vP_pݔ]{G{xxxxԊHڥ:F|Rkf '+7ȝ=2h=3 ;^;ptpl-NMK>4JJV+*)(ң"#Y0LA,Ty՚B2lS v2u7ܗC_B 9Y(0V hI%A+&zN·czc`2FClY10p}x 0a8Cτ f8rF< 1S.FLUI"D*۶^lE^yvqVD۬p>3eE\΍g#UwlM/9n7E{Lh|RSL '*C^:Mjbtu$Nd%eVls;=8<%aP&| >&Q%|yC#0_ꏛϖ3fB8x&) #VCvQ>{(}f bTtm!L<D΋g2k_|@G}au sa;tUr9md=ٜ\<ɳ,'R\ <_s'K22 R͇ZU"#&cFKX6cip\W=59ccɓ|l7o}(aeA-t<A߂#i뼇8dtt [tX.umlmQpo gbd# jk ǽߑ)Yj피,D:fb FHUC3 Jy!o;Z LJ+˿{xxxx+Џ@D׈yuxTqKF5sCx N #(RkJנJI1CV 9ǒVfF|$_ZD< "by*t:E=K7ܗ7q=$Ov2G\ bl2݄ ]2$ c|B@PI.Y4B"ټ'%$@ArY6WxwVAD[&"'!CyCQ@:qǿ wx6JT<9=s15rZf)I!U~zeG Ft%qWyAWtA "T||%7\ʭ BFk=p >g(w[p A+z=?F=dw[ _L??\Kg,j0x!=FC7cmA*6?(íX?G".ޥqի>.j,5ӏVPqep\UuO1v>d&CUs%"鴆dnќ"wNΖZ܍a '~<ڍ Y-mE· ѧXRErF,⒖"2]P״^G:6#E<9RU)ʗAk4b+>iXD@0)$8E=EqMR(7h~tʊ.WN>zF߭Puc"EzR0C ]by!`4v=g򎠭=+E=qFYK~a#'2mfCqQETQ\)>t1ס^O#598r$L+'0q`*“3G.~)O9D8 GЗVs\k`,hO'JK 0UhB :pBtzbWpG-VXrmpw(t(W+6Z|ֈryKAHf=]񤣿3䵙~0m/Ek1s}huٴ Q4??7ecn _W&qyuŧ/t`f{u<_$'2F(@aVGH^\@~ޮHPP<(/T !`ң&(b\-dY*0*R*3)}h_3j>]+NvQ4b`#JnwqbMṑN:"h@=/KpyΝ._֌yTyQ~"&Zz1>9)Xp3:g?֘CO hl@8JjqH2 IBFejg l(7OZ!/B,CQ*+ Hͦ䀹bچ>wol*TE9%>^51Z0E P:\bkPp>Ry챦'8z$O#@:=A`Oiڦ|?K1>wZ4VEE(_|=chuFNBg/ Z#۶VUkl7;jkLe8 VȒ,դBtkʫЕŅZWD-r$`MBwJթLpy8w1_Wg0?}g?47͛7x?4wMOBSELG?2S9Hot18욠rXPeS(F^׵0Q##ڐ&99R&u?M F< tLwJs? > Nt0tb?AG"P^ZFDj,@xx"Hxs pP$bPuPX/F?HfrFK okɿ=6eOMz3c˽f/l{4ь|4mtҚTgS{fż~H^4Ip2d_Hw+r@-q!$(qjׅKլUEg3$(lK!&d }.OZ'NT`Z10yU sw3ez∃RG * g6Օ`U,ZםXc8QQi]i:4.ޕYϑR,cQƒH.?E$;_#`'v͋?ʽJZ)=_1|ңņM%l9eqrɴi!uCho@m8_N1uSLZ2CZ,Vn+}3ހٜ4k*1>f++(OMྒQnbС--POF&.~O}~m:*nBiǑFe)DzU,RTͿߗd"أydiRQ4R]NcE^ȭ|'s֔Ҟ3QE@/11sssss9gMNRXs H>/gOA`2` ]#LTc]sã17đ<~ܜO~rY|Y^^6++ +MWWeܶSQGŶsq2f-(D>ւgk䨢dgy "ؘla:&iŇzP{Ae?O}I= 'GcR r<W7xk)e]M6M9`8 WN1΄l}y˴CYV?0͍g??^+FȺ$2e#8qCJ̄B^-__*w&(KajwÚ_3YEAGh|{DjU(r bV90`kso )_U jE1pPP(S& [P]S&Wph@\&(*8cQǙ\WlT )ZqjbjBo9#NX%>iEc Jh^:ṕdFŔE=c7xc}=!Hj=FwgT"Uv)c588B6߽bsG>#=9JS)ڗ$9XQC}?5ۿ]йgqʭ׫MeD(2\u=ۊ(! @ iŽ*6ѵnɹK *m*r݉2‹X=~d67L{OiU+ׇ]-3bެI}5Xfr_i#_L>cn}햢WG?WOfMa{a&W%+m[cRK'U†q? #fnn`[zEì53"_P7KCZ[q"pwVGr+baQC \.`jRz|R}$~@kv.ijܖ2h=T, (g];汌Dj1ȽJDD;ҹڼ!kx"^H!4,k-N<Zu|[sp!'΂D3>^ ܂| z "߾3KB՜IhaؖOV9_ ybR@!%!C鼔?[6FQէºz/єή{#JLș3L񃅴M#T>G`'RG%3UG| QpWrՒTJwpzrݔrqFeOǁJ׾kDt}__ߡQ>e4DC{?]cPOKZhlBLX%j3T<"M{e+7e4s̒}_w~i3xuмMi72ww*"Y{EJz'fyf?OuE/+gii3f 3|gekRf}M#YGwNqGO`07wK i-s.jnR=߭rt }V."*!:kK=ğF_Sd4χ!%mYG Q* #5i%Z5(~)'>9\y٬DQ%"ZN:P! 􇵨'LϛnL O& X^x@Osy \;] Vn92jBϞy"g7O^BrƬ>[\mf٘4B'j9m,WJg޼C҃e>[0io>notVđݓ\8a'7{1+ J(>@WY}\‘;_i \ӦP#U#ȣܧ3Ea^i{#qAIm5͈ t.آ9"@{_g]B )wr^ϓ@sz {K_-a8~OQڋ?z K5 7YنTjp,n'Uxu *>Q1qR k-=fP` n{ 6C)!C r,~"19 \4cE~'2˂CȈ"dEخe(oE c DN ?;$DUHAGQR ;u(V}|!=TZwߌ+'=}s-6 >-׮.ӡvzK;c2tʋ;a[G7קMul):%mo.W[R25)ҽ4L8p9@¨ ˍσsS&e^J*!E8 6#:3>qWD ~c<ƻ"@мN=$ڤKܳV!&19ܕ%ݧ2h;pr^>Hŵ$[M ?%G=*xrf;k'G̋ Rρ9mS+>9u^59y 9 22 JJTNΐA~Yy*#~8,WMs[ʴ fcj4{B1vZty컈/V y}diEy(]列JӷX#2X<'CP"*zhi I@NȊ 6c^eoX%ɖ1OkF*#tW8jJSed.h (8BDT}xviH5 о}aՌ8\ORU!bm7b0dzktyŢF˩ww$eMRRf-q^ '?È{ ?7'rqmC$F X{ \nmڸyvjO%zQ@ơưLs։AٶW[0"Yҳp(gc^n{z :b8N`ķ=)04 zLiP,Dy\衘?ੵsB jKi)dnH7GiEdަ,B۪ )8)dhFBھ%QN-^V[bgX@*zf1i .|^̶2SR6a݊x/b.+0ΣW Q񴕨h—2#D%'֔l~ieu+>Y:tT zRc-hK<> S2y}Pxn+rO r =%|uω=K P 3m'rzmΰG5L?_|5 k'B!w)()#cZꑬot F_SjNK7PƖ7h& =6NK'ι];&x{K\vMg-[۷o;~ c/qow QF1ѡ s^l`Dz(l1vi'P@clJ6BhQvz26(q6I1/F/BA#!GQ:FQͦK yq/@!ӫ#I90a9j@ / 牑Lc:J!rcGosqDE(CP נ((\vJ%Wl" 2pBW} Q8s/x} [^hTuTjb,;Hevj\ß%|a=Ç∨a={s{&iB,xg55[(1N03FGMZ#8/^E;( N&krh?3?NS[ 88>G< Pb(8Ƙ+}<]04?ifX&VK8bBD=r*jNQ?̤|!5 YR{tu-}xPZv[s[2H\y1P\-R#J- dl *Uڔ^9Q$߅z׊@P?u U⩰!{/♜#֧ҋv|m7-/2Kngd}t;ȅcmMJ5MlT&kE8;,> ۓV yDY !k/#BJ+4بxK>wkoq gO/8^é?|)U[l7<<<<<jāuYAн+[nBkўG#gBEF}f!%< ʓ6ϦUN4}`|qyrs4+IG9]ND7A%6TQoj3˭@&l !B C(oR@D;Lq$a%elrP$9迡kzu+Vw3i<Ȑ;(zGꂀ6.$ 爺g"B lZ &| qRb2 9}!%ZؐM}ݩ3"PLz$C1k=;7;m cG(PQ7 1,*2lhV$K~a\@Bq'1rBƘV3ϛ $}OU WciʸQpFᄄB^OD?5!CSQ:,ZkxT_hdlϑjծ)1 D8O*wp,'Vm }>bz\$vUr{rj[(M=~!À֪5})kZXiR !8Gf;XK]9T^}9a%F1ݣYiO76ѿ~/ٚݒ!?i=9%ˬQbC%L2#gn^ p$= 76\18c)ջ1רKz-ץf?91|:pvκ7PLi' J{50?-h'ρ &p{,Dv>^?JX1PE7{kk]AX鞌?]I[g +'ex"P[z`x̕3 "1@R5Oʓ]lAf/w։z܋ Ė)inj 8H޵4ZٳXr kۼBѦDf.EEXyAiD[vV;u,M rq(P=ܗwOJ</I]YPl^!~'BTĞkb湜:p<" w=+sώ' o"ҕiu&*%u5cP<{T8 U'L((SC=s9 T1ZNnT3l">{`ۄ3ѐ#d+b*r fcRW;Md`sQL6l1匙iLJ~pF<g ĉG/: YWf#2[5O @D*R8z IHo+N+ !G19b(O()7 `Xg8fܡkЭZ H}gEȹn]w4\P,x_N= #!eT_9999y Ł *]Ґ'Y$wAV*XL=ՔkkZƆYXX8ښbK[[[3({gsxDs6D,Rak8FEy%6@tE^2lkX 8BtJ$'ޛq,[ (0VA|$(tQnK#B }X(")FQะ, ކ^aeY6f&D }z+ȵtSJ;ژ0Oa8E?4r.h#54.ƈ7 IHl  =8PPsa%eמvEK}>E< 9J\}D]W=W֔^ӯJ!oiӓQ^\_%RlgsrɃnc_qؘc*KZm9R:_-B9|͘łGbjϗ9Ј`e=8V xِp=rmqGr'8?4{%xSDٯ<]Uu}-DK~HȤhP2kb긯m_9Y BH[U-ڀ7.PJG:x"r $/ S4,?cs'mQw@]WHzO rN1wSRsq}5@II׃9>ȽWJ%1} iC.o5 %._o2?Kɩ cξJ=s_@vܖމerʻ)Bl1oo}xtzz_?#yx__̏cLJ@~c#Xϩ@9ZFU&p{9"7} (hENJB@zU C%ѧd~׻ўR2%@՟x b0{*3tY587:+V}^ڳfzw)oxE_i sB8!>flP3rA=4XEn-RK e_OρYO}T>Z7~NJߦZH$]L&w~{\~˫]hxzxCKKA.u$-@ȭR(dEtw@zW%9S:i(b4?b<'{)Qhb{K{O\EgC,mD65™+*fDsSke)mA x&'I

    ;n!]zS?2}ziˎܟbקW5]W7ףܬ |oƋq?wۼóOm{o!?zSVz /{=}(yd "0`׾_?n+]V`nrܱn*\l xPiZ `1ޟ'~|Fg_uak~e t8Ц>ڄCs0<:O`ぇY}aA;\CPu|H;ƛ}c_jۡcb\I?סs9<11NLyDa: I?qO?́xe_Mr-p2?(.1 SPQnzo~1S-jaayѭ5mϾ%ǷpƖqJ>n]l_^=cr0yȾ Ny̑|-Tzt:-f{Xuc[]r] hC!!EǾMdc?f@o~缱y9=G>BN bg06]X8˸OV9+Ю cHј̵|&.s*A!V+٘MʕfF.;'Ҵ>(F'\+{6ITA+,)!Q%ҙrLi )zS[zC?|L2HkCU剕\T y+/91,h:ڏ1NclH>`!aEdA0_k&2uU]9)*MwbnGu%yOIbt3eZ?/b]?fү^Uߝ13,ejK38]+CAm4mW[eءBV]W:E[a*V(SQX_x˶M6CG󍦙y! o䛧ķa~ M?4U8 WacV&fs㐷+ pOx(RynG;ܠxnN9rsd~ ho@5ĕǍ!;ci;9m<7같նo-N/=rQW|2Cm.>t]~LSuec㹨bh?oE"n! 8is˂nHoq3_>u#e=n,=;؟d;Hea/qK_;O;>rm' awߙ?f[o<(ϷB>gضcGNx ׾ũ/')sj9V >Eê6qjqq>^8pr!]̧p<5)9ކY'up AƵ()E i>iSpp||ҐnfQs]J#~Ês(%ag+ ~K~Ȃp18pFԛClHz]GqDq|g,+8xh/-VjB\B]8;2p1Wϋ.0b~| hhxq~)ɹ[}{8;KV<)gby.+oӲ/g^|K"s/sjϞ=xpflo%hUz s6xG*W')|Z q=+<9)U7϶~ p^@8jcc9N96< +g>󙥝z2/ۜ8n7Gyd9_ 㓹ӗyCMjsȨOQ6yuL 8ƓCr>/+1k|;c8tA+p.`Np S<&;8׭89wa6Kp϶6Ρد\_W_}uq3VOySb{9|ݒ߆ Y*Rk=sc]F@ G%mfqn薼q=-6gl\CbVnCRq'rcʥTe۴T{O.*l[ON ՙ3T7]!SEK^Š{%ِM,ǴڒUBgi{39b ('?(vIee]4v\ʶb2ڈr弿gQM8ȥaVdq%k٘'RwO~ۧZmʚ*J0$Gw,ښ,ev`CІ˴5uT;K_]ZҁW=eҫ&c}^) &uhJ}WoX51ct M-nmZps?:YVp`.ntfi/7ry{^}s!F?P>VȸJ~p1|].;{_l1|_v_rYNxhJ?6A>߽S3MͯϨi'8&p_e%/| o9!sLfW|L_8wy0~^> αm8#LC,1#'&*F+g?I*9=8c!>7q ӊ}ٳgOq~袃HL1p6=NE %\gLިyg=kF5[8pc7q`cqzq{\a#rp'ÁN_< %C NY5)(#<0C'7WX𠄜ХaUn(<Țo+Ӑ7/8R[` l0x؀Xvdpċ1qÑ'{՚S lحC69^o44Ѽ~0s9-RIX`z9i+3v:yu|:&b84-fCr.93qΠ6|١1۪8?9m+}!p9?O.YHΡVd< E<)soQ~g?M:w~>[Wb_LiM7/S/I=vahĐrjwMicrsq9?J0&BF6i=@?Q5>:1+M @r[aUM)}HJ>*ٔ{Sw TY *7uߚ}sRoX+wS޼ %iiQSz_v%2[,!o+áSgрDpsȉ#.p8 Co6jЮmEJČg J,1E±CZ).olcy'p^!L5?E ڭCDC$4ٜxhFs՟8{kRΪ My:NNGkJoⶥy9p6;[|KR+D9Nmr eBtLe ?Cyr?8YReyk<'z0۱8p̲,4o(/e[ 8X% 8p%ޔ>cg37ouyB۶?8䌓~+F]pf ǡЧ ?L[8a2z8_Y?8c'`޾֬jՂSN9%tAeՅz<73℣g4r-s~(m[˾Ӽͺ k\tg?1Q*(6)c__.s8P04 [/gUy:=ZRߩ;Tv,ݏykdڍ8wrb1caNiRYmz󻜀&b[c~,;֦:nԖة:JoIltI['!͸ tO\$$b.qQt>pVO{u݇RzEý}){n)rͳN"=Ek_=9;ᅭoaw[=)]{cJ]-8m&`&`&`[Co_z\(_ عm῟}ɺ)]>ȳcQѾҔqEJw[J\JBW9y'G;;_ɺmN|#[ؼH{,3$v]r?$gSt,j;:`dQBN%%rqY>Iu(!v8[,8/<lzYg{7/{;equQEY75l(o]g;;K[⾐~l}MlVeOa,{ C:(NwJ/~ >tS^f/xA3<̒2x{2y3uOYƇSQuƘb0U#Cظ >}a{<b_lccUA 5?q|!XؾCa={o=X`~/[.XO:׽nv>Έ4ڤ,Y88+shbG!o1D5:7EEc ߜM갯l\>r5o[{|"z}3)y@[g -|wJf/Kuz޿o!)}7vu͏#Ԕ>)}ϝwS%/o{ϥSz>s}Z7&nqя~t* ś܄ ? Z7)>OAnNSsj,,wJɽSXw{É~rfF⛒c%-yËyʍ6ݬ!KfߘXFɉ ɜw F={fx+`ܸo +n0-[wi6 'pSËuىY~;k;lCzP਻7&^SR꯫_nkr>gºv)Z3c<~ƺC獛\QA1zd1*e::M:]<Ё0Öj/ )Tx]ip0sЕoS# ]p&_1 i.8F)J8`VC^f}ǥwJ=ؾm! HIw~nX@N_)=+ ?q1{] I~Jnߟtouf7Al?շEz8ҥ,"?'ުڭa~N;7=Y.4~korrUNUnrFNߩ}[5\p&zKVUW]U˼M[a]KG',31߹[t{K~LSsQ[[d~ߚq%)6[sd oCװr.rW2ie\/ǽ96٧%+Uʅ^_9GWPXup*y]'fQE/i+|(;Y:ɵgQ@+0S?y&|32sN>V΍>-ˇB ofg+2pӛc|?ui%t+#oYXiN̋.|kz/,'8Y"N7NV Za*7|_j?n|ߞ⊢S]}OeKy?Μg!M|u}C6!7I/ A[Ypʑ7堮W S&.|o*^4yo7a¢@3`yvx9<48$>eSNq,cxÁ7qJ3y8D:Cb^;2S7⩃ݡc1F(~6G5GP`v9s9Dz.94= /xT}={V0`|x#0(|]WnvOy9GΣ+M L%Zb1"|Nr9\}fi_>/|iPi#/ogg}׭%+:і;K@ccͷٸNrk[ S[vyb9~qi܈K~čC.|.*Ɇ6=;1-(#͠}>%~0`Y;nzTz!7{ޤz`P$SQ{Ld\'KM%}$G;;cb7ȾQ.=lډt?ڮmfkLeә,@lf?fhwQu`v-v8$Ky.UAa-  ʱsE86:{S'<4ޚ{NPJ7,;4xkovyc( Yr3)YӉvP+H( SwH'v2{4~)$o̻ <7g`ܻF0O*jvʣk2bg"h.v 1/Hڟ+}|Q*dW~(-x' Pt)܂Y3꿚pһMaǤtT~#گ+Ϳ^tJ_rJ?󨔾O)]{c'7q79/t$Mt緛y}Әq)Ĵd8ܾdMg9U3Rlɰ8qԱeEaGrxIcni0eNi9}tZ^:,|e9~R}ˇb[&maMcㇺ1aJ**JkײLLL@2c'Ȳ$狨OZo&B .\3srV,{ݾjɑ.MJ+_t{=lJ8s4cTp08|8{XYpsdf6.}_k5h ?9Ht.yFfi+ A1tf Փ:{X>jZnKԏNc_0/.KW77FVQM̂bUjƲ[;!@zceQOv"Ll_w2G|!__M%}} 7uXI]Wp~.˿t)N{۷/F5|ZO|C)}ui~y w\.ilSr*kZ:rc:ѡO9ːǀ tI\7olf/SWA9I8qp՛/'feIxzU-uK/8O>9;rػwoy4Wtq\i G[Z_o/ClAY&Kw--Nf-ڤό駟^ް9/L={,衇1ݘG?ZfgnX4eqW_}ueAOZRCݳgOyA?+2oڃ vȑ8S,UQGU臾_ rǗ{ @{[}JWw=Vo7LVCCZ++yu|. w0񫿘ړ5j~W^4ܡ'ұo ʟ:z3~7_:+_ xƋV[:']o-={X+p|]ikA:.:m*J\_rݩ:V1|mjdkz/86,|$%#{{8{Hf>pAO;B2rS^/~#z|3kX8wz43M q) 'J6ʼzj}1V:Wv,#;]mf$ y?ؕOzmg$58%ݳ-syIH_ҧJ7e{-:Iz.:+ ͘NUcҭMgrʔ&gOTC,=Q;yd4WD=ٕ uw+_l?nQFu00000000000000UsH2[qnmXt~:{DأJibՊb[UY~ :jlk\1o}ϵ^:Hk *WeJQidu^zKϱ KXcF&Ҋi߬ĭd68E%(OLʢ(Gmܪ;&Ǵu\ۯaHVi9qӮX\yڐ)-,Z'k%q&m0000000000000X%J+FVvkæޘ'\d(HGyŒ1Iwvೣ8~LG@ȵa[iC3ud8c%ľf-Ɇt0.:M>N XbsU(#|F_e;$mKedt<k.Q :zQ呷ʐ eb&z.i4y"'H_铓Py;m&`&`&`&`&`&`&`&`&`&`&`&`&`"5UeJŔ mQUӒɣX:9ecXg(L V`tqcU+Lʏ:Lyb&}iږ_r"Wjiz)H;$P:`Aɐm7$NWsLLLLLLLLLLLLL!otJz1Mݘ'|%lJ+.阏vҹZ ҉y 1d|Mc RtSS GP9,G$y?rֆz+4!ʔ/$xNwLLLLLLLLLLLLL# ؞:cy['=պ(o%1V^r蔯*#i՗L1n tZweU;鰜1;\˵W*OyUZIX2M<2m99K##eGyɉʢ&`&`&`&`&`&`&`&`&`&`&`&`&`&0|-l(/9qnG\;W,]K޲ub>,խe1t*_:ެlh[zb%!YV_W)\zSc)Ĵd8id^aQL:VK]f䰗aӔ}R|2v!FWsLLLLLLLLLLLLL! ?=ҫʏű6C>bZu6 b,ϵ3ŁO2rP=ɱ+Pv$S 96TTFdQFFBLɦIDZ ,B@~VVY$o2UcYLe1Ͼ<b>tPyeLu௫4!CZVըu%J.yRN{ꓧ^jGiŹhCYŴl #N:,Wc0000000000000X5ckU8U&y,2[N2PCB-3/;dc|:X2 C! <:;k|lq/=dF(ybبCKuG]MLLLLLLLLLLLLL`@Ou[L8n%qiO<֍zo SPUV:١L)D},r[o؈o;͵ߨ&uLLLLLLLLLLLLLO6KS.V.P;rJK>*SXA6Y$ؒ=l]ɉ%\r[qif'iNk׶LLLLLLLLLLLLLL,1M/ǭ%ˤIvN^%q']UdU;ùU>&˦BlJZ-AzVZuQ4qL^IgHXWSN2ɺ\O*~+-{ʯ<^ԁ9Y\u2|JP}Ջu겘G_y>qLSFNC2SBlkuLLLLLLLLLLLLL<; ,[id|(/ye-[zӒ)Ve1ݪHy-E Lӹ%L;K=h##Hˍʞ1-c UGԲ l5c[e1b+ZTږ%W\%lHz+ʁOCFY+eq$'&ȉUWZʫoC(WxH N';Egc-KLLLLLLLLLLLLLL`yDZg(J!YL}m3rdCrű\M[1vvXK6czQA.WƼҪcZ1u *r-qm.wLLLLLLLLLLLLL6K@yvZz,^$u_d<[:bd śqO҉yiyX>% td1iFiB,$mʆ▝!]MLLLLLLLLLLLLL`2VZJ+?JyX>%d8Ҕd˵lYZdcq,bʤOLPt]Fvԙo&`&`&`&`&`&`&`&`&`&`&`&`&`"e˭:,Uf\ϓ+8V~H\AR~rY-ZdSNK$ceYn]>'Wy+Vۭ2LLLLLLLLLLLLLL`8od*#i-cZe-XV[!ԟ(ެsxj^-y3J//S'95]'.7wQa&`&`&`&`&`&`&`&`&`&`&`&`&` ,hnײV""m?O&B|etnKol)6t<ʤOӭuyKgH ߖ,"&`&`&`&`&`&`&`&`&`&`&`&`&`&,E-Z6rwtZdQ^+M[V"[x^-˫L1;Qg,]'O]n5,10000000000000!0*e1?/:fok|n&^ۘoHk[uh~UNvZzl,2Ҋ[2)Ӊec麬G̱ۖ uX>Ғ)CqKgrlvt븶Uͯҩ<֐N-2J+ެ,֯ NɣNL/:m&`&`&`&`&`&`&`&`&`&`&`&`&`X<ߒGYLOo,&ME'yk[lrz㩶jX>-P$WeSNҖlN,wLLLLLLLLLLLLLvyVkkY̯"m"c.kztT5+V8kkYo& uY+?$CKLLLLLLLLLLLLLEխZ6Zaľ%UՏ:[\^nK^,1]m͖e&`&`&`&`&`&`&`&`&`&`&`&`&`&,nN:1t!.[8UEl3E n]o\C!}MLLLLLLLLLLLLL`,7U^|Lߛͷlgm[VnV:=*e)xC:;5kc 뙀 U9 lyX6#7N;9ՎEʦV#-{*#WuIoE`]0000000000000}"Etݡ򖼖yU|KgHвѕl]DwcV;??T֒Ot@\x|v~ۖ 2Gsc5T>Uқ*-]Xtb~;Gm*oɧʀGCuβ魴l\LLLLLLLLLLLLL`$ec!E-ݖkKO7).2YlHH)W"k&`&`&`&`&`&`&`&`&`&`&`&`&`Xsz򡲖%Ӿ/[uz'mnzmLLLLLLLLLLLLLvpDB; }$re0000000000000؜0syڗ`Yh&`&`&`&`&`&`&`&`&`&`&`&`&`&$:Nu9m&`&`&`&`&`&`&`&`&`&`&`&`&`2i@qt(i0000000000000؟wzpd\o+0} ~ Q(JBĨbT9ՈjGundWh, t,ADoDW[ѷw ĸaXLf1S4c.a0CX,5ź`t2F.l;p8K.p;qqgq!'< B|ߋ#( npNI"Db 1XAl$^">$#H$WR$I@ZM %]! >Ud_|\G>GG~GPL(ޔ$J.erI`R*RRhQUxHP4Vd*.TW,W>bfn+|Uc+4:. < aqX`C!!!OB-BšapXpضs 綆pVG9Db##""FE-ꌦF/>!'fs̃XXilGb~ +'j& ےpIqIIm74i~; L,Ypu̅).b/:IO>ήaRSF8\onw+=KH-M}摶-m/ *o҃Ϩόlg%g3ud,EE"Y[qVIHrUqtCj&]'̫8n%KKn,Xa8:/_|`sޕʔ WZ⚌5_Ppuu E EAC ;7|/_+-)/ڏv?V8)uSfͻ``ri~ධm-emZXgqt"m-;V+|7Tջ{w=%{$-5&5=@}fmI:a`.mn Ç>wѺqo(8*= 9qqfjsq Բe*kKl9|ݽ_N韪:vz3gώ{u>`Ǣ.ܾyRȥ+._dvqU'1^wrFN6w9wt3LW[~.fݾ7N읻eww˼~b?RzTXqo5ɜen<~`3w_ R?{V^ {Uկ^# #Coon|ш>},g/_-Z[dzEl1{R J"TDWMiI& 'ݓ @79 wMHZdVDF2b 4IT.R+"M!goH8aJOHQD/_ 2oWW"I(iTXtXML:com.adobe.xmp 1411 973 "Y@IDATx]E-PIޫTEbo>)v{^`AEEl0tBHH|s果[sS.V>;3fZ3={w0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`0F#`@h衝z@c2o͚PFwzSrv[+O8~0#+?_^j=`Kё_Ry!DBqкx3_/GG?4H aFys봟h'?/T7,"ژ"~\Pky{j$@h-.-"_:]%ʴ矯??Z!L^K<{[kUv}_Y+8|eU ZK}-}e~C׌3?39+O"JUI&G4kQJe'Rv*>W(5<><6Z_RqT:%2^z*Q]_ѺBoGX8@^5&/LVMXMbMpD#FK=\PvbKBsCה??ZK5'|WYmdېG8ן ?^hN \6!x)q?%/^h-ќȯ^emnCS^J,474_xZ9_/sj#܆<.?e^k{! CV'Wchrj /ןRS&eBϗ?.K{i+?Սx5B9Zy??7;#_yl]t̙b>BGG^@!  &@*u>-Ţ<|I4]>*:~JLp{\];nT.V+QxQRteInKVy-QVpQ)Ͽ)\T/)GWEן?4/ה?\M2_Ɣ'EL7tH\OuU')"GY!UKr섧V F+Pp$UD(Nx ;aW{0G4_9GUtND8*/S>dk}K>4wTTZc^q|_ ġ]G:˱v0G4_9GUt{g0O%:"U^Y'k@o@v>uZ'|Ko4)Бoi7fR`Nv$Cva?DGNtARBa>b ?)R7oW*kh)s +;_^UGxYr\ }P*r?ׄ?H7{>9_Vrs B$#: JɎIqӎ<4?٣ &n|_j=e|S򑗓y_sן ?^wy_XG'yawu>1w?sU{ta>sPV>e|Q/},b4@[TnH~S:٩D|Ư^dRmzbL]^&_ɗ&KBTuy/17xU]{W?@kY&/k{2*& B9}ReyU0$\ iGNs򀐁BBt:) DPV=yD QfB USb<RB?zᬧC=e(RǗ@1`#U_"'U[q:~y矯?Vr`@~h=S^}\(HKRZ?v o�fE[1BOOU?D8_6ԓ?eث^1߈_>_6GV^6yۤ^D [*{S `~CWz_T1> S;(ȶ,z_xj2˞ԩ1Ӿ6>uϘd[_>{u}y[^ʛGKLSה_yWO?S{Kֵw-ENJY";4\-Cc+=U9;bMX'/}eI]m__$yKzڦuG4uG:Q:> T hjKN'K ^'U=u! {RDe 2mj'mekSI]+y4Fů7~/1ƟTO|Z_/B?py^:?TD CZSc'wi.(mg5gGj#EWL;#r`<}IqpBeG'A6ANP{~á-,Wo/+q4t_{zP hZE k?^}}eOkZ*.ZKP(fh afxL?ű>5&.M*HUG^KuRFe'U{%j<^o_'l?ƭ?׿׿r׺_ oRI|hz5=?j_^ha@T&E^~ xZ@xq￘kr:uTm$~ѯQf6E @ ":ʏˆIvL4 6ɼzWq ?_WF>A?eԎT߳fƿ˚G B~;Ƥؤi>~7̵ppW^S^5{?յ_|F2;_Sbk:ךu?!:݈Q{ˮ$Kר0%ؒx RTzʹ |#4e+N1/";RD}SY]<;ljj%y|ixi?/9{2=<ğ?sʵד?'x8DUR#ٱ ybj*>mj+t((^m H_q4b /@P" 9yX:eG󓋝ړ׉$⑧=DSmI՞6>*~vxjYǎju㫯_o=|jT?^}V/?މ}}eW?>z ʞYouk6:C_G[^|lhW˿o_>G~WB a0DQ^6ht9뤧(c8_V8?z*'QЖdžig5n=_$~?Ў Vy'_Ͽü\a~ 75|y[|d?@{%ОJS^+j_'k>Vk0\zuޓ_dvAGuF)1s`K">2)"ei ήPʼn`5`#ɑLlA|^Ɩv?7yƪ<>uDtOKƣ2oz<|kU{'>%u!MS| _m_m2P1T \p)#]0:&?D}RR[A=~tNOJ=mҡx!ŗ=pEΏ6%&tMpx) `x-#Qx5rz7r�^f?Cx{ Xj3?/Q[}A깯Q&E?kv'{ :a A K-}"ԫ.e;7qCJ&~ǖ'"6Nr']m|eU*c,>tsp7:^Suozßӟ?acC_/t_cON";yOt9jO;b?hn:Z$(E0zH^/>R_m;O iUJAt2v#WSvcCŖ?׶NmϿ["W]On3G%vtݠE9돮SהWx,|oϻ7=T{?$>HeMGŮvמ)c'/:'_ێrm|ʒ֟ܧl%CKr05H)N8 "[ [ ˎ6NGy|Q'|@O>?^_ǯKimԕ ivVgKL~dxYb{szu]~ZvqvKJ٣$o+['EW:t*X:mwA8yؤl)[5 (TJmG]2F䏶ȆȣSFֶv˷ˎ8Axrzu\|7K CR?]Iy˜| V_h?/￸ohOy#y*Vu{_{J|^_)z¦+{ť~].1le >m(+~v\Ԗ4 zG{ucxg۟.r@ӟ?ſ0oo͡!HDmjEs=|3bcOIUH])u']|X"HF (PF0@{ch\/y'L|' D'^_c;D⫭Ӯ6|t_cq|W\~ Z;XԮ^rNxQWuGyxqxx'{M_ڃwGwk |z֞|azG7:#U, W[tIEt2v,*;jwSdk;@LtR2 Ф{G h.*>'~OH[lԿܾ6NEYwkǏN"<>y.I:o8?Ͽ5k|U?NJ4WV1!kGk??Ds5yVN? Yx?9W:_:kuCdS {##U;Q{W+Q;AO^zlkkj2|$ut)u?\Kӱ>Ova#)[2+^~F~dK*NUNs,9 @ů@"/s}Rz 2:QH<BdKzC w箻Il#56.ZZZ:A-mԜTmڊ466Fkojn*[[ۊ6E5);>?_^tE|/?Y s??0b (-Z4Gr=w?t%Km,ȪA^p$eOyʣ4ё-&\lHG9$rJNkP|I4bs$cXC؂EKbŊ哹x#`0F#`0F#D7$qEK%KV[n6[oܟ 2E΂HqQ6JIąPِ磬rڇ&#"V+CP-LDuT0v9jwR,a1F#`0F#`0FtDbxђjC#GxJ"uUNي-u8ы<퉡iקb%'Q{ߺlA4܇:Ni XQ[QzД#N]KMإxOo*X0F#`0F#`0@OI?8H?T[b#SvǗpG>#]eQH,ɫL9cD| DP/?Qv1(MC!,F#`0F#`0FzACKu"{?yb/I^|')[ɋτT^O_~JW2c ?$S褧 -uC^2y6[CA0F#`0F#`0F>  Z!wso)19Szb;HʏNtUD鈄< tɫ uA[ʤ ^}'uqG/؋o፹#`0F#`0F#2m= / ]QT^6$g&(?ɋNmRyC*N:Y˸9 LuƠ=+_@N/򍭭 >#0d5bX ᧭ UF5ݜ-_1X?ʠځ0F#`0FX[(!&%p*ɫ>G豃ׄK(E'R>VMr27 +OR 0x5(4'Sȟ|/|!ӣE ^=v̨3zD0_ M_p9< c#`0F#`Ŋ-G wI 8 z6Hɋr|@K^m(+/SghwJßA@PƆg 6e ?: GYNdx}-A`#kb0F#`0Fw]3qA7KVɒ?+lK'}UG:AoKق%/B`: c D4pU``6a~I;+DZMscJ#ӆ#`9a0F#`0FST%##"\#(n2zKHsLFZShF1Cnξ6&0r?"c1X=B=: #CC|Q.lr Q~GpQs #!l1F#`0F#`G8ʮGxHي$(%zr ,e B}-)N}w+>z%8iDQl )`Pj+{Rt;kII&-lJH j&64F`@` _ip0F#`0F`"P1q,5ZW'?S'm8WO镨si @!N2 KD`@t?KBVh SqU.["i\-7FÔ;mԢe䭢m"/65,mٷD}ɘma6t\/zYqsōnm7z8dc!4XZ獀X9r0F#`0F` @,rO*nTvpEkOڈY)#I'u[OĭLu:.f\Ɔ<1i:6ʎzM٢uثcq5>az' S!>25F jۜY?Ɯx͛mmza=0X߰h\S%g9s|lٱG8gC_{q;M왿ڠ ZF pE#`0F#`Xh(iF8J1tW*^ExMm>XUOuž=^'g N]W=m|VelPF 1'e B\x"ܟ3yԨP]X1~InA([{b1sŎѶG}B'qbѩ{"$"wyҭ?ڧ'7tۣtoGߒ@9u9zU#kylf۸0F#`0F;"v'#WCd(hq|߰}8mYRlר yLCbtVrUlٲb }ЕQ7xӀ󺁜{&N 0F#`0F*C{?&< .=,zxLtyc騗=u%4 ccAo@B#R:2\BD: k';S&^1h#<6:Jm˓X\Сy&9љe+gӏ5\ 44*U~Xne/ ?7Ju[QH\OOMq3^]UNd9 niLjO3]Gi}ZhQ_j|#])Wt%Kĩl,^ |љtUYաȴtM[#`0F#`@Ǖ{W+nIOq?;9DɖlUGR#:t z#t@euQu$e+#`᫼zbS1y"z?ct2M%E@PCJ$>E+ғW=>;bN569yܓމv'uW=&;;qץzr5<=}}vJO) ~NJoץ/Wx\@@GݺBA+0F#`0Fg E]W'vK?EVRă[ĦUTս8tp$:䱔/Of ~$"GF~0yhKOkv:%6v+c%OѝOCalGmK_᫴fvI۶%hd||--p_kzBzv|;ԜN}As}K_)='o9؂<{q;.coѸ* my 3~p\u5ECMO}EgObP4b})wSTM{2xpl=;SA7ZIaū!r?U9wn i0.oa`tac1F#`0F#`V/ f9wI':J܇KqۓĎǢ=mP2%?Rة P/NoA<>T UBmbB퉢mmz@;Z|qOylNO,SbWA*> ]*c횔xzҸ.= _kch̼gIqv-_<׿8v̧>^њf+/og|h_Ltvm_r.^o}'6YgƆl?/*̞/#3eJλ//^߾Aϔc,:1w׾Gqx?.M|}'8O xu"Eb0F#`0F~$1'[]g'8J:SUrb:-z,t7B0" X:ʵt.gGE~ҥq!?trA475i K|#ǐv{~ء<^?/}g?]_u͵|*=9UlՖK.{7rˢEWOoz"}!ICq]~g[b F#`0F#`"MJ"T%x[8KڊHB|P->xHa6]!S!I^C!u* z5@˿')>'e Q,Ƥ6Ȼu7x͛b_c#F `dSvm踈Yw$*?(ǫ!x""-xȸ8nw93Ώ?3%?(-M$'OCcXz"1=VpJJYnj.$pDzBl]i;sTtlH`dL"z(bF7hРuK.<=xrv7db]oƛnO~cȑi~nݶMO:8+dvV_; 7u|D.#`0F#`0F+mI!K##B (vu"l!zAp?IU^ܩ/r]pO`"8&]`:;/=:AA@iǗo@&/D7nmm"uR̾Ƙ3h>ROjDpO`ncĶf]gt+;6ڻ|"Ҹ?W>w]8港<F`^]o["qۣ,(G;?-B@pqjp؅FmTsC鱛K?tS;=yXn߯/^uڴGS߼__X[ء;WD׍6ܰ (rg .,}4ƏI&!kr52F#`0F#h,\3gL*HYȜ+ϤL=vEH']9AdK_w*rԩA wECzЭVt* 8`ǽ++< ~ucJ{?ُ=0~||_<".f+sEMύR{^]}+{ƙP51WOłDk_}#1)=Ȑk+e\T<9k~#`0F#`A`pk# |RlD5SuŖvϙǯb-im|'A`JeGBO|at>ב<bsH/tIB 1Mc\=cq}L5%2g$8{6clszwN:1=IMr_n鋟/~0G?il yw|4{z:yϗbvݵ;/|N?4_l~N>NOx+bwu態eˊWԾ#Rb0F#`0F1Gl/1wȹN񟐼cj#=~_Sр:5Hi)Pfb)Xy^ DT9*0>QxMbҎ^1' ɋ]6t| lH N~qK?6;k!Zi&qV9zh#6BIa{cƌ)#75o?&pȠfqkii!G,/ {yH=骮=GYU~MDsC#`0F#` 4tJ},9t.BlQ4[HU~?j^eqIŇ#XeC=Tzr rW'sjKXmR|QFCdOY=)9ڊe ~o]Rx 8=\HNH'p_z8eRǑ$+"RlTƀF*#O=B=yՉxwuǾ0F#`0F#`^\oV~R#BĆzDgY*IrNm_zNkOBrҭJ,VDt*J(}_Ö"):&>Ż;[[&^`1F`"kx:w#`0F#`&\sxH@du9d<:ՆTh=D0SjK}"gd8tWCOu=yseu=@*>}͍\!#`*;,F#`0F#`@/%I Q#:GRZS(rbRgq6HE')[_շ(RC"osat @0y]*VŞv`#[ʷ?ލC !R63&Bg!_/[|Q|qd-=EI?juQ#E/|yEϙTDz<"WelՇWqByv] 2 yՓF#/)[Nz| 0AGO-cd9cnjf`#0P^oȁ}#`0F#`ZA"j-WN\'xZ}=S\*msb% @IDAT7UW|v'tZ5`tXCB^zԎbjvi+{@ρ=z`%PTN2z@K cFƕF =2qK#`0F#`X7hkb,xZ=5ɋ};a/z^zOwљGTA,uIu DA::L J~eG]ގzJC'!w S6ȵF (oPg̝5F#`0F@KhJ/ )Tܩy 'Q=J!?ۉN.EҨRH:D!H[ !:uXKE ,ՓJ?l_*hjlAcp:F B!p7:F .WIJt3P#`0F#`@? p%BY$)%:xΜ;R8P*^> zBˁ2*S0@@G'ɐ_uT-^mwl:!&Ç#E`Ȑa1F#`0F#`EQ|LpxL҉DčOܨxMN⡓}'jN1(ǶKڕ:t "xE&UנH^>h)[_#(>u-8_Q0F#`0F#`Qd-xMԋ Oc#SkMJi>Rש`Q:V9z11 N K٢L@G}m|3i0F#`0F#`0FS4KY#|fOrb#ϚKO`x8SGH="[RtNA=??#`0F#`0F#rQ'%xM-F׋zI=SdS7Z])G!0)AC4HfQc-BH=vj+-Khmi֨y3N#`0F#BG8^cXw0߈Cy+]?]Rs.3 ϩwTڈo!<2X":A`O(GD[|P&vO-)򥶔He<1YbX <&U\(jO͜Ggg΃j_ŨvmTrg Xh\٫ΡGTFGYm|>x|a'pPP<˲MeY0WqF#`0F#sxZς|&#`"H^NxMNіS9FQ|.>mpX?XDPy:Peu(@KB'@!L|$UFQ[E2িxҁq#`0F#`3Yt@#`bexYKk1 n#ؑujR*x@&qU*nS·qN+ZZc[L06\oxWS)V$z HNL=z_ْ'6ؒ砽Si/Q,.'d0r@ܒb' r^Ƨ$._Ah[L',M \~;#`0F~E`qz02lXz̷g}lU4iR.O?\O|"cx;U~qq)'&or-.ZD&6eI"ޟzfbcj'x"[)V_z755!'Nu$2}Ys=qs:˖?N{ƛo-}sݢy ʫw=>6&פE`X'^&Q;n/l0F#`0FO<rwN8!&n2!vi2LRgψ|V0$%dKҏ?|,;7x"ǔ?11'P%Qw~b㏏ћL!c֋}#; 8+<rhGao@ya%\_Wb]v~|VeϟV)n}5&LP]t/^)oN7Ϧ?_9/u]9Oy*o~|:FU tޙq/[lE6o}[+m O.xozc'G?<+.;x;⨣^oů~u~u_7Fx$?M- M&2|СJu(3-ج]ҟ-wHᢢCҟ\ԽܣHr:T)|9ޣX㆛nǿdx˛^ .K'V2- +#6i]2?bLߞ5`gdpOtz5grO̙| ^@۽0F o5Ncc뭶ұ"x+ >ę?8+Nߏ ԩǜt+|V3P?׿q%T9s9';|5ΞK|?ԼxtּJ5ɂ iΤ__rSIN2=mOmj"g>ˢxlXSt-Ɉ1hDN'w7-+V?'VO~nKo)іȝN\# Gyd8/KoU%Ƿ_^DG>xk_S< S>g1Me_cǎ?Dbo6y{߉"8ńtQ}o+nߊ9O}:Nam]ӥ86ƹq^{]|kwk_])@";K+w7D_y͵oILUdxJa߽-6\hnT :DKw5O<&%1{'|/٫ʛy<xN0FٿHDÕ8Uz*⬛ /O4U=7l#8oS 1^!W2AD0/\v*wqG,\0F&b;:N;*Ҧ%ZB{>=`6eZ,^"yݤSNOzdnccSLx}I*:"I9GEC -Yg_4fOEј:`;)>C#reG$ _ywcJU B_{ hN~~v,Lˌ,<:7nx`zѸqYqN[ /G>O./TZd\/G~hybFi<vQ1}NWc~U\:d"va8嬓f<^rM"x, 6 >'qk\<oysI~{Gn:'vO 2]ѡ8N<=~ ps1cFGWL>Ck_Z,H_OvJOyA2FTRk= r~?]'3w}+'&ի{lF[CʋWQ?k)]#|ˋ[nwL8wŌa?5^ K+;F׿…\>\ K<xm)9l:]cTl:?̉}UliLWCi.e_L{O0F$kNC_pa~=T)M{omҋ0nԩ ÉMFG {*'!oXQ&F= K(~,4n0>xVQ++v~P7#B!RDu.Jrb:ċSY8T_y9 DkwB0>#EУSg)# U`S|>engWŅ׋h]{"8nB?5Fx5D=DOa1xX+WɁXF'/8邃~UaZ6mZ謳 |tí'3y&N9#1}vmSN.~BϝWWVO.Hӏ`׿^D=YT"y&i D.^R#wY"K_~`]_Υ%m9g}ɘ'. /c1f9̕W_?&gϿ+5Qӟ~(9xf_4dv-似4VEwWxK$war}}q#K|jnОy̧bDZx,X9il1F#. '?? ̩as NjPG3 SlEo.|cvI51ByK"n-г3#.䒸7=rwƬ p@p@Oޙo}俒IK~/_Ҵ6Xs>=bh.آb>%c{OH(jV_-Q1c=$:L~<WqGuT)1?/z*x`ECĤ1K"!IoZ㣆6qC9!vM[^IPW5v\/zk+(y=ܳxC,7!_1;=ɪ%nXdQ(-3ʰX0ʥ^ۼyE.X#aRwS!/WD/ăbρ`*&6QlHOG݉+ 9ӹ|p J5R|R/ ;|Smv}_'V'{!CN?$*Sxa=C'CD1z+"8S)Eໝ6 QUzbuW"'t͍D$<>˂ vbyDӤM;˧2Wr@c͘/RFC1t xwFgSy;8G E {EE4{ǂcLl?jbKF#vcbXbPc-QPQAz;{2ww 3;?t&3ƍZW8"MF}VmeyP==QB`?<+ |-g6r,1Ehtq8閙-zðܣg"ڡh aMW <" (Ce}6nYz^{1|h5кiVUBk嗣/ ,zea"`lբ-^ 5]i\4Σ]VE;Œcu9"*X]l 6v*#*[D%叱3X:YXJ!RׂO7N $"}μإz%թ ِ G :B9߮\e>Q ?.{51:)`h`$H]&z|qߝT0_`7Ă4ݮUήpM7{(ϖÈɿ>'v⠰"Froή0|Xqr_V-ѬYuRLH\ } Ͽr_nG#HƢAs6bʿ\Y!J6._|XJg??;6vOױ Y'"cN--C!5W[y~fKdOnHdaCz)X%{GQLd!< >N 7hPږd@",w#Fc6cuzEKEyJ`׉~WS +EU@: :(em 4'>Z#uK\ܧxQM7Q]RwL6)ИU-U"IkMQBKGp`#7.F e99"xF֖E7$+k/nk]½˹giuL%B#@#˪ν{_!vi~ꫯC{KcT T>|'qR;t3Q"!)I!aLmcdpE+s3s#ҬI# 2i#isj澎_q;c!!ɝ L꼵ZVr7(ܙ>U렓[# o䣏#{Kٗnkr"'M>mxq(45̷{v^<|~&8jivT7䭬&g\+-NR4eY/>̥zGtPg zq!ܥ˪΋K/4GzU),*&SL6 :-[/?l kMث=y4 Yr`c-\}ANͪBosժWJwر_(BCJoG}J]7Ӈ^UaCk1ƽX!a ׆ULxаB˚gS)"' >$z f34\mɍbs7eMJ6=(Si}Fdň$sI]YZpp%C=4 -r.]/;sC]%ջ 놀Y^|">qF̍\7|S6-ooZ12X)XHkrI 6lxqC$1DI'$XygU;~رQYhm,5[mWIK DQoP 'WVwL7z'vސ{͸@J>@XWmoєuCړBB=EߨђZ #"@Cy?9 NshҘb2a˕ ѵ久 & B* E"D=K ;hm;^+ʳȍZrCvvû8̙I84 ~o:p}bs_'eFlJ!yg U6ISЏ4pGXy"Ar4= i hY.MI$26 C*^`M⮟sY $Ys")~f-*&DpzoP|~oiN=X:4zꩵBw5Gx eQvO6,F+g˜ڐfv4?4k(th ˡrhh$M 3Itn*iMMK$g_72/M GX /`y&Qú鼌u&1#ΰ}-6|v )ã [(k0|3LF l2Hݙg|Y?\ta]Fn+EE=~xɒ|^9zem[IYs^ߋB2_cM멚-“ 7DPJK:>6%(C4Jt?}b,;<*aDK'.1y00V _բQJ|i,cd;jOXc%"vi|Dp鷴p=>Tu}m aKK#@!7œ\O V`Xh93c_)jP9аs0ϗVݨ[0wխcJV'o  4M֤ihNu̳|=@/W# -@7Q5,Bz*YO=f?x/k.d+& [v6CN8b!;ޠmj L~M7,;Yd7Dms ·;u9G7>2 9?ƘJH#w}/p/wK_|s`L !{:EP"QH !w,-|+!!*%|Iz{G 8u^;L8#zrS͸uXE(Z"H%AT+QN9=|(E>#*[B=<챘=h{P\s7Wdf /&;|ǁqD䒟YɨQ_"kS?JH/:Hf @RR<}G "q/RBxCZ\]uLDzm\cs8#8 ڷB짥BXڽd1SR ϿRҽ?F"7'WΙo|bd9T:Wg9r&"l D'#:maa斊Ω7! qKOMs.yĢ~?s;#_ZniFuZ5oj74 kg5[c1!߷ >Asgm5das-PEnd2lvpˉv&EFvn#sid4Yxvm4Z^Gkcgli {Ʋkt eǧvfg,j|һ6(64o\ 獺nmMǖNfUWFF`owCž чAJLeD*1_:crWtƦKy;˕rT&բUxl cb^˿U`FFw^Ƥ7IVk~t5D|_D0snpqb;[BH|Y`Ɨ;o 3}%G WHD26q?vZ*-Po/|qs^})3r~f\{)yxDo*M(L&jqQaKυyZqT4may|0sBC ~^~Yh}aCK}0CcN F=Wq|w^uYha0}BQkO&wњ=C+lݻw}M8N4B/}5RgCN8)ImcqCwܱCB;cQW9ܘ { hq\+)y{ɧ»Njp 7ڡ7ɾMn.ju ȃG=~3s 02H>C1/!19U1<"[ط7xcwX25~oF:L0\y|c +;vw7RBXd?mY+v[n㰲wm/ K-,6"ON}3pc5F-kk~1[08VB͇soCqo>_CNr *bF2!w?|tprR'_HlnljKAڪ]‹/ m0ci $O;y ,ꎸ ^Gq=1O4QΤtÛg9n={^b굑o" \u#8#P_cfվE.r;]vFԶ;ܧqh ^"wsS8ZZvk%f 1F{]ό[z5R?H !!S}믿~ Իgv6ą|cjC-ܩ^qOMځ z#̱oNf׎ѦW)k4}OuO$O3<_|Ca}K3ѶEpB&f!{g/&a,Sc X`sC: ٥Y>gq1wa |RJ=~cR:iA{CYjo]ºI'>&͘6XsX]00>kTyۮv(_Mڇy. ƩD?yIIJ z.,o$|GO?B:%>VXW6%ƨė8PhihA3)mMEf C҇-|?J٦:!-,op]ƾ8 Kp[} ! ب9)}&;lf%|i"0–1νҘ|sZCC>^cimC0"s3kHO>ßM7B]$ E~fsG }M7":nv0-՘!uG~|_xЫ~U-Zgon fy M-߇[G̟gZֶ]pa/Ly&l_r-H9y%LKgYRoK/$C~gMħ~N:dTYyuaʩ ^i#wF^~zg<ֻtbŮ #Ipᇅ~H* !9׉n-!Tm zу: Z̍ߒHV}AwSҦeӰ{3>:ͺxdw^]VF.Su&llm mҞaO=T>KK;?5mڰ+zgg-[\Ula\[WdZjMzcRڵjl gV6D?jF`槣²&\0oç [ڛU[7JU MPΗ"1]  J^ #s QUc|+ܥPV@PҧgױzoS9 JdCɄ0΢v&FlW$+_kjlP2}{#fe9¿׵ⷺNB "L o-oY?FHB0}0闧3)ؗ-h\͎EƪTi W6hYnߌBE'oi+"@2ջX4er(kmZ-gw_8'yTITEk˗สz[-hE]o>9іhSM~HT$Cg#Ėkk9f 7D\{Cu}~Wr6ODrJ䨫$*F7'M ?Ulngp+9.8TѺs#C%Rsp8i,t\pZDCjv4}D#0h\MJɩ!âWzUx)[&  ;Є{-GpG : 2ڔvpͷ=}L>0~E pʂjCFA)H#Ky iژ31SϽPkBuUm {5F2 M†kt a[nCm~R (_T;C :v>fAx{}vYZpQYXS*వ- 7%|=~6ҼW^ٳC4]&R`7u0~ҼSeԿ_XDw<_vBYnw!s.6KAk3s@Xj-v0@Qb<^ٌKOZyRB^GDd w0_\KJglqZW?,*W(52ڊldH|0 [C`6=O:J}W{Cw7fEH3]̃'~&FC ~MIg{gd圹{[:_>~Xdpdś/{OuJjޖ E~|±:[RNTؕ䫯!Sp>q;GpGpJB&|n$r>,͚Z>OHw= 8m>{ f|71oeA\2қ}awS;گEJ غY177]n-@a깳`GIm )#֖裏‹/ aR"5rgPM`\}0sbˮ*̛31η管}-ۆ̶[/G:Z`U*mݬ"s=l䪫ݶ%dWv9‰"l6F {.t%&"X6_hbC=-~ Jy~: Uٔ&@DK?m6A+@ F6;|3N>+;|V0uaPaoߖG?(̲>rY1p27%NM#j#-_z-vXNsWU Mn~GpGp~hE5SJTkoְ^{-|kfi^Oƨ,}9;_Յ|7iF5~RԙC-=7yyMk4~Os].EW[ڵk)CJYhQφtɮؐe$´`4d0?51v=ڭ6ᗷF\|,89{M&ۣ[Y 7,69(k>pX925D<2+S C<'D.fdyq@'^6$u豥 nydGt^KKvV}́`ǼWcd\i#ҳXEtc41#=uҖOL4$V 3-pGpGpGhi!j/Gp]w3+Y"hYaq9Ȣ/g4 Z-sF8h?s/8DRuxLI^uY5r66%%>ЫN)Fi ?JGW)2.f"lqKz&ΥI>ȦeC{l!rO[vZdlc~ZZl\c.#8#8#8+/͛5 pOx»? N#W002vn-}_3֮4"o38EE*RyO/-p\!S[l9CNM7ņIq&(,Kz7%ڀU?~XSʎi ) ,NO/pGpGpDЇ;@A6"QA '*S4铽U'RXCįGlC]z"̃ZPq(q,Vz4~Iau-;6 [n~sG"P.#8#8#8+|䳠GϷX)Xg:AHE4l bS6N.CDЊK?, _ڲt̍}5߆89.#8#8#8?Lg?>zsrgr7\OJ)NUkQIPvJڢ"D^zRa] .cDuX&kɵhAs8#8#8#!`?ǎoYòPU'#u8JQ<%\$dQG'ҪYSGTZ}:Se.ZƛYe) SI6";-6|[.r/z];XBυP..줷nl>GpGpGpGX>('K?1AMF :H``Ȣ rXzl">dg,3uqGpGpGpGpG ~-4gNQV-d(~lPd/$06\.Rz#D'[ʞM!@pGpGpGpGpG j?.֢#r*#6%r1"o!frUXN [5+谁ŧZ5/k3υ9spGpGpGpGp4mMy?*HxHlGUJ/Ss9t~ƈ)!c3ڜRt sϥEPGԦ΂$HJ. Om4 ̏>ccog'.#8#8#8#8#TF`MPQ-1OsLI`8HىĖqUtBNCÅV%{.l URHH:>]@mA i|ؠ$V6גi8#8#8#8#8#G߸K-쾂 [\j[5K ,mŗL_ƉVį3͟y8#8#8#8#8@~Ҭ&XV8S"H,f8"eƏ)KaEʯlGD sIɽz8#8#8#8#8@E?N+,*Ƿb 0"e)ז=/:axH^E /Mʮ 6\V$&EZh?z٧uGpGpGp~,Ȧ MlSxNt\eT|ICel*0?rK)&e6B)V Cl7+ x5Ne>e #8#8#8#8#T@?ӊ+-R`dlJJYV͒Z %Xp"O[k7ZCL3pGpGpGpGpT8 IUWT_`[aMd#qDuJl `JA?uhS# "GpGpGpGpG(@ X}q O)^iT\gnUYɋ-_!k%lJ[c5$;qx=h\GpGpGpGpGȏLj >4V\T2lQ ttVi X:Pǧ_Fd-vjͿx!\GpGpGpGpG(@*I,'+SeE%EƙX<%5z5^S].Ŧ^J٢yvqGpGpGpGpŋ#Y}q YS\J"Js +L1 (HZ6 {!Zvgh+'m"IYq~?@\GpGpGpGpGXTp STONjkr\NɯƫMYYmFa}So _رc+,vڴia!__1wܸ|K9sfg֑~ʔ)aa=7oh_j"l[#8#8#8##  J5ʺJ)8Ӕ!VQҟ$d.u1b#(8$W ~EYuŕ;8zEb]_q7+5p7O?4t-._~'Oߍ78{ J[c. oF8÷~[3fL$?{YÇ+ڳݻ5\dᣏ>~pצXKjN>J}3gN8%\^{v__ӆez6)ݼQYxmpsϦ*:;GpGpGp "#JxP?RjqƖRd!_wGHQh` /0!F塇0aBB߾}#i Q_2;pkqVan|!uKo2tGpGpGpG`B`r?ӓ˿}ʴbF HT@Be<,5:Y5@jhl>l(<"˻p~X@Yz5ׄUW]5n}1j?qL?pUW?8{AE"(/(!stuV?pUFxasS.}@%;xlx'rGpGpGpeY5if>FZn%A]\ D_hӦM6w޼y'NdIVs9't)xQFtqISd%>#G?<'tRLZHЮgϞSOE&ï~H\~Q_T;s.6~/fE=.>@>@\K@ w! vmQG_{yM38#7.\yQ_h\y ![o)ܩkp'dt[?v.[uGpGpGpGoBc&+T*\SMIٔpU? !{ŘVd:l|sa*Jj2RXr{c%oV˕FBA L/DԩSc^7bb-6䭅4|9kڵV?{q7{f#:!!A !_͛GbUV_ZWm6HfC9$FBVLt/k&2pΝYfhe"[o+@32B2$lc7 ͯ}&O6luXؼIg/ ]{.l8+^|ᵋ Rg̘uL_G Y'+>|-ZM6 D"?G׿u$I#qgkqA'\izͅ 5#uaΕ'gaڼg> f5#8#8#8#D s{,4?75UaZbI_4B +pDB 4\Jp!Z|j6'Q~WuV 6_$V-=:F |A$?I@4pC>}b R}sRho)kׯ_LAT1c‘G#IJ,l0u =y0`@$hY{Ĉ1s_aE&rVc#GƜ-I-A "vmu ]ti: ͟u="}}E"{ɝNڷ~u׭}8dLiMJ?.lya.#8#8#8J@&2X]q qXnR`132իԑ4%L~|[c_uq_Idlɝ{n&?1 sxU) YUӰ sYd=lF]!CD$80B6$1p5Fy!jӾjX8kjb j_ɹˁki.M?|# 9 O 9ȍ@BєBBFag}c9ȣ{|@K) a=.4H}c/).sÐ'?a> o0򸾡kf\O8#8#8#|! "U*XR/*"bq[KK`aK[},F6Dǖ߯c#.e*:Yjook?6h2;CN߬Gpq~X 8(4 Tґ4g|TU2rּhѢ  wpM?5]|*6;vk26tl&Ξ5! 06\GpGpGpG`B`'Cv" "NY*{|&'uHS*"%6_.[Öl9CNHԪDYr4^8#8#8#; 2)+9cx^iCA"&Ň|"5o.Gse]Ekތ6u&(LNEK'~6S׆c,maBϚhL>vبsŴWϲ<ɛtvjza ;sb^uȠͣƜUϰ:!\pGpGpGpG`C_DŽDUҋd&viX3V.N5?:ئ㭙_5R`âhs!eꟶ@—6"] uG+8CvVw9xc\Y/~|p}pyH.I3óc/ 'Q@(K>jJ#8#8#8#8#"`)(Β.t=?)r6HUcD觮%is!xԸu1 jR,!j>Bqѯ6u.Hd6n@}ϟIlC?_O& wrDZZcʇ|Aԭ}гTDd#8#8#8#8# (tq ?ZW'kCK|)F21(t^DvLʂЋ̅e,dHO播t3Kc8OlEbN(}Wt9Nf [q4tJ3DZ4:6I)9vJO[Z&Ht_a@}DaF$x3h|72b}+#8#8#8#8#PrQܣJxFxL"s腻D'RتYS!NS%hz0e<6=B5?6̍.k""rOE p("feIhkk?|/.9k#V& z5jP)-U4ijxf̤E~d>GpGpGpGpG , ' *+=:K?ET%?5'>ұ/.\G[T28%^m,JDkaZpj9)8` Oy3.ϑ,:rۇ&4Ĥ(F ުi8ꁼ,W3}]xv줂uLbϐOڤ{6B%-"zUڄM2/mmFM7mQGK;GpGpGpGXf?UM*s8Q uaC]}9Kb/[iӇNХZG(􀳪Gѧ EȪM_JC.>;m :lƪ>ʏ?ѷJ16ߢK%86h!Nݺg8g2_==|tw بھN6ƆK]wtZ't(ڪRovY{V v>0 y_oW m]XDs)!ӽo]kjk,&DY_):sJ1"`劊SKu;#8#8#8- %"#<8ǔN[U\}I=n'_:JӪD)Y$s$.Rz6 (26OΟ1Rג1_众GVi἗>."R!6%}Ewb+_OɚC[@&cJo /9?aݱٱ*̵KrGpGpGpGpG YWK"A+29;O01 <,8D_Srგq[Vk>l4s- 0Y~ZBs. zh~.%`߷L!4tMoNROHr}Kި蛜¤HsC6D5{O#O#!vYop'hJeΓ6V)Y}^:#8#8#8#|$g1g o).pRS|%z8I_)胃O|Jhk~q/L*]iӲe\p=%z1v)"@$N~4,,ZCry/DBBK4-qZmH;#uӔ8Q*f0%(-{kt/˜9гxH^֦*#_DOu/_ҹEN^iqwo-odTICA"ٛh+s^+6;L-^^KU Dr+J FRB=W)[,/vREB& rpGpGpGpG(G@#\%F!Ȅ MlSxNt\cXU>0,Thc''J!:fBZ .W Jt,FNYa~ʜмMY=M6y`[ ޵G9mUňgT>.&D*J}U:N4!Hq)#LMɱgOR`1^:#8#8#8#T-3+mR''T+:2xCGɅGs+̅_JDi҂a18-D FȞbC [Z|` q|S@qExˈqW gmfQ;﬈D!'4!S#8#8#8#8J@ \"!)>yDPH]t sK@"{tV ϝ_>Ǿ245m֨a4g~`aLq#lťڪkǿ7nq?^Qz솈2Y7a, &rc4:.uGpGpGpGpxExF.pp xJJڈ8Li+:|xDW>qj2I51phl"(Ycx5F>)u&A-PV.w3]:EڿOD3/ 0jl /L:wJMCY%~Fp߭6%9NB`rpGpGpGpG`E`q&ÀHZxJ$$,:e[FO؉rWSeW "3"a tG5kڜ&±A&%iDb6>Ч7-ӏ]:?kK:/ i\֠2Z5nzaW%%9Z6%SYO"{ru>,txIws2P\GpGpGpGX(*R'&"^>R%$$Sb/R%%:|# $WXć|2.0IU, q6GÇKW~4V,?з8&cY;F̶.U#@ohۤQ'ݺg>Ө0#8#8#8#8JGvSra'6$m8L.JJtSejMiMP:tR&C,Pv%l(%B$^>46}rDbV7RSB{ydP4cpGpGpGpGXϬ 2Z)%2I`5EF èb#S%}R"?6\Gc4?D$63nY XzHJo1TVǾh]f藭p^*DN8#UeJ⫝̸ޔk}"~b"/c2+#8#8#8#8+!UBs7 .d.~0E=BqgnؠXf=R `-,6/&&ΥE2y@csa䎧 =`cX :AW/y}#44u"b  M9L-WܨiXNdl}m!o[Gygկd(".H>u]8#8#8#8#I5"?;SHܔd WD>t3uA?9#EeG)?ѠЃ6R=EʩJ&B iVmH[]k#鸔m1%qtG_oo$% HBDZ(ѽВsrS*q;l<,.eS2h]֘ ]C䛬I^  `_w}Q$pv8#8#8#8#H,gʡ³"E`63HY1p>egfC/`,k4N6]ÚQ4Vz)!$Pmh)+ZJeL]g zc͎pZ*DEg7G:(=1(2";%x I,%;#gT8#8#8#8#r!8;xPFeT]$H8N.A}̗r__5I46EEk1#&E):'X6~g-Khԕ&3e1-,W>_H\"ZR$NU]4>+_6Eo+@ѵ, O-8#8#8#8#CU.QGK$"~$ǿđf71({*kRgZ,%9 -:66\kIg BWKDpqGpGpGpGpGD'R:X{33?Od+K]\ r q+9/EP8tE"[B[:vco uڙ+>]GpGpGpGpG@yd8HG <;#;ƪM1\ꧮ@XԯTYUsӇT!tSy ʕB"M¤ؠť3Dz:85##8#8#8#8#8X(ғ#ipo.'i>Eߛa2+*@DҪ6c"zufF'=1Qʏe(2~38#8#8#8#8#P;V /1N}V:v\`aWU>hP%@ MQ:ez1On;ژ}8#8#8#8#TpmID}:; GĹ*(RJZWv< ´igcE O(>TWD6|(胃U?QO5m/VIqK9,f̆:XjfЦJ.4?|hoS0, זA#7߄7x#%3'|f֭[ofĢwޡm۶^ C ÇzQguV;vl\sͼ{p=;,/+1=#3RGh#SLI[RG.ni.SemysR69PG\-h`8ϝ{-:֢ }:\O 4V%c1NWϓhĜ'4uGVVYF_yH\)s=w?@^s5`>ꨣΐ-;wNy뭷FBuY'ҹ6YV?8qਡþH5f_~~T:up:-}(Nm}-Ww5}iҤIhѢEhٲesڿKG O$rk]7#FEż^y>~_M . W^ye:ujK j}?O#1:~OS6*-5W=ߚtP_kyg}6\{xwC=4x>\auw}77Bo:̙IOݓM4)bG +dBN&A :q+*l3N"[ʢR 1$uJѯU#K)bY ԉ[3;ҼM†>ֱ"XJg%.GD6}IWhLm;kȑaذaop'.T3f}Y?c7~AO\\`2{RC!/f SL79~St9ve]A<.T- _Hզ7.|wN|! (?0. @trݸqP2߄OP<&:mޢ6D=9 ׸y}Mjky\SMetMq"I syem3dseuX9sb>kduOUSTP+#<';W;qhn A?%~)5U)aad] qkոB:;N/}l;mR@` ɋK ̘zcPie;""|S)jq芨Qd 7 ?b}74G~ 'H9>n|ZkN;еk $t={,FBBr-G}N9H.K/r[+2O;S`2dHA5gv"yM~Oģ`nfbF~?FbU)*_a>40 p>"I[%![oo?%r_%ȉ2N?7XACM9CO=oZzxὄz뮻.wGV[ÓO>e<ޛ/< "yyQUv}oO<?}a=DC^Fw7E]|~{)syG/ƴ7?-$3_twg_>?Fx~ ?U>}x㽑o=L0!l6sa#^i$y WhAxB!ow}1*|?6s5{?q^f-;w-ȽZkϟ"J7xco8ߚ;nּWױcGu{t@{ !C 7d$?UWſK.$_~a]wO^;]w?+i|Vя~?{|i.>ϧqa),>NpBBD.W| w&`rfɾ@!# Yx\Qq\]Q\@@*"(ld'd2_yNLLLwO}szN{0z0CC5x衇;q a1"!'KPE4{Od&]A9ho<(Dqe]fzj?񟸄-qEB"'"Nvg=xKt#JrIS.WKzro6H +(0\at`qQFp"JSCe0ˏ<"N-|^<F OpqXvm9,Lh D M7xXvFM_b*[fr3@x9 䇄=~>d :K3 *V0aIZ@rr!BETcMft '+ Y a0qBٳ:a = &Lܨ;O)B+ҟ{HDGO; &r!DPb@ xxC߀ -M4) 4YHmMdHc0&P@&DEoB _q/6»0CUS,̙<ԃ! pĖF8aˆ=-[q_ÖU3K+0>H@@LHz2.=B߻>hJw t三/ D0$ H=wM>+Ř OlzL>E#DsL?O<@EB{D>cƌ 7pBK.&(8ܿk svm_"K'2^<=|_` /8 _"KF gѵZ.q GnxV; )/?Yۥ,贚%^\\fа ߘhq3$K.eŊVMk_ZTP^- #a¬A(#H+{pGXJ5&PܬHY& 1{M7uΉMh`l)P"oD .a]驿aIߡ/^LVײ0^Lz"@3҃A1q>!k{"a}7cX>ȧs yHƪ#pd* +lrƸ3V`hi39^O3_Bb͍٥ud-}}1gQD{!u|!<C_v61bLF8I1!m!poGKx~/X:B`Sa^jժvKq/f>mzx7jmR0' gI􈃃) o)=ŶOD_]twɃ`[ "ڇHhi`5ZaUxq!s c#\xFIG/\>u :݃H82줭СqcSmHW\~W~F8'%A OU{ܳ 57ၚj`}w2y}1M?eE5;ytJ<|~/}Gb.r <ҝDnO9npGx`1A9^D +@V@B+ӃV$s_5u<`< h.+‚h!qf `^{^΃DH>O?^Ly'_$ x_eI]2d"dHٳgkҤLcXdn䘇ul9eG}HºY >@߲j N}KOޣA1c.!05nI_g?~!~Ǣ[%c]pA /FbGǺ@~2ln;P9d7߼_2`42XO? c<>9Hc a xI$wdo?[o^#]%48FqAHKN0\J\oI~.ÏE8qqJîD<Wm˅.FTa≣\y݅m!їmtCzخ}?\Gs!9yt\+Ĕg:g(#l)60w) jTw=@To!ZyXp,2T +f!hEaP^>пЉGEFPa$e/sO=x LD;"1:+ f9m,{4ck6oP+'@>! c{Mbc=x` wEx- 7xyg ˜{"Ĭa\WABВ1}_> , o?.WGDp?fB>O[\%Xƃ G!ҏǍ=œ/^F9'~9Y%#ɏV\G\8^%h 񐿑: ¤E/CGV2b^z0pO S<^0@i'!yo Eq},!49c#y[_6HH#l8c"xqΙ_Kz1HʇTV;(ǻb1MxXνs# MCG:˜UCx^-_8sMyX̼~ "&D)- W8El/[sD"_MGه>D?p!.;ODD?>MO?B2סbaMx|AE c$C;fVixy$C=<+=d=7)G] 8Lm/e(rs70zēWqp#%]Oʧl#}bJ1\*+ 5(T8H-t sѧqK0񽕯|uXDҁ;1) 2LpX+wOnt;ڮ 9Y~ԂHt+2B- G Y9J3Q,&x#gr6DXoVP0~G<%7=n~|G-vaq%!n Z"-=1$]6՛` ҕv2xMD0qAuc+y Fڙ#DiC0 iwÅm]jGٳzc Q+py %P7A09?OE7 XCZ ECۨD RW< /C4&^9cƌED8,w#r􊋋~ \= D~ cHa=`bM},7҆g>Ճo[oAP=0; qB)xYP*,/ 7Gعçh&?xIՓ]S ^"??HTXV̩h.ke72_eĜ㯴Eeʦ)^hc2ȕn؍NcEpgjnar1 @~.?\?Q)#|]PMБQ #bh`F*8ᒟt!?EF%ؐW!őW`'W]uYa˟5vvmF00c$)LugSwVu-kJ>:ZlfJV%1冀@2h!7BJM)],QͻC f$AMa=+Ne0D',`|X!}59O~[?=Isӽ=գ4ɱQ)Y8k`>c(z7Vn1YoyN!kzmU,|EAMU b0%oJ_eF{ҁ/%\lN]0ԛP"0UDiaң Pq%~>aD'(  $L Dg`B jDKpUg`'[]o0- 1w@ ~MYp@c("/u}Wov F8=ms<T@\ɑw,ffds#J1@mO#灱t}|z 'pk+|Uz)qA\%NvǞl_\ʇLď>:IU'7 D%I=*FGSYtItEPb7S>Ҍ <+ u2,>Ct&CH:6/%la tXįDl4sd+)+uhD-4<@P1/3:X Gͷ#7LfϞKyLl<LF &LS0fʃgsĊG`p/)VPy>g#&Y 7`,v3p$ GԬpF$]qOvB&&rEbbW0B. GdGԏ0b?n|$ҍlLy%0/g U<HٳgќY7js$,.0/Ea%09_,Uo'mƐ 8P+E8Fb|p~ 9v--J}y u89D?^688:sbq$^2/iط#*`sx<!)hvwz$DNw{XvwWX!3?B炷OEp!$M.vbxoO/B[ST .A:Swޠ`!M& j $"qaʃ>;1&X~wDKg./`$.o8ιY.8,*S"|cc!|;м3g+:.߹\Jq"<G#x<G#x[vgk d8F_/!|J_(ydžJU|c=*~U߰V\"cN$Kvh BWje0/@⥫xOuOEo$a˖o.Vqj:<8yBX@[dpevz<G#x<G#82]pZq 1,5 .aW|*J#]5Jď+Y㏦ݘ1ؠ`BE j(T9ti}j$MqYpSΛ`eU3c[H8'3U^<G#x<G#xR -몕8MKxLŠw /Y,~=aS(aKVϊ ²|SaD*~{ԓ*S s)7\Y *JƯ|M*Ȱ0`31<@zG#x<G#x< u<$(KX<(~\"ɫ0~qJ',WtpqlE?6eCI*GT*B(TʅIg*p+#x<G#x<G#DE< 4}T Z B"iNJůJ9o7Sezx<G#x<G#x<1p/# Nc ʼnL&(GݓDBԊ%,B: B~)q*4.N>ؔ>0O#x<G#x<G#D2IZqũףCˀHZ\qAaҖtJǏ>. WZ~9cC7ux<G#x<G#x<@N|f ϪQ'%!Zͫԕ.v!EAC%.A؍/^<G#x<G#x<@Tx>]Ɔ*_1Dm"!^{W]q!l)W@9o"zIC})?aՅU>e]~gryx<G#x<G#x<Q=?:SCROG뼱xD*l4~JA܅v!=&#|2ؼx<G#x<G#x<q ūqPnTʏib=i@s{h]ZvnKleSL~l>|9htQ0gYg},{$t!eҪVR垦sڤvC!<* .{v5evə=_/3m`AmV\nY]7$QhiXBMszwm,b?|G Os?u8oؿ$ UqB_3lt WU^ճCqT ji"n7!'—4M) ЅE IȎ<ή}}7ۘeWdd.>0#a\"ï.q#>]Gĕ*|JS/"XTKz6HsFĥ E +颻uhGWvDFDBWG.#΋G#Rzح:Jd@I(Vn /]{v[-߮q{t;fV<i@cVv4 nDHa;&Gqӳ'_KOiL;yfq(# ]#^qaEF7!|uWMG_ıaՃ02WK^ء1%2TqҸHC*4IW%A>",!.1a}\^q(xxb"Pd5>Y^lС$z%;ɔ\DvUk?vg]|Qw.8Z>\*k+7=֞;t$^pv{n{@"PSܚwiE *Λ | +ض9Sያ]w?_/|f:>xs30_Y\: ^aNΞ,#]KG.{ɇ-ʏ_]TwuǶGx~MFq2KG _g/ c#\.?˧nUq;v)niiip͚5+8{˖-hs+lնw̏ &O(Cʠ^$&8Əo;wLeo#0t-zʚ淪SagjԿSx[_X\fL|6O NjK/8̽8dմVA^hkwui2{멯.;۝Ww}sxRʚ [UWE͔R¼3҆!mf# Wζӎ9“]Tcﱢeq xuNqG#lo˷xܕE.=.tgdb'Yw-* 8E2?7}tYcK:.-u3%۲'Xppą'lbO67*1*4 eª0BïKh(qWwQl^t|v&"uVYMg v V{x{dZ;Cwg9deZ#tZǬ^wC 9@d^v{ƙSd:khH^B!M/a::p\))=?BXAp%ST@L U)TPzKW"(}$*_ A/嫜Z foMMM.++ HYЃ&3f̰#F /` v'wm - [ھzU@mmWzoKf+뿵uJ<)Aa,{kP)YaUF#xܳ::3~:{q"{i <8&YiBdN'bktD@:!P{UN+F@V -;G;C,IvQ?䎖l(G)'Sy AX E<`5rIS^(^6q%I=.L<*|".wa<`999* {;v0VB#7ohp뭷IwutM1g `%KloۦNjv=ؓO>7n\yҥo}X]y .Ae]fW\qEpË/hb7oVXXh_~yγ6۸qcwH7ZʻgyN̒Lj܊{'w{2q\f}a5@cs߱u^g6}%5-v3)¹.>>w٘Q#]@J"bkJVڞ李\u#ͪRW*Q:)iZmO@ ?2}C GNM˶J[Zaے6X [Vҿ/vᅲ?p~*>a]w} {w?O< ɋ7VCfgg_ _)S-b/rP^>9䐀=cU͜9~a[fAN6 ?O~;T7<;vlP>g#vmJٳg#v8wϽ?O_hyn(Z™28@?رe]U#Rte]j{~sVֺc߹)UT#.HvUw[ZhͭxR H5WOYYK>"8kms{Tt[_Z!djk}*+ֹ6M<ŧUٍ-mҍocߺVRun|Z"+W1c8Y%+'7h.T7RiD. fM.Ip#=Wi#*W6U\t.(, 5X!xyGs42: +}y %+Ƭ̅~獳%Jf08sβW_}5Hf/C,?cپMMMq|%GigqF|Yկ~5Ѓ|A~}A+Xjy6CuTG:LVbwxz쑙T߮4E{宊۴g5ei[{_-7NPn#0V촵{VXkVsf6C]ˏge2'~"ۂv{/^z?O8sm{]ˮt/}1YS|k^嗹{^3r;"So8J1>!|+yQrĆWqbIO:i1%2X 7ZqTXW6GHr6(&=T}\.6(  ~_d0gsaHX(޺uk` 6 V"9{|rknv.ۃ]tEK<)pBFw0ɹ\@ 9 Y*t` GR  #Y]csfy8L\[؛n>Sﰑ#ܛx[cU6B:g}>|KuGom13s{@sKU6--u^^k7=Ho|f7Kd:{lmD0Mqd:hj`xy͍W13POFYnN |$\ckR~V.,80!K\u ;zu&U'Q^ªp1ܛPƪr!rH\l]*KXC?s@GD/a@y8h0aDu^rb\vΜ993|t@r^z͝cƌ |x衇[|&H8xKlԨQ؎`0GGpq1ub22Νks[~q -X Xܝ=E|y緬3HKد?.Yi"_tE#!8~ud1 iVج/^q]VTԋG`pv6m^mYf N/ގ>x +l8˾t6vdaW/S`ٲ/Zy{asVmi^=TPd͍)St5%vʧnkfϲoʧMnMjAHxN3<O%AºtV>q#WJYL Uhnme=8w`pd W!ؽVbmY ȟnխ'T9&Om[3Hz?<-XnM230)>?0銾DO8O Β4?+"{Y|?AE1En0"¨0Lģ#]& 't]% ;4?yX<W_޽F&~,–8/[{&.}m\75<D`Î5vCZiM eVwguo]r;~@bZ6VklCLN7|xiFۍ>Ǿv%3&H>#:ݮe[^]Qs٬Ɵ9Ey=}d@_S>C[q[?Q<(m?ml2hw/v?nxx[lvTXXt$-lnS?c{ ߇O;KV˻%/():uh IB)ř^5;M_܄4 @ӉofO~=ڸ/|bJH`H^dUIcK8|`/de e[Y_p^, p7V9n°xX}~ ϚA۹rvOYMgP|S %mE7 }҇^!U{Kz^vlG渳Mq'S1Z&"mvV~c?ʘH:U*uߣШx=]sWB u!?/uGSl0\j0:=OG ]p+w Xt  m|Ҧ[`$:ZݖVҰ aL&mimx=O{yUc#w{GE^ܰȶ֯wq9Mn[ MPZ Pޥ2wTɛdYgӇپ? wc<= P]Wiױeo/sd%iHagsv~b8ܲ5ڼ5O[U[߾v)/\./%~W\l%hW7;Bf3/HiK6첋t=:d㨷8ϾaS64v,Q??Rd/AZS>T&i\TtǦ!}Ixx =/[oMlaYfci 5%v-V];mE@P!#XZex=ʌhoDr(u} [ZK]IޙŔK_؈w}#Vl[jk.|ۖ{ِ#__8_Bym]g?Q\_Q|& 3\~LU ]m\b"DЊK:T +ғtIyT>^<4Cdem`vx~ߡk}~V)lu֞=|B(i=K]o,3X_Vy:5 ʌvչ}`[M?f?~tr>lwcg 6cr;?n8Z/c"'ukK\,"iqň&V:~q\Z켁/weG#.n|wu2MV]`m` k/-0plwvX bRw>:7a3ů އy̘`3V{a}2t>y>Je=>w러/@w_G?xp='%\XKX&>|`:)kB2鋎 `~#HvFU}uݵ)l8t^zC'[h a|KiR0774g7Y&t3tbݜz~_#ac߾?Iw ^p#}/2xY_PHvz,Z$n|kW M@{f ` &^ZzoCbhq$Oh=VؒXZ Ϳ4 #|pD>P^Mp3bImg9C:7or}R=O/ 5u* .Q#n\Ӄ*zR8Z-*@4~JAx:†l\``HmlwiUT]āu1c5u ]x˛[㭏|oge̗Io{~WT&}>us",^#g ei^zg[[auk(բGlwj@O^|VQ5_ŧqJzg&oc)QD, KAa;pG~\œ..q%UW]S"gmTqUo雭cJHC['hhimoE랳4uT` -OԶ;WL_:܋cuUۈ$׼?K1>¾8J Zrl=Q\*g5bH.h\o")@x VǥB+x?l}X8o QYT#H):ښblds}JyzqdrgwW-LN֔TͶݞI©glގ]zK9K?ض.؎rO6ͱF֫z겎㻘 ^kw {\t#E{PVW*_:B}غlC:(9aQ\r!Gfʮ3b]Q%28\qV(P6 ʣp;ʏ.6򣇐k VZ+j_e=|oN8y3-:Lk`Jzrp02X=I|Gp ~^wYn"O{G- ̊9_+-|]ƝS;kwGx<֖ۊ]b3,") Rªѭ.Sp}.4Kw"'%.Ώ_+ (1L!tH_.})_v mVVо5.hk򭣠62!:LhPaWe;6gV&g[YeYV:r&*^@Z]vgةij85JR=GMgi:^wx;bXvh:a?iO4z\JBEju0~EwC袣y)L<'}'a߂쩬W]u㕕 $SvpOGs¢ET5Sz+l] 6l9r[[CmmxwuNlYj9qn-wH-iE#,مE5btP嚆&kpQ&wfm}cu}IQavۖji/N=| d/^ َt\)p*/ܜ\u"N09Y9{o&z>s͚ZZͪկeAKoJ*j}/\co 7F]uv#m(3qh{oV7F䏴q2)5ӂ%}} zC@cK=y#Pizh+4̎kWq_rlXS,Ǒ931~%gyG_>^",-mV̛͝VySmtνuV8n ƙ+Be׸] Kt:?8ѰEW#= 'sʆC8 # đSPM!e8U;>T ""/.B~L#]ʉFS&z92QO;$ tHů+ LHe~F6>5QKenPc͎eǝjEǝfEc&&{yV{iV[qزVmK7 #?>%xӃ+_]}`*ew87F9"fDY4FY=Y]+6z`vW U|<*dڦWۼe&-nEgkFǒYԱmL8 7jB)5ef.{~V[6[c{`ͧɮAgO?v}]oNō@kuG1 G\w;X=^gǞjSfXg'6 ~Za\FU}Tڪ-;ŵ%ia;v+?8KbA`L]3U}7<)Q:.ielb+e>0a]]W<W\5%D.'#C ),=C?`2XI` ,w8ed#_V$ cNϱϰ1ǞklͶp{Mn5_j <ۮcOh_yD`ՖeVڴ:MX]h#Fѓl˜lw,署ΖjKn H4޺ڠ.ԯ\y}Cos5*\`,߼ߪ\Gܱ6iB;VdXazFSaW .`/oivVڶa /g C5w6E=b'5̑/=.-{3`V8L 1|hX^u-ZnJlWe5"^wg۷?n#ȒtrEWX:3S%ygp^=d.~A;r7ㆅ|%!X}{vJӫ6 NܱZݑx +onQ}O/%(d=69_O_9;s8u p 2Іe'ryNA$K~O><򣋟K:p3UHlsÊ%D(C\@,;TxGc 'q.c eyIb;ܯ /D`;_*nV^a{ -rKWWnOVc%*[i9ۯs@rW~u4XݹWQD/s/$eKCs^6+s[k.J/o`{[_:ddudđۡMQc']jܞY6gfȪ;?]s3նyngӧhp̨6eT6iz/| %vۃϼh_^ڴ۝Qo)F_; GS[_&#̪FUͥoɗZVΘ̥{'۟,ʻz%`!|*bH:22W+Xȏq҅8qt+N[G"/F>ܘ6.XFU*>8*x\Hl&H`t_tHS^Ҕy?1D,^DF~\Ij~|\ ¤02 n+w~hgwVZvG6iٛizgit/W `˷ -l[eg4:+jm=[cDZO[y6 >HwԩXkp=puպIeBb95 %vX}+S3mI/)iLWz-+lj_f{58g<>i{ vڄaS-7چ>N_ƈ*;V7+,k}医FO}e-CZX%v3ز ~O^co>mQiGE :npoą c#=ܰNlra}&ICXvBo*C<_>y麨^AQ^}DG4aꄟ =5wW_޽{%Aā7GNې*7ٗ!̑Lw7ZY~B֧{7!yҙoͳγq)yW[2zksRJmoo3liH:֜z%ά,+.ɣ3%މ~yc!a;Ul1y=OQSN*zD P^e;x{f1~Ҕ=f|<~R7V ?H_eK7ecd ~YXH輭"PYWaKw,t 4JzȌ6*蚖 l៲Gƕ'J .W6̒n>g&O̘1~kE7rR.LCJH#t}؂$MyApPiđ!B]~ = !"@ #XǏa \ti .pע|4.*4'm{G){28+JȈvp2..CRk'띹yr;l>k#'vrԉ[,ϭ~Uu D"83gMPlM,̢S,^󇞵,XYim}6ȓ5ktg'lg:(SŲ$ز"nmL1 6$/!ԄZB j 1n-۲N7y-ߝݹyjڛ޼]wMIuLG'w/(/c8%'ti|ҩbj+@y o~bKxZQs<Pь}F8Z۪Z9~%¢wT]@|j=m[Du=f}~0)/x&Cz~cCC~xh8$hIԃhCDV3_IuY;2+Yh`(RiTI1"K2r̓_j,(,beƽOʐbX z7boVIleQ'J`knnߏ]:x:LڀG22YDY? (CRC}:B~(;%(X)!l(e6Vd@ybyH CX&R~E0@#Fx vitui2@m۶4oo."7o%$$Ν;=yX,> FO6=wCBfMX)dD!]C!Ro% d0t/jE ý)jrS(g)+)"!ɭnĔOGMBޣmy[/-F 1۩57GFPGɑ_ht̑t ['y9#[^(**̙c筭 ݊Bʘlowotwiwzg?z믧>е^vxb뮻̴iӴ1=ccO~W|_O:TIF!wH!FRϵk6}xEp'|#zHqF6QMad7^%y(_ϛBam Q 6ƛ{\-S_Oְ@8'!32 8ftzyѴ;+O%j[In؏x-yyֺ *8@8EJӇFzfv+uPlzk[/!%w{^^臖?]jI7js8o G)#r(Mo7\# ,a;#xD`k+c~Qܙm@ ?@0S Ų:je|2v^<ow_8MOO&l6(j&%Q髯4w\-ė_~IK.V#qGю;h̙ԧO{gnV*++eS.孷ޢrNV?ҥ^J={Zy֬YZCjv^Uzk22Z/"ul}P )mxv=bӵ}1|&w/D(E2x`TR˚Bcs'Rdf]9ѹY6uG-շXv}7m7V4RK3OiqD΢RMx'o&E裥ke5/(ڸo5YE`43 JOS_Pv\N1=r/^lg(~y?=y{y="?j7c bm%'y3(h +`GNЗ B;2)r_A;_dಞ}:ӏn@T=9;ȊX ~ݫݲe -))^xAh_n:z7UX 1P766SNlMvڥOn<ڦt @blB7c M#@M]5gPJB[UvzOz_ы7G)BVm'L+ć*߿f;1 i ~q").ֿG11-+\@=|ǒ??kUk ꛗM^3Ac84`xQ'TKDMnlz?{䕹Y{iiѠJF>t&ž0wב zXg+=L;J6{G6X*B[K_E^IF7벍X)B,ⱷ /8]?wGOgLթy;@. E2ڐzUZ;EBBڐr@3p:R'/Y2x,:b-a#EqQXon/;El^{Mi!233OV Ջ2iԩ4qD—7oެe#^,Φz>SꫵÓ&MrƮy` }1 _)d8j}=3䗗Q7+V3}D9%>8W~1dd;REl*nzn:{ H7Fc_}Uia:#5P-.M KN$]/Nֿ7}SGr{D^o_vմʰaT6_a}'3Ϧ S\z`\Zo9' WW-s9N]lؿJB2bд(:5WUU_*@KE.=$ڥKԊbGCGvɵ]ጚg[K(2R܀6젟?Uf~cE=Ks: `v#Eꙗx!)1 A4@ +`>z0 2dr;x`~] !xMd5~Lj#~s>Nz*ۃƍi͚5ܺ:kk+Iq8"ŽxPgt:t{/.84LHye(;J_D}b*貟hB)#w 2FߋҞ13i bdT]΃PÞ.7c\h"˝LQfW:;@mk]pBw\<_pV{*1^e'?v;Xnqx?5RߌoBez~\zg҃Wt}cڴs{Y"DHfX2‰Yw` mю2#~8`h΃(^,OwW7b6ӽ-Vk\n9=(gokq;:i֪W1^ PF@'Nu80V~u[IDE@M>|M)to *6{F(S&c<-oK:uT?zqr/K ^qGJSmX # q>/F@1}UV#a/m,ռ+~udu?=@{a9~1[UV##v=dͮ1(PTֹ_n>cKYnͧ|Nsю#z? 3 l+y /@[Q"k@/~ԁЏgVپU Jh-~qG}鎀cI.MN)g_u4èX%+SfU~*qD[NgVd!u$@P'`VNQ, 0rp@<88`M@=PSbv_%4S" ~Eq>֤4Kd$z +jo.rձ%TKUһ#5F>I4~#rh}5b7{Ƕzgm{<XcI#H /9bUŹi`f:ȵdw}bMabBitXMWqFEK_I3V(7ta݀S{tf⟰("3.@(Y JB^xpm3؋ļHQǼ-je"/x*VN-E,MUy联xZ|J3_V{x~;X%a98':Ojz?)eKmgX[FêwH+3FуLT_Gm3͢rH,'JFJo*^h#@R\4{|x'}1(&SV71@'&S\y#` ^(j1!Yj> mP䁺]e{Vq˰z{ώ]:AiP,z!5TӫF+*cO)œRwl0?=3)>KoK K5PB6?L;s7AHAe7ԴRET oQ]/*wR⣥6w>/Oa DC{9SVyaSߴD"xK\@Yn;UZC87:z&עDqbE^N6VmG??PA a*N׃٪ۮa}zmS M6zeNj=f៌.AWx!Pfpm̏X:<}Pf?e^jóA^&~R.x fQzץ)y>%Pi}2Rם#-ΌXr[56[C\^}WWfL^_YR~yZjnGGa}zUނIChLlT< ׾XOu&EXmdW5=y)+#(s :"J`kJMnb=^% o4 n UfP}X?@g>cQB=; }XjyHy@y(\IQ]nC&x/R1?a^p" .e6\h*Uӊt׫{BTtӤӡjlV)lk_Tʘ&R'cLv2`lgXE\}g rgQ22d|{_ ^S<,%x8߈;cnIn<4.gB>ZĢ#҆:BF+E3pY7-Q-iO W2eRc"dE"94WDr o. jl^;8 ;jiɮjzj PqG y'Ӕ򅣩mr_<ťb$)ЎkI B(X0`pGNffZZV9 Q&y ܲ$ͮZS\\L5h=0|@hP){s#)3([M)3KK1!ٳK/.6LJ|f M~fj,B)ә".a"GLNtdzݧkwRIUv`@}Xq6R0jaZ"zRB|/\[Z@rB,]3G*!b["d<qZN6~ndFWL f`np6#}8,l,w4q?Nr١}@ Ǐ{hҥTSSCz*Tww+)tu-"3B3DWْg)1XRa)Ē URpzTJMqjngvI#Y(m JRTolD3NLy3(!&4uU`ZKm:bNz97j/XkiUBV/9m~8XG wG#O=`f :i֪y 1oЗ B;2)r_A;_d5zL?E} <>_ń 驧l٢oHIIGy^x^?y<-'xB[i eՠI&ie?;곲^O>^~e6mG}h<_p!%&&RTT9s֦+)U>ڋgQ#dҬ}=cZڼBGqe!5'\.(1:+Z3$X,_ҁBP#.1sS;lf){$@X{LxY}^3Ƭrʯ2Q@[QNVK;ègDEGů=)V쓤[DSR]O ^uD԰LOGOgaoGuN0P9̃:p![`{;hȣ"1Ћ<asW?x;%W@/w:?#1+#hݺuZ 8맅;w. >^uZl]yԿ $lh޼yL(x:P)85SG0;]*ܸ8BOGbccս sV#gAVU[A_pv9~![AHQHGCCg}Azڪa4Z}SbOK$d$;Wi5>ؘ9F!Hб՜rf 2GKUHgm/4mWc@y}\6<0~@zB~77ٚib;S<<=R_8?=.Z 56h57B+&-\v?SW4*3 DUWn2v22pH~A;>c|DFg^)^}PO:G)W9: }O>&Fᡝ>;Ic2DDe3{ F3#j*D"4?*W&-~KN-=fǡRj}G충U"^*C6=E/V)x⁳'(OwR:ZVs=` ]4+ܹS\Ba (rM y}uSX_&L-={عwm#ջ|[oB6`e.6+))VG}ݻG6C/}] "| ?9r/ƻw^J7x֮]Kyyy+6n8"t+ nԖmk*sBL٤ \+>{9l= tgP9M؍O~r;L:zHe2:\tlATؘ]T|M tp偛Rl>O:379dMz|MO'V`zԡZn!-ce e0Nc#~CYҗaAB7yzǵոX 0#!ă^n@8 9sp֞$z̄ ,6x…ꫯJ @H٤ /7u}TFuX*{0R%`6ÂuM?R(xg>H-mzw|S GX()`=pQlD[Ђsg6 ¸<*_Lyc %,D ioFiny`pPop Ohg q/G܎Gߨ#HM78@s6}?1`hG["j<]BBbP# ^ngYgG]1@B0 }XvB빎u dG_QQvO.yGgMՇ&L5MRX7ytZ1p"Jk*5 O6N{lþtf|1eF8|Z ||Sl-GȄ{o.2P{N=Fť<SGhN[ ULx SgÜ2_x.k- A]|,a|"~+RPp[4Ťbb5/B1鳍S4fͦNq"6hnvOJKKXj;6R?WDڇ?vFOEM*?ꐖP(Wl4,Fʡ46٨"=&3.d{_\<~dQ(-1jE ~ҘA}d0ǧ6WPD`061>=A&/я yc n2ڸu(]\/;`xexR ļAg.`D_N4A_yƎppN/-nb9Қ*{LIu5J /XOOP|,7]0X,Y+69v/ۙL=$&{gLGAmHY;VϼhGPfWy Έp2By6=X = B\" _C5,=&g"IzW 4CG `"BdȵA,Qvt#r3 {xcuwxrTG`lCc|: DR'\T4k'&#G?F mr (C8F 2<8uap!,x!>h~QL`Lj"y=fb1!QG8+ Of2e}ħPb%_٨+}#F= ϶WPA_4=h ʀPDfL?Vo$ݠu)(cODn!4 ]}ys .l/xu'W|1G= ^#9r9Hq>G)@jm,v!1@백 A@g6@|Ѥ9B;X'긌6^+R 3šqV4,vv(#]\($*E)ĕn6nKE5*@[SE+r^@^^^}QGˍ|V{*! 2QHyHw48BT6#`K rWDNpi072>2ME<D:\:=x%꘸?&CmIY?4eN`8C<`<9~YVw"i< ,͡ MUX/ Zbbz9<ͭg#5+%cNlP5^@:T` 0*b@IDAT*o/PR=FxVJIP?:^#Q{ F\T2XǙjna[t <o p,F]11Zq<<@j^h)a}fHqp d yX6# 8*j`|Y(R0brb'-^z]we7P-2a/dL~P?s&-d1S,(;$ERY}k{MV*֓U7&RuHy*l1_#_aojC"lun`NT3FyĺD1 ^^>;#60p CA#e~䙏eq;q@08 e HӯvmRd2Ћ[˷m WG8%xY,I*Α-D|V\Ja{1ٙ!BX Y0aϹNQ laaK#K27u-,>Jp^"Uʎ@@\L *p,b 6WcD# NW08JfbqEW\aJǶɎy]C6%h@eX3:FA.xP>YMX&e2܏yQf^nCD ֜qjW+ 0_C*VM5ɵ-Wiqjٕ׃*ϋ'5\||;o{,1-e^IS`L$ldiM*Q<`aY(;ID=lBX[`WlQ!=lc^4 d;aCr @=< G9HEG/ʎAMh-,sݰѨ?u'.U-ߞ|[`qj@a X|H-܍#[\;7x)(=KԒd/|&\@MD<}w%`cr5IBgV208-!CTH/2S٠Ep25HB-5^g@>8 /A`)ǶJ8?Ke./]fv\<02p >LG l0Ad,fȣꐺ֯V )2QrV#+R6ja3 nΔM:j2'˽k<])qzG)08W==-"g dBqU2!<-bS/ o&HR1ɽ}<%zM RAnkϢJ=`ڊ`Էp|>ѭr}.PwT{D! /kQ[χB<"6xsnGj)sCro CQj7.K Ĉ d!Րl+g&Yڲ@#A i3˃g73Ӭ$;D;phpJ1ܒ/R_EV눿mDʜ*aQ4y `! \ =h;.<"vvj}a^?۠ъU ˒`=<s^-l-jeW@\\}rcmƻ^&dG3vbo._Cڛ j !镨M|ںX^h (4dv_;B;eB킡,b@/G=@= e0#2X?w_ U*p2itAnjv ULx`xe(iL*[y60(-F{ &RO(*n q$D)S1AL@:bJv'fSW=fٰI+ B[@μ}V<-*k)'Y%3+ @qb(x7Sq_ze >:Ya臱0Ҷj9 E>.QAۖ(aR`&-]R%Q+e9kl`Z܂{D`NG@"'חq9EE3͒Vez@`>0su+5J?mCc}<.3;̡o4!(1&Ojpfl >@̋zRg\C70OQh'sToCJ6E(2RqaβOLPXX?(R0k; * nma X8$qwLUHl`p1TNyned5vҭ V@䨌O</Yjd ^8J =ٞij=kjfh .Zp2D&QUCA1f['pTG+vH̄ S82a ٨cv)xpprAe~N9ر}ȺGchl直G* ?)K3U5PϘL~9w@-=TA5ݜxKNW]]+2yU054  ituxJ@3]V&5^;7pU(tHۥ^ail"fA$0Lc)2}ƍQ 0C`Ÿxlpt*nDJ K~KJ1/ o}SH]$˞K1Δ7kb6əɞ `FmiuI3(~aE z =pDS`5=rhkC; JIMO& Ր , [ZN=`D+8v!1V{)M~ ĽKE~Ú%pGK M`F㟌^QAXf+:ȀRq  ?xa,!vY@/ۈ@;UI# =l49`:]Vj>~`zD65Z)9*?^mXy iRf=}SYΤߌˡ~8ϷQv|J⁷˩Z]UXeo<Σtnx+6oR훝~7ɡ0J=$3t)my6j1&нSPoR3J˱=V"4-'#w< K5^(8@dhq  O` BC1 fJ2-xƗ6,pz^J~1,ehnD%b۰0 =G)2Lt_p#d|=uhG0a#E;/tC @ @x%.W6Jyvl4c9̋2y؇2; G2Dݳ#ďU\M"@=Ś!z 6Po엾}S`|_ FՀ[wx`^x_ =wP8 P9cX|GʡY4C<>8y&{|DhU#I`)bEmFOmȧ7"]|8KuFݣk'Qxxbh& =(qޚ~+^g!`_O3{h xki aZ)m`jgEet"@3wݲl'}G=g|+\އ9`9b;=+Y-孇5{9ȯzA EGV{Zk+UuܧHy3Ύ@0@KgPsgyqS^MY*"M_*Ծ,t ۾1 z˲".p9}_9W_@(M遲eR{ۏ6z4K si8)W9VZ_TMwOPz{ `nd"6/:wgV߳b77E1tF +AÁϊ5TRD]ks%OCxcD{&n|?`P/m%hWtոC}7֮զVwo0)ޔSeX85K ! F|6i t08VJ߇'_Xy>[=JzzF5Pl$0 Lኔ|2ֶ.gz?j^clXQ'tu_5cq  J)as!/@Hbyz~=m2[D7|Ƌwf.e`%/V;IIڪ ?@2P^xgW!@e\X9[Q,6t|x.N~w<߱|/Ћ2 ->NV–b2@_ MfX5^z) ҡEǟ®]oz;PΣkq~nl5A ٤?_.CZ=yQx*jUd+lS]y.yF{??`y5dʻ.$^i]œ=P',0΀BW.dL{ %b'p  @74 *cD>Hv0x Dz|ދ.muk-!i@oYz A@o'(T]| bJIGQ `ٚpæ``v%Fjrt7H^}F,VZ"y^_a8#=Ez7D,ȡzB41f |~߃!6{M;D96!E"' e@ #Շħz*t{_z5rH_`R 9*1:xR~LG`qv,W"pj~lxyz98}v$2*.i1 p 2aUJmwG\gu}/|ܗZ>ۍ8=_&n*+~dd/|u:m$vu8|/QNl&;QVxE<`(ӝz~2o2C.?~l*ex~¿icRLLR #V?F, vɼn\*vlƪAׅ2 6iLA D*sd j =`an`129_{`y[Rxt9Zs8bY8]ĩ+b!N[Bvj}rl{3LQe=^Y=I=Jƒ#uϧ\玲J{N|}U.їE>4PX_xj.@@ɝ3;Y"O]Xar]D[~K. b'?bMa:4Hy< e`{ц:xQ񢨕ѯd  !'AlbðG,AEM?qt'>^? :IU{yj)4E1| קC,Ezw5VяEuYH~,}8RO+HgjgGyc|YK麊*ܣ}3;Q"|#RDd&z$,;6;FU?6*sm6K?@h^^.cJ%Z;أ<8xYY?t[9)tGkQNPX{ S/t~rmu]v"" $T8˘߇9KrUSZDJo)6k=P'=^( ĘHk74ߠ8y,rF,BW큌yaBZwc.?cY"hbc$Q6L\Ğdޣ^j1!OjG5օwP\qjg:;~%Z0]Ka]Т6j˴ȥl@cS3I _7<$|:Ƕۋ:Sx ,(9NeXbn'k)Lgײ\`|`qz3()(j5ZVP2P[2sI-b 0?rQ`Gsv K p4.;y&*MDq}3eHu>(c{RYM4E GFP\2[A TU['1 Ѽ"jl|'E҄a2mOWAX ;JaՏGxQ0|8tcЎ~aG -=p ,E{lZH1Yo9AQm\͵Uvy`˱vs֠@E38>Y⥕-LA3V(+r>gp50$GyxH0^w@?v;av 'nLrPI%DSt4gukVn ~,D!nK3-6?5V<9Kg3EwQ3 Y\L= >zG:`Hy`W-N[s"vlWz =_G(T*W.i"?9RE!r-LE:SͲHxPR4_ 7PH%5]|5K<9"Ewtz2sH{:Э=z>ʘ+Oz%x{cbЕ^bG;^ϣ Աg\ `L J:{h0yEQ ^ 'LGu>A؛үu?=3|ztf<%[q?b"r~G:\X.n8yzd@U]#-rPINt*t„$ (o0@YG<6Jw<䟬/}F9e!\cҳ7=#6~ 860̪C.?7;9k v2 GX,h18ccev xQgXxY?>;_#ܖݤMyZmO5*X끦J/' v_}Nዋ'_֎f*-q|P1"bW\)""(9!{h-"jo e!=UPBz_eQ)biPDTЪyR٣1D~ zNcә⏌WbU'cW1soLIE۰1; Ѥ  >ȁ ͱlYP_(RPfіX\_[u*VLCŃ/{)P\ hlU3>eX5Y#gN*0#5fGAUUqR(+ 遭ٔW*עʩ1(|{G)e읍odLvv5B hjAk0)x~X=H~Աpn~!FEjVyenFc+J4ֶRҭV[rym?$ᓇ%{P0F ZHL&)[ 恺f~KMN~@ RgcdԶі#9}X] z&vS`{=rc2k!`.؃rMGa1(C&x!z0/Izt<`A,߿$5Ve\R(=MfЁjbE`Cm-TR-'xGYbL>߆ͳƧY2#cH!(:y Rb@ʏ2vxGrsKmSU@t3;} e g2~*2 Jc-@[Ηx 2ЋvAC_ bu@?PYAC)(~gnEe0XIvWsG 6eh|tq[ i"1HYb(,ٴW:{+#Aʝ:BJGS'"E7kwQe]=C6FƤz "opR."o%s=hn/,e"\_Ʀ$Ga+OO᧞+꽒E1/ 0L#iDŞQjC6 3m/)(Xo5j)Xp, ~"_.~)㋊jnk e!mUxq$ӁRza$KW9jC*(=7^M'kʹ)*)Ӧ UhNs%QFNq܇q ֋=X?H~'#{/u}[__O*YgРAt]ws=:` g}6tMg p-E]׿v%\BW^yӕkQnn2lad[(^z $z US@G]_{ |Co0%= :XR#!w޽NIII򨦦oN(_|(fB$ﭷJǏךhƌ4|pMMPbbfVzE5\C#G"GM~f:iԨQt ڼy37kw!C&lPf[*쁶6qŀdBaT|Q)RDŖIWeKe5(wlr2\>mW"E) 6zXk,p*)Vz5i/"RIeu@tv)+\vg&?'niM]&+[sp!mgm B6堟X~c1Ћ2 2f~:"uÏ?H'O@aD\RӇկ4͜9Skh8p@\?#""_@24~饗4>O8r- =Cͣn9#FtӦM_|Q; Ɉ~5:33Sj###e̅YynnaÆii.ޢ`^ 8o{&sԩpI3?R@JSW)mSFE%Lt"</o!KsGeaBZ,X/6x?Hpf O C62 Kl8˷rOoO/6JKk*YΤvZHyǫwu_sH?]w$ХY'[Daeأ>yE}z|zЃ> eس>Qx:Ю~R|<d߭vڥ!KRII ͞=СCx߾}_kwO} tȠZz7Ǣh*'$ OZÇZ2"/^L-Ң ʈr֧= DܹS4FǨc)f/RalݺU@9眣CFmz2;DF# ǤI4 /hiثoL#ߵo=GT<XS7A =}NblkwO]/˴k(8*8Z||aq ,rD*3Vv׵Ѣ]"w!Y.Rfͭmb9<:4jtj?x Ňܴ6dc&kt#5"hHB*Y7`\ >0r9BvZ"@p~(b8,]>~A?1c|DFg^ 4' QC λtL\ziDaF| FdO7a)+=N'<} 138L7;Sd #o2ϊt\+J;U]L{G6U kXƚcO<(-& R(0bPh2llN#d07Z4@T->Z_s ^MCn]l@/,rrYȯ(^W/=M6iZoZ~W^yEu{Q<]o#G|Hz>}% \t4@0RHl]f ]wu/_IYܐFp 3]:I5F`o,rk^ =ao&}Zg!Qt1RxM[ 2OM"\ r; rȨ2Ў2Ƴ,ޣ,{P@Nkt饗.BԪ+rٞºS:媏+c NV}\wx<aDՂ !oo`Dodpc~w!HHa @" (/lqyȧ\#!n@ȫw_QBO_}IcTR =>TPCovWQ\@e}tD9=Kb!0yoP^>ؑ٣UjZL羫_,FHyFgkQ2~|utPVy׌I'#AzG^-j9]=Ch:SPU`أž7q1u=?n \ƞyDQk~|u| !~(c(fQJF6\tF2Љ2~Mt`j8>}@0bLOm`"[%w~<:V1'u,L]!s_\A[iU/- - ^5EEY:& _o|:|o?}XAٕ"opu|)~/k7Rkl~#ѵMd؉ \9KS኉#(P|.#eW?l4e=K޷RpEdHvY.pracIt([Za߬ yƻ4sA| 6LMᯢ4Lv@FQ\8AZG<,CT=y6ZrPfYarmяl@HD 5qc(2~NS_i+ZJRHӌSy`oIZr0elU4 "ƥ$:c#(NwښiuFO4PeaFF`"oY*łK'Kn2ؼ}n{Eihrb/5:9{>Y,45CFӔM.@yM=?+\6U1N*_pdp?]Y'^Z0]z,28Na8!9ܚDk!l_Uq3ӱ;io]T`V=b\yDͳKBO C%N}(1b[ h9>*ZyV}gQTWVlبHGֺ VhΖTJ.JƤt/sE+gM+WNEhWi_+gg^~HI` J ]sNNzսz[ᗕB薙3(aZg>.,TUT5EgkwPӼTZCoP"@xh}Fҏn;CZd0*UxNZ[/d|yRWr>[M@%Oߕ&"3 ۀbϘ*h땬Y?`q䤯A[({l (c+ E{[w W;=HMaΏ%>ҮqEQysVϷp/3e#)_·Lqp \QGn7TPQM ^siӑ}*{6͡oEk#ַҀqit'dͰ>LD%E-Q)y,Zs ˝&(nR¸IT8n846 KG i+DҩV ]ou!pgx`P4[{y;k蛽5T݄ۅӊ'iu' Zg#1V,:| 4o:$9"W~}}ћ\>qŇC^ZYH</~-|HICל/wcƋ7泥ŲN@vZ&_<"M)=ڂ?xaU͓510 B G` bDƼأy$籶")(aé1o!DE"/ct"@KkPa UҤ'͍cΐ ,w9ehJVF>@l Z}ˣvё~vǶ}z4ٔ`G4Q'vڥhMr0=~a,u  FX"6's;c@.x@ &~1FO p X(j1 }*(=g2 %eO}5oHeJ,ǐ(ߊ<"Nv1(}~ڇzn󺦂59mMTV-Ns )nr؎3ŗL[r?|yv7LMX"'KL'J4PYe?5M"%|2(m׋~ wi:zvj9SVZŏNzDc<=P c,_\k kpF'e]OfIo0qM[ǞOkxr0/P`/;QS ː~eQV`U<<DOs͊j *тϪYy}hh-ņ/K}ƺO|BrzGS4F1@R څe:xG UyI/}XC]ocgmjm]Ks"s4zp|x y``l=VLJK[n%oP'445{?b~;e(;i.޶fN4DÑl=L_l#O=W?j ɞ'38o =Xͽ-#݅NM9N,Cua{#ڗ!`v*efy2c^y@yI) rbq)'d&g>kD&*U恗Ǎұ{좾-0y Dŏ 3oUj|iQz +9{'6^TZ ةE|VhzeTOs/B犅U}zE{_p4m$H;g\U{xog>\NHuez)$P)]90[G2jzpy=@ b +яGh=?Dz`0,Әe슔偰<[\ A+7]BU[,9+=-ž+6wxJo3{z b(?{@ ʕ:k.:Oڪ"`j}%RA} E<:b̐y4suiTN*gx 5]?n6|8&fɮhhj߾}8 O)[9_D?Nx>FfsHvђ2ly}d#o^,ll|0hX# qkNSW?2u9<(n{F!Ft4৴7 l))#C%E{;2e7۾`_z⳺X8N|+/~8T'Q];ۏ?oV9T'A4ͫowyA?3P/@X\?}@-OPuq=u-W9kwDDRuٰKض׉.S/V|42u 0=6W៌^̽1'un<02pcDF@d6 2lYP_8h̘1Կ(3g]q,+5kvmD?)**!zzO;%,,qS26utj u1GPv{?rBND#Q&d!mbxi(7Ѓ.JWRSO#ͺ"L՞P♽N޽{)== nKK QMM m߾**:,/6L'N[oƏ5%$$Ќ3h<Xtt0c-wڴiZ*6nHݎx;eZlYw^ݛ7oƏ5JmݺJ?0A'޴i #r=seggk^cܸqW[eOLX?:QC>4 {ORGF6͚vQz|loz +U|c#9TրCmhѐ8C&5[,X%hf5:.7Blqo+ǔEfZׂGPXE~KVd۾N4,嵴]\cZ{ko2.R^}=fT)-C^Z{4@(ҏp[0]{+05>>|'a\>gb 6C,G2:E DhC?da B?Q 1el ԅ>P7K,`X c#H:<312X?AE6Y;#2 B-.]J%%%(|RC۷k^Sr 7xj{D):cbb4]H[Xr|M- /^L-^ڶ܆ 4~-ٳ;rNˠ hc"##w[*840lSu8Oxe6ݾ{U.9t#SDx纣*ylW?ZLX*}+{h /”L 6 5/VӲ]-S18-mH7v }/'MD+Waq7MԢf  p"Q[IX^O4q FJ@1䞄t c+++c=G # \{ァ@/XMwq566RX >9vVE &D4#*@R޺2JRx^l-1I)11@ 8^+ņg2".n;w(f<0yD]7&>ړaMYGroNIi`6|>Փvݘd:oJvӬtVfRCt5E>{rʫgQhUBL{`LOxrg3{ ]MD :WWCrw/\)^:񇝴_\#\ϕ2z⭯i"Љ(z #a` `Mr|hXB;de^|4Y?Y?t XQh3Kz26}9iBq# jɅ/߭jUȱ(ZEO/hh 852~6gcY}䒳qm/?YN?>} +<&^|wI/>p5hQ'LQ!A -wWrwRNQYkiSoҷ[ #@b\1 h8)U4&k cb<)aw!{WG9XԤGb=e<}5@Hы {#@5ku]G/21<8pr-;QG"bժU!S? p'Y~ꩧI]ZZjo DEPZ*m:I,jEzV|^xDԒG_y~F=621bOv e/ʙ!7KG>Ve{2Yg-"//D*mswbL=zIsf_=Mt3gV>]7D~`<KiTNOB׍l)?ZInyd<1;{_2OVdM ygh#QZ?c b53Lww3!CG}EXE@XM2eLێl2#O$8x/?]`phN#ssU_~Uwq3k1+vFD8aq vtWZ@ʹN,bNVUsI<]C̗BL@wLA7͚[7Jq=PUHY H~.(3w2lVuz~2Uؙхj2D><ᲽArh4Ldǖc`0x8Z/):<İؔͮ@^X|ƏG[`J6l۩LhØS ]g` c/C~Y(jI_=Z"6 ?g{ Dz<0=xbHcAƞz8}Nʫnpf程Oq\ 9CjX쑏bψz/~6k;zlVazc}tKh;Pzy[\E@8;-Νv8B7^:MN3F^! 8:zND@V @hڰ$Zc$qEUtׇ˨MH{1wx^Hy֚t,_4uh`VB/CV7T4SB裧nKk4ϰWN H /JAh V0m,(D em91_T6acny` Byb؃BCe6ZhGc =~,A{'`2aK`B5sQY!+'C|y0NGSbZ`μrՕisn}|ϥiR{s#ỳcgNIQUrvn8Cݲ2EhgYX.0Ndx'ʢxATEm < LB1ڰ,bX1 xuX /hOX\6K)"iKG4ZC] %DQDq?uKN._ы_y9`<\?st3 fg;81++`qGLJޙ_J;3s(HTiI1/GMir+sn:\ZC^ཀXh tseS鈐gDZ1ӀVd1M;31A,c^σ6E}§ vS׻[gvj<=wE qss^npT0]=6NIqQ kwb؝%vzU9~*yq  & '$vRExѿ}'뛬z_Xl!\vTO))K.H]Avh0vyx*܆~޸j2 :3/xP6 fɚ_xVaPcя:{ԡe /'2E{,X. hO` O(2< F GVRgX3uQZH/TG㾣e] RT\H }5vrtmxilsA~4B,bxtX%Djikow{i<3R<,zejAO*Kp< _5:.plLM̌K*U;˶ѱ jO"_@IÛ-R 2Ik͆шPb`3n8E,èʴ(ofS^MH`ssC@@+q1s,RJU0\xHۀG`/qc$,V ~7( xQ |<^qQA󉢆-K,K ecC; nQ0c1ǣ 2Ў22ю:Ġ3Td@$0nm%@HC{l Қzl^Zv(JEO&|uE4.Ż#v˪j߬nAAD3GрI,ؔ_^M[dӲUQgÓQvƆ[]BTVvj˨sch[>_DMHKj{  ;QB|~qrxTJF#=u335{C_Jd8$F$'Q^c5fWV9tL-v/%^~ 伷C~Cy<_\\NAUj+0I=ȋ~DQyO ƀ{%d3(j\#:B>e̽1x!7nbR}0fw/\0uv f^(CV"''J`.B (M~ؔ]Io?N 3 =%Sh16Px؉BMt³rWoRX MKG Ң y"Kki\Z{$W{xiƭgSX}fĴϞnĢܻ̈́LH%0 <DWNFCe`]:-ܰ_5'Ï!HΧ;/ɧG[ST.YOhNO@c{:tX[v[NeW 1G-[K|J?1H p/C&前f l(b9gB.6Xc^3xQg^l(&Vf<ؠB1 A((lμ,{DQю~cg> el׃hC` G(2< eP^1YAa)5>M|g `Jۑ |齭 `ogG{2%ۨ$7Et4uh EK_7p\kdڣh;>u@!ąʩjJg̠V{8=m/W;iyEsroo8|RHcDd5B.{d(̋:?{gWU6}&e{owJYPDEA"X@EtPBB 齷ow '7޹3snks瞻sYG—bGtC^E)^vbC0RWEWRGegB ٚJGuO/avH^D'U})0f@K%^_7Y}lJ.n}:ʦhld"[k{Tnξv|$m9]uAMrn>!+hk[裖 I@ h+“ lOVL_.Ͳ ! TMOMig{k[zYM?k7>8>(BNЮK6w7n />\YM s= {6gr[ 3[gO/yB#uM=se6gۯ#)k“Bw);y\42i:oױ[MPmgL~ 5\5L+_EIHV!8&EQz)=>Iuܨ_m)õ F0H*SǠ&I2) y.#N>zSC@ 6uj[. ZpGl67iiZ-ĽձP9Oxܻg%s-k£29ca)3Kf۳!xkHsk C_pg/i>,0;ٰU6:|3{mwn~w?ù|u z!|oZ=Lk\{c"{sFu2X綰a@k=C\f֣6 f0?xYAs,a'2z!؃njj!^\i1h.ueЗzʲQ40DpRi@ʦ$"W @$wCӢ'ǤL͝2vldNKGIu#iid0k|؊ͭ#Ulnk‹JڕYQV:`E틭8lt:Ąh߶}M< ևǭ7l= B)zX./Wcuظ6ls-kKzenHWWڍ螓!p=_(C6yK'( j+MOSiu,+"+-VÛ[ jm@]Uk٪X.W2┅+ڊж~>c&󍶽uMw{sA|OcT<TX2sEu.+ /-R./Nok{-3 xYHޕksJXw@̘n f,^axPl)}Hm›a3  *MFTp#jPuTaˬ4]J^Ki k-x. p^ C*B=, 7QeaO*!Deأ/Lm6[~;7 10L}:& ݐSGZDROlKB:DG_)e#Eh/:lS?q@IDAT0!`60 0PrB}MQ_ʴSIbW4tUTƁ-SgE`$8dJ^|7ۓo?l7nPljk߸{I 5`aUYj\t\)G)v=t?x߱torpx? @~sMY{\t7mz9W]1lƸ@UU'D:5ˏe|.!@VɳHPdw oCxaK6KFasΈPlѱҮ9`qɎp(AgtGvMunx91 9]v[<[y䟋ʦ2_xS1FHgz= !"-1ՔApB;ؐ^F=Sq|6G!Юm;? dZFO o:hljvܩ5-n[UjלqXx;z96] ?ggn{nُY^h!.A`@v.ΕhDAݻ؏O=ЪBGMml C{}? /keOY'17&\FſlfI("bet8<H:$N9@4M;aX𒲖m4Ϭ*+68Iȏư'37CBցoqQ6gֱ`_eA`DJex9e٥"P]["2.۞֣q4/<ĪC~Hٚp9Ux -FVݩU_?ϣQϭ9Dm*,V"@)jC<}ЇU}4.#h<~i?0M#>6 >kЩ~s1Ͱ7/Guo)7G&j? a7k_LO9$ĆZsSg#=74G1'kGw1$G!=/:vr5,p ) ;yU6axOpHC9)%'aZj (Kŋ Uю ]=7D{Rcp0m۴ h{Mc>@W9\yL۶m'ϊc.@C u¨͓&y( wO;&4!K qۭW]h]fS@lwlמ~ѱ/v/s9jruܪ(?rq'$1L}Z*HD&M!` C=R2x8MO5YK7XGZe7ޥ5#cvZB] \D}؉F,Yևp>;:<^>܀rx}dF"y@*퇧j{҂WK ZǷ"aNgqE֥?q ^.c*oYhsxhqlK*l +LY`Kyl&_D'SӞ#4v(\jy9سoWuxY\xͦ[''.%-G:MsrC}[v!{P[VBwi>Z8MtɘF".?7zT^B8 /{NkF 3͋C7Ļ.?YHSc16GVeʯ Gך~ʡ$xꗊ> fr]Ў]l2x81fN dh{4yiE/VN{W=g{p +dEC;!}w˪獭b^zG8q򱳋ȥRK~cn[YÛ[:ip???,h1E;*wLr . 2n栏I'/:O^zlƄ,ȆGvC6e[Ыۄ l}>}Ǝvb첲{Gq-}v[]ɦiFu/nӋ1+>wĄ&=O\#0~#lX)CǎOwӂb伉Mb&f R~~̤n:5nZ_umȈ~V^]o'Lޒԇw .G)[ &#aE؊;<)hW9dki [="sA$E' -K[:<.vǾ/x㍵ڹlݶxl o}즛n7UcǎvWڟh#!Gys9qz饗͝;!uێviO6kEe6yƝDѹ)zfjG`[vjםy}S3m%G c{v/ASn]Gذv=ۛ VjAYII=6yd8q]~ٺdl[t]q?!NC5 ݩS'{'쭷޲߮چ:Y(/Fluͪ獅GgvG<vE;"oɀ@ љG);{ yu6GNٌ ծ?h;xHVHw VpDxsӌBOh ևʢbyh"&2gR_84܅T2 DlmA-"IRGIKzemt >uFW<՞:lҏu^]OnSL*{Wr6|/뮻۳gO2=;ώ>h+..Sڥ^0lcSO=:w\ XM4)Ƶz'G?Q9g"Z>1;cco_jժnPh(C'3'+6:%4Id#l2k߿[x!|"o"x|ֵ9sfG 3cqqrE9ڟ^zז3OZ^HLfy;ceź$ΤnX֝ͳ =[CF)3z*-/]co$l8kraW' '4J6cC?"+ GTN֋:& 5IMHbɳ@eBiГ%ŖtTzTTTDҖO?6cƌXW]]-)7p 8?E]!K%ܵkW; "󪫮<0AVVV<*d,* =XN;o[{G϶I'dƍ+!gҥK$!/ۋ/h|?ց&yz !Y'?I3gNbc="q>s<~o[$'M9ش=cƃSNɊ)ri ;NJ64E9i OOŮ=p'[Xc-Z7-5!0c}#u"}|. ȡ:OZ \aθu}4'3" uC:6\lfiM0Yq~#b5(ApVBWel$C}G/9>sK9y@*x❋ xArcbggf <ŁYf<39l$z*z gyxh׶:ކwn FDCȎGT4/c6n'hvoXS'ژn[i+U&_Ubs'9;@RGڕfUEgO~}zt*.=~{yNE^ѧc석Xy 3o cչ~p_>׉}nuBOYU*!a͵*~J0fX "ia6u$ `t4„Һ&Md$}E2 O.W D$oC xCǡL лw]69 px.D)ھo۽lhgm1?p&!)esE_A~govTan`v 1a)29B E7d'9oϷ h <Ȫti jعn=æ3hhvϮ90x!V+\Z%I.<&:lc'cUHca"q=yvM}E(\؉v{[/֥#vDq?]r- º3 w "g? r-b2\ 1ʕҦQlj&y8DqGcWD2m7}JKJm9Sm7mc.DlhosWFˏcC"eaS᱗y+h#Y{Cǎl5%VUU'l^l7?M])M/sٴq kY+K9>s688 a4>c;mcvipllUNJ ^|Ml ѣ:cG=6œ.)ij|5>cOyGlfA)IiBZ4("$qKKDPN!`K2yW[ .B7 ɐl !р*J]}Xw!!pK*B2!^!4+x\r^fI4LXdZ !# ߓNR!H2%CťKG !vZ{u dg{ok{nK\U@x+GO]y\1sC`'^10$RÍ ǍkAι8KmOdwiiu FcY틎~iϣ5Nfu=o5<.>`MĿK)}yH~~J9lzPm24%mJ1hBgra~Gtc|6B1#zwkL毝N\vEmX"{gA6/1gC\ಢ%nHvA`}۟z;6{ŶOow`8dvHne[}uM.h qt[f}dӞ}mhV ^Dzyl@y[A08 @#st0B^EQԑ&P%yPءT6#/SJ$Q_ʚڶK1R:HQy骯>*:j> ?.X^*E};x@R(3PH6굫Y4P̞~D~BBkun]G asۋ,'oC,njgu(k!ܦ#7Xe{Eﭙ(YBǟ~9/!C}=cU~ 3Wj<:~ԫ o>r׻9~'{XkVZLr"!dʐyԉpCJd}lׇ-ȁRId{(:iDD,z IQ&N&%R2yM:d㤓I.}(&/15d28qw!$W@>p28(9M 63oF7ߵ$;띺w#{W_htV_^Ϧ@5:;0v}v]:%+Wx|}[K'헮gM<ogG1̾u6r`{#^[voٴ%B>ک{Hw +/'()3<1N8IRHQ$Ү2m蠋z٢.' ;E*lt9AH名}(o JtHE2YՇ$Y~B)!.)}ic^_}Hѥ v28 R0 .hμm#7qܥG'6.< /^jv gkZTugV7u->oG`vӯ?p{a{i-C,.>v_;q!.@sD`UnmC,z}B{Kp2`P@|`Se+6-!;y[/ig?~8Pzwou{lZs.-GlĶƥTt{ډ{ύrhhp/[n0 ʹp9Ȇ pH2;O8юwז,_#`sN'OwDRXWe6n;w.+)Zh0p"[!E&ܣCJ}2Jhס:xMD$8ɓ`.b7`6DN!̠"e|׵PncHKr.K!7'#_p2@@i%!|ĔmNey2lncߺ{ۘKN{jۣ5kn,]@Xڜn?5URSvҰuGd)^8Ǭi7t{[ndv|nUev;'O8F ݂#DXz=tkP5. @QxvR;qP;baV.A <3//5l=EUy.$yt@qqɋo%!mKjGH90yRD>PHGd]ҥ,kJCU$I{K!p2ho5V۳߰kئ6\3omX]wHC3 }j aO9bB9iwd魎@G๩W^Hab ю #XE¹[ mDT%(P G$yi˄ϤE8]bzI^d ?JG*RΦ$t1C LCKYmLEK2勎v:< K]V@ !dpn6mdN9޷՛W6-;֋;Ƅx2Ď;xp>DwgOǦεknv@Y6O;zPo`Nm#&/XQpҦgσ/ڊreօө y nG5ҎoWҷ' HM7SoNbYly$§Y/, _r; >!ضwNJX`/˖ޘ޲mf[eϠ6Ow+퐺l)9MSgfkPWə&ާ&øԆl{o9v?J6!(CX*,@:{ɞPhKB>ؤll_5]IdP 'UTYliA"rIr=:-|rL)s Ji/`q)N 1΢ mYhk7jjY ޒ6V]UR݀piG`f-\bO^ mEc…ֺlZ a:7hogllnK|̾&+m漅{sY lU B,~x1P2%lbvjCM&Gh8Ǽ>{j {~*;7p9W2!:[TA*֧ q9ǍhݻtrƝyhQ4vpx xO^ a^9^8_rZ8aJmP [0[g,./!i+(Q)<#OV 5$܈Zȝ΁5z;%^l-_nNzB9T[rҘV, ourNRuxcyYpsqN\10|%^Lܸfže՚a֭_^qcǠޅ'gūCM%ʜwڷO tⸯaoCʰa>.$FnR ĉCj#Ie}NYlzǗa!Gl_.d0OF!2mI"u!{iHCGih|٣m.#4ۗ%[7DG!S+pqG!br u52zyaI&OwJ'|k # 䰋#PFɐppq?9NK_l54?dj6E<"]RE:->d`I( ٤?eӮ1[IEEk%φrGpGpGpGpf@}?ӊG 4lmAY-*I[*V0T&My6nQ8Rc [X1ӎu?dsaÆo%%%VZZj'Oܖ-[ ݺu޽{/A0⋶jժ 8#8#8#8#8Mq3)1R&#+<$ByRćDW%:q4>zcS5&Y&IL84a9cb*''ktXGWvDSFD~c.٣.g9cW^v]wܹsm۶뮻/i|AF[]vUUU׾:#G;.N>n8l\x mֱcG+tM=P2eM6-/܈#8#8#8#8#+&Lp#cܥ.ibMYAdS<8T8FOvũ26ժQr!@MR&e@PF $'OzMRkyqvEYB]b6"S?GlUWWѣmƍOXm=kZN lЂŋq"Y;~x;3lҥvWD|ӟ=CvˤqGpGpGpGp ͑INΒvQGGQ{h]?՟Ok#}l++'6]XdXb&/*c#9ڴyKܒkq61tDx{ѣvҤIu2ҡC?n~'G?s9c}sQQu%z~_u>c_|q0aB8~W쪫cFz7vn'?m~}SO=nv7a]w]$pƫwq=5ٳox5W2;U}.bq6uTmZ\1c88+GpGpGpGpB"թ4ra\?E2g .苷wIJeO16c%ǧlbO6V9m$$^ JZ0mu~A;z<~x_~a孷޲=#<xERxҤIѻcp }޻_mСmm$![#$Qo[n}鲝le@VVV<lv=|&?+VؗiM6lW_}~D]Bet9O~5ӦOX9#8#8#8#8M:aڅ?şV*J98& !Ir hRS  }1GijƧlCړv7T.x`$T!B @h8{o;?A~ghv #PX|ⶤ,c9逗.5\c/͛7/uSO=e-1yfc>IZ/i[o56&M8^ҙք.3gAC,C\?g}6Η"Y31]GpGpGpGp&$Rw){*vٔ>}d.>cEDn&ր˄,Ib )mK6ȓJd2m=>I;X :?Teeyiܐ!C":`S]W '-a߿V2M2k,ekRQ@JMOۘ3gΔJ)t0>zk֬0D//ͣ˚QQQAbV)/C S?GpGpGpGpGi Q\%,$(nRe0GK=B*z/v7dc>ҧ.BY% ^g$ϸUT.ڟvS@QFHabeщ.wn|&>/{!ۙgirH%/qs$yօH&wƄa8Ғ%DGK+w}׺vjmȑv8Dz@IDATYg… 3 Ҝ5K.^zuδyxx컷o8֬E.#uI u5r@.]\pZ1~i/(~)>#JK+}َ$%靋NضIy嗣,^}z!q,X`^z]}#5;N$Tyx%#?cXdr:<}kB[{M7e]I\֒iM#1!ё~'n_@MA}fr`VyL_l`pL&2^8@1@m8@:sZ E5E3ɡ"YEYBỲ .BWzC799d]q06*Ӧ1ȣClP4~]/MA!@$1۷o7¼%%%1./Dj ҪH)JOb;ҥKB1r枎<δ&C %j*.)yxGOZNگ#q?c06G"&cЇSqZ~~ia/>>;IySFGe#dc=e%ɼj-]M1mA  2tIt!q)kǾB6`ǩ91dk8*~{$^yAqu aK/?V[ґ>` M3FgOG 1-#uA|o{nbpgz b~k*sS:Z֦@>4Y9@]y!꺎϶`?_ZZ+B"sB>mœƄL8V&\#RAs$9E8KIRP:I8ҤnT;5tS>JG=cs$"uk0Ų&qMjvH[M#]Rl>,G49l84fne!PV-J<=\1bDZ^$UnKo|W^yvu`3vu"DB$eذav&ɿqcē )LwnHt?3%<@$q|};_NPÇۡjKSɓ 9l[o_x#r|#1TQK%sD.ԩScX#{g|zb .s 8餓jB֭[|AShJr^u"t-q9fҤISțoi{oKNv'ڠAbo~cW]u65 !Ch6~[.Xx1~ѡk/퓟v +89{/(Lm/qur~ކkԗkcM{o!xrSNIyGvNdržЌO>d4;;wO-k\d8Te>l<Ʋ&Lr\/_a%/!]?ӱX#E-[֥L9/*\AN*3?\LC#(RU#|$yxKl)!qO8OYҦgE3CӶg(ccfMXFäD5&^r|Ю@O P%۬R)HԻ8_pc†r1" |\,@|M;?)SԌ͘|pZ]UyUl?R~TG&Ü5K_SvٳS[],A> !"dܹTk{wXRL~^-l5U1)Wx/^^W믷s]lv'$4O`n0ۺe3ݺ)78FZYY̐!Cj84}rpm(XkV!pkc1"Җz JIGKǁ Ҧ'S0!?|&5w"~M?_0V<=e[>'xHGqL^$u2}&U-ѫI8-t:*}gR-r:l2!ԓ?GBMlvqFDx}pQÆ_/Ƀ,.54I6D3L$NXQepB?`ǏJ ea?r.AYI':xHr=yrEޞy $4vHC()¼aD̅R6_\-Å l.HbLx6# Q>!%Ia6m26G'Jl\y\/>7\/<>R˦5 yѓ/?INs>A7ʹX%zH nIs:_;Ib(ێ3!n.#Ј|"^´C o\$[.TuAScCx AJrȝLB({dsg/}.6l`/UI0 Zx3E)wq ޷|}Oy:$zᜆ Cxqq~x鮻H!&{BxKH\F LYOps=6n&Ís$uoi?%R۷o$kd$>sqZ xS* (adȇeqq`oM!^bÍ+k鄧 8ryɶYW94Dpv뭷2]Op8ӟn?5ćg[= 8\GM?8ԐyҌ)$BWB^,EXeAWG`!; YGh,@,Eg$pMI'5夝G{"CCw&X}HHJ'D˺{6Zq6~؇xs˘;Ґv2Nԍ)ccbI +U%/h xK0CD/!UR cH)/cBD7ss!xs΋?Ghj~ MAEq/O=A?O@pKto1ށyykyADD/d^BUa" D:F69s^mdlT.]ҙަs(^zjF֘ d>|wkscHz Lpl|]IL!2 q~}cx"Cn45 {ty 7/!ֽ#J74iR\7f>? as/4sLbh\.\{ ,•6Gȯ B_SzsȾƃTiP_E3~wR5X(&0eM`C5ɐ!#Lv# m.uGh,F@rpoa64\1 (aeyxZW!$a8cz$?6!4ַ ޶\q] qyS$px l 9"-4ױDB}\ 3.ؔ,ج7\ VvIF$>C^iS?<\yjWyxm σ |„.&a-B7+r6˙l!%R&f{QT&^8MB/ "U<.<{yD~?S07MS!-xK(.R@ Y͍a"D/kKWeu7O7`_dړ{L)fKOK")8osKh  Eoki^ `C 8g_/xZ'y/]rW.MOևL,I]C*5G Ad/ કNl Yp У 8"㠞9 DLE}\GI  HI&8v /& .J^,$AIaR4. F5'9%9r΋8œ%G Haq'e#/9z} W\!S9\ iNg*饗F K C7 <2 x4B9Q\ҏI' vw q08w\V&D/G\g\`|sk|7tVSbWO7p>b3Nk vԖw#w1}M,^~{*yA/Lȴsӛd)9|~AE$ ZHU~;1Х?ij{t~<4O%уK`|l@7sZHT$<}Mkz.8'.ٞdžHN}:N-|Rf*ק?4kջ 3ᖩMXem8ql=W}[o6}d;]L^8G11fO6vu< {/Mm2j'S;sn" w@c_xbkldgϥ9;:?tב<Ϋz[> #D7* N d鄦hO+]ƠM9ĥR>!JJ֦Q1M2BeM2zRa^,\CWl `IC_GH PR֬SHDC=QI}1i/tD0c@#u'甚L}<12'nr}ri\3ᖩ>\q@co g}":G1m8do'OU8maNMgP#PRYKeOa֒m~s+rM߹ I$O ("V}hN|%90A."d8!B>mТ#4 yNȧ&Ohl?nϭC*`Sa *dkk>uԟ@G_dcL.#-_9PОΎ 68@&| w| |6G ~~I9-<2OxSqY?\` QMgzu@W 2)قV=:ϛؐ^֐ǩ8{#-{`SvQV0/68@&| w| |6G ~~I99?ddpY~P YhgPu~Q!l/L=BR+U?ʚ/  .E@ɔt/z/+( >#8#8#8#8^TgWHL[K7dc=:j'a5mؤNI9A!Tԫqm#hʔ4٤1-:S:&zO>i;BǎOGc6~PuqGpGpGpGpG =I.xO@]ȅI)9q S֢P>İP?@B{RG##8#8#8#8#8 GYWO"5I g\H֌ ]9hS=iB!=ܫ@2N+.ˎ#8#8#8#8#dC@f]T޲'*Z\mxJ"{m,P<6/z"8TE4eޝZ_͓De:BPRrJ"koVd(e !B%"2+C2OehTh׽Ͼ>gs=|>Y]YZowkWD HD HD HD HD H"`E"2 HZ{zAh Wr8B}ʼn2nA =!acL@"$@"$@"$@"$@"E`ў7 H7?|j}`8,URV-/ t/zʅtK-섍(#T&v5D HD HD HD HD HA`&cp+eZg[ha$HU "w=qމv! P! N V+\}CZJ"A|3r*Jv[}KI@",F Xd,HƏ@14-&BD`E GbH'BexS.gnK/J[Ba'VC]Z#.O9@ vB'5b&Ti\d4HtQT9qc 勇-QIIKJ[)@" B Adz"cƁbH~dLKVf?O&".\g`Ѩ --;XiqZG $^vE8z:wcziҒnvjo-D`5ĸdզ35\sM+')]zw:]K\rKgm窖}+#ikG.[$ 0~aiclomveIOV'~G\8a+D`\,z?v]&Q³1 \ƑAvȍ4ACcWj;(ʴ푧 YsDMQ˫z+<-9?я_{^Vn|W]g>e-,/~;xD77F; _BoV'cC`=x[k[s5i#<,Znʓ𶷽.w);󤦜p .(zֳs衇V}lA=Q͛B |߭d[lQUIwNN<Ī';P~no~/׽ʣڿ:|.p@ " /SN9=.7y2mkZ"G˟׽m}{򗿼bG=jZ {nYc5jꪊݛf`}mySR /no}[˽}>p[|X`9Su(̫ G {غ?b OxB5o|csuu-|+'U^_RgnqWV_}2kd #g MfD0°<3<s1ʝv4 o3xf*{Gy o/;c}K~W~[V~-o)\r%|1-nQmkgg駟^6p?YjfGwMr1:C>XŘ%ױG}sOc {󞡖a"0L'Ҙal1TnozӛyTk|cKG>Tg>=&o8餓j?>I/}i+;&s=f2>7:蠃 袋*>?j=>:22ÌA&fENST!RU s 3+^&D`9/3/!oh _fʻAzP}䕗kVg6_byX=u[ P›[~|uA^L֑HvxVTB m7׿:ye1,,L%53?i|w}7j8ϛ7x^=- 8;{E(̂G>?O<# ?@pH?cn9 'lGh|3Z`A苼d<L)g'b<6{Cs}!a׾!yC;4{ck&cJsybma8ս-L~{Ӓ軐} [d2Lay3Q8ouky2<a0Uxs#s:}B\9DG8ÌAц?9\L@,t!n~QT 4lD=æö4eB]BG`5*\i ȓ.e"H2DBּ(a貫ԿubG*5aY#,W{_V?7Wx8iz^F7Qq# yFGbd7 UCAM.y ЇDTs9 [BdkEj7Ҙ(D?d2I[Hn ؙ?~-ϖɯxupk Radk?1q!7xCEԅZ/sFa=r@q!MOZ`0}m y&0gy>=}NsԄX'X <{ a%+ɚ%>A!3ܓs1F]0eS'H. LuK `2̳爷z&gjEY<-ZtOxx3P4nvscyՅT13mҿ˙L'LccmEyvU$+ޖ4п1> N&4NEXB=|4 0.q.hV^{ostk#'g̉ܐ,!j1!ÎAԔ43^f?/* J4TR` s!Z6{I+-JS&D\yaK`a+ʅNV7XZ`BnE+DDl8}[]}x !Vx@ǟ/FI_LNٳϤ7SյD`<}#?Iڶ*#/i[9kCnX;a/Bu+PgǠAW_BD/O Uu#o"h`£WCNg9׮~® /}N60AԒlPc2_GxHMM&y1+y\;VdS)"vmJO`WL\E:N%obhKӵϖz.^2F^)m2ladrSayE G#y?l8Gb;mAy2Yqxq$'"H!q\-q*g?=oNY,~.i(>uV<&X}^W$\?9!z{AY̴i2 yqQGUE\g5Ƶc7u#xz ň|r3OG #bZ1xݷ8u#sa{骿ѧpNi9-2mwKP<-$ #2 v :b>{gaG:c*#>' }E$H]@:fW₥9G<6(Љvu[;Ag$ s7qx%t*ҋ#3-×wNv: FbtNι\gXcқ5j$ejUVxP AXZj{IJȰvB_212@jcPӶCZ Bދ!ݿH7Mu:׫IRu+a }ݹ*F8vک=%wb6#fQ πމ*5oA}#Cԧ׶= Hn ڀ@pg|?d<$bAMtI_ 1 aC? Xx,-f&>\An 6k5Ts^Kr>C6d $mʲK#xQ?c/:%qaS) 6Y7nXG9q։VDoѻQz_}n'6SEC<P#^yAee^z8z<|@ΫW:ohȖh?|&s =e?:yi]gZ+:^$d/1F)311QhC&kX;B^fȳPcϬ V}N$3|@J0;H$0UPCi.QvL,ZVSpZi?>Dv[Ѧ:u^2) W\\;P<:ym3= +5e`77T1` RMHA2^C0F|Š:Ģ{:@x,ĶO׆ ɳ)cm!HB2&nDG-KD /~t/{6,awG=7-><2AZD ' \=W_12 BQLۼ޸s*mj_R/DچЋsyt/=l9' Ayu}u!-(΁0NTXnYeq*e- WGqpaQsuJʪb`\x`&`^ %ܢ^V_ur3=zMHqMǒ vvz !nҦjTASTR(^ioUcTN?Lך@"0R K:zٟjza5L֫33si5sտc2*vS9l1J}(e.8oaӧp65B,v$GlHp< L/LvgN@IDATP' 3/t7W^~1-lD0dZA UB|F䉇2@'͓&GO|ЧֿҢ|xlEtpۍoYN_bD (4^)f2y$E D`1ٿ,"cEcp{Oi&҃\f[="l\^ QQ?VpK(0T1Bl\E;s:-ml y !^!~%}KYu>83[)@"y& db" cdI! ɄD`@Wlι?ՏcmӾ0dp-6V'*i#TeͣQ6ꍰU~)@" խ7,Gs~یCʔl$ L'8>f(D @/PɴD"9qsjkp~ )%ة00ґ r7tt}وNH.A/ځPN|غ^{y x?U6߇I'1]jID HD HD HDn];tn6{>ES>Aж!vd {.+= ]Q>4ىTIvθʢQD~Nrmpp6:ҥ!o [hi~eSD HD HD HD HD  Ԝ }6"-ҥ--3R2,%ߖEʒ`#.D9S^# W6þtbQD HD HD HD HD HB`cl?a5+]d HAy|GG unODG~J"$@"$@"$@"$@"$-<),Za($P9b=oI[#_8w8;*'E3HD HD HD HD HD?FCO( a΀Qp@vMf oÛ7*pnt٥# D`F KOfcf"XAe#7ܕ(1:v]b.ޒtN~ؑmf(D @/PɴD@Q=# 3xUJm8T < ppj'e([Qg/%Hl 1.q)L5\SIJ^zi=].'|6G. ?Yk'>K29#ik*$3B`8mbT3ۑc2$7H'yꪫZwVY&8Qǹ?kK +H݁ 2A`;O7wcY{'O,GuTugImnsno#<wq /,niYs5v:ַ~l"_җʻZ/r[ߺ:ky喷eUN:<(~g=YE=}C˾[z[qwϟ_y{_ ~k^Sn{ۖ 7pZ+_o.[T^wiwo[>>?KbwY);'ߊ{=oqOЯwBoo}7~Pis!_~yy{[\]rhB֙,fYzau}1 da_(lAq9ԾJ?a|;<|\_o>{YsyU,Zkz׿U>_Ÿ7oSϒU 0ˍ͉'W\qE{yOIc/ێJWWq>Oy+OJW8√Nwꎃ€q~kvrm;/pF7*ZE/*{G[d_\a{m3!z׻־\3LÝze5(oR;.^ױS*8J).ύ|i9Fl3Ic3D$QsG+4m/*F2!I42 y48@P#NڽF# D`x[R~ G? _J"/xA%._u[_eA0X'>Q41]Շ9vy3Y^WUV{bA)ӟo~'=9r'Wu뮻ۯ MZ{gO?MG*^{U;gpiqT` 2 oxC7 OxBAj ̤ +=1HA|^"⵷ H7ܤ^Q[|N[8蠃"~vZdg8"7}_6i2y!w{=L,|b !ow~՛8R~v1AT$"pO|bxMFyfc x`%/_rݬ<<[GY$F"i<#mq^[Q3!򗿼s$+ Q?eu~![q.ccI(!]tQy^ǔ+_JַUr!x1 /|_cܓs. -ۗ p;Y)|9 |\ک8; ]'qđAb\~h(LZ;W0B8 .2tv MI9DADmFmTW+HDXxC <ϯlՆQfK:^.RD&#n#MbZ"yt)G=Q5KwI|y#YϽuzDYwm|#kRh0}Sӵ@ΠoM6D2vک[A _=Wubgysҧ>J|)C'nxD&7DU4oI?x* p,N@AzP*GYAPW?`mvݼjmE>U~C޶"dv$,lsOx[Pq^/ ^wE S b~pU)#Χ*yGyG;ommj^yDo`v]]Elwuo,zEFXcq7<=꾡}я~W'D`vpҟݶҽ93n޼y/cd3 ou]wRUaī9^&Hmc/zJ#lgmN|"{81ʼnYO+^bޫ7ü8E55K︨:#>ұR3$Ń 2t}6a/$uužGtRۜFhdT㢅/za+;ؒzaCyQOIBxbbAtDl%%$zW'$Q+=qa턾Ѓ@*.F{6|V؞Jx5"LU 1A0&[%͋؊-03ѫfܧ<)pJe@C^/g)O c{-ΑHB #g+J\{W q/x#쉉,=6ԱN;U)l!]pYA$_Dn=] 9DgExFy˜s{:ygX0V3Q(ͅ&!p ad8LR#Cշd,pGƖ\.tZfk=#HQo2!t;XX1M7/C.դ1l3s8Ozc[ 趱A0}\7[q6u6t.H[9No;F=Xz-ƙǦ,W̄T}p2g  50r1a\V B6Ao!|#/: e94mFCU|zҢN4%HD孉H!D*V兘x[-0b2"{ ȚxHC OM,&[ r?ڋlrxV.@ ie@5ik%>p3yGވN;T#Z2F UQv<  7% crog j҈&3&&!m!Stkef&`4K"eh, uwq_m7.~ֽ`(~; =?-v[^ǎK!D`Dƫsk3wEvϟ_}~K5aØ` ҇M%HfD^{%q*?(c(}׼=Kי+$s=˕+/]oso.C ̡!b!|}7.17 9 }%8Jb.ݸ׶ T`P[sa_5V a>>G` Q8QgPtX{ýѯl-3'|s_pdɨ4+iI7xK:$HS.~z"D"_811QO"" `8e3v7NhI̩00f\ceZycٽ߉.c -BmHCs¢'{l{Žc޼AaRs&[;!qL{vTs(7JGԓKS.m_}Arq ca0me\sMř )DsQ&l v8r."-f^a_(|:)@"0K_=b%>v x{ڟJIv5ڥ kZ; yVm5A X\ /LAHZכˎɚ ~4{Z:c&- AS.9'ڇ?~Pnu\C\G.`oU@W[Oxu5(c/ۯRms3Vx5( 5X!bo+HA2^ HlaAt>@1hal:35{Gt_FSKtx]&lR=-([om;'"^ ١φ+4=ž>,\pxƅX\2B'#XB(y!}Fz7YԞM_ב(z0Q}MSN+ۄ]y_wqGBF-BEqA[&,qd$R5Sׅ1x+k}Z54ljvZ31[s )mj818I#R~I -]elG](GD qH\4hr(! h/+u1l,t"xi WFC<'6ꬎ}.mGv3ϴ Q~Pk;};QE>Ye. pɸZ>_D cjTr+g׸04 c|m:7>פ$s\/"o{K1Ƞg[m#TMW8L9l"~]ިqDqcqT;?t7v'lIHNvsgU*HN9m*t.$)=D/l*PN ;"k˻^FEqv)J9lF+!aWL^7fTxXaX]}؏,uK`8ۓOV^8Ŗ "Xk7Gm)D6{c@`GC7b&D: D^oiQEWk=\bF#֖eiZ~Sߠ{J_D a-u&cMm~߳k\}gTd} ۗ^˸9I ʹO6b\;l4447 ʛi}S7*#8,{H3S1rceKp8;K T}kʿ`,C"DkAA7ئhtil828y/;(#e;ɣvlnv,yEV_3㐩:L UHIzX E/@oިl$@)|;ZRJ7_$Kc&i;Xe/[.4֦w0Me AF#?lҔ KU#& tpTȸ#_ RYKvNk2 qaHt. Ћz:+Z;IË= ˹#BJ~s+zk?/d=|x[{+-O~RIUΞQ+"<dUa cXz뭋|fO{wڗYl\{ʊ[֙Rg֎D <:\oI$>f|XD @/ȳD`C GIpY$3*G.q ź҉0ߖ)_zD0q.d#.MeFHDk<✷Cs }i=y!CGtn~oWP"ZGYNF6k?sʻbK ,c9^uE>_? m RنDÞ?j;l̮>oVsN;6RVL[e/s5'e`+%HAd3LOq }8PL@"_i ccJ?Wm+ø11FЅ 1*/?DHA'pzDyI6鰳zP&uoyv!u[_~wMK_3e]j+_H.\rI8F"я~TO=O|3)[9kC7|›.e_$iSxD]xG=?+7wV +NYG Y<+LV(Y~D`VeVe cnx1 ~92Q.xMaI=T<)/oPNTNڊ]4LF;4(يa~&l[ly^-#$aV&&&v/Y$.kvd .m0؀fLNID HD HD HD HAJU0#=€ci˿Fzp28.ePr6tvEpQ~Xyqe$fqN)>lt"DoAC-w6lS;J[L޵^[?: 8w}kI'-;]Iޖ[nYC^ƫzÛmYOg*D HD HD HD H<9LG\N5zax^/IVR˄3<ʜrmӸ zCW(O>'.l2^5gyf eMJ I;q^-D[>z /bz;-uh@NF V4yKĪX:Е6d_G8ǎWfENPK]p//i6.o/W^yPr':/uU\xݨpr)wWDH!O?2]D]E73#cA H6xP8㌱#$@"$@"$@"$@" NtLjK 88OawU)'$rHt:։vcx #}Qa/'OxpzOPGq[O<|;ߩ{GIMoZ/Q7<򑏌2h.sg /,=ܳ ԹQK;=/~׾ {?w^y+_Y>яNi߭:묳N3kkSկ~^Wy][oͳ:|.p_WaolkZwu{|9A}wk?c&c]CDk\HpDxUWA"OӟRZ);me9\`T\( 󣡑H8q.@"Wp'Z%Կx@"0x@zN%=ʻJ-oyK~V^'?w62JI6]w]9蠃6lSwo-z~"$\|gy=|;WC:(_%h^ו/W#8\}կ~u%#?޻{yew/1X~]6tZC-_->V?Z'}uD`yDӟt׾V O>W\˟me9J1yLyK_Z򕯔o}[92,RiC+OwZ\5|/k{?nD駟&/q;cW_}%r򏡏 7Jh>P@NcquĮK'΃Ѧ!}HshPZ9iGizjTJ"o~7򗿼|V`mo{[ Y~ ^PuHdj^QO~w(w*Uxm1)F`?zj~+?Ovi?HD`7.w]džnX-!`qܧ pQD [Vev]FK.z!5ϸg޼yqܦva 5ϿVSԂW-ZV7'?Y]&X喙gmF%0oMi-X@VzNwS9 ַ"e,>U*[ou[rbQnmhGD2gAD%s:1BҒ+w_t=V[mU=ǖUG=-G~כ}x#myNSqh>8۔E<㢚\T?zZAN'WB7Ai :ʀ+G~ENG> C?2XzXx$#|+^Q =ĥ'< }nG>Oؤ&7I]6i_R=nꪫ7Mubr{&c:d8E}P_UL2 SF"<GLy#RD HM,"#: G>&Ani>F7Q=Dl F",TB'21+Y>:#!YyY „ 3J:"}ַ4Ȓzd9b|ƋO{Sme\jMA[nuöEې㕜}g G}/lA55iJx>SO513v7s6~bha{XSzi-FHYX#ډ7 v0(A3.ړFN9`#:.{qO`$^; r71h[h{~̈́6/J ~.!;S}{{BsLT J$}ͫ<%HD`Dxi;c 2|}؛M!=gF o:l`t:[؛PH4&?EwY!<mK8ݶ0gӇxJkIY{i.k8o޼o zmu`:/8FARd?x!^lm㍈WȉW\>H;]thSr.Očڽ~dt B6 oWYl!+ #8#}u(Ҧ#fЏ䚗D`0`iOOɔ),X1 7Pcp/41@*DŽ_WuPrOD*%X?ÅK鴝$#`< ."#`VSc|[}WĶU_:aKמ}W|$78 4n7ߑGY|(DĴߢ~J",*$EAQ/ 8>FĂU|hNڈZmi,̐{?0 '>Q6mkk&T\o CNS5'bQ*vSB/<goz>$}pCRs*2[DI p^W'X\% QHGyB6ALvNЕ>qK'-#¨#Q3K2ƥL^!i 27B mmwgQO'ZeL@"0. fPXb0n??j`dǫN&m7/2٠{tCJ"4?5c]Wf}i;HD`X7o^:II;L5pd]y7 ~0%a 6ulC, UO8ݰ+V{ϯyị̑"K.Ĉa{J\yN[Tz#Q?0@d^QxG4~ö÷hRnPq8FdpMq8Ћs9xؑeʼnhݧ3S9~'7t>7o(3sg; *@?±c >48Kepgq, ~l?#=swL*|( S)kѐhFĹ8:b2΅QF ؈ @N}!)@"ЃnW[=3;ekĞUk`l՝$@"$:Y%@/ٿ"@2G|#x8HSm m?^I\*+/s>P!KQ2ږx腭ȗ`KzaC}wTSDE`[=sJ3bcؒ{1%A0&@"$71 W+Indr]! ܥ*wlm0P4fqa,3V,DvHh 6c ck.gRr)@" :w)knz;l󠌲FVJ"$@"$s@i3X1e*̄K3xږpi]`ՒAt䰲m9o1uA͆2tWD8綉PKut)@""`p&e<HD H,w?Y68XneN2L8FpdCi뜞CZg ޒ8 4Ҕ^x:O)֠;4Q GNs"G"6,a+NWHJ"$@"$@"$@"$@"$"01x5Uq?BQ}3%21AFֆ8:(e$`;Ѫo/lD HD HD HD HD H&! GopΗeHn۬}eX2E3̅ r#9{qD:6]<\gnEyQ(-LF5;%HD HD HD HD H,r* NSHeSp8U흖 f,XFۖë7* W: ;8y%Ҁ|lȧ'>rA-%HD HD HD HD HA`dct6O]K/|JVS1sq@!A"zЉ:0$p ?I2Nr(D>[xN$x00d0QAPEl` -IWya'B:LG$/}ͨ?B:9rb;ϖ|;w'>r 'Ԣϯ?/.qՌAͿ^Wu.k~xZ'.$G0K$@"$@"$2@Ι',}q SW[m_?=zo屏}l-s;SfFQlAx1U<޽oy7SO-{l0m%\Rx]v)ozӛ׿n$"`kq8mMe?mcf YO"$@"$@"qsikWt-^s5OOfk>MD`V^EYe&\Nue\?/,N VJ˄3<ʜrmӸ zCW(O>Z!{¶~y!_i%:*OzW?#>{ZcʁXI_n&z;$aڪVV%,XP=}؎r'vf$QttPׄE{soݴe9b1#(;+;cm[ֺaqSN)P6{YVYEX<jmmnj1["g6l*R܁lNĊy#)/BveC^N:;-uL'k0]GʢU F]H[ȏ;E@'0\P;Js[ܢz?OQ;~ #Mn3nGm/~n)}n}z:gMvE)nBJR$2T!)'B )BX] uUƐ*"D% i{\Yg}>knw{=ڊ8B\))6۬f]->^*t7MSh4?Ĵ,,^{m?\^}_.7KNjo///q?8я4I|6Ƥqa 5p03̙6I^= 4Q6~|#ҟ#&6K0lWbd#~֏?,o^Sy#5jc9ɋʼn-m%ߙgYl`@0W= |pb"%W^Ynr 7P>d_NN"ӫ|jͧ|}%>(|z}𥉼XSc>DkQ[馛o_?!^Xx|jk'l2F>z1EݷƋ1Gf}-!>imC,w;>(j/nXrzԣꫯ^he& ?!裏{s=|/><˟{M\uUo|c'? M$  Hߓ{~F@/x/o rz䜄xoჼ,}8Xol>򑏬0cC}|ܧva%Bq|mjνUA4~׿uy!8}O#Jfv58zXg7p\~1yL=5{{>D'{suɔ0C':hn@DȚ{O.&I_v.蟔X{~SbC=grE#/>}-m;$ òPh3F×ŷ f@x5֎7 k |&2%V 带_8cG~ Owve*(!cCoeo)&mXDSN|?l8![~)„#$#",uY'w82į;~\[>=G4xG?-T>&bBW ^m Ϲ[~QE {EV"㎫> p 8DI^eſWܻoF|ג@4 H@$ _|_b\!a/| iV=1^{󛌼O`'y/p!dG?3k=DorxC)Kk\)`޻q ˬrz\y\O)^}WuSɜ.=9da!J~?{ޒ4 oX"{z 851g>'Z#Z#:c4cFEZe1x0џ6ss3F ډy'NWiBP(Sgl3uׅfс8s:cX`CMN ф,9bL~bX~B08\o^-%86)VM9̶f*J u^pw//4Tx$,#"<+STŇ6|GEw!\OWo}[­q IOc1DtwX!:"bopS}x?cx>F!#5 H@$  H`817|+PY/;_knu?2pk 9+!͉b[$6>V!:W~lD`{ DplՕߜk@Z 9){~s2}CC^ȉAڃ~#]WfG`d0$6}BdPjS46$0>SgÁw׿sǻyXbN1lsg-?vbL'(NB\9d-`כ4OkM#xaEH5~_"'>BHd><=XϗMܼaM|;Sviy~۠)RwV}Μ9u'7X/Fygx>5 H@$  H`8ޣp=%ԧ=iO]wuiG(;ty-|~c/{~#3[՟\C8/mN 9NsuDz[os*yҭyO1`yψ1x0N>!81z9= So4Sq6O4~@@&`TfQ<O]YTWҗ~b庇ġ/Jg& ,&Ky>IfkHe 6`{{{?ޜ* S\8'Ì|Χ˽ƩZ7"}o79k>977hsBtOk\xAD~jq_5|1L͋3r0@.r{_wdWӸZ$  H@8C5>5<1]^ l0Hx{RF\IN [q .D_TOގXӦnr{i A%Z~yO+׫x{| )kڼ/Aøb_?ΏA ǙI_D֙#}BLX 6BmZ66Fyaac ?ڈ㡟5bb3˚) 1 a /|.?u"v}~  ׂ0~ #/|ͯ+qe*wBq0sUJ-oyK'#kErO%J^h{[ij|x1"y+޻~%/_p~{׽uU$KX.Rs"_ kmf^!F8M ^X &rD$  H_Tfy?͙3g^/"^|We.'n9ˡAx/{~ 3yo~^_~SrJ7B1%4_zm{^ߴyeN<#…+]wݵ~ʧ>ɼvq*s8u{Ɖf؟tIUԮA1!t[< D̯Ϣ?׫??#>hQf-33)uƧ5k6?m~|GYl"mv{f$%6FL>蝹M|X'48Xg["mI='~%K˅m?gnfW|k~ xȋ.W{P 8%k8M;kPn>_jG^oX GAGrXJ@$  HF`3񛉼/59y}^;[ j-k {äAއ~%ۘcIݠ;]:.Kp"7RU01iGHO7TEWMhG3MČ^J'Z*rn^tWeldA}?6%ƺxbӇod~a& 4Jk|5NrF'ü`Ny=!/beB7>k8e >36.|5 H@$   {&ZX6,glnAi{Ayx2} |P8~nКa [??.t#:%BFa!0usNV8ofMh8СHK,IeCYlځ;Ʀ'O!2_ћ/0 2V(u8\h$  H@>gAZX5$088oϩ# vE ?}$AE :XGe Ø2>O$0/e^@Ũf~{c$  H@$ Aiaۘw'0#F{蟬4?q`DQE\?Fjo BN?>wCbįNǽߓ`$0/QY˒>0$  H@$  +=ӿҟ{rxul0'D:t D 2-Id` Ĕ,yɑr)x]! L$  H@$ >|] hh9M4#%>$ei?cy(#~$Ѡq@'8$c,dⲰ)X'V$XJ@$  H@$  H@@rDrQUY8:XN L;"aE9[a8n=}%u|1?ɁϤI@$  H@$  H@E`&l%k+ cDցM7m;:cG͂j˵@gAdf9OI$R$  H@$  H@05'{uEves9_{1,(J_aIq'$  H@$  H@$ CDhgE7/̣(i3J9Kca~'WPDN<|c1Ṉ$  H@$  H@$ЗԝD7?=5kX+*GeNGnǏyN? XZ$FP2'qj'vI@$  H@$  H@Lhg~4Zg[1ucDU4/u,'v)BAlV#WC$&WI$&i3Lwa4 H@$  H@$  H@# DM 7M#.A܊9K\D]uZf!fx8o%_C$  H@$  H@3W.j3Zj]0'fG 3F''GIb O=hSs$  H@$  H@$  $01:e4ON~n4;8Iu1h9ћӊ88JbQ=q$  H@$  H@$ y y'2c7l= q`Z"9J,W8TR]xyk X}̡NL|3_|3w5 H@$  H@$  H@ L*I-'닦zG b J;n;N&i^ġ1$\G%Q8';j$  H@$  H@$0.?^PFM`9`iz$񡌱 8wrN5>>oO$  H@$  H@$0IEFv~C:a a6$ЋO┌e.sҟYl74:~<LJ'y2'!9 i$  H@$  H@Fq8+cIюЩbaiS#j2EЗwZ q6Y`? , '<,r 3%  H@$  H@$F %Gg6Ot~+k &`",$1HA%;t3ԣQfyXOq3.yWrWp})oqr '?.?.+_~y_SN9{ #1%  H@$  H@$F1{CwDL菔Gj̡yƗ2:hW)$Fhbo3@alSga,qE(n<[߹,3gNYve7_<(Iey__~n(o{g?ED$  H@$  H@*U&qG0,l3,9{WZՁ@6&hKC7".ȩ?3Z}zFX{zp7T-1ɃݶVX̙3o,ǫ{]ԧ{eUW-x`YeUUW]U?o}ev+O{ʝwY/>3Ψ]wr'-آ,e뭷.~[wvaSKʆnXrAK/{GJowY$  H@$  H@$/B oZM1&e,#/1H[ߌyObOӾi1>%|MGލDpm7&?㈶XF[_0F:B0J=0gkfy+_YEQK(=lF[o-+?*5'Yf*~ӟ./|oضn[n|wyevb/Xkʉ'XUG袋qW/5grc)+Ry+^Q}^'=Is-^xa]: H@$  H@$  ȶ?N1>+g?j6ҡ`Q>DZ:PC쥞%V@v]ӆ_Ɖ6# 'O\LW^%)y?я믿~0+'{scrH= œ(~CRko7/zֳ9Svi|B|ή}.W_}u=Eqc9k{M6?$  H@$  H@$D-3DhLY4Khq7-+c)y7ǨgyaÇqSgkO&V#jÂh$$ F$Kⲩ%Vujzo?8j/{{3Ѥ믿|;U]b%*#rҗv+\n '{!vmվ'bkNw|쐀$  H@$  H@=@TvE[|[3V\'z[&yt#ֲ JDFJU ,zG;"rWͺ2́F9:>@ X \]?яƚ7 A{^lꫯ^zx\=*".18dO?HqgY~|_/lM>VE^oDNwoVT2_nljdM$  H@$  H@NFDEl:dNMzh69M3>x;)jX_G fb6@l1bzݮZZ> _>X᛼l$}-9ؖZjꪫV!OS _ǝ\@_ݿlw{͗~;|-Rf"WFo- p{#Hqw;Y ^W\q H@$  H@$  ;:H=J菹z;k3ɇ9eSN.eq-'>*DYW ڒz+z<3%  H@$  H@fL MTƈt!F>d|iGDU1y=/qy0v`:dYI6F/agel<_EX4< lu]Wviz*;۫+fkM敀$  H@$  H@,.Eyo4V?:O~h+0m18-%A,$!}XPiRD_椏8UC6@Aư6֐Hꫯ8$  H@$  H@ ~GhQ2g{dtvZ>1Ʃg.G|xJZ߮Y'ـ& H@$  H@$  ,tĉǩ̚9?7: :^1|SD% -"n@uQ1|@̼σOcϗxus4 H@$  H@$  H@} L`NGt8C~6}Ȣ+Gioqd04 H@$  H@$  H` 9:ŜMuFVAl0b/8g>_J͟cd05 H@$  H@$  H` ]Y?u(@۫.GM?1u#ELNIΜ"#r8yÜblX̱$  H@$  H@$0 263%sy&.9yrjN` (,AGjǗtg$  H@$  H@$  "F98['{ uC0 hΧXu:=ˆ=soOI$$  H@$  H@$  "]sW\'aGZ67ʑ%80H7p)`ځBԉيEbsxa) H@$  H@$  H/.'-3Z+kjx9E/hJڌş~NRǘSa(x%83R$  H@$  H@@_SwglhZ$oԬ}`9pQ9IΧ?Ň:<,~`hCɜؙ& H@$  H@$  H`3](kam{laU i\ZXNRF&.>e]"1J"1O'G|g I@$  H@$  H@I`&li8b0[1i ]JD]uZb7 0|Ƴ&1|?kIq@$  H@$  H@$0L蕋ZCv:̉DQ'>ocxbSČg8:<)G\4 H@$  H@$  H@# DN]$S.l_͢Nu,sm 6Ʀ9ZNf.m"1}%m8XyhO.& H@$  H@$  H`^wމ 9algm\1lT&^Gs̥/̟(wlM$  H@$  H@`SJiRbޑB8b0mXҎLJSI~,qgq-IGg|8~'& H@$  H@$  C`b (W=F:tf`l(XDZ<>A|(clCΝ##2G۸$  H@$  H@$  C`RqQi6!2DX"GM?",#8%c˜'f MǤII~FHowC$  H@$  H@$ ?7FDm`y27}hc$~4OVćΜ7څtX|XpڔȆ~`e]ֳ'wG\n%nM9*?s4 H@$  H@$  H@f8#>_Yw_G & ֊$cc|`'ħ 0'mgj$  H@$  H@t\3z&?[ 27%Xl&e%vsr-?qRiZj=|_- H@$  H@$ Ś֘[+S-DD4/F_ҟ8/1xs6XS,si3>e7cv[_?rW_\;W_}>{^zۖs=|e+ko[$  H@$  H@bDFj4)c~E]2ig~RI_r6LlD&i+f$qD,%N|)A8uG;G͟]w͑&M7ݴO*'Gy˭ZA){mΜ9e+~Yocr1ǔvۭ\uUm{*G0y+_Y~_gqF?Y& H@$  H@$0@gFD+⏈y⇥͒č>!x5>YOwC]89ВlC7˂yb[:(1S\ǯV/HAe=,믿~Yfeʊ+X>]e x`!7_oMjVZ{wav*觟~zy[R_~{>kגE=)'|r/~Qo*$siO{Z;˗rG+6:r7Z^Łx~!C$  H@$  H@A h[OF/Z&5PW/m|OɃ?F=ï??ZhWGdnb1T'>,8dAI0d)Y\6JZ-cYOR.{B*|"~ӟc_zח:Sg^xap?7%/yI=)(͚^c=B>sʲ.[˝\|wyev([otnlU0& H@$  H@$ "09zggf+ ObٷDG$F AIW1m"gє1sX;FL)G8cC\`g[lEu䊇^+ʃ* j'oGhA9u˳;k'9Uˉ .pbw/GydO8O}p|f]']9'=F\hjh5Ήg?UfMs6'qtp+F2Hx/}GqD|ͫ،hqĉ'XOFvN4o$  H@$  H@5C4qCqHtJ2ci3ǘ1bNcY,.3/~SXXBWKƱ _?Yۜ<?#Lj|Z~ӟO~w%<^oPO{iOxpur饗aӸ/}K A㎫SO~r` zA(~__V_}zb-"--<򑏬w'yĜKX {i9묳W ٸ/;s=^}h]ŽpN k#rr?˼>|衇+"A/8̩?D5_㺉 7ܰ~Q}yL쐀$  H@$  H@" ow1:(cJ~͞qh-uv]ׇvI<#51W7ԉ3(7ߘ8e󙛤avƲ/g1d,BqOyKܰkGcUV);Ӵؙ~J<Pʶ{F_enZ\qNo[&.9wT"c۫2'Q"zb+Жz#k$  H@$  H@@ne{"S"֦u -Ɖ1E?EMnKI_hh3c5PO lYL51'˼,e]~<ǟ%c}yxS]O&'j?5YפB0ڼmwÄacqlK@$  H@$  H`}Vcvǔ'+#b=)K?'F%WIeƥ= tɘ6 csXg,@8Ӧ΃ dr& H@$  H@$  H`0[AN?F\T'ke@n`lN&AToOQo}񡏇Svڇ?q^ AM$  H@$  H@@/)qbq*άS9;^G+o$AE :}C^>yO;('sok7G$  H@$  H@$Зql n9['$4ڮ:p! N?w> "JaCbįNǽߓ`$  H@$  H@$ 1cs6O։6u[v#>"̲$jCc#RX|)oD6掝ߓ $  H@$  H@$ 1L?v1gUS֡[ds,m6񏐋19%ß:sZ˩sa3R$  H@$  H@|/$ctϔG˩]8igS$L36n6aq2_b`e[IO$  H@$  H@$0l%k+ cDցM7m;:c\U#&s{`̡q2?%OK H@$  H@$  H@DלD-I~t͍ؑrdo|  D ưs v+ub/~2Xo4'bXJ@$  H@$  H@K1IGgKxZaN}#<ځ6c񧤟Ӿ1Tp&n|" 'b1Ṉ$  H@$  H@$ЗԝD7?=5kX+#FeNGnǏyN? XZ$FP2'qj'vI@$  H@$  H@Lhg~4Zg[1ucDUs:Q}|WF,HLHLf>ߙh$  H@$  H@F8gtC78LVmEZrBQ7BpWAB# 3q Zo5?$  H@$  H@$  !0S1z?&%s"`67}O?X1#1sħ8mQ;M$  H@$  H@H3SF$I [엿FSK\@ClK:>HL~C/$e I@$  H@$  H@w"CN?vs8g{6@W F% b.rC%յ'7s)?7',[$  H@$  H@$0ԡhhw:@!#ToFKYcK}e~_b0{2I@$  H@$  H@X.J3){_il& 7Ors'HQC6no~4 H@$  H@$  H@T\gth?t fiӏKD(NX2'vC1C||x'sݐ& H@$  H@$  H`$?#9F$hC8&X|(M3??sj3' v,6%1+#X}|W,<]yiSM$  H@$  H@8Y;lW ȃ",m6ebun "iẻoy7?$  H@$  H@$ a=FWDI0VC%s[~F0\lK^=,q˃(̡/jo}3*?s5 H@$  H@$  H@ qG*g?.j3,{_qlWe>}ށ6{,Vj?}NO$  H@$  H@!tHhD?C?$}2۹âR26c^O%4}{:l, BY~|u _. X;F,ٌ%O3=.W\qEb- biVV^y;UW]xU( ?p #C? y;r衇?堃*_Yqk^J+ի'8MkvکO/oy[M7TrB*|ַU'=ܳ(naP򕯔EG9cʗޥږ$  H@$  H@=Jq3-#:DD/1ǘ1bNco5WS,2e饗.gjVk-^]$  H@$  H@]NAb蛳hPcS~yG$l#^SH23cؤa{Xo믯W^ye-1{=y)t;'w7dz=>S9a챏}lX}C+^rYgÜ.F@Ƙib'= K.dh_N<| _(_}{_5 H@$  H@$  H`+ag?ΆfOlnC0*3 H(K S'.,yK?rCD\ǝsi_ 'PSX@Z_֍7޸ zի"r}ˉ^[|}Snrg;_+(zO%Xb*Fxꫯ.w^mǗ15 H@$  H@$  H`4{߻J3u& 1m&W, X]ڈ"b!zӗy''c|i7DZva$4mۗf!`.cӛ;LNhA7߬O$  H@$  H@ @ױ.=sfKdhU8bp_De$A%Q2KI_|6e.c$n H@$  H@$  H`4.S[:tlnEU#ަ:r"榤?cSgNk _N'OWƜblX3) H@$  H@$  HZr1gJ` KL\r.)&QYڙ<|ݮ||5o}&OQ&?C؊#ӸԱإ M\|j5bq5DbrDb26O$F$  H@$  H@$0L?FGq`bl+28 oagMc&֒x毁! H@$  H@$  H`+-5l.uO| R''q/#>uyhS߹h$  H@$  H@F2&IR\g}7E$X:bmMes\iEbK|q%(О8]M$  H@$  H@rr?ڸb0b-s%+*M<5,>P'&KI_/?Q;`ٚ$  H@$  H@$ FӤgESe#q`z4B/XP[.#qOߓ5M$  H@$  H@ctQOKJ{tf#&0Py|P;9h'FGdq{I@$  H@$  H@?F;e?mC|eD0K~DXG'BqJ29O,I?Ó<č4 H@$  H@$  H@# DDo81$hGdn00K?FIhɟUk9o  d) \"jgቅO KOrT~h$  H@$  H@!qG|fCDG6L@aiI(+Ǩ#vC8OO;/`N|8σϸ$  H@$  H@$  #1:#zgLʅ*y3BڝGe3XD fAX6FIe}UhLÜQI@$  H@$  H@H;T9qQgK:p #g3.ĎKg:KEεXbR7?$  H@$  H@$ }o$j3g[$4թm_Lp|!7A)i3F=xƖ!a2ufꈾUoAs{+Z6C$  H@$  H@$ 7@qʏY?Qo qEe[5$ {s6~<6|O/uU'|gT.e6*/Is)K/tYeUZDIcfIת$  H@$  H@&!pȒUϜmsQ_nyZ͎@|#ҟYsz|J,ccÏ%Vmk:lP^eY|,r-ˮZVXays:g}{} Hxev(x#o?lCfg}v>, d$  H@$  H@!9WhElIxڌq6F?)?3`OgҝPaY( ?@ҏca xu;F,Kn6lSd8r曗޻/{nY{QrE ;hxFYj׿g?/ڪ`M$  H@$  H@jz?53FL:f[ۦoy?m=i?3F ډy'NWiBPKaNY% 0OOcY4}3[mp$O7qq::>#4j6=O6tr嗗kv?vۭ(}sUEU FH}&lR?N:}Xsr% 7ܰ\wu堃R.5o@˕|+kQ7[\qee-wIb hկ"^{U~y}k[lQO/r3yGvکO?-o)[otIr饗N3" H@$  H@$ ō菱RCAĘ6hM3>x;)NH|DZ$?BY u,ҟ &p=i~bMlkVSWo-O 77+\EvxGB}c[>ϔk o(/|qbW,sLYi+^|{+|*|>a\۰:Tn+j9ьQC0ab|(rKy]o}C /΍x̜t/5?$  H@$  H@$*OT ʹ:p67С ت$BPDڌfwgQ]uZn'rF)'$9mf!!+7tS= X{ޞo`QzT7QN>zʗ;c=}˻z EYs5_*3o}^A#>~9˾[:wtϩO8rg=!JsS_u] ޜ6}뭷tҽ3ن$  H@$  H@3 MrR9#}6"PkAm0ڈl 3hc1_31mDƏqb3˚k=/|alNreCk|3SO=,Ute$ޥ'Ѽ`͑IOڊE}2|8I@1,fay˓0,8qU2/o?[!/l;ʟfK_1/kv`N>v9'?lU{.+s)OyJy<}obvmWG;7V8s3?|:6X{!& H@$  H@$ $0uMD8러 2*%}Cm18"R2am-3N=ju.:u9n<轢gF@袋|UW7.`8}_^.O~8#__[d8묳Ivm}{_)fD*s=RЇ>TOג+05\sg}v'Lһ$  H@$  H@X\u69BI.huGćeCcKMxj]s_1@ߌw]Ӿ?y\wAoګwB󟻮y|x_OrDBpbP.ReΜ9l+Ƈ/vpFyk@{QG{~?/>WEq\u1εDVhn5l^Tϟy[RσO_ . {$  H@$  H@ N?|NvOq ruDhU⓾:G?'cF)6M?Цc.s[}~F434E$O`J!2 dAXi?kPW-Ku|iG%8m1O?ꯙG<29:0G ? $pO2A6},. emnnA! H@$  H@$  H`4I?JVňoDv>u,ֱ\O.]f"3̉e~J'ɟ8$  H@$  H@9ث[.j#-$8ai0@!Vl_"_כ?'߅$  H@$  H@$  &|$#Fke "pKqg$  H@$  H@$  $#6IYr\1U9,sO= tO=~̋uyX0?'129Uk=3?M$  H@$  H@8f?F$>Q&?C؊#8yc9Ke]"1J"1O'G|g I@$  H@$  H@I`&lhnr18u BV ^ "F0, 7 0|Ƴ&1|#g-7n$  H@$  H@rQR^90@>J'p9]W5%>9A>J#_0G|E& H@$  H@$  H`$)y$uʅwYTN%`s!T6@ˉ̥MV$ġQ2\܅$  H@$  H@$  K;!'9L =`a+#1Qb¡\cub⛹_I@$  H@$  H@L`Pi4MJlq?Y_4U;RG FKPpp7I#ҏ%,%>2?/1Ǐ=Q$  H@$  H@$ qL?vA꯴Hn6lHЛ'9e `vb$D!~7?~$  H@$  H@$ qL?.J3:mS?QK@G%q^|"d,sb!>><ɓ9OnH$  H@$  H@$0@G蟈_Mv4Oc ~,cďП]֙ZN@ NPϕ,lzX)Gg& H@$  H@$  H`,Gg6Ot~+kZ6d2r:o7T}dķC<_M$  H@$  H@0?wFϤ\gK?#xDY6%A߀i`n8hc\]>$  H@$  H@$ gcmۮ:{2`RB U1   @X FH]D! ?4% L߅heal?o3ᄏYwy!7s1>{:TyA곜eW=x>&ֈfWe=>S%b/9\f">z ̜'6@"D @"D @"[H]Gijc\ީK1@5)-c7vy189:GhKk]b[Rf*@"D @"D @"pz#h8oDDo qEuegy x^fL97y빆876@"D @"D =A\jR֮zϹf,O.~8$FQc>>џۖ9|sxF @"D @"D C`zSED;Z='r)^y~@-,>r3f=}ĻQ7?\wۻm^g=YGM8'yQGydug>? @"D @"D SMO%S-vO_#+ RMMXA@fLM:OrcjY>g ^W~Wn^o苾hگ|W|51Gci]ieI[sWd!UtOY`=&OIʦ(Nc\Kb=Ƽ>sq_u-/yз>9\c:{ ף7>h뛯Yyы^y7+ry|7l^n7o;s?Ͼ<ϱ=_&D @"D @"tajhh{gVn9\χvI>֒\~:O<ꏩA^xIk!7<:57?~ϭ?7Wٟ]`D__ܼկ>6}W}Ն_ETs o~~`ۿۛۼ;6܉?ݼ[3?3>wކ1G~Gnop?#>b!!`YyyYr[2|w}o|s>sP̅2"D @"D @"&p]Q=߄9?܃#rbhfthniƻ1E]YK&s3A-0݃s+//ټ۾~6ozӛ6{6ao#%x7|7l~Wu?}}ؼXV%/YZa[~n~ ==/OOZer1b7}7m~~i77K^_H׼5OO_(ͻn>?yY~@"D @"D S1nUQ?>jjS5?}M}RK9saѺ=6L8ba 똍q8 c6k~7c_\^5Yo֮Z~e}*1!1wk_峆hwy7GW ~7a"3x_l/Fu{CvD @"D @"' ȩY*:%B-7z%~\h\1?}I >S!7{bAs1a6KR\@Xhs|\;Kg?%x6pȞgˏPc `]>%]Ǘ:@"D @"D L`?nݘh|`O+K_"KZ9bW fGw;OW y\9{ȼ\>p;cY6ٟ-}~ww/C#-0|w" 𖷼Ȓ Q;/-_{@"D @"D SVS{|T(qDԵFRXZYX[b*s(cG !CK<~cxt1so_ͻeYq'/QqOOn^W:R?'cg?ٛ_ܟo^-w/Xvovw==i۷Ƙ'B|e,@"D @"D@uD卨<;9rM2湫0fn^c"kg퓱:*H;f=k~C=esq@R6 `o |wkOCbZb!c/}KYr0 $? w/_r?cooCC}9slD @"D @" %0hh jꏴ:GKZKr7ycWבX&d&1gAE^b-uua.h @IDAT><$1>bZcyo>1E}3OCD @"D @"显ybɅ+!H9!>q$K03=tS48@"D @"D Ozhji-cb#훇ra̩𱆋ݥg~C=F)3!-HsYy|yjis93ޭ\D @"D @"DƧ9GIocI ^^(:F6xY8uO}r,@"D @"D AC\iO!Y"D @"D @"?SkR>?{P7wr$ }c VP;z]˘>1H80ђ֋wc }rZZ|K?l;@"D @"D @"pR5MZɬ?5U{R]##*Ē굨B/~<sW%?~wjY"D @"D @"H OSβ2>j'jYSE"^X1}&csX_Y5ywE @"D @"D XC\Ajg|  #RXb[\tc2'}O u\c}*$1E @"D @"D 8I@QqXQmd+Xqy^g^;=U5Y"D @"D @"5,]?s':>}5b0 Ye!5Q+%M31vC}/b'6@"D @"D @"pڣ:ZS=~ꟳJU=0=,,+uCsY.1FK^ײGw19UY"D @"D @"n^ZT,1F 0.xƘ.{z6˜w--KN`椿>Y"D @"D @"nB\:MWSN]zBIi3G_õ;(a!αa>B3}D_Z?Z6SY"D @"D @" @st|P1#T'* ~C`=e((; SL@#z70cȹ1[5Yp-@"D @"D @!pg^GT|'v{5;f1v}bp!1Rg<ƷP޶a?ċ7@"D @"D *'ک7ժ9ٕKsKb-h}gS\1;&ލZ]]k#D @"D @"%sSSITӽg<JVᖤ\h; 47Au+"]cڹqyX;לY"D @"D @"wo?jA%;1}MJi -:.k%F5fqلwt,: iLeCɕE @"D @"D KEx'>upzc„]Ru1kwct/ǏḷZY"D @"D @"nZ菳IrSwOkQvj{I(1ρ0Z\ϚqYYG#7?~慸XE @"D @"D 8Jz&oB<;<+ |hop}1LQ׼ƙO,@"D @"D AD8d?Z+*-F 6"--v,2yry<:vyM"D @"D @"? d?~5 "Xݼ`kK,y!bsbô1\|ēwuY"D @"D @":6ٍ>at"2WXAE^>W9bLJGE֧w*@"D @"D @"VGT{\?T7Oюa#p"K{·BdSBO _#<\0nt/ߝ`"D @"D @"yu8rޤ>FYqoCRLa*RhC >+g=f,->cYk]U D @"D @"D` ǑFZÝ2]uYV?-}rsm;G<}ވGcbs_@"D @"D @Ꞷi^jyW'1cEA )2v "-c];\KKXsn}e@"D @"D @N@:Ip}v/q${ػ \?)i9j#D @"D @"%01sGoJTke\GmKB1c挧ݾ1xWPk 󘢰cM}F @"D @"D K``U|'uSvp(@c1sa/451.}s,@"D @"D .z5Jsos􌳘z,PQ܍XK]ZUhÏbQd=c3o cS"D @"D @"$p&OuZuԣ\#pcg9ХEUKq׍* y΃G,@"D @"D A<_kXx|9A[+#֒1b>a!52@9|ONb]Kxb3gտ}mg@"D @"D @TI=O~O k`ZX2V]Uŏc `8gA-@"D @"D @8[I~YvWGdX0kbq8`^ k7V"`l+2C9n}D @"D @"D k?>HSV!’Xa1~DX +Pl˜kYߜnvL]O᲎kO^dc]?D @"D @"D ' ?7"+9M'kạanjŏђ_MObvt>kw n6옖h6Ïw"g+.zǴ&@"D @"D @"%kGbnBDGݧカF &!69$s6j1 {Ibu5yEf@"D @"D @P{T]?wgOsPYbt W03?zny.6˅1hZ.1956@"D @"D @"pۋTyA곜eW=x>&ֈfWe=>S%b/9\f">z ̜'6@"D @"D @"[H]Gijc\ީK1@5)-c7vy189:GhKk]b[Rf*@"D @"D @"pz#h8oDDo qEuegy x^fL97y빆876@"D @"D =A\jR֮zϹf,O.~8$FQc>>џۖ9|sxF @"D @"D C`zSED;Z='r)^y~@-,>r3f=}ĻQ7?\w}m"D @"D @"vn*}*j~'#1V)*ܒK-~cGw|&cEѽk̾\; #ks #@"D @"D @"p`MGM:(}z'c:Va4XemП5T3H,nEg!L9p;>>D @"D @"D { ܾȓoBD3ݧ=Nw0`LpV+B3f.}sݼy]###<@"D @"D @"p[Tzq9)@}ji-jb.Bb/e19XK_Y9.6@"D @"D @"VG<[&1s[ߧ1=NSk"g*2G 0ֹh1^]xFEփSBAh;Ŝ~]x0b2q\ c ~Y9SD @"D @"Dus]AG=iT%bp{0c>g8a[;7Gm"D @"D @"=vyHMj먭}xI:Bq̜ۗ> yaS64sD @"D @"D { l9#jZz{?خneYcy=}9q3>~.6Xfs5ݥonE @"D @"D XC:%YFiqS*qkcޱK M^by]\<œØ?GK.Z/gyHE @"D @"D ;Ȑc oBo>g8hk`Z"r8ZG8,Ƙ|^65IkiO,qƺo,@"D @"D aۛJ4i'TI!t@KR zbע 1ws=c>^Gy4L1ZiZ߼I ~׎gڼAcÆӒ~&y]n\`yy]T}d@"D @"D @P$vHMWֈ$f1d\F;c/7I̼9Y[,@"D @"D 1jkGNL*u0_W!`GO 1f0-y]|E4?ǰT}f@"D @"D @}{*?>hS}1 c V%,s^g޵B/};f@"D @"D @u r7R_Mu{{;u!F&e}2ܣ8;R9Z}i7Kcks>CjLe@"D @"D @Po$AqS}0\ !΢,:O1 0o=g}õؚF @"D @"D ;ȒyQmA_9?QO (JqG9By2oV/D @"D @"D {LOxhTvdW.+/EUGNpUtƬx7k1rwv@"D @"D @"MO%S-vOs$*Z["ro./}cSg@"D @"D @ukJ?:'ȡOm?EV VEU%1,<ks>k2fg}rcID @"D @"D($ sn`v *WUUUUu0E]gb>yD @"D @"D  lYdohj1B؝dzhF;50/9~9> M qX?1Qpøѽww~w-@"D @"D @Vy'DUg=zY=H I1YK91\Kew-U3x"D @"D @"5G?Rk=zFwhwe[W%S̵Y3{#ᗻ3ZF @"D @"D C`rΞ?{ڲ _yF]4oČ=-05t=p-y\O,90b}2s̹ɗE @"D @"D 8E\O΢: Ϩz0`J(bm874FL&qah'Ý ٽđPscf,r٧,8v{樍@"D @"D @".)S=p5b/ YX(3?wX]B51c棖f5]SD @"D @"D`/3;G$VmAUOu۵b0­,k,2=7uņ cвƼ:D @"D @"D k\GT$?(uϹ3b@EUs7.b-};viUK >?GCGIYϼ5N&@"D @"D @"puǛ?iQpLYEZCQW!xt/a7#_70zw/[[I"D @"D @"!p]QAj?r+X =¯>Zq#0b;GrOy.ƴꏐ,@"D @"D I)5)b~=;ū>΁1Xq(@eLY$GyhE;~)D @"D @"D ws|qaM mXKB\GX>9u-->%XןUmE @"D @"D 8L`{S&-d?ٟ*=)hbIXw^O wZT?fnGp \+y];,@"D @"D XClq$})g_c5¬Iဂ)"z/bZ`>9Ȭo 缻"D @"D @"!p OuZS3?z>SKB`Ya)KB-se~s1u>q\':>yu"D @"D @"$ި86I2j‡13?FK~5Mw?]1A7~0hLYbذcZrx##>?Kߍ<3ӞϚ,@"D @"D jĮ uʾ1\,2њۨ|`&y;硾1kE @"D @"D 8F@QtީI{?YCfс*^\Q`P ֺ!,%kYO֜,@"D @"D Ao/Rur]X#{]|cL܊p=e΋x̻Sc'0s_[,@"D @"D ^n!Q.vOꫩnqosy{.=!פZ{0zX0Gk>/Fwul s·zH-,@"D @"D A9:>?n㘿sk!2UYW)& {1q\\`[SD @"D @"D sYr3?m>HZ=;>1 E)3G[(o[0sED @"D @"D` OԛjNʥz9S%ȩΘ\Fp-Z.֮[@"D @"D @ع3|XXpKR[.}E:|G1r\8ɻ,@"D @"D ^[lqm}ưl:^O+F}Z[ " jt/1Xz"xS{u;wXE @"D @"D C`#=G*t˛?'hGTTf%Ǐ=_!)s!'/C.r7`e@"D @"D  ޼Z9oRdhG8!)0{)4! s{i35ſ~wRY"D @"D @"HzPjGNx> `#>kfco#rױuFw1Xc/VD @"D @"D {L@sGuO[raK4/5輫捓f1W%%F]f~9>D @"D @"D Q?ޔY_gaYL A>sFw9ˆq=6.5gz[7Om"D @"D @"c5wuRyS>8as]B.ԟ_crn}4^S@"D @"D @9#7F VU%! 1sn_k+X5yLQ|̱kj#D @"D @"%}fsĪm>h`V FUeEUxƱ0~`yZ֘wt]G\D @"D @"D` jg9?zYL=JbEy.*4yGw1rhs( s1뙷ש?d@"D @"D @Nx::I8H˜w"*8fFYϼ{b#|k/O"D @"D @"#?W>hS-Gv% "PG .cF1q\}ZbyC3ŘTE @"D @"D 8I::&Eos_uS{'N90k5h׵33cp-h]#ED @"D @"Dnw C?5, sᠭkIh1ᰐcyc >''g<߾ͶD @"D @"D  lo*UӤŞ'SSe'5b0B,I+^*C1az_r0OwgE @"D @"D k?RT?,+v2`F518P0EZ^/@5Cq gr06U!w>qY"D @"D @"5NvyGχzaI0?",zQ(eεoN7;.s'pY5'BSY"D @"D @"?_&IX͓^00chɯi}'1];K5;h 7K vLK4ydGwqs㳂uucSYE @"D @"D XC@͒5#17_^[# EX9ZsyZb$1:cG}/kE @"D @"D 8F@QQ=\s_WP]GKݣ6 =8sRnl~k\l cѲYײ|p19Ud@"D @"D @}{*%95bpI8S%b/gyO]XwLmxfNkE @"D @"D K-$Ů??)-Dֹz࿗'<0 QZƻcjz:R9Z}i7Kcks>Cp"D @"D @"$H 6?<\ !΢,:O1 0o=g}õؚF @"D @"D ;ȒyQmA_9?QO (JqG9By2o7əE @"D @"D K`zڢ:1қZ.g=:yĝ?M:0Mxp\lM"9`s~ÅEN.\x>kcZog@"D @"D DۛJ*k'>N4yL9v?OԘSrcͺqq.}3M %9}15[ߵǵpg@"D @"D @NG5JWD$n?7hjkێK-r57wrr煛n>Eg3sj@"D @"D @"pIETdzH$>sn5ϹkY<ɭӄؔ"Yct/AΙûVY"D @"D @"nZR4sY9mOZ>jk9Bb/P}cLXX:ca3'ca姰m<õ䤵}R="O'}'mloOhE @"D @"c-b#,@"D @"DzR-R04wOnr?5C0\?j.<D2#R`ysFGCd@"D @"D |luij-'ZD="B42 c KYWAr0 CdGw;Os[ڇk˝; <zF˳l@"D @"D luDE5FDsOII-b?;?=l1}f·Mp 51{8EGw)Pxw_D]3 Y0ǭ͈k@IDATwt/E^o}G 뜪O-.i Cm.o<<,@"D @"DII@=sLk%}f93#!0dcꓛ1 wp1 I?|o"?Ot7 l#D @"D }$0icZYHDO音:Դn}ܗsõ)c+._6g>ָ_,&11Cö6pf"pA}7߾ voӛoo^Y"D @"D nKRQ]vBSDuQbF1ktso&?0&ܤEXC 9/g.|s 27qW\{ml'o}gg?#/w?ͧ+7}~ *@"D @"D$in^ecuN\ji8Ok;F5FR"઺KyGw1ry/1sr@ɏYuPxb KAXe@"D @"D ?M;WG*S!5_iݫ>vaIBGBy" bt/y}nc Zf֥eb7 cn1-߻F!j??_?ۛxӷ>@"D @"D'&IΩ398uTK|1/c1s}3VGUZ[FSFrZM೰<q1}xKy|)<"p.n-/K?x͇36zh/_G4D @"D @"pc5gaV}F fxA|YK:&~+ ץJk#5OG^s3WHSO1ĺ98ɴ21>1 .gXK׆nxEf#|[D @"D @"C`.⨈?Eg^'R4u?[_Uy 㽶`CQS1-٧L &TYO5w|e \[_ј8x1~wp>o,,؏m^?$@"D @"D xR׾f3i?cI Z'i>|Gw>c]Hó~@ 5ɟɛ>q(WD @"D @"%@_W؅$Z#ƈhSEģcWҢe5rn^5RP?pݘ69CC3c6!@,cab 1f-?Qy\O^O{6.j\?,0gX˿˻)G @"D @"'6C/?;t$c=eK=>q'&kWt~ykon|zrb-CQ=4$P<~Fww-q>.hdF~I9swsӟwwyE-o)i9mJ7Koi;x޺a>X<pm4.5__O{?_?&_xw_̻v`ї1Ϡٝ÷Cy5vϹw0G}bk9hտx]lecus7fO??;~s~b>06b}_Ks׼~w~~~ῼ%/qG¯$%GRϜwwj 9'a̻qW1v^^St;ujR1Mǜ5s\3-1rcr]Ϝ9|Mbv\o3.\5o,@S3@ƻu>|G?x51Ac߾^}xow߿ܿ?x^m4/'w\1}2԰uwLqa\\JikǺqS,f}b0;fˈ13p=>k#c. clLs3w37csZcq1rbblY?5֚SsX~y1:Zn-j3wu_Ԙ͵WxcBp _;Ȅ׎['/ZwIW3}>~/^}i?O_|_k^'}hדk>_w]ġ?gY^c9<5hc3s7ØCb}]l'.9hEJkB}0147Rg\C|чKɥt/cl5\`2G/:cYk k21Yߚ]K~sX}݋Uץ^û^Ͽ>.^#f{; L_/`?}~P|x}by?E>֩`K}q\ƪe#'ً^&K7KAbp-A%Y-}GXZrꛟxe}k듟 [t/S.3dw1c1G=s}Ys-?>}<%F-c̽1~ߕ~z{{y>.^# m?G߿O>пg~w'?fM4?r@Z6Zﯹ>k1s5i\ ='[k?sѽ铃8؜nG.@huib1ran\cyZ#@|'/9#F}bi.cڹc[}bw_F\1f}c~f?|4,/^c.anwŦ߯~Gϒ> g,3W|}…5__}oT^;~x/>?>CY Z>}>U߸Rw5Ki/B鳆X{Ɉs\eGcc| <01u~\ۺ7Ǝ7G}c\s,~r 6璍y5|1c.FW?4rrY9/Ld b;kxc?^9}\9箭>/~?4KϾ_VC߿=.Y1}p簏y-O,4>A<0}?w%ι#u޾혺kϗcM=+Zƺ7chyAbZ7cQMaO3'XkcƼy𱖃'x(>3q=T̙ŨK}ęt/Qg7qãO1:煾[y8 ?c8[ߵ̻O1_!~zw" ϟ>qϾ >?{&\?x\1?ca |_0J1s}^1gY_yDz=Ϙy^&~h1#n/k+F)qn kMiwcؔ5= ]`-;Lj0q8}̻ZYX3?P39Fen̛>ݵs}߫?guL?E>'G}m~?0ey4RkmajOy^y^].`;o?Wg{_߫X_GΘJ.x-ͯ Ju\?W,|}ί#zϟ9|r(?c ?Oc ?澚qɃ;^y|9w-0raӜgl039:l,Xc$'1Ga|\a