pax_global_header00006660000000000000000000000064142670302250014513gustar00rootroot0000000000000052 comment=b8f9659688a38476df9f613be3342bb8e2d65402 zevv-duc-b8f9659/000077500000000000000000000000001426703022500136345ustar00rootroot00000000000000zevv-duc-b8f9659/.gitignore000066400000000000000000000003421426703022500156230ustar00rootroot00000000000000*.o *.a *.la *.lo *.swp *.rej *.orig /aclocal.m4 /autom4te.cache/ /config.* /compile /config.status /Makefile.in /Makefile /configure /libtool /ltmain.sh /missing /stamp-h1 /install-sh /depcomp /test /go .deps/ .dirstamp /duc zevv-duc-b8f9659/.travis.yml000066400000000000000000000010371426703022500157460ustar00rootroot00000000000000language: c os: - linux compiler: - gcc - clang before_install: - sudo apt-get update -qq - sudo apt-get install -qq libcairo2-dev libpango1.0-dev libtokyocabinet-dev imagemagick jp2a libgles2-mesa-dev script: - autoreconf -i - ./configure - make - sudo make install - sudo ldconfig - sudo duc index -x / - sudo duc ls /usr - sudo duc graph / - identify duc.png - convert duc.png duc.jpg - jp2a duc.jpg - ls -l /dev/stdin /dev/stdout /dev/stderr - ls -l /proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 zevv-duc-b8f9659/ChangeLog000066400000000000000000000066001426703022500154100ustar00rootroot00000000000000 1.4.5 (2022-07-29) - new: added '-u' option to duc index to index by username - new: added `json` subcommand (thanks Nicolas!) - new: added support for NO_COLOR env var - cha: duc db location is now XDG compliant - fix: various bug fixes, check the git log for details 1.4.4 (2018-09-28) - new: added --directory/-D option to 'duc ls' to allow listing of only directory itself (#196) - new: 'duc ls' now handles multiple path arguments - new: added 'o' key to duc-ui to pass current file to xdg-open - new: added DPI handing for graph font size (#201) - new: added '-a/--apparent' option to 'duc xml' (#171) - fix: improved cairo and SVG graph rendering (#202) - cha: changed license from GPL to LGPL (#190) 1.4.3 (2017-01-02) - fix: fixed mouse and tooltip coordinates in scrolled CGI - fix: fixed lmdb read/write locking - new: added --dry-run option to 'duc index' for testing purposes 1.4.2 (2016-11-20) - new: default per-user file path is now ~/.config/duc/ducrc - new: added 'classic' palette for Philesight look - new: added -n/--name-sort option to 'duc ui' and 'duc ls' - new: added --header and --footer options to 'duc cgi' - cha: warnings in during indexing now show full path - fix: fixed multiline label printing in CGI graph - fix: removed PATH_MAX references which broke build on GNU Hurd - fix: fixed line stroking for HTML drawing backend 1.4.1 (2016-03-12) - new: added --fs-include and --fs-exclude options - cha: disabled gui gradients by default. use the --gradient option for original graph style - cha: tooltip now shows actual size, apparent size and count - fix: once more fixed cgi parameter decoding - fix: fixed handling of filenames with spaces in 'duc cgi' 1.4.0 (2016-02-24) - new: added --count option - new: added support for windows - cha: renamed guigl to gui, only one gui (X11/OpenGL) can now be enabled - cha: improved font handling on OpenGL backend - cha: changed CGI environment detection to work around bug in Lighttpd 1.3.2 (2015-06-14) - fix: added missing file font.c for --enable-opengl 1.3.2 (2015-06-13) - fix: rewind dir before drawing 'list' in CGI - fix: fix clicking through CGI graph if tooltip is not enabled 1.3 (2015-06-12) - new: added SVG and HTML/canvas graph back ends - new: added OpenGL/GLFW graph back end for better portability - new: added tooltip to CGI, enable with --tooltip option - new: duc database is now portable between endianness and architectures for sqlite3 databases - new: added --ring-gap option to gui - new: added --color option to ui - cha: optimized memory usage - fix: fixed building on Solaris - fix: added better error handling in sqlite3 backend 1.2 (2015-05-11) - new: Added --dark option to duc-gui - fix: Fixed CGI file system traversing - fix: Fixed duc-info output to be consistent with other tools 1.1 (2015-05-09) - new: Added support for leveldb database backend - new: Some visual changes and performance improvements in duc-gui - new: Link to ncursesw if available for proper UTF-8 support in duc-ui - fix: Fixed HTML and CGI escaping for duc-cgi - fix: Fixed unit scaling on 'humanized' formatted numbers - fix: Added UTF-8 charset declaration to duc-cgi - fix: Fatal errors are still printed in --quiet mode - fix: Better handling of non-printable characters in file names 1.0-rc1 (2015-04-25) - First release candidate for 1.0 zevv-duc-b8f9659/INSTALL000066400000000000000000000120341426703022500146650ustar00rootroot00000000000000 Quickstart ---------- To build Duc with its default options, run: $ ./configure $ make $ sudo make install Generate the configure script when it is not available (cloned git repo): $ autoreconf -i To get the required dependencies on Debian or Ubuntu, run: $ sudo apt-get install libncursesw5-dev libcairo2-dev libpango1.0-dev \ build-essential libtokyocabinet-dev On RHEL or CentOS systems, you need to do: $ sudo yum install pango-devel cairo-devel tokyocabinet-devel Duc comes with various user interfaces and a number of backends for database access and graph drawing. You can choose which options should be used with the ./configure script to build Duc to fit best in your environment. This document describes the various options which can be passed to the ./configure script, and the impact these options have on Duc functionality. User interfaces --------------- Duc comes with the following user interfaces: - Command line interface (duc ls): This user interface has no external dependencies and is always enabled - Ncurses console interface (duc ui): an interactive console interface, which depends on ncurses or ncursesw. This user interface is enabled by default. If your system does not provide ncurses, you can disable this with --disable-ui - X11 GUI (duc gui): This is the default interface for Linux and other Unix systems. This user interface depends on the cairo library (see below). If your system has no X11 or cairo available, disable this user interface with: --disable-x11 - OpenGL GUI (duc gui): an OpenGL/GLFW user interface which should be portable on a large range of operating systems. The OpenGL gui is disabled by default. If you want to enable OpenGL, run ./configure with: --enable-opengl --disable-x11 Database backend ---------------- Duc supports various key-value database backends: - Tokyo Cabinet: tokyocabinet - LevelDB: leveldb - Sqlite3: sqlite3 - Lightning Memory-Mapped Database: lmdb - Kyoto Cabinet: kyotocabinet Duc uses Tokyo Cabinet by default: the performance is acceptable and generates in the smallest database size. --with-db-backend=ARG If your system supports none of the above, contact the author to see if we can add your favourite backend. Please note: Not all database formats can be shared between machines with different architectures. Notably, Tokyo Cabinet is built with non-standard options which break compatibility with other linux distributions, even on the same architecture [1]. If you are planning to share databases between different platforms (index machine A, display on machine B) we recommend using the sqlite3 backend. 1. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=667979 When picking a backend you probably need to choose between speed, size and robustness. Some measurements on my system of a 372G directory with 1.6M files: ---------------------------------- Database Run time Db size (s) (kB) ---------------------------------- tokyocabinet [*] 8.4 19.2 leveldb 7.1 31.5 sqlite3 13.5 71.1 lmdb 5.9 78.7 kyotocabinet 8.3 26.7 ---------------------------------- [*] Tokyo Cabinet currenty is the default used by Duc because of the good compression and reasonable performance. A problem is that Tokyo Cabinet is not very stable and can create corrupt databases when interrupting the indexing. If this is a problem for you, choose a different db backend. Graphics -------- Duc supports various backends for creating graphics, but some have dependencies which cannot be met on all systems. Especially on headless server systems or embedded systems not all graphics libraries are available. - SVG: Duc has native SVG support, which can be used by the 'duc graph' command to create static images of disk usage. The SVG backend has no external dependencies and is always enabled. - HTML canvas: Duc has native support for generating graphs in HTML5 using JavaScript and the canvas object. The HTML backend has not external dependencies and is always enabled. - Cairo/pango: The cairo/pango backend is required for the X11 user interface, and also adds an option to the duc-graph command to generate images in .PNG or .PDF file format. If your systems does not have cairo and pango available, add the following flag to ./configure: --disable-cairo - OpenGL: Duc can draw to OpenGL contexts and can be used by the 'duc gui' command. To enable the OpenGL backend for the 'duc gui' command, run ./configure with: --enable-opengl --disable-x11 Testing ------- Duc comes with a rudimentary test harness which can be run with ./test.sh If you have valgrind and you want to run the tests using it do: USE_VALGRIND=1 ./test.sh It will complain if you try this and valgrind isn't installed. The test harness still needs work and more tests, but should hopefully help keep us from re-introducing bugs as they are fixed and checked for. zevv-duc-b8f9659/LICENSE000066400000000000000000000167431426703022500146540ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser 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 Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. zevv-duc-b8f9659/Makefile.am000066400000000000000000000031631426703022500156730ustar00rootroot00000000000000 bin_PROGRAMS := duc duc_SOURCES := \ src/libduc/buffer.c \ src/libduc/buffer.h \ src/libduc/db.c \ src/libduc/db.h \ src/libduc/db-tokyo.c \ src/libduc/db-kyoto.c \ src/libduc/db-leveldb.c \ src/libduc/db-sqlite3.c \ src/libduc/db-lmdb.c \ src/libduc/dir.c \ src/libduc/duc.c \ src/libduc/duc.h \ src/libduc/index.c \ src/libduc/private.h \ src/libduc/canonicalize.c \ src/libduc/varint.c \ src/libduc/varint.h \ src/libduc/uthash.h \ src/libduc/utlist.h \ src/libduc/utstring.h duc_SOURCES += \ src/glad/glad.c \ src/glad/KHR/khrplatform.h \ src/glad/glad/glad.h duc_SOURCES += \ src/libduc-graph/graph.c \ src/libduc-graph/graph-cairo.c \ src/libduc-graph/graph-opengl.c \ src/libduc-graph/graph-svg.c \ src/libduc-graph/graph-html.c \ src/libduc-graph/graph-private.h \ src/libduc-graph/duc-graph.h duc_SOURCES += \ src/duc/cmd-cgi.c \ src/duc/cmd-graph.c \ src/duc/cmd-gui.c \ src/duc/cmd-guigl.c \ src/duc/cmd.h \ src/duc/cmd.h \ src/duc/cmd-index.c \ src/duc/cmd-info.c \ src/duc/cmd-ls.c \ src/duc/cmd-ui.c \ src/duc/cmd-xml.c \ src/duc/cmd-json.c \ src/duc/ducrc.c \ src/duc/ducrc.h \ src/duc/main.c AM_CFLAGS := @CAIRO_CFLAGS@ @PANGO_CFLAGS@ @PANGOCAIRO_CFLAGS@ AM_CFLAGS += @TC_CFLAGS@ @SQLITE3_CFLAGS@ @GLFW3_CFLAGS@ @LMDB_CFLAGS@ @KC_CFLAGS@ AM_CFLAGS += -Isrc/libduc -Isrc/libduc-graph -Isrc/glad duc_LDADD := @CAIRO_LIBS@ @PANGO_LIBS@ @PANGOCAIRO_LIBS@ duc_LDADD += @TC_LIBS@ @SQLITE3_LIBS@ @GLFW3_LIBS@ @LMDB_LIBS@ @KC_LIBS@ man1_MANS = \ doc/duc.1 EXTRA_DIST = \ doc/duc.1 \ doc/duc.1.html \ src/libduc-graph/font.c \ doc/duc.md install-exec-hook: -/sbin/ldconfig || :; zevv-duc-b8f9659/README.md000066400000000000000000000011541426703022500151140ustar00rootroot00000000000000 [![Build Status](https://travis-ci.org/zevv/duc.svg?branch=master)](https://travis-ci.org/zevv/duc) [![Conda Version](https://img.shields.io/conda/vn/conda-forge/duc.svg)](https://anaconda.org/conda-forge/duc) Duc is a collection of tools for indexing, inspecting and visualizing disk usage. Duc maintains a database of accumulated sizes of directories of the file system, and allows you to query this database with some tools, or create fancy graphs showing you where your bytes are. Check the [Duc homepage](http://duc.zevv.nl) for more information, documentation and news. ![duc gui](/img/palette-rainbow.png) zevv-duc-b8f9659/TODO.md000066400000000000000000000035561426703022500147340ustar00rootroot00000000000000 This is a list of feature requests and enhancements that have come up over the years. Most of them are not easy to implement in the current architecture, but I'm still keeping the requests here for future reference or for if I ever get bored and have a lot of time on my hands. Anybody is free to pick and implement any of these tasks, of course! ### Show increase since last index or time period https://github.com/zevv/duc/issues/153 The main reason I started using this tool is actually trying to find users that increase their home directory rapidly. It was easy in the beginning but starting to get much harder now that we have more users and I keep forgetting the initial size. :) I think it would be nice, and certainly possible?, for DUC to show the increase in % since last index or a configured time period (say 7 days ago). ### Incremental Indexing https://github.com/zevv/duc/issues/115 Just a question, is the indexing process incremental or does it restart the indexing from scratch each time? ### Per user filtering https://github.com/zevv/duc/issues/30 At work I have to monitor files that differ on a per-user basis, so it would be nice to produce graphs that are limited to a single user and / or use the data to produce a graph that showed the percentage of the disk space used by a specific user. This way I could send users graphs of the disk usage limited to their user. ### Directory mtime optimization https://github.com/zevv/duc/issues/101 When running index against an existing database does duc compare the current mtime of directories in the filesystem versus the database to see whether readdir() is needed to update the database, or as a performance optimization whether an update of that directory can be skipped? ### overall graph of multiple datasets in a database https://github.com/zevv/duc/issues/56 zevv-duc-b8f9659/build/000077500000000000000000000000001426703022500147335ustar00rootroot00000000000000zevv-duc-b8f9659/build/README.md000066400000000000000000000016731426703022500162210ustar00rootroot00000000000000Installation through RPM ======================== If you want you can install duc through a rpm package. Under `build/duc.spec` you find the spec file to build the rpm. Tested on `CentOS 6.5`. ### Build Using `mock` and `rpmdevtools` to create the rpm (`yum install mock rpm-build rpmdevtools` from `EPEL` ). ##### User Add new mock user: ```sh useradd passwd usermod -aG mock ``` Or editing existing users: ```sh usermod -aG mock && newgrp mock ``` ##### Get sources from repository ```sh cd deploy/rpmbuild/ spectool -g duc.spec ``` ##### Build the sources (src.rpm) ```sh mock --resultdir=. --root epel-6-x86_64 --buildsrpm --spec duc.spec --sources . ``` ##### Build rpm ```sh mock --resultdir=. --root=epel-6-x86_64 --rebuild duc-1.0-1.el6.src.rpm ``` After this operations you have `duc-1.0-1.el6.x86_64.rpm`. To install it simply run: ```sh yum localinstall duc-1.0-1.el6.x86_64.rpm ``` zevv-duc-b8f9659/build/duc.spec000066400000000000000000000032671426703022500163720ustar00rootroot00000000000000%global name duc %global version 1.4.4 %global release 1 Name: %{name} Version: %{version} Release: %{release}%{?dist} Summary: Duc, a library and suite of tools for inspecting disk usage Requires: pango cairo tokyocabinet ncurses License: GNU General Public License URL: https://github.com/zevv/duc Source0: https://github.com/zevv/duc/releases/download/%{version}/duc-%{version}.tar.gz BuildArch: x86_64 BuildRequires: libtool autoconf BuildRequires: pango-devel cairo-devel tokyocabinet-devel ncurses-devel %description Duc is a small library and a collection of tools for inspecting and visualizing disk usage. Duc maintains a database of accumulated sizes of directories of your file system, and allows you to query this database with some tools, or create fancy graphs showing you where your bytes are. %prep %setup %build autoreconf --install ./configure --libdir=%{_libdir} --bindir=%{_bindir} --mandir=%{_mandir} make %install make install DESTDIR=$RPM_BUILD_ROOT %post %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %{_bindir}/%{name} %{_mandir}/man1/%{name}.1.gz %changelog * Mon Oct 14 2019 Peter Cummuskey - 1.4.4 - Update to 1.4.4 - Added runtime requirements * Mon Jan 02 2017 Giacomo Sanchietti - 1.4.3 - Update to 1.4.3 * Fri Dec 09 2016 Giacomo Sanchietti - 1.4.2 - Update to 1.4.2 - Removed devel rpm - Cleanup spec * Mon Jun 29 2015 James Chang - 1.3.3 - added ncurses-devel package requirement - fixed file not found for libs * Wed Feb 11 2015 Edoardo Spadoni - 1.0 - first version zevv-duc-b8f9659/configure.ac000066400000000000000000000127571426703022500161360ustar00rootroot00000000000000# -*- Autoconf -*- # Process this file with autoconf, et al to produce a configure script. # # autoreconf -v -f # which is just: # aclocal && autoconf && automake -a -f && ./configure && make AC_PREREQ([2.13]) AC_INIT([duc], [1.4.5], [duc@zevv.nl]) LIB_CURRENT=1 LIB_REVISION=0 LIB_AGE=0 AC_SUBST(LIB_CURRENT) AC_SUBST(LIB_REVISION) AC_SUBST(LIB_AGE) AM_INIT_AUTOMAKE([foreign subdir-objects]) AC_CONFIG_HEADER([config.h]) AC_GNU_SOURCE AC_SYS_LARGEFILE AC_SYS_LONG_FILE_NAMES AC_PROG_CC PKG_PROG_PKG_CONFIG AC_CHECK_LIB([m], [main]) AC_CHECK_MEMBERS([struct stat.st_blocks]) # # Check --disable options # AC_ARG_ENABLE( [cairo], [AS_HELP_STRING([--disable-cairo], [disable cairo drawing @<:@default=yes@:>@])], , [enable_cairo="yes"] ) AC_ARG_ENABLE( [opengl], [AS_HELP_STRING([--enable-opengl], [enable OpenGL drawing @<:@default=no@:>@])], , [enable_opengl="no"] ) AC_ARG_ENABLE( [ui], [AS_HELP_STRING([--disable-ui], [disable ncurses ui @<:@default=yes@:>@])], , [enable_ui="yes"] ) AC_ARG_ENABLE( [x11], [AS_HELP_STRING([--disable-x11], [disable X11 @<:@default=yes@:>@])], , [enable_x11="yes"] ) AC_ARG_WITH( [db-backend], [AS_HELP_STRING([--with-db-backend], [select database backend (tokyocabinet,leveldb,sqlite3,lmdb,kyotocabinet) @<:@default=tokyocabinet@:>@])], , [with_db_backend="tokyocabinet"] ) AC_MSG_RESULT([Selected backend ${with_db_backend}]) # # Check for available libraries # case "${with_db_backend}" in tokyocabinet) PKG_CHECK_MODULES([TC], [tokyocabinet]) AC_DEFINE([ENABLE_TOKYOCABINET], [1], [Enable tokyocabinet db backend]) ;; leveldb) AC_CHECK_LIB([leveldb], [leveldb_open]) AC_DEFINE([ENABLE_LEVELDB], [1], [Enable leveldb db backend]) ;; sqlite3) PKG_CHECK_MODULES([SQLITE3], [sqlite3]) AC_DEFINE([ENABLE_SQLITE], [1], [Enable sqlite3 db backend]) ;; lmdb) LDFLAGS="$outer_LDFLAGS -llmdb" AC_CHECK_LIB(lmdb, mdb_env_create, [ LMDB_LIBS="-llmdb" AC_DEFINE([ENABLE_LMDB], [1], [Enable lmdb db backend]) ], [ AC_MSG_ERROR(Unable to find LMDB) ]) AC_SUBST([LMDB_LIBS]) AC_SUBST([LMDB_CFLAGS]) ;; kyotocabinet) PKG_CHECK_MODULES([KC], [kyotocabinet]) AC_DEFINE([ENABLE_KYOTOCABINET], [1], [Enable kyotocabinet db backend]) ;; *) AC_MSG_ERROR([Unsupported db-backend]) esac AC_DEFINE_UNQUOTED(DB_BACKEND, ["${with_db_backend}"], [Database backend]) if test "${enable_cairo}" = "yes"; then PKG_CHECK_MODULES([CAIRO], [cairo],, [AC_MSG_ERROR([ The cairo library was not found, which is needed for graph support. Either install the cairo development libraries, or compile without graph support (--disable-cairo) ])]) PKG_CHECK_MODULES([PANGO], [pango],, [AC_MSG_ERROR([ The pango library was not found, which is needed for graph support. Either install the pango development libraries, or compile without graph support (--disable-cairo) ])]) PKG_CHECK_MODULES([PANGOCAIRO], [pangocairo],, [AC_MSG_ERROR([ The pangocairo library was not found, which is needed for graph support. Either install the pangocairo development libraries, or compile without graph support (--disable-cairo) ])]) AC_DEFINE([ENABLE_CAIRO], [1], [Enable cairo]) fi if test "${enable_opengl}" = "yes"; then PKG_CHECK_MODULES([GLFW3], [glfw3],, [AC_MSG_ERROR([ The glfw3 library was not found, which is needed for opengl support. Either install the glfw3 development libraries, or compile without opengl support (--disable-opengl) ])]) if test "${enable_x11}" = "yes"; then AC_MSG_ERROR([ Only one graphical user interface can be configured, use --disable-x11 when using --enable-opengl]) fi AC_CHECK_LIB([dl], [dlopen]) AC_DEFINE([ENABLE_OPENGL], [1], [Enable opengl]) fi if test "${enable_ui}" = "yes"; then AC_DEFINE([ENABLE_UI], [1], [Enable ui]) AC_CHECK_LIB([ncursesw], [tputs],, [ AC_CHECK_LIB([ncurses], [tputs],, [ AC_MSG_ERROR([ The ncurses library was not found, which is needed for ui support. Either install the ncurses development libraries, or compile without ui support (--disable-ui) ]) ]) ]) fi if test "${enable_x11}" = "yes"; then test "${enable_cairo}" != "yes" && AC_MSG_ERROR([cairo must be enabled for x11]) AC_CHECK_LIB([X11], [XOpenDisplay],, [AC_MSG_ERROR([ The X11 library was not found, which is needed for x11 gui support. ])]) AC_DEFINE([ENABLE_X11], [1], [Enable X11]) fi AC_CHECK_HEADERS([fcntl.h limits.h stdint.h stdlib.h string.h sys/ioctl.h unistd.h fnmatch.h termios.h]) AC_CHECK_HEADERS([ncurses.h ncurses/ncurses.h ncursesw/ncurses.h]) AC_TYPE_MODE_T AC_TYPE_OFF_T AC_TYPE_SIZE_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T AC_CHECK_TYPES([dev_t, ino_t]) AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK AC_CHECK_FUNCS([floor memset strchr strdup strerror gettimeofday lstat]) AC_CONFIG_FILES([Makefile]) AC_OUTPUT AM_CONDITIONAL([ENABLE_CAIRO], [test "$enable_cairo" = "true"]) AM_CONDITIONAL([ENABLE_OPENGL], [test "$enable_opengl" = "true"]) AM_CONDITIONAL([ENABLE_UI], [test "$enable_ui" = "true"]) AM_CONDITIONAL([ENABLE_X11], [test "$enable_x11" = "true"]) AC_MSG_RESULT([ configuration summary: - Package version: $PACKAGE $VERSION - Prefix: ${prefix} - Database backend: ${with_db_backend} - X11 support: ${enable_x11} - OpenGL support: ${enable_opengl} - UI (ncurses) support: ${enable_ui} - Graph cairo support: ${enable_cairo} ]) # End zevv-duc-b8f9659/debian/000077500000000000000000000000001426703022500150565ustar00rootroot00000000000000zevv-duc-b8f9659/debian/changelog000066400000000000000000000106421426703022500167330ustar00rootroot00000000000000duc (1.4.4-1) unstable; urgency=medium * New upstream version. * Bump standards version. * Move to debhelper 12. -- Jonathan Dowland Wed, 06 May 2020 16:20:12 +0100 duc (1.4.3-6) unstable; urgency=medium * Fix FTBFS (dh_installman: Cannot find "debian/build-nox/doc/duc.1"). (Closes: #924473) -- Bruno Kleinert Sun, 17 Mar 2019 18:55:56 +0100 duc (1.4.3-5) unstable; urgency=medium [Ondřej Nový] * d/copyright: Use https protocol in Format field * d/rules: Remove trailing whitespaces [Helmut Grohne] * Address FTCBFS: Let dh_auto_configure pass --host to ./configure. (Closes: #915595) -- Helmut Grohne Wed, 05 Dec 2018 06:24:22 +0100 duc (1.4.3-4) unstable; urgency=medium * Update Vcs-* headers to reflect migration from Alioth to Salsa. * Change B-D on ruby-conn to conn. Thanks Helmut Grohne. Closes: #903067. * Bump standards version (no other changes) -- Jonathan Dowland Thu, 05 Jul 2018 21:58:21 +0100 duc (1.4.3-3) unstable; urgency=medium * Adopt duc. Thank you Herbert Parentes Fortes Neto for all your hard work and best wishes for the future! Closes: #886013. * Bump standards version (no further changes needed) * duc-nox provides /usr/bin/duc and the duc and duc-nox packages now conflict with each other. Closes: #885404. * Add a compatibility symlink for duc-nox. * Remove empty debian/patches/series * Revert src/libduc-graph/font.c to upstream version (DOS line endings) to keep dpkg-source happy. -- Jonathan Dowland Tue, 02 Jan 2018 16:12:09 +0000 duc (1.4.3-2) unstable; urgency=medium * debian/control: - Add ruby-ronn to Build-Depends * debian/duc-nox.manpages: - Upstream manpage generated at build time. * debian/man removed. * debian/rules: - generate duc-nox manpage -- Herbert Parentes Fortes Neto Mon, 30 Jan 2017 10:55:43 -0200 duc (1.4.3-1) unstable; urgency=medium * New upstream release. * debian/copyright: - Updated. * debian/man: - Refresh duc-nox manpage. -- Herbert Parentes Fortes Neto Mon, 30 Jan 2017 10:33:18 -0200 duc (1.4.2-1) unstable; urgency=medium * New upstream release. * debian/man/duc-nox.1: - Refresh file. * debian/patches: - all patches applied by the upstream. * debian/rules: - dh_auto_configure: - Add '-fPIE' to CFLAGS. - Add '-fPIE -pie' to LDFLAGS. -- Herbert Parentes Fortes Neto Sat, 26 Nov 2016 08:46:56 -0200 duc (1.4.1-4) unstable; urgency=medium * debian/control: - Update my email. * debian/copyright: - Update my email * debian/man: - Fix typo in duc-nox.txt and generate a new duc-nox.1 * debian/patches: - Create fix-typo-manpage.patch. duc.1 - Create fix-typo-cmd-cgi-c.patch. -- Herbert Parentes Fortes Neto Sat, 05 Nov 2016 12:24:11 -0200 duc (1.4.1-3) unstable; urgency=medium * debian/control: - bump Standards-Version from 3.9.7 to 3.9.8 * debian/copyright: - License other_1 renamed to Expat. -- Herbert Parentes Fortes Neto Sun, 19 Jun 2016 15:28:07 -0300 duc (1.4.1-2) unstable; urgency=low * debian/patches: - ftbfs_hurd-i386.patch file created. -- Herbert Parentes Fortes Neto Sat, 02 Apr 2016 17:18:35 -0300 duc (1.4.1-1) unstable; urgency=low * New upstream release. * debian/man/* updated. -- Herbert Parentes Fortes Neto Tue, 22 Mar 2016 13:48:45 -0300 duc (1.4.0-1) unstable; urgency=low * New upstream release. * debian/control: - dh-autoreconf added to Build-Depends field. - Bump Standards-Version to 3.9.7. - Vcs-* fields using https. * debian/copyright updated. * debian/duc*.examples created. * debian/man/* updated to version 1.4.0. * debian/patches: - fix_typo_cmd-index.patch created. - fix_typo_libduc_duc.patch created. * debian/rules: - '--with autoreconf' param added. - set '--prefix=/usr' as a install dir. - two lines added to 'cp src/glad' to where the build is done. * debian/watch: - version 4. -- Herbert Parentes Fortes Neto Wed, 09 Mar 2016 15:06:01 -0300 duc (1.3.3-1) unstable; urgency=medium * Initial release (Closes: #783310) -- Herbert Parentes Fortes Neto Sun, 21 Jun 2015 11:06:54 -0300 zevv-duc-b8f9659/debian/compat000066400000000000000000000000031426703022500162550ustar00rootroot0000000000000012 zevv-duc-b8f9659/debian/control000066400000000000000000000032561426703022500164670ustar00rootroot00000000000000Source: duc Section: utils Priority: optional Maintainer: Jonathan Dowland Build-Depends: debhelper (>= 12), libcairo2-dev, libncursesw5-dev, libpango1.0-dev, libtokyocabinet-dev, ronn, txt2man Standards-Version: 4.5.0 Homepage: http://duc.zevv.nl/ Vcs-Git: https://salsa.debian.org/debian/duc.git Vcs-Browser: https://salsa.debian.org/debian/duc Package: duc-nox Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} Conflicts: duc Description: high-performance disk usage analyzer (without X support) Duc maintains a database of accumulated sizes of directories of the file system, and allows you to query this database with some tools. . Duc comes with console utilities, ncursesw and a CGI wrapper for disk usage querying and visualisation. . Duc is designed to scale to huge filesystems: it will index and display hundreds of millions of files on petabytes of storage without problems. . This package provides the console version of the duc. Package: duc Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} Conflicts: duc-nox (>= 1.4.3-3) Description: high-performance disk usage analyzer Duc maintains a database of accumulated sizes of directories of the file system, and allows you to query this database with some tools, or create fancy graphs showing you where your bytes are. . Duc comes with console utilities, ncursesw and X11 user interfaces and a CGI wrapper for disk usage querying and visualisation. . Duc is designed to scale to huge filesystems: it will index and display hundreds of millions of files on petabytes of storage without problems. zevv-duc-b8f9659/debian/copyright000066400000000000000000000075171426703022500170230ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: duc Source: https://github.com/zevv/duc/releases Files: * Copyright: 2014-2017 Ico Doornekamp 2014-2017 John Stoffel License: GPL-2 Files: src/glad/KHR/khrplatform.h Copyright: 2008-2009 The Khronos Group Inc. License: Expat Files: src/libduc/utlist.h src/libduc/uthash.h src/libduc/utstring.h Copyright: 2003-2014 Troy D. Hanson License: BSD-1-Clause Files: src/libduc/varint.c Copyright: 2012 ? License: other Files: debian/* Copyright: 2015-2017 Herbert Parentes Fortes Neto License: GPL-2+ License: GPL-2 or GPL-2+ This package 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 package is distributed in the hope that 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, see . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". License: BSD-1-Clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. . THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License: other The authors renounce all claim of copyright to this code and dedicate this code to the public domain. In place of legal notice, here is a blessing: . May you do good and not evil. May you find forgiveness for yourself and forgive others. May you share freely, never taking more than you give. License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and/or associated documentation files (the "Materials"), to deal in the Materials without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Materials, and to permit persons to whom the Materials are furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Materials. . THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. zevv-duc-b8f9659/debian/duc-nox.examples000066400000000000000000000000171426703022500201710ustar00rootroot00000000000000examples/ducrc zevv-duc-b8f9659/debian/duc-nox.install000066400000000000000000000000351426703022500200210ustar00rootroot00000000000000debian/build-nox/duc usr/bin zevv-duc-b8f9659/debian/duc-nox.links000066400000000000000000000001301426703022500174670ustar00rootroot00000000000000usr/bin/duc usr/bin/duc-nox usr/share/man/man1/duc.1.gz usr/share/man/man1/duc-nox.1.gz zevv-duc-b8f9659/debian/duc-nox.manpages000066400000000000000000000000571426703022500201520ustar00rootroot00000000000000debian/build-nox.inst/usr/share/man/man1/duc.1 zevv-duc-b8f9659/debian/duc.examples000066400000000000000000000000171426703022500173670ustar00rootroot00000000000000examples/ducrc zevv-duc-b8f9659/debian/duc.install000066400000000000000000000000311426703022500172130ustar00rootroot00000000000000debian/build/duc usr/bin zevv-duc-b8f9659/debian/duc.manpages000066400000000000000000000000121426703022500173370ustar00rootroot00000000000000doc/duc.1 zevv-duc-b8f9659/debian/rules000077500000000000000000000025451426703022500161440ustar00rootroot00000000000000#!/usr/bin/make -f #DH_VERBOSE = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed FLAGS_duc:=--enable-dependency-tracking FLAGS_duc-nox:=--enable-dependency-tracking FLAGS_duc-nox+=--disable-cairo FLAGS_duc-nox+=--disable-x11 BUILDDIR := $(CURDIR)/debian/build BUILDDIR_NOX := $(CURDIR)/debian/build-nox %: dh $@ override_dh_auto_configure: dh_auto_configure --builddirectory=$(BUILDDIR) -- $(FLAGS_duc) CFLAGS="$(CFLAGS) -fPIE" LDFLAGS="$(LDFLAGS) -fPIE -pie" dh_auto_configure --builddirectory=$(BUILDDIR_NOX) -- $(FLAGS_duc-nox) CFLAGS="$(CFLAGS) -fPIE" LDFLAGS="$(LDFLAGS) -fPIE -pie" override_dh_auto_build: cp -r src/glad/* $(BUILDDIR)/src/glad/ cp -r src/glad/* $(BUILDDIR_NOX)/src/glad/ cp src/libduc/*.h $(BUILDDIR)/src/libduc/ cp src/libduc/*.h $(BUILDDIR_NOX)/src/libduc/ cp src/libduc-graph/*.h $(BUILDDIR)/src/libduc-graph/ cp src/libduc-graph/*.h $(BUILDDIR_NOX)/src/libduc-graph/ dh_auto_build -a -- -C $(BUILDDIR) dh_auto_build -a -- -C $(BUILDDIR_NOX)/src override_dh_auto_install: $(MAKE) -C $(BUILDDIR) install DESTDIR=$(BUILDDIR).inst $(MAKE) -C $(BUILDDIR_NOX) install DESTDIR=$(BUILDDIR_NOX).inst cp -r doc $(BUILDDIR_NOX)/ rm -f $(BUILDDIR_NOX)/doc/duc.1 $(MAKE) -C $(BUILDDIR_NOX)/doc override_dh_auto_clean: dh_clean rm -fr $(BUILDDIR) $(BUILDDIR_NOX) rm -fr debian/*.inst zevv-duc-b8f9659/debian/source/000077500000000000000000000000001426703022500163565ustar00rootroot00000000000000zevv-duc-b8f9659/debian/source/format000066400000000000000000000000141426703022500175640ustar00rootroot000000000000003.0 (quilt) zevv-duc-b8f9659/debian/watch000066400000000000000000000001301426703022500161010ustar00rootroot00000000000000version=4 https://github.com/zevv/duc/releases .*/archive/v?(\d\S+)\.tar\.(?:gz|bz2|xz) zevv-duc-b8f9659/doc/000077500000000000000000000000001426703022500144015ustar00rootroot00000000000000zevv-duc-b8f9659/doc/Makefile000066400000000000000000000002661426703022500160450ustar00rootroot00000000000000 duc.1 duc.html: manual.txt ../duc ../duc manual > options.txt sed -e "/>>>>/r options.txt" -e "//d" < manual.txt > duc.md ronn --style=toc,80c duc.md clean: rm -f options.txt zevv-duc-b8f9659/doc/duc.1000066400000000000000000000556351426703022500152540ustar00rootroot00000000000000.\" generated with Ronn-NG/v0.9.1 .\" http://github.com/apjanke/ronn-ng/tree/0.9.1 .TH "DUC" "1" "July 2022" "" .SH "NAME" \fBduc\fR \- index, query and graph disk usage .SH "SYNOPSIS" \fBduc\fR \fIsubcommand\fR \fIoptions\fR .SH "DESCRIPTION" Duc is a collection of tools for inspecting and visualizing disk usage\. .P Duc maintains an indexed database of accumulated sizes of directories of your file system, and allows you to query this database with some tools, or create fancy sunburst graphs to show you where your bytes are\. .P Duc scales quite well, it has been tested on systems with more then 500 million files and several petabytes of storage\. .SH "USAGE" Duc comes with a command line tool called \fBduc\fR, which is used to create, maintain and query the disk usage database\. run \fBduc help\fR to get a list of available commands\. \fBduc help \fR describes the usage of a specific subcommand\. Run \fBduc help \-\-all\fR for an extensive list of all commands and their options\. .P Some commands might not be available on your system, depending on the exact configuration chosen when building Duc\. (For example, the \fBduc gui\fR command is not available in the \fBduc\-nox\fR package on Debian and Ubuntu) .P Duc allows any option to be placed either on the command line or in a configuration file\. Options on the command line are preceded by a double\-leading\-dash (\fB\-\-option\fR), some options have a corresponding short option which can be used as well with a single leading dash\. (\fB\-o\fR) .P At startup duc tries to read its configuration from three locations in this particular order: \fB/etc/ducrc\fR, \fB~/\.config/duc/ducrc\fR, \fB~/\.ducrc\fR and \fB\./\.ducrc\fR\. .P A configuration file consists of sections and parameters\. The section names correspond to the duc subcommands for which the parameters in that section apply\. A section begins with the name of the section in square brackets and continues until the next section begins\. Sections contain parameters, one per line, which consist of a single option name for boolean flags, or an option name and a value for options which take a value\. See the EXAMPLES section for an example of the configuration file format\. .SH "CREATING THE INDEX" Duc needs an index file of the file system before it is able to show any information\. To create the index, run the \fBduc index\fR command\. For example, to create an index of your home directory run \fBduc index ~\fR .IP "" 4 .nf $ duc index /usr Skipping lost+found: Permission denied Indexed 333823 files and 48200 directories, (35\.0GB total) in 1 seconds .fi .IP "" 0 .P The default location of the database is \fB$HOME/\.duc\.db\fR\. To use a different database location, use the DUC_DATABASE environment variable or specify the database location with the \-\-database argument\. .P You can run \fBduc index\fR at any time later to rebuild the index\. .P By default Duc indexes all directories it encounters during file system traversal, including special file systems like /proc and /sys, and network file systems like NFS or Samba mounts\. There are a few options to select what parts of your filesystem you want to include or exclude from the scan, check the documentation below for the options \-\-one\-file\-system, \-\-exclude, \-\-fs\-exclude and \-\-fs\-include for more details\. .SH "QUERYING THE INDEX" Duc has various subcommands for querying or exploring the index: (Note that depending on your configuration, some of these commands might not be available) .IP "\[ci]" 4 \fBduc info\fR shows a list of available directory trees in the database, and the time and date of the last scan\. .IP "\[ci]" 4 \fBduc ls\fR lists all files and directories under the given path on the console\. .IP "\[ci]" 4 \fBduc ui\fR runs a ncurses based console user interface for exploring the file system usage\. .IP "\[ci]" 4 \fBduc gui\fR starts a graphical (X11) interface representing the file system in a sunburst graph\. Click on a directory to redraw the graph from the perspective of the selected directory\. Click in the center of the graph to go up one directory in the tree\. .IP "" 0 .SH "OPTIONS" This section list all available subcommands and describes their usage and options\. .SS "Global options" These options apply to all Duc subcommands: .TP \fB\-\-debug\fR increase verbosity to debug level .TP \fB\-h\fR, \fB\-\-help\fR show help .TP \fB\-q\fR, \fB\-\-quiet\fR quiet mode, do not print any warning .TP \fB\-v\fR, \fB\-\-verbose\fR increase verbosity .TP \fB\-\-version\fR output version information and exit .SS "duc help" Options for command \fBduc help [options]\fR: .TP \fB\-a\fR, \fB\-\-all\fR show complete help for all commands .SS "duc index" The 'index' subcommand performs a recursive scan of the given paths on the filesystem and calculates the inclusive size of all directories\. The results are written to the index, and can later be queried by one of the other duc tools\. .P Options for command \fBduc index [options] PATH \|\.\|\.\|\.\fR: .TP \fB\-b\fR, \fB\-\-bytes\fR show file size in exact number of bytes .TP \fB\-d\fR, \fB\-\-database=VAL\fR use database file VAL .TP \fB\-e\fR, \fB\-\-exclude=VAL\fR exclude files matching VAL .TP \fB\-H\fR, \fB\-\-check\-hard\-links\fR count hard links only once\. if two or more hard links point to the same file, only one of the hard links is displayed and counted .TP \fB\-f\fR, \fB\-\-force\fR force writing in case of corrupted db .TP \fB\-\-fs\-exclude=VAL\fR exclude file system type VAL during indexing\. VAL is a comma separated list of file system types as found in your systems fstab, for example ext3,ext4,dosfs .TP \fB\-\-fs\-include=VAL\fR include file system type VAL during indexing\. VAL is a comma separated list of file system types as found in your systems fstab, for example ext3,ext4,dosfs .TP \fB\-\-hide\-file\-names\fR hide file names in index (privacy)\. the names of directories will be preserved, but the names of the individual files will be hidden .TP \fB\-U\fR, \fB\-\-uid=VAL\fR limit index to only files/dirs owned by uid .TP \fB\-u\fR, \fB\-\-username=VAL\fR limit index to only files/dirs owned by username .TP \fB\-m\fR, \fB\-\-max\-depth=VAL\fR limit directory names to given depth\. when this option is given duc will traverse the complete file system, but will only the first VAL levels of directories in the database to reduce the size of the index .TP \fB\-x\fR, \fB\-\-one\-file\-system\fR skip directories on different file systems .TP \fB\-p\fR, \fB\-\-progress\fR show progress during indexing .TP \fB\-\-dry\-run\fR do not update database, just crawl .TP \fB\-\-uncompressed\fR do not use compression for database\. Duc enables compression if the underlying database supports this\. This reduces index size at the cost of slightly longer indexing time .SS "duc info" Options for command \fBduc info [options]\fR: .TP \fB\-a\fR, \fB\-\-apparent\fR show apparent instead of actual file size .TP \fB\-b\fR, \fB\-\-bytes\fR show file size in exact number of bytes .TP \fB\-d\fR, \fB\-\-database=VAL\fR select database file to use [~/\.duc\.db] .SS "duc ls" The 'ls' subcommand queries the duc database and lists the inclusive size of all files and directories on the given path\. If no path is given the current working directory is listed\. .P Options for command \fBduc ls [options] [PATH]\|\.\|\.\|\.\fR: .TP \fB\-a\fR, \fB\-\-apparent\fR show apparent instead of actual file size .TP \fB\-\-ascii\fR use ASCII characters instead of UTF\-8 to draw tree .TP \fB\-b\fR, \fB\-\-bytes\fR show file size in exact number of bytes .TP \fB\-F\fR, \fB\-\-classify\fR append file type indicator (one of */) to entries .TP \fB\-c\fR, \fB\-\-color\fR colorize output (only on ttys) .TP \fB\-\-count\fR show number of files instead of file size .TP \fB\-d\fR, \fB\-\-database=VAL\fR select database file to use [~/\.duc\.db] .TP \fB\-D\fR, \fB\-\-directory\fR list directory itself, not its contents .TP \fB\-\-dirs\-only\fR list only directories, skip individual files .TP \fB\-\-full\-path\fR show full path instead of tree in recursive view .TP \fB\-g\fR, \fB\-\-graph\fR draw graph with relative size for each entry .TP \fB\-l\fR, \fB\-\-levels=VAL\fR traverse up to ARG levels deep [4] .TP \fB\-n\fR, \fB\-\-name\-sort\fR sort output by name instead of by size .TP \fB\-R\fR, \fB\-\-recursive\fR recursively list subdirectories .SS "duc xml" Options for command \fBduc xml [options] [PATH]\fR: .TP \fB\-a\fR, \fB\-\-apparent\fR interpret min_size/\-s value as apparent size .TP \fB\-d\fR, \fB\-\-database=VAL\fR select database file to use [~/\.duc\.db] .TP \fB\-x\fR, \fB\-\-exclude\-files\fR exclude file from xml output, only include directories .TP \fB\-s\fR, \fB\-\-min_size=VAL\fR specify min size for files or directories .SS "duc json" Options for command \fBduc json [options] [PATH]\fR: .TP \fB\-a\fR, \fB\-\-apparent\fR interpret min_size/\-s value as apparent size .TP \fB\-d\fR, \fB\-\-database=VAL\fR select database file to use [~/\.duc\.db] .TP \fB\-x\fR, \fB\-\-exclude\-files\fR exclude file from json output, only include directories .TP \fB\-s\fR, \fB\-\-min_size=VAL\fR specify min size for files or directories .SS "duc graph" The 'graph' subcommand queries the duc database and generates a sunburst graph showing the disk usage of the given path\. If no path is given a graph is created for the current working directory\. .P By default the graph is written to the file 'duc\.png', which can be overridden by using the \-o/\-\-output option\. The output can be sent to stdout by using the special file name '\-'\. .P Options for command \fBduc graph [options] [PATH]\fR: .TP \fB\-a\fR, \fB\-\-apparent\fR Show apparent instead of actual file size .TP \fB\-d\fR, \fB\-\-database=VAL\fR select database file to use [~/\.duc\.db] .TP \fB\-\-count\fR show number of files instead of file size .TP \fB\-\-dpi=VAL\fR set destination resolution in DPI [96\.0] .TP \fB\-f\fR, \fB\-\-format=VAL\fR select output format \fIpng|svg|pdf|html\fR [png] .TP \fB\-\-fuzz=VAL\fR use radius fuzz factor when drawing graph [0\.7] .TP \fB\-\-gradient\fR draw graph with color gradient .TP \fB\-l\fR, \fB\-\-levels=VAL\fR draw up to ARG levels deep [4] .TP \fB\-o\fR, \fB\-\-output=VAL\fR output file name [duc\.png] .TP \fB\-\-palette=VAL\fR select palette\. available palettes are: size, rainbow, greyscale, monochrome, classic .TP \fB\-\-ring\-gap=VAL\fR leave a gap of VAL pixels between rings .TP \fB\-s\fR, \fB\-\-size=VAL\fR image size [800] .SS "duc cgi" Options for command \fBduc cgi [options] [PATH]\fR: .TP \fB\-a\fR, \fB\-\-apparent\fR Show apparent instead of actual file size .TP \fB\-b\fR, \fB\-\-bytes\fR show file size in exact number of bytes .TP \fB\-\-count\fR show number of files instead of file size .TP \fB\-\-css\-url=VAL\fR url of CSS style sheet to use instead of default CSS .TP \fB\-d\fR, \fB\-\-database=VAL\fR select database file to use [~/\.duc\.db] .TP \fB\-\-dpi=VAL\fR set destination resolution in DPI [96\.0] .TP \fB\-\-footer=VAL\fR select HTML file to include as footer .TP \fB\-\-fuzz=VAL\fR use radius fuzz factor when drawing graph [0\.7] .TP \fB\-\-gradient\fR draw graph with color gradient .TP \fB\-\-header=VAL\fR select HTML file to include as header .TP \fB\-l\fR, \fB\-\-levels=VAL\fR draw up to ARG levels deep [4] .TP \fB\-\-list\fR generate table with file list .TP \fB\-\-palette=VAL\fR select palette\. available palettes are: size, rainbow, greyscale, monochrome, classic .TP \fB\-\-ring\-gap=VAL\fR leave a gap of VAL pixels between rings .TP \fB\-s\fR, \fB\-\-size=VAL\fR image size [800] .TP \fB\-\-tooltip\fR enable tooltip when hovering over the graph\. enabling the tooltip will cause an asynchronous HTTP request every time the mouse is moved and can greatly increase the HTTP traffic to the web server .SS "duc gui" The 'gui' subcommand queries the duc database and runs an interactive graphical utility for exploring the disk usage of the given path\. If no path is given the current working directory is explored\. .P The following keys can be used to navigate and alter the graph: .IP "" 4 .nf + increase maximum graph depth \- decrease maximum graph depth 0 Set default graph depth a Toggle between apparent and actual disk usage b Toggle between exact byte count and abbreviated sizes c Toggle between file size and file count f toggle graph fuzz g toggle graph gradient p toggle palettes backspace go up one directory .fi .IP "" 0 .P Options for command \fBduc gui [options] [PATH]\fR: .TP \fB\-a\fR, \fB\-\-apparent\fR show apparent instead of actual file size .TP \fB\-b\fR, \fB\-\-bytes\fR show file size in exact number of bytes .TP \fB\-\-count\fR show number of files instead of file size .TP \fB\-\-dark\fR use dark background color .TP \fB\-d\fR, \fB\-\-database=VAL\fR select database file to use [~/\.duc\.db] .TP \fB\-\-fuzz=VAL\fR use radius fuzz factor when drawing graph .TP \fB\-\-gradient\fR draw graph with color gradient .TP \fB\-l\fR, \fB\-\-levels=VAL\fR draw up to VAL levels deep [4] .TP \fB\-\-palette=VAL\fR select palette\. available palettes are: size, rainbow, greyscale, monochrome, classic .TP \fB\-\-ring\-gap=VAL\fR leave a gap of VAL pixels between rings .SS "duc ui" The 'ui' subcommand queries the duc database and runs an interactive ncurses utility for exploring the disk usage of the given path\. If no path is given the current working directory is explored\. .P The following keys can be used to navigate and alter the file system: .IP "" 4 .nf up, pgup, j: move cursor up down, pgdn, k: move cursor down home, 0: move cursor to top end, $: move cursor to bottom left, backspace: go up to parent directory (\.\.) right, enter: descent into selected directory a: toggle between actual and apparent disk usage b: toggle between exact and abbreviated sizes c: Toggle between file size and file count h: show help\. press 'q' to return to the main screen n: toggle sort order between 'size' and 'name' o: try to open the file using xdg\-open q, escape: quit .fi .IP "" 0 .P Options for command \fBduc ui [options] [PATH]\fR: .TP \fB\-a\fR, \fB\-\-apparent\fR show apparent instead of actual file size .TP \fB\-b\fR, \fB\-\-bytes\fR show file size in exact number of bytes .TP \fB\-\-count\fR show number of files instead of file size .TP \fB\-d\fR, \fB\-\-database=VAL\fR select database file to use [~/\.duc\.db] .TP \fB\-n\fR, \fB\-\-name\-sort\fR sort output by name instead of by size .TP \fB\-\-no\-color\fR do not use colors on terminal output .SH "CGI INTERFACING" The \fBduc\fR binary has support for a rudimentary CGI interface, currently only tested with apache\. The CGI interface generates a simple HTML page with a list of indexed directories, and shows a clickable graph for navigating the file system\. If the option \fB\-\-list\fR is given, a list of top sized files/dirs is also written\. .P Configuration is done by creating a simple shell script as \.cgi in a directory which is configured for CGI execution by your web server (usually \fB/usr/lib/cgi\-bin\fR)\. The shell script should simply start duc, and pass the location of the database to navigate\. .P An example duc\.cgi script would be .IP "" 4 .nf #!/bin/sh /usr/local/bin/duc cgi \-d /home/jenny/\.duc\.db .fi .IP "" 0 .IP "\[ci]" 4 Make sure the database file is readable by the user (usually www\-data) .IP "\[ci]" 4 Debugging is best done by inspecting the web server's error log .IP "\[ci]" 4 Make sure the \.cgi script has execute permissions (\fBchmod +x duc\.cgi\fR) .IP "" 0 .P Some notes: .IP "\[ci]" 4 The HTML page is generated with a simple embedded CSS style sheet\. If the style is not to your liking you can provide an external CSS url with the \-\-css\-url option which will then be used instead of the embedded style definition\. .IP "\[ci]" 4 Add the option \-\-list to generate a table of top sized files and directories in the HTML page\. .IP "\[ci]" 4 The options \-\-header and \-\-footer allow you to insert your own HTML code before and after the main\. .IP "" 0 .P The current CGI configuration is not very flexible, nor secure\. It is not advised to run the CGI from public reachable web servers, use at your own risk\. .SH "A NOTE ON FILE SIZE AND DISK USAGE" The concepts of 'file size' and 'disk usage' can be a bit confusing\. Files on disk have an apparent size, which indicates how much bytes are in the file from the users point of view; this is the size reported by tools like \fBls \-l\fR\. The apparent size can be any number, from 0 bytes up to several TB\. The actual number of bytes which are used on the filesystem to store the file can differ from this apparent size for a number of reasons: disks store data in blocks, which cause files to always take up a multiple of the block size, files can have holes ('sparse' files), and other technical reasons\. This number is always a multiple of 512, which means that the actual size used for a file is almost always a bit more then its apparent size\. .P Duc has two modes for counting file sizes: .IP "\[ci]" 4 \fBapparent size\fR: this is the size as reported by \fBls\fR\. This number indicates the file length, which is usually smaller then the actual disk usage\. .IP "\[ci]" 4 \fBactual size\fR: this is the size as reported by \fBdu\fR and \fBdf\fR\. The actual file size tells you how much disk is actually used by a file, and is always a multiple of 512 bytes\. .IP "" 0 .P The default mode used by duc is to use the 'actual size'\. Most duc commands to report disk usage (\fBduc ls\fR, \fBduc graph\fR, \fBduc ui\fR, etc) have an option to change between these two modes (usually the \fB\-a\fR), or use the 'a' key to toggle\. .SH "BUILDING from git" If you use git clone to pull down the latest release, you will have to do the following: .P git clone https://github\.com/zevv/duc .br cd duc .br autoreconf \-i .P Then you can run the regular .P \&\./configure [ options ] .br make .P to the regular build of the software\. .P A note for Redhat and derivates users\. The package providing the development file for lmdb (lmdb\-devel) does not include a lmdb\.pc pkgconfig file\. This could lead to errors during the configure phase: .P checking for LMDB\|\.\|\.\|\. no .br configure: error: Package requirements (lmdb) were not met: .P To avoid the need to call pkg\-config, you may set the environment variables .br LMDB_CFLAGS and LMDB_LIBS: .P LMDB_CFLAGS=" " LMDB_LIBS=\-llmdb \./configure \-\-with\-db\-backend=lmdb [ options ] .SH "EXAMPLES" Index the /usr directory, writing to the default database location ~/\.duc\.db: .IP "" 4 .nf $ duc index /usr .fi .IP "" 0 .P List all files and directories under /usr/local, showing relative file sizes in a graph: .IP "" 4 .nf $ duc ls \-Fg /usr/local 4\.7G lib/ [+++++++++++++++++++++++++++++++++++++++++++] 3\.1G share/ [++++++++++++++++++++++++++++ ] 2\.7G src/ [++++++++++++++++++++++++ ] 814\.9M bin/ [+++++++ ] 196\.6M include/ [+ ] 66\.6M x86_64\-w64\-mingw32/ [ ] 59\.9M local/ [ ] 38\.8M i686\-w64\-mingw32/ [ ] 20\.3M sbin/ [ ] 13\.6M lib32/ [ ] 13\.3M libx32/ [ ] .fi .IP "" 0 .P or use the \-R options for the tree view: .IP "" 4 .nf $ duc ls \-RF /etc/logcheck 24\.0K `+\- ignore\.d\.server/ 4\.0K | `+\- hddtemp 4\.0K | |\- ntpdate 4\.0K | |\- lirc 4\.0K | |\- rsyslog 4\.0K | `\- libsasl2\-modules 8\.0K |\- ignore\.d\.workstation/ 4\.0K | `\- lirc 8\.0K `\- ignore\.d\.paranoid/ 4\.0K `\- lirc .fi .IP "" 0 .P Start the graphical interface to explore the file system using sunburst graphs: .IP "" 4 .nf $ duc gui /usr .fi .IP "" 0 .P Generate a graph of /usr/local in \.png format: .IP "" 4 .nf $ duc graph \-o /tmp/usr\.png /usr .fi .IP "" 0 .P The following sample configuration file defines default parameters for the \fBduc ls\fR and \fBduc ui\fR commands and defines a global option to configure the database path which is used by all subcommands .IP "" 4 .nf [global] database /var/cache/duc\.db [ls] recursive classify color [ui] no\-color apparent .fi .IP "" 0 .SH "FREQUENTLY ASKED QUESTIONS" .IP "\[ci]" 4 What does the error 'Database version mismatch mean?' .IP The layout of the index database sometimes changes when new features are implemented\. When you get this error you have probably upgraded to a newer version\. Just remove the old database file and rebuild the index\. .IP "\[ci]" 4 Duc crashes with a segmentation fault, is it that buggy? .IP By default Duc uses the Tokyocabinet database backend\. Tokyocabinet is pretty fast, stores the database in a single file and has nice compression support to keep the database small\. Unfortunately, it is not always robust and sometimes chokes on corrupt database files\. Try to remove the database and rebuild the index\. If the error persists contact the authors\. .IP "\[ci]" 4 Some of the Duc subcommands like \fBduc gui\fR are not available on my system? .IP Depending on the configuration that was chosen when building Duc, some options might or might not be available in the \fBduc\fR utility\. For example, on Debian or Ubuntu Duc comes in two flavours: there is a full featured package called \fBduc\fR, or a package without dependencies on X\-windows called \fBduc\-nox\fR, for which the latter lacks the \fBduc gui\fR command\. .IP "\[ci]" 4 \fBduc index\fR is hogging my system and using a lot of CPU and I/O! .IP Traversing a file system is hard work \- which is the exact reason why Duc exists in the first place\. You can use the default tools to make Duc behave nice towards other processes on your machine, use something like: .IP \fBnice 19 ionice \-c 3 duc index [options]\fR .IP This makes \fBduc index\fR run with the lowest CPU and I/O scheduler priorities, which is nicer to all the other processes on your machine\. .IP "" 0 .SH "FILES" At startup duc tries to read its configuration from three locations in this particular order: \fB/etc/ducrc\fR, \fB~/\.config/duc/ducrc\fR, \fB~/\.ducrc\fR and \fB\./\.ducrc\fR\. .P Duc mainains an index of scanned directories, which defaults to ~/\.duc\.db\. All tools take the \-d/\-\-database option to override the database path\. .SH "AUTHORS" .IP "\[ci]" 4 Ico Doornekamp \fIduc@zevv\.nl\fR .IP "\[ci]" 4 John Stoffel \fIjohn@stoffel\.org\fR .IP "" 0 .P Other contributors can be found in the Git log at GitHub\. .SH "LICENSE" Duc 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; version 2 dated June, 1991\. Duc is distributed in the hope that 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\. zevv-duc-b8f9659/doc/duc.1.html000066400000000000000000000746331426703022500162160ustar00rootroot00000000000000 duc(1) - index, query and graph disk usage
  1. duc(1)
  2. duc(1)

NAME

duc - index, query and graph disk usage

SYNOPSIS

duc subcommand options

DESCRIPTION

Duc is a collection of tools for inspecting and visualizing disk usage.

Duc maintains an indexed database of accumulated sizes of directories of your file system, and allows you to query this database with some tools, or create fancy sunburst graphs to show you where your bytes are.

Duc scales quite well, it has been tested on systems with more then 500 million files and several petabytes of storage.

USAGE

Duc comes with a command line tool called duc, which is used to create, maintain and query the disk usage database. run duc help to get a list of available commands. duc help <subcommand> describes the usage of a specific subcommand. Run duc help --all for an extensive list of all commands and their options.

Some commands might not be available on your system, depending on the exact configuration chosen when building Duc. (For example, the duc gui command is not available in the duc-nox package on Debian and Ubuntu)

Duc allows any option to be placed either on the command line or in a configuration file. Options on the command line are preceded by a double-leading-dash (--option), some options have a corresponding short option which can be used as well with a single leading dash. (-o)

At startup duc tries to read its configuration from three locations in this particular order: /etc/ducrc, ~/.config/duc/ducrc, ~/.ducrc and ./.ducrc.

A configuration file consists of sections and parameters. The section names correspond to the duc subcommands for which the parameters in that section apply. A section begins with the name of the section in square brackets and continues until the next section begins. Sections contain parameters, one per line, which consist of a single option name for boolean flags, or an option name and a value for options which take a value. See the EXAMPLES section for an example of the configuration file format.

CREATING THE INDEX

Duc needs an index file of the file system before it is able to show any information. To create the index, run the duc index command. For example, to create an index of your home directory run duc index ~

$ duc index /usr
Skipping lost+found: Permission denied
Indexed 333823 files and 48200 directories, (35.0GB total) in 1 seconds

The default location of the database is $HOME/.duc.db. To use a different database location, use the DUC_DATABASE environment variable or specify the database location with the --database argument.

You can run duc index at any time later to rebuild the index.

By default Duc indexes all directories it encounters during file system traversal, including special file systems like /proc and /sys, and network file systems like NFS or Samba mounts. There are a few options to select what parts of your filesystem you want to include or exclude from the scan, check the documentation below for the options --one-file-system, --exclude, --fs-exclude and --fs-include for more details.

QUERYING THE INDEX

Duc has various subcommands for querying or exploring the index: (Note that depending on your configuration, some of these commands might not be available)

  • duc info shows a list of available directory trees in the database, and the time and date of the last scan.

  • duc ls lists all files and directories under the given path on the console.

  • duc ui runs a ncurses based console user interface for exploring the file system usage.

  • duc gui starts a graphical (X11) interface representing the file system in a sunburst graph. Click on a directory to redraw the graph from the perspective of the selected directory. Click in the center of the graph to go up one directory in the tree.

OPTIONS

This section list all available subcommands and describes their usage and options.

Global options

These options apply to all Duc subcommands:

--debug
increase verbosity to debug level
-h, --help
show help
-q, --quiet
quiet mode, do not print any warning
-v, --verbose
increase verbosity
--version
output version information and exit

duc help

Options for command duc help [options]:

-a, --all
show complete help for all commands

duc index

The 'index' subcommand performs a recursive scan of the given paths on the filesystem and calculates the inclusive size of all directories. The results are written to the index, and can later be queried by one of the other duc tools.

Options for command duc index [options] PATH ...:

-b, --bytes
show file size in exact number of bytes
-d, --database=VAL
use database file VAL
-e, --exclude=VAL
exclude files matching VAL
-H, --check-hard-links
count hard links only once. if two or more hard links point to the same file, only one of the hard links is displayed and counted
-f, --force
force writing in case of corrupted db
--fs-exclude=VAL
exclude file system type VAL during indexing. VAL is a comma separated list of file system types as found in your systems fstab, for example ext3,ext4,dosfs
--fs-include=VAL
include file system type VAL during indexing. VAL is a comma separated list of file system types as found in your systems fstab, for example ext3,ext4,dosfs
--hide-file-names
hide file names in index (privacy). the names of directories will be preserved, but the names of the individual files will be hidden
-U, --uid=VAL
limit index to only files/dirs owned by uid
-u, --username=VAL
limit index to only files/dirs owned by username
-m, --max-depth=VAL
limit directory names to given depth. when this option is given duc will traverse the complete file system, but will only the first VAL levels of directories in the database to reduce the size of the index
-x, --one-file-system
skip directories on different file systems
-p, --progress
show progress during indexing
--dry-run
do not update database, just crawl
--uncompressed
do not use compression for database. Duc enables compression if the underlying database supports this. This reduces index size at the cost of slightly longer indexing time

duc info

Options for command duc info [options]:

-a, --apparent
show apparent instead of actual file size
-b, --bytes
show file size in exact number of bytes
-d, --database=VAL
select database file to use [~/.duc.db]

duc ls

The 'ls' subcommand queries the duc database and lists the inclusive size of all files and directories on the given path. If no path is given the current working directory is listed.

Options for command duc ls [options] [PATH]...:

-a, --apparent
show apparent instead of actual file size
--ascii
use ASCII characters instead of UTF-8 to draw tree
-b, --bytes
show file size in exact number of bytes
-F, --classify
append file type indicator (one of */) to entries
-c, --color
colorize output (only on ttys)
--count
show number of files instead of file size
-d, --database=VAL
select database file to use [~/.duc.db]
-D, --directory
list directory itself, not its contents
--dirs-only
list only directories, skip individual files
--full-path
show full path instead of tree in recursive view
-g, --graph
draw graph with relative size for each entry
-l, --levels=VAL
traverse up to ARG levels deep [4]
-n, --name-sort
sort output by name instead of by size
-R, --recursive
recursively list subdirectories

duc xml

Options for command duc xml [options] [PATH]:

-a, --apparent
interpret min_size/-s value as apparent size
-d, --database=VAL
select database file to use [~/.duc.db]
-x, --exclude-files
exclude file from xml output, only include directories
-s, --min_size=VAL
specify min size for files or directories

duc json

Options for command duc json [options] [PATH]:

-a, --apparent
interpret min_size/-s value as apparent size
-d, --database=VAL
select database file to use [~/.duc.db]
-x, --exclude-files
exclude file from json output, only include directories
-s, --min_size=VAL
specify min size for files or directories

duc graph

The 'graph' subcommand queries the duc database and generates a sunburst graph showing the disk usage of the given path. If no path is given a graph is created for the current working directory.

By default the graph is written to the file 'duc.png', which can be overridden by using the -o/--output option. The output can be sent to stdout by using the special file name '-'.

Options for command duc graph [options] [PATH]:

-a, --apparent
Show apparent instead of actual file size
-d, --database=VAL
select database file to use [~/.duc.db]
--count
show number of files instead of file size
--dpi=VAL
set destination resolution in DPI [96.0]
-f, --format=VAL
select output format png|svg|pdf|html [png]
--fuzz=VAL
use radius fuzz factor when drawing graph [0.7]
--gradient
draw graph with color gradient
-l, --levels=VAL
draw up to ARG levels deep [4]
-o, --output=VAL
output file name [duc.png]
--palette=VAL
select palette. available palettes are: size, rainbow, greyscale, monochrome, classic
--ring-gap=VAL
leave a gap of VAL pixels between rings
-s, --size=VAL
image size [800]

duc cgi

Options for command duc cgi [options] [PATH]:

-a, --apparent
Show apparent instead of actual file size
-b, --bytes
show file size in exact number of bytes
--count
show number of files instead of file size
--css-url=VAL
url of CSS style sheet to use instead of default CSS
-d, --database=VAL
select database file to use [~/.duc.db]
--dpi=VAL
set destination resolution in DPI [96.0]
--footer=VAL
select HTML file to include as footer
--fuzz=VAL
use radius fuzz factor when drawing graph [0.7]
--gradient
draw graph with color gradient
--header=VAL
select HTML file to include as header
-l, --levels=VAL
draw up to ARG levels deep [4]
--list
generate table with file list
--palette=VAL
select palette. available palettes are: size, rainbow, greyscale, monochrome, classic
--ring-gap=VAL
leave a gap of VAL pixels between rings
-s, --size=VAL
image size [800]
--tooltip
enable tooltip when hovering over the graph. enabling the tooltip will cause an asynchronous HTTP request every time the mouse is moved and can greatly increase the HTTP traffic to the web server

duc gui

The 'gui' subcommand queries the duc database and runs an interactive graphical utility for exploring the disk usage of the given path. If no path is given the current working directory is explored.

The following keys can be used to navigate and alter the graph:

+           increase maximum graph depth
-           decrease maximum graph depth
0           Set default graph depth
a           Toggle between apparent and actual disk usage
b           Toggle between exact byte count and abbreviated sizes
c           Toggle between file size and file count
f           toggle graph fuzz
g           toggle graph gradient
p           toggle palettes
backspace   go up one directory

Options for command duc gui [options] [PATH]:

-a, --apparent
show apparent instead of actual file size
-b, --bytes
show file size in exact number of bytes
--count
show number of files instead of file size
--dark
use dark background color
-d, --database=VAL
select database file to use [~/.duc.db]
--fuzz=VAL
use radius fuzz factor when drawing graph
--gradient
draw graph with color gradient
-l, --levels=VAL
draw up to VAL levels deep [4]
--palette=VAL
select palette. available palettes are: size, rainbow, greyscale, monochrome, classic
--ring-gap=VAL
leave a gap of VAL pixels between rings

duc ui

The 'ui' subcommand queries the duc database and runs an interactive ncurses utility for exploring the disk usage of the given path. If no path is given the current working directory is explored.

The following keys can be used to navigate and alter the file system:

up, pgup, j:     move cursor up
down, pgdn, k:   move cursor down
home, 0:         move cursor to top
end, $:          move cursor to bottom
left, backspace: go up to parent directory (..)
right, enter:    descent into selected directory
a:               toggle between actual and apparent disk usage
b:               toggle between exact and abbreviated sizes
c:               Toggle between file size and file count
h:               show help. press 'q' to return to the main screen
n:               toggle sort order between 'size' and 'name'
o:               try to open the file using xdg-open
q, escape:       quit

Options for command duc ui [options] [PATH]:

-a, --apparent
show apparent instead of actual file size
-b, --bytes
show file size in exact number of bytes
--count
show number of files instead of file size
-d, --database=VAL
select database file to use [~/.duc.db]
-n, --name-sort
sort output by name instead of by size
--no-color
do not use colors on terminal output

CGI INTERFACING

The duc binary has support for a rudimentary CGI interface, currently only tested with apache. The CGI interface generates a simple HTML page with a list of indexed directories, and shows a clickable graph for navigating the file system. If the option --list is given, a list of top sized files/dirs is also written.

Configuration is done by creating a simple shell script as .cgi in a directory which is configured for CGI execution by your web server (usually /usr/lib/cgi-bin). The shell script should simply start duc, and pass the location of the database to navigate.

An example duc.cgi script would be

#!/bin/sh
/usr/local/bin/duc cgi -d /home/jenny/.duc.db
  • Make sure the database file is readable by the user (usually www-data)
  • Debugging is best done by inspecting the web server's error log
  • Make sure the .cgi script has execute permissions (chmod +x duc.cgi)

Some notes:

  • The HTML page is generated with a simple embedded CSS style sheet. If the style is not to your liking you can provide an external CSS url with the --css-url option which will then be used instead of the embedded style definition.

  • Add the option --list to generate a table of top sized files and directories in the HTML page.

  • The options --header and --footer allow you to insert your own HTML code before and after the main.

The current CGI configuration is not very flexible, nor secure. It is not advised to run the CGI from public reachable web servers, use at your own risk.

A NOTE ON FILE SIZE AND DISK USAGE

The concepts of 'file size' and 'disk usage' can be a bit confusing. Files on disk have an apparent size, which indicates how much bytes are in the file from the users point of view; this is the size reported by tools like ls -l. The apparent size can be any number, from 0 bytes up to several TB. The actual number of bytes which are used on the filesystem to store the file can differ from this apparent size for a number of reasons: disks store data in blocks, which cause files to always take up a multiple of the block size, files can have holes ('sparse' files), and other technical reasons. This number is always a multiple of 512, which means that the actual size used for a file is almost always a bit more then its apparent size.

Duc has two modes for counting file sizes:

  • apparent size: this is the size as reported by ls. This number indicates the file length, which is usually smaller then the actual disk usage.

  • actual size: this is the size as reported by du and df. The actual file size tells you how much disk is actually used by a file, and is always a multiple of 512 bytes.

The default mode used by duc is to use the 'actual size'. Most duc commands to report disk usage (duc ls, duc graph, duc ui, etc) have an option to change between these two modes (usually the -a), or use the 'a' key to toggle.

BUILDING from git

If you use git clone to pull down the latest release, you will have to do the following:

git clone https://github.com/zevv/duc
cd duc
autoreconf -i

Then you can run the regular

./configure [ options ]
make

to the regular build of the software.

A note for Redhat and derivates users. The package providing the development file for lmdb (lmdb-devel) does not include a lmdb.pc pkgconfig file. This could lead to errors during the configure phase:

checking for LMDB... no
configure: error: Package requirements (lmdb) were not met:

To avoid the need to call pkg-config, you may set the environment variables
LMDB_CFLAGS and LMDB_LIBS:

LMDB_CFLAGS=" " LMDB_LIBS=-llmdb ./configure --with-db-backend=lmdb [ options ]

EXAMPLES

Index the /usr directory, writing to the default database location ~/.duc.db:

$ duc index /usr

List all files and directories under /usr/local, showing relative file sizes in a graph:

$ duc ls -Fg /usr/local
  4.7G lib/                 [+++++++++++++++++++++++++++++++++++++++++++]
  3.1G share/               [++++++++++++++++++++++++++++               ]
  2.7G src/                 [++++++++++++++++++++++++                   ]
814.9M bin/                 [+++++++                                    ]
196.6M include/             [+                                          ]
 66.6M x86_64-w64-mingw32/  [                                           ]
 59.9M local/               [                                           ]
 38.8M i686-w64-mingw32/    [                                           ]
 20.3M sbin/                [                                           ]
 13.6M lib32/               [                                           ]
 13.3M libx32/              [                                           ]

or use the -R options for the tree view:

$ duc ls -RF /etc/logcheck
 24.0K `+- ignore.d.server/
  4.0K  |  `+- hddtemp 
  4.0K  |   |- ntpdate 
  4.0K  |   |- lirc 
  4.0K  |   |- rsyslog 
  4.0K  |   `- libsasl2-modules 
  8.0K  |- ignore.d.workstation/
  4.0K  |   `- lirc 
  8.0K  `- ignore.d.paranoid/
  4.0K      `- lirc 

Start the graphical interface to explore the file system using sunburst graphs:

$ duc gui /usr

Generate a graph of /usr/local in .png format:

$ duc graph -o /tmp/usr.png /usr

The following sample configuration file defines default parameters for the duc ls and duc ui commands and defines a global option to configure the database path which is used by all subcommands

[global]
database /var/cache/duc.db
 
[ls]
recursive
classify
color

[ui]
no-color
apparent

FREQUENTLY ASKED QUESTIONS

  • What does the error 'Database version mismatch mean?'

    The layout of the index database sometimes changes when new features are implemented. When you get this error you have probably upgraded to a newer version. Just remove the old database file and rebuild the index.

  • Duc crashes with a segmentation fault, is it that buggy?

    By default Duc uses the Tokyocabinet database backend. Tokyocabinet is pretty fast, stores the database in a single file and has nice compression support to keep the database small. Unfortunately, it is not always robust and sometimes chokes on corrupt database files. Try to remove the database and rebuild the index. If the error persists contact the authors.

  • Some of the Duc subcommands like duc gui are not available on my system?

    Depending on the configuration that was chosen when building Duc, some options might or might not be available in the duc utility. For example, on Debian or Ubuntu Duc comes in two flavours: there is a full featured package called duc, or a package without dependencies on X-windows called duc-nox, for which the latter lacks the duc gui command.

  • duc index is hogging my system and using a lot of CPU and I/O!

    Traversing a file system is hard work - which is the exact reason why Duc exists in the first place. You can use the default tools to make Duc behave nice towards other processes on your machine, use something like:

    nice 19 ionice -c 3 duc index [options]

    This makes duc index run with the lowest CPU and I/O scheduler priorities, which is nicer to all the other processes on your machine.

FILES

At startup duc tries to read its configuration from three locations in this particular order: /etc/ducrc, ~/.config/duc/ducrc, ~/.ducrc and ./.ducrc.

Duc mainains an index of scanned directories, which defaults to ~/.duc.db. All tools take the -d/--database option to override the database path.

AUTHORS

Other contributors can be found in the Git log at GitHub.

LICENSE

Duc 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; version 2 dated June, 1991. Duc is distributed in the hope that 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.

  1. July 2022
  2. duc(1)
zevv-duc-b8f9659/doc/duc.md000066400000000000000000000535741426703022500155140ustar00rootroot00000000000000 duc(1) -- index, query and graph disk usage =========================================== ## SYNOPSIS `duc` [options] ## DESCRIPTION Duc is a collection of tools for inspecting and visualizing disk usage. Duc maintains an indexed database of accumulated sizes of directories of your file system, and allows you to query this database with some tools, or create fancy sunburst graphs to show you where your bytes are. Duc scales quite well, it has been tested on systems with more then 500 million files and several petabytes of storage. ## USAGE Duc comes with a command line tool called `duc`, which is used to create, maintain and query the disk usage database. run `duc help` to get a list of available commands. `duc help ` describes the usage of a specific subcommand. Run `duc help --all` for an extensive list of all commands and their options. Some commands might not be available on your system, depending on the exact configuration chosen when building Duc. (For example, the `duc gui` command is not available in the `duc-nox` package on Debian and Ubuntu) Duc allows any option to be placed either on the command line or in a configuration file. Options on the command line are preceded by a double-leading-dash (`--option`), some options have a corresponding short option which can be used as well with a single leading dash. (`-o`) At startup duc tries to read its configuration from three locations in this particular order: `/etc/ducrc`, `~/.config/duc/ducrc`, `~/.ducrc` and `./.ducrc`. A configuration file consists of sections and parameters. The section names correspond to the duc subcommands for which the parameters in that section apply. A section begins with the name of the section in square brackets and continues until the next section begins. Sections contain parameters, one per line, which consist of a single option name for boolean flags, or an option name and a value for options which take a value. See the EXAMPLES section for an example of the configuration file format. ## CREATING THE INDEX Duc needs an index file of the file system before it is able to show any information. To create the index, run the `duc index` command. For example, to create an index of your home directory run `duc index ~` $ duc index /usr Skipping lost+found: Permission denied Indexed 333823 files and 48200 directories, (35.0GB total) in 1 seconds The default location of the database is `$HOME/.duc.db`. To use a different database location, use the DUC_DATABASE environment variable or specify the database location with the --database argument. You can run `duc index` at any time later to rebuild the index. By default Duc indexes all directories it encounters during file system traversal, including special file systems like /proc and /sys, and network file systems like NFS or Samba mounts. There are a few options to select what parts of your filesystem you want to include or exclude from the scan, check the documentation below for the options --one-file-system, --exclude, --fs-exclude and --fs-include for more details. ## QUERYING THE INDEX Duc has various subcommands for querying or exploring the index: (Note that depending on your configuration, some of these commands might not be available) * `duc info` shows a list of available directory trees in the database, and the time and date of the last scan. * `duc ls` lists all files and directories under the given path on the console. * `duc ui` runs a ncurses based console user interface for exploring the file system usage. * `duc gui` starts a graphical (X11) interface representing the file system in a sunburst graph. Click on a directory to redraw the graph from the perspective of the selected directory. Click in the center of the graph to go up one directory in the tree. ## OPTIONS This section list all available subcommands and describes their usage and options. ### Global options These options apply to all Duc subcommands: * `--debug`: increase verbosity to debug level * `-h`, `--help`: show help * `-q`, `--quiet`: quiet mode, do not print any warning * `-v`, `--verbose`: increase verbosity * `--version`: output version information and exit ### duc help Options for command `duc help [options]`: * `-a`, `--all`: show complete help for all commands ### duc index The 'index' subcommand performs a recursive scan of the given paths on the filesystem and calculates the inclusive size of all directories. The results are written to the index, and can later be queried by one of the other duc tools. Options for command `duc index [options] PATH ...`: * `-b`, `--bytes`: show file size in exact number of bytes * `-d`, `--database=VAL`: use database file VAL * `-e`, `--exclude=VAL`: exclude files matching VAL * `-H`, `--check-hard-links`: count hard links only once. if two or more hard links point to the same file, only one of the hard links is displayed and counted * `-f`, `--force`: force writing in case of corrupted db * `--fs-exclude=VAL`: exclude file system type VAL during indexing. VAL is a comma separated list of file system types as found in your systems fstab, for example ext3,ext4,dosfs * `--fs-include=VAL`: include file system type VAL during indexing. VAL is a comma separated list of file system types as found in your systems fstab, for example ext3,ext4,dosfs * `--hide-file-names`: hide file names in index (privacy). the names of directories will be preserved, but the names of the individual files will be hidden * `-U`, `--uid=VAL`: limit index to only files/dirs owned by uid * `-u`, `--username=VAL`: limit index to only files/dirs owned by username * `-m`, `--max-depth=VAL`: limit directory names to given depth. when this option is given duc will traverse the complete file system, but will only the first VAL levels of directories in the database to reduce the size of the index * `-x`, `--one-file-system`: skip directories on different file systems * `-p`, `--progress`: show progress during indexing * `--dry-run`: do not update database, just crawl * `--uncompressed`: do not use compression for database. Duc enables compression if the underlying database supports this. This reduces index size at the cost of slightly longer indexing time ### duc info Options for command `duc info [options]`: * `-a`, `--apparent`: show apparent instead of actual file size * `-b`, `--bytes`: show file size in exact number of bytes * `-d`, `--database=VAL`: select database file to use [~/.duc.db] ### duc ls The 'ls' subcommand queries the duc database and lists the inclusive size of all files and directories on the given path. If no path is given the current working directory is listed. Options for command `duc ls [options] [PATH]...`: * `-a`, `--apparent`: show apparent instead of actual file size * `--ascii`: use ASCII characters instead of UTF-8 to draw tree * `-b`, `--bytes`: show file size in exact number of bytes * `-F`, `--classify`: append file type indicator (one of */) to entries * `-c`, `--color`: colorize output (only on ttys) * `--count`: show number of files instead of file size * `-d`, `--database=VAL`: select database file to use [~/.duc.db] * `-D`, `--directory`: list directory itself, not its contents * `--dirs-only`: list only directories, skip individual files * `--full-path`: show full path instead of tree in recursive view * `-g`, `--graph`: draw graph with relative size for each entry * `-l`, `--levels=VAL`: traverse up to ARG levels deep [4] * `-n`, `--name-sort`: sort output by name instead of by size * `-R`, `--recursive`: recursively list subdirectories ### duc xml Options for command `duc xml [options] [PATH]`: * `-a`, `--apparent`: interpret min_size/-s value as apparent size * `-d`, `--database=VAL`: select database file to use [~/.duc.db] * `-x`, `--exclude-files`: exclude file from xml output, only include directories * `-s`, `--min_size=VAL`: specify min size for files or directories ### duc json Options for command `duc json [options] [PATH]`: * `-a`, `--apparent`: interpret min_size/-s value as apparent size * `-d`, `--database=VAL`: select database file to use [~/.duc.db] * `-x`, `--exclude-files`: exclude file from json output, only include directories * `-s`, `--min_size=VAL`: specify min size for files or directories ### duc graph The 'graph' subcommand queries the duc database and generates a sunburst graph showing the disk usage of the given path. If no path is given a graph is created for the current working directory. By default the graph is written to the file 'duc.png', which can be overridden by using the -o/--output option. The output can be sent to stdout by using the special file name '-'. Options for command `duc graph [options] [PATH]`: * `-a`, `--apparent`: Show apparent instead of actual file size * `-d`, `--database=VAL`: select database file to use [~/.duc.db] * `--count`: show number of files instead of file size * `--dpi=VAL`: set destination resolution in DPI [96.0] * `-f`, `--format=VAL`: select output format [png] * `--fuzz=VAL`: use radius fuzz factor when drawing graph [0.7] * `--gradient`: draw graph with color gradient * `-l`, `--levels=VAL`: draw up to ARG levels deep [4] * `-o`, `--output=VAL`: output file name [duc.png] * `--palette=VAL`: select palette. available palettes are: size, rainbow, greyscale, monochrome, classic * `--ring-gap=VAL`: leave a gap of VAL pixels between rings * `-s`, `--size=VAL`: image size [800] ### duc cgi Options for command `duc cgi [options] [PATH]`: * `-a`, `--apparent`: Show apparent instead of actual file size * `-b`, `--bytes`: show file size in exact number of bytes * `--count`: show number of files instead of file size * `--css-url=VAL`: url of CSS style sheet to use instead of default CSS * `-d`, `--database=VAL`: select database file to use [~/.duc.db] * `--dpi=VAL`: set destination resolution in DPI [96.0] * `--footer=VAL`: select HTML file to include as footer * `--fuzz=VAL`: use radius fuzz factor when drawing graph [0.7] * `--gradient`: draw graph with color gradient * `--header=VAL`: select HTML file to include as header * `-l`, `--levels=VAL`: draw up to ARG levels deep [4] * `--list`: generate table with file list * `--palette=VAL`: select palette. available palettes are: size, rainbow, greyscale, monochrome, classic * `--ring-gap=VAL`: leave a gap of VAL pixels between rings * `-s`, `--size=VAL`: image size [800] * `--tooltip`: enable tooltip when hovering over the graph. enabling the tooltip will cause an asynchronous HTTP request every time the mouse is moved and can greatly increase the HTTP traffic to the web server ### duc gui The 'gui' subcommand queries the duc database and runs an interactive graphical utility for exploring the disk usage of the given path. If no path is given the current working directory is explored. The following keys can be used to navigate and alter the graph: + increase maximum graph depth - decrease maximum graph depth 0 Set default graph depth a Toggle between apparent and actual disk usage b Toggle between exact byte count and abbreviated sizes c Toggle between file size and file count f toggle graph fuzz g toggle graph gradient p toggle palettes backspace go up one directory Options for command `duc gui [options] [PATH]`: * `-a`, `--apparent`: show apparent instead of actual file size * `-b`, `--bytes`: show file size in exact number of bytes * `--count`: show number of files instead of file size * `--dark`: use dark background color * `-d`, `--database=VAL`: select database file to use [~/.duc.db] * `--fuzz=VAL`: use radius fuzz factor when drawing graph * `--gradient`: draw graph with color gradient * `-l`, `--levels=VAL`: draw up to VAL levels deep [4] * `--palette=VAL`: select palette. available palettes are: size, rainbow, greyscale, monochrome, classic * `--ring-gap=VAL`: leave a gap of VAL pixels between rings ### duc ui The 'ui' subcommand queries the duc database and runs an interactive ncurses utility for exploring the disk usage of the given path. If no path is given the current working directory is explored. The following keys can be used to navigate and alter the file system: up, pgup, j: move cursor up down, pgdn, k: move cursor down home, 0: move cursor to top end, $: move cursor to bottom left, backspace: go up to parent directory (..) right, enter: descent into selected directory a: toggle between actual and apparent disk usage b: toggle between exact and abbreviated sizes c: Toggle between file size and file count h: show help. press 'q' to return to the main screen n: toggle sort order between 'size' and 'name' o: try to open the file using xdg-open q, escape: quit Options for command `duc ui [options] [PATH]`: * `-a`, `--apparent`: show apparent instead of actual file size * `-b`, `--bytes`: show file size in exact number of bytes * `--count`: show number of files instead of file size * `-d`, `--database=VAL`: select database file to use [~/.duc.db] * `-n`, `--name-sort`: sort output by name instead of by size * `--no-color`: do not use colors on terminal output ## CGI INTERFACING The `duc` binary has support for a rudimentary CGI interface, currently only tested with apache. The CGI interface generates a simple HTML page with a list of indexed directories, and shows a clickable graph for navigating the file system. If the option `--list` is given, a list of top sized files/dirs is also written. Configuration is done by creating a simple shell script as .cgi in a directory which is configured for CGI execution by your web server (usually `/usr/lib/cgi-bin`). The shell script should simply start duc, and pass the location of the database to navigate. An example duc.cgi script would be #!/bin/sh /usr/local/bin/duc cgi -d /home/jenny/.duc.db * Make sure the database file is readable by the user (usually www-data) * Debugging is best done by inspecting the web server's error log * Make sure the .cgi script has execute permissions (`chmod +x duc.cgi`) Some notes: * The HTML page is generated with a simple embedded CSS style sheet. If the style is not to your liking you can provide an external CSS url with the --css-url option which will then be used instead of the embedded style definition. * Add the option --list to generate a table of top sized files and directories in the HTML page. * The options --header and --footer allow you to insert your own HTML code before and after the main. The current CGI configuration is not very flexible, nor secure. It is not advised to run the CGI from public reachable web servers, use at your own risk. ## A NOTE ON FILE SIZE AND DISK USAGE The concepts of 'file size' and 'disk usage' can be a bit confusing. Files on disk have an apparent size, which indicates how much bytes are in the file from the users point of view; this is the size reported by tools like `ls -l`. The apparent size can be any number, from 0 bytes up to several TB. The actual number of bytes which are used on the filesystem to store the file can differ from this apparent size for a number of reasons: disks store data in blocks, which cause files to always take up a multiple of the block size, files can have holes ('sparse' files), and other technical reasons. This number is always a multiple of 512, which means that the actual size used for a file is almost always a bit more then its apparent size. Duc has two modes for counting file sizes: - `apparent size`: this is the size as reported by `ls`. This number indicates the file length, which is usually smaller then the actual disk usage. - `actual size`: this is the size as reported by `du` and `df`. The actual file size tells you how much disk is actually used by a file, and is always a multiple of 512 bytes. The default mode used by duc is to use the 'actual size'. Most duc commands to report disk usage (`duc ls`, `duc graph`, `duc ui`, etc) have an option to change between these two modes (usually the `-a`), or use the 'a' key to toggle. ## BUILDING from git If you use git clone to pull down the latest release, you will have to do the following: git clone https://github.com/zevv/duc cd duc autoreconf -i Then you can run the regular ./configure [ options ] make to the regular build of the software. A note for Redhat and derivates users. The package providing the development file for lmdb (lmdb-devel) does not include a lmdb.pc pkgconfig file. This could lead to errors during the configure phase: checking for LMDB... no configure: error: Package requirements (lmdb) were not met: To avoid the need to call pkg-config, you may set the environment variables LMDB_CFLAGS and LMDB_LIBS: LMDB_CFLAGS=" " LMDB_LIBS=-llmdb ./configure --with-db-backend=lmdb [ options ] ## EXAMPLES Index the /usr directory, writing to the default database location ~/.duc.db: $ duc index /usr List all files and directories under /usr/local, showing relative file sizes in a graph: $ duc ls -Fg /usr/local 4.7G lib/ [+++++++++++++++++++++++++++++++++++++++++++] 3.1G share/ [++++++++++++++++++++++++++++ ] 2.7G src/ [++++++++++++++++++++++++ ] 814.9M bin/ [+++++++ ] 196.6M include/ [+ ] 66.6M x86_64-w64-mingw32/ [ ] 59.9M local/ [ ] 38.8M i686-w64-mingw32/ [ ] 20.3M sbin/ [ ] 13.6M lib32/ [ ] 13.3M libx32/ [ ] or use the -R options for the tree view: $ duc ls -RF /etc/logcheck 24.0K `+- ignore.d.server/ 4.0K | `+- hddtemp 4.0K | |- ntpdate 4.0K | |- lirc 4.0K | |- rsyslog 4.0K | `- libsasl2-modules 8.0K |- ignore.d.workstation/ 4.0K | `- lirc 8.0K `- ignore.d.paranoid/ 4.0K `- lirc Start the graphical interface to explore the file system using sunburst graphs: $ duc gui /usr Generate a graph of /usr/local in .png format: $ duc graph -o /tmp/usr.png /usr The following sample configuration file defines default parameters for the `duc ls` and `duc ui` commands and defines a global option to configure the database path which is used by all subcommands [global] database /var/cache/duc.db [ls] recursive classify color [ui] no-color apparent ## FREQUENTLY ASKED QUESTIONS * What does the error 'Database version mismatch mean?' The layout of the index database sometimes changes when new features are implemented. When you get this error you have probably upgraded to a newer version. Just remove the old database file and rebuild the index. * Duc crashes with a segmentation fault, is it that buggy? By default Duc uses the Tokyocabinet database backend. Tokyocabinet is pretty fast, stores the database in a single file and has nice compression support to keep the database small. Unfortunately, it is not always robust and sometimes chokes on corrupt database files. Try to remove the database and rebuild the index. If the error persists contact the authors. * Some of the Duc subcommands like `duc gui` are not available on my system? Depending on the configuration that was chosen when building Duc, some options might or might not be available in the `duc` utility. For example, on Debian or Ubuntu Duc comes in two flavours: there is a full featured package called `duc`, or a package without dependencies on X-windows called `duc-nox`, for which the latter lacks the `duc gui` command. * `duc index` is hogging my system and using a lot of CPU and I/O! Traversing a file system is hard work - which is the exact reason why Duc exists in the first place. You can use the default tools to make Duc behave nice towards other processes on your machine, use something like: `nice 19 ionice -c 3 duc index [options]` This makes `duc index` run with the lowest CPU and I/O scheduler priorities, which is nicer to all the other processes on your machine. ## FILES At startup duc tries to read its configuration from three locations in this particular order: `/etc/ducrc`, `~/.config/duc/ducrc`, `~/.ducrc` and `./.ducrc`. Duc mainains an index of scanned directories, which defaults to ~/.duc.db. All tools take the -d/--database option to override the database path. ## AUTHORS * Ico Doornekamp * John Stoffel Other contributors can be found in the Git log at GitHub. ## LICENSE Duc 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; version 2 dated June, 1991. Duc is distributed in the hope that 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. zevv-duc-b8f9659/doc/manual.txt000066400000000000000000000300671426703022500164250ustar00rootroot00000000000000 duc(1) -- index, query and graph disk usage =========================================== ## SYNOPSIS `duc` [options] ## DESCRIPTION Duc is a collection of tools for inspecting and visualizing disk usage. Duc maintains an indexed database of accumulated sizes of directories of your file system, and allows you to query this database with some tools, or create fancy sunburst graphs to show you where your bytes are. Duc scales quite well, it has been tested on systems with more then 500 million files and several petabytes of storage. ## USAGE Duc comes with a command line tool called `duc`, which is used to create, maintain and query the disk usage database. run `duc help` to get a list of available commands. `duc help ` describes the usage of a specific subcommand. Run `duc help --all` for an extensive list of all commands and their options. Some commands might not be available on your system, depending on the exact configuration chosen when building Duc. (For example, the `duc gui` command is not available in the `duc-nox` package on Debian and Ubuntu) Duc allows any option to be placed either on the command line or in a configuration file. Options on the command line are preceded by a double-leading-dash (`--option`), some options have a corresponding short option which can be used as well with a single leading dash. (`-o`) At startup duc tries to read its configuration from three locations in this particular order: `/etc/ducrc`, `~/.config/duc/ducrc`, `~/.ducrc` and `./.ducrc`. A configuration file consists of sections and parameters. The section names correspond to the duc subcommands for which the parameters in that section apply. A section begins with the name of the section in square brackets and continues until the next section begins. Sections contain parameters, one per line, which consist of a single option name for boolean flags, or an option name and a value for options which take a value. See the EXAMPLES section for an example of the configuration file format. ## CREATING THE INDEX Duc needs an index file of the file system before it is able to show any information. To create the index, run the `duc index` command. For example, to create an index of your home directory run `duc index ~` $ duc index /usr Skipping lost+found: Permission denied Indexed 333823 files and 48200 directories, (35.0GB total) in 1 seconds The default location of the database is `$HOME/.duc.db`. To use a different database location, use the DUC_DATABASE environment variable or specify the database location with the --database argument. You can run `duc index` at any time later to rebuild the index. By default Duc indexes all directories it encounters during file system traversal, including special file systems like /proc and /sys, and network file systems like NFS or Samba mounts. There are a few options to select what parts of your filesystem you want to include or exclude from the scan, check the documentation below for the options --one-file-system, --exclude, --fs-exclude and --fs-include for more details. ## QUERYING THE INDEX Duc has various subcommands for querying or exploring the index: (Note that depending on your configuration, some of these commands might not be available) * `duc info` shows a list of available directory trees in the database, and the time and date of the last scan. * `duc ls` lists all files and directories under the given path on the console. * `duc ui` runs a ncurses based console user interface for exploring the file system usage. * `duc gui` starts a graphical (X11) interface representing the file system in a sunburst graph. Click on a directory to redraw the graph from the perspective of the selected directory. Click in the center of the graph to go up one directory in the tree. ## OPTIONS This section list all available subcommands and describes their usage and options. >>>> run duc help --all for a list of all subcommands and options. ## CGI INTERFACING The `duc` binary has support for a rudimentary CGI interface, currently only tested with apache. The CGI interface generates a simple HTML page with a list of indexed directories, and shows a clickable graph for navigating the file system. If the option `--list` is given, a list of top sized files/dirs is also written. Configuration is done by creating a simple shell script as .cgi in a directory which is configured for CGI execution by your web server (usually `/usr/lib/cgi-bin`). The shell script should simply start duc, and pass the location of the database to navigate. An example duc.cgi script would be #!/bin/sh /usr/local/bin/duc cgi -d /home/jenny/.duc.db * Make sure the database file is readable by the user (usually www-data) * Debugging is best done by inspecting the web server's error log * Make sure the .cgi script has execute permissions (`chmod +x duc.cgi`) Some notes: * The HTML page is generated with a simple embedded CSS style sheet. If the style is not to your liking you can provide an external CSS url with the --css-url option which will then be used instead of the embedded style definition. * Add the option --list to generate a table of top sized files and directories in the HTML page. * The options --header and --footer allow you to insert your own HTML code before and after the main. The current CGI configuration is not very flexible, nor secure. It is not advised to run the CGI from public reachable web servers, use at your own risk. ## A NOTE ON FILE SIZE AND DISK USAGE The concepts of 'file size' and 'disk usage' can be a bit confusing. Files on disk have an apparent size, which indicates how much bytes are in the file from the users point of view; this is the size reported by tools like `ls -l`. The apparent size can be any number, from 0 bytes up to several TB. The actual number of bytes which are used on the filesystem to store the file can differ from this apparent size for a number of reasons: disks store data in blocks, which cause files to always take up a multiple of the block size, files can have holes ('sparse' files), and other technical reasons. This number is always a multiple of 512, which means that the actual size used for a file is almost always a bit more then its apparent size. Duc has two modes for counting file sizes: - `apparent size`: this is the size as reported by `ls`. This number indicates the file length, which is usually smaller then the actual disk usage. - `actual size`: this is the size as reported by `du` and `df`. The actual file size tells you how much disk is actually used by a file, and is always a multiple of 512 bytes. The default mode used by duc is to use the 'actual size'. Most duc commands to report disk usage (`duc ls`, `duc graph`, `duc ui`, etc) have an option to change between these two modes (usually the `-a`), or use the 'a' key to toggle. ## BUILDING from git If you use git clone to pull down the latest release, you will have to do the following: git clone https://github.com/zevv/duc cd duc autoreconf -i Then you can run the regular ./configure [ options ] make to the regular build of the software. A note for Redhat and derivates users. The package providing the development file for lmdb (lmdb-devel) does not include a lmdb.pc pkgconfig file. This could lead to errors during the configure phase: checking for LMDB... no configure: error: Package requirements (lmdb) were not met: To avoid the need to call pkg-config, you may set the environment variables LMDB_CFLAGS and LMDB_LIBS: LMDB_CFLAGS=" " LMDB_LIBS=-llmdb ./configure --with-db-backend=lmdb [ options ] ## EXAMPLES Index the /usr directory, writing to the default database location ~/.duc.db: $ duc index /usr List all files and directories under /usr/local, showing relative file sizes in a graph: $ duc ls -Fg /usr/local 4.7G lib/ [+++++++++++++++++++++++++++++++++++++++++++] 3.1G share/ [++++++++++++++++++++++++++++ ] 2.7G src/ [++++++++++++++++++++++++ ] 814.9M bin/ [+++++++ ] 196.6M include/ [+ ] 66.6M x86_64-w64-mingw32/ [ ] 59.9M local/ [ ] 38.8M i686-w64-mingw32/ [ ] 20.3M sbin/ [ ] 13.6M lib32/ [ ] 13.3M libx32/ [ ] or use the -R options for the tree view: $ duc ls -RF /etc/logcheck 24.0K `+- ignore.d.server/ 4.0K | `+- hddtemp 4.0K | |- ntpdate 4.0K | |- lirc 4.0K | |- rsyslog 4.0K | `- libsasl2-modules 8.0K |- ignore.d.workstation/ 4.0K | `- lirc 8.0K `- ignore.d.paranoid/ 4.0K `- lirc Start the graphical interface to explore the file system using sunburst graphs: $ duc gui /usr Generate a graph of /usr/local in .png format: $ duc graph -o /tmp/usr.png /usr The following sample configuration file defines default parameters for the `duc ls` and `duc ui` commands and defines a global option to configure the database path which is used by all subcommands [global] database /var/cache/duc.db [ls] recursive classify color [ui] no-color apparent ## FREQUENTLY ASKED QUESTIONS * What does the error 'Database version mismatch mean?' The layout of the index database sometimes changes when new features are implemented. When you get this error you have probably upgraded to a newer version. Just remove the old database file and rebuild the index. * Duc crashes with a segmentation fault, is it that buggy? By default Duc uses the Tokyocabinet database backend. Tokyocabinet is pretty fast, stores the database in a single file and has nice compression support to keep the database small. Unfortunately, it is not always robust and sometimes chokes on corrupt database files. Try to remove the database and rebuild the index. If the error persists contact the authors. * Some of the Duc subcommands like `duc gui` are not available on my system? Depending on the configuration that was chosen when building Duc, some options might or might not be available in the `duc` utility. For example, on Debian or Ubuntu Duc comes in two flavours: there is a full featured package called `duc`, or a package without dependencies on X-windows called `duc-nox`, for which the latter lacks the `duc gui` command. * `duc index` is hogging my system and using a lot of CPU and I/O! Traversing a file system is hard work - which is the exact reason why Duc exists in the first place. You can use the default tools to make Duc behave nice towards other processes on your machine, use something like: `nice 19 ionice -c 3 duc index [options]` This makes `duc index` run with the lowest CPU and I/O scheduler priorities, which is nicer to all the other processes on your machine. ## FILES At startup duc tries to read its configuration from three locations in this particular order: `/etc/ducrc`, `~/.config/duc/ducrc`, `~/.ducrc` and `./.ducrc`. Duc mainains an index of scanned directories, which defaults to ~/.duc.db. All tools take the -d/--database option to override the database path. ## AUTHORS * Ico Doornekamp * John Stoffel Other contributors can be found in the Git log at GitHub. ## LICENSE Duc 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; version 2 dated June, 1991. Duc is distributed in the hope that 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. zevv-duc-b8f9659/examples/000077500000000000000000000000001426703022500154525ustar00rootroot00000000000000zevv-duc-b8f9659/examples/duc.css000066400000000000000000000013211426703022500167340ustar00rootroot00000000000000 zevv-duc-b8f9659/examples/ducrc000066400000000000000000000014571426703022500165040ustar00rootroot00000000000000 # # This is an example configuration file for duc. Each section holds the options # for the duc subcommand with the same name. The [global] section holds options # which are passed to all subcommands. # # This example configuration file does not list all available options, but is # only meant as a starting point. For a list of available options and their # meaning, run 'duc help --all'. # [global] # # Enable the line below if you want to ensure duc always looks for duc.db # someplace globally accessible, for example if you plan to regularly run duc # index from cron. # # database /var/cache/duc.db # # Enable one of the options below to see more info during duc runs. # # verbose # debug [ls] recursive classify [index] exclude Cache exclude .ccache [gui] fuzz 0.7 palette rainbow levels 7 zevv-duc-b8f9659/examples/footer.htm000066400000000000000000000001541426703022500174620ustar00rootroot00000000000000 zevv-duc-b8f9659/examples/header.htm000066400000000000000000000001451426703022500174140ustar00rootroot00000000000000 zevv-duc-b8f9659/examples/index.cgi000066400000000000000000000051361426703022500172520ustar00rootroot00000000000000#!/bin/sh # # Simple script to both generate simple CGI scripts for a bunch of duc databases, as well # as acting as the main index page to browse those DBs. # # When called from the CLI with the -g option, it will generate .cgi scripts in the $CWD. # # This is totally not secure or hardened against malicious actors! Only use internally in # a secured network you trust completely. You have been warned! # # Only tested with Apache, and you will need to make sure you have the +ExecCGI option setup, # and this file chmod +x as well. # # Author: John Stoffel (john@stoffel.org) # License: GPLv2 mkcgi=0 title="Disk Usage graphs" dbdir="/path/to/duc/dbs" wwwdir="/var/www/html" duc="/usr/local/bin/duc" # Sort index by time, or by db file name. It's just the arg to 'ls' sortby="-t" # If these are not empty, use these files in $wwwdir for the .cgi file's --header # and/or --footer options of 'duc cgi ...'. footer="" header="" # Option processing while getopts "g" opt; do case $opt in g) echo "Generating new cgi scripts in $CWD from DBs in $dbdir/." mkcgi=1 ;; \?) echo "Invalid option: -$OPTARG" >&2 ;; esac done # Now do the work, cd $dbdir if [ "$mkcgi" = "0" ]; then echo "Content-type: text/html" echo "" echo "" echo "" echo "" echo "$title" echo "" echo "" echo " " echo " " echo " " echo " " echo " " echo " " echo " " echo " " echo "" fi for db in `ls $sortby *.db` do base=`echo $db | awk -F. '{print $1}'` array=(`$duc info -d ${db} | tail -1 `) if [ "$mkcgi" = "0" ]; then echo " " echo " " echo " " echo " " echo " " echo " " echo " " echo " " fi if [ "$mkcgi" = "1" ]; then cgi="${wwwdir}/${base}.cgi" echo " $cgi" cat < $cgi #!/bin/sh args="-d /data/sjscratch/is/duc/${db} --palette=rainbow --list --header=header.htm --footer=footer.htm" /usr/local/bin/duc cgi \$args EOF chmod +x $cgi fi done if [ "$mkcgi" = "0" ]; then echo "
PathSizeFilesDirsDateTime
${array[5]}${array[4]}${array[2]}${array[3]}${array[0]}${array[1]}
" echo "" echo "" fi zevv-duc-b8f9659/gentoo/000077500000000000000000000000001426703022500151275ustar00rootroot00000000000000zevv-duc-b8f9659/gentoo/duc-1.4.1.ebuild000066400000000000000000000034361426703022500175350ustar00rootroot00000000000000# Copyright 1999-2016 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ EAPI=5 AUTOTOOLS_AUTORECONF="true" AUTOTOOLS_IN_SOURCE_BUILD="true" inherit autotools-utils if [[ "${PV}" == "9999" ]]; then inherit git-r3 EGIT_REPO_URI="https://github.com/zevv/duc.git" KEYWORDS="" else KEYWORDS="~amd64 ~x86" SRC_URI="https://github.com/zevv/${PN}/releases/download/${PV}/${P}.tar.gz" fi DESCRIPTION="A library and suite of tools for inspecting disk usage" HOMEPAGE="https://github.com/zevv/duc" LICENSE="GPL-2" SLOT="0" IUSE="cairo gui -leveldb ncurses -sqlite +tokyocabinet X" REQUIRED_USE=" ^^ ( tokyocabinet leveldb sqlite ) X? ( cairo gui ) " DEPEND=" cairo? ( x11-libs/cairo x11-libs/pango ) gui? ( X? ( x11-libs/cairo[X] x11-libs/libX11 x11-libs/pango[X] ) !X? ( virtual/opengl ) ) leveldb? ( dev-libs/leveldb ) ncurses? ( sys-libs/ncurses:= ) sqlite? ( dev-db/sqlite:3 ) tokyocabinet? ( dev-db/tokyocabinet ) " RDEPEND="${DEPEND}" src_unpack() { if [[ "${PV}" == "9999" ]]; then git-r3_src_unpack else unpack ${A} fi } src_prepare() { sed -i -e "/ldconfig/d" -e "/install-exec-hook/d" Makefile.am || die autotools-utils_src_prepare } src_configure() { local myconf=( --disable-static $(use_with ncurses ui) ) if use tokyocabinet; then myconf+=( --with-db-backend=tokyocabinet ) elif use leveldb; then myconf+=( --with-db-backend=leveldb ) else myconf+=( --with-db-backend=sqlite3 ) fi # Necessary logic for cairo if use gui && use X; then # X backend GUI myconf+=( --enable-x11 --disable-opengl --enable-cairo ) elif use gui; then # OpenGL backend GUI myconf+=( --disable-x11 --enable-opengl $(use_enable cairo) ) else # No GUI myconf+=( $(use_enable cairo) ) fi autotools-utils_src_configure } zevv-duc-b8f9659/gentoo/duc-9999.ebuild000066400000000000000000000034361426703022500175170ustar00rootroot00000000000000# Copyright 1999-2016 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ EAPI=5 AUTOTOOLS_AUTORECONF="true" AUTOTOOLS_IN_SOURCE_BUILD="true" inherit autotools-utils if [[ "${PV}" == "9999" ]]; then inherit git-r3 EGIT_REPO_URI="https://github.com/zevv/duc.git" KEYWORDS="" else KEYWORDS="~amd64 ~x86" SRC_URI="https://github.com/zevv/${PN}/releases/download/${PV}/${P}.tar.gz" fi DESCRIPTION="A library and suite of tools for inspecting disk usage" HOMEPAGE="https://github.com/zevv/duc" LICENSE="GPL-2" SLOT="0" IUSE="cairo gui -leveldb ncurses -sqlite +tokyocabinet X" REQUIRED_USE=" ^^ ( tokyocabinet leveldb sqlite ) X? ( cairo gui ) " DEPEND=" cairo? ( x11-libs/cairo x11-libs/pango ) gui? ( X? ( x11-libs/cairo[X] x11-libs/libX11 x11-libs/pango[X] ) !X? ( virtual/opengl ) ) leveldb? ( dev-libs/leveldb ) ncurses? ( sys-libs/ncurses:= ) sqlite? ( dev-db/sqlite:3 ) tokyocabinet? ( dev-db/tokyocabinet ) " RDEPEND="${DEPEND}" src_unpack() { if [[ "${PV}" == "9999" ]]; then git-r3_src_unpack else unpack ${A} fi } src_prepare() { sed -i -e "/ldconfig/d" -e "/install-exec-hook/d" Makefile.am || die autotools-utils_src_prepare } src_configure() { local myconf=( --disable-static $(use_with ncurses ui) ) if use tokyocabinet; then myconf+=( --with-db-backend=tokyocabinet ) elif use leveldb; then myconf+=( --with-db-backend=leveldb ) else myconf+=( --with-db-backend=sqlite3 ) fi # Necessary logic for cairo if use gui && use X; then # X backend GUI myconf+=( --enable-x11 --disable-opengl --enable-cairo ) elif use gui; then # OpenGL backend GUI myconf+=( --disable-x11 --enable-opengl $(use_enable cairo) ) else # No GUI myconf+=( $(use_enable cairo) ) fi autotools-utils_src_configure } zevv-duc-b8f9659/gentoo/metadata.xml000066400000000000000000000017511426703022500174350ustar00rootroot00000000000000 NP-Hardass@gentoo.org NP-Hardass duc@zevv.nl Ico Doornekamp Build support for exporting to PNG and PDF with x11-libs/cairo Build support for a graphical client Use dev-libs/leveldb as the backend Build support for the ncurses client Use dev-db/sqlite:3 as the backend Use dev-db/tokyocabinet as the backend Use X11 for the GUI instead of OpenGL. This is the recommended option zevv/duc zevv-duc-b8f9659/img/000077500000000000000000000000001426703022500144105ustar00rootroot00000000000000zevv-duc-b8f9659/img/duc.png000066400000000000000000000200121426703022500156640ustar00rootroot00000000000000PNG  IHDR,t?[gAMA asRGB cHRMz&u0`:pQ<bKGD pHYsgRIDATxyE&%} Ed_EA'=DFA@@5 .(BLPPB!YF qN,NMߙ͗鞮SU:@ hV/:u@ bL& 譁C\03[@``S`c #hw=uek.U=x,n1kՒ>`W\K_"kp6`dP lKc Ȼ lg?_u{넺/zE>S_'rk/[$Qӿ77o6fX n>p -3lP꫻l9P jȑ'\b y7@h {{ Tc틬~y7\H}u"SJ ZE`EP?$$V8ݼ3$FZ= ԯ4/X^Cf\=5D,ש ͨLX&{!&`״gMꣻppw+Ϊ⴮Z~,b]t!,̈́½ep)p0Յ+0Y踤y߮H C^X ^`xZ?pN t\ƕ^X+B:Ž l Ӂ b#BbY AW=JG zOWtYk'XIB>p.8܇ihvC6ɼor0V:#H]1k\: "L 4\Y$1qMnռopV6S)od{ːL?Vl"Խ{޷9cy` L]dƝfd;E轷 VXYo^onV)DG1=\}3y` i'lD\=YH\O * v% Eq‹ZA7穚;׻3 ]TҬ m,ɵ]1\9mxU^Mճ},\ ,zw^,ϼupY4sqo#]%.`t5A(gjZu /3 w)݋֛^T/vT>Py*ST~ fXJ*"Jf;*w#/ʳk?rAdu˹Xޑ ^`U>kedK\GCN:zvw%<V)՗PZI|w:rk:'-XYѵ"5IQ;kg.A*xUq.yG8v=pbkjq%|c0qXY8a B<;׆# ^HBlBCy6 xͮt3 Ntxo.9 w9Tfp@$ٮ'/Ґn}ʏK7tcz\z+Kfx?J tqxgv2km>*oo]8PV:\u(q&br֩eV pd$)*}n)D8VO!˂z>0@@7ÎD Zhg/_V=hG\; {,5At$?F<*>z-Q? KRc3$䎣+> <@7ca >VQD >GߩΪsݗ7 ǽr=ɷ 5!#g\jA6{2X}$1ބφc TRG1"|#\;e5Z?,-t#zg5dB*Pn4HٱKz|9O/:>O.SgXO BjSSI'_r7vsv"/#(#{Q#Ny@Gc~ZzQm-d5XymjȖ Qv`DPm$X??=@<-&6=1g{jK/p,}ͯ,ˏiB`B&jh?lkizV[m},l@s +o7 /LoD,A?|RO1>g=2kY=w"?#TOy^l#KxU[S6VO_~BHB^J,ޞV.$w׵P? I}=nDBrK4˸crxURzoFtZ;E75B2qiB} ςkXٰ;.l.VD9.$x50+kX-bٗB8<p'^`.$y Z#/m+8PߘwEVBwU?"&yW$@wU[K#yW$ ܊Ttja;_yWNL ԳӺ3~V7{LE9`OûYZ=Hț yWbB88j0^`U, TBp+^|p}_f"/iPC'!%mJӉDsNc?W2"G]vD`]|,TI| ,?.d<,x r1p_Ύn 0/hp݄NDϵ++0e^xeYĮ<1hD0=8bt!3k6BEk!3=s$K6iiՅ' wr8X3,~kn5HPX"@2 _]y1> l[%pbIO?P/ɻ)5^ IC-M+:|mH姐l/4H1hk9{4\䒯 3bH0#,;\KjFϢ1o AF% Љd N[gP5Fr nl=/Y<kd]x<x<֥3d؍)21"#*:cLJ"#+c#FB.RJu(w RJK>`v-1#V,ToHvj.h +MlJn{l-`dwsRR!ݬkوZ)[ߖ)d.ZʡN`R%HS)5MyHMAw\)5?sO)"^]b*;J%)jJyO)c̆HVR6p V{(:m}t1" #HȈ=)Ε)0t ^DܥƘ>RJ r/p#Pm^Ŏ?Iv8EmARj?ĊgD e` '78}6 z+q]uڠ,_ža5c Xly{TB_iw"#d C;ߝM@;;Ƙ1Jٱvi 2]*qgy .<~mM6`A,} 1lZAG۽˜{ EoiiV(ckGFߎg(b^VP$vԍӖm[]56>x8?i);* "o`0Ĭ5.H'bϨwL5m)NCts,/v3rd : GL!@rOd)@"_|}g\`X; cLBD xzEUԾ?p9 n:ĥvL1f `2?ՀɇօjÀMGԽ?c>n֐Cy?ddS)5+㷓UYWBX[ǨwN)6.wWrHydFKa'd(IG#BqڀGvh] y^~*dceeՎRƘ ՆoVup5+K2Gfs["Fk1Haq1v97XN8c)u{I+#Ȭ;d/VeRQ#jZB.WJnlt_o\dZƃS)ZVF)1f pƘv;y}ȒXc ~P,;hUUJMm[ KM{ӣ~_K&"#}p14J J>c|G{%~9кX̰6A/~Y {?i( jc2*zYWgJB)7C%lxN+Ƙw[U> nGoE:b$V _߱N~SѸyA Vv\-EfbqzL _F͸ e,n/Dהƾdzb_݃0%?W9SvauYord' }p)<رp^|6vN3rc,D;7,AZ)`nB|CPcMw!Uh'ҩ.bb!~Zcx؉8ENΙK7!v\oIg ප=Ƙ;p ƥxD?wK@6Vۇ j-WӘM)%&=n.Dn/#;SKRJm@|:/AJg3{]KlRÕOq  $"W4DYqwɤ/{ą7)t-Aޑ-.ahI-5"(qs/{ߛYJ~ q2EB=ߖCeۑ 3Oҍn[xmhL6wPt!%,OQg,n7e"2[8h@fO+9\jUcG7%tEXtdate:modify2014-05-12T22:38:40+02:00LMtEXtSoftwarewww.inkscape.org<IENDB`zevv-duc-b8f9659/img/example.png000066400000000000000000011426061426703022500165630ustar00rootroot00000000000000PNG  IHDR  phbKGD IDATxwx[G{Y-[xgo2 ah-(_)!ZF[V[vڰIHHޱǎg%[{ۑV?.]s|ѝwN px7Q.QQ5%zP py>&"9UkFDkB@ `zω(f<_|><ϫy''|w#("; ܔVPP&":um}~mUwԬ9vwֆo##ڵk z__Q<uQ@ ϝY `Hh(8Z/s@R%lׇz8sx6c} b 0"Pۤ8$U.&'l2CQqc tpBQ1 !@`԰, FaYڜ/5>c`P 0j>G! a b: Fa@`H 0j|>/a: F 4@` O 05LB@Qq:' t pvCQs< F  F c   F qCBQ!!,,lDt@`԰XNF ` 2p: 0j@t@`p ay !8ex!!@`0,z@`h 0"<ϟ> ":\mxpD$ t10]LLt_g$xlֽD>e#try8@&qXnTye]dn8` 0,O@JlniꋭT7|IDT\Y}rPm0AF0c2ɸߖ.twDNe8o\`A ub9ɉw?8jF}m!]L< 0"<a9"xZz@O]+a|1p,0 F1,q,I %:| {@ẇ`<>|,2 ?#憫.2*T<5!X0"=`XXd,Hɋ#e;J+g]e j%Eą#S},G^/\E0f$w9I=ߋBZ^6H]h}Y#Ll 0"7`/Cn= \f]c?7`A附.e9r85)3.cI"2sY0 pr3,9l>/,kq8M.r{XfYeNp09,lۋ}D&"j""9b~z#7,؇78x DBjd`r2 5:t26{gjV|jvO}dD- R=AS559zJRZJj FDa}ߵm=MU71t˯33߱՞F1I0Yގ@0dEݽhJ..nlZ?5&vOM OnwPq{‚0F@`B|dxc"w͋%;֝;K+_܁ZA^@1d\  lxU'jm6wYGGI("5wb:k]OViVRLhk;";>s}њ]O$\c?`ljH`hX&:JDmcLL.C{_f4ND5rIQw=qRͿ&؇@Ɏ-;Ʀm~EwMKF?xYa ^?аeF]q%/СDd @Y#6/+O^av߶?vGsRMD,:Ȱd䕹Yw8W-vYDj^/wh%b9?7wڿz  Ͳdźc"U;ᣇE]O1/'{/[зOltsbDV w^ > 0a5 @<5!vv\vʁ[fl05Xj\w]pLrr ҆&3(vue {0(_͆riQW0oa[qAmǻ@4=)UB6޹s\Vcj}#rb|K Uiis|ulu8vM7eȌ} 까H>.BsoǷB8LB jQ̈ :e[m]1a)5"OI?1i Knˊ}Kos; ; *O W ^_E}If Rn{y[7NvVN(nrܾ Htx4ʉ?.sbxA5az榾Vdm[]]@Iz.4l"@`²A(H cAK|]epzӣ%yarSnz=3Úx.ooEV[yg N9xh4"Zm5f\ת{ۜn/,}|/U.{p܋a:=ގd:7._^# tD+%J-5;)dD+%J#Wf̄1QB/m69}ほ1+v؜_Tw{pF@`BXmnwV) %"T,-hAQ R&ለVS-GL4=M/%"jLuQTH~Y_ PYgJtZS c C?v~C~?:g &JJDy0B5 E&~j^ND xb21m?jrNK S\>2w8+vc$Rul~6G]]Uyyn,ّwx<7dt)$)a9Tzc-vuMmJ g;nZ1['`ʧƩ.줤7̙ND$k?Y#"i~!cvC5r@@T`Gю&>71Tpi,NOr6NP2,Gvg}`dtid^qO-9jәo߲co@wKHDkEV{/^ye͚^Jk@`ipHJ#"r{VRAU3-F#_Bq]í"# iY=3.D\h%S{g c%>z0<t}bz IQa -$ii6Gk?a =EV*OEK8MYQQF._2_cџ_mEUqɎeˮ VE'"v?ʅE8ںЁ'_5Ā#y7ȏ e-lvNYh !Z))bV oDiOwzq)tqj1C?x>@DmgD'ݺsÞF5Dd?L 0"|Fw'?qgA4<j,^ұvgBZx3S4u8]AD&1bJ=Z3.+$)ni_NQ #k/^?M͘xK(X?>whus@8YSVNvkY~ϟ{ J++8eq{߾W55xO j_~OM-mn"=G+pz> w=-.7Y_uF#"jt *juFk%ێ)av"u]{D$bb!hlseBYaD .*^|H*Lt+.y2|t7ƎN27M.ųMb8 IDATv~n "wyvUFDc]д_nժ%j~w:ԗ_~ĉ?h4^k6PTVLKGǎp=7dO !7ltD.Qc U甸`ٖ#F<)])b0Q#b^%lVWюoԨ;g$(=klZƫ_DZDG]&D]fGHjXw|N@g(dzB\>Q)Pa]^"A%¦|e>>G].ON~MG+jɑLNK aC;6IOrVJCS9@`DBaEuN1*-JֵkX$f;WѮfGvN`7+=Bajw,^%v{kC%۸G-ۍ"e=#\1sj"^vw4gNn9b.KM$͝6? SY8,HIիgr,sIOz݇oY.i7_|~@P,?=`q~JIDiU&+GDDA "2qVWў#/I'j0R! pջ s#TRDP9C/w48kzDjdu^g\3Jܫ\4}tٳrVVﲷ5Mm7{Zf<{/e9Dk+ږ-48/;7~B?6u;+teL  0"U˄Ő.+XLmC^t8! <ӑO.n\8Us]Z.=6=m;?Cc _^z@0EQf&(˿o<\|p0O zz-x"X;ȕvؽEGZJ-<{)^\ DGJ.VPo'0Γ*AvҸat? P*-W$2/>v֕3c;\\e''!_^1F@D;O3߾ھ޴qLk7\*BVΝMp8M9?*,,Sܼlnc*#" 0 V`|~\pX% N{LYq!ң5m;S G@ҳODՈ\SnHU.ێ7`մoii߰4z[Iٯ},[GDl C1?;EOxm/+E|e! E%99\3%w56z߳"q0B8+ç~I~ŸfK 0 aș :9j0+هX 0Sbty*iaU'=6Xf';4=5LrB%U&+%FEN7CzBr榰zY:QVXȝ J>8R|x49Y ̌3z'=劉a6(j|o.~bIzf8?U++A8/;7~BZɺ)xxW=[#Ç;X9WO]w19 mt8 XhcCK[=Ǜ}s2UۋL̼)ʭǦT ̬tjషtxs#ROݸRi1a|̋2hCE!S95 j?ulIU5PJDz r񢌌mQQdžg[m?;#鹗njA-;\WW}:R^U)R:|j/5 = 0"?i]:ub1i qq]3>\%,pƅG\j6gA#<\L 7;c5vIXMшDr[S*#F"2̌h=7OMKwlgm]`ryS.ըz߿K<dl6(6f&&񥫮'N{nM[ҦMp ϻkfjo{]K;wg?16'7ӦG'ą̝: ] 0"< p` 1 D#H)ʩfC5rtx.QIaRBn˪r{YVRl&_ԼL+Xkl\HyVvh9 *;vq.iPS^aV>pVP%{JR߽d)a㏷o-+և񨰰fM]s}ۍ흴U==ҺJTx=ssӖ6;7H}-, a 0"8X}H$ $X1<)bxK<󤔉9'R$1!μz8QhN" p?6ڃS2Vr0 OLDd\_ -=_,ZDzc+{K:Zktؿ k9/J;Uj֎wM<$/-'`>W{._ N~*ccUw^ܞzݻ[z+U.^7M,isoY[*)8Pu:hͶDazm;*nP@`DN :O][[35p ^IX8'L$X(Vh ѡfJъw4Q^N툑I% {,6.|S* K9匘iRѩUX֛YGV|wZ4޿IE̔x=~mngʕj_Hoilz8מ˷_}F)׾zV}t΂ѺQ⮬6<1 }ǂ5Z,@.8'Ҍ*7uL&_z aokN_UUJC$#&z٪ p$ miil nm4*j}'+W\@6Բt OM;t=I9==$< Vb_A|O(WcCmΔ(͑lЈ:]a 2i)hD(eat1}-%QJG6/㠲ƒN ]iypkgFz܋_ gK| rSj}8ZɦucdNB.]w_~8_}YѦo_!e o\2멕ӳ +k4*lj9^{;#*4gCUŕ'Vډǵ(?@`RSBgg.pM.|^!vCEr%>׮w8l:,8>\|v*a3euj9*e"KH( &XwKlDpM{NiXl7:vUO#La-n~05VϟuZ)'e9jQՋizv<_q"bƢ9/psDB [4l% cJ\45V-nsɗG+/?vpҦԬԄdyOrΒ!{ 0iL ļrY_]SBDtSZj,prX*,zTZpRIV<,7d{,#.LkU [!DI6)$ P@ V&K,KDR!=f~jJZZ~V>=JUIaxQc˿ƻ&"[:mChŅD]; 3ώ:λ6:$X4xGן8?+(X[a6ƥe˲S֭}u<>n?\|uzY ټGegYj &fNK-YJ::~lvĨT`K˟\dP󈈢T2P p<+%"PHDBV@!!+bT,P P JHRJr\!U4a2JSLF=; e:ATZFB"dra]+aɤ%B"6w)2D!.j\}Z&Q #5zgF" 8IndlԿ/mjBD/T +?VֿbzJ'N>->=nVRҚO$ D$ x" z7\߼y iDD{VV]PNv슨/kli,DOAFD!D  *HIB5RZ.iP$=JX<)E!J,Z'*6ũ6ul&{Չj]V׸΢%S{\}S~jc.7l685`y퍵sRhlOKCR?=}9K e9zdݺ}ougg$=mW2u;^lY4{nJ]{fmOUD2-Os&1"F4B IDAT+fc–{w55컺ן^pk ^T$p}QJEE*6q !=͞8@y#=&XrQn!T#xƸ9K0:+}dko&D[N;d D]}M XIdbwRP6rͥo|mwIocyz|Ŋe*tz^ذvoUm4^ĨUw_x]3S}x#$#"XәZӫ/~d`8?qr5!|Y &[ZVzUrbnB1X_mm^DBiZ<~*-- d"'s$]L!v/D+(-Z+9Xd+T; jiED ɥ=f; H Us2uh6 KN>|Ybx} #䂘5ky=fKk^z-pNyY^޽yqʁONBjpXG<_^rF_6kꚛ w]lF-pvv|D]jAF3f+Un2n}O7;@@`L6Cͭ{1-+/]EZ:ctfL;\ kïN[~zh|{.J.ʾZZֻAz~nedd<5?8+_OLQmw>hGi4% &C\_]jZ~淵K_A[A7f/Rf܎)h^jj3QVCf+2{:۽6XluֶxugÛ~N4m^@)-Kd+-**܊"LE@ II^?hK6miڂCsӒeC:wUY>Bl: x' X۝@'"H~J&'I-uF0P1^lZzu( sH JZ==tsʲdFc`?*03BƼ5bó_ʬK%fFJ/]AL4ğE۾~fU9ܻ3."䍷{2=VjC]f^H=b PLuK>: *է=ĊO67S@?@!A_Iǃ?{U$VL^ ELV`qz9س";w>lTu.̒^[աA{HSKcCENyun䫡vFq }|@@O҉惗^7W^&-mHn١@( aP86{iXtD ^LLLεTm3Y'L<ҋ/L^'mxya|/\WywyʉoVeaH z 7n|\^}j/!½b +)~UQY((0N@&Tj!@2}Gap8hdhR,09Rc ep_Ymdh]Z(cp+pN]ަo3Uý`}ҕ_JjemKx~:?WWg 'ܸ6*ɓnO25 UbKTG{=nY-S.M 79u\/]Hjݸ~36"Wq)_5 Onw b ['xӣR{cRw'X,p8ǂhɯBP\#!6<N:ΩmYe 3ݟJR8 і#i-ý$xlZݵUM |u.Wz~QQcLy!^ xiS'pK:NЛcg_M&Bፏ Y2N'|t8 W+WO򺰮jP:Q!~Cnɳ:S|.W{R< CF==5+ngtZkK`Ceq[Ӽ6 . -B7 _Z/7{ӈ2͋EeC@$`ڃő05IYrpXd' .+Qcߞ"TJ^[N[Dc\MhRL Z8LHГ1ceUU+ދXBzdࡷW͏*LQ"o H9J wkwBzdx!] yؙW. b JqahC LKK/L\"BIC `f{eJsFjl2(@cQj84<519^8vi~܊Mԃ۞>RՍ/aArцۍ,z1\! A@@2rs"xsI$ׁPwˌ&k85cF=:\h %a(tA3Z`3=Gԉf/֍P+44F+iL53֟MȨ;xK dZ 7JwU_ &&QaC$<2Gc[W]-+U(^7z|adp鼤{Q^eփsz2hz:^g}[=WpBl)ߝlLsM]a(A !RU341.\ΓP(𤋮*A&' sq,B;#A^ |Pcsha#1@hfW!ڏE(tbh+MX2 c,ʪ5Zsar2 MANFxx|2,jbUU')ܵnײƎǢPP^-ƈhtASӻɌx]31uc\/Cnߜ+گo=}< J ⳇI~\7^z,q0醀VaH1@tpϙ-b|oVd`H h&s$@;j璉 ぀8v'P8La|Z>O'U&6:ƮӘU* ɓH08*)/WFXgmd6@: j@ 3qq0TkyyZ[t9إ~l6q{+;zMo\n؏Ktv Z6wVSu攨ȰoxhCI~~|K744Z ^1@̊f2՟9$^"kk[ޥ P{`YHHD6{(tA?" ;àjxR1Eu2S7,T譞L"hb0hڮ656J`{C %Q9t'+4"'ãxO߅lؐ)| n~p/mm]яzUS67?^1F ?`JKݷf}?+̒U\:a&FG|+A {joΩn ~7C)ɾcaXBު:$s=޳f/A5}tTl1Eu2FŠǢjDRf4K3x (+ʕznWiO ~:H䳟#l/+kV*wעa4\c ř:xdTbq: h_֯{$9SDBg0w}TZOc#BvnʮƇဧ53QPxytC@Tk; 8IXf`jtIbkOTV&RG?dmv~V*P,јKYRǠO&CoBҗGLH"4SuՑ GsUƏkoJG [S^\mJMM^u0 F=$,glN[ pwp?/@8=vFQъGa_MqZ8Gի__S(~qӲYjOߓY6:Pv(dq\ޛw; ܓ|̜0&BAbd7xBvAD]s#pw|# .B|  SRTԵ˛qAE|gYLiN`pɕ^MINgK\.P8s9Ś/}:: rko-Emj#+0E:yg[b،*AƒiѵZ0;',!' P'-6(igq8 b0RքO\dx977B[kZwN jæˎΗ(Õ0$ !XƗ1Db瘟72wJ?3|! [Z6 KL YM"byɁx?΃-d}t)I@^Pm5|8"@`w:h>L@aTF@Q|k6$oLyFU>=H/X/#)FOE,aR f,8դCBu+#<~$E] UT*W(pǚL"1`@D>+l l̘ҽCB^|`zL׾!M:&Ę}__(Yg0[`W{ Q-àc4[! 0D! q pGO,诜_fhJг+Jz1μcH/":!4xpaȸf4D~ I4?\##y:(33AI^%~yXiw\DGG4E1|Gs8!Ad,+{M$c==K$fAA噖'ܴ&v<դО&(&MZ=[N#`qU^.18S9jk/|B#jY`&DÆ5¼o V+kft^6 z! HB_x{7yFyzѨQcphg\z5z|xist N' ۳ 8m-n̔}߭_(әٯ6a?f) a a@< }B}3==- MUgdm^ezi{=7*=iMI`∐?aWVm7"i\ɫæx ~-oY*S1ۋ}cJ5>LJbld t`HUah`b}헐sм>9Xrө಩P˦L?:(4zO@*ɹ2@0ߗBgw:akA\ wdN"pycU,C$zKpEc7Fy:<r%|U֧{tm; | nBt/;YuWC9WiAW&Ip8pBfnCptSM$Гr='t1I/ B|;%04~Aɬk{? |htBa!VʮTO ,(NDچxdRbj, 1Lv7 aPw@!LA>F-wjwDqٞhOYXY,l8t`Wsv5W. Em_j5]E72ىM#>f+{܉E0=Upc"|.I?ޣgK*B?r BJM8p)BeUԶ’="|owGFnpY,ꭅO澻b6,zk_'/5m ם +ʧ$8A?/Vp8McB})r-:]ڲAٿ74;N .! .eF {nGyЯA1͋JQteU^?]8 /&&r1iio8z2 3aGiikP(]uu_|a9 }]C{6f]$_4E@@ ~!mj{Ulw|fo; _BwחO!]Nw%ĥږ%`66EsV3ED\Hݲzh;q~WY{ogaз˕m$sgspwؕRD';Ɏ `!~<s}7(˲}Ak:)l)uz 5V+S4 *QҽMr{u2liIəÍe<gTjj&ռ.w^IL<ݮׄU;+.MV5%dGx2$eM By ?b {ֶ9p-H$#b>|pr˓_T;OD BSټjqt9hKGu>&ly"6c^HLX.s"M.u8E#fG uꖤ dΣ}[-ݦ5YF[䋥-nK$A5y0GpMh$\.$60:z1ctx=:XXS^*Uj}xym{%11՜j3ZZwz|dsr_H>t%+2,l q` gGZI>>{VPw9'N?xi𺢆f;w50 P\c#P[AS %LJUr;T"N*,foFSݼq<ٲw, a¾u zw1i[)0neH7(lRn!R.y̷R7A:&,&6{ER[[0ŗ]>! XCe1^d4 }4&+TȔga#&0/ `'ԣGJe=MooB =Ł4Zt{A(|ؕ, /cb: 8qsp#t!M?st*ٞU]Áo/W֮O[`p+p0Z&ƇճԺBBOhU$I8 ]WhC@ dDA+mT-ʳn¿79o LqJ|()S0,fb‡0#ύ_"7Bo~waU%5k@7T{{(55Q` p:n?8 |||Io6ojZXZ]L# <)<)T5_d0LSY,*E6@ ibto7ɸY: ?>!㮃fO 9,( .6 @BA< ‡fbwT2sLt}s5"sgocoqۦ.Hd߱ts̄].ȑH>}%| FM~eֵ=7ȆpB:; E!s̄>Hw#ݭ_b1hCc$_x:P>P[WE@!aMtu]^_7NFחn}i Ot_ i?y.s"M>"b<7N뻾;++ۊ⧡02C ȑ.KnnVml|Is3՘1c4pr)xVijlo?8Ãv')zj֏{DTO S\HH] .boGG1~L*=?->H̑GwSM)-}D.wG|o'˦p7ΔT(?955d.>CLVTujBopYP b ͦj+if)H?~?8X;:γE8gR /Ƨbd =bnQ1$ѝʁ?`Y:G2YJ*L"9duc8Dk.ՙ \VOCebP؛ Dz=7[ԆA)U*6K$"S }v\D-$]5ͯ=`x: 0D\݌ΠpԑO17"8/:&ZϜ<E?*lZc@HرX43 (&ߦ[*E%\l8Rܬ?еz#~❑#W{ɘ6C٬.ˣR 􁠠 XXqϖrn|s9WrkeK$CO<=.kLeQ(h^ṱmxtk:mJ.S,oE:#nlU/:Rm߃B`c 5NGd:qm5bS\BVT}p^({F ߻͏t~F+.7c3!!MuZ*'— "Rs%AA2RvNf:ʌv}zitp:n|p€M7q_4Qe"`Н'@PLGMtuOݰVoPfUnxn|U#ЍSqq.^ɩmk[ .>>=2M:C"+й&Eرv&'όrk>zFc6w~!! aP+-cYD KO<E@Q?5DDkX(L&w"LvT*=`8?< =n'OX^;'( {;~  7 W Ģ/{,5zqvI~\& ^)_|}khoF͢`힘vဧ"!~Wߍ?wkm5Zm Q}:zt4ս(/\8{e /}rLı.Ƞ(ؗ+ܓqy on NRh mí ½A4D*U+W|o,(#C`Xܞ9 FT-qN)ws#Q{fz0?=δwgK"2/X7#L쪰5l&}q8$6/DcP(p>ˋbIy>җܘ;zKƦtw D.`mm ƺ2=%wz3v8_xBfُ0(i6@KdSd vȦ 2& p()@ĒQyޤ+O!xl. |P\ܘ+mZ cbP(=JErQ035vl::ҥ?jFK&IOp]l' 뛆pJ ܲq=/[{Al,%՛^}wm,/\xjN HxY'#FL I]֕!pG5^/v%$ }܄QyW{o&z%_1Opt̪gd<'- =>ʕJKN'#"NgVXaXhsV΁ѤȺE{`ꎲ#}b+-QO]ZxrIcUXUtBFc?dj:TI|ۋY=lTVֹBዮdzzxt|?'<]).غԸ,@%Cg6zk0΄;ku"V1@ߝ͜ݝYbeX,{b=K{] azƕÚ(yy{߽֢뒋TcE?@͵zAuQ13}}@:;^*ޝ[Xkt XTlDcZ d/ƏI~K#+;\D}ce81K<ש;<8OMJOޏ޼"81ZL$ =]Rghj}nF/#vGVCFMrs@8=ለ184{ ]~5??'F@@~|#%%դliY.Jp^ON^`h]Xt!8M&3O|jXi8}5eAf|ˆ_Xv$Z];z!{ !i]*/\@cYWc1qAmuFcӉDНayD33 >3? ҃V;DQX0m1<w*Y7z|1m45sk/Ń?iv58,=! wU,pk1@V{hSC*5h rՃף똕> @oQvġp\G[C_-c$F}?n|FV$ any+%e"[EyyE14'2,l CՒ#/\j D>} Ǒh~mmv|lػƠP(g'..r †.a1]t}sz~>]Q@/7IO|QzL:dx73ez+NBŝH# -?F&Q,aEh(ku5^yYFl $g}Q戸 o~uA/\)kU!tC *Kgt ʋD5ދt40یA k=nQEjv\-vjed]<}ZodiPOЧ fl+.fdk"zؤΐ+N]N kkiY'Ŋ[>ÃӜ|԰fuLJv /cb|{sI$|^^U@t 'Y`fö#'+,,J({v/c2%4{c]) JV b UM}+>O3$&ufzU\ѰⱰ1<Б HrҗV>-fJlvi3Yٷ}4*7cX G_(0Xl0;\U 37`K Z6é."Xmn)u&_H>>(I"X J%z-jP\쀪4[6?_~/l64ȺLچ8o6kSL Sh2+kE}}|:w{U{իB@uFs;7EE zX`K^,U(,aRSczPR^+(؛;>8Sb#OdXRö#)xF*:5Xjq<֙En}2ÆBg5U5OϺš1# w74(d% `(aOެ8 7/h f`+ǠP_XSX+kik,J*7%˥uO eZ栻tm3j.8<4Cyiox\l hz&cs~UMoԲ ekzL^@I`g)ث200{4:>2m7,9[DC,? a$pC}fa [ 9'zs]K~)լJNĒawWIr5/mm#F b/o/e<̰U~ w8ﻝhotº ғ<޾'`ʑ'3µ.ASl((seUsE*Z.gݴ1O׶6*YxUp+1@kX~Z(H`:z=1'!XU8r*7%t "҂D՗#Ch4rwln@6+fm7}ܲe FTW_">#G&c DYerYrV+t&3ut S^.s}Pq<_QA#r\2y3(Z;2?++bzRi|Bi6knu|N[ [|j^RDj{"B.65XO==ACLrlתꠏ=&=oܞ DXl&-#UJ-Ua<>bMx[<=;}:|ZNx97فb-}5%熡B#A㭭K&SsOrFyziZCLfnU.\<҈( x >mɼD<`_](~Lk&yӓ'J A D wy^]b^ecp"8_Cҍt*&yvLx/WdUVRm kE$ m:UT[*:in$O&4VktV4ES1^kMSO )G78zs$H\'7:N0*9`ǣ1I‚^++fsd*cq{dA,k7@ҝq5cbEĐ,JeҎ1KwsFfd<"))ˢ( q b,3 %:l*驾oO + +h2L F␽1?l-j9 bӼ1^^{_LLLlwۿ_WT4ohXn{L 2Ұ6DF n_4o-{l6}<*Y~~݆y:NsA IDATpb/seāA!0YmѼ us4p0׾K@zqјO'?9 5ԉdΙoU5;4j\T(ȃ+,AS_)CEew4s[BCw@Ar+%/>Ch?mWci].vt-.3( Eb ƽT!/9aǁ{ܓljׇjX{@h;plln_9)_|sw" jhφ\Ջ(WnIJSk-xPDuOB4Z2YX%PLb23BD;UaY~mŲf]~zh+tf֢0hyBAl™GyyzJ*%uL\ތzt{5zb&Xk8]gb{dwY)s6.K08[vcKzzQ4,{PW9C8ޭf:0YKٵ.<< -0zxl(-m9Ltx@p--Kgc1G 8}̘ht񟗗 lV 2@Pk2Q|re<p{FR}IyDh@о 9/1@J,LUX4jB|'w SYKg'3bP(^E<gFc;rERtf3vgݡQժ>$Mپ!->}c"Ap0$f5HX,~JUsX+ZTz}_t?o»43YY(R^c'q5mЧ+'eu:F ~>2 J5!KR뼻>dܓѲG3jඉ&> <0g'Q.pqSQ$&m?<D&rYEQEX"%]7uBRbwH&+nSP)N(P[7h{qK$&.g7=9]>N47+ohxL1G>*)>>7Cn ڒW{if 3 ƓnjRl/-}H.Nu c!,ֲr0*tFZ# rȻFX.-`yq]ۊ 1@Z$jmyI~LzB#C8qӣ8B' #H5ep şi:2`P;`80Im*֦\h`'9-MV>.NB ƼF.j@GmrGefSlZ}Fm#,f;eF(i86kXo"YNltsK}O;T}:Q4~/W(wDLG@͓ G(v^=".B~t6-4LUA1vJJ`` rA9*}!> 3u^gR; W1b73maUҴX_+h0딚]TIl8N.l \c@ԙx[mիGL=rRRX廪j/$$ƍ{B\nڒED2h$`~Pɝ'Q'+`Sw\.-lrloSf?q,~0]:A S}f!M֘j,Č#M@,C6)(K c~n NQڪV+ܳCo)U:5?iM| Xfjʗ:S7F!F˾:ݩv@_LC//fDTT7ijKt v__X?}y1/1Zebpa$MV1JA'ήnMt1EK2r`(&zJ$ 4Nq{ Xx. eL$5JzWZe f%^Qm5'9Z,)Go[-/SsXע=Ԩe^"HOo_ILGo: JJ66>(=>k1cR:uZmkAR'=Hr7t'zccf/BTH~3;Ǐ#`0Ca@[TRÿqNr\t0ܪhS(V5IJb 4kZ%͢qa^]HeRH494h+أۓQ6:b*kkfN}ՓNMPER^q V#C@EWy"6F٤u\nWL6I>|.t>߷H!hR^b Dh5 7p&9ٱ~g(I6CzCqBoyk?N! .p*No~A  ='6OHvJF0"^ ~gs6$}3^iƌdoOi>KEۢ)<@hTzmjj󎏢N3{lMNBStH^/.(+!rMKPa0ڱ6iJIVɅ>vuZP,dm]{(ku% kqpI<V؆OL=J2ZްF]lb򈺓ZQRK7ynanBPOoXPGbMH9\ Q9fKվ nnJ>&M!23uyT-gL?zO%8= 9֚60U *er\y]@|f(#)7nww O,LHalN,!Bջٸh^hi.-|GH7s #f)Pԟ=kU}O/.LaGfNap#O䶴u'}LJs/I‹g<=v痰cbSt=?wd厺n{spBgnx%77>~8p禦pĆXѳU>=:CLjmVZ߳܃J!)nRvʰ_l_p{:Taagr~~D Wׇ,| An4umj:^!YE #d7121-iԑ߬;gMKeRit*^Q.%:fyUCpgUwgb֫̒4{ fSm8~ "ƄHY, @@lU&NŪ?8;L|mI7UZ[ɨ-Fhcf^-𑮙Qw w]J6z*NhFty!X=?G-.1BtgG0a>З83pBê|} 9YS yTK8!A`T QIݘN\jI?Hwٳ'֪|-ذVP~9}]#sZtFΥSMMsP4 eTsT?(*%>44Wu\.%d|F k-GS ja!!S1zP^mku4jbe 2!͍~7// mG^.w'6 B6E3%=7Ix |hAWXD1$ÿmQ>O{M¿+_g5L: nʙۛ‡S'dHXS]..{E4薃m qYe}>&,r{_dzT.H x^s&_Vw\~\Ujˎ:#~C>jY?SG!nQ?, Ok&.ϕ˹>=vܩVo4hcLQ4 z>g4:}RmCCpԨBvzl󮦦emtvɌRm $>6(-}X]y=Lx<^v5齥U{b[ې @|>qfBB%:tnɓֶu e raкJaӉڬULȣ'<=*-a!PxlZ ԕDgD1y*{lspa%KOgfƣ)BV=[zP2,{_Jˣ„'VP_ y͂{EB~v"u7K1907&fEE*8ׯs&1n.YPl9V‘g`'q`T44lnlu8aGPq\xFgSB FE6'&;c)>Fg҄8>/(rL!jM7dcr˰*ZJoĽIvijmk lujT'G!"#lnj'ڊsx3'$(CBַǪ-cS2EgNe۬6js m;<5J5#:*^hۿn"o-S /Cހ:7'*&k[V?L}2YB nxbeRT<-?a %@A!Q1xS ji`T ǴZLNgU_0%*jz#I{qqΖ96M$`j"#EqTEW; ӫ_[U>5*oyy󧕕 aIKhјԨuu?-_n=F@ |( Ekh!fsBv#?tq \ /U I^?S,=nyx!8&~D4 E7n-u_O~`_ }|'Cw^y$vVI݁| =^CKq"3)T΋aϞ}⸸p+Ijk(){U*3++WUV}Oz'T^ujh^ZC'ώ”cUyy55L܃LOwjnڂOoh$:nI&%'yUBRy)A/AH^Q삔(Mb(IOh$&E|c Àx۞48v*1 _-Ѩ3qc7;JB)MgnW:j ;TgfOJaR@@QhNYck /1`D' %G&MU)o;eڈS(Sn>R}Toqmqz؎vHrT0J3Ȁ߳߳-7$}IA[!p/WX̻ѯgu{ns|=y*38ȻR?|fpR퍂4J7:MN'yߡCSZRT?*,LO'ӧ.-7n@HV=`dΧL 6Cr؝|xoΖx1ln] }$MרukշJVBR|K Q1_Zo NKvuP)0/q/ZTPV5`l 7۸͌khG%MKytwO1Sl:KF[_|EpL%** #E7yk`B2@RJۆGUsѧ82aHVl@.ҩsLFl9`,*uҴȨsF#fb#Z~7 gޮf5T1bq)5u" ǥIsۿwO\aknCRx. )= v )S*&=`nZG*d2J(mN$7b4E=!+?%%rJF%# uuo:Wdѭ*p0:gl()=E /nil\Tmy̤fTr"oy1 s5E»t]~ *%vrDvא fsRqTpϦ99e!G$ O?^U^XoEZTxѬaӢyЅGl:aON~ci~v[6Ţm[ۻwa AA rӢ/4ƇJ IDATOsX%OHSSq\tN`1ސHAmFnދϻĚIV[ Rncj5o1AWf^/XoXИtb|(>I$$D*%`|a ]1#FL/_axzlkg`}0; b5ɀ ¸FSi 6nDp9kpYY{!{¤' κ]BhHoAvSt>gyns!Y>+c3)>9~<8.~gl/ Fxk)p%0mioR([^W/ozSb9H}Fs:-bn<1I?ommy{ud>IQ7$4NJǹkV 53nKr*fQj4֭:tʇ?0(6;榾KxI3NRI0R43upmO:<޳|&}73_H|2oCx\+:[9sMv*?!d9khB@_0ޞFC0O/ 72?>uYpbZ}ŏPn.+;tQH@G' O ,~}<)8iU9uB?3ρ:%J2wυN#O54 yEp" WW[g~h#A(|oR 9ryG^I_1o{ED>U bbB<cuufs}5fѫ?6]P/>,;x.=Fllr\F%9T^B3vp驩=cߟ:5d>qΜ]A#\$fiGC^Ө5fĊC|Gu R!WWn"i\:uUo꬗R҉TFƘ5#YFNݨ3cYwT~WB]V5gt ҈GEF"T,4dkp|e'&+al\XԘp檍g/ m:m27nm=Bcl1b_^ vWCP ґԥ=nw9+[,D@&&з(z ]%xwHbHA*+!BDb?%WǏY}wG7P`6y!;V׬s '[Fv$3J8m^2ƚSPt>6 [_WWqv‰J˒cWF y_/-]sh|#`.@ ̌ثV>wU/IBal7"_/V_? T栒 }bfwR{ǩ'N4C#̢[hLTzuΚ7vzwwE=zml =$ `y1kdZl@./ztj9,6EI]3;M6~Zkp>?iJITkZAaH9=:*L )loV2qrdq9$x.n^ f1 I(zHbW ߏ{3ŅՄ)s屺J٧wŽ'#gtJə >hP"B `qܬA"gd h=E2ސNmɄ;Dz F𫎐Ưq?RG*W= ݽ!6..P`xLZp6;YӾ<Y& MU:ռ!k)޻m4 Suw iczs_Nv5}Wm[ (r]UϏBb㋹cJ/ٓ'j!J7 ri=FΛΕ^#Q [#Ň{8aFnstz?Sݢ[zӐ:bBr7~yy=UUg~agX}@Oa0/z[?9N»抚.$Ihq]srW~S+^Mf#k'N,;1qO8_UPj9́L*Z! J3;i8Ѽ-Ʈoa|@ $h~6뤸pzO2P! I}jDe=qWA%WӔԸBa'͎l'׻)|t|mQ}tG701t9o }@HKV\ ׿K';QaC%\>c]5$q$@p]`".q<^ب;?nA ^U@DIl*Ro;WuZY=+HB *XPc⟎?w5G@(>~+ć %0*1丹>og/L0l($p &|ԩ7w8&FYfͩdGyB9_HoSesՂtm4^O'~.^sgFEmbB6:NP-Mz8'^U5;ε032F#)g l^Y+`h0eB1\`PIW(e&cj FTqgeb\@2Ӧuk\?*\Φ;1Pw%V8>Rɡ+mT:aYuN/ъ МCerw/OH GCOc3gއ~m1OŽ }Mq˳|  /P9y,: .V´!T_b!c 8yCְI/Z78-|>~ɮB 57=" /undSʐޡS[ۛ:+Ged/=so_@>ǏsD 8L(E (->n1~ii 7Ĭ@oW+Z(dGE=;#OQQ7v{qTVek| ?j?ը68Кdi'w Ѷ8ya!c쀞E )BtECƈィ%kd_1IWdH@Bֶ2lj;Z492" @P Y$R]Z _bd2(.TzY|m=cX|6-TebDW,2zR~!C6[f(2oyK`\U,0!XP\ #V8gt?B8GyK ]%ABX7j0ɄK.nkqnshȨx4Wr[7[ ^"ƒo*!WP,&KGP boi]Ʃ.k!;QrO@mlO++߫0W$;;1 aac=>,/.>u|_�ED([o}c#؟ڴЦӧ5?V H0+4jܶs~{ pYڲJv;غSPx-?v%粲^uhEO}~ly"kRe/?^V?ü;_>sc HBHĜ`=Z׶}UHYUA,KI)Tg7_R)\¦ =guXIP"+lxq==Ps)` +ŅBtbuGgH,.%}>_GUsWH`<^/ vdaP Ii. e xǧl;898౛D /bf> 74laR黏gd@.Nu=].xܹg IʷT!=H^.)>޾WjWdd'$|^z=j />C&}Jfsy h3Ѷ \DHHA&tմHf7Ii\{u!F?ч'dCUJ^ҡunqlJ^.{@ 9Err:Go1Կvwh0h/Qd>Ndv/1Ptxq{6WrHiۻ o~MٔE+TΖG0elYD0D=H,ILWXvH;jii^z.*KvKqIT_^f2>`[_`hTZh^BoA[;uan|`J:=5O,Y8%-Mȑm[df;?q z@ņ7895?b^!Xjsӟj[+JtaaƌRf !lG.-\%;,ITh&fDӣqn?&BCF{|U:c+5!T^-DPHBR++6t ` &bp~Yސ'j\#IHb |Y4P %|}y:=:4 Tǣ[BzW{2" {@Ho gPF|txA󵳵X:]:?Iro8Ҷ?V٨vŘLLoۻR35H$vlM^V* y6LS={(R(V t%?QiA.꘰u/ 2Yuv&NR}BN{xo7p͎{5_vb!RRֽ2cƆA|o6pM3p{ >AH ~pbvÅ&MRlhJ.InqbӃ~so{Ԩ jAbQEF&wp&Y?M"\0>M_kHDMMOhwjٳ+ST*ЩTTV Nj;n஄Ee(뫽ּ{b91z6bIOGGwKط<>RBb.Nj8ax}CsNmWW:dỽ#Ѧ#Ѧ3 xFx -ičë́UkrP/ҝtq8>wޯ/yC| $e߁< B3~3wnL>~+D$N(svx)Byk}>_ܥ}0EE[PzUX#''P/;\ xET)tv  ŦgdҨud77~d0ggߦp.:ǖGo{dHǯy.+Ku!j'Y}T}t I _;tS]`# tH~2k4Gk׾\oܗ,OJ`taDqt81gg*Ly8eM} s%[&$0Dpdʩ*q;I>ϝ6;9 F)ntnc ml&ӘK%RjtB~XWۈ+.}-DhUvl"Ov32&}\Pb\uȸZWg<%z@sV̡cgl:a?`:5M擸ZۉfRy BE.Uo0".UêS6QA4W׎#=BH0n]'<Aݽ0Y}˩\8KC -j|h߳ /z_IcSb/ jy%j҇" ȱbvHV ӎp/CþGP2:bV<΃Q1|[UU3;zy"n7ϓ'tKa'3$$|<#CuI"h~Zj?#咬WKj4 FŽ{ߘ1`Aj~rӦ#OF9\s } AśͶ5áږ"y,#WezC0gRx@ i3l +Zjܸ7YZv[ku.wcfK~Z[̘tn8vR{L_c+pf׬\rE+1_iDn()`PBN6w0~A=>Ag^0)OQlDK#dy&8grA=!+.(Y{8Z\[ ħbk (5t܎78}*S0+:%~" !;tp^N |2AGou8(.*yYt?Ɣ&l{*{}6=l3<W}ں-ml<߂[f_ &RCnm~NI`2m2Έ.pb΍UT-X4p]@!` #4WVyvYu]~DTcZ_DPQ'/&3,O;¬:CZ 0Ch ~sHё @"-W IsH `Ku}>p\ y^Ãt99<#XI[cz#5:Q5a^/5{ X<(Z}g愅m[FFƥgIʳgϟh͔Jo]ciiJP:JŋϞd$y cgk7ַ<}4s3X1#bb>c&$pמ<{?7A C  ^D04))$+g(? |6mS?4ц#HNh;hPpgƾ_HP [* {vl ]vs|:@p3wƋUc\mq WSY,\~k]~D : :=T³lD YEGmoCQl敛Vn 7v.DO° 0&'8(`m(06LNmi.@+uwTh Vb.#\PyTR\ Hg @4U;&=7BB(L>O6V{%M$ ~!+x(`efSNZ0yȱ i?=vQ}O[bf|p_4a]B_p$=:j9 A$[&٬B>@Ȏ ItwcRw$$deW·Ajk*7 Ҩ$S"PʉKJzfjj}'MR]j ?xqSӓFc AA$hbL;SE%j)J(yw.A[e"kT0f2ݣosF|i&8KL]$&%FجkPt" L\VR.D'ܾ鯔O[ۢu11# [ SWEDI(R64Z劽 )=vrB8f{#kM-o(+Eoqq 2vǣG/ &;f0Ul&d$ f8 Mз>K\h=K\h`X1bdVT:R̡px P~Yh .85NqN@ȾK>- sg/AಪU QT*+:Wѫ?Ǚwʙs<1&;ݡ/#=6[6[pa}Mcf󎁚φEaS5Ka Rʕ+./nVMMqS$ D0$H+Qg/7@JL:@ g*5jC:Xm8~&9L<ͫuݱ: Y:zFx2%VR?_9HxPgѷ-ꈢs'8f2ijL@9, ;VgE cB,kIfRpA-Z=7TcźH$0~ 0 v!jm-pCei,2`+C!ܢxH3 r'G4Nw'J`n8&G ! :{A9\ nedZXP{Z:M"qx.9ݳ. ?Acuhtc%ɓY]~N]?!HezݜhWrJ!#ǭFh/Akk+CSyy烶џ\:'%UsIqcx@o\‰PK- k%$x21%@6:JV¤B;[Ѹn[wzM.DM|_3˽ NdvB[6! I{e5I¾^-óF}WLX&$('OVhhn‚reE y+ZmH~t#pIƍ'8vo rФCTGpUN Y9ryź.*EJقS. ٫Z`ej]>9uDItcn ?pñGaG¹\wd4b6cSF K&ZnLdN}Үo%8 [pqa|v4 LLܚ4|a08GxL5ٝ>e9Z<3 PKvmgeIЈ6^y! .P)G1{k=Lz7%Ii1Wmv@FZM>I0KnG[Y~%ii}Bҍ%#ϫ"],7tP(9e0wPREw@;]xͶibu ɢ"Ld=A4k8l@5mXԊBd^H@e rM/ !II%J) Ea~lԿ%*@RoitZ V߂#fɹtj;a# cQ(0ghkN Y?Ԗ¤jJ-.OLLr<6Wr1Z/Xs$x% !tݞ3cars`9v9I^񴳭;MV{5Xrg1p{vvD&<ʕJZNŏѼq{'94NHc G*ǬП'qmCu,Ŕ {8t~u,"!P2RJEMtap&Zi2ŋD1+g9/eI3!;.1p$]@YAP/khMޅnZt0MGi]H:^L]Z?97h&qh\:E9iw܎%a(x} ^{($W Xu?:8i4_ii&6owa:~N$OU]k77nɷY68E7$x4u峲_ʕӴZ}-[v/7]wm3.@:꒒?(e21bL !<%*EV*Y-}.na;t$+m_bo 2r\5I_0A,H0Qdr }"çmR/HoPT)1 ) ovgL @wbf0 ò%+nآ{߬7 lN7i2> `WpdBNEB.)4 ]CT}ꨍu"E-O@pc? ]a069 -_XȡKQOp#Z!z\?Fj.A=VKybmѰ/#t7 p}X˾SL+qG(b]oeW RPϴ @sPSSM{ Ǎ9#?NL%W~n ^62M&u׮z-In:!޵pMLf{/_~vv}3ʸcXMgfl8Rք(j:i/\\e1XTSI zTrF0gs`Z.sa_J" BTLl :F:S ke8a &T<P@gmX4;.j 5:&M*zukstz>@JlP_p\BX|rAW.J{ˬ*Q$0 GE+&>6K04a ]$ͱD,Kuc1𪄼f _NA(P}=.Α01N2ʁ77tfA~VIpD%NvsCc(R} gRRM{g T1Xx;̌}i}rP~C6kX|GWWW `AN*zEG4axF,o _Teö:kfE#}(ӽplWiN"33Z:@|Qe;;EO$ C&D\ rPG (%O]Y1Fusgekz4O|pXߘ7Gs+"Y_O7 "@bVAE"kj[ݽc?'ޜ4c7U߿4ۚ||~xajudn߲/ q+8RY]_< M_lmkD682"l~nĉȐ*òy׮۔ޜ_n:_+JeaIi/~Fxbj)]$ ]i(j@`M5R(_BCtŒq14Dž~>'s¬"=>!rTY1.a'aM"c|EE&b?Ķ`qdqyDP$׸ɼ2k5 sĸ@aBa/eb1\]Uij,#?L+j ^'fDvyz? s 7QV9#,!􆙕 v;EwTeױ\"CG73|J9@`s|8[ȇb{"}Q:#?:6%9~Ef O~@"m(9?c|.i(yجv}sXWe &0>(9hZZbl_@o)%edp(.'1AåZtH|@M'n۲egi6EHn hwݾ\=?ujaƝ\NEZ1+3˫WIH$.Hx;j^% lw-6jֹӾ`c88E:i>P%Nj"PHd6|,ɅXƞ/SįJ D)d4ء8UCÐL\ wLvm6ȐF0>xfU*$y:>HW9&j` B*#Xbî+mߞOK $ahk&A" اjIvvJZK/z(*v-w:ς1X\u$JګX_x`filٻqI/}nӦ>no_ctH^ż\l~<G[]i=Zd\R'gN49)Æ}m /y3/ؤTŊsuRJ2T4z:rʭI?jN*BZp^Ů&t IDATѨi:pqIJ~_^Bl7v0, BFX\Pr9Cӳ,G?x̏NqEefY] })D" 4 Y%RB!T66$v.jF AgZv>Rx<}@bE =A@/u9( \\=Kϳ*Jp!jRG"bXebx)R=tM:CO_=+YvUJR;!zh謭n 8=ZhAzN& 3x$-%zKwmGIv4&A }@_җ\/ቴ?HGy"-'KM۹J"eӊWl޺ISܫŪ4{0iBoeك)@d8MDQR b5?/jongŢ98tBѻn}uf4g!S\":}zE*W[={nw? $>95-jqA _޸OC7X ceqV&jhǎfKY7''kMK(H-+ eۂ4}n#U2Yf?xUfQIѳ R~=N(A,6V*>!$w/0,R>T0ALN;8188k%{~cVdt@X|b72mtlʌ!TeM=TIK D8,c'j%-p^c~CI_%EPXm \? JS#7:J0l~Tq~G/sZWJ{aþ sV bstLpEbY_ʓW%=Ttqů^ $Y %i`,Gv` ODgd1< 3cA0ݍ*khsгauT]qrLz֪(oƠܵpo eȿu0i|a¸dPB @׎?lQT|/c1p2_Z퍗ef=l>,>A7i m'ܒs?g.-MEZltGV$OQ˧f*jϮaT$UXTlX&>$FZV$j'q">ŤY1kvNUΔЭɆdA`R}DF)r "PiZݴ#ĮeHy-L9.BB'1z)?>T,Y[:γJA@a;ideV/%+R ClB`JH4TVCo>+H AbK6^lMYTZ!;'ߔG)dN $S$<8K@fg6`!]k[q=4VV~twKHWr/1`m1AwI sfRv!W stoVSy0('btOc:z֭Bd_y"(Rt,)fkD/f2ip}k=$ S_=1KWP USF{|yMY/m:ݙ/˓dR>}}i68Gb\z96#ii---7БHоicܡA:Z$,qGNk*t>u֔2Ѩ{]:*͡w(:ٮ6Z.h#d$rcǍ>FH֕WG#B \V$94o(&) f~fjJo!LS̏m0eV$Q*>*GsH6kaH9CP@l{ v{z)/ZxKFcatL0O*^+|]`zW(Wg3_+Rꎞ&&Wذ8z+f+NJ7ncΰ>ⷲ5JFҿu~1`z2Cb :$Dg5  5+TfiB8T?0}Ve$>e?(&nY 1h.&LZ׮ ,OJyB%, CџVəA},Tj!EƶBKÖ:;hCË;~nST w^PyY0ozk͌$噪 d4ƍ5ol>9&gd|)7_P^ZM7nzrs[D$r,QgL3.@N1zY&]" 1n۶-NCRf̸(%EP 2Y/+ 6(j >ct8H sTO^ea<%C|cۦZdVjD>fb|? $k{V "XR"v#w$ s]*RC\"hy<C81:W(egygD2c%"1!8PeZ7X(O3.;tJȓFD" H-!n2: JiҏwP,N2 :C `+z1 .PlM90W?D0ޡ?_X[x_L.^ p|{sRbñ2e&і,t|iVku/KT僶{OR(5gXY495j\K23o2ǻ/ܞ=O4|w\M3fȜ~mڰh٤Iﵶݾek_vu:1uyzmKJJ~-.?~a}Rw8_WƸ9Ť%',77uh{75)L C32ypٲ2zEU*2.P[4=QxHu8@:h9%6מ_&GEӒFuJ%|WIp`dXbMwoպݩ*"(,Fh; hO?@k`lTH$_J7}^aN](}|f"P,ָAX2IZJ'5(f/(p*d=+U*E"1zMg+D!Liӹ2DKn[!$bTݤ8U]avT^*v=˴I$/$7~\$|Y,Xq ~Z8&bw;n|q֩ѰʓXP\M0޽f…R!k. '=&AfYDZYADɃ;%J,〞ݷ(PTzeMpޯ9.8QZ}YYL1Z1x)@03M>ٰȓ^.U ugIFRR9|£knr׮v:ӷN8qr DUEEha ooh_쒮6j}X˱j}: K≄'cI$ّoҘ%apvQ;lPP.m&.'wM@ME:"^xxuڻbigb)\2 8<-YA; ,,p24`H ;>g<߳*Hs8`L DǕ i,/!3Mc\лܫVjĤ)gѐ#KaP:r–~ <"r\pPzYY7V~--w|Od2Y֬T,Zc{o[=!b7~I{2ô݋'xŚ߾ ô3Θa\B&ߦ%Ém{ n3nΚ#qv$d¼< feXfv@2QW^ gV(u@ Ml=M2 S4܈.JӒeI0htxbg8q[4d2 1>Eal5O\*_Ts"1rZru[GJ!U<ި&=A`Rnz͵'`^,׊x"YLTt]V/*x(OWD;MDž8,\z{Ww\($xыxy"8?WR hHě$rROЩ6{f"rVX"AMK.ɭ;/Y ЯWPH"/<$,bG~bE+tY:$OBӽ,ѐ\ !6f&Q= k.d)De(K~p~oZ+? 7Nr H;㾮'g/9ɴ^E7 q4y~. jWdgX/qGG^<Sy(K^y^^7NΟ/66ԩIIյ{wm5.ן .jb0h78'qreeʡ_疗?8??xR$BfMPx]D&fZzKhR2GQ >^wRRuI7:Y)OB,g{bOALZ#ܰ$#gc-v+Aܤӧn%&H?iO/铆\,Y:*<!F&rCg2d ᨾ-sG63g-h(^5 ί Z*TAP\u()\9oLޣ̹d2h#dI_ qh~vВT !HR_͗ɦy6 !DX,2xsMgw0d3L=2:>]_m6`1>]U5 W_MMgvP$>h|/eeW-OM֦ꡨc)p:8 )¢=b7x8 >MzgB)f9Ü\ͲrHt6 V8= "8^͆^ow×=%͐GLx)z76|,cVh 97\q5zoO2Nh2f@F*T*J(iIQ?$ihH=$,tv{iT#h4 (ҿp:#]aP,or#DBX",ϲq\CA{MXb|\W>"GmCzhFnNȞm~:<.IQTLC\*E_!MDdXQH<ԞƫZ$D<+7rT:.n,.@/8F$_##C&A4&F0]?x+o 4\`;$Bw`Z!9:L&n2z!BAe3Į롣;I6E/`xc^p0Ur-}˕J%; 5޼e{>%HdjLpG#T< ?$O0ێ :|6kᨒH?䋩2AC-a<X.ʅ_QYB*8 2f̳!C s$Lu}pVX$.3R$>ѵ.' Vv&6=/R҇E 9v9a-'P mSr. ,;.!4KRyؒC T?Htu]d"E&H8)F7gW pG[08V jw礙M׬Y—^>}" ~ƚwW4V]`UU|ޭ7+q1oqr H˦]-Jl_}h][ҥW'T# p>ʳ'N,Ҋ+Xl*4#Tfi -2U+mA9Ixk n7(FtᒋI&C Z78N:7'GE"ъAbd`I,i4EP$?㜄R" ի*ύ&aB Hcg+<}j b>^v:H+'-XfUKjTFohu_4VT(6@dda5x8(FGءCY~!Oh_c'eg{]YI^t Zț.TbE:qFkNf< 1x\t ܰ`z09<pXH 8v(H{IO%Jw(DC`@ R*)G?.Kf vjЧވyEw2tL^4J[)^Tg j 1mH v:L3->2g҅;~߫ۛ\?Bmm}mWݎ 0+srkxvϞ;9t38Ǖqr OTdmwlmS}M75#㉛>R `Rjܲj%"9iǐH\DZXD}`m]nl)I>9.sK27ԵrM`8kA`];axM=zoE"Vv"d4ˈB(*pxzZ!2L[ݦR*X-R#u)*6]! N/UX01,,шeB XhC0ucDblLRDHo!0 IDAT_T,1 ˽^vQO&s񦯝bT"%TxP,z5ɭ;6 Ԓ+tKL01 ޚo$`4zsv \gݰ'p$K@k0+~F#|`Z2'&A!6sdzƻ/N$WPO۹@a=fnXuuu nBu3f=)5U~rqt0dɪҌTzEF MX8o:|#v¯OpW. d5zz$HS^_OX4U+fJ$`PS:(z(jCk8\-b0$vɂ_"F6Rziz^ab1}#JS7]"B|wWw$ GP=S?lk[B ,3չA=_sN[Vhqf A:w|",.K%{:T*EfI»:;Ω2ah*pCaZ./ku~*y(9`$?Sd8fNMWi(o0;,l b]p2?F:Dz1I<%ak_c;#āO' d6Ue$dƙ"C#@c~ oK Z%ۻ_g L Rm V3x|g< B젛X`y^`=ب-4aeٛ*o3+1`8sf%&ӻTT\&oݲe_MkqNWIj4?kҤ?Nw@шW^n17?%Y?eK'ʲ X|I"Zu]y tFM7j^J2/k?oL5 A2P@0 $d"n_8O} Caw|4xM%bD?c( F tmZ2o sD/xbZL:,ۑ@lZrM[G`ϤP$Z QG!G#tW8AERTPj6{>6W4ZX (y9LN6b>`aAr`g\SCjzD.A⣫@ZZO<؎r">ŵF&˞fxgѰ&G_&M*ohV6^WݻQo@-.(xhyq1 u:|Eil^]S)ΰlz-trrB<6]"t YAOxx/~W_x֞LNa2)$*v" {kS0è@*1/HtJ *L}EU*B0r䒣H;C!Sm 9V$l,5}c^6 i ` Sv"uq3+dLSȤ:R\0Y"C]ֹ bɏf>_&$f)^fEJ3@[ ⤣;yzy6?էxkDܟ,deIHQϹ[ $Fkb,4 >[A9ƻ#ڷcf4Œkwt=RO @jGC)yT0wKd<=,`AQ+>?*ݨ`#/u2rva:/v0ZzFE/d">jŀ3@tPPCs PRx(:8 Q_ m(P"o;Iih`Bck(jLEpi(ӽt2:Y*=&B1BD=Rz^A`Jnb"I^* ox\"hfɄBoGr7=L/W,,P$uz)>"Zgb2*"tir)^%r|gZz/]8 Z-U狶tJ6!HqL&bm!cSl$]t7JAێ\| "B `Q*8C# k>g"DogdA珗&b>nBr\ ^UOT ْpf>X|hwhc8(0.TK& (vv]KL.eخ$&wQGÉQH5yԒk|ekӁL 46?k_7:W|3 Of0yi3F͛7׼tyPeqΘ_W Zv(vsgg$ i$ު2,!u 8ͨ3̧^oGP/T-_UvB'@niw[ RܖH9 {kShB M@+H"qpVS>rb'5 RDZ|U*R(D0ωt\bH*:aakTʥwߟnqJvXdLUJX!L~H2e DHJEs!=CHކJԬj\RڂGN: قEɊ|dTUr7y[ъEjEA E(j3_>a-2Ao"y"1Pz\'9j+HC=*5AEG z1 矿 Ɛ[Xς#+;c414kA2p3-q+%>f{QBBX5Ixha)yÉL/t7e3$yvn_Ɔ C>3T) oyO\?h̿?PZZ?c9W:85CUu_7y3 7_52-C+$ Y**HբUn2/Ռڭ9e8; ]tTYe'VR$;-v3#8M  nrgNI*,hRHiGmwz!ӘC`a%'@Hd/v ! @Bop ef(c>1D< 4)Ppx|B1J)UXUI8TJMdp&}CiGHkHVW˒4Y* оpd܂fEȑ; ] ?Ij!W,L~wõDcSERC]G t.  -ri*eG Db %qmY 2&)EbqGlB '\d, hnXڎd\ fX"*г`us]"s`Du&j@z=`Ҡ-UP-LrcGg`J\"SfD ޡ B2ar"Ww @&Lߞ/xyĤ} _~رgZ@iY֚N|s.tt,'++/8e.pfq̸9ID"@0 JoaQQ Z3tꌌ^lX >?Cރ ٟYZP$VwuTV/[UEw#5r]R>ŠLU}E>t"!jw}..OXZ1 ࠙cN8lL%9d8<`|A-Ì#!^-j t: F# >+hvxiH䣁X69uQSNUʔDbA"Qq"dTJĢ}oI2[Yd7ٯBl&|5.K>&3}E=b|I Qx,ʄ(ۃTC$|\#bSnwpR F[df"b9v4煢`dXT^la>(bdi~l<6R6_e=D$g$д=aBdD]76oӝN_͆Μ2KQ!?YAUV.ε W=pxO,RZ+!< wa_P󎏢{zMFhJĊw;HH/=y9SъIϴ*X ʓXqb #U:J$MN+uN0r*xWo$2aN; 8WwaYS9sKB`G MTtdSɥ("gg,m6)1w4ze[MIڠ"ni+=a 7r?JNo6|%8V DƘ/K n(ip8`4p8>m  bкZOFUA{RwY9YaoMV`bK! [[]Mdhqvh9on@R9&k`d_ 8KAF5 Fezm鈢6VKFYҽ.;>^y[QN7L!MۗTe?XVW뎎_e }GB ) ?T%iwx<[o[nz_pdrU]rɭ?s qODXyE}}I˳#&V0z= -=knlH86~nIiqE8r8s0eZPI gF\d|X_D R$`_uA渙k`ocH 7MTjxm(V#W `2i 'yH\ӱlisOñ~{FI"F֘ΓDe*QzO-Rx}ȬPR=^``ESD EǺp@VŰ>߯ZͪQXn3| #Sy|ǻPwe8VPW8e(v\f};] ˑa%82_=`pP.^aɉ?5*t:O@$b~6nœ #9\%UU)b8#жޔ{i+";Ψ%V %ŵ*de>A b165/NL0hwjw}C&wv ;B~9MOG$ Eijude#F?V]]vC:J渒))o>1i4Mnֵo-n 3m %B~I q1jԓw͞ >[ `na!?#w$|&k6B NG }_&_wÒ&ddA$qCcWQQ.ѧFpD:u;|ndLurD!p-oKlz1 6Ik^;}&tNN9`cO$:uIJ r2c0E 6Xy< lŷ904.\OrYdX%v WEr*9P'tJqosN#{U{?Y/kЯn,@[1`5h얪B4aK5O:=-5 sP66_)2@nHKթ~m W253;&^򮃍$ QU|z#~⑆%fNFÿ,(xGYv_3 % N9Ra>:9.LT`ܑz_v'%#Qy~[w6q&ddꖄѩn[kbk{km 8‚"3jSk'',E ݷ<=ktZ[R#.+Ё`c\^o NGz}.?OG>mXNhyMXU픂K[8,aaYBTFQ2;Z|_KRneaƔR~#H4/0328c`5;{{#5(fȠ(9iɚ7$ӯ^J^ Z} uz7.Mb@(yV@$1JK_ t\^'hq{@~WC2 $^CA ?ǠVǃ~.~6 Bp`A6$*#oòe6Pdn1&te^i}ԛ\"~ec1:Vd<ƈ!+I` .xDAU=2x2 y&?}m6\j~7cIףm{$j9띐*R|`IXRmJ[^17#*+pٽ/::9d?:l7659}̍JNfI?qsc=,(X$P 峳 O gY^@-81 IDATśȽQIe7N.H7tA#mkőa:ϐ7_)Zlzn*}G;.I du`Dd+ P#OA;HQy\>g'Nqw_Ξɢ(5/']H7<&jxM! 1l $>ÀǺm@';|g׿`I%#H ' $?9y`  )]uራ^4\CT x/zEDA@*Oq^ p(ޯv44aBNs `w9E4i^♐r?yz€'!t;-UUw[c*Fh4?m߾+/OoH_ƎD7emmPB r*voZ_['G~hl$ {K/?``rAM+Uն(O~ke%If'?umR6o`4v4(=թoH L{a}m`\^͐؀Y(1qI\)vm8y[>m;-TQn0hG#۫+ n3KKROvaY]g6 L5&M>v8>auNJ"ZC^oȳG 0S# g(PkgV L@zg|<Xij~/Enב6[/k09 ߷\`cKI=OH&<=iEh|}90'{uHTn? ~WM~F,,9edf=V]ݯñ?j'?o0mzJNtMkz;:Ӓl665ѻbObwN(ފ(NLc y&1񠏭m N+^3u<5)=~ϼ_꺉< "6f{`6ۨ 1 `^AC5$"~ L3"= p8m':P-րU3I}mܰTȠHov:䈩s rW?H͏$ۛR:jhjIc`%m_E.szE 5c<žg? eY9]VI48 g5O "Оwh;a.rꂡ& $f#k;?̋u"_w z|A۞CkH*,3>肊F7| GvDHj{)r1zM$4KUsmN_ WZԪxf/װd PKV# -2=_"PsiAr1Sؚw~|k`2pGW2nk0")1pL#OWzhUQ$}9\i~y} .} ƷII>yp. IbLp(=>*W ILAPp|V'ǰc:Q eIQ/~tn㞪֖E,@ 7KVYf MS̰2_9ܿOk?Am\F`RXoH2k{e5n%z V)Kra)쌪 !珤CvpC l3c@{qs~c(3y` R^ #;ab>[aË'd T&ζ隅Y{9`{F Zc3 Ϳ1Zc}7%U-iejY)1Dh/bfO*7$- _\Sm}1+*ĹthgsGf:1=9]&~UPr]]GMMq^r}cڿn+Բ*&OZ ? %9uZjt̢} `"zY@[뚙u-#M@E?}>۩\uD͍$A$i a+(L֥*$Fe0kj:OwhE=Kii^ ^9zC]nպ\wѩ'/j?}>+b$:=Z:}Wijiz'un^ȧ)&>sRi4[۝Ǡp9tIhĤZm$%F+XŧsMAݶϫ~qFVWa.^h\ Xɮc(uÅI4Z6e얈2e7(PP$eVA]A1` Vr|Wi(PJFϧ8W `k`9 Li ,;~?Nv5{l) $ 6Әn; 7Qvw~T[g}8Nó:89% GlegJ|[A*1/|ݴ3.:K*1?|ٴ[n(-]r|~B\:%PUVZJs ruluSZ^D{~r:yI V<0v/I C~+m|PB[R^oc78;xamDؙp1L݄`1p&O]Uuge@6?y@.I\=m<3wdS_HV_;QۦMR%Ȼ~ ekͳb+ 15h^*@߼I7YZ~@t,100M+HMz靇 92BO n5C^Y};ZHGOЫF% 5/#]2x,pzo ץlu0Nd ɻw6iQCX'qՊ\ߘ=cS϶ؚ.Ҥ,H7.,cm jgC ɮ6ˊq ?m) ( !IU]38'IG}(%M*Dxh0 $/lӠ).)ޏ y, ǠVABPhG| rlY 6%9jq#3iraG/Y+Le<x:K-2-t?;ߒfg/ILrܬ"iWC-ٯ GvE! w'-7ϔ6t7/(:M`5--OLN6=V]yreǡOK#uRS_o̘+wvX[ݲl=ݱJ(S@T{eUK+?W__9d G-0_X'47 ?u98vAv0D=fͻzQ ^|6ieͿYh0pKt'tރH(q9+^kSXa4u: #IdPǗg$cGC&"8T7b "ң(fb:s f !/zs "guʡ 0y7rߐF9$E]x81Gx}";2.I랝)&-ІvzȈY)BrH3Óh A $N4F|W$aU;&B`,Kd^_ͪn1tu9iiio-*7'%`piB %tf,E@]ޚڷ744x*A 2typDL+ȡvSE^i56>]w~NbU}V 4Wa`S`{ga{*Mx i X6ed0`֍!c>@)gvC1@# սPi^`ųz"=!мSf^#6XӲ3)/L0qk;~g~Ofˈ-G%k`rIbX "\뙜+D^YN-d*l@z5ʔ~_VN߳_֟;g0:JHB {{?Ҳ|sccӚ:d RRD?ad-ƊwAXug}2ݜC7 MLN3Ks2m5  FcgUr1>Zb4}(*鹫ptt;xVHG$ky#G#GeP+67v:%:ꃪ-{aKX3Ls&{ZoiD6T]ty7QzGLY3D)(vx}4SA࣯_u]wkjkWnjjR;xD4&uEk0<ǰ:oEնfnJud$kN"ǘ 3lAOQ7Κ^\ZLZymFile.w]4:viX\ D"ͽ-{-E)T$о=4*L4jrj7@1Ы> ;BI#SkEQJnkiJ=6U T(;>5JӈMU@f {OGsF(ᆬ-)GnL1iܸכt};u&պ场@nb֎dh^fPd4p0' 0l z(K t 11DqX HUU1i)[ p*e$n2  }w Hnp?w| nWm7d(@K 4m^R:]3]ͺELCk{;_d!1G w3ಅ:KYdr5[{ּyR5a:6¶nLx"Kfy_׮jkcOo# %U@Js^͍<&3:#V!`t-J47nzff>̉(K:ٔہ>OJRzwuʫl TTf1kF.( "Yio~ۃJrT_lHϠkkTw8~GxEwPKKM) qag0!)kڅCjHHUsp*!,G:,)(@#P3*FoOSi$AJ;a?wvhEC~Pγ={OOuO'l'"xz~Q)Ɋ4$L UB<;EaXrO[m P47I*L4[ iD@E46IQVhHwрX:0Y̰rC<Lȼ(Pށr ru<2D烔Ǐ߯$ЇBR9S9(wCMcұ@/N_>b.F0|ݼ]b,6\ջW)նd/א(~rB,_˯jɣ#L0=qEq+ ͎'_YL b$Cͯa+JCӹc 7F枞ݡPJ* P^Ynk>榦uulN!xAƐ #|ȲΡ%$_ @Bi,V j"}]kJRƟ.NW rr^Pȅi?tY"y=) 5?'1F_Q}r?U: h1 0N h|bi))ﵴlY}EqQ %0NFnwρ_fqLo A/` !iSUHIT&"E?fGM"1='Wp)nm&o~Q {3GkҰ TKy6E].[MN,JRls>kWc[roe!ri6=-#tO(z"]໻$d,e%3Ey].iN.L<Ó:_LXBGܱ $‘w^o-,@1lʚ._}7=[6::I&>TC#8F[qs=6DIYp+3W ՙOc*`!98E䶝 *(0$K0PGbTPJ]XNSs>);Q@?0a`}>y`!ːrA7 -Ai $؂yP+\!-zY$I՞RT~r_RZK3w;ސ?|]iP@Ng J&%VZͅM7n*,zyGݻ{{DgwJ($tu\tti N.Cy9qHñxa8Uv3 }܌G+a>[.p#< Y{Kc|ٔ 2fme[3k(,D_;-#77v9o@\{뮂䬡ӒX=;-WnPheu0HaYD}Qx4`Z9zqA*ɻ{kbr >a^+ Y9 ,hq Bl!R]M>_h&4R/Ҝ5@Ss@i)C3i|e8aQziy|,mE )]Ӳz=fMV?:%íoj+a$m?q+N4? s&s,td`uAƠ1ݩt:ǶLIALjho[nL좬5=]-z/|^Rħ-7c 7R»mzKY.Zc~[ٽ/Yno~-H/' >h_yuu7|x"gZ+~ u-e˘KƔ2Mzw7 R9}4/ҋ.h֞:Y+}q>o>7>s&؅*%K3Epm#}u]C0X} )-!9$4ywko^(cP1]ʍs4ˎ6>>v$Fd;Q,nuLAvT!ZLoZWĕf%EFnG'NFy|A $ɶjx,RF(>5ƐiAlsQ%| 9mZAbQ޾w%VpOiJEv>Hˤ_nm ^4ll9Ӵyu/tK%K:4S(F8|:ڿUav0iL(րzZIz[0X>e3\]#!p8 kp  > 8Qt.>G10 >f uY},C0^_`$.d57UeN47;ZӓR=? ʝ^2a=csLyf{ͧh&"N_pVPJtȧPtoe^ 7%1C߸΃}jӯ8 @ Gfy-^8UھBAܷ7u?I˳^T_[Wr'-CuD:Qky_.'("aajPls 4,lrPj/%ۃ{#15RޫqO8Bo\4/Qk5N!=:Ζ\Ϸ5+~__O4TN9p޽n,r82RLkH_M/E.X]w].i9jӯB<;0RXUL2i\rSM`xGuHH {dPth,qqMuAQX(jZ;} +j8qlN^e8 [S!생]"(zl"Tp\ҳ[+nȆ>AR=ᩌ]`{S Pα8 [}a$'/*Qǐrezݗkڪ` H~G@yُ<(K>;t?w5(Hy1\9!Ǵ`DŽPyu.d ˈeeeګqI??hS \3]/M . ;O5L\_t\5 TV@iCڣp7Rq.oWZ( c wغ|r9&S+wu-(ʶ<* mPp[k[:675>9$ [$>37VX, Tfљ/I\QQ8 3ȋSKU u;ܯu}mRGxFe/JIɛr _B; G'XdJzGf 6p ڡ(kCښ`p A0`2U  .h; <"BLg( FJQj,`Z lQư,H9]#XCWZm3If7o[q@4㐣#꒣㧊9w.>Eypn _J*) y ׫LY;?h`1S!/Js`P8^C2կƝYgx ,!`PVNj(`2mv1!$"V  8BcȤyl*Wr]xfK R;W*IYBJ[DҎP084E-ٹ"Ep錽s{_r͏,+8ggX}gE`^V:$'29[E*ns$> *^;u\1|;܃H-|+YcƓXCG ,K0\}  pC$}X Vr\v=?56g% u}BFg%=}kx<FAȱׇ0$WlΩF= F$I_MRAm͟E1|~չCEu4\Q *f==<( J4eY64sw4,N;3UU3}<.{ߌ'TkYQb!q*pBRLT6h:XUm6;[h"C}qRs zsCy\s9^bs%JԿ1ˉC5NX3<%ZwI)*9I(].?0H*ڙ FG?T e\l<ஒ>C;&tM]P;8y4e2>Ś)|E8 C*Vl6[83)Fy?٨֚ F òbDKCb]aIBv '.g^;cs*vpwG ~C:RPH %-BĐ^%QwDaM1 -t~7H\-^~又d]3DȐph֠ۅFE$orNXs۶~tel^)aa+I6@|ʴ'h$;wWae7ZΫuz4hfD<d-!ARvmr61p5\%6\ݞ_b0|{tmviDi)d}K~5dZE|&BHHP5ezaYUH* V˂贻C䀑I9sWls6[[cK ¢$&KxUNٍf]Pvt\e yk#"1b9Ӫ: L@Dx7tWJ&vuuzh9Gv$>Z'B!?bw{܎$Pke8J4K eJZ<9mf,Bx$G!)5dG"k֔?WcyPt+Qܛ.g⤽*g.D0,zF5|CW:/xԂHQ#%N[z㥽Di/aPOӳ7 ןD:3V_TL;梤z8-y8l 8}N5rhHP*h" #'jΣuQ=`9f,ǸBgyՙO# a^i^뤽mAӴ@כsft#DH^E|*V^e  ~ BPx])}S!rR*`D,PH6nZ%>&K Itx&FDv(9Z93H5:Sr,g$12N(xQ^pgqf̙vCG!nO1dXaI!obf`y<4B8g-n.Gvl,ʯk ]! O%U5c<A 20E>^|Zphu<^\@ ]yw]]Л<)+.3THh EM rWN %s]=^ZJQh bo9/>Ƌ<|EJMnT9.V12Ui#5FNkt6;RŢml)3u~.tWզ$ Y0S}ɿD$DZ C u U(KQ >:ziѾ\2nЍq\OB;A`&ȺS!L(y xU 6tX*' cc yDg^x܎&$Q?P@ dD.B2GX Vo 'Iz^?4x A(k4r=+ sX9o}"5> Ñ>%0}g<:z v]m09mG#}xy$p<03 0<4I ]@A @R p6[H$j n u}co4q@dOT ^݁"DvC{v %ۑS,X@-X`@mc骟l7.^ݓ$ >ow:3Q a#'&,vĊ3\w(.w0:A U SuVūw222Y7]n \[T* R RSCuu`֩TveiS2C4sSA$$ PHdk7p\kqm˖m̞m3 &&| 6|/Ի#eǗ*Nh .P&/-֍:{>"Hb'V H!|/"# eBei^NP-‡iW{-G u=%4^|ƕzǵ#Bh~\W+s'tRjGKuf^`p뒭"dܳkmKģ (3F!_(7Vob?$Hmp9E+7E0CIP^'P$' Ǯ9XbN]eb7ST ep ǂ6ڿ n@dz=-1g@?m'C)Rt)QEFM#V LcG뜴YwQuF'j]^-?W.*PPS]ѡ0NI4AN~=lWlX?U0Y K+f?u:'#G':vǀԵ @+ nwΒql[wOgӯ߽{tiyq-_}haovѪ~HmyYQƬ3:,5~F ˖&t2$u {jO->[7vƒV%r(#d~Kox>Pr]f6[Z>qsVH`|%x*ug.\ZZ }P#&T*k ^1fy S_ůUe,ϫPuPCԽ#poKrB0Ir?XePp{pD?`}4!C$]G=#I 4:>kE,~7es:82׷9-G䐧EӾx MeGQ8t#C&bZc5%m3ԑl;xC&b^}+ჯw=>3?3fc7%Ŧ}_ &ǐgDAb+˱q @N CbBqf.F{@7܆{^B߭V_WJ,Vi6f >d6WT.dCI:WWV.J~ڝϪ!FO<L &!vt^g=' @n< &놖pݘ98g޿ y设]7?7Դqv\$ꉀܵ37}ww9~/vb(|וֹ-2mmAX9y\p$!R`P8ůyöE98iɈxe^3]s=̅Ͼ[SSh%+2v0Kz)br5k1xlI3d" W[ijh/S/=SW"")[<5ejn%Eںx{= y< < }<=L[CX$٦bG|jR@MkVmOΓ,{:Tp &PGQOyӿ3ڋ ?#&.$> _  wWoƅJ|v+ޘ{/gaS";Us<~Y3@ėB\~Y,ǏN)!!)#@j|6=28f!~m&/5K+7\Q%ڊ x@l y1 ?6`x:Nx|^| Ѷ3ANF@VJ*9'cTΉHnOHkc3&ha1ϑg,;(-@rwEnqܰSlx_ |vCv,{5wYroz 9RU9qQ_9ZY?MtMtW)A#>IyI_?`4YѽE=ߐi?K1}Rx{޺N_q+X Vhvg'Ζ 8Ww)-=\p]{91rZOoU=Ԯ-tgRlr c8z{>!Q$T6XR(?,; 4ήoΝ]slk'k[ A3' 6TSH@x?^h2,xx,z>  BjN m?e[&Hm^@wzFɭn#^:I}Dҹ5E[9/s|~ԛy7{$Ժ\[*]#\̜ RC91_L$H7Fӟs8Ho6+ /H8`E,Rfԣ| ~[~EHmio@8fkI# ry|hznW:>Dc3G$IM/VF2h]1<|>z!zɵQp@p5ݥ<8`q;O2h6l{A2hvkc21jA* h$Կnq2(SAiwC{R#d)X,BL欨XF <vbxEdYƫO~Y_8@k@@|͖}8%Wcc#w땝:GD4ytxjL(y$>jyvZBO3gk&8xL~EqqY}ɼ/l6i,]Zӵ՛r #91eLBjhqm"J7 Y׶Jve4{qmӬyqNC^k"MXqO6M;j~z`ɱd^Rzr|TL>٪nGMC64Ke;j[&ǾI'( K1R ݼh5`vH>yf`\ARܣ^zUUR9o\Ϡg.Ss$O/Fbx+KJ('D遛*t,oćP#YhՕ<|*[75xOXf4 ǁTB]#>=z1 IP*pVȃXȃDL!Hă:X E hG '2b|`qõ[}KxxRHF)CFR4N/DFb4HpF;ᾑ}q%DC W})8p/^||am)ܲ{Y/K):kZmo E7Eh#`<E.<]Xya|^gb(1*Q)?1>R|njS4[."5ZiEpI&3^ / /8Qx-bW.Ai*|&DJVúJXD(qK:O,Gob[_஡=qG lw[Wfg%>>#0Yx5}bBuX:a$EÒ i`ei<wp9[œ][n2F`c] ^pƉ2bGB۩gj=E(@ߏ~@q:J0(=1qhfrPņUU$R'#;$M2ڬ%ՍKkA}9Z1*>ȧӓCm{s-_i+ ]\.kr\m*gT9ܣ-6b'%[h-)Y@(n˖=9֗nҘeLPyZ"Dn˭پVJӍ,[&.'F +JAL$jmC;KqX]pXu5N$80t.lT }v0|+yRN4~ xZ.4MOb<Be|땻MrupfWN($[5)¿b 6ˑ5[>H`EDZkʍy-125BtV!*U>ߑ.D'@1ث.BgC-S6k5ȷP PߞĒ|̹l0ޚ|dj(xT j Jl je!7X$t^4?o:qV k>ϷDgo*c7GW-| YRC{~^+W.{ɥ4(%m^i+c-ܙro5 =2#תTqwOkLQ*:֔I{g[^`-]B yT{ˇi˷xY} }y󷖺2%IOOW`+wjkiJ!9Q{ [-iz %h<"؄:ax܍'e=#4؁/'"wAad] \ 'f~LBG4Ң"3Y:׺GGB O eY[qp/l 4O`"hGDL1I^">.'FV5l, fzHPkl%k׳/er1A72{Od cS~ߣQ0LSW8UY@ ۰̩;Sb>]́~* xSM/`x1ș_=W2\y=E8q ,ၓE9ᅷ9CްzWbFeSe# pu!BKC˔o L1π'Umr c5~`@zb4  O 0n0gA8LME >^:h,k{u_dt8P{Ө\xC-МD&J{ s/ %@W @n-đ~qaڻ´ΝBGVvw++Bor|`ܐ49ǂaWvʆsEU ~~E$/"8crRN._"B.u9KH swQlki$jφAf3YoKXccVu=z K:M DžbYSs@U\T1fd'Hx-57B ?{GpZl$Ӑt>Tt ~1L<_ sNXPBXExd'H e d;nz(9=zqzu܅9ff+Nr ;<3 f7+p-<')Q'¥5$_%#!~ArIZL E KL=w!tPT#%`~! !7zuuxHA=%íU_AĦI^ 6o] ܵ[aO2&"rkI SV$I+UhaþšzL*$5^[Tҋŵ' >í+"o~NJq΃Dw~YK5ěp<|/E>R(mYxw(L۳lb D!hgZ=[j 7>N$ybN4å,x9 w9j%DϏ˟'((o]\^ۙv#>Z,"_պmۍr 8u~Q' !A41ϒTWvԂ:|_:9ټ7"7?2%tXgMcbֹp^ٻxP,dsL5hnAlމيdY.8zTԣzu=*>M%1R,#t5 rGeʐ$?&ΌasB~j ٛ[ɇ< &89R%MÀ.1 (~ڟ Ve yaxdx侾ml)׈׿vھ-+j7Xb>yXnSQ{i@~n%L[,˦=JO$[.lqn)v5_Qwi-`E+A2@Kpusaez&mih+}S\E-)jg7~\philkc$=J,g=&g'1,Ae8nr\sLm&GRE@fH!pU:<;jރU,pu4A1m;4G V՚2db #ƂJgX}ħ4: ޺vs*|Ht&е~ Z^6w`!db`4ԣu(vdj,tu0 F+$G*G@pf'yF`,'l'qv"~SvX,gt#܊-A67Tr|W|? +AZGڿ}:(C\Ց6[ţ@e/>8"UX_aVm WW^5ͮrQ4iT/j$佂 #[-xp=as 7zkͽQ~JiWƊujp3c5{^oiӹ)Y$R$r\LIUX|Gm VS Orbf ALa`9f0/5_h2y0z"Љ/8 8SUH@aW&XE{t^u#/$̓~wm}0ZM琕UQ(]ꆻF<%\TU۱]6Z廽Np}ZGbJ"D<dُ{c΃:I$C/.وySF *DN!sP@χa`܀ HMME\J'5lũ&w.>m"$9k`=@*-CՊ)!"ZUҰnyIsܞ_Y yDXǯrr .U79ߴH݉?@QΉKLHIr~{\-LN7?چgZ;Z.q?8b5ySd@dg_0vܹ7vKE)QA+~SViXWҰ2\Јtx0lJ} _|Is㰸t^)$ 9pd>'C qH Fr>%2?veݦ@C`y"!W2kb ػ?)BK_02?YpK!":Q7aБ]ARy-J/G<~A4t6w/- 8eEԽ#_Uʰ凐ɠٰ],HEH x ovz tzl7,9>l׿܊H! W'LO]fqkѪe!i"F.8t%% j;uעbdqjC麠.cb>o}@.@Gj׫k&~5T"ۆ׭c1.a'b~|qYlAС'b5wF7|ۀx -F12=&}:!i5H⪢ZDHKU I$@v-NnI.# 6w<&`Ƙ~8| Vl/ -ڿ ̙-`nwK<TMڎT_{nE.X.j+(qBɚ~}BSV>IRw*,#儱ބPR?㮾cO ܧQFtdcYM3 +jV3]nYB*[܋r{ p`Xr v[l_ܨT!_?HPLMDU^xp :mv#]Laٹ)s0LtB$]^9(hE<`8Kۛmb2sS˕,E(t_7XNڝoܫ}${?/z!jD+=1FHwId4}XiI0aK:HۦL `Dz:0iuX肁`Dc {l:ᬹc~+c҆5ō(7#&A`!+Y] oc5kI;_n4`!J 2kćOPZ~禍»k#%6Q! cK[ j_hw|# 2>#4+׊r~٢;m8|x$FGH=~lsMkH)ZlB&#)M^Umsk0>^mhe-][OKhZ,s4ā,)6gw)W*7B1uTz<ΥJfY\oój$'Ear>EAbu?IqzWy.PH Q|J1!NVO;Da|_Ykj" xڜ1BG /> xKnYgrkP6ӂs 4,B> =ubPWrVۻc_Wu,cm6v-dc2`ػk9ą凑I @67/K(]0fs|]bxoG/_{n%$@Q VQ%&bz$G+f-R4g=~dbEEp!ʜ}Q[)tYR>a.B|l Hoip7r䠠v;YuaZe6NC_)qܐptA\ϙ2=m _1rOƊU/ b 4E"Y5WU,wkjvFp7ߎHRJ˶6e )&|Q(h^0'Ms 3y/ 荆I7D_FD_nt.Af3djV8 6hs`){mD$8|ćo ״Aܽoċ׷jH&:L;:L% JH !H2ow>\g|\FާN7_T[/W9W?7))H17\.<,:<1]DgV2 񓘘ioT{.W]-v՘Gs\/V"U!x4M%73N !NBþc ijEF)3HA,aImmAejI,,ϞA#\iD˺$ o[fb_p`n,DӃH.h! Q-x|O9gP[**@ Hkx"5|N`ۺ :O4y! N/(wY67?<E,؆Wjv3ҟݏG/_{n$Atlv|aUJ4%+'KkXYmVn]IQ0̼κf, .UIUʺoWԶZnVnHtӺ .}޵GhqTYm=YzvCvcrjtDf |"MbpXSl8sbIb"IZ,{U@%| ǭrߊ2M5vrUl\*X.ky{+5{\TM܊Ň0 @[@z?c~ͮ/"Sz&{y4ŧ)*D-x>)$|tKJ r[|jjxLL'qLX۝[b~]cX1;Xޖ焓^PP*\r D;yJaTp*E,{]yw|?;;;n˲ql @  !$]\.R!$Pt0f*V6muJ^I+ye0̛3~Y-H0eHP @6jĵtOdlKLe8:[bDCz|쏗㳖:!]aYA P6 SGVBD&l^G~;X܈;xLR@]|b|<s_x2퇇 bQF׮)UlXb$$xqj9O{؂/\!HI6i;!z[JB#71SckX4Ʉ7yD_ہ8;K&ΧބO aCzTp[Et'ӇÙx8|~ ,83&!u`ǿߊtx@ w1Eh"DBf) 2ӺQEF高 }|Uܞyxx+7^o+3{{;1p*-+K4v 2v ᮖM|Zt襣c=~G ˕|D^Q@_oWUO{ӘxC6K$0eJDšM2H6]ѣt4MKl0ξxd0h\E1(+TO?[[EYӳ!@2v8 ˀ17fiz1**XdFveo $ I"G|<ż [o tu m;GmF$ }Ո虎 IDAT1n;-IAIAv6ʑArveZ=| ~gN\a/6a 6Ǵ`Esv Ŏpnێ^Í땇/ .1kWQkVJzdw0fsz5t,rs~"4< }ζƪHΏ#hP7tz?FK$y7*RxR>1Ix( Kb1+zs4IDhX-P(D.9 >w;2pc\47CoĿ&ԉs# {BMxo~l/55LUtbr璮U,")o땇/ <(o,)֤3e%yuMUT"NlmQN?u|!i73 fwsԗ3$wYA|úRUnjK7>8TkqJuJP..e\jN?#6vh4AHհnFLMb=NɎO5ӯ_Tyl,ɖH^ WI4:]b1|B$wAW $"xꐓTySI6-5K6/7˔ds0zؗN UD-ߩa=dF`\Qu:ܮϴ;:z )=B3DȩpH+(jrƨ jjZ|$~$Ʋx8R1pA8s4c oY:~㓦ٛaّ̍ίH9|?d@5w()|mo'޾@HB0९.ÖI3l"lьF>މ(H_/k's ȥ- 2l9p~c!tSSefY!LA0Q zasP.nV^!Y[oփG=r=}H2JKfsmvtG4 Kn^/S.*<3:: y$m0dB}{Nί} aꏞX}f^%xd8xaLm*Ւ-r9-%5D3_ Hku~I+K56~nZ ׂmCx,v/~AsV>2gk>}&]iǫ(<< R\&M+Q.[ 1/ݯ`Sݸ\.c͢ϒxg0OKKu7?_*t=|Ѐkhy#ghh׽ȧo0jזhTK ZYQg1TRbdu\# =18.nꖴlho(Je֪5uz1!td$HcG 1i.+ӋDDږ7;HHaQ7a<-왧ٴ$jʂgF#cm"*?jмʢgEu'GR^,a~B-'Iѐ9RD3<r{.$.{7hP| |JmM>K \oSX.G_A>>8E@ וY$&k6o';lGƆ=v'p#vv>ZL'ѩMD*;mv_> =/v]qIZf`6Y7Yt^!vUIZ ܄?0{1 zmXW02Ƭɢeu I5K*VM#$ =$(HV'޼TԹ.C< G/cJEWCnI+J}}οfOl ?>;Ri< :#NF+K|6ݩV7cz>b1ճc,?%Gp5~ y<ѐBBH>fb7pSXwĮ<<<n,? E; OdgBvݚs]i}Il( D0:q:qlh(cSB+eZtE)ռDZ`I!o0Ci{N !ۈoOn\7$4Un(ͤHGcvowC#N_hgt^RPoUdH IU͖H$s#gqao8R%eFIglA?|Ւ2;Oq a;-MB&|hV7+JH|"RPۙy) |`4땇Rp-kyX$?c/oʒ&5ӬW+:c4kJLZ TY^yxx.UxλiN5iа=N٥͋~$Gm#64q\^s.|HddY]rLZVQ-g+JMtUpZ7==uƂq%D!QSošuL+2rrb8vbnlst`CycZBN/rNFbɈ'A/64r,Z-ڢa6ޠ._bh<_H$J?R(SfdK- L\$?=9qҾ9@hz*^$ Yx$d 3,^B]=c/4$k H[4EK)07($12<u?Usnh|?C7^w qnF?΍z5kQ<}%׼<2kJ&4MٸhiWs̡bFA??XI[yxx2L?]X<9NW,ǔE{R^A>8Fm1X%ۏ }vJ-x P ?s@DbUU NyI Z)5-3X 2Huv̮=(HJ +UĢ%e̒%\'7ƶl {v{`$I9~tp7ӸSgAjkLd^)"Q)IZ@0DG/Vӽ Eե:u jQEmh4U4UhΫ! ưe4rz%k1HfAM'O~NT~rSYrKbϊD- &"$ܹW*<۱`tg4+xZ"Yo?|T1B-TLND;w2?ދ>CcOcvO݆3Υ`)فυ< \Z< CHI!R,"qy8׋+ϥ/ `6h&DĨ?2u/ڻ}cS,Mj_D21qNzmvoA"b% %r c;= h*ijZGZZ`,ErZZ26U蚪,R#(rQx=1jOL "XS!Y5@ `Y,#ᣇƜh(vڼΓ|!,$r9M7t[JFZ'Kq7I$@O;@!5h$u[LiUT^֠/m(QEBrjȋW=D፾}zl'2~ʅ8ү&-K3'0p<mEq&21̧J5 RC E!k?q:7M4a`~%+a8"F*ܥ&ҰppOW_iF)D+QH\ڜ~ʶbϯ S땇R|mKk`^s I2JJFmЫj9pu֮MS;˟z/|d>' qXw&~͞sӍuv?J===NOzݺ|oIAȉcno2T8tBu%V%[mP+ JQ`MVmsPk5 )#.eӉ8C8x܉0^M2bJfBOr`Y@ =caqz\nghW{ DiPVgDY?g6jUk JfBY!R""$X"z#JDmhZenQ˨&\`,_\&E8z7~:꒶|~5t"he_H-VI#^ܪѴ(нxWNgRDz׵ sFp%X=LJbB Jvu6Yw|H^ٌs^o,p].g :Y#U+jR*CcUڢ_Tn˙!ǎQO,$!DeZњULmQHSRJf00FWu^3d#m}cX;<\n?\ա?d9c#G= FaBu:tQ( BP̤ݑxbm`{P(;hbb-Z%ުlTҵV-Se$^  uﳋ 4_4cj*Lpvypbۼ~sE%e'ݿrE*IG!+ ۡUP᧫E~ 5S@2\o)pG#zDiD3N'=eW㥫JG&6Eh/^<<<̀A#7^J9i}H_ސ箧izk?y`צZ1<~x-?ieS((q}Id( †-H$pǛpXdR\Pfk 7x#~aɓ=5ܠUVHrZaSsCITi5ח4E?(摓38u&}'J3JUibI_d,Vsi\czNoumo#{m?\}^ͤX<:mٽ#!GF;(C"Vj3rE tS? @xd y `h4P5_hZb_MLS/KN"b%IHB.s̫bfL&'0|L &\'^W#nqnLE?4(Ǖ2_m3n|dSs\<x+ 5>`nb)TLr-B( |(Q^yxx.5xr>~]LL81͘2k*7j BŠT%XZ\g&f58ã>8:u -O Rڼ\Pj\_] Jomkm \X0j;uBAUqU2LJkucTk5r9!ɑD"Q폟B Ҕ\CW.*uă_|{{͞/ч6:43R2qG##:r%Ozwa/~+ :WX?TMI)n$dQ|}8w]/(bZB,^SOwҒjZRr\JCH&=!j>y @}ƣ $EKRŭ2'>) ?dth(t?x</01ڙֵW/-Ƈ sxpoG~،(d?\f Rxoms^G{،BĢI(T$ jobױ믝x=\j2V˓|] FJY=عXy2\\7 {á}hyIH2U()B&4X%5UzIMR: ΅r"NP=~c,!҄\-QekiEbMi)Ba:J1Wu SS2&9C*:}CQ_a։4u$WNw'G"h>70S%oS7`E|5aXxݽ?2~- e IDATx98=;Fb+RRPD v<8!" ThRH≀c= F޶1w )Q@mK*i$WVSd*Ez%#6>XL($*ocJ$8' # +7z%T^))Ei!L?ߟDZf!fntuOjU4xzw#o'o6R>%S;^U X4ߴXQ^yxx.%xF"YV+QMSZBjϗM˟z+6 h;`_goӝ4#BN V-/U 95kDDFvy`Ѓpw&RZΊGjteIsZWU rݝikszqٻ:iZGLDBf(jhIE SaъMj#]v땱Xl?$>un(; O#\.w9GPXrT_$$E\ڞqg )q2LdC#G$!$9J4M@/7l_ c#tM:vAB2s#g( §)%}H)^n]0r!0ׂAן6$މK2ހވͩ` &_zz< @N<؆^;Leo~k  S8* k$ ܼ8ϋ+ϥ/ EdCcjƵr)VhU٠.ѩKuUI<G1Dbq{'GlHebNH WJD͢+S^2ȑqr_,OZr82#H<&SYB#TT K=ރ=֘=Y7nLn8›#A_ɤDbKJ$a_5`o,;`t^[MlÇo{h/XGL1!$Ѱýf}X CBV!,3of1l{+R$!CD*Ig~op4ƽ]s.N #h"yt,xv9,$L'Uhtʭ5'[uT$9 ̄A%8x@$rV*>m_\2Ha ?iP.Z(ĠJH+>_Q1Xjze) U󑷟B92p默iXzq{zṔdaQ( J2&Z\1ijrQY_e&٣B<ƑLw o$PK1$) 5R([_BnÑ!玷w/˞]k=yUr#0$G=nGе&M2L**_L jM1/}ppe[Hla4]!4mf UbJC$83c"HfRR ePxuX&PH-ŞGk8{4@4â=KlXj` `d$$dZV^!sS B_m/cAV2~9DZVQBt4p2d~ooV[NJq/ZT W x_zf<ޡYwRs\ ȷ\,'~ӊ97嬠XJ))BKA.4z̬dF||x ZaG1<q EB@bR kTy(BBIxo^mp!`Go ;ݑpSiD'1PFQB(*Ώ7qX˜WC6HܣLH%%SC-S7ց +Pb@YBФF۝Cwghغ S_倞h@lęHRm)`RNђ[j2 Y~ZQR&ehw YaIl&ǢE.G:"WabXd=o<^5s._ ǹx("E8s ݈@BW] X4NskX`x\*`hFb)IPh #J^]a jaA,oD\NNF|8=a[|MR)N.JD],1VRr}_&/:5 q4vwV# $X+5zؠAmsIf$zv9г#IaIhDͫ$2e0|z{o?v! &&@\_Q?OiF{hbd4 F;3yv!j-"Pdbf(p8iE#h6}Tщ됔`Mo%6r N~?GsO]#xx&hG$y Y#9Jlғ].Vd8ܼ_m/#ϥ/ 6 ZQSf6K)qV!S+eZNSj5#UՖ5VD ljyr(+}܁N ԰-6&Jhpoy8_?yʼnl/lZ"ˆ݃xk0LȄiHJW2-C$zV8X\se$g,!IwgvGc:!fZB8bwmǻV++k?~!)éH,GI-zD82<*"ﬤ&Z`7*eRPtA1yY3G[{N/DŽ;cjTa/zRX+^{e3O:J$2H؏lL pvj\ J*bw<<<Ibi(Wu:lCeF\I i*ƪח4UT4 =>Iךtwg.i P,Q ʠ{鍿'C"بYkSZ Dy󎝳z% bw4$bk/@9MҨ2,f:sÉP|᡾Xrh4'D; I f,$>RISMZjLZV+$3w3,'/yt4MsYxLX[E-x4>נJiP%0!ٯ̤,X7Nh'?7XV*0Y8& w.0py)pbʈ2e%%/ <mNwۀdJFuIX,i=%k)00ƠV*,:m^hRhStp?f;RPDQ!4#gwF(}p!VW걪BGsfa?uwzO%bN@ Dzк\+3(bZsLLSlShL产<+6d *Yǡ!ɱ ?/qDcC},}2{@W$j9J b2ĴJV" JF!2F=e Ld^ɮ3%r |NS`~w$[kp#!s<<9DRh9D36Q$r-$qAє"Vtݍ+N<<< F@۰6ۮ`-3i2$˔ єԐ|ܙd /י1*ON qȰNph= lSX5JI-UɅ8sactG8K+Ry<:=O}'4i"9e8XX}mCmŇԀ7l ǷSa?U\qs2q J/pp`R.Z85BRdSS tEÌ fm!X[ 9b i?S Ѿ6T@,SI&T4ǚUJHv~ ;8mً.-CX-ILJe^.F Q1ź+pۜF*89ǝmKb6Ʉ,$)L?bQU"Fä942T}X ni(}H b$6,86)m MUhK._}ID1*9Z)cK],gI8W2j*J%uRX&Dr`4J9 6<9ggvF#xj^²`Zn6q(~@ H\BshjR/[*4DI&5JT*LSV5hn2L'+(ȢFY%섘p3>3dr &ts  bB\d5Jigbu9NQaP,]!˯UMO qIC9[F-lL*OljȱPtt0G|(R*~ΥY D#>B662aįC 2 DN; paNhPP̬u2p֬*U*!f LW=p9_3+ *rd.: L(&^B!2-ZYNDY1M2,(cYq%(n`(o)2lIk0cŜCE5&Sk>800J@މ!+S`Fq@sϲߴю)υl@ s) ϥ@@[;N[(_S4Zb%%BKE9%֔jdzJ[3z9sq934748c)⩾]ZrdQBR.gOΆj.RN-[%\Dˮ4O+7=9G}O/հqzQT!&3yNajY'!X @g{)d'pj'E=f/)YwvbGs. (qYo|ەL-SJʥ:DlRѤZ+*D^R`QKٷB3,Ozωp(ƎXdmcB7k"|X/ܦKHX"vfc"#iS:)*zX' F?"}䜝%Si`<8'XĜ"?3[/<<[6%s+3D&fLBzL`9JҔA Wl@@t<7l0ieTE)]&zDb(HX$ BgQBBz 9t_y z^_0љ}]*%Jua:=,]H I%%˰l[_FZdH`eY61Qۏv[f7CG30˱s!_3xDu3GQ' Ұ0uS`t!giӹfi;)/03(/b<<<ס zAO8Vb%EUWR$F)IeZNr-(*))2*hsN? MTLiZBb}撚]F.W$>Iaa8t:/zdA*=+Ve5|;F4-VX lPp"S9 >g2y\pLM+;_*V1P0.@<<:2hKLIIaAV2ƢJ)eTJAERkri-̅D,@<( y\g{mT(/DnV9H;7`ΌZAp5ECltiXim`\Q0hX H**1:c}D!GSyo υEچ}BzeUz)nJc0t6p(aX)Vb":7$gzU)6XWո^X"~ɾp4*\IbEB\cqw<<Ţ/Fm(xs`S5T,-ϻ^@xx7:2]c{CFxN".׉EZ*"QL0R S#K(RWwpF&XL/XLvo0bd##8+$JH#3x oG)jA SVHH1=}1_ !±/WX4 sIј1RdUAP~wLlC4>uHQ5YNH#RB АBdhC$2\ҬfiןYD'ʌ8;Y 3y~ WWXBg `a OYx28qҨSiĠ 1cJJVzȗKAg<>#߄4AhIB rBQ"eRSJE&r\P [LғfnڣdSBrW(cE|፹3w1SQNνB9&1C=Ǭ1S %ϻ^@xx$z^o(al|M6H2PP4zTDBF,b(XNIRJ Z$$H6ew)@B)dbz1`lc{e[UFz1gPpBTUQ1.#ZV+2]/c#tLޣrIؒ6}G0cn9CT! H~8IvǦݜe0istQ)8zHP)|||s|S,q .] <7"tk 7yt|[:~ڪOz-Dӕa(5PDLb؈^:TJ/=Gm98ccD{_~%sdG? ),uw}k"LwG TN|t!fB(4"(humZh" Xy wF/u={x^34\Zx%6ڭ-MֆvoJwj}1! UJHpF- @HA@+#Lsf m즬6K4UAEÂZ V"zٕS]Qo9G1~9*vyic$<VB`9 Ro!V324{?6N89c<]D bvX?DEc(1/qCU0TΌRCtdۓ9uv\Z윥eWڲ2v1X2 pd<qZluѠy%!,yR aɐjJ@-"@ zieeI)ldf3ɤ[;cۻe˩*F0&qI,E$[fֆ(3xiF[LDPPn@iA4a >>CSFMPT5*3FH]Jd+N!bZ)]i]ɮDЭ2{-uy0GHzx!PBӜ%! N(2HB`4 ┠\7ld"#!Dc)cYݲf!~U)@+>a7sc@"MCM[/@||1!;KّDSD &E <)$'m\Q-N79˗/㡲9svu]Θ1Rʟ !6I) วzjC=4yŊÞaÆ͛7owK)%8b<|P㚷/U ParsP@Y:>G !F,;8,}dVڕi q_s V6 \RYM6Eƌ!,rz1 `ժU#~_.Y 5k֔~ؙ4i҄{co)/BO>9SQG}.iK+wr)gL}Rʈ"Q )lIePr,_s[@||1>t4zibP>>PNJdnQyLAS'@'烫3$;waSO]D>Y`ǖ/_>rLyyXT*uʕ+{k;2[ z!ĻR )SO=yѢE/tM[!l\I9b=&|s) bs(G"痴sP_Z!R{(Ó=W_}uiV+<=cƌkBtbGyD1 }fΜ9sr`0\s5X ؀8ȉ)'도A2i H˱t;( HbH $"qSKgر9xܼ4؝H<W׭[WfYVWe;vf2rH M[B/!'L]_y̅^.fmq]EX@(Cn0o9R!Ɩ(qۥvq%]˓؞$zxRbH+a{n'9"-+"k9*+,)D#Mx 㺊P5Uq3|hFXt{ # )ssMێcǎ]zul.h-InӦM{~_,={v֭[~s:Λ{e+|5\3|́@@._肨^`,Gr,9cWupD( kZԴh"o5fʖW- z),/MMzIJNnF+6J!JK:^ )m)qeK'bU?)%~}YX.B^9z>\!H)u]7|sk6裏fԩK|ޱ4cO\p'x≙O>L?vOJ,^uåL۶Y 㘥 i6KsFaU<ԔܫE@I J$u<)GN"D=H6Cq8M٬[V&iN¶lmKOJ<,E ]WJi*-k+_s4\WFxW>xP8DլVzJXsFih*BH<ɾ~-,Ćyc;ݭ iӦ}W^yndɒщD¨l;s6}+,\p/o~-[ltKKYZZ5kV.3gN+!#m0}Qt}M~뭷lV/--MO2[ouI !Ė9( S%XK (P!T' #_NNѾ2 r… \pa# !D~vCCPz%Wq,"69RL h}KcᠮTRUQ*z$ BQ4MSBf@vp!JHTa;4דZZ'^[I-t9Eq]Kuifz^ٓNg[-isfYɤ$ qhOQu5B!=BTh^`uMj駮 vQ.$:qUҙ{lB%G_t}Y{ V]In-9?O( pj{ўw,޳- Z,k^z{uv!đrK'AHփ⤧gELoeEd8XN磏/@|>Q`arq#*K5Ux")@Rz^$d zPL]Մ㹡iM54EQ̠CZ@Ӵ0@@ P* F@'i蚊-m u,G$EʲHe,l:k٫rK 㬰N6T?Z<>4mdus= :+G15 CdPQza]úłAb w]{xv4jب,^<81" $NGaEVBqAT]$ln+]#良 (nҼF/-򯃰 )_/@@&W pXId+ 4uD!4#)* qP MUוf,b*k36 aSjZ0b1t5 tM%jEʞbL&hIHe-YTkjMƓ)ٚȖD $"k[u=OxvRz*hA+ A!ZjZT WnTRvKAߐRv4EɟI's@PX( RIF .͛=B"])DɹLS5=IBz}dD &i@KC\a/@@Ps7]unP0~g;.Ek:aUTiKgD:5&!m;"<דzdm[u8ږ#T4! U(("hJa&f0( VP&y`P;?;)rv^(YPUU5xd,}#=I/ ԰i3˺U[R:SC=Kݽ?*cJ,FOS@co{`>>>9q=/fۚ ҚʐdtiIƶO]Z]ϕRRdms=s=Oq]4%<#`?ƶtvtt͂a7Mst |`TI S0?/!9@1T.f Kz2"GB)L PiJUlrۣڬi29g@V5j*i_4 )CIhqR%HSa>>>1Ha֌mMCka[i *>z)ŊSUL-OپѿŤR0U輤q`tM.PKo}F1nê9H8#~`sm&EiY6%$ r-hzYuؕ$ 9RGS,~̨]L veL& `?{_c66Vw5;DO:kYi;Yxlg)u-{*yipղ4zq) F6!?1jwUirz> p^*1Uףm-ʉޗ`)Q>s0q*Gp%)U%4nsZA6wk&iݣ4G#!pa;q} ;-p ^O.b`p'woVs=seJ+ǎؿFf Ѕ*zk:Sw) jTEL3j㫢T#Qۆ?-_w´ m9߉r^l!Դh'yQSa*xM9g(fml-pw֡ASq t[756c(Gª)W4ȮS}} sAA* Ym:sO5U#4z"B PH` 麩 %P,d+"`ijҨi(`PH0:{':D_=zI\j̘a grݩT}K6k;0봷md+?,0U5JhfKJźbLDI Ky ]B?ⷸ?EUW\ISRkt NHfdDv^B2RJ -i.;QXX;"tH-PE>>!äc p紐 x0Y=pN=pT&Օoe;7]N)ǚS + )Z!9s$ zذo9%AMUBwܯz'D à4@̤DEyF򒒪6YV8L'ԏfarz+77Cŵ?97wՕ<-nAOx8nCC (܋d]dYbY¤:RDw!2]&D49% IDATgdԌ|IGȪsy$=͆=;3Mne7%:8e~Fؘva]t$Иϑ/@Ă ?K=җF| mCHЁa h[f2i飳ō aY ]e2->{j$x޹w;\ܟ\=k3dǩ&3 ץsw5Yeruв? e茚XJ'4?~~ab8gtzb r {Rfn9nP|wEm`Ë(?$d uD^lӮT꠸.CJvpdaFBS]w֬z\$ԿA}θ=IUvWn<>w֙DC&xKޏ]*$KSйvU)FTMUs>z>AWq߂d ithL}7m3峳Y3Oؖ+eJ> -Ơ[6[ }| |؎SPPhn 0]Gv=+}tE!iղD w(8a"I8>z=zۚtJ9*,~SgzwgYƿ]~_bʣQu L1> /72:&< wG($ȉ|C˃ǧʇ/d 4$aXvocF"%: j^'9AyL9eYsmROrͳk1)545fX?|"@^HҧEћǭ.Ӯ{Xx4ɵ*Lxq֓UT zM^^mG#7oB__*'Bkewӿp}p~_J9̠G! IJ]"@c.;?R5v(!]`e >W0~JUh h5/(GF"MꌊCp%44e3ҶG\~ɺf,Nzi&9ONv~|rZ2FN9 4&/з(E"%/,T.\)QL0`DF57C& z1!/"^} Y^2q^::hJޓjfmx{x/L||>2H$;ҖEYaDt(oZi 簦 v73(&ݑn,JC&?a8LD}RM@1bDJ_c3`D(TNA{ͮleSM]!Rm=77"AXXq,(9f&د81  #/Yz15H!봽"2RUɬ[K_L?VX>D^RW'Ҿe;.{W>Aʐ ;1_/UБt}֑TFχǧFY@dp֏b77`;.K+"/0(KH1y#tE0<Ȥ #rQ%!J65g?voyxƭO:{ζ k&k ^}|||$=L& t1FGu}dmKm=lOѺek]]VFqO&sȄ  ,@ b_F=Tܗ_F7f ]`l1.FLF658J^Nk{% .M_ŗod΂`v>bVp՟9'e&~.Ee1bSw'oʴ1|ϰsg0ǯ_ă̙Kވ.k ƿ.Ë3x4Om^r$I%9?4%9]#Juye:${%%sy1E cvs숐vvuI`ĀEJӆ=,ee`דliɲJܕlfmL;{$ Iw񺽾p 9Lat m$A= jxIIiUiɤ5 )W^!BBiizED<^U-,^̘HD O\`úsC@ڟO3gW/?﹛~sn<.?svA^~>4f̵k\:a"irMDžN?wz[?璓O"<ia}]]Hu"2=lDjLܝ,o sBKd"2W#-MݎMݯ N)K6Ko{'¬cE$mΏNjv}ޫqDHzuUpTafi0nړMa/@rmM@5P]QJ)ypv`)Vt&螧}9,Q+*l\o[7>jYB^`U|?`Te%~>4SNQ~} `h 05ά]eݽ 8gO?},;wy<9` gR x/ݹ? &S$Ԏw' yҊ1Nۉ )*걫]l^rvn\]2cce*5_-oi~-3A ;ǧ j&jCiXǮm?*kKcxϋrGt*E09,HT:D^|~:@6.j/ $*; o Fa Qq4ج{`Oak3'+($ nR]x߂ԏסFKªh޸oM-=v9 (9| *c޹/V9b,}%xP*FDx MtWFV wt׍1c0jZ&YG1 {{oДv'7W֧+SJʀ&!DRJj/UBK NaARV搻|Uo%/~ytAU%4ņlfXB|ӟfҧ? (-Eџ79 ,%@A˲wʛA[+~>y ~?׿i%3KyN> ܋+{wo^(p׬B pm%R^Fow/w6F'Ǔ%/|s:1:DF*`vبgz}f3eo@r+uWq1AU >CBU%TU%@am10n%=x-woFBY'(CNB,ΪԀS2&NEOھңNr!(<=^@_ ^DjR}Ox֠~Y@l7LkQ̻*:8XHj#L0#N/)Lo)U24SYהXР7suDMJK!5Htz98/BmCrD-WJ`Eum؃Dm?QKJ4tbC',89- XkZA Hk&u ! [7lZ>A@F[n]V;co'Jbc?]}o g;˶XK*# ݭ]" NLW7/xǧq9q_1ّvNt WwRP8PU?ՌsO^%)cưc{4?kY'%IN&ݵwwL$s?';ӆOyt02">7OdGןAN:WOy9T1x!R \w>$tx'yWV!P5~#Z‚sw= k?:T `VT!<:iѰy9{ ?6GjI̿l^9~6o؉{k1jgqG>9l寯,SR6c'{reCp际1zfAWqW98;zqHx`<4&9b䙟\z/ev1s'|r W^YΎ dje11nb '}o8[罶6=\/O4y %]ojrucեU]F=!^C\82kasS=;mXEZE%Ά+~ri2|O/p=]瞂cY߼/>]z%->`TT?!j@ yuJ,qϿkٶ6xN~1J9k…;Vw8e4yM.=dtMegC/ o1-̜\zyq1oG|PB1pbnXt趫r7]؎ê~m?%g0o]w1}`_>%|N6]H{X4#w^qM}U.++pp.I׹P|^VTÓ-]UZz׻&0y2 UUs' oVdy92ݵiEo?@*uYkGDŽ(qx7plc1 ,; u 860~2khٱ iYd{9fQOB8{qlFf!t nqsɬz)sH7ޒ}ލ7e mV-0%9\|UÎ7B ={H.>r1E;(gf7'${/TJSwQX_ѫ^EE,;tN(@{f7zz3g9394-*]a=ͱ'IiygAsѺ#hpyNNfAsn`(j~*i? +ErO!\裥_,zȱn\WO.䁟ZQj<.k,X0ԩS6m5Z) SHlÁFO^'ŷYs< oR=u׋43'`op5Ym/?p}9y-l olvZ߼,xf)>x{_zgɾLHr΅ r CTrwh*f߾V>uz$/ɬ.' IDAT>аuŋo}'Eƭ,yn<+"һS>W}k93/f!Hjf\˟{ gM) d(22bҫ^&]d="yU:b4kMmG;I A@Qg6癭VwtxxИBCBLVkPf:<0-?ƙ\W:?2ĶɄTVBRAKVW^EJ;XPzkeĪdd=e2<.3RIyXv/c>Td2EElAӬ11bZ}6&CjΙAIAl#a`7ρܷ) "Bsrjn2q<]Qu=<*cNFbHR۽iA>dZb<$!NUP`A?evնD C`0aƢlNZweT j*Sz_ 6VG6歫f5zq LDt+7vY{~g]t8qW/? ז!"׿ncqlޙңb~їSE2êٺ_4  gܰU̙ ̉#y?xڙ z1m`֬ʼ'yaeK?oԬ (½G"_5&Ò妙sׂ9xwL3gN1w-~Iu׵suF\~/=tC{_r]۰sKbs-M-BŸD$&+2N蛦 BAp{7*1۪jĤ M(k0 4# :Bѭ OZ1P]շ[SAAPv>DtA!sO¨QlW^xQY;ԯG 9ty[?`_vYС͛vCμ}|2}:OJ%=Xl4=z`ٻqr;svi3zdNXJ!B@x |rk5xa8^%Y3|8 ,a6 yG^.XnDoIFKVIc !ӟh:||o<{2erV7o^O;J`'̚4{m(2o/^}^~J*ȚԤ2MJ&'!+2#Ȋ蛮:IA@- @&8F+С3mͦM/U NX9J/_&.j<'7 =,KnfO?18r%W=4wͬ͞jbʾIX#M2OD^\\¼)Sxe^]1}p)[.?}V^3N5{ 18rɈhHmU -"vF2Utyw' GRD邐tٲ ^S YI"!AfbĆf7Z+:psz9& Ӯ['mzn& ;6Ro墫# |#;TMZɛO,qL>yaV/j+Ƿdԣu߲v[`K8R!KZ"x`ѓ5sFo۞[M01^g0{V*6Y]JAQS<G~k1 LEaׅ=o']ҰSp; :B^ʪ ]6y.Ոqļ-`3 >* 1` _~}/'F0[|&zuUAnEq'ZvmiVxMɶNL lp)C܀jw߶s؋OJר}2mt$ռU`<J%C]X/CTJDa ""@FQHJ!*A BC%BnE!2`4"Ȣi{vʤ$) e7O}EU'!k{<{qSo1YmJE i/?+;7׮Pg\x ՄL(y!(:z\5e(4:=ǤfdV(sKA@`k 5fsWɹ[D8:BE$$H/(pYۧn&4X"*b,!`*2YmCΊ*Y6k' dN'l zTTl=xƏYZ'[,wF== bmNe]%t8^ZKFf]̙0||gW|줂,'ow~h}RdtWzl6lG-N珀 @qye dΕ|^,տyt+uաƅo+&bEhG췘{[8wngn8D.5g~o"3Ӯh-JwL xqR ^ĖJ-'H2@]Q_c#hhD:|pZa+_8|x!G' qY; H X_0?6r{ɁuڐJEL.yՆ9u59euuuVGE^Um.7ȯ3o-UA@p8*=^/rY+T$ j3` \\DFBT}.Χ/L.>+to;z{{'bΔ) KK{9]ZƢpS%MG,yAV#?[Ӥރﺋw?J>YK&NxS,}IʊX +11QGvX]jk+'$' 0f f3Y'O-㙷ڵW| NE&Sߥ Fy}=:ow:d֣EͭKP蓑Bqq QQ4EFRo2A|d>'u"J8sZ#T*BBkh59mwE5N۝|_g(nXUפ$/Ѩy 06k#@4p#GOOW$¢Sx AupHMZALWf59 LskqS17pW]ҵ7%Q">MGDMeO{W3')ط˟}σ=;5떮.5>FJ$[׽/v;8u݀yZzar:\ `1`uJ['@[PhC>= {ѭs/π n}MJ*kNO;f̀W==@8w^TUUoV5붓%U\ ;`4:"CC̅"Bb"#{=?nDFFlqS2yt-|>8{>oع=>$7K/odx--xnZ'J+ݻYCBy,y_".mjA! Zikl|aP~޳g>5O=EBTRIUW}1W/R +fh;qPdf:{w>^\G?s=v,#o﹧[ojRtuE#1[5NXiˠI,9!Ϙ!I]Vrt ^~!Rx%-v8b8K/K/ڇf ÇwvtfqgU[pU/+>!Hqhp11^.+ӟ}rʐ.]/d^˃7l!C7oFt8ۯ}&M3EFXpl܈bAtWv ͸ND;|ËK .J2D4Qs~ߟQh8s/E4=&/7yW9VQI'=:e&J ɠ9Uod}zzV~Ylen= *^Q!Z GDOE6gUg\fN Jey J+w5wo=&>6IQ=[e^ͯ}.`$/}\9y _ | s?9s>U<ƢELe~S6k&D!陔=j{UU倘[,~t*'NHflɠр(Ex ?_ H䣪 nX13qr9b|<(x-<Ո,+gqV+l\"; DZ\f3%l!rs?BAN7p7f?.BZN;|Wk(n1wZ~EFII I-BJD]ؔofE?;BWW1Yje'(ΑSzDDB!MZf÷*4XRHתf7_Qc̼;";R9l i@n3S=:z$#!:rxAF2s^ Q*.=>!~raEj9L l4HĤ#3=R XR+R+J#C #!,`.B -J!x3EzMN֜Qݒ ȹxLD%E_t#͌  ЊdT&jVC˨69xY 9%& ߼NrNp`/ MG> o=6NU;NEltHeWdWNKs֑Zj_g'Dvnz"` ICh3U[(BZXVm4 X7u6[ЫU>)q3e1 `fJ![8R+r ,7Z+LUU ’ʆkt7聙l@0jQZIn DY.旛,7W4X*+j Uɿ:H3 ׋y(ސ 0י,I>FؿORYvTV]aaRLx] [_'Bywbi˥,I~u%mxD~vuߏIwB|dBBں)f\oNi}{l4L?7 rVۇNO@@?"zvSnJvSǧ$ߊ{tR9oxVxtZ<.BQɳP @ѮҹpZZ'MfZ$D@TEW]mzglHv ]q-TM)`FE}yynGGlÇd}__<(Z)2Tȝvz1;z%Wnbų87޿*^-A6/0Nl7^"/Hrgw<8iXxVBSyș9."lrN]ljD͎ȌQJG.AOKBtyPϮ|v37κU?nb@ ̾w-`HϮ-`DldiQg΋w]y{Ն]̞8<\v\o=68 lXfDO I4>`iPyoZwN>"ש雝"߽sL&byE:r+,}$V7X:lD ݤ=e1M9 R!'+5xq,Jd~1Biñl&*,,D̴\8V^nI>WJK11 ~}=dQQvI  @ݧӋw*,~;?6 ;nb,<{GsT5p#ysaUZR=3R`؟[2:<A a.ġiGy 枴*+-+5%xH㦐H[jNL&%fm0s/;5"ٷzhtd2yڋb uuQacU#55풷tQ^9WDEAfVpsKf$&,ks*4$BYɜ@B"dii(:wAS]#@x (ohP]ݭcc du4mGk>eZm-9eټ(iTui :a4;YIJcOnȯ5|֤tI!8\n~-l?VX:ńu(:hfh>-ƨmRLN RzԳl/56oww&+x#X.#еK'A楙oB}Vۙf⌔ZOJ@}e9Ƕk^Fht,׿)rG_A&̍VQ[T_~g'pai v#LapU:f\W_E39GΞ˯KNrBBGc"zȅVd|D\+"TuӢ'XeoֵkG^;=1p='ǿ}q'[==4Zd<{q39m@" G4'$>F38S-d2E^awONaƽ^]0§#C&1)zt:ɟFiʺ ӡhZ*JYl?t۞ZBX)[-:\.}8㠴9V\¼GrD%"*~3f`xlD!9>7Wf4w‘ 8(o&7TU%VKƞ[B¿M}lxߣٖ(w:!@'$9v[,>ߙHuyFZ.)}\o4=l]nuKXR%>?HNQsCY):48H_dFFU?.b+Ӷdzbd1&{cv"$BfhV#* 8@+&m\g"0ִMB8mVZ-!.>|Ni3Hg+0P$^)Gaϣ4ݚõ?8]ٵ#~Qͼn*^ ⺻APh8uv(/y7DXW&О::ugPՐ/>_%$.`2el2 lF%6QwE!kBB@{ĦKӍR@m8{aҵۂϊ_M'N~w| Ll=yέ.PMITm#`Ǿ]!`ÿ Ӂe{${i\elqTT’#X[rs9G~GiUc 1jnx1ˆX,}qO?)''cXxeJXhdD׏o0pb4' %yz]]cUYYPh6Yms$ }Nqf_r~ZRlF"^p8=lYf_VSay>'zA9$Ai!S zT"iݺ#ZxJd%xLi]6"Ft9*YSUYBJEf䉝G඘qh{଩FDlEK[ p6-H\ΐpJحpo8L1 .#H;̮G!QcMSiOWŖuu'NLOX,l9.=U?nh3/LKHS^˞Z7 -EM¸D1"D_ד n)cafke" K&h1!s!<Ͱ8wnF9|I AQ$`DԴV e6zdH@nDA߅SB}AHo$v,}jA'#tdsoeHnGuvЌxny.i 544(R5&(m u̓d~׌ܬPoUr}h6"7Ilto*0َVVg mK)W+qW]3, NukS+[4i6J*);"B3dD0*K=qLvy:3:^bm0dѡ!}g]?ȴJh!D^о鲡}C}enzڟ|{gIEbW 陦4S|)17䞗?xRbtV`Z+EQ zCBb C~QQoB&&I";vq畕P]ݲ!gy[{&RX`Gk7R5Lu8^6m8XdYΜ0y_xYOHFb,. &⥛o[W0E9qٙ{$OAaeW>4EU5<2w6w/}v)p-mʦWg<~wG 籫0sH"/ĢW90o⩯>qЯ!|Z(sz1;z||cĥepÛ1xDrl^վW@G`IedZvGH_s U:|WnPi$fug\~ۣ~y1-A+$%9C+u[!3 %nFUP/W5Q:6MmJe5䕛U M$A11Љ7=.YܴϫQT/ +w~&))10@lDk佲$ ]`sؘP]}jQSRRVϾ"3+~?;<}^{/$Hޫ (EQl`EP.Mz {|&Mr_̙̙9d4% wg[bdB7AACS IDAT`ttet /W;xڱGnJdT^'*k4:^o }}sņ$ಙ<3jH;Pb| 7;2-`"ZJYֲ/!bڵFBRQ޾EJv6ʫ186(,0Zll%漿5 xY`٨x{wRR[ucbaY^^^{^"*$ןUU%gݥy 2{tT ^s@"+ɎhgllONa3F;WQa|ô Ӛ5 H/o'c"c͎G[{wpϾXm~A(| XO OV=8{x{/eS'b-`/*vIc1:72K1u嗘7+W`/Q~wp},- @(2U@{!zG=Fg̮Z[Τ>)Zܚ@x8o-ڏv4!&"R֘lV@[k5כ|<(2[`k#z=C (47͑Rgi:^M}^44" EQۤR,ށS0h’h ɋV$#D2aYfFYsG'XskyAzSIM5m>wS\_Xs( AŢwkV$A]k!Vx^PmUU}B /W;ܨ\twʘ\4>{%xVǓL'H';ְP h]' B+b#|iN:yXx#jBiy,6_@AZ7񌀴"ҚϷpdu8( Z6#jLp.] @e]jZY@dT[yf&=NcoS]pt: Ec9u}{/G#*$ M?#-2$\5Uީ-' 1(GG+tz\^-J+K0 b#fxp6c ′ 9vK\X\!BIb$U"9' $k57ȪK˧M{&"7zAfp##?/[>wMDKF?a7g Xxs1,pyz=^Ҳ/|9e&֜iA [kAд5'$D^p^ԭN)MS<&->a är5,$ !,s\L5\b ?XۢHW'2kJa@A Hkk/ pEA@=Iz`mП \Q;YlU: Kc,7K =|􅸨`d';w. d=G >N=Ѫc-ʦvv ;JpXZZ1V9y 3m/T(ty"3Ƕ{Ӟך6JTV2& 慻 ܜlF }rՈaֲLSPju(mTd݅2bYRw ekkdBÈvNדlZXi0jE|>W󋲺V; el?E -sX|gH\ '8qGz ?V2ݯ_ 2BI~;?ghڪwws +&bq67ꇭؿ[8ۛBm偁;))h@*5r@˸ 1߼Ƒ 0e3B%e0lelvjD./ЭJai,Rq~]]NH.>Ο|>3Gݼ& $5 =/I|PghwE|.YAQ$j-?(_K+ ejƇBOE M \Pjd`h3 Fiyp9 U`J>X0nc beڎxm4g]o!!bDG'wVK[FI9Ądz@S!(Ny n4x/B_Dä7ptzuNJ'HdҠΤ!8,1X5=zఙV}}`É]6LkA-[ G+LZ-aYf2L`͝2І[R1l>Y+U1Aִ8X[9Ӵf2!g_q9@.&;90nx^o@^a-/T,[_S[/ j&UNvߍ5旈LFAInz7uRJҐnd|Ո0ldUJ>xF@ڇB&Ui]aKwD.] TV¥o**3C9"?L NN"$Tf~11}Hl ~"Me_P"ޫU9-M4}k/1`kC,2+)[[U"'ޯ}?G3 s ;F4I48GrSM/.X45A5 ײ+UG*ւE]~v, GObhTeeC=7$ccxwD9x !Aݱ d`fހ:<(U|ImRFQSZӐs/R=9vq,BHi5R):6@PQ|bjP}:i&jHP4 F޹s-b6֫Ԁ^K;vj4PJ U0W>- D{yw?\&@RM͡K'fXYM&BZCtiiaJ}}ATz$5x\Y1XTC(P}<_K ¤Š1>Ǖ,HqDCRBv;ָ5|t3S)k¬0\o׬. p CS]JAU- :1ذQO ZȊB#ǡ7xÍv( Vdy1M)}cI\Qe ##1`Ai҇h & LN'7 M;䊋qofk'8Ɖirڑ'Z)ygSbX⃸¿[OFŶkXEyErgǞ:.kߊLGe{s3{H^g@vNdiIQQI1itfNv`FJ8q@3 Ȩ)Y~Mu˕4?7G0aO<'4 OG{:r艩]:IO|;NN9rig? \pz_8ʐg[i'Veqb R=We% 4@&"zF  +hJZהܮSeCR eJio'k h'N+"QnDT*}T~ͤc+?ax?C\KҡqzRUm*jB(QCfU5ϫ`]G"oFbi}@ ̡2JHŠb#'B4e2-eJ~|;_oW4d~{Mzc[čX M` 5{w@#LdļPTprk*m4>p.Pj6xB(ZIŁ$= =Y=bw4 X/XۡHfN/w\D Me$xk!8<˺Ͳ+#X>0KRbq0kÏL[廿Y⻺[2Np۰7+!&EaHAŇ)\5` \ZR,#86`[ba۰` Ҽ b+_A^|ꚫ^i"45a 4 YvAvvidPUUxZ3t#jTC}`3&#yy(6p |^ZW>ۂbtxz7W~YNu\h:USzcq=`I u^9oeejBG&F g04S~y rb$JW#xzٌVt Z7v9r~,nNy.$I4Z^͒դ5uÆ?,?x`Hi#2V$@4fZK7o+JEz9=<؍K:hNJRK45RJ֒ #8=únTi1 k}:H`>jQ"?_аUƧ0zTdHo$!``0woPֶ0HĠHa0ouR~>8Bu=" ]=`i5uA.>P$' YR"(܈hȒA+n4Mģy`JIM؝n2度y& Pz`C/W'巓ǙK^ƏOZ bS~,@PG.֠jn?gYpۉٛB,hhCD$uJ @gC(< F H$Ibeȸ|.Կ߱ӣF>v F8c $0\>Yu2[da A |~Hk)Xw$]J/Z ˑ]yhL KLɜ}ӯ&MIP@qUP1D5̧7ׁ1Qyn_(O\بocј<8O/~@ٹvŇ]={v٪U~߽'"FM' +ύ&г_,?$ 2 *5nf**jDpau, MY!9Ts+9W^^Yo!(ւ@~ݓwxPRgQ˻wHrQ8z.6ƾHa"% Ƚ!-5`M>~Hر$˴ 9i:t9Kv^N"QR Fʟ46[գw*2r+UBبs' `>^ja?)j<TeUUUNNrk<.7m U3*b9 0E*U(n| 2NWܬ*oWW?֟ qNˣM3+pP+Ŵ4NJ@Z}3PfU$dn/VbrdEy=7!!n$R1p1WjIpvŷD *@iԠ˱mkغxa}5(P:mi1 z<T*P$}} 4edBq.PCr1U+s+6CT(B4`XF(4. ˕R?7uQ+/ɰ0˼4m@{3$v˔N6 J8Zby3PTm7*t}z.-` C`̼ 8-օybn<|tc4 )gc_)1vlRoVXL$ Net ykX+>`hue ]?v~ڸ=3?] w*1jGHg.Ö_#c1~T,@$o71.>W_|0 ;7/Q1 '>i2Xﺀz۶ G#ִW>CAI >^Cyޑ>/? {F }^#iX@D_w'T7OPdMYuCUVahKDtA&I(l0PRPR'ЦE& ~>QL P^#…,J۟eK?Kkifl\.$+Ϳ]CYq/a8`Vxy@V'Erb+JiiTɡ1>Y;; N'䄠  񬺦F5(Hְ~afZ`К}J`e"%krE?UTbFzp&d87ZXUVxK31$2Y% Bp5KX<>MJݨT{55/UT3; [џXqqaR]]AHt6K$ڃVZ S p?]JvXlIVqr|54ƶJaܻie[Km ˔G+oHek/[ǐûZ4vбFs&(@&x(h`Hak4t B:`R }] h^:(ހ' WF2/^.Gks9S^X]  Ʋ. h8; V|c0:$ `pz%]E "/I[ƈjMBȤm.(ɱ@wxDBm<˜wu3a&"L3A똈8{0M6V#Sz{NXYqHX;b{Ǎn:)St$Fiĵ[?bkkh@g-8 .݇=^a8~6&IACeU._Oֽ0oT;v< IDAT|5>_!>s-qjGhvn^B]jcH!BSK>toN5pOVG:w)8qY#WhVSIӻ̯/q?XfSzkqVmFIm-B==4A} 衑2=b`g/`鳸hkzAr϶9>LO LRE[) N*.V1&dQ=72E1 e Kw6SF3s7+*-n˞ JSOՄh[W A[VG0cE/B͖>d-nK=/\W{Ι.pk"L ǚb & Q(p*OYhs?x-[{ۥ; {iJwwrpf`k פ?*oOͧsbկ|l8wW*5l&Үmƭ{xcz|5Y >X&e&żs }` 3 DɠCշl8pLLTsXDr X,xnjQ26/Gg]"]m-r6HH®WbؿgL%Fk03''~};W_? (,`mšS% =%!Ú=.fL1ctoscb T?o'[ּI8n֦ A`Od_@k P/tS:Qsf'%`wMj% RP>ݼ{(+:*ĄG/n1,Ϩ3* z*3mYEeB$"lX_u3~ep }bMmjbfUABx[sv4Z2ii-{/KrsjF(Ą¡CԐa"&ڇjqۊouA<# \(t`-"syFUՉĢeCCC,[Wǵ0p -rHzE1j*.[S+%^t-dPp Vrxכhҵ/6cﶷZTRIɇ%YY?oUS~ R/ =,/`ua/bhTv~Gpp4l0>o@0\IIǬ7L(̇{7w<EyL^ToȔJl9v9esk5[tzl)jB\;ZYD:LWI b L: t.ӆQ6&o5!k7S`NBt(ҋ8kmBP?0#dt&qqE׉3!rxaoammh%MK3A6 y ]7s4z;ږo*)q2ѣGo>;H 1uB?L2\B7:s|\pVL:/ř hu pvb"grKg/K-'\)PcJLSv8+n=anm*miL*RYޢnnR3<lBTzmBӡg@U[`Dvv6wܹ>ykʊ'D6khDYx~nG{B PU+Y]sLqV&s &(_FB? PXVg8x$ZORmXABEs[4.BFAaIrMM vݩMN, X\yZ-_ZRT_\`jedF1l2U_\dW6TKjiG6#<^gp rSKUGd7{BQ|1~H0ƴ$xBK4ɪ%r%GQ^iz2|u: $hUgh#(\[5qs `h($jL.iHzP, jOL@ r:ldԊT`Xn|u,<|0vB^MK0YI47.1". HttzZb\\o\JJ\NN pNҰWyzp ``(Ҹ -XjX^DRηݔ*ClHSt\-'yR@jd,0lD 2b^Ov]!:j yz>e8^AaKQ !Db4+zj H1}k>KH<C{D4f2߿׽? =ƋF>Z~h70s@ܺ25"0XByK7`@8*KNLF 텃'cAv'|hrBYr UA ק,tԐ~ݱxuPYѢn8̜KABw6}͘>y>ZG6-da$D$۷ow_n]|(> @y@#]2FjiAs<|7'2]րe5IYc$AN?5h( ccy7h&y:K FgJۧJd(ޜ1 t.a9@'IDQBp91[r͖~->"lߊ\fiaHfNͪo٧<-m{?[O/A-}ǚ# ӡ"#pi IUv^#xq/yi||FVWGX21-)=zNJB|甲z֒=xsf:IiӢyӦEJ-RR .'I k;ݼ:كN]<}؍K 0`>}zg^Y ^Kszhժ)!+C/fӞ=S>ٳd@QH}rX,0g^vvlvJ\̪N*.ɨ]2ݶ}jaEuE?JqfC؉O=/GeE #=7=ndGvNAa  `;T;븚1~N_~`LE֍Xw(6o| +>Eݺɍ?ABJkP$1f34;mB+ń|DB("U#^ UE^@/3H(NqOqꗦ`=>PP6S _/]í)/exľ=~MC[:3 dՉ* -Ɲ?6Ui׾ $ABEapj2Vt;&'+Adh+@w }!0s>76i/\j|xuPV! ud~+Bp(JHWm,'v~i%b`يGdoo\}}=|RNS :|vveg^ht}F_!(C]Maq (WO f+jzrtnVF" hz$k^O֑.̷qsnַm Hϫ0,/rƸ 7IDO﹗?M<Sm<{äX*({[zBPש%t^hLoe}q%rSKS+ 1.6M~$e:dl3{Xv`'H:Bu\Q 25%oV{{׍/?g1 =OW\{ݯ|pHK̥?pw{ӬwjG^sEYINvc΢N0W,w[ہ=<=hJŝ+99y56h/ö$Vhp RFyVv䃢aT`pws7'>#0b2(/ۄ/DžդQoX T-̂1W@QaI^ߴ 7] C0`/LG߰P\LNן7f*'`g۸kMщݼDr˚=rA&B6!CG΃R<(i(=_-\&6Ma}xwDz@R_gX6$m!c'g95k݂mMQDxX8%.'&I8UC#-5AAҘAE={1@5AT0y_)0(J@cY;$VuN@/6[d i D @`AƩaB+jOc*:x?~ w}HS^(@JH(ATǚ}9Kw_)Id n*s\..?MZnqF?U'kngpAW^۔";F{d\ W),c8V@H7+/_QJɡ1#{tZyCH@^qYNaFC:86Jp7Sy%1K]SHY1YS/Jn od[/`/ACzt:r9ΝV֗R45?rle.GΕ5*X9qic!;i#ɹ&N/d2gNęеZ=RS z[qvQRd7Njfyy/<34y ==?7bkɅލ 588L9}nnzwH칔=wICÆ}ı4izJ̐0wyaBNK`Zíܼ̚omͦ쾙a8gcnkx 3:GGڐlIoK3ahBS+rߜ~oKlmm](V\S?j <F҇֊[ui!|+o9 ECT`pePi:Iޠs@TJ@Pdt5vЋ:|A1Y$״ T&=EoJ:1@~7=sRQ>ضv!9[ `VI2DzL|7t:+ǭ}2w} IfCΓ_m̭a;sy>5*4D|~LsfQps% zkw)$C-Hڐ,4\r5~۹1%qC}>vhe< qg1`"1b |TcHG3( dCq0L5kć.D "̆RV ]d 1 8&9"uV J+2.,~ ր:YHj>au%/>'lH;kIZ[?T\V lk#b\ lDBIks%QQxZZ[Gt=3jB$Hn%a;jXe5m}==l< e Nhp[?l1? <}Л!>>6B^]O/|uzdI_Uh4x}ԇglP"9pfǁdDxzik?( xxX lcIIyUUUUKa'o9 Qdâ#5g>Jj,]f3gJ:fوFc"ĆVf6~UՈ ¶%0GOAURP?|kpwi& +>Ł߇NNsndu IDATArẹQz#MLDtLj3݊$[2&!M) XQs^| L|+;Ly1 (@z2d=つ,C!a7/l^5p zXB=2t.ҢB ̀pl@MEj9@t:`3Z ^dD.*Y޵>ٔ!#]d'p6$IRzG'8&fED nhYIk:Gk2ҁ&3~ M I0"hKq)(iZ0 H2I4OEEc」ge5ncl\6͘bJBzp!@B tBH!B{ w{ݖlIV,[ng--9sfh$֔WzMdhe \KsC <:(w@74I1y04IcFK-컃221)C d{&mΚ<rXn:[X=A&3-8xb.yg3rRL_oO{h7x{Q_APia7.A hd|El[bn&aG!5ptZ}i]0?ˎl>Y9U JՑrv^nMݒ9EbKʜjA3N yY%UR\U((7DQPuPP[:t8~/d`>Gh#Xܛ5wo%{_V;Rȑ{Q}DB\K&zخ׻h->̍zV]@ 3u6gΜ^ܠ@fۍymӧS>9T^Ev:$&&劣׮Kk5&롓KߨimV9Vn^̋בcA!,VgJKRsĒ?ʤҳ0l ~n[gB MNpZ<1A%?tց[A8@B~)I(T4@:8LiD;'Ƹ{G>2)j{ z#_mQ {1ljͳ hd?\k0RԜHOlqҕ}- *% ~A& < pҿ,K 8 rK Şյ&0SL5( .3?Ch8ܻob1 Kj'$!; i;7ϫkkkm۶d_3ExǢ0w7zRӯZXDF[Ӳ֔,j>?yN-W#=aދyd_[x hf$Vv0 tZb 01xZ= ]}Ð_U?!3 wMK @c PT&C1kQ;H-7Y?hL3S1fFgAd0̟*xz`Kغsv4R)xBS.qͬ"VII)79),zv.bs[ZG$3I|1I!2qjAJAЇDŽ f?-UZӋt7ss󪮦PװAtʡ=&`YHKK}2#XW]NcxE+ãuw:W_Oޞ}%camBCo_^+'+ JUZ HI̘qo'&~R z Ϡpx~Ԯh{-&|6sR$pPPVZNvMjyEQU"%E}sEq:{upJXhȮ";&cEyc}̧0YS9@ dEoxud4W) @)Y^ d"`JKY7A*0p ǸTZHԕ2Z-{xnlœj1T)TiLi m(`)G/S )x+8`ؤis;p_u ?2.X:]DO{ ;G{@+!7v=8c Y |Zq1އ^c -$1:e䉅xmꇸ}I05(H&TCbp|+pASD Odg%/pnk] x h DzV9E6Pbf!<|N[*Zǐ!vdᰀS[@I:UTh a<6g.% QT*0H] 2},_0wͻ8{)?nXS`{PXR C@Jo6:t@٥BGt\?)<Tz[ K]9xYE1=&ԑkWrz&Ŝ_i?R7[#CU'C]V"Aiz2 zEu\g\l@adMވ;IgJ*0?O7u`y%I-/+%K79>>];u1#4/|po0A(ssgϙ;<;;KvrGזIwW_oq˫kYv8o.i<5~wl^5XD7}no2pMzq[@R7 VO }^{c#cG cG}Sm@EUpchIq쏨.oX8fXC^#&EvUv ~>_O_BuE9yZ 6/a` 8sSD(ι1}&|KR@akNit2r<:V*/yEVAx>;8yDST({;k 6м-êz%aٓ5Sm5ShdfC׹bͧZ=iZ4@+3SW7T+r93; xŁ9~DoCUt hLNG_!q9p9 㵙_`ㇳ9h Ga%8u{> :>j3) Ƹ18~nϼ0$i 3?-!Ql-V4[P\6iK'm(;)K3Jdbٵb|N8w?(d]Eo/Nj0ۣ8HrzԳcyϩ@IJϿ#|}~)LD 姪e>͜Ӽ܄ή#+%fb0n?`6ˠ|(dUW.edWTHk.ks4#EGNu bt~=2Jrz'zKK/Q^y#lR?>Dh+|[">d$ay g]g=:a݀pJ.[0 wT#ov~FjۮrchCk笎ֲun7F5bC.C_;saj9*ݛ ]Ď3Ae B(G`llFMZvcڿ~iǯQ1ca6@~]^!{+zxu 0Yvci*`pLZ\> W",OF Q^:YB jkI-sEx:7 X X04.CQX"F|f=>ظ8ƍˉ6?nLێդkZ>1;v4 D㠝9=0{Ir&M tD3'GARf$>B|ɩ*+#-aA?^VmjQE Z-puz$A3OD07+;e6s%C;uzZbn0wA4a#"8&WhV"F ̙ܛNc'N̝:E=^a^.Їtz=t+@oZoWqZzӾFH6 R0nOf10G0{P@_zb__ȼt:DF.KMrd w٩Gzt5a\aB{I믐)4JɉKKyuŕ>mvvŴaBM&@cU:eɄ[yy9܂Z2iClN.QEv c4YHtrjNvn݂JYJu}Ǻ;8< I/p`NjLgw;tx#`Ri ^ OH fælsً]%=L=*n0Mf0|nA_ڊ j@Q$&`6sj;sUk1mqN,t XNy b_$p~N]@0,IX{aR2}9˫`TTPCuԙxH6*/#<! k D&ػXDzIJl;&湉=u=iIoE3xʥ#1"AǾjGǥGcL\B_5 ,;,Vo6eoGg .Xlp:ج= Q$)ϯqٕRY69UUr]c߿;=0hjЀ3~U%~:'2:F0ӥ"$Q0xlYy]Ekzwa9q9qPTaほ.b*lv錸r%[t~]u6zPnD.QFpG5LZL?gl;N012.;2.kkܢjҎa2%^g@aEm˼[ͪ(45\OwEG==wL1Mz?̢"ʼnKb[cG3{ǾDQT$ED*Ź%R٣Ԫ__>]FE fĭ<Ĥ̪xt^ܞ߆xgM9MկK;{svdC!,m%sD6/nthXnAiޟ6hWZ mޒb-׊1(s b.;sE|d[+r@@cY*)?EQtƜ~K,B1=ѯ"h=. T% '~$sg<9z~`Wwؖz ?esD Icɻ`6k `:s ^4EC[A.l=B͠!Be&  ԞAS KiDʄf0h4Dس¥CiҔ$4$<=gQq{?awI|Y IYV'_|t.DeS>iZfgw;.> ʨ%B3/& ;\`‡&T.k3ܿW 'emʙZV,GHG$8w@ZÅaM*2;*YVjvvmNgi+iLl&(xcuQq-É\W'[7*̵T"F!5*vNzqw@QBoؤ!CNy4tw'-Y:p-S=?LV0$+ SR JK s 9bs >(<,*֟LN.H,+MJ.)&Q ,"k#y;a (NLPG}GV8_fK"]F( >p{/Z*]g#'l6r{$ 3T IDAT0{-0Րb֙AQS;* 3g[G6Т6hQߞ eF7 8&g0'Yl'zD;nJ1Z[Cle=m|h@8]]Mp zO>px-=;Uw&:R6@4;q}FH ГFtG79PeȄkrX';=<9 +B9:(Ȏceq`d4$0#pA.:L[6](ù?^ajh@h ]C8w~{ׁ<㇃jq8sz6l4:to~,uF3NfWd{r$h<58doTT>әL<:O&vˎXG* 'FqM PTb|P) ͝j'C+5{B𕸰䁣ԙUdW'֊쟶@Ϳ_D彔~R^ȳ;{耖+_t:hL,__Dg4ZvqunnxOT@'uCݢ]]m9e&Oə"_XVǥfcX9*(Oaܟ_p&Վ}fOz\Ɗ*s bAM m-Q!dq=ntr~;RO+eLRa1ʙΘ|;[,cԐ ^$@dE@RHye}" iN" q4@Mz$YbZfC Ͷi$ichYaQ:92'+BeMXW̅ #W!>OB6~ڲ߲QC_\\ yoõc'f;\:wyFhV/Bf)8$*7ݲܓg.3?h:NY4Zs3\M;_% >"DnGpy\f\npPX h |@ z `ɀ. ) ;^@A YdFkFj˲- *2 @:h\֏fkmr>bN-AMrԫl,qϋ+(™-p__K X6?)p ?@ʥ38[*xgh' @ţNZuv(ݦۍ*g7|swРW]x4|o?>Bstb7 %&lf>|n{'!~!;?y]L8\ ioAvqC4o"#n"G # Qh '<3_9j~j;'g7N1E0t J0\&9 ҃ƴ!( X0T,:uwp ԜteCuf0Ž`cƄ( :5daA Lz{ބc)U2+22u7Ow7?n۶Ӓ*Jq:%qiizNUĊ/ ru6%-Ƞ8-clU.dRrԴUU^L8f<>N?u#rŖ.bN;7bQJV)#Q7;ڛx嫙( _\1gL|:lݼhNjB([$ۓeA":B7:l ݁7Z<@M@n&:9 1R 3֞APQC"&~ L=T$PHӾ Bڂum6 kqllei2ē<酯n#B]'/`a%U/aygg|u/R\4%:FD"ǹC| @p-=]V~!ˆ#'Ot_h+۶8pڙ10bHCfQ=G(Q'5eocWAix4\OϟG?@iCAV)< d7 rYqh`syJ8NL{Zn1t1GYJ M) j~}uٜ5 ys|\I l6 o˼ez4@5DBokNȵ k؍C`lǕ,o$;cDBnuu9$Up[0w-s!-wo CjjX{cxU1d">pCcx|s': wP*!l_Q]n_-vG/X@dsf,E%<\+AлO,2HUY:=A % <&_Al?ƐyiւbˉQ HA$g~2v^Ro+c{!?iQ<_YXp& cq]m] (dnP\%%> m<>_;j)n_#z5xNtZtmi8v k vtacY 'x6o1nҎ5"Z,Y[;۹Joz(hԙj\I 4w%&JxӃ={=sV58)ComW~;u^]wR?>Q]-ͩS,~!`xx tuFnOVS))5ғJ.' @RM;w!-F ?ѐZͅ{{H VZixGkL&]s^1];o:_qt)ϓCAYɝ}r‚M~y7P{^omdfaBa@ض (i B@"BMf|-XV? N IdoA!s゚4-Dt|}7 ;on({6OŗۋqF [sqf\>pwL-M*܅ԋ(O1g!`PT`? P^CװMO;Fjo@IH`B8 ~%@\6k kHGcö˼@:*rhRlg .#MW/_Zp mـ RHAcGj3P|F"u y7g͛oL0adt4Iqٻ/K1j^S-ǃx/"ħᇊ1~׾¶e@Ap`4^[Ɍi?΅$3ut1xZ 7̧2CяAPz@ r0⃍x5 [>|۴?0Mȼ_M¤`(oI{iӰލ-dX_MA IK ۶6t 4rXxwכ{|V!tH=Z+n̽uVxQ>؟쌤'4fn4f5s {Se"bD oG }o9U晛İ^fs8͇v3;7gv,z8y `={W6? 3mR@O:@pBam}DrQQNϘe縙_\P#J))AFu?,,1:FJɤ՜쬜jͻ_c> U&f& &/4Unh*&Uһ`3L^NɃYH׍I`ٽWS٣ W'qgiOz>o=Be;}L0$z LPJqK `'mFP Fْ n{Y"sby)*4S?x܍C+:FW^zn9, "ΰ|K0kN9<<8|qݪEc0vD/\*O~JZ>}pfwKz4]Om߶i7yӯV&UI49_s> ˗;?!bFNum-٥(z>{KSj2A[}̗(B|kkO2ڔaysb[;8aΜX948q"nf:EV,irD5/PԶKKyN)40j: SN֗dΤv ;7srqN.d_iiyis:~s}]:I` @4dx#׬$_}#_FBI:=e8ϫ啕n>( s[l(+B[[A@nL^_oIKŽ*k7T1|'|h$uzH^œ=@lu'Y4[߮$Xm(jzPsnM}j"''jnU 8k՟ͯ;Xa(jNVN.MykWN7WZX+Y&t:+? P)k2|3joqR%bVH`[?݋ѣ'}'?|'sbʌpY>'Ξb;캢|8 hx=)_AMljMc og-/%褁4P4& |& q<*TcvNlIlQAjgsqaǠ _^'+3@/1@jvU0ۋ2F@oI@|%. Gm4۞APV__Ϻw«UUU`Z j1?pptA3bse%`|.}oNUM I@9%l ]cQU pc:4;`"Շk И=Ҽ _mn-Jrg0tܾo4h27 7G`A5|wdgd#x[N+r;`cps?.{> 6Jt쇄̏]3:LS%7y7el?CxWz6WJ<ި5ŧv66RJ^\ E%5ra'`G&ݐ \< P_8 ЉP]8 QЦ=`v&h߲ !@HC@IÍnPl2`qt5ӾolVp)F w}ӳ3i,9ҿ 6m;3^Ŭ?>2t?q1mmG꟭e[İUJvձ91?ۑd-+--7AXh&A`HHWX0k)iUҟJeȃR%(f?˻~mkPȸCFb ( Po/5c8CM-Br>]UQ{e IRP6"v^݁g 2Gg/"ZDc~""I4< {KyN Ўli׹m jk}X-9kjH$b tqo/x]].\зȩ?V=3** GSʳ~)ɮeB"ϰ8DLYɵwӌ ƤS46F.$L:drtuu7wQToپٖ{!@ $P(U)""E@A]@AziI6wcS6vΗ眜yν3-䪟+Oe$Q0e^eEwۙ҅G86lKaxy} |%Vk͉#q}wWgJ-h/ʾZ2Ku[]zGk;;eL l 3Ī'[ Ok!|H%PH%֣HB.K)T yz4L@w*s؉1BO0 á ~ޖSrdg@ʲ,GIc 8?nh.PVփ/da1]-V@)/[OdA}qw膌) 0` @k+tW_>9kz2Pw niZhė{:~5?\j\dm!1iVl^2ޡ&|2=B0SV/Gh~2a ~=UCo 3LF|y)c!y5-VYj3|mh`wû_iGL"JD mi*@e943Jt-k}wq=]?eʔK,yC6a}.⫅aɷq+fx{Q;%Td q;puGKG{F K=ߨltf%f.{Ϗ-ά@> v OKGå-75@vtOhEX}/xf\,< <LD@/Ƃ 0qnSmӚ/nngw//{c!qirydrU_* }!!i$#>{{lN&JEiIHZ Wdr~Kk2;Sxoazv*?2??(r܀ple>̼5cGJV[ ii;*v>u=6|^ltƆNN-;XV@_m6A9EEssnrIE?_JK[A^yx̔=*%~tޝr²hN H./a.% jj@ '"ϰITGغL3h& 76ZZa kONIлVVkA_iHc;|*Q\}c_gJLH";#MÛOHy!X9&DS%7=W0&hZWZɯ+ȵ4 ?E r."X#q`Δ`Ͳwʴ,^ؘ`w[M$$1+lصx.\q an&!L֨$ʤk KxvN Bt P|`#Mpg1iK|&Q/^d;o?nܸwo!.${߂ǤO@^dޅ_'O`$9C>[բ'Wq8aܽX\@}Tk~ L:B: đy7tN G P~G|;cl7>_mH:` hJ3HN9sl -?7̠|ӗǠ pV4>r\,5OK"bZs-~{Y$6jC}m NֽE@`+uZ`0@8R(M˨>Avvv(y9^wN6,x9ܶ5hpI">y]*pKxaIciKѤI(:.喞[lqqӪR%,T'd߅25 ͙%o4B,EF": 4?+ᣧ O,Pac0lr y-yG g{ ^(\uv *-`O%>".%> 43k`X)R`0R{^nr~OQtd`H\Ai~BgJ~ !i&-u?VG׿ 'Е'е[Lسwo?y^PBmYN.+L/'|q?yUƍ'B[%P IFN"6#do"ʤחfHijg%h#m\~Z\W} _//['gwKZ"~ZTweEqP埪?ǞlKZjF̩#9ACge|<,#rF5nB9?ޑ<'U`Pꑸܧ1zKWRlLTD >ɟ.)TlNW/$B:W(Y*ySGnI8%ILx w߀o9e/ }I~C9Ա9#!E!CU.>[@  86sWa+gⅺM&V$[\WgKT~gg̘! :rpZ4D=}#1u~@ρp`ۻ8wt|0m!1{ mxAa)wGɂOŁXTg 0{`|8r I+AX2f-[¤ŕa6{PsvkZERB (X*ey-WLYt]94bhbY@[O{qN|~=bZԔRc$ޜM]՞+;jFB #buF -x? OF$T>hC>t QQg`P |P 8! ȁ37{Gb=80g..?BAd{_n"RZp!ZjkOSgk*娗Y]CO#= Z6:U>_u7h v8~XꭈBX*~Vg"GCzk_T޻'+;K4ugHrν73GG,v|^2ߝ[=&f{,n6o~N3yeꬳEƑ; X|/(W: EQwzhy/$JH\nWuıq8Q:# /!m+B VZq{vTK{0ngtdbZHXcR)a<gXv g-J&N3bwFq+U[I@N}qoIgW݁q\1\{ *Q`BIQ.tF&wOB\U|*JsQZQK1v4oG̐I NA".jɾIGm}V7ǒ 5\iV|ݫǣ]Ǿw]NB:s =4|MǻvA]{bBxB:g96LrW(H8r Wnn;QHtz58qQGv#zDU*g }J3O"VZ l"{#@SU (2V$C/o"# mm9NNQz<;AWvs7Ó &JgFĦ H&A  47SϠ#r~L !iHB܁-|DPPB 8/Q,D'&+q\r>ټcӇ}i>y>hmFPwΪF2Li¹;K>qCG;l|&GmʩM՛z/φ^~Xn 4A#1hlG^Esg'%7U׫Rqa.M&Fx@w{o#ӆ'h# Z4Nh`AJIᯯ\XRdeWUy!_ߏPieeپn2 ˋsj^7ކl;|f!BRl0$h ,&Ac0)H@# ǥ<͎EP ^=Qr.b[ª{ /u$ZLɟ\n@^,0qzb޼,BN --=ג=>ѽ meͧn[ &tm¾Ƅ{S<>>~[@2精9jH$LY*D)z6V#oNJhD+%F'-XC0-W*| i~No֦W\~.UOloOzdlKK2Sh>oU^.4?l/0̅3=3USA=6}Lf~Qr,',@A%Uf!;H/ dz*|;O΁#eb#F +Z}Gx6E/,FSV8N'4\gѡ|Ĭ?cﺷ 쯑xc?¨S?p3!/قG{Pf帍ÓO;g2|Z52\$Pf <ߞ~9_GdQ.$%xp>:~w 7!zD^T:yY9t ^GxߡO@4JxrmZr`vv.bVέҳ66|% >1?&+oq8y}sgʊSL$&c_Q~s4Ɩ'Xy64;tdq9h06i DLG#dp"CLBj &p>otj9d3i@x@&@P d&0#Uy7)[xM2^{m܉Y1lˤ9O}!0W iתM*+E+4_Wb;k' No25xԢ əԲ=WUbfEa8hG7$݆?67Ť!CV۰[EGM}d|1b(G ۲8/K5m3bgHLoY#rbkdUZ[YSelZm@;sTФx:ۚ{Gҳ?dBx$IʟRi,۞ZVm>.2^iDs#?nPi'+z9>}XZ}7Oډ\ *KjxMfePEA3Kix /[;mZޠw 7~ oBs8Dlx :#Cy1,Z3 Z4M5T&3'ݹW@m?:iN]SB6EG:08Qhُ؍U:'q\qIFsխ'NcE$X~c/ ,Y R\KFN:Yylׁr{x8`χ/D mƴR ذVkڛ)^TQtl\M1$FA|542P׉qTiL3 (M qf9ΉEC`|l$- { z-';/kXUtS]]kh`VˉF\v'~.܄w݇#Kgf_ĕSU+ ӫY!{FwP;?$dmz"2.g/X1 Äc/Wa,=<]鎠*0UZZAczA Ep]UIL|/oRZ{cz<77E_].xaƩgGXx&]r"OK%zv`ՓMXY)aړ'EzU s IDAT/}ABgR@Pb@_ lˀp @p' (id|Pz $S(T."\I#_w{GYH~p:xTf>zlIF0$LmOÝ:3t$T& z G",7PCO/=G,+Ҫr菓Cj;tn,`窅&ЙַNPԈA(LJ ^4M{z7 [#9߾N.\f2h̶XUjobUoޕr6'e6ѧƃ#0/޿!W@Zn6 ޸z FLu JS` 2T!?Hб|Vl; eokERapGA-Q]jNlxԈEɾ|ܑ/߈lV)f|w9F3f-qz&+ԏKk~4P?^GzcI.gUխͪ!uG*GaYuu^@{q])&V*Z#o\`ENa_:G*j!Σә,hٗPK+B@$SW3zn#ebP|*E'ȞJHY*5%=+-sԦHJKU;3]ܜkGJHl5-5nn]eo^|_3wa&wf;td2Q*LRuc0;]]͵I~ӂXZV? رĦ\)&E{ U'\$7.rsS@ %)P4,s}-7[SH8:y As 9KT} @ l}2^) b*Q/d6I#*s3X2S%;#Dqs`b"5צsN4 е'?HVgו8]Vn"F/sfCWG.ltvjr*BZm;٪/G3>ӮvXY)Qŧ_\PaR9ڙПD~Mgw܂lpcs t f?+]O8>=D)|gOG$3?rٯVww*%W19t~Dg1c6[o}E,dQG̈́ e1[;Gۇ'Q?%?]'Ɏ+x65jv1oz\GsTu&(( aya为t\P,qQ7j =~]E.\+XԋUROX^@jM8?GV"?Qh06}^k.p1 O%r^5#`;rw4SQq.w hl T6EȵeMP-o_ `ڿvwP`Bw-\ID\fx pJ, `? ʴ[HL `4Y 86 i{HՌjv]Ql(LJEPkюk `@ њ|@0 &omU]>V;>E^ =؁27l=ի Woz-{ ۹ugl"7)!)-ٚߚN͏ajt" nP 0_O$@Y!7읋# 웃w{AoAÁ_61dB,o:coI1lm&vB x"~41/.3Pn՝̯T7v0elǥ4K0wtiq O[1A|h~+ǫZ o9^х5ц?@X?sPlL ;DrF K!)ԲmA(\{"UL{s|Jgbu1t6C'&OC6~ P BbbtS'ڒEA1ǫ9eEZX\]?S"; ^7>2Sx0@= ]f^uq`}˨5WR(ԃ}fr]) &"ˊD6yK2#@J iʄeIJT tМAi5 a| BR3?OSΖ֋KK,q#v`ͳ+dK݊|%載X4.S/ ?iVC˼]b+OެRjk봬P{_@p],ƈ: ׺Q@عrnPxc碪4.0ܔ8TW3}b4s <ep ǘk>bY0K{qN|'ZEiiCZo ujCi))T ݼMEn܂̕j{B>Fc@k>p ChA^婙[Y-*f{sjM>^rj}\$ԆEvłIoRf @]v R/gn=rDҍF=^a8hA/RJq&$,_o?AT0<]!`6SHMxU} (3pN6שo3\}_|gyͧOLpמK#_j7q5{OUIƴo N>2* q%^~XQ?QTrIJ3ֶ@ ;+7h4ӆ6S6CaXIi!#l6&CFA /Q_f=}hl,_Y],+_7Opa>vG

OLLVZU}P/;DPv=MǎnJ/sH1U`F )sQN˟%'ٻd) E ZK|H7O30d ^k$(E3 ,j zhgh.B'XƁ7`׊aRe2At;v Nd,@#3#Ss͙eu צX`.lA$aqz% +kms&yDPVh-){2a _A!8c0)BE$GXFQ2Mևy ]=C_Oӱd|,<:8'׿~.B;3Zܭ]N=!76lx_@Y~ ^܍7ZS[PUQLW$?_ Lǧ4+2`3mR#pڥe@wE,U4יŧnA[^eU$::8iu ;^^E^U=^e=%wʨ g)YjexQ\[O1ӭԭrS_2K_4dAA4Nt&: ?b  Э [ZѹgH_?7ꊒt:>P_ꟙ,8͞1ھd_'>V~a.O+r<,8[a;útscu‰OeuyZ[®YOqN]C"@ #dNqA_dT,=6U b6CS`Pl4Ij)iN)k !Q 7AV*fKإ#Uwg.Efuꍔu2:D"*"D|6(3BGp.+pZZV7)Ƒ$ŽMf<萌i 8H`' (3r,OQ_fzF'PH}!MeP'ӰOlDBo@ׁȯۼ9s?ESIBw$ ·-鮟]$)09f}E߹́>\G ƴ@`Gtšu ?^M^ΥZy4fB-hzf0CB0 g `: Dބ>p0iù(1mл8Smz4EJӀ<XgɡQɠVկc:"{EVR<¢:9V6T@oZ*ߕ jlnߑ6WDYϴ$"ʩzC8X_񘴿zQa:nJ{Iul~}ڗF~e+!? 9_ujR2#c:kEDd=/Ddl0@\G vk11e9=5Z{jw7JKcxY ;O\I/5s 5L~My)KL<~nl e31uD\7JU5; qT?Tz#T? uO QIx6r885HR*'|І?@iC9 Qrb :E/+NӺw*O=\Ӊ=y{]؂Ô=ވbܷCUr)Olچۣ6IvNBpy#o3^,YTq|BAcmք'rIܘ/]{ v(>xqQ+kMܼA8 2!?嵖wS20e`X>aO ?H|ǿ:vrVBZAzoMh(5l?+ʉ}ܧ_ mS7 {hԃFg͖R`v]>DO4*\sӸQ}'ʱM9 ɸqz[x,dU$_K v&1ÀS邔C(2ltYqt~ˋ7rlzM^e5HKc*Wh{{qrR&6Eu]\P >>ߣAX`̉CYcaMdžNƪ]N.BHo6㄀0O E Lz g+x\geⰦ-A&tu.JS|< ?Nx什jje9ϰJscd `A"qZvӓ_ωygŒV&V7`{Yo0Ɇ2=V)ׅ?\pƳaӊ(UTYw І6҆6s):N#Ы_<ѻviS_!9DG'",gAQWpaR)<9HXYm;'^̉ژj#v|!hh[&uhi۩Jo=qhϋEE'ϱg*ݗ*t5Ƈj5> =9 .=}7[`g 1M3yJp졅UU?f}~p:n);}t g~UX.Cn%NmH?s?CT '@(Š(3 0Wm7PT`x}J8+"x݄$ā3}B/AyWbBG]4ћEi;+?6is)U!j2W ;v엔ɹ^i7ݯbzLJKHqa(ҩBv68૦6ZȠi h^fָ"?l3YQ?Ό nD"V"UP/uߔ.[@zJW<Ϩd9{=yJ=VUh+g ,j/ V),י>8{Ong6ҷe3hsEf', 9O`5).D&jWS FRZ iu ݿLD>|^"G2U2EJpH;@U4x}SW4Ec4 ݠ0o0 TaX,Bpd4;uXܹy@@21o৭-]"z IG ͦ7"NE~a&xycXmoنZw+ vˆUkEsLWa/?~&_s8(-!}t^\@\1nPG@~lֹLG? 5&pCgT ~`C-dC4CwtF52Alk!{%ϼ"_nJQh r/ծ/AoaC'wB] ZEuAdځ q`J?QDnKMg3Ǡ >us2 ܓ0E)?Y%r,pl/-0zi IDAT%R˩]Cmɰ|߈erW:z1¼"&?LOʯYR]6F@ІGͩC dFy-MY܌CkD7uSt6VU棹5u,lN0/|ɪS+B>(JMmX, gQ)vΨ9nqEPNLwN׼@2x)46t_!H hB5P/KLe#eCy=]h& 2Tqb|O!EYܐ&=, SkDy"sN tzyPG:x @O 0H-,{_G;7t<Шâ00w00 _+eHSSuy ʧN4 l'C.C{ܢEXkݪ^:@ 6kԭ;D XmȦON+NPcx\3|%[RaTjPxn#rla,ݰJ3@> #*.:]SFFAcEE]xZaUUӂ΢ EFbanLh7foB'Wer0%?0^`vuI:"Y5qcգkc|XG'Hl&X!{;R-#&eYTTޡyy lmΖY-W*޾-&[/EBq-!0(K623q6YlbMN*{eڱ,(ʌ)Ki}wI:}T 4; fU?4:؇=iH4qFnDAbfnO#}ƆkCNx@"ѸθaBL%4̈^Ag.HKTo?J3\N\M/u ]^<354el.莽[vcl\z~s &|Q`Cs!Z "|&YTWnZuN' Ps"!)7 @bLPUU!rpp4Rw~#&:;8gUY~h)jsٲ@5+kJDFb5Q7%A)rbJ@%Zw1vѴ0۹yki*j+  (L;~xD9[b!0SPY X={s휽|)*̶<ܔPYrf ]Vpa}m/!H淖 /""hլ NxWѬFV\."(4{ZEMtDO@:Y_:w$wTrn樆){2+d;˸?p_c :Džsf>-7|tT>}#޶KOlG^ψ*"z{o]O~SkaeCnІ \K+%($OBa R#X&sS&dq M& ]zV(Ĥ*ݚUiQ!NtLJG3j=Blge8pMcecH&V)KD-=$D<ՓS 6);2`1gȺTLZиuT7Ä9/pQjtHw!>W@dO "D(s@Y0x^/.bI c(ޙ-`;w_¬N4Mtz8~r|);z츘FϘN]u~,)-kǡNZ̛X\,SjH2G24ZcY׼`:yqRDc@= l?|z@.v4 ]+%VW#$GfNkAY:`7< {})wsEc7<սOPέ@c `b=̓%P$\U<b[DMՎSHle\#>P*M)+Gv[*M'Bmm7 /,}h5ʼ[nB%OnVh,eN6k9Mh9$IX4}R,;'fƝY-b_ +/2gGM￸wL QSoZe'0hf+$`2Q8tzb6ل~`/g\o؟7䧯$? ,`㭌.w1tv}٠܄ߗdTݑEAY?. `*-I$!c ݙ J}8|9qbzޅEHΉ6҆6 E~;L\tTQIr"]T]DeD~~"PDIM'3 )uXuaISiGlo*8n;UU_{xA\Y~1iE]$DAȖso\Z9ޣF<.6Zn7)2\bΦ%4@@Ss6.Ky TaE/_D.)@΃T>ތ3h=cIst}7M{PGhfA?P÷RLCSB?P=^oW Ԝ岅1_?μUV6Z}hokyfHȄ< t:jY}Ű.[E}ꑺ+>*zk)x;|:h 9-ocأE,A@3`ɄRwM rɈn'S_ +lJUԨMNȯ\b)xB H'Ϧo}j ɴ&+w35.h6}|[!նTʱ\RČG9ߕVW߆4HCI1V/&宽)uiG__T~<Б5e/K<sL_$tq&vO}|F~zX~GLM]7FK2H2Ρ~.ekt8YVW^G$I:mhE: $1eݼ=!o?Rs,P@b@H͙Lv]W cER^?Y!h7!*CS:tv<$վ"Ma(8i!CxZ"$4fIߖmE@5OVE] ؆ǁilWl](\&&PqKbܿ>e(Dvr&#.4drv,܍mv˺:.b<,М$4% hN Zٰ_6rq*ŗ1Տ^~QHہB!y5*˳:sBUְ{JoOo*fYl 3SϡQhT붍\wIcK!)%[缗WzRߎ$$2u;'Ňzv d 8v:4c|o~ ҢP#Q=WZ| x$a6N@g'c ?^| |f\Z'PIūӴbIx&Msִ YAq 9ʉ511L8n٤G9ǒm^6gF@І[W?šS{VR[Ace>uĮ_  &+5.2YۣP*%jŞRިʒk+˟|4FyBޡ0LxĘ[K{}}$Y:my;С^ xt@'c8 VPkoEر?p5#"]' 㾙Xe&r+<@qx@2a@S=P& p,j*83CCm{i\ף"_AZW@br26َijZRx׬ܺ~E~[k4OCA!rK,]` Sӎ-L[H&46@2 WB/B'B[^SA' AVG;_%A#nCL>=?=s 82^sԁAZHHєxXK;<id3e\HkI[4#ڶ$ͶͶkk_u-KN.vppl|4hdiCb[oFl{6lٽ|\~; FkJ0TFRB4_ IzZK-X1oG$:+.~$l \!77mL2 8xnBO(ru7:$HKӆ Mܖ򊫍ߐ:rFT=$OFF]D|ҬZo<ӵٖN'>nv{s wJS:>݁BWQbv:8{Ovn)?=tF^Ii;wrdP)Q>;osDiC^\{LU 'ND5"?[NQI1[! dTYzB~~/Ff`QC^yZROQ?C- ٰrt]g7":y̘4A^4H?Jژik˂Qg©IҰRxpϜƓmײ7>ȭ^z{7ʎHтPxFP֛޽Z s_Sk wRˆD 󪤺s73?y:ZHBdҜtU"4_)L+*i4M#r]Կ`/: m'Rϱ{9v#|C+Mu wsQ4eO8s0ٞo0=u(6Q~pఅ=ЬIzó5D[\ht_9UU{R؄8<9Y@K*ڽ(VjZ]z^hhɽ{IBW.B&VH7r9^dkr~bҮ~h|0g_wmaݩZ* MIIk HKRBTVlolj{L^CU异{;Ao,ŋpV(XD!0cX5u 4#I_ :q8$m}z;:'l/[]2XVͱ/#|^ZG95j|'jUj4Auk0*Ks`R`O_5I#=y4 d!3\oW5zpF Ȱ62Ku^U73Pqba^PBMv*ښע̿ 2#6_wIiC"( ~{sPn82i9GDn6@kt NN!)*5m8xC]z E!}ZTey&!N{OSІ4Hp4ө N]Neu5Ğu݄LR//Jio&Eq,V: (yVcWG}ܹ֮t}'H͏UjqeyFC_` N5sg4P`N_x8r*8>ˆv h–÷dFќ>)6*Mҗ+) O$vE[hrrM IFMo`{`75,P#'hӇ,FcV 4Z>yW~F)*؛5wb6AiuصS2 m@Y=H`y/ w}/bQ`6w̖_@~An IYUo>HH~R5J~mCmw\eǟ*swo}9M^P){ H: ֈ zH8yø(I)t*u߭̊hegk~6u ?%aMLf&=:XR5Vbv35.nɖِlfvnuK)~2nU/"&x@}Y?AФa,%>Ui7q:K/ibSg6տ)7>0:cWB_WW=M)sC IDATLBJjIRKa J*SFa}v0BLg24Pb&#IJf\\&)diB9 -v)֖CZUۨOg~ 8,A|OTg V F52ׅ+/vj\\TFvN)2 ~z ! Mcfe4l(PZG۹f 0(A:YJ!x;8TGV#rh+*&3sHʘ_*H!Ryl^ҧ7?4<psvi2% H+mY P&WS.զ+rY7tsIof=qֵKĈD,> K~:<߻g0$$R+RYX`ͰkZ[-yZDtF()eպR OG E'zNyzJ1п>R$VKʹ`Vzkц.H6ı{ОnVg{q>=Á'nH˯6 .v/g9FߖwWB*sƳ%*6$q!-M&:0hb޲y5;_ANiv>m  O׍U3?ntﮱ]<>Px\a+Tp.Ha̮ ?vR0!!@S<5h^ҕUH}`gYmֲ]+)'g4$Eh$ٜTՁZfB5Y$e=NYBRutY_<ժLЩM(PFNc"L 8,dHp4L.l0-^|"\s2@ l6c c8FI 5AKl -myl)?av4 Ẍ́+`0"(-E 1*0.[ؚ_ AaTHPua;L */8x攭ƤBuu'($Np]'4y`Z]G&hDիP=}*|#WK֡1TdiLbAOo_a>'٪G넥uRb4 '%ngJҚhtGDcoU2l ϧpO,YfuԕE(~C^y=ykB{~1Iq͚^]XofYrK9$GCTRaIMg6#tuy|3]֏tr~a 1ju~w}14 IHKLw6_RE \]E Je\ ǎϝ}l۞;a5"RU-=$Kل.| ặȰa Ijf]0(6Y 'VKHOM/ەS/xֆ6HyN>E*_^@+Kl=P|nf̏"ԟ{Yun`c9H pj,εk@ͨU5K<Zo dVjLϗ+4Kr+`98\K5N6 $G߫Zod}4ӊbaNHH,B8Axhp0V3`t"՛-pb֪Ig ͇°`.n,j<׼TPS:V}I6(ŁA&FkХ7f z+\{!/=;08GWD)( ݩo١JQ.nl\ݐRjVVgWo̺,n4΁D@O>B뙄Ⅺl2C@LmZ|޽Urjw,o*h-'޹8by5 ?뢜쏧ZbH s?/w"Դ"ݚ & f[ pqT;уESp/HTBƃ h4/ܩ 93r WA'=na)ʂU?_ΧN*̼{pv,Z*6Mr6_>«¿"*gφQgREx{sɣC47e=uciɛ RіGN/PJKTBgv"8\TW˓/S4\bxDZgɊDTz#~>&ji-_rQ WV%Y 6Y0}V]Zf}Z>tzXZ1E+P7KkR9 ajs4vC 42(*°xQ {xV-&hz#Iuda I4 mf7]`_HH.R>QljrՖUO I9fj\;/r̒]Tڌ %Z7$ :ںl HҼ$@s I0h5G(Dqm Է%HͼЙuy1Xb2m2tx~q߯#b1 lv?Q`prˣ80J*@)% P*)AXD,|w,xw,ܝѩ?bƒ{| $Ay0vB o^ 3 dՠĠya5~ɧvs'f#fKr*+I>@ؖI4 idFz'byz+m᷾ד^wy,hd8r9ī) }Q-bDlZ{o7>T**.0Ң̝JZb"]6 vFu%aXpN`i uED$G态9;$HwmמdA\ŴׇFsK5KSfrs#IL= ]^+Z=%@+kdΜs9GnkE< ⣂9p\c{.sMQsfF^ OG%nGd֛NlAKI tdӉ%ᘖ:8{)X~XL"Xc^.hSqSSϨ@&xBD`Q,[n<%gs;ov"ڀn!N#:{:یchMT#Uf GDiC-4VAH//WQ̼-c_w6[9;]%$ܹb? ñai7=o:1 )7c"E#}XJfׇU1S.UZh;nGg6=>nU)JV/ur޿|TTo&Ēҹ;x,'^$ }k5 ,zCoJ4BM͋o,hv8X˪#Uxq&#\1f0%@^/M^~j>/VVYIEG넹4LLa  a\]D Z &'<ST@{IpFըCLJ)`,ZvAoEF~ܚCq} [6^lF`\3td'ցdG6 d2`2i31ƒ":қn!\NsM߫se5A>Ό;?xX*Ǎ`(8HQY#vf}T$}g[$?-/muQxиPyFw ka8tJYS ^t6^ػHnC#YHX{zFjH~9wu1|Y"ac,{,ω3tfVDt`b>{WfE `y9?3bŠ#2S0gC,:c~YmF@ІgCأ'}'H;: &stӪLݺ0Ra]W?x]t bi2^+٥lN[d-  iiYsNVX)zўO&J^:E(Q/K5z9 ClXY2ܪRZɡb}'ן/ p^}${$HPhhaMK]+jHiV u\JiYDbTDrS&+kt[_t8tۮCgH.!Օ]x8R]Ib,{9A}Qa,LgTj֦F3jX;J#i]bNwz,BmpA\.]~($g1̤zeDP/֐^a-nJwEsE'A=;^}(Y%UۑyLٚz>~=rڣK'E9:@wݪ"?֏ߞnx$ȟik.i} o/;$  gں䷭W5lgGa&gG!9_'k[w\Һ;ٰ<]l[7ɟ=q^mgRrL=:0gvBڀ_aIMjetBe=686kֻnP:rX hºܖq5gz ".Öu$42M!yM"`03 KoqmﭧjMPԝLjx3GPS^x EQՋgDŽy+Ho{z0M3%G,!'9ڲAd0b{rAdMHvkjH4İycX!`Ah4ݽ4"֪uTVխy +Nm6x0 bxyjF .8ö%ҔSZq%2`H۩ؗ`d4[rxA)ioJIfX4& E'h5r} "HfP-a0=7~ٌf3H%T  $BUY5gX_3jɂQ۩忴I 4WOc"l?|Fl_6B.|v ̯' 1 /wز ooo!,8 8k^܂AuFzq5o>z0UKН|l ?F;w|z+=WdAع`ssͻ0mHO÷W(G>,<># &V-},P Us-O2lj{8$QX6΁r>pM'V ʳd=+v5{ ]x}ܣ!F5-/]qN 8 *?OFis8lR"gZ1vv|$1#kD=Y%!C ζ:`1tE{D0zFrV1>:IJaa1Яk{v.!W3Jea]^[$ᶧn穕2o-(_ڭC(oȗK8FXwlNUu^ct&>١:Dwgtn6\irЫW {Pɒ93|[@y, g_nYuen$B]89 wn>zCǕdےXb)S8oNC4& *,Wtn~6? WWA^Wb#mJ^;<{C\zAo/~Aw>P=AOg!=XP\?8twbּ_O/4P.;-ϻFwʕ XEE_t{1* v0N3Fď`t`h'Σ ^_=Q`DF74$N;x 7h"1#ƀ.vff~T7pC5`a}  $_ D]t& $]!1t*?/slYu:>ӝYz`pFAMא o0UF~e"6 Zha ݯ4t¾XQRQqI>NГ_rL*<;fbӄ )hz@V_ 7,,k&3Y[Aͬpcv3SXnW:, D}_ IdM&gs@LtfDS,thpǀ} xǀ&r0:>0?I;W 1H-2_o{/Ђ ]( LFd(jtN667|}YKߗ|Xy- bvۡ瀨uou(fbn&1dH:}h8RHXE:>heuf:G;rNl>`F)H43^iS_q?2S4}l*Kߝ|P֩aS% Ck"iqkΤ#nz;G?TJL7UhYO\$SApB<. L)8e+֢us~8 IDATgnD`/_ٸmѩsKv_ ;Ç0kԽa=xGRm?І64C=ߘ6Er7gWME3CsۙSϙPo5W'`ꏷs8&,?s80,o ])ت￈kK!^nk9UUo)Ӗf>muy;k7ùUu+ZMt4UjG8~r_fv`y9Ln)X2kxkLEG>tu[!\TKi\j8_Q{R~50dt_1YqY Xz(Sa)W LJCr =@z̓ #pN2~y;&访~K`hB{e'H^ApE |v=\0x\JLŷ;Tjn3=<ǯ'b8j!f/_xOU/*2̏$B2e*qΝ;*rדړgC9ZF%OE_'zZ(rbZp>򙙕Vۡ]tߟ 44?=Hs1̛;dT*[:ũKO>{#7tphc\D~5)h&oUj~4+xSZYu{j' j2o޿.-d7Z 1<#M;9UOfOC{zjܾ R& ɇmn88GZ=D4w}8O45&)}gd(o5}C҆#&io{! #?_f|keqb&vzb첋gWK땜S FR67)(k.%~!}H>LQk-HB$RzEQ Soݺߧw܈ocDCjI.%}},ƣ8aFAh~Hkqc5 s@'ϼ/4mMCrKa̛l@6+'Hpl,.Ъ䗊*tW=x3T&c/4I4Ojȼȣjċo^*EGmϤi}(\?Iʽ'sǫonVV`޽'WV7Js9L|5gerX2jwl.AkQG-0~F͋0apk.5f&oH8N5|ra#z1y>[8%9d2 tŝz3AMe+϶HA 88Us`]usRԭBW-7?:>̺dwBHVxRh@x{"}w~D$H,$wg̝ss {DO^%۠Pڒ{j$zן%0:1^ @Me֊ sE ~ǷA}Z4hkem6-+OT*6F.843êK.7q_eF}2w{^voӊ6\hz'[yq9QUP}Z)|-)H̛oXp2󈷃'M?. &IFY{L7‰#WS`ܮ2]GaXw"AݛH腥88ppsP,4F`ˈ…eKOX0hx}F݀1l&8XcوaU8]?709gO`;o6hT*:-Zy{o/D H>q6lF3{;,M/" \ az͗pc^c0>9biZFĮ]Zfdd\p Z .F>M,]QEJ'jD\o0A R\pGmgaI]ٟ(KuvU+V%_KOIDes$*Wowu#0҉ێw萘K5%ڮt}Z'řY~p=}ZeRB'#nKFx$GQϚ\2Jf%?1@Pl@'B|5^&tPG (_\0rrL2#@!i@\ WFqpAʅR iCTxV|{f]@pBPWq!Ejݬ۹WҤJKZU2PSU}/V1+2\:0sA>ꌄYFU"m3:\Z}(օjѐ9UuC|{o0$?Z$J {{GiivuĮ!|qV^q?*/OL庈b2 x2Ie}e@1|jd T(5~(<&صh$߶ ]EXWM.-|[;5v[Bdm-]e tBMyBoܙd_ӗS=iu֌ktfkhzeFu\q@&W0.m]9sFiT#AϤ}[w",*i緮߉zR#[=yWkAx֫Ao<̚o%.4gwͭA2>NR7ޘݯZ8؃ PC{#`\&"09ŒǃP&Cy0%}IxRH^H8<):$f7h@(Jq}D&'#2)yB^#(HCd x=O[J8V2V./*4e9W֊ (T$n ;7mEEqwkpEϧ$yW2x_}GV #,?P'"d~#9JLN"g3.N8:iS)>!+dqy]+!ᦽ|CQb{bc~|vS/{\@O7~_͸<R;ᏟTJz R.k VcO#@[93@hբ$k 't"jCbQMQ @8yFX7\@R *"Cz &%rʌ͍>G>*~Wh&4w Pf46Bz{SdzS:0H[ )l$))$p<*hT҅ԜEunսk>x+Tד~ yEJ}pz447ÈM[q~+֬AFoZI5eQm&<#֯I @FUh@tIB`0a}}$"^PzJ\@ٓ L, 3KqX|y3\u}&2P'3)tl7hrJP,|4.7e*:XOTI(4h%,\)UB`P(V*MFʣl*M>XiS^'nx4+V_m$-(9mA3=W\UJ*ʌV(3yEu\:f1Gz ţAP@7o B:-tIg͙`1 A ,P,@فBc(J!.XF>Pk h@f,'hn΢ٌ='pL&|>?/A8˧=,)yd|*2wdֈ8J5KݨlQvU] `B[WC8%R!aS]nuwS7~Y%p4_V7HR F.M#4~bj=K& SrA & =_|P$L\lq`~9[ ,XEҵ}4bX UGN%?3)mݼ{}}ZuS&-{/Ңrmyů1sԱ)&:1z>/5T*YޔرsxF(~XB!VS{'ÜYᰅu+ @7W։MWƒa_M QxBD=_o.(_:$3h&zq+#IäA=g|509;~nVlFzO1Pd?ȓBD._;P̖9 jvNt}\@grIm|Je9`'΀QT^PM{#A,srK9 q 65~tl:hCajK𚷨r|0(UjD&BbnZtqo]n ~/Hou*߼?A"Q |2jԨv( T^`̖A*x0]BU*H+j J0ؕ,+R_IH*Ciz*?W5٨NFjc&ͬdZs=UOЖjjr5Дߓ84 itteZ|Wj~M_SKödUr (fʞצ#i 1ËZ2X4͍'E]4񍖝ݯȘT{6}!`یR!o%B=Gǯ$_WeoNNս!ʔg \߻1{Mg3]虣//=XNc=&o\9C(?;oϾuo$N"8l.`mCoj[P6xp6Q ]{^#jJQ1ePw Y;Nm`fw`_d8{ɾ>C::)πSS^Zt4leGyh뢾?]-5D(y23bA1i] hn>>ǯ?dgNٰpɑ㍣ӳCv⺅D%)S~z|;z!y$wѣ aCҨ ?XT}1uc{˟j~(٬ӷ]Sڷ2 >O.[}yTjUcTR؀ibAM^ ;+eƆF>7M-ξPqiE3j6'#?N84o6\wH,ޤbIcGu^#]mHۦMBdr 'LŎ+qx,qqƎĠUŸմI6&ODxZ 66Oh4a YgpU۷!Rkփ(i$VeTB͑zro+W+MZQ=Q&WpP>#Mq5SЉ5l*hčr|;goK+vPzǶƣy%I*vZc}W &܌*߿&3T:i$<. ,f"D@˞@8xZ^45c›Lmm)18:ǃ w^ט{rb:ŘgX[]3a1m5z~aλ|\`C28h_'J 8jlo"FMp䴉g2i_U 7i`n?}dgp7ѵ3\kjk+`i>0YP/K$.`abN6GJ}ȵgqq7?o=' w 6L>ה^-VG̋?/XSstkfkl`2TkXuK2Jiz5whRQLU 4L96Ҍ-g7wdRmqAt u,r) ‹w=/pG$G0+׻o;Ŗ,M(>)nj:ot%ߗ@2O5ъ7Q% .1 >‡U#Jt.:Pwx[!5tj 1Cv8}1^A*P tq2 'aXx .>w! g4:[O@ow/F Ѷ3͂Dׄ%O*ć|XNǕJcY/m}xKD}"OWFGc:ǪQLz~Q|άT#%$\I3,-]>b~Ǩ'Wd\gFpoP\IoFRuERꉽh>Gz='DW/Ga!W/I܌ҭ3HмMshu8z޳w7u g_ŦP̸I.+Zx?Q+GdUK.~~DvlM9|UVUJ+Rv6X`gWŋ#/|6~ .UC'qQ• 3}DvxlǍv|Čܸ *4mh<-|Zۘr bժa/M)?~[7re3TN;<NiزwM"fiX֤8#ZC(.o2}2#IZ"*) T˚c7++tz~r%KUiy}۾ +f\O+j(H+D W -plD*Vv & SA@JzDB! NXX@/Mk2PAA/B0Y:56 M {h hٲ n-1{^|BVNct4@}YۀbbT Ur"H 'JY}KC Aiuݰ#RGkMCwH4}++J8VNE (I9%o0l]eO+.Db9 V=+SI@>? @ #fu , }6KVhIA"Z񣾖^ʼWc=-\.׊ uIфeܣ_U?Rx\7ap1ɂQ ,@EЋ 6ˀiȻwP9pK?s}h^A>e68| @.$EPa(}x?N 1!$vDJBsʂm?ذk_ +z+y0l0۷%YjiL57 )ז)plng׹n޶oVںGƕ]{6@VLʫ#=#y,F r]{S(.Vmå}Der~WO;j oTӄ.(mQv~]u3>d6]ڦu ԥeծ]vyqJ ]uˍ݉8e v5` DDZ$= \qu߼<"VʴW Z>.KPLX ,ʯN{n<QO@~M^:½k6UZ?ћ/ YGP:5>衾5d6\},|L5_1m!tIaġ$Q6>]iϯ]gLc$=n4v#iN() (</\UG2=hjq/TUjla){1轄{5fJt;I;55@$ҹР!R,ydIt9ـRQ6f1Ai 䄲" $V}e6cShsWgD  ZC{I/Az2e}a#KȼwXq4HxYПe4-9]3VK.)) 8,A뾕;Ӣ N_b1(W2o0bO=E*߄C Gb (Q_nD3!%dPuwM*xL;upywĉ͠r`4j}a>x_bגHGMxqtF >м }!U#6gO( vq?*AB  _0u^ ]gK~}+1#h4g}L4ŅiaAQxqdd^+dP9#EOj:3jf_@J> a9z>|^盇WzOK8y㽁a7)籌X $Ngތ"O.6TDy^rH15en!1es[~r D䦃wDi59vHd|ޖ3$E@*`u{]̲{Cb ["rZDDV"C{tb~fߖ ~Z_I>A϶?q{#. M= Տ[Q[SEIIf\A .*0pǐ#DŽ?hƣz$(|Ƶ5N0zmŗ d AR=hQbJ98ڙQ1A;ekcjTk`) v.n<>5zaw $Ib$\a'D<|n5c$#2 tToT#33&]9UɩgX\S._;X0 )C?=ef _  yP>S' b3sd-X?_Eד z+ R*?\v*1SL|pߋE_e ɐO؜Is<+U*SaQoM*elظŠ 6Ĕ&MQLҬQ+0/QQa{Nk2yѴZ5T;$Ao>.20(hY0a+.?h(,Z1oAqsǻ_3CGwR'{#U$A1++WeT0e/@Y#= ˯38ݾӯ=| ?5jh5*lFUhTD[|dR+)`PyH%Y7CTKa*sk.~\.OMT7|2%/I@'H[1ˠ@2Da25C3ҷ4 ^r)iT^&IKSAܢ#ҏ;j(ڒ? -k_S(0&JplQ&ΣصdFn=փ[ac u9P.l;}KC𑤦cf8r!4qJՖ\ ҅{IPYVøFysu:1]lh#4BJ 'vmS+eBv|ܔ/t>4vח.dDy;tٹbe%2,g3ȓ=`g =qr१)Ojp0/&(Kȭqm.l_Ot=.?O[X9'd?cހ1Oa}<~WC͍ hCC}$@h$!.."A`.θ~ XLH*tZ Yِ]Ջ(?nI$X$Z]sh &HUG^7)˕PU+㊝0eWj?*/Csj[byzX<>w2-#*1IJ[Ǖ٨Vtǎ-g e/5vZstM1l4QL,OjuAipݧE!B]A.h%~1wt<g~]k3^5!([A.Y;hЅ dX+h?r 6.6*iNǐ>EUIbꟙ.y-ML)ゃk=<-5tB>>g}HJ*ЭYsSە5idտ%6l%RkX*QIJbCgPT q85wriciIniMVkӽÔִjuτJEfk5] Y4Μ \vf/ۻ|[T(WQN}9IwOݗĊX3'zfڥF+WK{Wl(cvk+l4sLv\\,Hw^6;2db?""-У+zR)@@-н+Ȋv++}\Mلlb'Hiy81~<~~S в8 dIX(m}k\(^ii{ Dy{m,l[ӯ*A`_;4G:w.*P(&95helLj}:mwmi;U8,VRyl|\JE4a4¤roC_}(QTtKawΈ@2ո%ԩIsG#{jH<~[9Dvm^5t^[amo>7 ]Qgq?ݼ-KCu;cneO?ΫPT{a4ڧ䐧Iө?·wL.`~.ʫGvx<ÎaLQO@Bb{R &?=ڷz%oLUɊjXg̋&g a.pvҝ6+~fج\/k[VÖ&H>\Ӝߋ9Nͬ=Zvo`խq\Xwmbst(V_ov6#XNꋍuBn\r!a7a&n߅2HrOI;vaNyͮ!IKŋBD  p Btl;#AHnWWJl)2,n$u uIPX]P0NTv HE# YSeHFPݘE5PcT2e::Q&O1UZXhXf@w q@*W^S'{sʁmcp%/+M%K?tY˨%N'' )*Jfإ}yyeiQhTs^$=촑= IH߿%mi݇o/ <_T"ūG//6֣vr=QoW mFQĄ4[kݢ=UҢ,}cIw۬YɎX\W ~bBI@AƍH0b+'\;$IEbۼ"z VfAPSS$*ڻ=]狡 A'  +!x `3ޱ=PmY8YޮdE*VS)$+!ekĦg [NݢqГ$8s*:#INI-`ZWoPk^5GVU#*+Ԙwa* }ԍ$ D- b4` &3h@' رw&IcҌL߰TH|rZ%)T3W[7(>jjP>^4YD(ꙬH&qG>YU,?DP~~z Ԫ6IN@Z(rijS X5y@%+6]t(k%4 ׀?}Xܙ7!8XtK,)՝2sm|Z-c?G&s L ? *!Ǣ40SV-Pf63gvײpXqjjn'DYt3x޻thӄ=`cJ;pRLvl$[oW7ݢ{! ӣӮf>ֻQ# ro7i` :v~{O_|X IDAT&,2~Dz_s)}7eD0Lݨ:'iBbBkk3} =KEܬ;Y҆/Eۍ'IHZv.QTJTEu(]ۜ7/ICTZٻ# D8w4:z= @mӮrnp#v2VTUd$_Aʀ}6>TKɳoǵ,'\ao]Ը,‰QV0 AVLj%j NfLSK.͵@MhSYe*l/;Y\ɔG,٭/&Su䶦&IMZ\J5M>Y|sȂ%]fs2ǠTJTʅ qC @(GW|;@Q'U :/Ӑe<Mrh.mvğLn.E ԠQ>Lq&--/wE|R@#"[izޯEQAAJ̍f=*$( ߻nU۷mk_)rr2=7Ep[ŀ{ĿkԮc:5H'*o?.73W~!Bezw">8y23:cS $$>KJǎ}^{wp䇕Hk}^Uz `cŒpsBQIZKvF' 㵮؉w=ׯ^\~V޳dmK㗖rlҾ-xt$6~_j+{~vסE+}: `5Ѩ `f3"86w"бEsIS6l,6l $x6r@tʓˠtճ?UHn%qDs39ϕ&l3n,f׵<-԰ؗ$ L+^P6B!@4L .!;QE(`'`|_(PuP^RJx1;U'#?UNUKRLo@YA+,5ydo?ǥ>W+BF| ^-nkVcXҌzzp';{g,lboF#=i_hR<|ydEV&ߕRbM'xwӟ߇MҘ7bz̘yjٴRss [d0ix#BU7b͖/^@}LTKH1e01Ӯ_:Sg±OHr5 $>oD=G=?:vR֍*,ʈV[#$5ZdDNv6p_EN ĝ.\"n_SHpO볩-4T88 V7_{Tjz[O'+׼ Caڑɡ l89jn7)J?ƒGa2r,}sf@E@Fj5YP @]z&BC08ZYzq7Q9& J"OW E9Na1FR_*LSj]r}u ^4:^_+Ѩ>=M͸4/LZ ؙq'1X+_4d0+)J+Ӿ@|w\&>?) )X ݺVm49ZS҇#KOK_)kD .I< "O!y;xpd(ʯiBu {wwol\N__گ$!,qٻ*()/IEN՘!VqWY Žs;stQ$JE~ԦO\Q/⅋.jyШn obl"ؼ7@EI"R QFF h`Z 9HA Bb$X(`HEj->Y~ȄHZu^enʸďHJԚn.PBOXo_cS.ann'kQR ^>};G(.9ik_$%^3Nvt[k}a>LDiC-8pnTf/)22d.Zy1 $er)xQVdL$ Npk2֞?;}?$d'MmڦtB AD8QP?QDd)("{A٫-{t%9Gi>핋=9mFŁ9' CEF7\Wk{t)n : '\9`lmZcŷ M( Qlq{>k=Li6a\:Շez@f"iVke+kz2<ٌ&+ jo_e&`ҳTMVVs}&+c8o-R!07W>}VU,l㶻ݭdɒmU|٠u(o|\@`TuƹʭrߍfL>q3d;SsGylCUQ{:,u3$^y&5ˠo͝?/U@[g[TћШ;O%,o[%kʸϡQ@8dL#$"ڢo/+]z>p(~d:a]E"0F6[7|Qp‰' Tq@֠Xh,UC4Ud8b_C4чxQ.iRV{5i~{i.8Y| y)!XI[1k̐eՖ)'e-;ϕ}TRG>otg$G(GsjJ䍴0o=7*5zj M0=a1(d.!wk0:\ ݶ$b4r 1j .slqMlȭ@HgsLq5_[#ⰽ[nX>^MQ~ֶ2k4XkSq=?`4DDtg9]BoZk 񂆰ڄ_HS=>cB)qs W.Y6w&'EnL@" Ģ!&YÆ`QD%W= 8#tI`0/^K %`QPs># me߳. M9/JY W+&KY@7Ui9dqI~l,Ip\ztya>;uTf`(4[/5oyv `ٙܺӥW@, 45K<#ؓ֕`ywpeۭܯn4Pӧ?”X,]QCp.A;T/&bY+?haMu; hƨb%5R"Gvbv;âDAˍ~`r3:;3~bCk5/'p .XN8/(ŠnR[sMN nQI3;QϽC۳BG֥_Wm{d—qJ7m'] H3?}Ѕte`?f7ERodsց¦nf$ff=CܗgPۦ M0u]ΰZGEW4Ve\P X-kѯzk8=U+˪P+k&b\QG *,qO䰣lR6}9n$9{_!@[ ^4ڢ=ρ{_`7Uw  P]tc u kFor RR-i\57{w/`b{`DZnjڶ\U)b!v *3qj X \ybH4܅QQp P);E`8\(m4HO>RTsnjLusqܿGc 8j_Ϟ|t_hhW2Vqkia+Dù+&"n5me^͑[M6-h&kz粿Ebԙ>Ir 7<6LB*!")QpOV6vdi'uLSk 9ģ8ĿZeC(j(VY =/vM 7.ק^>;~^2w9zę?sX^,M/l66e8vc,jWo`y7Y]Ϟ.7ӷoWX]%ՋK8#ܳTp,B0YJg8(1A4 nh3Fk3)/wGg3{k![@$1sVOJE `CUoRKBrt,w%dN|Te-%T]Ǯ_r}1}Bzl93x.Ֆ  |0Kh\/ 00]eP\YS>d|g޽dH&{@Ǧ[MѺNw%T˿pr"S@@Q|!eњjW.SGOVvR3Zg2޸5 'Tx1 f$>RqGS]!ӳK܉OgY6(i:Wٸn r_0]x \*wذPk_n#uEv|_[xAtYBοpٜ`-80wz1h(n~Cv+AˢׯO|_Zron3,ZzM `vY\_b9+vnw"[kwEbAIc(,n^{xOt[3sRO: 'E B)~VG!}/&6ĽIɣz"- wZB:ޛ&;%W[4vh4[,]DˡwNSyovNaB &ԋӧ38O^UyJݵr??=Hw!N$ N8/N%RżݾD/sDm^+w(Eo7Ú"qW%@\0j~4*s;Ζy!h3;|Q>^qܙ9: ؗ{HĮٚA\\#:.u\7oS#1eZA7]F*5)lVm V/7B>s]Zwf i2Ƨ\.6bek3j2‘fy.X(@ki.p J4wE p;~ҭt{B4(]FKUwuG,X%WTqXwXkO<:A`v^gos'BL|/7Kt캐01IQ~[J #(.":̹ActgP)xLI^_&$p~+.f+LBLV+l(..ɫxA*/L|~* +0ix,{`;I#pgTi}$#D#tI ~ވɓXsgneye^82p0"-bqܨP/d֧HE. Aᙑ?~vaWj8 Nb6ir/[}YVp3?HM4si gHc[  NVkwwE%HzrҌ^|'2ɉRFc?Nx%!^ln}M P Ň[_-yYKj2CѲ_dJJ[M2cLC?(XL܏ڵ[^""~[!WP` 6ڪxPT& ӣ9GQMQ >lu@2HZ֞xt BGZV}W]i|N' |xd‘tt)"v@:G'`WcY;*[NdϽtZ$b.j~xsz<7n40vi+JU[2sAժZA HFjx· k[Av~1o2g P/Rx^;rqBU\Iƿr-2*-ēɠ矏WnUٻ]Q5g ʬ7tC7Xa|IԐlzŦ 3'_I@p_NPP b/ 8y+VqnH \)msܺ9cmX6d:::;SQ@]9|U=>+^Sj3x@FEvgv: Q$Ãfhm6L>.@ y)Smfʯh4+UP(ccB]DZWƷ'hw \MDneSKT }^fVjl4[-]qkx1i8Ja8ZJaԪ6}ƯIR*}Hx!ߕ36osa|O4XdPSBD,Vv4I@;v| ~Q:X@Ify.wѐ$6As ʆ#p$+}9dBcHYp狼2@qW-Z}f^Hq j|jbX:{EeV5HY:GDzkx!1Nd[<|)x`;Fs!N6d?gKϭfݶ~61>>qU~Z^.߇ϡ|;:qrh5Nd;{Dvl¼NlV*Hܣ]8 ѽ':bu(U۳O{^$ os,Ȩ {&E}[ 08,h2t^zzAQ`ɼ܋f 9&_=x왪W1i1`0!PXJd v?f?]-JoD9Uor(VƤ9"wQL]=muಅߦ WnhY)Sj"H//)u,f/#o$ɲ{p'ڕ%lܲzsvDR8$k"WvLtM:JXc)wjFT ijͩ˅8'ҟ3Ndy׶u!g͊1Е=KlxyS7/ܧ 38tp}_.ܯ\AR0HM &TZӒ놦"hTJG@d ^UDHr.RK)٩yw~ǦzqY̑ L~; NG̞5Mq=ۂPyCUWWf/kz1#}]PdSVсIZg<+w1o\?'`#(3vl~`:ܽ^|j "k/1M:ȨؙU fɜ8u,{\Fg`N2UcT:þ\¹vU&iG\džkԺq uf #ZX& Lo<' VM&pn.3UVpL;[Cży 0Y[ x[ mU 5O*x>8`q`nUHw a]E!QTCZ_7iZcEW,e - _w1z\Iϭk]bx5JaP]BearK؅r` Ռ6q{ Zyk3vM-7"Lxi +;er 쉆cȝGgǢsUjKR^޾$SGy{{!0…*o`=ׯ;{dȝzDR810>D\+oLu:\"kkn<,pisKnZL{DI([=<1T &TziӆQ}"pAԝ*vAyZ3_BP1>]'vn#GG|?1^BPytX*@:?&%emQ-1^J t%&Io[-qS$|puaF<̒L\gA@F'w*42%\gα!ޜdʡjRmx8='xp'@ZklN  >8\]/r-*ۗA(d.SH S:L{n?W|m2C[*yu~ĈP/* v]|yGQmTWQ3h.l)%dnlfO^4)A*K;usvPJ ڣNquRU@WVPt*4:xC° n杵GǗRx鲆Kƒ+Nwٮs=BAO4mPK'tXn"Ƃi vUH`z{#$Wj!(%)]fU }6Գ'ee .8\ﯛWGJen@ t Վw~DċdZ[[XgNDOϣ؞Mxq8RPg+a޷߾d/5/hZzY]BOS7'~5*kTqhjOP1vrpW >lX)"mw+\' "T7t (#'dScdJOrhz=l EĶYqJ3R?Úaa.  ZW:`F o_4A }nURsFh%4 <AQۢjlӵp+@.WUJAxf|y[38m1,"KA%vŬ˖…\cj].1ܱpwߺr'R.`iMzR[Ҡ_יw^pŨ"zH\/_tbNV5`ו6񡽧\Kt{\*\oE|E@ ]].(0o$Og4nnWzͨ56/c0 7w77w#%8W+ /_|Di"I A"A,ګ)R|  $N^)ԭx8~@4ahҨ?P鍦PK;5Aw!N$ N8wb‘AHD0X.3ro:h82 r+Z ~¦Os|cܓS?Se9]R? (P7/{ˤiVWf5DLr%>dT3ISJqӉ}oi_1p.sMbR@~j0M҇" /9=%F;O]PZkiڦ5~ޞKl_:2Ac n=7=&SPؗ^]0M9@}a&ς58R@Щ9 v^h~9IBQ A $K̻9`r 8z.]PѨs#> ua㗫圢 gG >#v~Cx= lP/APdo.5T,hZgi3MS}?#|\767xON X[$DA;u,O3"4 \zCᐦvR[*hmjfݳdWtJR5ejN /?;T"=/%Cp_[Ԋ6U[vF^UP` l+1kYNcL24 jmS8j#TIɢs?Φvں,pW0ؗ#Cߐ??")mW p2ی8~n8ZL6ϱZ5ԝ?ԵEӂClpk凃+8Qy6PJXTYhqnNcD :zRraGT?K; >E!?kLq!!-@j9+6(Gc6vYaEwmؐCN! nU R"}y!6NmRI55Ca?}<"-u ¾Ď+K߹\9ۑ ݊} N~~vU4iUmL aGx_|i}L "{I,&ҤPZWUU%z9n7tqˆuGq is9̼Kp? hP5gBkmƲ&I/GS!zlwT'?,GP8G*Ek.K ݰ0q+ bN)rk}c\tLU>atFuT:&cdC TCI@pװ?ly}(MV)>x!\D0x^@K?u&~ <|Ü&IF{•VՖolcqΗn1bk4^ ; Bݨ9l KW˛.z@\2.SNɹd3?r1 $*L7WSrvsTO^Uj|ʤr(?X}ymsvZQljtuyeNd+2_c4$}D=̹ m)S^o!K0I1QQO5gh,dys bVcNs4Y*ȚR/iw::Tk1YؔN,VM3a!1FͪiU~G%Mq>rP;`*5-:ϕڻru\: IhGm]vS&ͲV$߭ 5<bSvú#'Ibn.WCvq[Ua=\Jʁr`kT[,Cۮ4$̘ۚc)RʇQOO ~Gdžx1.um@K}UK-fд?6Fqf F(B Qnx(0<) G|=xZLpLImSbL~1jRe3e}Bi #,7whG8O%zD8{< aqH~~B갡7I8vf`( I %W#Et1AtO ]]E(hT`9'p"t‰>FZU)^+diiȇhO|h-@Gq2;O1鼊gUduLz (.?pA@N_ A@gRaw~\lՆZw 8B@Lb3>l?E~k{Q C!ӇuZ$͖bٸ=l6^~^ӎaϽ}i&ƢXy[I6Z=hAe\ CC\ޚ1xat1n\\|yo$ү~,Κ2)9)mTZ,V@Y'LWbv{b[>}q|+;uGJfA 85x_B^]`#e7ۧ̂",{(YCH !Hp)V @)RhKU(B)RhKHB]W;?6Чiw_sm9sgHrg-=hza&;]-6VT(>(?GrwjfU  su3%3fas/ǧÑ,TOS}>ƭ0ݝst"{ƔXTkFw *F8YcW#;Y"R%at -!Gd鐝XbrY UKC|z[_޹.\DĮ!$iU";+N;7ToG={a->|K1^FJ?)3A̫!)QYJֳ,DCQhieRrhV%UvWV/ȯ5۟gxnp}1t"Ad;c18$r@x.J]p;~x -R4@.qzmz[pߢx"p: HkGv@i. VH&buYzu5k aot ',tU]-]VD swN[?WNcHZ~{AT*sv{) |×֙^bXdˆ-+39c:8l, ֹT>Zz^ZjVUe}k%9".ՖsnYiF)EZEp5aբp# A-#R7Zs=!$y%_+$=  Y}.1z1z -[p]}  ]AEB O0hK<(,Gwpv6rߢ]}@`v`lО xBަϥug6xM4j#Gx00<󢣣q8飣]6e<֚eBj#( w_ϭVK׮-5,r^ƝI6.eٷTٿUkZK#QYf^)hڷah֦b il[2wBfv5I_xn入Vl\dFɻ2?ɢdw5͗od_(;SM}A`̞{q=Oo6V^Gǧn70q|Y^_WeJ_toĔւY3 =!hI`:X (rxau~XopZ۶x݇u1槃Q).!b>_0 $D\nQ8Z#ظx.|ٲ~:56SN5~yyyG-Z٪U"6%RG=XXizRִgi/,+6~ RiERFE,%dbyEצ%4  ǀ YqȦh,k3P NbȐ ,JwkOL. /s}[8HZy\ URYΗPlԺ`^#Fy gC}]ں;,'O}IBHDo5˄OѲE+H;@oQ:8SۍAsQWڀem Gʦ{*5bʰ;syyk$3D̉_ɰBoB3v Y\ӵV)`x|  #%SǂKQURl GО ׿.9ҥK$:z@TTTpeAAin6̻.Ժm iteVELNn죁}#ڜ]|yщ5vjczw^yW-Ź Z0e:qRsUЮm|:>Nh=,,= =ue8&~7l!FjJy.">ƴ*UOsО.[ =*ӫ2#8?,p @4 oد(v vý:[Wo87MSv @TVQm XrpUVxޓ} صaϼ("'.\FF6񗰰$}g (V%/>}>^Qc.ٍl% M/*P}}(Ħ$*Zh:w@OG53@ ͭ[O?=ƫ*X 0t[Y=:F4Rք}Uϟ7o=rld#?>lf1(TuXɴUe% زb$$ȍx{vYIesw'Ikd,@̘E=qo>\pO>Ƕ.ī\nՑCwO<,ӽ38;Z6.+hzYjwWB>@|.w.I=\!컭.NݕN71of?NUCGE実BHc`AW:ٶqlp 7NHAZt]as{ HHćj@a0"My$ʌ7gCU7Eu u_])\5T֌ZwCo#3YSA46Q!^.+_7]TӉ˦C b̢H]M@.Ѻ?E1tÙkX0mtx<,6yMP=B׃ h$ j'OPNޠBA Gk$#€ j@RASkH$bb˴Qݽw4;;*Ju>޴iSxܲ?^s]V{k.lZB=IHdJF[;bxk風k>'Ə8}%c`0n I5`Kxoj/Ix9a:w({+1q]'kզk>>}ҍEgWխH b.ԝY7nL5iG/jɩ+vݒma'b1MT)ƒ !~7K^^*h0[~={EZkʙC6[CUČm*^)-p`lZGR,y k>Ո|YZ8ucA62břO"[2 %<پ R!+ y7TmX4+]RX+pp8|$?دNX_pDS!RA(%m*fYTHȆ04qVW]lQڐ %aS^ez~nˬ8bp, srE1G^p|qC>銑wV J"/m.nˆ6?YA?||tq^y9aA ٔi4*E rwݫsd9z.͖/d^x (R^N/+*JFc8ӂw.4 T@7'mu @oEpN44J*'Xb6l:Yf£.ImG47kg@fэܭJ)JQ ^>EQۗR˾Tji c42hxKMM`,IX .؜նH'/]Ǩzf wƔѥ]Hxy{{;/8w,TZkѓ@wZѹ;/@hg/YZJ#c b{tp1|D̛7ŋa:iqw!OKJ-SF_N *X8w;JUâqA3G s{8nƮ[ydމZ)n!!GbИc$OFM'AX%#m$ ,rnQo^R막Z;ly<b3t[Ŵ){U:|'yf[VYzN|-ViMH|Q_ci[,h!1q.Ӈ& 0xAںM99?݇tEGs!4dhICaR[vamDupom c %+T?\VcIeB7do;(V0W.#Ai [llBxX-֎%hAsdbg3N1P h>gnYF2ecgzvŶ[T5nVMibnC?@;= }B 10$ QKt e  ؙi A#Q̍-f,MSev}GbbzjOb \ޛ5p:!!ēmXջeU5ׇGx~4m.A-_Dy>>Ǯq{WVۖ}ld1'Q÷=GmѮС_,==U ,č}pu/K9x~2ەSn^W0YCN3YCڷrfk?Y1?J|7̥.C7oo0g$ZO pfSTVUb䅧}"<jpC84G~}5ŷS϶ʃ#I2^bmDjObz ٌcJPZvo˾[cHR^20-j xN] HHje!+MN:-Yd0m/Ax6> 㝼D)eܩ V]c}سԞG!srrŊ=-,,=z4СCh1 Vl޼8Nx; EYy15f8\Av.TRvDzW34$8HdV}7Lץa{fk?4ca6ݷ['0 0;O^XRLI ?;a^ۢRJk8V Z$ ߞSvSFgtN PpNZNti2u|Uϋ -0` 0`FOןAb gHv`<ՄŒie5LR ןg?ͮx]\S^88j`k.]?w.=+M]SBK3 (AR QLFgf#ɡLZ+$ P;S7Z)HT[Nl&UEԁ9 =|,:Pu-gC+:3?_#7>su߽RiڳJ^{ Pf1]b/WھH^#-mYтͣM_<ӥemXv}w W^zؑ-0볊ʪottm:~i'ߓ]Ұ~k; {n%uf` :w!H@qHQ $xP@S5v" BpQ 5HqM@yLi(*x _;AR@.8 @U  5Ƨ\}(@*UA4@r,bjVjRk0Mp*Li:}+5EWDF:Ajrg/B||Bw (lyfJKMeaMV˘f\2RfNoU'd}CZqFSNqacw.>x}aX#Ƅ/뷨O59&YycM%3cnU'IzU[rGQ~ yƥFubE6Z:komFtؤZ1c f,4_яƶjñ'nfL+"UU06%m!ۺU6sjsCWJDgBp×wԗ6\ќ;YbcӸhu ?% qf-٫Y;ވu[.Is*k&XT7`ߤ%e2rұ׍9ܰlOL] {];3bv2c[^K??sH|~ kla GFB[QxxHjU1[X+>@BՊ ƆC%/\fJwQfPqXumMnXgM35tivdAOЊE-+D]UR*T H i>šyM)0F$P zMKx`Q#[ 4f+M1i%1$I0j#mfڹZ;W%Z[KeJ3QOӔ,H+FNAQϵG{[WzmbcY:IN7 B$,X{*U~Vb&=oiVX+m)Y#n\-dhAA)AԫW'{7ܚMA>2H#I-:P#騆QJ/Zqz0.$qt09V!K`'SBDu>uuѫ>bWLe~,$Ĝf//eGtK_.>OYxRvFv$vƿO6K$>]:H2kF$5livAvTwJ& dMbC3džiMhf̘a9za;[ \|S駫+NkDCĤ{_}*84ZTd_yt WΗGnY yOmnIa#Z., ?e|MOk^ 3TmFGʍۙ/֟~d)fCkMmhp.w^V@3X[NȻ&ג7Y0кewH3Z @" ],Wx z1t |Vqv')B5v5EV<'ٌi<_c_GY7xu-vrF<:{Y/.H`X$:6<,<8Oi"C!zz3UGD66bE2ÌIwޕ'l.Xxp;_[drF£!n6JYM/HP+U֕ '> d yCU@q1_C~8!]A9wS Jd Vǁ\A8tB 73H[W~Rfr+ ` X;oξ$PY x!M""+0/{;Y<~*W5&@kSGi.{6W:&}Y}{U+t -Y ˤU UIvb赆ЀO^!3)Rs]zmkW_1.GՈn4}ClxrvfAAܜ_v!>Qm9N?߿ӿ.8؅Ε5w1yFpvd ]TƄvk&\,Y7ٳ\Cd[fm@WM݄4i\?uf_l1c>XH+bSJ~HZw?E C'?7R+gtۭWEGuh# ]{:v*7x':X0_UUb!u瑗g $߱AV/>Xk8xI?sՃhnhN",VOXBkSKoZ\B\S&7!Q6i.bqi42Rc0 y,`dI`iALuFsxDsAqI"\%:( s4JuwM4Q$GB IDATZaPo4@-E~9/WߩӛNSjgI([؆Ǽ_򞤴0rE[e- Zk:ǃK eOV\xQQ\(F%tc~<.%Y,pAfi%{h VXO$!rw| 'Et\"bگa9~oGLs 3Ѭ.~*)ܭFQӱEkxcًh;j:`brj}I$5֡rȸ{wowl =MJoOxYaqܘȹ`Ɛ.NK'Yca(L–'AX+g'ˇ>!Ԧ nްOxkSnL:On쌩yJ'qXkvVLl$Eb'%O-uLsw]ifD GB.T"[?- tex`ۏ3˾{͜?Y17_"~'m[*grv)/YR! EOqɻG9[?N@Nί:quOTDQ`哫wh)I4$7ébMܯHG؉VnZbE7B%${6ͥŚ*PZZ@lE A4:h4ǦHS= @DM$G i+3oB2N̳իw"YFUʎ[v?ZAuG[RmbaRM$U>K6h5kӑM4KYں#"eԹ`Tw5/aĘ»e԰s`m{x|>ijդ=4+|6"6L? ОY*)?sFAX1{2&}9`ݾpAo٘z@&+я1`ݪirvj%yO[nLέpъkI5"ݵ7o6i9k~[Ml C?xp`Pք/K`tpە3ը0dEFIӗП%bVގfl<${]T+,@|dYou sߧN.9Ҡ3B]Lܺ, Cmo/0ᣬF)8i`m>sLj~MQm8R TuSK;{@~fABR|4,@̘wӮ] 253w۝_o=+nqz*Ӎ\Td%xW*T>G6ҲW(/yT.bu]c\in\f\VhV}dyNд-NܨKA6IK]5&-ɖbA#L)(IYRglO[2 ͳ7oSh[=št,ER<T#0L"0dY#E7BGb rQZ,l8$K+V&MYЅ2%mD~ly Wir!>+9>2ݪ0 . IP/E( !n66t7c-cvW5.BT;Ͼ6-/{9[Y!!, ;Ns[4ILIYNǔ`dTrqbhH)ܯJr`s>Zrwʨ7X+ZDwuQ\~mD22j suU_F;HTn* K[za HzKF UobZ#_FuDGI0f%ےL3$иA7&lttWTWŧF=cPWE|4f4TZ#1(F) @]L CB5txUƽ,񇄊-K>5Ղ9Ofξ9H>S?}吃iþV@ꟙOLP7J"=E[H{c,Wm!:yTf_E,K+*3nZ2xEܹx_ܚ V/=h*ZYH/p4(V#/Oc~{OU`7(o.˖*TgΗ$ i(͞#;lVF@Zyu5_a䗔ǰ1Aç U*1p M qY?Y(Ĥ|NJQFg`* :Pz-84Ut| Ml `=r2Ej&aT*1ZoLFXWVQ SaERyRkGt<+LMyV2uQ.ݯR+NlRo4bPYw J8 ҷ yoKNI>ޟ)Fl=ED*[j.ȜI @:/+mc4#Hi#=3jkP|{Ý?zg0eڶdΟgqrfȚW3bitB9֎#=DŽ_=5Al)9rC[IƵazFsBܹ>A˝չQLơ.}>E0[@̘nYS],Xk#kFQam;>҆y $:ZI˫dhDz:+BS\&K}᪒|kW/M @VkU/nS|:?f\J6`[{EN))(uvk~&o X͹_H e>U)-00`Tj@qhGA̡)a:=ch0h`!H 6|8oxIU:\:ٴ;?˯ޒZ:L7->EU 86(x@skeo<:#rb5 2}=A\ʽoujyj<׷zj^b0Z[?]׵! ~a?oQxfvbYЯھArcN uo}z׮N=ESH;̯ tcā U|}>jŊ 4>hBNQ#=IJ+P2;t &jI)>t+άkztA8P{F߽vy,g jt?:#PY6T݌{phCƄb]_݊16ûU?VځJaG0+ lN3N gp[O9VJ"q =]qPx@$'89cs}O, ^RxԄ?6T#;Z,BtQԩ$wmpܘ{Jy@VY`Hw PZؠ\tDBşPZ~VX? FOnb 7r՝{Tgט0(K$Cͫ!ho;Lb]n^ie J v>;y ~!ȸ^%]n >|/9e1{{@oO ӓn{΁.,U)+g{*[ٔޅO?nʣO6>pS6_L曂\ }5 |ܜ?ds0XUr."dAbl gywF /Yb֤ c9j^y;ӴFz6zM=U)Iͭl/lTr86Θz*qř)L]j˴v\(گr1*]0NCdRklWuy?鼞tgp"|ؕ^)7ۺ,Wj̰λu?m~.2ߐ`! S+qb$ý߭0/&MJߔU'e\NDpAC$RXc9ыQ* dl:(bbSH%+>xl{]&]I27\Mrsa2mtP2T@e'%N"QJdP9 6WͶހCP+y,:4("SomGRxHO'BCivuViR~O&-vm>dO޿^l+@U:KG7-7 6Ņw<e?w7xj*x a=ݯYu]x{c.xٞ EwxucR 1^.Q sKHǫ2d tREQNE1R7K4:#4/=_&M9`IJm4^ = }EyRrph;^iI>/ŢFy38lxN Ok>,nع/|j1BE׌Xq坺i_<I`n!7Dznu?G#{+˚??"4lwM#D0ٕF ~Zդp!I&4ΈTJLĕC%׵ubJEoJ#I|V<u~&&:1+pg4OߩS<=\\\8NN@I2Ј@g=>M]%OO$c~zd [,(56% ^:- E4{^h /~h~@`65# Fz:ѳ%vmJ :xÆ`*2ڍECKJ"b7tCCӬF)ĕiaܡG X b9(Je: zns S.:+(mk[xb@}a6ߒM#͡]XMJ C5j^GjDӺ8ʑ%z~ fE~=ڴpόHE*Ov*o5 xo BSRHb~<]gtFD O0TT5oPΗ :%3Ü*l6NJ Geem,bQ@3/(g)W_l__@8xrL^s`ˊB /2EKs?qVDa'-| IDAT:Օ"UD$q HޮN z'_okHrw~[0%:T^J>WVdX_M~LF̆)a9 7ʓJ1*Z(PXZ}aCPO6C^,q%r\+1DH@FIIwf2(a`VIE2j6 6Q"GZUvv,zg^D*ř$:VpK ~P_jw`vw;[nB4@%kZǻ,&\ٝIt]Nhf~Pcdʜ.H=wPW--Hy}@3 ztY`lv^Qnd`$ru]]$tL3-A (,C9Y+RݟԸ0gc@t+:/ 5aT[#i.$G͛.P{bGu2:񶶎iEM8!mVYXl{r._K dWy%/ni8胣ā gzT(l75Sԯ^9aN\i&=wOV%%$77wM b6 Mē?0{JrBdk[b=}B٫09ޔه2KۤM tc%EeL.qO~şV^j:mh^ݧF}U>ᝍpJF2!V/7 ?Gh Aӏk:ӛBRc`Vh"`@!lpjuOCO:kq36D~|tĝIKs>Nt_qC%b|$S/iiͺ¯$20?7Z*&c 0zKM Ҟz?t[ϤE%=w[57ؕĦySL:30^{X28KHfz:.$*)9𾅗ΟXyym%lw  ~y_@"WǬ{|BkH4HgC+?Uͩ]tžڶ_&e.W5!H=?Ծ8ט{ y zemP($RoE$J6 8ŝL.V^O eYs tL h[s3˃}@Dˠ^6Xub ЧumEg;n/Tُ"kDxn7 s>$[scWk*oAw-@ S6/[m>?g`gÜ8ha&r?'ya\~g$j›MV/L\&յdB򚌺N=C p8!`7޿;u+WؙUT)8p02ā-=a6tN"?N0{qkM?rb`wJ)Gʛ,`E^\oXfih54 ?8jق3bEgiթ sUB~pf8'gĉ}z@#RᬾYj'ojá]W c\AOd _*S*;5AȈd뢰(ՙBl6ՆB@,V[wc8 Ȑ-D& j:L^4ZSܮiI t#MrRrFN&B5nk"B3=ƚKAݰg{d~6ΝwB-vm'/씌phdX㷌KY'?RJf[uϗiGhuq5~wnSQ|m ԫ5' ;n)sl4Oh4fg'kU4cO/yޙcC5wvuBRnE]+R^m8Su,J-{~04/?BB.z 8>5 EQHNKXin2:p0&8rpL+cن]=PؼZڞyȅWJssvEǑZsPSϧ 콏d"kggV.[>z QSi#l޵.c)dH[y#K_!:YXԟYox❼*7;xzJ]2%iNbpLF 7/Xsz$ , j@8ɑsxo5R+>| tMSXۓG[ʺikwfJ[˳91)U-3#_1-d"\ hPtrdyBw:ݔa]rkyIkR׿zQ!s撘#B'S>ztGt$xo^B?IZ~}/VT1`>2mIfF$(l&ntC:D0HX;bO1APaX V? ~   "nCp/:ܦ]kOU;`V t<1AZPMaLt*QxT0݉ w. s#h4]PP4à1IӾ7 *'81׶kRmܧ]!/5uY 7vviK %9?L"n\ Od3+oՑHصs#{_AL^ɕ3}^޶)1A PEf^28J@a+_eu,N'l}wd3JƤ!!C8s_ԩu7c;2 3(2ā;䰙߽e8nÿ=鋇g;!KkgK*_Io8CKFaK UP,0V EPbC&R}ȄL^CA.I+gŧﻘ_X9'$)T*h7tFx~ q[\ eŕBqaxsYQe=СMm6Rc+4˷fAoו{,! ފY.22, f1D"N$"7$X"tP HnU~"N~'VsJS&մp_c@̨ M2ftjDz8,ϳ{c (} 2!_ꆭyhZwwޖʎv֖>״ǥWe;:%w  MpE$rGkFV{::]dZ#˹FX+mi{$3' #?r-g7 pwYID̢K %K?ݯNhIVe/q#1LNaz^T({Ux7RkS/! نۍ62 tW*Ċf SƠGZgp΀Iɯ9u,+H 21 L1 E ?.^ F5)ЍYPėʨ#@ +V0g29Q}U>4#_p 66 q@Xzeح;HZ[XQ)Me(dX fd?kv*znۏ,}1>^+[skpm=ŹeEz}I[e[ 3/,n{- X/&lnh}W 9@8D$??Eg:PH$Iۻ8~2=ǡq)K}|\NTwJ@TRZbr8A1&x?ȒIe\jj_H E% :sb_Fv=in]*-;qȲdO' k;TǍD E2* rqƇA`I'JZ $[qn "FaD A8tY0ɂY4`X 72@@`h  Cȯ`L![TZS)8U-93#ZTZ>p- @ZwP~aa?' dKG @d"*ɊӢ&r7Tdzs䋊IW@z*[IrwyjD#נO}]"e`V *enIraу$35ɥF汃?]n窖myhwB]̌H@AUlY&Ӣ`&n>,n;sBW[u,\*3|+do]LS<#q` LؼyK$rzMbhw8Z(xnqX5|٤ LcIblD;A&ztU_>1ɒVyeyW+babb6 d\(xfӼz [>Gz*|z;F:N/T@z&ߎ׊,SV/C-X?@%2l ,Ff,2BaԊ!f t 2cFG3ƞNWDEݾjk@`NLsĥjۉoXr$B/6=*zvQ̍q"Q6]uv_oQڭOF.K!ғnf^ q\!RڞUU1ܸ<~ݘ\hj#Y'^ZZe7)rVqەyUI]1!yJf"wSNK.ma4Ɔxnvѫez5&>AF=E]47f >_ܺ }KY+e&[a  1ttRqÌ]V2g25Y@PŊhD[ R~* RdJ(T휤HsvfzQ+<^,I2RZ:g8ApN@vn;^>(7ӥ&W#f*V'Me5 ,%-#^XO qmT;5;r[sz PYU5Wl(0^;]а-;=/֬J_:5[sR^ѳﻠ VաxƸ́8 i _T/V W~;|rej3X3)osR|}t><~:7>oz9_T$Rv"i+M%r,&q燇3vjyAoNaapD.1=Ʌ#Lz m&3PyBl-okwngM#˝7Uc6Toez1ClnR0 t.1[0`ӈنѩ$[tP.BG+J~;gBxc DN+^hQh3\4g?9Н bUkb+)ԅZy|P h*lY?wǍnXM?\?,0j̐Qӹ_xo!Vmjy\'uCQ־գʂhRBrǠs[;Kw_ĊYSvͭl {s&^/uspA5b|RqMG|y*ϚM]}zVbL_EIE&SxG_Y D̆͌&uWA&VNFMf81ȀC~ @$!0þjX%=o& FxAS>F.;Q"q;tB؁SoW7XlLp!1=O5 i9}x>(Zsݴ&qY^9Rc)A3Bn) RWlRUP%jqaO?Ɠ7 ﭒ ]Lҝ'KMS>[/6}LuQId|m nb ijYYx)ȯnϾQVqyߴɔl8C8Ɖ^+X4,DdΗT?+${3sgv kxn*%Gk4t&Ya ߞ6-:6'}R'lv'~uryq}W+QX4*VȪ?ٰ?cMƚW43[AWyLKSiY%Rf5v5 9S(m7 s,/@V+qP\@RP܂#L.+N ]Πnzz3 8"X;C20R~ -@#r!ιJ;Mm,(eh//xU:Ng5"}TzyV QuY*43>4;~/nl.6 <9 p uYvC/QMU?^Wyҷad9,W*_`@enS# “}嶋_Tr[9<`lj~[E]s^xmѯr+޽Ksr@8B}ܧII  gF;wbԛWMyM}]}-xޮÞ9QRk>}dسէd&|ȪQW@с^_MMAf^o-^k/i<|(3%6dn+AvMxlȮyR(2BÞj`b0hk`8hS}<}N S @pbnRq2\7Zmlp nt;( -=>Ţ99ι4/: -"<@kid9Ðy =BiO8̡^>GANY}yxzDt'wh /5.xd1Ŏ ;9Y4O2B@Vr`3Y쓌KqoѴ[@%#[*u1)puY?s*Uޟߪz,Ƽ[Զ^nÁ;#q`l y{twz-libo/ MߔZۓqw-\)YDqTT^;j5YI wev,v5 ?W<Ý Y>=nŞ 59/yrQ+gwf|!LF"AgܪSƛ4\UWތ ޽^hm2K, GCC%PYo<)DV/7KwI]Z%FUTw!PQ`1=fхiDpQZsf"xOp d@($oCK_7%$~L&p(9WBbr: \:sfhD]oԁfѾV"JLp[+"euj%ѝ xo/o?U$}nS$ozKv\OO/rkrP¢83+FY\l}O8Ñm d3EF]#ޝ ߟDH;Mg(uoGM~mQnLCеi~}5_Cwxm-5vq<apԪTkU]O0LfL 3tEa6 m`5p܆ct Q6,*c=7  a8Ԇ8jA 7FFQp&S=o\ejSDc{rh)Y/ZqAmBڰ:؅L J}5ϙ a찌6ip}aAx+ߌ4V7'ZoRp-MlFkF]HǓǓѾf( bCIOsl1cs;×.?PR pY-|o~y1w82 MKOYL$ "PPhtw 5Ю.<4'22ۏ^csC RܪD&3kq_fYw{0 xu9:= 2t2!ͅJ8[lxʦd':xO@ׅ( (jP2 >nwť^+^МH4F l.6;1@c[^m.ikoT5? ϗ Ն+N͠|(h{zeFUЩחh{}Rk˷xZ|@Ls}׵|b|x[ρ#pGā糦od19Ú>qb@c4T7w΁I uVd.7ϚyoO_sIJ?s+6'pN5wW_*שMiG_k $t~;ޣV>xyoÛIJ`X6̬XtfƠK݅;ú38޽=?o N$pcX$J8*зA_ >`@jg[~7 'm\R(o[ > [w-h/@LV/’oJHtnܗˑ G I{Pe]VQc¶0b} ݇*WX! '*5`yBܳ'+Kb EB~Ą5s~۶yc_:PuB.<%%%mRP/7ͭj|)!zpv$C܅NS H L }.hII^AK:7X+RJ'ͬQO-#es0 $2IAsO|mjPC8O?H4ӬbLu"T"bХ6>4 -m =,AEI^!r/bowdNU(oگ5*<Ѥ`{ 7Ɋd;w!BYi^ۓ|]y6bi݅w [ލ9:p`|pd@8}TNDcˋ&SFCZ.W5nvv F:="엩^<[7p~].?9j=khVa&$lU5fdԉ_=b^DVP/S">zf @@dv%3tɮֿ9Aa~T3Jn󰨪[wUoٮxc۽Kȫj&"aBlOTi*2}@"1HtR&͙6  8(a]z_a8TtKhw`B&hwdWC: 5%YasX;FFsoi[;q[f}?^xSœ. _>z)jS|,RVu+>88pp$>{7MIv‚=ѐ+񩳲xkNv֤͆NVKY犪z~.zfO/ɫvf<'&>;tAN{/µ?ώ]8ܚA@zEU<'`ۺq4ϼM ,SC~Ary)͋LF ݲnm@H?y !;M S(ߧ̌~sp߱Z'C]ٍLpe3A 5,2/Ȇ<ˆUtj j™j u=N{.hy~Ҕ.ʊ[ )A#@^$x !ﳵRz}U};Jzo $^L1ibonek[׶vͦh^H@B'>HHB'9Dy8L6g0_EHc&E՗"'B E1N7k9dpxI<=v3(En7r84Ͱ~5H,قu54H|?OOgUwW4* ~@4j13'v/gc}}n8g5/+ٔsR]V8olҘO,-w?6EJR{3?kG7*'&D[ؐyrOSD|X gMr9p3 ~:V~X`{?nйkڵgS@|r贈h1/gKsѼι(=w=eQy_)$ޓ3#6%  Py¢><, ŰAQ[v;RTd5.@A*(@A\HBb}4Ep|ˉqAfܩ1 iE뎝ؼlbҭEÂS+ N~yܺlDy]=?#fq\@~KZy}GI {~nZ(|q۬JD*.R?AҔT͉'I伒jcbK'Q1o8W @nUbu&.R, q39;q/Xtn,aXp94XuМ '!MU8~R9+ b Mx?}YR֖hܨ K~}AONWhټ&UVI+=!.ogV>g |PQxMK7-:OS߼W<ۏ8zTaS{^ՆEwfH7e;M;,˰,*5'FTDr5t\yyl{ar"G9O'4`)C.7.X aiEz5`JBQQI'/ bx FuT ]۲oo7UplCQB.n F=irGNK ~MɅs@>|yƢ 9oRPqʞ[ ˔WaA*EQ4[PZ̦Ah)f _] 2٤V9ۋ O.)]H ;^,W= j2jS <bq@Q͸֦;Bfz.< w Mi Xp8uW9 X}`BP  ^$!LM7/#'Z}L؆bJ\Կ^nwkۣY)W!fYuS one;9\t]hkKZݖrӫL4^]O<_N7ߩ~ٙ۬;|ձc'oc_Jܑ.(kgPkZHg*k[M}MW5j;;.\}os8X;.o/p\.\ >ӝpif/E,p;ۯ~݂u*@H*aA\HB?n_qP,2wk֍tlCTNRΘF IDAT@͓˷^2!uƞ '=6IKv]ϣGaZ8tzω&'D>1-%B}q}ӫ٩ixd[FD &EhP|=)yvsarT#%35`Xj}Ip *֡~1+,:;p!],:/AV B>v. ˡ\ g V9ۓ sl:{58˺\ "zA\HB}E 5:^ 4yNU# 3C>u1?5YhI˷(>&-9ީsgtu5s6N {wJJMۋ,Ns|CMmSΓyaxyuXvo9;њ{qB"\),Sᚓ9_X1|w ZTw^D3X! 4&@݌_g,:;b>.mu ( K;\ B@v2Ugs M9NPPxi o!cwR.7/.v3,t {ە'E.7L!R#@aA\HB=bC']?u_4#f W &5"dΣgx{ۦMRX-Q7]5=cΓ?,4#-snL}#9ɉTNE?'[tGQU$Oύ5؜UU5V%OSq_Jz~ek*h'G0:"\USvz~Ypo, T;K8}±c"CgC5'[r0hmvq4d dz] y\7C; <r3p( ݇Yr(X7뙿&rNjdAİ# A]>>?Z v |mS7"3zEDqu]j$'Y=r!bChZuYknMx a}ZWEq޴ AץEzkPwu]P ŌAs)q2BjwA,qlD^\@P ˂ϥih( `,84P`]gH/{d2 bؑy{{V$݇dmUE63)g/]?_}Gs7rRf +xm2S{*T?߽?owe56< J }9k4ZҪ5:ƒokw7޴Eߔ_$WA?3=2һG&# I@xajϟ>|{/n_XzjUplCr.ykۮ;OV(,66nζMפ%jhp'}ac1a^4)%hGvFX=6*gW-HS^nkAvYxS-'"<g'".ފBFE"7Q[zer}Xo܏@$( Y;<2p;~ZNo=btٜN y@鞎4н^).3 /xd2 bqG:AE)xΉB>/~M_8±ɴ.7t.jAj|ܱTUp9ųSnC낕޷M࿼f=?RcC}օ^vGᡂʿhjKI};~v傱@Gٙq(t6,Xlm+hj{1xyyE$cOv?M5|ό>պZ L u3I[ 3ҾX'"œk~R!vK #six< }va)H)^ Y!VQ >{RX~7VRĄpj;\(O֨xy^۸剗_6Ɓz~as>`o6aYc==Q$So RDV1˰ԩc)rg僓$5ԾRa. kUm}߾3E7Kkʽ0ܛ.bw1n}{x V@@" 2E4=9OmIe5{?񳑎<$)fӶ{fOYTڞS'^͓#o%-ݯ ˥䔘7zoّUPH$ ^az:l(Tcc+0SGOW(vZLQJktpK,PY l U(R95jYr MD.LV'# `!-pr4Ų, ˂F돔Vcc5ۊ o:QɊ/65-ZӉo6vr{_Y;/2/cَm O`&F~b'6Sґ#(@=GVO.9.~ h/ɣ+¦/6~ oza٨a- ~_YE%VaϥD<. *|y0 4Ű6dz:,!tHDxlB bؐ|ϫ)V}-^=ұ](Ut6<պ|7ግ ̪]?%rOAs3Rq =?0ytԇ̝~߉Z}ADbO%=Kj?dv4mv)v-HI O"T1>iQ\kʔ(nH-F tc5ja82YUol|C"rewA"bwb!v'x 8p>AT ڳ[%Q\>cAÆ$ U#5*d#g=dBLVKo.mEx"ou OH ],,~踗^qz~V^jgPiao4sKݓWjUdiΘ8S$ Ώ{ Zٯۮi>ؓͩno?_c3itJD{L/޶-GZt^\SYf^, j<6\Of2 O fX,v'+`sYa9t{F4aYCS(!c=6!A1lHB\FGϸgw39n7xmE+}8y0bje^ߖczkg^c 519_Pa"CVpq4EյۊWƅ@g2F\ȁ KF@:&}9敏L[mSMG2O57k}7'sj}aHaCw vbL8Pмs'ܐ;ݬHa|^ s,r94X! @؄Aİ! q G-3Ǘ <Ʋ7Џpx-sxZi .74XճP4Mr܃ϋ A+\79u[w_W7loUPvFo.ӧ-Gj:cP(a7L_[Qg,iykrRk/ܼ(^_3;q/,U{'YH+llU|_ۂFG?\ZyRM^3G5햓}j ; Tw)?~89aH"ۯ, + ) ZCW' >{ v/en\8\npz:˰,@d}&)!f}7Sc-[shҜΛP( \כY ]@w\DIS\]L#co鑟o;yP( Y:)mErАW:&=&goX0W]} Ju8> UulYVy fgEC7縵)5U3,suoJW9;Pi5n_ IL_˲P:/|p479]nV(t]-&݉$Cf=a/LA\\$!Tc;Uu~ˡWNT{dEB9&!>bd X'rG2+T&'FݗSˣ}UbQ98zpbi~:\ZZ^w,zxu֬Mwx]e.[&o79w?H&HWVj5ybΡqW@=g9d sr3  e)p'x4IR<9'Aqᆿ%A\c매i0ir?.D3Ǎ';:#%9S]FZ3%5t&|nV=ש5l/5&䕴pvjmQLo"n>ɪ}&$DU O=}}g %+*RZ9nrݑ<紌I!!^:u-g_>--iw.\oS?wJB۹=^N5'YH{VBtG_/J n>vJvsC Һὺ9Bws$9My:HbqRtɝ! FuTvKw=~9ZVHt4{CZcNLX{]o2ۺ6谐-MM.(%{y- _@}sմt?ي utt]06yUc5h/WܥjZ^>E2\gzv;k+~QVXٮ 9|;i._s㛂o~:^d⅕GV? 7KU  n,wݙð(fM'á)z6"7L<9/AqaHB\r?)QX,‘e5˵%NwXT-DbҘkd"֜"X>hM>&iiaΏ3 ; +ZŤIn{%JԻ3&%G3#ȱQaJӅfR.$r1Wgnћ .]fp(X=" .7d"(8+[n首B?5Y]eᬩ8r2Iܘ_\r,&AV/6]YƧ`JJke(ۚmYe5o@F|;M͞,ƻǞ=jUiގPu i;33;\欱 _bW䲉iKaM{)̛2طL+G%Vy[{= >tyic6DHkԮ5}Bg)ai\>UYs6?a/Jm]F8vralm( \.PAZlhN;Z\u;Tcj\M)ψÿwԵ[`/̫:9Z;0kpݫ[EA?I)qO&|ެ)ʠm:./Oq87,LK_^Өh>z~Tm7O]>'aYu S}rc[v P|wފozhZC e^/-_휞KáK{Lkt$,ȣ",à]3x@ GԸzvӁ݋ŜDTa Qf\ɱx:%2A 8W7iJV״9q4dښ_Q3[ݨz0WQbTzsWάҚVM`L ӧ <=QglrDm.=iѶG:ƠY,ȮiMK館a*5; fըvJ:XWE>]~b=a!Te:&M  I<NNt[H -%Yj,D*yyzz^ \7];}rZʐ[\Fs{ÌFc'ddqmOR:>4Sʭ'WnQq`q5+>aZ}}x@}fU?z]9&e"Xy_xߗNsfт˲3m-Iٵ:ՂZV ʀs IDATI4E]] ٝSZWPB1ScF Sl,H8>><=/AqreX-_VTylR|P~(7suk#Hwu}H.;\[2O= bßzcqyf8'G'q,wWfXp~u6.KEo;ĥI,&=\\d_^@w\!( OSX X]Р%#u涝wu{=(H$XKA# qRj?tKtzMu3#HlM pvO ^qQ[tjU𙓖x{Bh :LfT71iè7G6e74: ǽ煱?=76,0Uk;6@5/72 -)~kEֽ5%,@\J2 5lƌWlwIHus;Ӡ+(dG*kڮ|Oa.'-X?/% قE\4;QXr]nxF,eM 17wQq?b~J VKVu3)7ο5ËnRo/lIQɴُHu&F[0.s"n |EAձMmmCy ?}ZB\`фVГsL9àdaMEE[aGV C΀L.wmԢ|c<ӧXG&RA|ݖ]_^}3 ђK)|tF3 +U{pJ:WZ]tGkJ 'Dio>ZTw^ iBe&|^`^7ˢfC͆fš1[]]&f;:Gn/6Ng#V#BA I@E=:~=յv׵r<Ԑʛ?d麺>c//~R-^X-7;Twl@Q|g0_{rw_vNrNj lsvxo S7)oh)`\P_Y$ʚf6;'.e08npYMNr۝fw3Ve3v,.pnJVUAÈ$ qg܌ρ-'raR9 x!MC^^gZ`c]؜[`aYPpeʃ vg[}VԡgEA\0צteo[FnqPh8ӕ`[C_UT}f,^ղ  \muӚZv{P.LU*_Y&5,'::r;&K]M&ےYh(Rq-TVWkQjhK* O zN |i|fQw[z-GKk<'MaYz}')Z?Z$f#OA'ĕiZ͜9ۊMMok\Tj-b#XDUw\rY@2uC|Wc5,Remed@,wY?Нk<*5$xфHIC#.HOOW~R{IBqy U8=):Y^ѣyplÛw-׷+Z_!g7;v#eoeXŠD#v4VW2) 7}?zJ}PBH%J 5uz>OSEE " I/ I@8mth}͙1[5Af`3x*ٰ@9҂J7}/ O N8:e=ʼqIYf{~饓|NSw󑢆Һ*Oǫ i qNb8Ѥ[@4ҁAF zĬ!ꅟff敷x;0,ٓQ1ӓΒ(n w|2&)ۤiF,3o}@`awZ2 ,57MLFkTeC} $ S@Ѩ<jb::iׄ36,@HEAI@ k3rl>r_pbMCwop@o3eq f=1.Ylq#w#crљ? ?ZGS7 餙IJ7àYwu@4Ů)tG+RF:. HBxJH5ߟ3 ?طy@cFŏʀzuI^n.fڳ7"wpT2m4P{0k y3^lQ_l>>WV?CpJJbHY`L׸3^O6W6Ba4EHyusc{gHp0z?ar__︑ I@9^[wWy%6 '0v@rrBESGfsrhV*ڴ]ʘQOL/k 9pb+:6Y>r~ W 6p:,}Ǐt\A#ADٺG~v.mWY{<~+Kރ]:M> 7P6-!6ZFr"3vY;)$"AHEA $ qO*U6#ɭ8?;x*#tv\FE`ݮ:^ʠfBͺK\EgK 1XEWe1bw)swQ-.4ZmtG"l:]n)JI)^ KI@*PTz[lgըTڗ0xbȩYsPU6+[oB!ۨ;SRRnjm8W얮oC59Y`s(/=q`,Y̲*GUs뮑jbOi;MR,21Bq#g@ SR "//?> >fLnh@?H.p^@"&D^||1dyie׷:22NYamJNIJi^MܮGMvޔRi8.RkF*Em< RD(}}6"NOO3&KyN# u6RنdH$TQ_ӵA,8xꌻ NK+83  ]3auݽ@zD*}eF:6 b`d A\=x{DԼ fsRVQƖMj5!PU3OF*}eלsi[^^ҙz֮ModQ|藭{'F5hBÆVlv{VB-v#MQkIA~B0jAqn  D^^~ D0@OņńNsKzts+e(ҟ3 Nը?hڕe9f/Z{^מj16Duqn]^ɿ#>>) un+mjl_I5}8GbbXw.sͅZqaQqPV|8}ᵷUghokV q=bf`9U7bۯcugyO?!A@J[:gƧdDTŰ,*겺J/Vgƍ.aD`06ITR^{Qsk͍uln K4#Y LL)ƪI=NTZ*3u )Q $(Н\dA@HBDor2FGK%>TMs' AX_U.jb&/Z(ryJLIv8'[rJEUin &GӐ D`18A~Kdá\lJ&޵yqZ\[ 6N\l.C,:|>i#A?q Iu^[>>qcL qCYۯU b3?Iʑ I@`A ^z4l}787n$ɖSUh~WCJA\ .lwd:tFssYߙuhϒ䖚JVcU]G\:L)Kq" AѠҬjPi~r8Q[s+mͯ4VULaָi 4V7Rv|"fAo@&G@>bA"[.흦qPWZ4ؘ/|8#.oC Ara#A1qI ^s @B".a Mņʢ~#A10q 96nouF3jT# 䩪Um@$}" F .)SG<~lbBNU4 kP@B{{ּީLf(O(3s ݝ-šDyֺ3=&L|1-#m( @A^֝#OMM2Q<.O~<<\l[{m (0 P*ٳnݚû'{}~ŭ,//\^ :T*W S@3hWNbhtj.5F[S@uom~ז5_+:rԇW~\] ( @Zoך?Bᝓ}@>Q@j:ؽ}c;L|?_(N3sҹ>BPB DjOG׼s}/)E*93\ɪ{6VVnXsR@TUm=_vݓl>2Q39qӮE 2ۚI$n{'= 1EjhlUtԅx'LZHu/'S]ͱM?;%Ʊ疖_0*E`1\PByc†PRsw7D[P@ZOΣ-M!4E153ȮΦخ&/a`صk߷ev~sC_ڛ6׉BSQxgP_ss}hpxȫgvBձwf=?#גɗo/MO_IL* M*a,n, UVWCz>ǟ|op(r#cSU^( 76meRI[sIDATo󑉒seD zmu] B򦡶gѾ󑉒Osvkbk 7c_V}gʊUwWVBr:aD)s@RB! ?7R@|K$^K$^<;pkhܳoϮMaph$NuPWz! [ZkƓi b #.<7p񹆺CٹGJ.mme['oD /( @!\<:ˣ!`X$5xu!*7~~P U3ЁBc!_Iz6sv431(  $o&5\H$&}ݽA(iUb7]jǣhn}! '!)L zi JJ&gS=k¿q]`Wi:446Y,}|H<&l)Ea 0o//.~b>Ǧ)@v{IXZvm?Z+Ї8(ɒr(ٜLgsLC@h @h,@Q#B΍lX^~C!J"#RdVToپ)AQu>$o|TcwaB^ёd :LIٌBE\βWI%y.NbyQ>p"DNQE!Ki6|^%^c=޲[Y]W\\rG7 ?p`hc3zlb<Q$)Dfhb<*֠T\@,mcilbd/kWYYe&Ӎ<|H:h2Tvx"L־ezfR/ M14E GǺO32Y~ݍ$|H4DI6j-Pb@m-5CZGYQI' ( S!Ϝjlnm^hfŇs<\p9Z'wԨv%Ҿ}͝(I$+ Ca?韈ω*W!imkJK {CIL8axvݼޛWœ֞P0 B$ BQ`Z:/޼uGSEUq}} 7whVuy@nXyJ85G5nQL&z7!=qãm7m8F tZI{F()9i j47MLc3:75Fύwtu7߲Sx_C~pHStF!kqvbMMv>h02)0S4>t7n6?9V7} SWl,Z_Yevw.fi3ޛOpVi*KEbS4 ZB8I2ٿgfbYVl(܇D&pV}qgDVizx@jw>v)p6gU"k|"9aMoug|H.dBz?GwH*((mڰPD)(ѫxXk[yM.j.VXlzeun>_j u6IYfois}5kko0|H(+,euIł*kT&js[ujs6+5gk EcO[n'>$4Mi5WEQ$@UۿV2q_OgeN2Uӥ%7z$;Wy7%wb$dY$֪y1H̙U~Se,J瓊:{Cw|0@B'|U%WUP䙨Je(_n<{?ixdM&q%&scNj̥;\&|AU?bЩ4.5\vs9ZЪ͒,FZV&"toêydH}%,G_eiT6V’8Ufo0 ШӪC^LfxFE!3dc*vϮ+‡$`"W%#tbUvLdf(}lew*Vf)|ڬ\4UV5VPW4?c*WsHa/>Ajf,Vyfæwcc٦qTήTmXiC~0?)]2 )yERaI&KMVǘ:^IC cL4ںmkQtQxF_LYceܑΌӴ&tj*T:BZĒ)xtת'`lήs]nobP }jM&ţzᾏ8w]|H\|H~)cDSgYVezWK^B Kg-,B2 Pz֗mSuGO[&C#:JUeV1~}JBEQ|epA[OCxo(3ΖI€#@ L\͝OII hXF(uJ&YV6\fEL.>،l(2^L6!:MyWd\hz\,K^WцMZ퇍>%F~畟g;յuW HbX&.)M^L1oS%MVHNr"*D!!xWCPp$I52N+@a_맃\Hy8lp5UwP/q]WiE!DΗL"Ɏ'bm*q,n]`zǢwՖ +5#'=`IFvv;߃,lߔbkBqX08u$hdnpvʳcʤ"EL6Mީs#yf"퍵׽S<x׃%p_ۡtF]{s"J&ײ@5;{WgFp20 k}j}S}kMx`ںU{6(IҙCy`ˬOozW]-Sčw!akK_\ٟlvz]w1[m1B϶6|jm|6,Mv*g~_t]=%Fjlj@BEM&j=3s䥗;eOu?srkqXz-+IhZ0śL}hf`:gɡkliE5URH䪪;n62ם3N{c̵Дo8s^r@e)TnU?SSi++|ĢΣKN!5Ŏ 9xŧBw'TեD?=żf#6LaT@`*;S\4-4 ?o;:7np8?QK^_i}L7ON4V}XKMn&{ϗ[W/O,?S]#`g9A=}6u`A[2C*DUjL%<3;Mk$Ы/ %([Thnhj \9gt֦&e?iSi)zt88Ҋ; ξwx o" QAVY!JE_pXy=C%ޡqgn޼v9ŷY׿[;'Ihm}m:,@d31R}{~\|ec] Er_ˁky%W @g{>ٷhMj'O77AhlZk0==s_1 FcD!mI]zA!K,R%pbLegDF04%n<ǚ zB##~@H",m=}d|ZNf{7Wh2aFctlsO?%ܜoLO]Dv'>:8>.^!fٻ\_ygj *Ֆ JٟMrI< ML?|ϭ\͠}yBHS1gloB9IldEn??|pKwNYZ[l/Os{ # !S轘Q,m^zuK(7^;:9HR~~;u߈e,P>wpKPz˚B*( !@,Fj>Oc36۱?m뷮]TSkm87X,Np&s<*ꆆwN9Xkߔwſ}N]75}_4 zXx#@hq=e)kv~O BԈb@#AOIG}Pg𪪲?zHG!D!8j iA!: r+xFH ǚ V_F}$:3(Z4_%e*JlߥRhWke-2[m9qXIIvM.x,618X/g@cwhL$4Л޽;7nV]h ÑvND@X,K@J SFfpy98B3$<R< @H D!:qs$KAh Tʣ!25;m.J"KY>sEj _O-&SNae Z V ,˺^87:Yyo񼽨h<)[f,E*v[UZN.w4mof2DD6۠g%zNX`/ge,@"\.\걳h`;kZ*ک[T*s z*8&P^ *'d@.<2+IL4Y\^]~=u6-uI,h W~,M9t~tkOoySZnZ1EٴܙHFtyk,y*+G!FC-EvݷzwMF#v%Baٮ3x\ׇ` ;;/ /xkhBM9`xT~"??I}_S/^scG'O^|#е kÿ{J˪zx_ɇQ]g( Sg[je\.7>6feɤ!E€0 :=d\!@sƅ U{vUhoLkOɉO?fuz cF[\]?=1>IfbnGiWId:=71a8z(T^:vNP dNg97CC!sap8:n]NE\Z3OE ! 4iɗ4ÓO|{9c:'%bܷGOT[KA~hVן<7ǟb3W@BxfӧNSt''xO=/}3Tz0Ac=_KZ횝;Gߒ=Py#W_-аf}ΑuF5!Iҥ.!3|AJRXOd^Cd1_m*) +( z.|CkaEQB( X2qMQ*/v9Ʀ:F64\eEPmʓQ ˅H4h>;_Gzd⫏6;O<Rǃ@nz(_/r>O}A/ek7ᄏ;z;juu7߬ھi6<`}ɷϲoܾᎻph՗LJ]o荦$ P.Qsk/T%~a03J> =^ )P̙=K<C8bCjBET ocgri)FRݱs'k_}zV<ѻKrDjזvvH,P =ZP[o>DKܺ}7h;$m۶a[[[_} rZ*龑Ҡ_{ò,Zu=X_ZTvbm;8=--sUg4O[,zL*u'>ۼr$~x]$/BKɩ鼜在"/pRR, Q $ |p}evL2PEiČAx=:<;\%6/ $bࡗJy+-Ĝ|&=˫\.--ɉD']fÈ6jR t6 A4N&#P81It,Nƨ?*b-oPQ֛);٥3@]6iIJ۽7i|mRhilv%0Dg qTd\X@vqzLL>|]MMUWwV[^Dn^R.H5xݎC'Vsuy閵Mlӭ[5ۮD*UWQjd 0/9]N(**ڵk]U+w [[D"qrxPYwmPedkEэ״arlq-7d$D8۶mm,*25GCZ\;_jl:oo糼+X>*#KXO{?Oɓӹڌ=P/}qUEyټ544ڤ0]s@(+d B㠌eUY˕4M J:(V鉔# E z"f"S*-Dit!C!Y-db(zY`|x͌?8Cl߻^\%ei`B3SHo9_RS/*b5fvgѕOӴIqܩk`%c3E45%~%@&XoQeSx4vƊJZ]=2TOZwvu}Ԟ*/; ȃiPg Qre!AQ"f"("f,E!4!"D$!DwKŅ{DfݲᶨRٗ b$#B:RI!T)@@|Rm s@dg \hI$ lriHEA:8OO2}a{Y0%ZSj#:j &!7e\ϙ#n")rx<)?{l^(tn\){Iht0f(&umiqMfr޺:FxcN|БF#90g~kBzFEuw6Dq 7o1ۖWN‹@!e*P6h>?> E-Ot!(+H 17K/" JZ11Wc:zPRc4[0Ey+*D__5s鬳zֶs-0:oST< u/FR[<(J;z~Mj7.eYȎ6o݋b.O!bDr,~p 9%DSACCs.M!.V Y7._%BM50j F$ŀgx'+ ,f)÷=~167(;:uӖ $pN J9kߞi\soH''xZou󼧴"#-'ҩd.a91FGyIz侮aJ8t(PR]<=+NM T[/8==~lO-N%,*$#5FjRV*fCtv3 3qK!u[-ᚐ"PiVI ظ?Lic$0RT"[:aٺKz 9U$59߶>"PNpFM]*éAoo~#9³lM(m";4'^|W/VWUQYUsGOOP[ߥ\VMZt~4`-)Oᖎ\^y&'wN̅"{n}'oX;x]kw !BȬfx`^EOW^|*3uzn+vgPɩ/<99:mu떏YU;+J;Ԃ/t7E`_O7VkYpKdYY : #RchL{]1hJ[H|o׭ct! @YJ҇`XYPfaSk66+fwBնUsSŵ,-`ZeeE$1L<"+$әm׼P8vG_݆+!aIiB`~YxjUӶ| NTwg;!M7ݼއrs?)B$IHQM7\? ̍jx1fV H)2L%,d|f9=oT8jKvw><$Q E!DV`y=,n g$OoZgW*>#HӀSgO~c4 8`$j2ebkc&^լfFK陹ud6|%i}{??f&A]QōNN+b+4`*j!Bmد0LE]T8f"sD]\J3h2ȓ?z<ѥhfdV0btA#ɪxZ/&[f%Zm0bjB7.~5mgG#1dѹ͝Mi3>SQgq}C ,mlU,^{OE9&+ҙ@ZR0Vs4h|i";]s<#3~uUɕdӲ U6j^~Ƨ^wo5WU wܚJg?-I4XJgع-S7!.e(M,k^8fiFFzEb)šKd9)NFSDF75Z;;~4Y]_ynus.s ,foRg$yi4)O3s~Y g\ FNsMN2y*:4jCkE $anUT<;LIf ҅y Y_Ľeo"dDeO״oo\A`MjB(6 M#ޱ68 l27mro~zwԫJݐmXUXFbP00JJ2H855j/-睞"8ɜ;y(Ep8]W6,ڜnZocSt36}>hk[O9ZҤeˍGh&fƒ9kQqVpToZu[,Ik'eWS{6<;[Pz 02\7AZE׮7Y18kK!pG !}u8ƬfѢj',hPġ9ТUJEPAIHE \)$ tRQH!t1HG!XZgaXX֙F5;|LUe‚<EM梲jrbj=MZm]C!fG;;o !`& h:9T8 f12- /Z[o]:b,z2B|edEy{qtZӈ&mSXIr XW^sY$V$ B*-}=.oK2)#ZMCAζ^5Žu'mZ~=?^ccXInmEg?=VW״ m?]o)@U𖕰s\:&0Aux-v$MtwpqdtU*8obzٜ()Jy̯*H*Ⱦmhѳ͍ݦ[$SNlWAAK**Y 9PxHNCS-jhøҮ$yQƿs|Ww鋬^+s}NYBs~B0e6oU^*ݺCJ::t֎SVcP47V[~s*GFt`6oarg~)-6y;r&12=&YL% Úhw 3}zy>JM%` !4Fj1v^[\imX&3="h`3-.񽨈)b63=Zi 2>sG&3̌mn6B^ 5]':~l^eo%VKi ۄO W*'S_Bև쨣9f%)NSdej s3!XU(& (IIQ&P"{z4S\VisGJk0.szBF:*tj:9h`(ښSfY fg&}*JSeZ#m[{)L[ywo0kVSfG(4EJ-]6UV~;1"ҥܪ2Q0:WơR_|~Fu;,5t\fm1&2lm;`zlt; ԭape,CZ,>Mk7\YX-754f-jW2[*ކΥ⬢D%v/ψ񱉁 ]N[(*0N&RYj/ F~X̭kk@ff$tFMu,Ԍq,3%z/thnJhs1#rr{z!kjU-621 K)b3)Y4狝ݓnR?hb{-q(өD(I)ss_k XY d9r|z{i%B(̜>jj," C cWS_Åif#1T麴%xHRTE-0M@jgQ~tl$4 NPNOyuxWɉqDT^k?m2U! 3:WLaHfS"z+p̣ ^ cI:&[z5\*N L֊*ALi(D@8z~L5v_aHcqy/JՃOt&m=HU4b%ՉIRa+D<>{SS[H}.%w\Z4(S5 .`d:12z1~訅K\ߨNjEw鵶'>նZ])7C]MjįB͹aP l\g lee1|mXfu Wx0a`n=yR9rDV#Jۭ┍/R1Zn\vMQaUg?;V_c\^mݿɶwL^T^swNT dO6;LucHZaWH`Jj!=T鶀Xf 4Z+lmwS4-)VWv]!*GuqP() B,$/v0!_/WP3 / Y% E6@_NhtV|vcr#U}맶6lԘAQUQU[RFB幹@A%E&S^ѨZ(Rt{j'&_4@]Q-l d|s4NMƼ7 h__XWVhG[6*UGO՗Vi}S3)_5Ņhh[}}f-e4QΙd0T\ɡ(H7?y'>97S񉬲ߢh!4zT$ni'EP v92)P٨TXCITCg3iE-nA5]IѢj CffѹZLӑiө[R uM~^i(]W} =겪:^0uhV`陙͟;לΰ8y~/Ĕ(ԜCcM2CfQX3Ϩڪh\jLǚ*h|q"1cZƀrT[kƬ_Ӡsvu]j܍kiOHC'X Lr]+D~s.BMȘߊbOQ41:slvz{mҼ$$EHY腶D֊x*vEUűr_]+` ( `( 0B* `M:j7U=ts}+0_jk!,0ڼJ Lrr$ M͌$qVh}f܏O *3ڋ,hZ\xwyE=*ZWfXEcn(N@7o'B)i9Iѧڎ*);cu6\pـ5c\!:3E8D%tsU vV10Rqu$L&˝=thxx(XfffN{%LeFd(Ѣ:Z($ DU4:ۂQh3"zB-1fhiډ̍ *'] &ގ:ʤhs8X&r*~_,.wqͩ))LXMX*N͎OgӊVmjxn\3S3֑Yqe*4K@4=OOL{T*,$CJl[sQ{47x}:sʟIYIfi,)@ )}p\,sWJ =6%NM(BTBԒ^B+z@ɠs1І22Nlf$ )?Z2,GYf]׽/Baْ5[DI.WfÖ́c̀.؞Y938DQ` 4.3!ɱPhX[SL [4X[3m%Z9{ι=Q6D).ߕJ*5Z>?#`X6( e},yW9pp B"\_G۳wHS_$MO5n SnB 1C'GN`47?'Ly`Ea1i`[m$Qg3c\0+g`--RY"Pn)jA xK~|@ϡnw{sS{%E?=wl?u."R8<;+ZkKgV%"P(V:wτϷG:5Mc=3nuylGD9][ʟ2 <?O?4ti5:)읟W^=M{e{'#:.iP/>9@T@CEI.^vlΰ>~F`t*VUc,<0Fdzb̀ TCB )D(Jţ$Y-66|)M-}@P ș–;u纆ãer0.eVanUSiyԑ}ZNjkyO =l%*;YFM{*ilpƱ@ ; OsV FņR>Y?r6.G\L#7:ޫ $6?c+3mc=\>2c흇cCAM sb=T*b@$ Zⲱ\*+yIls[!@WAZe6jdr.RoaK]DQHQ0 RJe?HN̓惑f/}xsǯߵu  }1L_i;^5EO"~uYf"g"i/w9d,ncb5λD:!XVǙ\edy`Wa~K:925"DnQ )g{e鿦rgGT]oa[ ~r?A&y#*Uh'9E5r$;N|=X;KA" EQ5L.Hܙ TLM{?̈BDDH )-t~$݂rd"#)G,T^i5X8#R7΁g^>Y&δ|-Uo~q9lo* ^@\gәexcŒMYF[;zQ'89Fѥi^uOǴ̼H$´Fp 0xCS,j͏E;hRJS] (Pecs*LMNnM)U%ʞx$*/%1\7=ߐJ OVW 1ʓL?VZTBg<9*IM$[?SfDd0ͦzZl GDiTD~)r Bt0iԂim9w&4*իN}?U2L<ɏ޶aO+Vؿ3[(EH-+yX Qc:{4K D#Ω>~Kn_̱)U }NP}az*J>(tojg/9D-6MM]i0 ! zNmWYXc0(0F#ũ 4 aj>- J0(y@v|t8;,uErKH6IS!w+u^tYd{[i1EZ4N@)OeT Гu[I‹lXYGҳLoL Ca5%'udb:9U/&TBU#Ar e  9cCHĆA!1?\h;KSA.v$nZ[qq!:j fVC6QiEI믽ɰֱٖd6#0^w W-Gr'6(Xd-QgtHlwo|# KC$|,1HGd6UdGC2Eѥk^*y%QGbBaF+hZwb6m TIdcd7i\D3CQ(RK!;0?nwi[8kQ}Gu'Mx-7zjL:5>|2̼ލp=IX27f3|i,+/hhJKCaQ1 됩W[(SV7T>WN<^;O<@adY-_#r#s5#>~Q+ȥ^6V_E*I&3M+t:}Hc6!2: Rl`bn0 .P!AqN.;1G%%=ӏ 5Ш gBĻG@@w.v}R i3Q[f~yIDSnLБ-@~O:31iws(fLj  '_ )=fiG׋BwM'**훚JNu{wo zvJĆÙ[~};w KG~ZYLD˔TQWHQD9̶t:5"TaJlβf,_NXQ0*%EsVh::l]£G)uvl2/ 818},a1;0?o?m7?|}mC\ !oO@6(p&?;&nk\vU3**V0A8OhuYn644ul3Rp(NR2wۚ ^[ӭ (G˖f*]Q@cئ .0$Q( t}tp5kfgLg>^(6~X CT t'ՉUG>B%QbB'*5H`*exq4{$eH\(&׃؃~𖿛Yesʫo,45Cݟg5R;a5s;,ݗ1z Y64?fsd2J"h-T%Cuhwr[4ޖ ɇ'39SehFR:e: }NquU_ZquҘHKG~mЖX1~W_HC,&MD;h۸^řݹ@JN{ J_r?o?`Z*n M$6$uT4nN52/\90Qbț*ƔV12 ^^5)%ܑXWa() #fk=wn.bbԳq'wm]`^GdIILbj6(tt$ OmgۆL厷l<=tKI¼Vp2 :!mJ O,6^[1ߵ;8~.'6W'3i\KR:)M18&|#ozUbqn_xXJuffSzi;E YT!Daղ-K$ǚ^j]6mA`6%"rm5jLG _F?ΗxH$DUݞyqnEc1=#: 'P`b ;! vqLBSd1!=?cr+ ?h _7L7n‚qٹEaA~7SuBEظW|r~*@01{k“mʥuN#.w1E1YU>kP4M;].UU]ˤcPg)ZzTE܀/xJbB@}׎3]#5M7mܢh.(jX֠hu`l߷-vR],GJn8B3zA N~ZlI*G^q׺xOf|$/o!Hb@:{fPӽ@ZgLktC2I OV%XOb8Z,P$z,giGd b'ݕ2R i`%hְjߙ݀ie n*1BδTL*M%tn,)Η5F]zk{ڙ@0 k/z'L@CeNvhY_ D"8`)0D"ǚ4O]nuZf{ _Q`h"zޤ7jBB̠WV.\}9=uX=_=b2!_$ f؍ёC5O\jhGB)%9䘓768'T;#s55CCC '/Em͍F0ƈNᐶ?Ah hqCI* لV"=K(9J+AJ0j2@ a8wJs:ىUZS7K'|ӢS Eχ8,L; P(3kr~"p"Oey("R2!s$[7M9xB-_eh &LZl9H S-N47fZ-Ȟg94  ZL.HVٓqBxS hkf@A/? h.1$á_gPČSrj JJb C0Il(dlË9MaT3'OČ-_ýe;T,MrE6;k+2՚[v۸uffZ] όIsceEy;nȯY)Go@2DJ"MD*|7H`95Zv D 0Kw#uFa@!ZR\)hX/U(0pb~xG] #HЄ] )Q00"EQrrrH"̼mKz;+4ȸ7TaȢ gQQV[FcsnXG1VͨHe2d|G.{cZPUxӳ{r9?ǚ0-VEYqYD jk&] iy !o3f:iYE3YVP..PyH08Pl40"L&Kx\ru׆bsKbBy:.RRnO 9Xgc58&Iȥ4FxAms`\(D1 fAmSD4ʌ)9- x_Nd]Ͻv|ܴbΑ;Eb_k !R** !n }'U&zJl(& piY01~4Ew<9_zuq'E(.SK?N][k4%UC$E]ɛeAM.\ǖ0Ux( $^Hi U/yJ& ) DbТ# O<B͵%Xz$n;z/>o n'X?(+,0ÎtTQ65g(#B1(°@Φ"Aפt/F!@RBQODž$+T% L;Ks*1LXw6T*Qj$I-gQ2iQC@LE/봵+>pxqu{(=cܤ]2: /FēxJk/_dRp "" 9QxӗZS-;#Njb`/<[K* `b(F) H2(+A Qm$JH.VDiV/r7U󰈒H{&s@l07I {.KorE%p֮|bmU{xG/K3Tz6ZOș me|WV0o3D-i.P>xKE(9QvEQDYⴓ .e^BD.’ $eRTD#R˛?|N}[kBį MF1~r:_^gK?{ͨ}\~ʁ<~=,|#;w?V pF)@EBśrK}SX_ >F`Lf{I\bfy],Zi%VS+8Ƣ 悗ѴVM㹙Xr `[VbPȄ@ 8 eUtݝE츈$$ /U]` Ě l\*<`,*yE!"Ee,$L*«p ٫4jecɄXiMuݤXRo%Uon*q(gkx"H9(qڜ]:/F 5H^=,14VU@A7axhcE[xU艢Q4ə$-Ɍ+570ۅ_=B"P)Je*5NzaVw eSAd m =S|8Le (2Ose9--w~74-α?r\^wX :Q"X^/<DŽҥ2*ydyj<K |/fQ$}1i&cj͚MkiE!2("/7U*ʼ<g̵H"*=cBTD 2%L-{Nl@p Ȱ$E"Y"P_Ǝ:ȝ 3M^z/Fb7?9\|6>BՔa۝ugպzP8BT" @p.M(d &EkP4A!#B F! &P.)FNJ!B1\"Ԡ@0,k4#m{ǦKg^G=ӊ=aw9Ddp(&AcZi" 2-lP!Q@$4QX|µV;%"A%u 4WNXŸ-y(8 kx"TѢ,jZO'(Ft,dJ< C`FrY+'1.o^W\>B'2Hv3-0 j@3`+VÃ*cT:pV(gS&{o$K}X7n԰y )-Gd1165& _PG+B6S3ou$al)¶;d1Mf`|y:4*!z($|D{ʹ腎Ei T|=RS >gV} 颲TVoq,b \\0[T|Yx:v,IMPziX`cxdB|4Fԧ}^5F65gׅO''jܵiT`- e[?}-Y۰5WܳkUE`KjѼATpuBhY/1$BED# YR+?>ql)RהKTmgyMƭ,k(<3';lkvBB@&,}xI+RD 򐐌qqp. Ĭ߾fGn۽UMfeע(h2M&BHvˎ{?=]6FD,HEtQ |XL 2!71 :7{v?y-yP+ކ?YfϯG&Gvm;=|k}z+69{|ΤBl&e cLв6]8AżI(+AFV%}HxM4|{2?P 'X$e:,%-[]\T^zA>]Q޷KEZBH(wnP-d#EFmr-ʺ.!$TBqvˎObU\i!,3UЊO2>e4ꛘu}Š3|L|!Ns5F% x'7WokŽ0M=C xm1)xfWÑ"Y|dށo\['3z;("eEERbpDVuu;yǮwUzx[/_z챨o.ƈŕoMGZ|Y&wr b#<~\a{Py{E<\dnlpvtK|tc\\,EӮ|oh~v+APԶ8?^" /A@ s9QzgܵƧwtb..T\Bț-,kaGcmX2][rA#ad:oҲ !hg9'hy*O'p$$D̉HJHX\,?+(up&2 ,KDZ=g$$ɟ /#^,(37mfƦyCvX QzrQ}겛<!D%y(>B+w.wCjWU]/N&_|,q.؅%c ,A !ҝ57~_Tmh4hԟkͨʿ w$؊AXW,ufCt3،w]Ca]RB\aHSNTvE[RTDPVéD\NYWdNP1FIr&ru"a HV t[L- [. {61F˻gd尢+_/ h n &0TF`םlV՗}+`o֭j{<^`<\*A/Z:B=7ݾ˜gaˋdsyEC:@}ȨU߻}/ZU[7~=]{N^tu&8ٺPdA^TGb]bB3~„?4IIJ$ Db¨ҬwaչHB104d⑹9_QQ1\'v e^uqwkY)jb^1iS@3{ǟ+a@V@A @(/y a컝^A*c$ ҅SD#50סK;aU6_m]Y2D9]nP xR/j#w؍vl?OصEǧiT˓cӚܹ@5ueo%!JQff.q;jMm#SIḦ́SJɨDE#v72 FZna.ch(LMHx]"f}L=e-^DQ"^E!D!( ~1Gơ>l1 @Ӏ( x2;nA(r|3@@eX+HBȧɼ1f^Io8OB]n 偿vkHx}gkg{T ehM*W K!43rJp 3"P,&YBɀX"sb*˨iEdhA bNA"-CԷx)##jᅗY Yy~!qhc*; #PFճȥf6TLUgJ*qI#@~> CJAbV.I?X?TCtȴܞIeA"@PR88v{6l19 & XpSx:/brnyk,h9@Z4-iE(և-n h|]Zs_lଁ@ $aA̋UJ^x4*("+Q,! 9&)(ũ!V h!T79!L\x!FȦ!^~f!ed"d39˅od*m oTFeJתb; ZjHkOB ,Ҽo`qBmY#sU:son蜚vur{NM8ړp.*<_VrraK)R&eiB2(20!e[gtu4ᑌ$!yUGƎ244 JXSVءtGmer\ Fy1IDAT=ӷ #L4,sPiTwJʗV9ӿg?K"$'d 8T ˈXPI.[E㟮+o:07ٯ~/fr|XX$+ʪ\-ͭR( (]A. `ǷYi=XjbSӉXVRS5 j!VN+Z5,g-f6_vH! 0H4O$ׅt. W߰h%Kbڢ41bڱzf/tdr:ُm٤S^yn]-]ʼnZ p qG'IH#Չqo,Y{wcUVr9~g?;w< 4z2t{@4*Zp`qͷYTpG>DEj'rM,$ltЗٜ`6{N>"iz=`T&b54-|lWh2M-/Rx6@`*kw431#JM5#NDѢY"ˌiP2jTMgB)79A0I(xb,21!^p%4Ola0 - TXO/˜񒌉T^EY1A^~O$cf5wԙ,:mS,ȱ1t p($z,a&wFpȃ bbHRiIڼO냓low0; qP$`/XutSs^RR|e[钶 yII@V2' -5;-KyN9ݴ2r?.(8&)/  ,]x%I{>/kwg^ E,9`(iwD4ynSPDsSVH5.R%4vV$FFgft&8ep4yclcvmx mC_+I U QG/7GmD^o ~|.TyOlےߋ1Ƃ 1Kgp v]u=N(]Y يR`YYa .hO|m-N%1gنx9K."Bldh> 4޶h(0Ѧ/wn=UzWY>3L2@ZZ_Xcb}Bbj^;Qjn IXˊS nz\b`,ښ 6]5V.#a2bd #t-(0D j%g\)f:a+px'9Aq}*nCE, b4ݖ$Y͚%eY.] RT˸[ytOD&"NE\"AkWeQ+^$Qer5<.']=aWtu%дrMBՅ{#JV::9BmרdIZ=/B ]fAV7jJ*O֮^pWTW:>WT}쎒";n6$އ;`4xx2pZ'\fyXrsƍWP2C.@)bw8>'}> H3fij M!ƘHZO{ĥQD)u^Fֆ(`1gwɒ7^>s(55n'?~y+`P}dǶؑƾm%ż(]hvcgH>'m",Cxe =$iAeVqI(  YGPHvO \tAX6822T[/ɩh: 032S Q(:F|/JL/w.] h2 O}d D"PJu9-!±kU9[:4܊6 `4< ܑű=OѬb(13UyEܣO{J`i߇iV-^yh敃^A>fIIΥM;{Yuqm>//yNd@1F%&>4+ Dd˳7OF~ĵQ]Iěew (YQ*Ap$,Ңϕ{B.  VrXvBqc[6y!ZfQ I{zhwk.M[ΖY4IOzԙQFe+]K:]1~uK )و N=ev5A/g_:9Yw_eF(2ߢ&- Y !tcn`k@>W=鲼rC9 Txj8V(JuK!o5!gmqT:#)-g\#}%j fs `QasRF%FAy oc ZUN*6qH2S/ MF!(lK~q鬀8UdEy)> _Ŏ$aAR13+  ÂB< Q8%PD€1[!4-H *UQϏU<Nަ>K3ʭ<9'dIj8B_l~g[xOu&kDrV`{==7vHAR"RdiRy`N`IR f҇5jiiC•G*^|*Jd$F" 1HBUlx- 9T!$hef@&m7"!Ě $;3w{ "ˁp $U|,-O9U*}0h4]k{27]=}SmeWUUgOOOrr>zmŪ_~W^z衇ݫ^?_{5|elll˖-KI,qܹs{z{.---8$I* FQ3ǓojHH rKXe,&ۧbDD" HxF0k@<<\xÜ[Bc?,0H%u AEapF5'QSf%mȊ+ah D!:3]aQ5x0ng":;;|_g"dY>p?0ZnhhxG?$w CMM͙3g|~W?Aeeea:::>|`0=qhh[VMM,wTIfP0nsFTm?eDF䫘0 H($2);A 2:GEIr +@ <'镊`($bs˾Xb!H apL`80~R+r+8uAd$A/EBӯYř3gl_ʲ/\XXx'xÝw966v'[l9rȷ/s=v= +>lKK˕&I2335(Jq__@BBUGK RdnjY1%R0* X M){ӂ`9#(Ë'&gEqQ]5ܷˋQSzAjӇQēbE"Gyd{gٲefϞ=qm$p8ZZZo߾~zZ~7559 srr6mJka;::@3gXk ԛ#W̛̬+Iʱ0D 1TT;۶reI(H/Pu5AK]M7CU+: (zҢ4,ia+K H⌺k׾q%_f͟ ;i: ut_=9JlٲW$uֽ뭭%%%$:u*55fUTT\u4Jl=k8zA , q8}?KU՟ojûGFBHJZ60pg)JWJEI^~cEٯo8:p42J0%@VxB4Km A_\\P " kDbԨfYݻw#a0D"^/EQSO=k.QѨRIcFՆa ˲v۵B 'WEc]'vfXB濽\̓Xb"eA bՄ{ֿ3Ώ +ZypURvҵ~+cwUx&Hp5? @xG ULPYDܤL Kfߟh $ :1@IҒ'{2Ʀv+8yoNjLQr #Pq_:T(#B?޹s'MGG 5k9r _hxU.K@|9ԂԴmMTɐwB쇷|rI&'5Nt0[?sKRa9EO@M5]1 O $r1c+O]|saVDc{Chg3`& (bTM+(e&e$nڷ !{m˝3 }"ed,Eo==*n,ERW߸ANiE(!oMv[UlKPʑzv^+E0pľ]fJ3ɉu9An)fa~R`C!7&54P`nj\a) 4,wjЍ0$UwExQSwӃ:C-ؤE"$ OmkS9QI595]r"=P E`,1`CROJ !~LPlbo-VqXmfcMWPލM*@E/(RSǪ奋:5Eڋ _'UEĤOsp GxMf'D0ƒB"=cF@hIdiAΨelkuƠ-32&QB$IR BD"xǀQg@kVGA@@QAȇc."A( 2/*wE\X =[A*,(Bc6W2w:ԠxUEbd =e펗?M`M E#,,yȼwZtE٦WHsdHA \|L$ȝzA}X f)}CDnl9RE2Jj Dbo8*cY Xh@4J 򂜠 {"-"saF !` 0"E0$uvptwsGFB>lèW%/"$H@IS*V" ,֩jV1%wz_iE)npiA3(,,NיKRH ZMwE/2IY|Q^HYvmkk/o:24괟MLS-PV{n?|Agk^oRT4E{!Vknq  NIBcrcQ,"axi!ĤnF% Gy*3xQ"E$,=[ xY$0 n l˪)O7[ c?/ N'D!Rivs7uIE!I%dFK=jp1ڴ(ὠ2a{ξA0Pt{cEMTAh2 $s] ywޙ1v( ,_E ݺ``VwsoMn3N㐀8y||Ք똩\7̐״ 8 G$B0GBX&FjE Q?at!@A4* lXq\1hL#:$֛\,{BCws#w") `1L+QB[g_RF"$IOlH[L1d::-*!fE1ˌ_zzZN7Mħ^Xt} I{ faE!hv&Ȍvϼm;:cA˝X$DIHU+2Ru5hLpE!L(rs a:4 -9+ " `[Kū/o/ Lj\˞?18sQpς(* JjʒE,ܽq(d`MJj q Ӹ#IJ2Vk0 BaVh{ d44++*Lܔٻnyi=;7u{vmVVQI"s,p& Yt 7 Dzz[0c%Ych^s4RDD%qjϘ c^͐^s ^ y<ᆴkV < ))L3KBA))bƵHL$Vx-@|kCw~ZMoWsCԓ,cB7P";A1fhlݛ9_ܾ<=FwYRЍG[zҚ}R㷬5alZ 0":A(rhqyV_m7Zr͏9Tɇ@"S EOOTG$IR{ue$!L a$̤3\[%),1g.9 b Ⱥҍƹ7Aiz8Arjd`5 nIIjDceND JdId0`96En"y@1S("\/9_ NO$+Q> <{ԂɖNOMu˺|$IRCzr$SZэ{H R썽)fcNw%ݳO}KFH} F&H&I4cY bHSkPf6N޳ r=}u$N4E1VKՒ9yQT OrP~92!`4Fa48A Rn4fbLkB'!7c 'Y&FU#yCIr^YfbI1#si^^$I{ﮯ@@I4ϴo՞`uijbt7_Dc5E,Lɱ>)N')12)q1 tVBDpzBANR;0\H)77{ZiON$V19>‘G'Fjj\cFhNfYu= $I:89$OI[L@#15a݆=OJ}-5-]n)|j40]O9unCQ.?lMdrʰD"5nU1HOG~$U~c_wro uŋd f(Z<ʶFAa( ɖrH[>lB$&B?!M" l5˂?eOZZb?R!.IޘdH IVZ:2AtTߠAqM;h }VBSbw4p- )'ʹ&%Kw^W}(y>Q@,UY(9E,sJ>Q;OX-[A7!]r~'>:1P8kw߲ "D';06y'6?z'$pxuf44f$"dŢԆµ!D"i¤Ҥ!Vki );eM&TJRBaB>{iZZ~oT',h':V?+cɪO^2ْ9joxr+bf&KNzrDC*#I$I">353bg) ͯ>ȕx#4)"7NP$a92(YoSC(PJ/޶},]ݗX{]o\i+WD̨88AhE%K[zJw:|4$b_G[|iC?vy&a7"b1ʇJAmruX]%OЊloV]U pݗX( 9&ڵe@(WU`Ovѻ) $1%Fr8I7= qWgɠ :Qo 6oJH͛hX_gϟjꖣ0RZ4Xw84Ix>(X+?BӍ1 o …œM{߸nr3E:[[O>ڋ狀u@N@Ɩݰ+ӣgiUKCkz%2#ߛ0659M i>YUHLk4?m CA^U&V5( ̇rET{Fq@Zmns+ xmpFx)$H'n#]cqx:|x4E(C1&J,V*)5HH % >w>2A/ jC̴bo穋o#pΟO_Olآ5'_Qĸp?ʦݛJMktM}_ۿ?T;~YT!hl>:ŒzJ?ȶ'Θ(znX[;8+4R 1hҮgd5\<}yb4hXeV {:<y%eJhB\xokioi :"A'vy^B5#uBԮKV$3]h=0,El4FCYW>=B@ gAT@iZRu_= cuM||هD$hhH*u$"5KaJHEhINsf3˥l3S!B cc,X \iI3Xi&)dOJHJ[ns|?r:; ;rZb&/K$WɭPZ2!_x$LOu ̃YgC6ؔeMȲMzlNηu,-PkX 9 yPNTAM.%LM"YM3=}uF2'}/ !5M4-11FaJ.-11Q8$AVwsh(ɞZv~'-Ҳ  tUW+65Zs{A@2NS7##kS{k0tEqҩ1BcZEj(He~LӖ"r8,.UnFPT?p}fnÙ˄ 4r ?S2iS1L 0W>|MCq%lmp3D@އL\*'h dCC? \hꓰz,)8:,5; NŨ$K]KD-Q\pSf/x!! IK'b$B5I_okUDgXWRJдBV*h^L8<:2s9&kZ%$y,$z%rM eo,jcqyGǛN|eq R&)dJ' RdPd F~(!464FDSv(֦ys>uQ1߫K,U3no3:˜3Y>E O8z`ԧRP,tL4utwn$N/RHt:=dd}n gϿ^1ёD?.:T>|,qaΤq$&!($b!8iVn rW՛lf9[|R{8(0*_<xufen1]3{N4K?Ľ'Y'ZLiB""6𕶝F4 T㄀̙4{Uo^hK( - h ŒNӇ }>_勝C=#V3|%IPӌs"zÑbMfq*ݞYZDӴ(ןǖ!h`1qDk&Ut0XXNt_ݎ2tB߬B\fM[W?-ٌqF! <ͼ=QQf1K@ aC(ST)lY s~DHcod4mRtpj{2q EFN}^F 3})iiN}Gk[z9DSs̫e ۈV._rfѬΊFXwعԿv.W C }W)Eϕk;1E"LW:* %̖D&E*s7djVD/nU?wdC?M^W.V"zuNnn{1 z.4w  F`R2 I hV^ ݚK\QUn%7"pFen&2qoB+C٩~_hnܗHg %F>ݗ%WkBXm<$21[Xtn pN 4饐a+xsb<@Y~&ȵGBi) "*S~7ϻ>UrNuaBrQY4xkنD6aY6iNdL)jK.Y&S2:ZdS@P_ipb=^o[wOt6{>L+ #LS5KEd-󍳅%ƚqcU`F(v֝:^]aN^S"uMA,()a7.* 5*qcz>H&#NHMs:ZN#VhM(>Ti64E<%|xfǥb\9kpo\[ЄY $B P:;YvḊġçr#E*cPM{ I'@ ] 2KCcUeoFSa7aJ1&X(umݣGg_DQTU PAqNhQr^Ei̤/`2z0$ kmtF Nd2iRp:]EU#O9(2 E"-1 b($3 sdѫ*xLWPD1@Д.Hب}3B/b47^#Hk84h jXn- F|!簨b-k_^g󂨢7 $95/jJ,wtv;}S s;#SEa*R@ILhOx_A0-{2UnQ-'sCϸ#|r8^{)i{jΘl%T@AL"PE%|-9)HXhKT[ 'wKǂݬ0BՃzcũD q)?mn0&܅q k~, E@1-Vjigfݍp8,اyzR 1'L@bA@ASgZ8/?P$s>op 5& mfbC{ Jspe-'&][+#/pƺ3K@ dZ_tѲQiطǒ`%#Þ, {$u~W|z+OxyޭM:۸Z4~NDu-VVIh |E}̽o(&7eomXT ܣ"'}'b{_TF DKD=j1mx80 Glqs9&qo~N# ! 1WO*U~W+#YZM-I14{aFR%k=N՚R+U ݰo?SYgLݥP'!uwuan+ISӤ?)cF+Ux@8X$.]AFi tIM:-Y h]6y}tF%E ʽ]xbta+9h>]V{&T8֧K.f1a;_[I#AvC5A9S)5!.EHIs?ML*z˝\ZͽFҎbò:ěebONJ$IZ̫M,8u_A#kWL:!3011#.ч1=MgNtZ!myfpݚ(qa)ۊ9  V2H\K3v9&+HX/p t~ry%[sc|_b,ŃdoM䈀6$NqgAW1 +#0:PyKIdf,1іt&XrDӟ4m1Aabt4` LE~S vOLѥ k\1y):n , VVtv'Jߴ3#~ibbH ۬#ED=ڞ_dbEHF 6R.TȻIyi);H"捘0"Ҙ4i42i1mw3IdUgE I A E2at(VA*6pm54/FF_Z$e'-]RVD,J)R9#\i&=k{N`hzD R5v4yP\5N旫n1kCGX(TL ĒjJ}YThu"KV>m"ĤPjړc) wTzs(3i^ :*մQ0 cPج$-Ix.%d B,Ef"fou0vcڷj.Nxf;6v(?*$ @]m+ _u⢑_{j-7E"珼rAD-),Fw8(Kܳv.pZ"8I~q||?>$t/W30 $3YREQ9t1 ^PNoP>9]KƜ2dd,$,s¯?lK'V0@Fί)y#n } 獓m@ tC1=R;[˧(ޞ`%l< u:%%+T/t L y^WAƜd*kN=rr5(Yw|_H?FG{[Ν8wj2}PŶK'`[aH͹FLr#Pww7% c,eo்xz`A*fpіei`y5#ZҺD9'2#{εOz@$c /GTA'ҿo琞o-QNP/$OACL6TnZwčYRIMBQ#[WhTͮ 5m0*@dkr`Z/2\鄸*veVxt*226mR=]C}ƎUYk݁f9+WcVI {>m~gkSt 6dYs-LViîǙVXj]xJeGx*D6KDO`QN6r_/jO9'54$,Du+)ȹidkCMUmXnF~{հ |C[Fݻ+wZj@J \Mog[T&0@WUѦT~34N'ksc^_3 6ۼҢJB D@r^P+Tizm?ޡJ1\%WxLEF%%u|==V700`N0e*:_ cJM-Jf7o5ur,- !@o :VWSnS'&?v`4)c2(ں7K^}P]< Jm7Ng35TeU=DH ɎS35d\p rW1( hHÕ9G=K};(@J5Y4%m IA>ěM"E7jIL"ZiHKFKTͼb kG$a-/-AgTL M<^*;I"4+S9\VWxX5Ky|uƺ-ٶZBz2Se~ooPDWnYlO4{#BPeL~ u5 9iתcOrכNF{J㠳 vݚQrgy=\RVmn #.?qμ5ӲsI'|S__M%c,a,cl%c%IUO-UHgcK䔆_-Q`Kc}B}מجl%_k?$20K2HKQb9qJ'ezkX db^/ @XͦA*~sOq$&L!>*Ƹ=jqU{x綌eot[;s#1]c7vڵ nl׏ ,psIVI֭cp؁yH |٩Fl{,L"95:gHA1abt>v+W`J˗/gSǜ$6׮1 {JiѶںV.S$a,rDÂvK/h`_d [?]M1  헹$:ovl<$] *P51iz$̟=ٯ08Kd^n';fBBk(l€\$-KB#Ј!b&GL 7WpyM;{NNNh#:5~6jtWHP'S+cq"N,1ӨL^c>4tPy͹浀9i+2I±rlUƲC}wi{/,t_I䀊y1QwiY<`L4*>&߰=+klپ'.C?1,4FNݬL7ѳ¼bm uZBCCh\T$ DrS߄dһͳ? ctpawuFyNS r~StSϛOSQ%SdhRtZ:!Vٍ9#3s + JK9٦ hf iPֱ,#$x['$.BkHj>TOLulQV6ǥKU<ys,i7ܼc<62y7X~cJ~aFNEQ,_#:+2.}?;:뎎d0-<@8T 99kR՛p8Z.]/_쎻oѻ x.{=Vߐ<mW͙t D􎏧/AȲ+/*Db$<|qxРo``W7{u= ^T=.+\ܤ#sF‡LԒ ey:d2E\%51I b,e";M൵BuJy$E8&3Y1-lSQfc+O>pȵl=j)D1>Ze)v4 bEXP=kU=ާ/6NRiK.m[N"|Eג7_YTs~>q)rXCe3k -;K4'Ѽ}uzb('`㨌"2ҵaMcX3.poFH0 $s Mc0B2B ѻu&AﵩexB.`% S: ?@$b߃Gmf"1a(*ZǒWZ=T_:!N>?QWbH4 FoL)aSOYY,3g1A1Cg Z7l^r՜}B̆7fT~MӲ$y\ή 燎E8龍qGTf쾕2[z/!Z~4)(x""4J6`0P]uhlU"Tyĵ#&-8_7Ì⟵쭊ҲhF^mĉ[OWe+o'NĶƩNX r|5~> -E!a!ȏKwN#QCK TL*BINOw9ch2qзUdNGB1{1-ch ՙ[NV5јPfݖ/UPyUT ?z56uQjV ,^ɜj议￷p]5(R |%*NI(/ʿ<.#HGC`scGS5%5uI麭H vu^j`-߸b(ϟ;w*yX` ~xyE˲Vu hM(I1E[{ڶ;V]b{ 0%S~og>a&8p!xR_`/^b/*:c<3/Shijb^݂P(qX!EHA@ 0]b=L<0^KPb6>nIR`:Apf A ~~Ēm]s']ǝm3c䒥eH$rW4sd>5.c%$oaT{۽-'j$v"I_V}V^> ^;ΐ9)5w!܋o)[D^ qzQRST.}p{#Ou8-gvKm5*ixrjXo5ջƬow^a5kJזKfdH [קcwm,W3(j/.+SzhjuQnKMvUx[fsw+Uc<6<|mQQr~{V=9eN$I\$Q5֚KG>$WCKo8<^u(R*ai*DQrrB򝷚lJZr3NG1i%?vZ(SfYS}o ϴD.R-GtoܩG t Ef'hs*eb5d0 fWb'L)I°<67Sk8xYnvb:3f)($bXp˻ĝ:1_ %EhSu>:TAvt |QRM;ْ0g`0tb݁*㼳ڗlKG>pT^UZmd@x""-+XAI(sJYƜ$7KO 2me&9 5]"&]kA=ȍ ;)6GOzռ[E+d,C%ODaZ6śpNiM: J:8BJJ ((#à9Q!spaNSSt@HXkuN`)6da N`l2&ZP+ozwN2 BF#b%*SQRk AaǗYw5JJt~佼]_XưZ. ;ͷ.)S5 IɣW')Z7~l/& qEA "+)o{N8XÅ'|50؛_i}Ü}-o6ܐo]q˾s%rGg;y98lxC(7/Ws/,ӯ\;[*M@q2oP pg W}K_*^D6f~ܷ qז*.:@FgKw,˿r*ghU8Z4͋k W/Ԟ "({̧u ݰֻ&355RI6g)cJ۾~Ŧ[lHޱGbZ34{yz>s_tD%Ӹ~[-HPg̋~ z7l8 KfS R SI\g5~৯'l3/~R|u^tot?&ZaXN.H9Ca_l='7/VFєƤ]q|ޢ5i?KU>ۄnƮ5~<'?m@dgqhfuWΣAAߒD]я`ˀjoK}d^+\xîܦ>8e֌ɞJGλɖҫSN?wxSȉ}=/n{d8Al;& d(4JkmQUS8d-Qhi]+o+'bu{lYvx(dv.;|{OEG9ŒBR$h:[v"B),G3~Ph)Hr.ߛ)-1+^V #{MM|7T.+ e1z+_xWs.r}#`[,V[ꮆ agc%g EU陃]T\awsڇmڑ[tW7431aV ~R׮MZz?n͗~ᡡGk/W6'Xg Ʋ,9zws(?_0?q~g2ʥ[7'u([_S7=v֤0^tPelӎGGNGλ2Rڵtm;v"N-o,Ҳ$Bmިd;Gs}G 6(b66,& pSK瘙r˝-Dᢅ'/UZveC[V{~ Q<%zioD--ʶw~q 9~j'|й/_ZZ66)p <>T E00$T,(ԤWP$A\ 䌌 i?M|-*:T_b߶)KDCum--~)G!|$ͬ޴cǿt/qHO:(@'8q/h4s>stW3bTPϤdf̬28( Ou\uglO$X]M; {NE2LY[4Nx%=H'n#UsFr|;}G 8>D̿Z9ߤ&d =!i"sVktr/MJ=w )0^芞Q,6 LTlpvx잋T e@ i{v.nJOXzpGe aO<*^=R62P|Nk99{cȚcgRsv|fw;Q E7b{٦?{][elG$KӑۿqƮrWS˔*FwwfV߱vc`Or۩;VtR}n\J[_nR0$9WʘIC,"r>8 2dO P􆻶­[vn(Դ%'".TVڸtJI ՗TBbXV.cmG.ԑ`׫&iM7Ba^*X<<|-I]l瞼pxzYz{j/UZb/ڶ#+*Yㅿ'd:)Ŭ@dOAP$[aar`ǡCizڵeV}M{0&r4mÃ^8TKΐ*o{zhYf4OCY+<~R|CĤ\ߍMn7Z6[lXaW #'Ia5L'{p]OOэ?*@dAH9 ] *^ $d$Y9QPE ꃀaTC}9,K`p/o)X\0Db~j<ʄT'xɄ4sPBȉ *  PBN? j*ʀׂ{TfM24bnly"pyfm͛EoѮ$J̒%Z;&7ݨ8f,)\fOuPii5]%gX4 n dj,/]d`M'իo1 Ij===9ڼk^xMŎΞ_cԢ(P;ݴ%!Ֆvtv$dffY{RFUw|lIZ >C Έ}g$;0"[UI/4U-I}'&fPcH:{彟JIK?~ꏿ?2 % ʱ _]'49+Cu_wKmz*cAӂAn< _I4P0ES+@ zP@9 @fMnIDAT_ j$-@8\тf9Z]g:%͚~kv.Hdx H uGz? hUAP < \A wi{B]d191(NL`b27@^XS%eWFM4 ]p8U/()F LIx˗ ,tu4 6MQ3vN j58 n`p y2rY6,]`_煃?w{߾!y͔W24tuk| L֕l0LS@vu-]|>ϩϤUჯmجU]Ė.iv. gy,oGK`YJȬp;;v獻4Ac .CՇ2=M Y񝼏I#森ݚuA S!FA ` 1 b9Fa"A vnP^zWl9o9޻۴kX}FoA$U"5CzUU+cPDts1v;-U'.L6Dj68VOw5ö}LߢhWKpk.4bT}w  RT(եw ]Շ^tɔW_)-%# z8azzYVVRV\nkMŅ C t:˧tƝ|:#+;`0߾[r@C0R |KwrI~ϲ\IވpQЕd`(j#65='3 K:v9wBVk#tv<秛?Ń쒏O4. |K<_ie;Ng/={ZV${1Oz[yC%K_}_wkGw cƳM^^E,i)$@d6PB,ȃ@^V^98;5l>VK-L|7qkEk7\kU5ũHq&׷e67Х$'̗Eb$<{mrol|^eY}o0iK U$kyq]'" eux__믗rJ*)~=I \8ߵV(mU,;L{7En`_zGWyώ~>2[VAMiu\32&!Z򘍵 m݇U)@ NIesiem{P- $Zڑ~Dr 4;o N (UZ %s';Zp훴ًJfN P4eX:J#ùdlyZM/N|*eD-KPts=2POv:Ifc +XJURU;*cNCvvwhGòC\0\aSab7R|A^kqυ,.ߖa*;A.w&RSLa -&M kO 28hd\lup©#hhJ oƪŋDdS{ѾW3">NxgO]xSNfr#/ ƼP!ʉ S+WG"yC%9e mkްmjlJY]U5W50 h_D>w1bfۯhphNxFתȍ4uS'}Mkpp33l>ϖTo^Y_93N!ȳ۰qWYeբDN><`mjz+vw}R=M{|Q )SYm5d={W]cTBۋU4YX^$|IP/ڬkʀŦk;|Z,6*o%(YBNƽ6E//۵R-.kU[6*2H1SYc04ꥑR5r %K˭NW>8k(K&N(1?t); %I_W9:bg.r<& I;Oxt5F>p}[' }cm\tM u%͎ nhG$j W8E3O?mUgOcY` /+u׃6) |cZLZФM|{߯`pHxGe%峾@eԯk !0muKtw $^wѐ|%Z];Vk]Oǻwnjk7_[~ʳ/~񟟩h1Z|k|go4L|2qw4-ScMϢ.6nfa6 1PpT* Nb8JPȵr& N^\X IrΎ,v("6SU~2(&+`ϩ Vt7Sz,&zWjoc[`}(>y@<) :Wsꆖ7tfMOjOo4s^צ,ZfKokht3C]cGR c*]f^%ɜy ܹl誚}{ڮ[Ҟڶ(|HN!0mmLz6'qɦIgw&yIkhNB݃eQ8D "ءOI|D PQK^9r).^9zZC[lZpwuSLS[mKh(ch.AzJזW^=3qxp`1k>LϏt6mqۮ=^_69rPyEeEeýGsH3I!fj2h(S{붢rW!;*ֆ6FsdɾS~ $UjNRyJ3;&y_b- dY'tON6Yb|EŮO}j.gf 8yF}CcݏXQSskrݴ c̓/4KVzN|ZCp%2\A5cm8! e-J.8 қڴvK+9/iu j]7˂ ䷾-M 49 y, [_ɯo'nd6C`9;ɳ/x"^ G^.+񔔞8~^O]W GGo]^=z/t6َ."rFԨ Ոt1^,]3>ru{ۧSR79zAP "PQYu늕5&X)&2FIbTQ!bn-B~&"m%1HC -APv޲qotK 85[V-x~tz*ESԧwn5FL3}MC, w(*?|殍eNU/t7O=iPx7eozS55b1 _}/Wr: yŋqEQBU%-v3F/ؐt}T|P T3Z <6=oݴ91ݍ XyQ-He tbN<_\` }:REm[k(XHA " HA =\n-(oڱLZ03]K+o~UUVh@B~۝Ʈ (A1ռg,[ZD1 EPMem" S EP5 1i5#! B{o?}Oi9 ! ˺CR:WS'{4>>^bem]O>~n M&@~$1 pӂ2WT;nhPsG굊~~cWűo,/[ntlǫF~\(y|.w|pw4o`2Gg>}ay2r뚳ְ]{~d81 }Q92wl]-*i"+ס(&¯dBPd!@,7Y[\06aVnBdf[U~<䬙)IF?_F$,"QV53 >3 %PkTcWx-mcի[Ey(XA4KAUXjx)kz^в,{%ԠIB*]uKdž/V\4*o¢\.w^vmukviVFVƲJJꖉ3OvkBv@ B>-ǹݾy.u)u{s~FP@"i* eѶp(:ʙܨ0b qS+;BF`&aZڸy @cYDYg3F]X%(E̍.W*bT'8Hx&0**i Ĵ(f"0tQxa[*̍ 󰐏f7>%T&/Tu>HM~jptp|*) |d5n|gj0tܝ5ŀN.fA>'%C6zԥ5Z` @mڶTy"~alWk`3Wѓ3+7d0|`kw\A6z_gr'L$CjV-#=]> koWtI3]t˃s/ع^{:/o Jq3w{yu)ZKh[{7\WVilr({!@<aLq7kt:#DHGfGD6Ph>HPYBa&)/q SRrYPKݧ 9r2"(1f @l^^b 0@3Lc0hDu>-ci-bťy6*кƆby_ !"*(9DF T̖(b@fY@E @Q@" R@9HhEc,Sh|vㅱ5 %ԭWSEX?ա?տ<ϵ>Sç_>E}% x aOEZ:O >nEz̛ύGm_pJt_wf* , p< dleUuI|d(=0=zh_]fLp|&u.m)̄@ ̏85(A($R_*fp,޸gJvC6-j ]/ӛgVZ\Y ߜ7>6.t@ZEL1Fjr202 8@ULԎTe_ًI( '.BgiFDN _E2[omȫܥjKkc\ޥA'w?ޛbŻ9y~/=DTKLx)2X;ys / *P(^Ss(IRljCg(r]^Nڏؾ8xܡwm8Y]!Xw[=o7O薭%FhW2o[A 9lq Md`ztIIBeV9|DG8CI`ٞ*J0T,ᬘ1`R^rC`jrc* S'ԅF1p5PBQ bA C DO_H_ fB @tpg˗?W?0[uht~8(x ͬW?;|˒z7?ɗ ȫy git.~gSMWe`Mx_L,>:'JěӁӬ/||>r GL&(emVeod6O2΢7߶tӧi?Lo[*r=__|n'>r8K2)@Yby̛yNŻպ*puY [W$rNdF[e0Q#c9 OjkRD;U!%Č*'R]lhU]82(rكr1ywa )hȒp-j-*yvɎ^Z =ҟȑ?ykm(' _ (Đ57]*W{3ImO&-ݶéZ[ڶy[4Cg ʊ"H[|[-S0Ϧ+*95g",MԣiVHuƨzC$"|%>Dz\L__1Pc^dWWجQKpA=nGP E0N)AQ E0EQqŖVЂ'ŴQA ׅ@+>_B1Eqa/b(. E._ - zʑ oÅ=)M{r`.Ehx1C4Q IA8)lW|r9JƬ<$`pq/t^.u&kp f = Zۯ=ZP"oG98|X׽ѠQӗ_Rxd*IitJm0iw=ݭP ATl)Ɔ_mEB2 M )Vn\mæT;㷮G[noKЅ(g߿kWlTWtyeْ7-_ L^zzjx@5mtB,_Eȹ}GYg]ޞX20h(uvPSg~YhͦH6<!QT!xzձ1k"\c-`!@E­.BAA!TYA*PQ((h̿XaBC_ 7]bג-.ua)^I܅o_wB5~`Kllm|퉁m*XXHG׭.,$.;+% UoefrmfFk\t4uAdO"c%sI<0|$hu 9ˉbG&ìZbݺz~ޤQk5XCW9=up``iQ9V4^zı *pն=^^W5PxI^3_&ɒ+_{H]) Q@ŌgTp67\al (󢤠`b(V' e ќ|/lƫ @L`¸uKxK20,u6W-ut>waxtʖr Wحגt[kj*mʋ]&Z9==׎1r{GZ*?:c8QpO\s5't7:^3TeE\TЗ@R]>l6{f~{ߟnխ^]RZυ& AW}k6SLJcEX$ -7s#N?? U 87V"QȠPCo>l0 &٪ͷ/* h0gŔ_Wyrn:-nG 9⸱K4vҪ"t( )>`x RT(sZt\~hOgU8 cb̥"rY~IGw(VOmW64~ϔb gwl@,҉XCUUU#ȘŌgtuS.+ QPjv9 cQvTWkqK{Waz5kC__`սS<'fErx je?*N|$d2'1yQ1>yh+7 1Eo n5v 0&w !Th}+D@J[t^5#0#F=f -*܌ (2_1FoO,vw NEc =5c\=q9d L  3À DȧA<x@@6@Q aӃ~JRCiݺk)UAoNuIr|CW\41YL XkF(ggѤ-kd<6|fS$uϗǟeСd޷F!)2tr ;l07ɉH~g$ 3*TKbjQˋP % oQ K9>\+\zį23(6d.ZR' r= ,@Ί xpE\@z&ŝ7m|Dg" >/^ߺ(۴|S&V˦NɈTnj艝jm-Ȏt A@!. LQdA7i :KxHsv WzMQH|aaHe27N|EHE&=` $Eqg-!7}:z^q5m|#a.xj V$+Iv֬{/?>lW_߾}Ջf|Ҷr_L&xILa%6. : wgcݦ_{]m$C6TĚ?;޽} bS,oYmmoma#&a0xņ79#CC5UN{Up*zC_4SGRsz׸y6ԡCxF=]6XjqjM'n]{O&Ϭoec;yY@ WD㣣h0LFfyr{\T) q^f!PHLP̊YlIYPe~?IZk*i]鹐^ )0p̄!Wi] 2&zhCc7(]7ФmDBRJmuzMl6A>߂$(_lkEáөo}ofr?j$kP6pSCNiKll+ vx4?'IJssqsVHDt!pxɈbü)˹s.*P$~iBEX5 YvI$~=i)RwQèe5;Ov=k31v:г7lP{STr@ӆdY>ey/#b69z.1yL\,cC)6`8+n{o 9~M{˽V]5<E/}]GJFVtV6 MprVqlýZpiHL2+N[;;yhLΩ{vVߪ$U;[k]e+7o[P_奬_] 1R9Yc\ȉi@D-5oʊK'SHMY1*y1e\7VƳj|>X5UneTںu=Çxz"Z)uZY@m7q,+^=1!^2k=3!"B88@P[@]+i:˾)ώM_-jPUyt-mCK &>2WT6߸eW\ܱc]q,aY?06o-(̼v6ZJƖk<>2y SX\k'j< Spt&txj)]}ecxqKZzTF zK[OCpz"3U2 n__.X1")qRCq-us^H(PȻPʞdUw%XoN_7 X^Vm/]?vn*dAXjlI2lUЀQq٫{b(u7qX2>i8;ՕJhs, t$Wv+m#f ȉh1@YQ+g>fb}THXYUoYW<!:ytOj*jӴ6O-=ǎ$3k<,?C_{1xљmgEFg*pt 2ZFox Vc&| K?h5;n;_ f'T8=>v+1(S)Ua^N{ˌjXgsC2a"VJ/KV̊ar_B(!GhK{C^{;:ۉoM?:0Tq+Q$YRc;jg;oǨwX]CRO\7ʲ`&ehcYѪQo=߿f*eջf("KAc DGDzt:e&WQ64z C+8q9Z89@Q~Wh/(VV)?(%TLï}lP⥉c/fMm_{_G'|+:rszQ ]ՠiQcXn_T83.Z'e}q{e;Ϧ@ryQYQlEʷ+i)(?~oo=əHܹAj^ U^g"? PYR+6Ky9:}#!IһCYL{W%0,Zwò=FCVwsh9 J;p||y-/S[J;:}nY͝}l&gZ?XtD| X]-ϿۆïLN]qXTeH3:k~|eV)-{C &'}gj@iЅ\xs!brm1tnf7g LRf/8+P9K̞Jcu':뙨KwuyUl]$ebVWޫ>1ĉ.y45+\ TK,\يDRF" T]{kf$Ee wG_8,o֩ ,"k3zE1C]Ѐ F6O*ٰ%桩Ed&MWc25HΠ(XeQ`mysR{\J+Б\B-+?tw-W@B-DAuM X"qxh`pSeX*`] q]Cz}$hBۼPΚ(iݑM6R! çf. LV6aC֯.1TTw9 @&ߘX( bÊߕ1'5RB2B@5ELvDY $c;{Gx~gZjt+w$2OS0>ĬsO9"96\l+&Sbwcq cԨ l Ed&TUzrNmKΔxZR@",^36~JˤwzdY۫,Z[o%+SZfڟ젌4P$ZCWeWw3ΝhhIf4PVϙђ$h?q.P*R/.]X,uElf:E:Gh.hMV1JĦ8Nd>rPF[zrsϿf,>:?Nr|;_ꊪߝhU{6p8߰Ё 4|i>Mc:^H~]_r˝-$kO,6tU7xcNgMe~cjo$S]U=?6 Ie5XG ۻO'o u9sNVzyHi{.&^{acc=i>^j_y)QdEHt5e y8@1c5Zy,K$fe1)D rM'"P}Uu){qy{oV25,( *f>{\lh5m<p"5ɤQAv>:i;eEj晟5Wn'If f{62sԤ!RIXYU ( fl25cL49a(0QdC~EqTffSe1z9P:J5|,-Y-l'_ZB@d2=/?ՍM+V-.ѣ- !G>⶟8EL$[Y:clpOI07uSl0{ƺ_kǂ,W_h/(VY ezgOCz_|l֪s9KKJK,EG!Jsg)ۯs.nRc "2T IY>@D1lKB = +hP a j,@d [>ytѨLVC&@Is1ڢVBəewP6%3dW:)r Nm46USoTWbjIN7Ul}jZ?6ӹme-gnjEݭX06y.y榻E=^/GPh[%g;" <0z ZVezw~[$, i<秆\0z:{/|SСGe0|mpR}h<;ޚDt˧ml25w4lr^kOgၞHpn߻HCPyV<`4/YS"dl[W1qUr!<K& |fڰ)x*H`ljxǁktL69+" RkI%1!q62*D\'i760{#"K1%٠ 2eJK aThjvSQ"k-xo /ll,=V8||L?)fv]pS?*(JS]>4uTZJ/^9<|=ޢe{_3{7yKXew~zEkˇ>HB=S̀7ueʫ.QK&]d%NUf:`Il4p, 3WFg8/sCugcPU[,/N1'0/J482!lkuazND2B8R DQxGt*m1@Oqㆍ3:""pG<{+E")gON޹UQNI3zW!Het6c9!Rg}492C馃`/0GYPbҿNj\uF#im"-YwJʡ3tw'l0VmgQC3[E45㴔RA&S4ݓVgcC׷<:4%Qٽ[YQb XpYkkN_im޲-;o7)(ʱmwO-zjhm{?I8/JV_ݎ&b9Zjq,Pl0 Wk(/Qv#H$ c('IS5PL&aO[oɲa(n8#Ŏڋc'QPH A@J"9.wT"ӘRe)upbkLfFSMBqX`tlϞ|E0.'I.+Z3ClN K'Uf}>:ռ^.gۗm.e+IC٘WcE>o$+b@c %IKS>;@u@EQ,KLPjY/~pRw*STNKC0FO(1ͨtAs\i. ''L:;^[u~-cUɲ/9mH T ӡћH͡WL{mUl4k(2:u&֖m .3aP9L0(f5_|OfKZcP"JbΠ>{ߦ?g|C*Yݖnrlۨ "KS:AǒUE&NylUy.F*m$AΩ@ᥞjPm j\ȱc'$8E0Q[əJݗpw޺XoǕxP[wj0qoiZ~lݽyꮌ9.csW+LPhsUd8t}(b&fW$e(Y$ Gh5+R&c huዓӌIlz.-*S QE ʊ !%EP:~JYΫ5Ujee j`3 mU"4ixڷbt Q[nl{]Bc Ć(qY*&NU_ d$81ٙMw=^97c1 $OL7<  ~ht"AM=%"˒R.#+ |IYIxIcծe;z}^àfD62>W[;~g@QTE$I1GQ,2T.l9\:2lT|FV"W](>sԆwʳl\Q':66/EdӊW{/8.HP)ޛO\/01A 9gV !ty<׳ka& "j .o F(R8Ɉ fv4&D!Hyf!f2f"Qz#FQ"(Z{AVB")ͫ6ɾPOSR6daAtfFCuz>kdtGl>U tZd6,˂(q~{tNmβɦ{^J7_p   3\ *v7qB&3lW02<=}ai<6K9I2lB$"Ǯj`+ (=;.`*Jc UZ >{I#4+s_|.6;aI6QD)$8*(pVd%6Lш4 c)T%ũ,!xV0*6"MkXhJɤ;V^_L SpQ5)FMkÉrwxAcMV/*u7O{XrNsI :f6l dM5hrkl<tXJp:kqe#2ؾ?s :˲ K._} cTpq wqŃ9~>]iO W&+4Yv[ FO3DYA7B =*T(x, JVxTI 8 (IܢDYEYYE) PäRU0q ]j$|y- h&8,qN$C1F1*Y<@NmdC1IjK^>U&3t>PshYclb˹lbhrb|? hAd(M6J⁇nW>]SS{c^ߓ0l/#V h.iY;50jG/6x?00juclp8i-YC9ApuARudl4z % VD:#r,xEUL !N-= +d2w ' P| M|Hd(X ږ Lq焌Nm$a* uCg"l>X\e)(ӹ\bH<5WYgev;bqtj+Ƴl;vl3'$Dh2[w\n58lRV5#Mi)S]MfX^V@]dI:skיx\r2e(@"hTHV2r pfԞj l>ҩ"@`sIXh#5zw)Mg}ABAEfjT[դo:t(:L@|e)Nb*R-]ǻӪ͜Z ơ鳵뺇(Uxtca`d׳';?tD24Wjs&cTFASɈk7{7߳[{BAVGx޺ZELAüf}E/8<M;嶻?P Ϊ,S'D._Vך+1Yg<+)@pU4GReIPXcDLK='beQ Up)]w Zwv"zJA2dM=#KH*^`:Md٘YRL(>^khS^cKK B&zGNxjx|CT>c6|[|/u+~?lq1yIY@xݤ!'uh9@۝ߢ5&$3鄀\`ƢU'窛[G&<:FyIV.F %(i61b2F & A (I(4 EV(P@FTqzjV ̉5\8n ("8AO!$ '+<-ZG4PYroLdPD9Y"qLxbΧZT\}<.vI^mMdD%s?飻w>~xKkݏ|v$ 3"pI +y<}j6WG!J0q+4a%_cS{:XԊ"(1Pt6! GJ\N8X.]Ws{rt&w6E[QKdʾ?;lINZYS{tˈy߸aآx(*q<m{ Uc $S T!TK+b?6:(=NvPmJkY x(/ (j!*3XJKk@[ډiUYuɑ=dNLQ|JnK#kjw ̜7 P8屔ʹy֔M] N4,9rJG:.K߹fw*p)#_,DB%2d89:<<Լ~G 5@HRAM| 8zoa$I"$:68@` tb0'ݒT, '&"ccB ב> ܜ~ @gnG&8 `I'=n ő,xګpHd(8FRK[l۱i͚Uk-ϫ# [3':۰f, MfY׹oHdZWdA!1%c(`2ZH 9D(DIH$F#I"±pWR Tu3@̉4M]qsLGk[y5/dD3֊-olp$Ȱ{)VFƪ..G::f]˖WV61KI>AKI0755:MxF,H9$p`'bI6) AbW(ʒ m @z;C 4\7SӚ|BDNJ[`KK.[SsX'$61LF (_MӉxBˆP zN50&MHumH(E.lT#S0 fYBIQ֠;fA),IVXA2,r@NѦRu4tjRhtҲ{ZA[Tl|'$|w@Q{\6sX$-*{,Mn32 ʤYMDl2͖p8BYY~7&/IeyI<#as,X[ gP+I D%پ0'0R6o (EPLvP@˲f(u 5wsgEE9M8OHAQEQfWT eפdϦY4UQ׸8Js|.e :qx0Fp9 |vG'%j1PRde$bd2?W׬sOah#MQIjk,ˣOoag!dY607gX yEQp"ef?{[YQ@y(*钕!8%1C QYMʊ@ 0al釭u_XTOZIa( gy.(CYc% ,L81Ȱ+w? f6Q((E s\VQD,anouMG}ԟ:g 8%tEXtdate:create2015-04-16T22:08:22+02:00%tEXtdate:modify2015-04-16T22:08:22+02:00P;IENDB`zevv-duc-b8f9659/img/fuzz-on.png000066400000000000000000001622401426703022500165330ustar00rootroot00000000000000PNG  IHDR,#IgAMA a cHRMz&u0`:pQ<bKGD pHYs  tIME8q?IDATx}u|י{e1d'q4)%mSnM [iSH!ٴ33I3_2+2%=fΜg!0Y_,>%,fqA_ŔH$ Yh8LQZV!1N1E1 yg!tO|1K™p8] @ c(iia9Vguvp<Ͳz1-=Ýh.u|1K-;PP 񡮁6ASh&^g -ZYxH" `Xp" c%@"ޤg櫮nނ%FfXg9>`3, (ȊUUUJTBRΧ #`i1 M>JVp` M9E:)#3eK}-ЬpFc``(') *EVԱwV@k@ % в: P($J۔ڞH"4:Κ[JJ+VZj/E_n%̆i4̳6#UEQJH LJц I}J!Z]pF1̳r%8IxQ|OH,e(-Ok"a]9EYE%Nkv8i gPVuU%@tϑ.آgmf!)qd{ N-ΜEVϙ[qܥYI81-0!H{쳷-](j<)ʊ D7?OaFVb1WE%(&% _r]QaG`EaQ[IV6kjh?,+Z!Da,&yy&R_, g%ކV]4M4v ':m3 4Y$ta,F99*!oO #hނ9,, ?dŠ0XH7FȠ :֫z܎^jW3#1kVkoбMI|ۥY~ 9LM>IUI\K%фh6j2 [{|isg}4=&{ J^% ARAk'9SUYL=7/[?#E8u?;~na, g6X]cZP䙱d&-Sr k6rҜ*˜^Olˬ U߂J{4c)M-_ܸoYSy1K#tބ@αUFȪ %z['wYkunf ztƅ~a|2dҙ- 3gm:Լ39SL cjkhF$񇇒B|׭b60KY #4SnH7)*i*4Ø )+$1&@Wâ%_TUypyn*mO9S Wq7hfw, gq~Pӌtѡ#rXǦH9WUVSƩ홖,LH$$d+X;p(t3;'E1T0/2ۏW9ծvGYZy =uYi,=oS?v-Lc Iґmo۞}74xjKcK+ȱ7׽aMΝ4m4jzXƊ,p F$IXbAf~{tJ۱U_$>ҵϸ, g1aP-5WgݾD[j1(uPŸn4NG.7ޫ3'-@HѱC<L^WV9gfpK({@U+B1)=1srdi.0 yZi.^>wy6Ԟ<(ۜFݕ7A5:'fI!EgUv2f44yV .(P 0

8Ug);<]bR3"nF( +<ɐk o'󖮘pVh`]_z}G/Vq/_xG莯/?w=1ymX{DI'oOenz=k@n`EeA1&SC҅*myk.zcgߺ_\ðɻ`1뢘 (dD%@Zp{1z(LNAQ%C`")wym۞Kw Bp@4,e3g9o{GGvMJUUݳ )j,M-Nڽ]]$P (j*d+Q(XMƪ]}g8$QI$/p̕ŧ VsV_G/nܑ8 A.3ǟ=k$:+=y䐦:9ΜNh͡gKYx cŠE3W%<ܫqN0޺x>g;k6=GzcKyQ^UI_4QYu0Kֿþ!22P՜ݿiI%uyH?0# D QS%DI!kSoXV];)RӶt^6--p,`$)Ւf1W<+^˭Wʖ=3@yG,6ƺLwNLpoWg7Vd2^ƹV}Sݩl.-`>xj6<(a.\_ACHk"ƈd_׷v Pǧo/sp DA<@(@`p\[jr޺[r sD> F).H{C%+y8K™ s+pPƐo̗Q11ũ Rc֌i@Tt'`p B1?pzc 4f@Pq3![/_k.TFM/> Ld` 1A3rr/ɝfљX,6P:yN/!(3Et382"׏{uAYVJUzsM`/٭d]cj/8&xGIẂ^֖7?8Lۺ1+ޓk3( lynSFl ̒pf#k'! #2)ލ.DMQT!]<{%1A:XK$UgDPa.YV53>bf>̷ryЙ#-<?^[hm6,B}:9n5A,4N21j,PqY?AT g. + D[G*K :{_m EzK ͭW~ͭ}xRPU'kixA"z.rL99xt[uYvˠ>rͺR{6@Á@gywT/˃X!@Fd Xhഐ*۲\՚`Kf>0o>pYL9. XGŨg_V,]5_iyU@@U)4O׭^ dֵv~凿mjSZslYAnkgߎǯ_l*'5Uڦ'M)|]m]3x[zڐEus75EvkxO%wZ}o7 zYmO>:QVC*H_WWWs⸪@ڴi;/3dYz$D) A$e1%jЃZ *!v$(pQ1Dª{?zSl:^Lal6CU%-=)U5:/;-??޶qoo{~ -iºƖo|/ !ıG{S[ y{_/ZLƷ'O~[oE"o?H$?iZ8vطJYQR5)*)?42m^JIqYSsDcNAQI:-p׷u)-ƞ)1B6~9߿޹Ѱsӟ%`?Wo jo|ܬ ׻b|8xf}0#^uT}q~_7'3U|۾/twz:Yt,{ݳg%pfCźƞf!M!CqjXiLce)ШfB,KCi~6DTg?g`_yݒyT9RjKV,, %IR8"`Q@;a['+bFDNex?>WU}hP˲"JR"DE9lV0NsmQ?+V$7q3,ˮvk2O +5*$yɁ D@*Mp2PndYxMB`mr~lyqQ9Uudw_~lI'VdxkŎ7q!ŗ . xDDY}d6iٜ|_ ^m5<'F%#ʋ~@QnjfӦMЉpBfV4?݅c$hL=I4 L"z9}0ՙ.+HNyqظh~J!LGvN9cP*PU4L0!RC]ϙ ?.GQ(8O*ss-Z(8HIh1$ 1! āAa@0HI *hׂY^൪Ees\ YWd../yB,ޒ'eZhcVhDSވy :dd4#\u};e5hve *$ FEH@ӂ( N9"0:@, D1DI@TS1#Oo4˙d?Y) Eu47K<_TRrS$( o7_涞=yIcQQ9=Ѻ΁y t>S/ѧCZRY?Ý[t:c/-1gKdW} \xْ7?ҢiHݻG?iL S0r8CZz}hO[0*ʈ cR#Q*x Srx ôLΝĨ miX8^udyQw亜:~$Io9}o~`8u 8t*_|k.?ՠ_Dcys!:WI˓Xq< >WM&)@!d0RSWwlK}j3<~3r=]#BTDQAVGkj?pT H-8`OJ/dWѯ: EW)jI }ЉB`X_Y\vd"Qɘv{jW/^Di5r˖UUz(MCCb߾f r9*&t> :ZFUWDU(_=ѫ渨 q2P>s 1*-t€$IbU%IZ&?pe _)8$LAG -Ǔ:Cq8 *3 Q .PӀYg5i'#QEˀtWMs/-S{444]iv-Bb ;f0 0rKQԸ50}A !Pei*=ȟP 9 m2YźZkɛK38f@O8'̨Oef2!!, Gj8?twKȻ',e1 oow~pꎌBSh=aamA?ޖ}M3 LgZ]/Nwғ2bmoyKV0 {I c\\V-כT2 AJix(yMY? VT\ %Bjzh$ 4jA ܴ&3ˡ}/LPbUOl|DŽw-Wfu y_V$d(= uV^`^IK;ԤE"i%jL$ZNh=q`/Խ֕Oƿ U>$LD Cg-(GP s$=X A75?L/ϿvBIcunk|9͸HFe0yõd!+y{z"Ka Zɣ0\2;_欰;c0BY::CGá߫IϲT";.oS 9hewXVd\$Diuul>~ؒk4ϽC^P1(8(FUWf%j`{]~YfڻjiEi=X,?%=A$! n0o&=.3xy&x'^ӧV8x94$Y%x8\$6rgf#M۷՛L6۹h^o;%r|kC!Gzh(P vv=G}KOwFշ$os'-XlfWmHe 0*[CE㴼'gn4p&A7>)JGoQ%ۊ3jz; q90Ʈt֚̔9&C&7. GsI_)[zxvܶFhoP,E1**윎6Wi{^j?\hNv" g_'՝q8>mq7,aD%EUH RRRq_j 1#MCߟ@ 3V:5tim0kr pS5u[^ª(q -Gys杵e<W6oX[[H\E(PB)Qű%l3 }qCaTz_Lb䠣]o3r9/tgm~a\͠ySP"6Kc X "8M\4,zeҸ{*߷ a민Fԩ1ڝY-'ܳ ,ǹ $1fy]p#@ZٜK u>(ff23'{"^o85mO!bpݴ;FV_y֖X̿́fCCĀPH5_%Ad'B2a0F~R`'Qgag07~4eٰdSo%G+6&T~nE $hLţ&MדͻMW: !/ȐEl6ךEκpzD򑔫 BE'b1KapYRHtr"]^4D_ Ð5𝽵$(--wT^v5W, olWVSC?2ɵ,. CO.piy5k޾P/ ՜f}U@/;k5;-?Koz(L9%Ysjt ei߷`¥v<<ɘ[NwN$)G#*V+ 7Y a "XYHpSWLDa°n+*X(7p‡Qv,=4tc Ug9(6|Hx@q6O65={(Dyi9es|0UUy99m-d3:rY3r:Z۽kO8 Ev)Beh٥e[J]v H[HDo!ߣ[:Pӳx,&M±0RLP0YGILY "cn rHW\5RYqTWuEaANn(i!p%A?z+)4\.Y7>r4_03H!ݞWT_\OC}Mu'{ZhnAqCФl4[ܹ>!Voo-T+w}ةYEeǺ=@gl vvkZ]ok@T6۝\9ϗ}ec7`-k%vpa(nRE,XBcȪR"D]60`y)Ǣ8kNXT*˪vArX}2 b i f=3çKQ}¥ye<-}'ve4#膧7feEXN&'^_gNE*ȯ:l>ezͺAN@[_wN3JtOoH;;esH;.LH-CBZgp)԰yyfpfr3-+=]Mͧz{YpN QUUŽWP%<5d҆d/k?n~fd,4g[^SƁfMq4FayנϭEuCNYy %(,%q?v0*1i- <oHt[ =(slm[uRH>#axrcˑ~UtAPn C#D{EDO aDqk=3|FVnai3u56 ~;s1e[_ndWS9^X2pzzIY ~OH6h !Uk~w{K]gWւU`='] .e:-MyH43)!(zpÎHWW}O &!4’E+L]Gڳ}`<h9̔v_+\SŁ !S?2QXn 뮪n;ܒQQOG˲jOG;BrR"IMRt {GBHi,Nl`5NF<3DBy)6g}KT8Vx`vVz\;r;_ 'b:A&]>shm Gbu+J!DEWO,BbH۰x˶ڬ-=U\&YF[[r=Bէܵm$K<ز7i2*?)nf,N=\ww 7ŃdfЧC,Nv6>T{MG^~QqŐVXGQٝ!`}['W6xyőT H%dLot U.vsrתbBB/ʕ!I/ ^N+s Z:z_> Oe kՃ;k= =9Msr qI_,eBK>/?,;q-Ax ´k.wS3"w_M1ius=VNtnneZ'CdbvܷiӴ\QUIA$9 J:aULN@%%^/[<{< A%2B:<\G=G[[c)A3!]$A~{?-=ʔ-fiYDIJ2q6d$_ȢOXcXLReU HpvtX)C55t~#ncr'pm3n5.SeOapkflz' BѨfp3S9-\nn'Le4UsȥŢEivX,6W3P8)L(3$"SrOQ}/,7usr Ei1 `ڰfAE>DHHYPgiKrFϳ%. 0xy(AiخC͞Sݾ+o^R;/pXGK 3G$a ϡ9m[#t5K2vqEZܘnx &mf?4f0y8(@ "6][775nD* & C֌0yWb_q5c)039C0#GRwDUl`4M3mR@#&v?uS%A،|VP E)@DW`=DUSfX٘%zrE;јu\W{{<&S֠߾rE.gBh4WU_6ܿkOIyEꁤ0kety͞mDwҘkK h! "TD6O]UmC2x J_{T÷ew,#=Ѡ EQBho琷f{,`yٙY!rbͯ{1 a6cLE PāPYFJ9F?; 왠5Bg8-~,@`_qPAb0 J EAN@(( H >7d~8{Q<qe eNB:rvXUzES3 zu~010:9O񅤸{˱]zzwQ*ˑIRLGc4Nܝ0 0RRR'e"): `553d8wN\OۦΫȚB~2Kh@iv3e/Z sa 40X$c@iAU 5e8\Y`$xO@bp'fbqMp FiDF3=B!@fVb}/{$¡`Nդ[- ںؗ5R)t#4屓y25cP2DoA@]ywE_ nbuѯߠў'UQ7΋'_[uU0#k$g;{4/&NN^.HHU+4ܬsBj0B+'5< o~8DK_^T]囮[_K$Ǟ޴S;NvWDImbV)NO v;U^w7.hի|sWA^c{ ,zE8؛`b2Mcy8yÿŏOߟ_b_Ozf+< a 6Wj{_GZQZ.6i t!+AV64ބ={g F^௿po:5'Bʡ1F^P*$1`G#TC@"g~ƬS84ǚCp-7{  DIB ݞ_{n? Ay_Isilݴbs}m(VởP}k$nr{E7^쉇@k;cdSǣ!GE^sEVfVW{ˮ[^zṯs3+_4->r5: |.8kW-ߢSH L=5$<%%i92Cr? OB}ob5PQUJ5o-ek)% ` ]RB)dXf)u"ф[H`\PNFLzA(g:4WX^U0V3E54"@nijD2a 9iN4g#vؒ9%R[cI~I|2lzGCBjYxW_s?wMёl6K30oDik<7h֜B:bZrBLB?`6[ ţs_~0[@5bei2H){8RUQ'3R*F@ &IiGٔKnMz ŔzaQM:XG/zM}g(+1?jq'׷ܰb 4ϷYP4( ֣ۏު^?$`YG1,Mū)*QcC[6T+&"P ~˷[[00sJ"dorF<" Y&i S5='-8c*ok ڝG1x/YL.*Qtfk#i-ܡ4fxCBj%=uªՙjjjNH4S5 ,n MS9\?ALcj L!Tm[Rלy鄄:f==ޒ:-4_?,Ix.0z[X6wʬ`@ݻvx}>)FkBW_mxyޥfhu1w i8;4ƴlc&9ʨ$$DbJ+^u¢ 7O il>Ӧ)#te:r a:e5=Ym{gd"JFaTɘc6^w8A~"Nw7;;N0ك;J/@Z_/EC2 }0 E`80XAJ ۅD=Nѩb{BLyb39fP粪ESo]&0hdd`ႛ?pjjᏦM=]d"6f{lP!(= o 10Ayj.7#@Wml0^;≍;Gc`=hBk&:Z蠶LFq$ ;&[r Xz--B3V]moɳWPٞ!9XjJH9d!/~ -Ts).sO+/qߓf|g}O<ҰA- %uQGCFooW_H?FcWը+M:{}Lڵ=%Y%f㉖p,:fS Sd%!*OvXO@J&}ЋhA@L7gI8 BȞ&]ys 1 42UZ>xh+Hi\K0HJD$ybYr&}6F }%(06 =8]0% sR)}á\VY :͊֞er09BKb=]|ɆswTs>OX g+U&5ҧEEpɳJQ& *Z#CQ IHfUR0'ӞK sZIDɗH;,Ph ֠Kr\߽kKC\c7TzZ%f)E]R]5mm}Q7ݖ^^gJ;CN4" Gaj2" H8V-ϯ|U :ukWx6ؕ˫r›ݾbސ?hѲK+2:"HF'tO ǡQk!`LƔ$c>Duєi8-V3,n3Ɗ#%VUU S*wW;#]#'rxO)Hw'f҈gBR"(Jd/;j _9;t0utlMϸx9Aðљz"4^n+XhrՌB@ mq!G6P4 uB4Q ="~h`y⠷@Q&`9ݟvz,1Q!cS``ly H<{{ 'Ɋ>߿#*#^np04yE:{bBԈu_!Xޭ(EV 0'>d̐.樄ks:לy, O_$}VFPaLڰԸyhUEZZTza~%( z@!@ThÎ4RIVehB>௯,  .~QCPכnU54ɵھrs>uӍ/oۮRG\'?5sۻvZ:o@Q57!xHk=`M**kzddP{ `l1n J*tE2aD?3d:42LM<s 5z]3_7'YttYi8LQ MC{_EUUQTao)Ca_ObiilYrlO՚gjzAe`xq-ſ:r3\];\P(tȯ^/{49*#B|Nyq3*GIIhSaFx 1/,Iz2Qxv1ѷJ"eyO3aMۨY WŇ`DcHhX12t#D@, G}8j_ *![o̺ۀ3Wy | ğlwJŢ~kiv!,r\ه6>yK1Z]2c={TVϗ㸜UWx_Hj3 dԉ@!] T-b)5MtGLaYDw|KP)  y BδHSp*)plY*ywL92Yw1@%׫E`tzyhk!㐙 f3t t.ZU8[|v~3Pdu mױ}oKL死͝[_~TlYW_Xtf{۠OUN1-܋ C3&FI $M7d)p/M@5)Oҫ~.r^=V`0xy` y6k"KU50*xhɢU]%RT2J*3:[{@Xh{3nwu|/VsJDU7,bS+ʻW|-.;ꫥz\,ǭgpzaA@IQ MM4:Fd@n4Qz'\x0aյR(ͤM3ig].**{ _1C- E׮hi̓OyniII?C_Bղȱ?!W~ZSC1h G!t h@ фSk׮]bDDAYE#}k[GGr%"DK.+N(>&aE.bGTSIdp*fϢ4E I|j"1NiiIڪIiL !c3i wDÓ!6 -4Y0kgR@X$lMbI>uXN/|o~k?.xapA4˻?}}_!vu,jWWU"ю*?s':(-OWף枞 \A88Jϑ:4QH;o()wrSlIMz'CBhUr'eR&@B)d417!0ҕ/6 ܺt1KZ0VThf`([ x'3W͛;ו8nڐn/S : 8 "%a\{Ç@Ud@$ 4,^hΝ\y[l9 ioojn{t(avHy5dY !r;H$:;;S!uuu:j#U Á@@墢s|S~ޱ+~O>~T=gyf``<#k03@8~PJHFکPJO%ݏ=DѼk>sEQ/~׻EwTc0x ?oZ7ސ$ X쩧8׿VTTuҞG;,ẃ֚ͪިx`6YpB0cNgOKB "-mэǒq阿^yd,4ZW0% \y#H A!_7D|ł&9"ɸw'4תgS+E#q2Z+M*0 ~9+L&ѧ\>|x'm6[zzs=H$￟龾%K+V^dӿW_}˨_Op֭%%%VrZ?kP-ҌӫAV}ͱ V޴ڃj&%  I8VQQQQQ!\z/l"Byyk&L8:D"8;U;+bZZZ~~%Iȑ#_W"87d䥹s݈B MZ"oM$Ē4g4&T[t>e@1_cynu-O e_떟#$"^5 F2Yy6rJ* 0wj-))9x/KI4 q`0;;~VMy Ə5kw}Gmjjl)P$58h!@tj}K*/}}Tന)ղ:ݔGSN}0F ð,;3cp)>yտdz;t;fŢ>z *Hel) b4˲<fQ<qBtZ,9s@kkjhLNNNzz]w-Eq"G ;"&U-!d= rI MQA@C78RIFT+ Ee$;,7>3l<*ɲ rXaNV?&7M&rw ]*.q Qqw5ibK`C(v0$ h馛׿{׳,[RR_Rb|TL,z1^bO?-{5jca`n EKJDžF8EB}(My;?&-VP*iק2^BjX$΀5YuKֽj)mnsǾ{A/bL}M]4Mo=p@ѱ"8CIN _ioHC7aÆ |sַ|nnG?nk$3LNNlذ!77\ynݺx7gΜ>EQ-Zz/]GV]]#(:+UV=#E׿x?ϛѮf<(YjbM}6֠ K:}C~Ej$[x i4I Ù@”:* y\@~μqtٳ!RKZaE 2Fk^I)`3_GNohqFQ>V+W\:nڵ`욜~MKKg>3ן{@Am1~6'DŘ9f {'+ >U; z;cjyžNA͝}*$Ĝx$ EܲI(*IJJNo4 g:YNEFb} 3Cf0 [-`r 6H+ ʴ{' }R@$=f*z}_ȉ! nVB/U 'b)RD4'E8K<~vZ@Z`ӂ.2kwեe:jhGTkzBdY50 33Z!. bsrr@Ve/3[ƴQ 4{#wvvW:J|,3vr5hYaR]AG-chCuhw흶D"1B9#0q2xP~zՑc*7 hS/ U*7=X9c27X֧'_}AcgO:8~yѯYe5{+-XpāS!Y=:z˜±L*َI^M$ˤ_8%O (c0:c/f-P**DgҩZ-v zCAAUU$ 0ң` , ` x(2J{cks{ް|iSw-&,(~m۞X"yŒyzsKQN Ƙ7j|F N- `F憸JM /gdH@F 栧g/7MH:y+:Y&!:Du!EY&nJz<7/5On_ hihzW@QT^7=! jLdbOƾ| &@&ês{B7,?,ŏ\i1c^ըܴޤa|͐$ GSj'22!Le([9RJ#rD[;jO]>* B֍ƶӒuQ: 7}72N*88]= za҇$̯nݸB[\h^ U&w0[ (w®7޶z4x:kR.h1 9)L2/oc&%s@$d)!P# 0U+|`{Q^~J%J*Ƭc)ij+Yf66>a*j$ xEc1sF7ºT5VEO׾7^osK{yO![En  12p-2B*ɍIdҝ$7yjJ%a]4n=E1< *D ,Mqz]^[%IJdiA40SL /eҹ.}l䷿bA3 Hc8}$4 *bŃ|Fs:N'>T_cb~OHaLmQn4SǘFy~JufQ꒔3 i ioX]V&'jǒR/pQ,GzhOT#)R(W\0NƱ$bBţT"V'AY^xnF)+-*-#*˹pNɝ"&?.+IIttY"޴4J C`;R cL4 34˼;ӌP!σ _yvŻxB:}3f~Ῠ [) R9wݖuߟ3:O`mySPk|׏ܺzYq>=r8uq׮^?HkgT !=M|n{6qMVenI=Qwɇ[-[#=*^8?a42*Ƅerw~dRO\ !!M <;Ҧv:[L"Bs;]XR[\vE@[U΍@ Ǥʱ&0UI!!n7BnVRSA k=gZeYZ(iέ׸]-@0컑Ovpj29uO$6L/=v .G%UIVr bTQDަFm3AA#G]$ G!ɝE "(>x3 |u*A:73t+-ݙͲ,hW 5TՕr0njN/}/<$长IcYJ|WFOۊ57HniGr3*pX1p["!O!l"NJ"G7qe PW[O޳M$ Ax߾1^'{TZ"L9+mKv$C'lܷp/v'j}00%I(HTԚ wp{iiOgS6>_$GUPүXߠs: :iV]"Pյ| C  }k?Vj&,8 HsVeJ5ۭ?Ze4C!OÄo0셜E_=7U%$Ok dx*Φ~0$!q`zb9hmPe _k:g Pu_=„pYbf*јpYh0, 2\'ݛNrϕw|y'M#JD<@F3aɗyuWxycOy"Oxu+#6 Qz/K_>|煯}҃Ͻgu}yaSFþ} ((^mW~YuڵŅkHaL{ۓ}=5G;\DBf'>"LSq$y׬YZ3(_~xgPMm"SQK:T&mG{_Z58&"b;iiSmU.FU  kVGѦE&=:/s:7aNs؞k+hKT<54<\gi\f>Oז:t0QS6!6qDž+U1 8 =y*7 ϋd.Y8-'tz=òs #aVnQUqŌRzqZq+v(J#MzyJӫӮS;EfD#)y#WO;!P ` ȳuz^[Q^ޔWOʾ%@Oga`Tk]i§A 0+l}?oj1rtrW,qyOoWǑo^;bѧtj}5yZ;}sBF#sB4BEe$8% a$clܳ[cyy8Bu0TwxB'P[=%KK @e&+ : :'筄c[t6_6>{3j75nLx)x֯"JMThC(k4i'!vt: Ƈb $0V\sNgs,(~bFZ_x *!{zFc^xL-wX_nw\gySL}fޛzŒmp BH @ 7.1]ek2S+ɫjY,Ξ=mo}jK`p7M]dOC8";sf;_ ܋Ό"sP{ɟ] b/y<,;95aL 6'^!\[_$*O6Y+?Qfqjn8wZ*)^VѴ>* nNN*Y1 W׊PYDJF"k{d"[">va>Z "祈B`g]wN\6hpD8J6kGq@β_XrP%C6JBBQIVcv~PwwO`?H84ݲw1+\蓭kGIC(m*Z^BQ{yp".!|G.̈́g?'XLFׂ!v]ن̚1,rH]20`V 2'2kF\@2 ͧi ~dVbᣱMÙ<esࣚbQSL$mz'N%L0_ltd~|1KIҫ|ፖmmtn.|vk@ p8%#u)brޒOy Bxowb>`Jp^S@fVzEłE]}2 t /[z9 5 .6h'{+EeX`Ga+4ZYkB.5ptGKzK|<~gݏ[jӁ܄gRѕ r;<‹S{銵K:n}(9zi$u.O4.3 '&?x{}YҸXRPS@(դZoi@_gGtu䔖/!wWS$dBW/[;aRr\{(:nɚԘr~z4q#rqrj&&NODAߨyًOҮ@@%zA{ZOݚmFŶq@Xcn) F3@[+B$[=01z &sEՊB&#.EQnѝ{ I۞@*m:(C 1dlzbp??G!?β2UT3֯g IS8B @e/` &.|KmsŹl  oʣ?ߚ{:^CD4x!#*x 3vGzu5%  ';rxڊyE]'ۜ!@syfyEBF`E$ Kbͷv:0ɤKJ/,(*/0 31"&xW6JpDs?VZM O׏ x9CFDvG3#Ot')pz4zڰI.ͼb!Ģ)gh.`Xf Z+ 5Sb`_jͰϾRpaEǿ}o[+@ ٞ2S*3 g?ѲS ;NE)1$EkέZ5ϞڛJ8P,{"Ϸ˵džS_UT:E.([-=߿˹'LZ=_A&8{PV!wc·b]r7`/.EJ F-rZ 5AͦDp7+RWr )j4DXͫJMOYjE}HOTQ]|,Wy=>s>E!C@5xX;4tR~5Kn.,@J-A.A031i%z;̿rDMd^OVl ǩF Ykpu,FxBigo\Dxb)( 69rfpA$UaS~a᭾_eH8~\WQY' )|pB2b x3XYQ0"5,Dӎ(Yr6Tz;,{ߑEIlϪ9-/{χ訠x J3KbNl Jo=&h&Ӡy[(VHxd vRoGEk%uqD _:y)p̐=_ѫ5\ q H.dgW-_..H2džy%{cfzKBiw֟n>zbIM)7۽󽌉8t #Иڱ[u?AGT,X Nվ':I#L[3l zI|t WTіĎ*ktFjn ]Yږofˍ׃wV%di 5cMKP\f\(o8mLQ$.l\Һ,S3ur%bYvv[(tee-^5ij r=>>fVAD;Ny6HH$R\cm! EYE}d~YMᘮb$ƻpmʺKʜN[鿰__XO6sGO6ILiGdHw@. 6!W+L(Նǟ_X̳K5MZl4 q;;:^))x0f]WfdYv ʌ$p #6̐XTLXdف鄏I)7v>,M 3!\I܎:5!qN[o>ɈyF(+]%0w/WtuM4 lE)ڂ䎎՝Tio e.e)k)< BASǟ2 =! }q)P!!3 Ac&W9;nJD?0Qvd37AEfU u p MՁOGd@.Lv0Y-2Ė9xn} L.T$EZikOU믐~AEֶ׷uvb4?k㑐eYPᮤu.2:i)Eqݳ't8ͶXO囶xٳGޒCBEI6UiE{Xx垝_5@[ mZ`%1p*՞+=y9'Xp/ قUif_ۍo ɝSnat"kiY*mb:20(4rFoi@KIO g"Y 9CC56b@{4Zy_y^EHQT#C axŚ X{ew߳;{ʵB[ 75J`T kHtc~筈 UR4%}phUK:؃M o'ȟb{c"RDr{> 1ȁTUr`P:fq5D5nvH$MƥzzUq`,c{hJ -"Hmu\ܾv[/Ȅ$Myl8ڴ晪Tœh: GG{_qhP"K:vQfqÞ`P.p~}?+*,r:}rǻ:mUH}{`oه*UfdO;jӤ(@2̻+^@d Y^eU1sE㩇u|t#y=q_^wedodMz̐*]UKy%7OGq]Pu7i%1v&pq#Ͽ J%wz$XZ`4Lxw% U/ Ka#N J~)ɔOMIvv$95,SH/o:x,!`E^w<&'Nn)U6WT\)O~)ivH1N:l .VR5*Ft"箧-.{W†:y=Ip魧ߓ"GC̤XҾvaIVy~*IhKXݒrߣ &qw8;[.a/:\{Æ[969dǛ^KQt/3"䘑K8 2jDoÌPgBKn' uMM؀Oߟcbh".^xr̢rBqܱ}9JLwPJcJZ,}#pBo|ce_ύ~_G ZVQd%%)S\)S֓~#F,45><MuX.sEps$DݞrmOd]ء3gz2CC:Z :O~W|_LlKId|,x4 7DS ه⊗gx8e榤mssH>+k,\1pv~E& 䇆#Y8Ab'TNƖcV113fyK~UzBZP,UK7ef|y\Ζ{#.O_np_w۱^4(]-(H{[8\twܘg4^rMq' qw-SY"d1=x耯Tg/]QT^qI _8lvqJp妶#GJl)9OrDg41 4'6ܰӽ:4ș=:q>a-]"0:?)S7׈ Qu-1)sNO„I* pݿYzp}` qNX\FYU:gb$89R Tuh&C2ifȪ[41.?z$5.I^ئG{鬖./Xn 0i[V\_ FS,9,k8UsKQu퐊^_oIK6)] a``/Q'iq?¡eLKFxE8k.mGDRR4Hδ´rG&鍲h+&K&4mHU rB8;`\`es,Y~m ^w(lN~8pL7#ߜ6,1o%qT??\TL,L.^v̒Ѹb~gk҅E[ϖ=g*]V3e'{zK *xL(Jh4+WJ$O}7$Bud߇'Cd[K!I=}Yz1 m++Pm~u~$ee-^.4} Ƭy+r w4؅#L4,Ԙ{wXFC)pM b4S):s\Ñ%i5/] Yz%ceȈ8s[A C1ӊKWۿo+LMl[\r iFB@,{lU}yTd1p(sE2"> @,p:60ʼnH|߿{ӍoG14IQom);/fR8q7S x' I;E"8 W,_s}ffi _;vm'ZSՋWx@S{_'R+k2kƬm;FI=bQ,.+lppxhW_7o͖mEM;N"dOM+ J Ņ 8m:|.LpMzV3=9ٸ eW._hf8o_X|" K9-٢.Z6;t0}`dܹ2G7˕pXaAv!)_p1AD6~dRYSh愢C!zE14|d *Ptd9LD\~LdY.UW5_F\9F1>r߭q"jXĚC<=?|e7'+S{>_ +/rZv 0.+ҟж?D&[$KA{RQ0+34Sn/_jM)o8cn>No[fw}Mm莚ޡ"bHĄfi /qc#C ˕%s J.|ݹhڰ2 (l>vll,R(Hpa,]zz}XO]Vrnx '}<5=<>}| r䖫]Yc) -OΙޏk)][^1~v}5)?:$cy&]c#Eҵ }ԡKɹ)6 ,|~_9L@2Y2VVX]f"gO,*w@QJ7߱=7zgbg=mD"q]W.Lu_}2rf+"Ɂγ_'-Y8Ph'q[^Id"p 5W*=W>PʲlC E+6'oxo$. C%b !ݘ:9j|| GlZCܺVR< 3<ύ( ߜR X0\D 1[(3XUf_DH$)qgXoN񏖈2ҏ4fʊkwy3'v;MDH|՚̬^zМt3ܡ"$|O~F*04Jz>n{5I7&W`6@,i޷O><"QT} eZVm7˲G?M  D⇗9AE*7`Jrv5ز,EiAJ(ǢlH;*&i+=Лau IFxEF卓g;ۏfM:&#٠C$2O K KzNM^w5rEחQs;o]Fv?ZO}(^CCE(Ǐ5uwͦ-ڒ[T6g}$)7lVi4ŎNfKxBo4rqqnwm1< Ü8jy["6f(JdcɎ6-!pFs ԘF=eX100hWM87e F!2T>i_ule<:dM\ `z^-4-LEEpqC##+R;I O'CP )gaI{}P{?+L`MA{KM8AXIa_,8!/vw;f~U41 P%(ukpT[PW)eߣe*p}LSv; %GU}}9!=gbCk7uamDܡs~'P-lz)^q@oX)_m8:KI<-ӶFZS؉ ]"8#BQdlpS~A_, ͘7ڳ.C@ː=$Ir\"/Q1I5'W.6U ~u*Z.?XMx"1X ,"Rq]{Wl)Ɓ({o}v~jAeޞTߪU3 HI!}+Y[xK ~J>ak *gNY <o&f1^yLK ;Mf,ٰ qbu[GQ㸶3;NWI=38Hu_{TF/GGs*co.K{0W[MNEF u+8ܭSeY0nݩolr:jBHIL#ւ2p¢(QQ<5_$5ο8oL.E'y?/7C 1$Eb _p{OuZLXIAeh" 05ӃWsTDhMoqFښ'^:rX"4u|FBɹMPX|e$Rsf-Fƫo0^jɤ)̉#ĐǐfڙAgs"YiDyN=85= Qz^vձ]x3ƲBL G , ($8d)1qsņst+%|Bh4HP5 KPzc"ޔQo D_5A 25P @pMuy}S.w^ekM1vEB,0xB4|!HUC,|5FIEgbC~LH-6m)|I:/YwOZkK7[CWCPȯi8nblN2Y{V^nי:\Qn̰EC0yrws%,Yp3Y*qc4Uf& a@J[_?ǹ#6O1*< C9Lzs Kb8.\42(~ q~D+7aoc rqAm1eąrA89UV%P$Luk\1e9Sri8G!<&FUXJSYef.m,(Rx|iwP3'pkk9-'䒅qC]{4UM)@Qԑ=|ufn̖c;BcȘL1 \FcmKYFppH']UHfKbIP|<:~p4 ,Є#0H4긛^wz ,|c?o#PusRUTKπKTFUgo+䗜r͑ܳKV3tG~;E* ?<]D$|>%_d|ƃ1_J7h9q\[K#i3rK*f@ ֳ "Ye^ojOK)¯R?,jR挃B;BA0&@#΍q*!q {i|> XƖP$ |!=ϿbCm[g8P4:pݎ858/+I3{:&y ۽ap#oV ~[OV>cE"pӾߍg[0谻&Ƴۅ8Ώ )ŋ,*j  _SsADQ-Z9}KQ=׿~ ?uf3W|?*Rڸx~mkGxY^^z pmΖP84Iu"7v scUJb$uz~7x7n_L:ト$ /[G\߃Bim)pN~j6~Y:7ؿ?CDEa9H.*LyNBh,Ȋtsk?YZZlRgȒL-KRdu*M]XS&e΅·2 }w#C7vbʧ|AG!k  oKx- z"?˜wuZK%᣾CiuC:<:pO#Ѐ/[- (x<~rv$4-L)] ax筞0lTRnUrjڅ-591+fEIネYU1=ź/$;'\NRUDMeLfKU[^)[:ό}iH0ы0 >3܅'S6x``ip`|߾]V!۝Hgdl柬fؤNM%J1"?kgی9|}ZZgȵOXdL }s?yv#8PH5U5?|D~q r*ZmyM$SI)恭 `oT5/vn>W'Y 14 4ƌedr+a}a9qZC}ߚ348-bgfוY+OEOUgS^c $q?0")tz`Yh</_~WN~)K5a:6?jҪL0IJ%oZhܷ x{R >ymonUK31ł)bӶ7VvQ\y5:z뽏\qo{++gޜuxxBuDnN^YڢPǭz'&KP/ dB>p̪SYuLˮɨ!=Fp:4i&8]e<1:hUS2cG/_dﱭ噦gU]ngeze\eSY Ph\=&fBѨX UՔ(F{r4ك\= cYJ17ljy )b4Scn1 MרP&a,sn:ޙ>2!Gy *L!>3%+"ޜ?/n5NAPڶ/-, ѸB"{X7~n_ܟUo|Bոq\owN0.X-]M;H׫=Tk&S2*x KLݓNK|ʣ DZqR PIR"q,vbrzsj0$C,uAcaP8$ aVҥ\VMO6N=vE;l̎i0RpMO *z4 Fآ+i/,jt&X 2gj\%iNPryyF`,c@ʰL4E1T*Z3[-UɦM+!!꽿HkX+MB02ypTvbw,] Ndd꫍=_aY2~!]hX3!E: '~{x~HXP8S5ӕ5<9>0)$3BR[yMoTC}mGRenS/D^~m'JM#i/iSR8b_)ebdA1D,A rc|$!+43P#qO Z-P$ pʡ1?rGF}?<>T\ ,\Ԋ$oD.M:q' *EqgTL kA䔊w=>ruhWwNXJia>*NMO12Au›0 GdpMj3%K6xw8ߜDGQQ#̕\1%RX,8)S826[atٙa_\|t4HdrN7S1ow xnOh2%!$R$-OxCBqB8+,y%p/rRL#?mIw_98Z$K UtS6`vjXNy cX=MiGjΰ.=@xo6K2Z>NH\L "{{n c8$m[Vs.?-T/=!# ^Eq;|E%nغ#??޳) mT麇 vÑh,JͰy8'bA\6Ng@$,OՐ9 QyYID$DUgCD)Jo XT@q*W)*.HQ1'[^^褣@%3ㅙzo3h2Oe@9;DTp<M8gY*&7Y0+Q xќm\|Je'IR(c oK㻷 n-bxZGٿzRG=&Zᡍ>>1oNJXRXDiA7(U** yU+zp,0tdfPM0W8]|aygݘDgЂfXk1 S ygzg[j'Ϧ]EY˻NՖɖ4sDKif'+}c32=qPdp]шr4EE{R/[/ueWϡ(cʘ􉭏+*{|D,S" GY񾚅K/O0Er-q.^y?qT"vi*7SDFNP3KMIpLb?\t CSHP$IS>p^{'߰Q'Q9ݝ\jeٓǏ u6g| ˲ HIc3ME(XFʰ,'85[U|A}@ξB|q尩%v rpY^=׈~+S6_Ε&qq$TT+ Ҭ5*CкkrXjFNID*eBo:R~SkFa&3S'+64v4i3OE1dPT{јW"t ׯ{\U§%܂{[:֠7|Ogߊ 7`t [D=ʝv=9S]a S 4kתFS xQyu_wFBV#"1$K^ls6H_V DFj`%8uD|RbkL6"N:=ũ(PTL&ִ ^\igb ;U$GSM%. DFy<*C /?o^ uA oݳq{[!O>ODqhW+$Ftxb[]{Z~U)-g*k B "88:?ryFM\{j2]?9BA21/ Qz8Bnzj< gJZNT9;x<#dx5;0jw!#ꡉ)|gĠNk;a?TJ;ͺ1{F B6$>b( ;_moE3|TNio>QSt:p42kV5 "&I,(QqIO7ki(#Sl~wXB.VhZ CaᲙ0_񜚴SF֢+ي$˖ػ%BϨ>T/)v˺kQcXZ&]Ƙa t R70' HK [BZvDI;r`E?Տ=ppB_B3LavQ E2SROi O@zθjP!J񣦳|ˆFPbh/\}$ [e$ JN,sgp~]C4C]@.fܔ=i Go8uCȗu jUL*R;#Yٖ6TUW&'r\0'«2-Oi".ev9pbނwS@p!I"9΋ JHG<;zj*D,˓D0]i0h+ \ !BHc9yޤJGQT)N%"E$ ,Kk)Y7Fcw HܧW9|U'8% 4XY׃6nZT)>_nϒ9^P(tlW.[]3& "e4uZC}5)0Ic2@ROp*TWo{HιЖ(1&hV!_ЕzReKņM@ S( $bת R+:ARTke~ȩ|f@䙾CIރPzyR: i$I=jrמNcNWfQ!>?7mMI$`UFcV#ç~+yu2fY>=2-"HFDRy[ԅ C'%8f^{i\)KPMGQ壑8yE"Q cZZZ:*vDJAin')p0q'4w`\&NLoT"7l\7a`NW = Mm:9lN!⎑`ʒމiPc'PD=S]g1Fb,+ Slb_*>_nEoH5&_)\Δ̜k< uw!pZne*%WpJ,Cq! d媌Dq⍛ _@OgÅ8SS-z "PBQv.1hXi~iP#x E8ITek9wAX`΋7GO$Uak-0Gpgvbelfɸ"K/I"$E!Kj3 rr>QM9.aNW`銕iHMa B?Πook#b݉ECr%>2HqCь􌊬3UfcHi'~[lUgOX7ð# ()KJ?8 Nn/`(B]7mHZڹ`s\sw -+%PZ%r`y'%$X( P*x|0!2'Z,ejj꿎v=R.w}29DBA_(|jYnAǷs@6$VYgV܌ yn:s"I{{:|埰lt7mJȰMN"PP0 q|BtD"˲-h7 V.Y=˳rl8xze](ApaUC~],i),fd\Ͽqc̉cxEY٥ƢQsr D(sq#_{)5#6.+D q@@h4J$tˤm#㹼@  ,Eѥ/^I_0cLusr?~A$;7/;7o6cLqxA~AMM$ǣ#fW$pQJ!8J CA9(Dx`MK_wY#M(_0_{0 WSɥRP$d.MgNw RzE0ӟ?&+Vh_ .7N’krNO[k94MT63'9̉p9n3s"c̜63'9̉p9n3s"c̜63'9̉p9n3s"c̜63'9̉p9n3s"c̜63'9̉p9n3s"c̜63'9̉p9n3s"c̜63'9̉p9n3s"c̜63'9̉p9n3s"c̜6vde/%tEXtdate:create2015-04-16T22:08:36+02:00 %tEXtdate:modify2015-04-16T22:08:36+02:00AtIENDB`zevv-duc-b8f9659/img/palette-greyscale.png000066400000000000000000000455141426703022500205410ustar00rootroot00000000000000PNG  IHDR,*O2gAMA1_bKGD̿ pHYs  tIME8q?JkIDATxpW9[vmz[5553g3geYlKe%ٲDJ("H̙3sss@?J.Ts9{q,21VW}YK~ v=vҲG< <}c/WnC[؟*{p,]JrӢ)[D:0eMblSBuij@+qሡMoh?-EIr֑26ס\\k1u,([2w3z'1Ni:Gq{sozAIkl\. mc]80ju#.Zˠ|:b; =:)Ӭ`ٮ{~ =!A:t'DlV"bot"jUŵWg^*ƶ9oD|{=L.r5ߊ"WI/.߉xLyp4#VzYaYqDDՂik ثCWS߹CAV{.Ұ1j;2rtt(m4d]gZZZCN]Ad%7⧬t?^^<%hk+.6ƮsJYv0=u^}JX1M时3^.5.Q5?ԟ.k+h.}8Nk[fMoWk6]_}J7*J`U M.%]GX͏p뗼S'Ø ㄲ_0sP8wGެ?k>ZaOow?],z9Rl`Y+8&+cs?L#0ll[Vf9_g6f'L3lv,S9 l jK,& `aQU0 a9@{n~&hٝ  |)}:Kϔ=E3Eu^.-K!ǰcX1Vb²zh2[6{paȋ k0)YEeE /&arꛙ9[b’\|[otѺjlYP?^^LX 8\jJR< {r;]jH8UtRMG2c/&䔔Thr_U܅_= *,?dW\zm4Ur^Xx&;0\DG_|X( htB4ҧv{Zq _AEQJ fxuKy~+JݚQx2Gh֋+Mi r82n.XXM?F^|XY׸g!w.ƍzaU֝U(?'%/>,f˖*wŇ5,u,عQB֒fryZu;y Fsw^%nrywNKoL9BÊ[!uusJּ 6'sU: u"a榀A6h\sa %vLRqfdt|1a1HDZ2 VC!]9,sxm~軣q_LXnG'EcѰPႵT6?!E-LRa^: z\cv6>f+v(3Cԣy9`5{’Ғ'4ZOb${J`j &j$yê]]Z7vt#t^Xɤ]ZifHbZc ) X4_/*G[bšITRG,g0`W +^LXWX\0 1[% ,Jiqy 5sDbtX^kx=( 5)(ZaTz`JfԠbi-vHueHښFۦ^c,kȇʗWU hzTg2dֺ{鍷%)_x{WfLaܛ'ˊ8ʧv[&U-b3.nhﻁɅ%d.X'ۨtjG_;%֥ՓLzh BfCgSxhs C)f`Jku%5DT\V =4>/!t c!-o4.=IţP&<:_АO+&yb-岏' D /DV(,`&lZີ˃G+(G|ИCC ,Hu,"3keplf &;+1p 44<qwgaLƷRˀ QsH6$ 0XVqX1 tPjS-~ϙY=1Ua 1 1hB/x]OvЪ) /m}*z>}ZZrZ4+hlphf܆KlسMTAug0?+|bDrZ^!)U^}~b˘#1sWD΅"ǪO>@@\P4d hػ[8.Vl `zȝҲ09\*ʁNKmge%>y/eGRxBc]E<:>5)\ޑMf}e=(껨IKwRw1<0{[USW9UKڶ93YEWixSi`,@~̝aŋvexOZ6cc *)[~7,T]i羹se  U"\Sjwu,/Zu={>zC ,jMF3p!(%;fɾƵ|, 7ufٜK 0x1SKJK+{!3tlt̞}Niax 0T͵+*M^>0V+jn;9 5rJ> [I@?r0J"]]Aǥ rD nZmЩtD.#E՚Z@dNX0x=m/Z"") )Š3e鄒Z/M~(θt-(v:ёV !nH-4JARvSdlT,) pG_\92LXa|{)"AYO'AXd}+nk$~ͲgFwQTjr {''M6T `1u:ݽpidD@^ԫlFFuV:]]Td0lB`uSJt t:cS>Ax_]1fCkTJUvZ@Z`3ż Fxx7A`w\vDŽ ?~-,l]SC̃/+za.ƅ?4y͐5yejڃ[Xw ? ΎϬa򍍍MNVӇbPdVC nXڢԝN^wA\bCϫp^3 c{:h6J +c+^>C BZZS'&MtZm`^krruPnR]2~{E~{̹N4cNS 3ZmvܠLnͪM52OG݇h[L>`34߈;#\~;{UDflǮH#{6+@U0pǶ9==i5ZpYŀfNY4ju^u3޹ 1\LVn|Fq&;7. WK#SIm5O]e9Al%I1?VچBܜۭX1GNXIeH&Z7Au7ݣbEg(L%Q`2 BRIO6{L\حgL-2)fgV]Zc=5%nђ ϩ- ,0ęҏO#HKQ[+_ KV|1)uƄ6+ +lDcEE NIePP"hyh/ʸ|\f#'ªmr'm~zya: avS4>?sUe;6N[A5&&Rξe+OeUenjJk $jQ93 *NĠABgYWd kx^^M)ڇ -?0[d6kUwمߍA!OS(~j$sbi+2{9EE-<vme6,lfC-__[۵  #O)$)3J?9#F|$jIQ2ouЖNNJܺKNZ )YB`ѿ~㖳#Ax $0)ϓS\rVf!KVmyU %,ݸP 1_}G]__V7M{DD}]5;ZU`mE0lؓaM{kD^|1{0>t(ZL譁`Geaʜ'>8OrqW͢v98VJ[a =,V/[wao3t1TF}`CT Tޮ(y37e/҄'i0{eBnayx_Xx,%lzc}mmuue޽"X6oSƤ,Q|w{lcQ<1 W}{>Coc?廱ӈ)Yw]~ֽ^ 5̥ ,ih'+|[8RGˏS.zE'>M xX$5`vwe 1,xØ@.zG ޕ''Z00n\,#O?4/K;W)M?98aJX`YE₝5ɨx<2#,RRTZ-I7FzUXv|?BH-퐍O7M;Lοnx2$oTjnWMJgf ONv^1ֹ٩م>YruRqccWOUPNXMGκa _ۋ\ [2L'@W/T&+r"XB*W(8#j'm۞ڂew8a]SWsg믜O͔sò@XE"}~=ÛD(rJ&>WL\PdW:蛪F^Ö _X>.XMplj!XO`G~Fe7w/4V"){ Y߆~g}^uZxn K=SSuaH vûްt_|P׫[LO I -v-Vo}9LÚ K?q\ZڭBzE{I}D5f_=#6Oa9-X۾Ȼa8M$N6r"ag#}uS4T2nO:a-? ƽk+:?D::I`! }8ǩk w1СÚ 2$^,f3SS5 aEclÒ{rNJ59~d;/mX~Ԛ]/~"F]; V _s +Oa:L0M“Ң´T/-X;;3PsF8v3]NYfGsWFzaǽGT}.X > =lX$4*R9򆢸RzwY܂nV>itMGAXGqɻ`}gQ}>{F?nd~<|]ꇵ䒏vzx?jfR4 ,&QKwMڠN]?U?45=xQGp1Ϋ%O<9]C>,AGǭ]JU =?:DLo񵔺+<ۯ}RG>mŧy^R /"Nč{tK#w֋iT`˅4e6g&㾧-BK=OoLz@/-wzNrLK 6aJsCL|ƻK^ås!dg}-G.l`eFEO 2K)H?G *D'7lTYX)^F9"f+<}bѷ ABpde]2 nVR(x|:^<91!,U:xDfݯy'btnݸ^Dԣ,V ܬwJi2Z,.Kh݊q#nن˶s"CWe}=6qR uK^0"ܷ!!9Y/ztAKn VF͍y>9DoUl:>xPiUC0)P2OϩuNXf)߻su^7o?$4D  8fDz^/vK=HM(h9zzdYg@+n*y};#nG(wy E*VUt-jo^>/,,/+XSIY}K@6:8,0.S>%vDvWccFEZOB\c-լW,Qp׶66 yo3}a 5$?sex}IoTSg~=E cOcG= ;1yBQv**Bz&;YS@hȧevTW dܮD˕j2 ~/vaՎχ(s`R߈9k-RM!(>F$6#=Gܼް=$<#K(@#blM.+}wLJِ Vi+ wXR=7ލLxU-+w‚H7=>8݂웲yLW,>rpݹ A-`NFwz)I 9$ RWXf\u7R aoϽ`Vy0fv%/ormVj3 |Aèݽ{D6v1hf߅JKV2yfnq-,4n˺ۻ{$xhHYa}rhBaĸ8Fraq n`. y zz=zHnGk;&laի#VFкXLP Zv1 >bZU@۽w>PVM4_i!@yf Y6+8, *<ŏT\uytiA-3=UyD4aWz)C *E0XE9ߛXٿn =WSź4Q@s9(x'X؇ߞd:Swl@ Z6h@3qi3ݘą}C:Lj@Ѫ6OWl`mθQ`yM8 s퉰E-lR ^WI_E4ܚG^8;Ǻ~orN 3Iy0qHowWִֵʋaaECKJ@U hH +c̘q~+c0LŨ_^tl7O.Eor}EJƯv)_qf>ɹ:SI֡^} '@!b5S25Nh Kf82|bP9;]ݹ K:†! ,4t6V4&%>(_­X21?NH`9iٖt9IVX@5]Ϣ 9c>7"48ymqO`X~aνm#ltj58f~c3;9v@`5M,vcS{Fc~YS bgUIpjUԵE Z#6لц/R8s=nk%@3qrnnR"zzȐ.gá'_EqUg:?غ|~C˼$u&pU5Q HݖܝA K|]~涘F;(0 =>#9/;D}seiqbvE~Ǩ"m4waԓ}mзƙ;E<'66M5`맸o&',1/xq3mc^lor>h:QIQE4lqPg" rd?~v1@;eC,?ZɌɜfʭǵWI2^ǽUº$f!axAbX613Nԍ@>d44ۭ eI1qUJ_z9/⫊c?# oڑadW8a)> keq-;~r5#nAZ~ab˺.X6jzw`1Cc}- I_N&)WD6uf|Ģe<~37pv0z(c,TPw Ixig$U֘fhl,NO vw LLϭKr p Ʊ )Y|<$9ZPF8T_@pE>'HRۂ!D슡g展ݮͯEGhA횕o/Kwk@Vd &^o4hZ$asx2;+/dVB t(p|P ,l30t\\烃JѬM lO~ $Nh3۰Lzay-Km޷,c&/7P(r{~TPlMq _`xex!WlgZB#H~Z> ezd0AXf-Y۰;q!ws~x1'g;ܴBtDA eKn%~󺶹s&y;H6#4hTE .k`1̐b_X]@^Fcw"̦(;Jr7I#B7,J#s?l3MhH=Z͙41)T˜uU:o(%!ꆥ8{[½t uꉒ/36Fgh[8W XgE܂ =жoXXP\ gVYzY]vm!~z y"n=w]kRITƶd8:ܽ3޳.kVB_{vl:ʹ3uzX+] kh=#QUM)Hkм(HiPC%j p`Ⱥ&u.ү4Se`7 i,tqWV-DVdTz\>><<2۲uE*~CkrεhW+5^q|2yBN: CCYr&?6uJX\_UkdA%$IHlUl{8^lp+,`Fi]\Yv|D1``d -mn$]8*zuU1uzbШlX냞cX!yV°\uZ xbTPz1dZKXIKZư+k6,W8vW6idmnsC乙fHƩ9cDN׭1JdOF^m7˓xYMb\u((Hަ^ N2zLͣ \d9S\O; RYCB6Aa*LqXE ğ7SjզzeU6Y"6ktG bpk,Kwej}I&\ǹ<^a/$A]tuce>{{&`k :F+n79+3Yb; ͵9#Yb Gߣ3q;_pٹNeim7 Z bY*!XisZ &ѤnmՃ}JEߕ6a895 +te TV199,J0sؒ<1LpZ5\fИ;w}\pUkCnQg4^ٜ%z~ݡ.AAYkr2OV+;om jk_J(aZP ZoS)&meR+fbIA3kͺM[bI@450-[ l8ɰ{3u%.6֕hȬK%Ô?^;BPVgX&(c4 &^oKG#4UCIl, ;?}k<40dɧAJ[\2/'g-7(CAc2dC95 -cjB'Lf*mz[2CZL102f3 4gٵrٻF:Na򙰰;BX*ڼo%,6A e\a xª16 )AoR+Wɉ)\ z?.s$%n(,Tq$읒b{KɇK3AD䗜q2NCe"d2 rܨta4 IMaz0Edyhgwe0}۴a>X :c &/oДw#[-Zl@Zsi;{6vDzgtҠ1;Ыؔf#v[/V%6l.eCt$}, hGT*j/}`bc~xlJ:Xg;ÛfZ漹F0u G P n-n0-WVLx(bKeӰ6dv(ƍ2E_jCzRYª%'/a@KKMFVjfWЂ@[ߨv깟I`l irX-[}~2yϵnmP6:dsmܗrXv+A ;e ʣK(k-R8 /h)DR0o" ȊS6XY]k1:-Lm. K U[ K[Vd#YRTծ.4P[@[ck䌧arbwI*ZY)K=(`A;Id[dccS㓵b#`-R9a|f^˔Rmm8gYET5^"fz=ܽJ;KXsU@'UugV`)wsJ☞9(9ܽذ9aj3=c-O1ذ޼߲%l0m=gV%i۷Z~{aet9|_Qbh`2[ero+ņuY&&dugC/:k=mW?%hWޚ,w/6[+_nW? T!ol[/ɯְ C!7ٯ񿥲'N/4,^4~yi$gza-:E.L5ܶ%wЃ%5{{ao\/D[aϿ煆|nM.'Z|^>d]/,7"8>b~.ͤ^ C64HIbmSoNo&BZ'-b+ ]Y+8ReVyyGڞڭNܒHDR8+?YZcD¥2^1@nv2s2Mqo+[_jG~+U-rVo>mRў񴴷N "/`լ.ܨc+Byб?J}эZȚYR_k N~|/Xz f6 /jZOj{j֓YL-nH)h[ -_b}M`bֈVY?S.HǝE56д@h:}=` %@,e[OD0w]lfD4W?Ϝg5Τ`}-`U')ǫD@c{{R~`%֙dIlhT̘n6&w_XO雭ɋP\pChք|`+G^;QUKI_X\7Nk9~[ 쳊*%4ThN/d5VNUR<,L1Z6*w_OX`gQe|f/>,yr}lV9-z%K?O/>ѤN"\ͥܦj{`SRrE6;gV5,]^0X5L&!?:PyA)$NC;p J|M[Te:eK q=IdYB'{tBj4d'1i`HqS.o3̫8eOY_XHZ'E`hoƳF ;rBp5'eCINVS79>_9^ͅ[g%^`}4y~% 4}?r  Np]44q2KrJtK}.R5H>G=C,?}=`jûԬ?|p툩}4@s}e1t ,¨T(Tcs j۷ώUBY @Vfq'P}AI/WsJ{o_k~PXzWTzrVxe#J95ErB yd|gaǺa3r#)Q+=7@ F2vźNmKd?{=gs3?{}0QT4MwTlƮK [\SifyN[s$_ѬNMD+pӴUZt m ,P72ϣ&E|j#j~,&ϛ8_AOa_$ $Gj۟׍ؗ9E"73qZ kXEbe3VCݯּHkWK[y=5XVE?SBcO="?lإpHjvz8p܇~Ӈ8QdLk6/?]X_ݻ{[:WXܧzTJ"?0 < +p=.H|Yەo-777>^^ÂF>\4c@>`3Tqism_$Q 06+?V$?Z2 y+Bʏ Y,/lY2r[vf#Aю#TEQCd˵&͝NbvZSKpà+95wZgi+JhFs1e+:qZ,چzxѶjZ> >+8Vk)2!}٢Udo^)# itk0pԌ!k)agjOשZ3Ds*jbrvy^9 g .1Lq3;rh}GI!ke掺5;.│1Qz*HoڵHZq3%٨e;aUJnaxp) vh,gC+$*:翌\+M9?~`A01=|:KaX/s|K zͅWǢ>݅(.X^Uvz^&ÕB|=i¥ܯ[łuq.{AU=NjuR{"H:NZV5l9@{L2leUmd$jcrhFjVum)Q{1f%|DҼ -=mjFh R{W']5 uf}zJ5}9qE{U ǽ߱`An2=2\NDSr >KFM-~XXg]@D*0wIR¦HVzٱqJ$lws2͜I+hFIY;>F̳Mxv'up27eE{?]ME gwuN Aյ팝lݧeOc@Q]' '&1v~Z4pC@Ocxc'xo L'+}eZxҘUba7ZxɅ0rZ|7m6sG^q3)3sh"`i5(de4bVKYzy88!,HX=uapmRT9;$4A0Unʑ揢+))Y'wnM_[aτ:~qxBu_t hK  IoQGk#.4q*鱂<#XMx0ȷX \R lw~S9N.[侧 R3 z R[ïgi2zOfic#ɍ 6[yOMowu<_YepPNϠEo&!qmrodb6C'UkER%1ߟ-lҏxRU$_mM ti%k~uWqw͡NMOEFyC:Qp,_قZ,{K7>sg-HlGڰ5HV٬7TAz鈒Sa*ƩYg‚ rSV'8mԿrT(Ir𚄠aZ3S7$UwKQ( $\)U]3L-X8,%lax(zʽ JfE^z)k!,+ #gVYHfKD`/rFRz?p><|."q6-0;h" Ke&yG>,mIqto8ܮ:݋=nUuyJ,8Uvʭ.?<u|f+0,;+"#N/B~mO]ha1J{)yvڠ9M; )\[X.< 4(n//twv+q+vCEj " 5^IZd[P)in>dш~H[jӢ%O }Ss!a[_R|U>&h6R:75w̆@`Aن4tc‚Z[9<6jyvP)j) :vwPѮ\ml懬+2Ó Gϰ}~BM2\ ~:T-E"Ǥ6 iDη"o A/'"Rga_pa8dC'k4 AT[ N,2lePur؀n='5 f=9C:Hk`RƄң?y%4zr=ZƈӞ|q<,XfXEL,+{~l')98?İФ5閲*?=#< Zimߩ}Efx/$/4eĿJ=hGj%R Dr{Ԭ`x)Cn*ىm6PZ #j?m^=G\Rz"+̲9Gᒖ}r@౯}- N[,ОzK=,w[AdpM%1Rt{7;\oj#jVd&f˟`2V3tcwT$%5-22S]~uU}3aڅJ|'Pk" F+ҚFsd NIna?oqj7U`US=+1yapԦRG(S@|:3T%K!4+6b6k<i5ʱaB uS ,} +j|L)g"uDuoc?wǢzp2q̊A!濟bo׶ jYy{|zUoJte!kƀS5 +\<Ą2f_{~FGJd砹x}U{n$ 32Io Ɓ9,>GY[B"p%h)?uf*C[gڪlH+o_kMrm!2oCOYvV3\ 'BsʩtT=DZ?1nbo L p .s=Kohå0,j5*OV3ϘWnc0!'4ډb'e5JY:Ha:Zݠasgte%:Sg*Xˇ!@!q@vpie t /1 g퍡SWXeZaODڗט?K$󆦖 zW(爄:fѐlc۞0Cʹǜ,TMA<ee,O6dF Dy6aO8jnY ɵxȑjE:um4`+7*2Q;QxIêsM0J86GP ev W$ v5V//L\}\ `zZzN<7?&UbO\@UN:Q-btҥI{WPnO]0r `MqZNǹBD幯'?~qׇ6]ػo;-K{9~d sihypS,HJCiHG <0wšFqa9lZ zF( r&xniEͳꑺ-D]ʹ%e('k]Jy B+Z[(1[g&U}eTuJ$m.w"(bJhWTUHҤO0"[L^Qpk?Ś?0vՆvU3On߶ ߐ=P.Xzf􃾡r똓LɬP|aa٢3AOޅ{V̖~Pn=]֪FHKM֝/"wO'`N joG)1(^m=`(,pg8;0?q&|Z5a@glƣUĤ! y5w2֢lNkuքB Ϝ#ppo34:,VuHhk~a+co`| D <`5ᄰT(BT{s.U*t VGcݦt'^VWU2c[?O*SPxn0,9Ro۬‡@V Z_܍|Fn/DO 0 Ewn?`#l1F`dW2roauq述*HξE?78{XHIwP{_~ma?_}w2 }U 򢖈zZh_Ƿlb>X5 )d?+zg≆ }zXSMf_UKqwƷCoxYʔtzX]̷tFȤgy9엁VVCXE%(poS=j6A⧗VDzav1oo`%Hy]Xm(oKyˆGIttXԈ }K([!.`fp]<4F]AB6ϾUSK>^ gVֻ i..ߝ ,wlcT,a2}e$4eJXlIb&{nh{wсmXSd3XbK߻݅5ڂy(/߭ kB$Ra>%EVp$ObbNh%zk)YDIyK$^]s&ЂmpDӔ߶'pRw؁uzoBQnt k6 ITרO*Gg in+Av6J_;W[ 5n-e\`dH5Yw`Xqǀ1/e1AK os'jH8d0G(R'U,Zj,#X(J߬?xf}3|I0u[ïfK'W!ų@|MSAGÂ! |>UIF)sF`1Qf5a-kSR7^9Ah=Wpo l1'V"Ĝ/952J\V\`QpMC¼zo<́tqJɪO8O pW^5EShʲVu+ 0'<X(Օ̵cݟ)XNWqY+om0gJj)9F)ȑ6ٗqJd$~[Q%~5f}mgNsٖGn#En`8kn\`1JP0djLY#G~څ5kZr{ X]mm‚ˑ=-_(ef%8*5@ޅ5 /ZK9XQ|qlZOp тkͅWRz^@ᠱ7r>XM(P`u>[U;C{."VϴA{?MY^Zf뺴IkSlof4Pjac;:Y`3! K;uJ[ ot&G~o ֕=촀$Swv)b vK[[[VScԥ !G~lͅ7#F~?r VgfFW%Ijʑ094pԤʪR2emGA`=~8 Oyxkޞт74%s2pmxRn@9! ;W5{cĶT- pH)=Koyh#WհV!hX  4; lewҀws&wʵGM"ڸLؙp1߹s%<**˜BSW1A6pmuwm>sݣF`JD B8CEHxb]5Y^W~-GۦV.[ D9z vu-ޓ%Ѿ'C2f1mQ rs]-gcB4߃"r߅'w.,Ɣ5f\4Vɺ4@9u12Ύu](kuZ |a= wh6*lr=&b-,"}ݵx QDRa<Xf x4ଭ|WHQ.Nf?rܵ^De Z+3C= /~kaڳ;y}}%UNKSNzUD] 66El< ;~zj@rO=YFl3{/ka)PJii1,xtF\?pN[ Jdv7/eTo-lRy=[]wVh8X͢'ݻ oB9X'mWua|8 U9G,3ɀ-WWi̒&Lm̊O@.<ibBxCIGgizuT/°Qv?AcN2QgoKMK(ڕ R®$zrb4ecx&XErdâ13VeXZxX0vdhV@@ъK/T֏=ow([,+5Tz]\j aL$(M=bG޲s[ºiZ?*l0/bnKM*haROW 2NBt Z@w KKv!&jVY36-BpYknp'Q2yxOvtYpmP&M˭X;џ./h^sGbqۺ7%IJfs>.gG B^}` # |m{(EoJ_;4>H_֛QX@L3hJiSg98W~ ʂau `Xsam@2F >.`=سWL0\`;>R,XK[Zܻrw.&E=|XzT=Wjڮl`!S(~l~E }]2>#Fkk(BkQ0\gS"'%Gć_u;--{MuSpk6anr `ҺB:OP`9 "J"6g% `l棣tk$_fnB%,YpT;R5)JerJˤRio^J!}B-DkBC%HBpi!غي4lD2HZK'G%,Dmv=}7]'p AMn^QYUmC]-4 w t.#nSpۆ 5re}γmC?}1=&O`ʰ8W9S<$ _J!ȯ2XZ_X"FUEA A?Cj@_RI-a#',0hr#d )1&4yaF[)qxZE60dqMyeOdɕMhQi·k\"ĦUtEP2}#+GSSKJ+4zspIzD3,Zvx6k2`vq*pDvF-x:py1;EAiN`-?3\ݿOA+min){d2*,mo1|x) IӟVI#2h g,!yFEȈvNڭB]\K0=\ ?l7瀕^ZYL7åEt> 1Z)+L l\8jvݴO퐬g7@[i6b|2S :zv#FhjZ7`i2LKWGj8%FC6HJv\sv 3e1#jֶ,v5ImG3?M0n~u좐S9< Kt-lw^/'MRzIG5݆LAt"xjYLZ;ox ZoNH*̱ įi˛T_KA"[BPq LYt]3xm~Xv 5sb 7wC}aldwbtxכ^Mס2ʖ*| p)}RNEg5-puy9TɦƆzv@Ӯj]?;ߊxe={ \(^q 4EküM=XJP]jEe> lҊnk5~Mn>j4?TY2`8( ^BT Ȭi%&Tl}U`f8%y˖ MڒJut鵦ZrULscժؾL!nicn&1C[Z?넋J<&g [3bUB-Q:(RevkzXp%X- pt*J"r<CC7/:-V\D!:bx9\O>6ӭíFRwgy>,[UV:,T5vnj\5 .~ -&CB7MK%Gڷ24 4.3KPɖ*kVIJh:;tlJN2i%.h"Be ;',wE}>5]z\ލ vnbK] Nf:J7? i+nAQy&m P@ F+*4L}ZeسV+k'?4ccO'SF: ]@1%$1Jkۯf~T~9@IG`N ywfd>J%Y`m7j\pD6'47{6:qqM[j} gG3duQ\&Do/.y ^aQ|>Hʯ$b(Fǻh;@Oж==I6G9UӵƧ;\9YM&WNmAeɭ&W1,Kͯ +ˋr0v!BpUTN, -T|#@HH_,&PƏU=%Hh؝yF>󛘶k򪒆E@Ja ʌܝt%հUvZ a],qr UaúպMVR$HFl&yp볰1MNG(0UZ2eTv$Ўj*5F#*IFU)ӌWs:+bwd]a`~ZaȮm mEl(zJ5_սP)dR{5eT?ɪ Mw; V$t[T=%rH >x0ȤͲ #9H_4C5 *)rvatn{j%„5M7⼚|jQpbXDzeXt<Ct-ovEw`A&!>E*[ޅ[(PJY:,KO4ěu}VWBk N&xŤ+kO Z`xd?TōFa΁;ˇRGJ[iHOđfq-Z@5>[SIEp1 mVco @NRrk jxZu% SBRڃAL|ݘ-P! 1 #^bsφ<'(;-{^,uX-$>X7%riz~+eb~fY2PmJTiF(*P(,,( I$%N}idty[I1Hazo"g rғn9-V$S:?5gRE8Eۥ;IO ~,y?.u|S-9r;wQjvY2zd{9zgsP7Mo^ (Uڑ5^(0#ж8Ps@YjXfsu,e2H}2ꗅ= =W!F/9?^)p{\O~ސ@HϽګ~ܕRYu5JrJt'/ HZu%iT%#4r\:&= G ,oF$pX ճI~Jos Ro+|vfДęEo|? j.4wٟ!~F"| \f^[iHA]+ 頨=G ڢVšLh&lR&Y5۲mu:1զ?Q鞱֘|ieN՛O5 6'#:BvsQ(!psˆlgBiGÃKsCGi [~@9 n%T Z;hkh:X2*}|VB/iVEaBW޼ӬǢEj*Q|4ۼEZןlݘvQ&[Ӌ)TX]Q>@1p tny/YYL+yED $rޞ_ U*+|#t\[COjq6nU~&IVRmQH(' uq'iӐo;k~g;b >9N҂M࿝BAC9н7#[ q{ASɎIG<VER&l3FMFaJߩdda ?F%krG>t^ruEZzz˥LLj7n$ٔ hc2!p o:iɓ'h[ GOōvNmM uP 5SA /M,MK{_bwFWv+sw'[er܈~%&\f)VSѶ?KJV#V[1dt,\R˶Z+oe0) Yv4Y I(keZh>0r ;-xX̟c =ltޚx%n m @[?BwFsYo}XW~׉HrY'e,AATNܥM@̢K!prXո50//?%}Ҧ :N^a%w<J5ݖ۰b#=߃a9n ڍO ƾ ~cX_vhK`ڱ݈X`m2U 5PӞf4z+ .$EnwbOh7dHHW6C0J^S1,nxv%SzM6l߻^Xs,A'JG%dl☑x*bpRS7}: ⒁,fx.h/lW@O}J4= :O5xm%<ݲGoð!赕zmx1ZK=Wt"?zNi;&ew}7ڸ:p)*ܳ<ι%sf= i>`ktoF7WO9f+"|%1 T:'%cJ=.1dQ'W(Xk1%f:ű;7h7! rzv/xhJ %'vل'wOAD}^1:azN1HB5+5ZҎUCEj"Í45Ylc[FDRb}; \X#ϯEouk}nFš>NeZ*R3l^?d%"V) a&]2ktޢ阋JÒꗏ: { ptpD$-撣QZzAHptpV̥vA:asfsK8p 'nϓ@/kΞCt7C[Kf ~B%IUÔ̲*<<>[v;,C1s.9B X.92g4;c3A<$Kds,}^gO L = qW,Ӹ!P`-jbE45Bzf?r60΍JH`/gGJ*Bx< ~%=J):e0 |5X?'w=JrBwWo.eJk~Յ`Nל K(;݋~m Ox`l]˒{pƁh[ 0Eƙ5B`X-?0Һ ynQ8D7f|v⏁vŒՅ Xrz2xL\z|0M'O Lˢrϸ8/Z\ۈC&ݽ^.a)PHU~еOr5jktK'YH>\ ۾rlXzJf?Rb&Z#ҵ%0zjMfe.$P#Q) \ Y7:?@Hf#i{:!ronԕ\( V!NKJokڛV|=@cBZqGq̬Kc3MN 6;Pc,{!V|')Pմگ>W 'u=EuN,]@'v& ցTI*Vb''sC騦v[/B n^TSK rh(KWl]$V77G::8_ZiAW$4$d:=pX)RzßCl ,4aɊERj#(w vJʕVZdX=~^\茚RkEI (o~IV8$/$NSZt)r4}FnHypӧ 7خ3Ҫxtf^rlLej^mM˕[x@F l>P EZ<ٵAI c@h%',]^L d!,@e ͪȯ?Ηl_[Q8YA8nBڵKWl-rg CI XVe O,cRH&yS\I$\}Av/̢KL#Q>.%0[}RE:;2<,9E9nBq(o +Hz; ZM wim˶mk&xߎ3]u`ש LRB!ȼwbEAgxMB<_K\e kw 2/&:Gm;cYC|YQmπƪ1LNcnTlj!۰,Xpm /S𡆥WEaO dZi),e{__%dTѳJqČ9͎w2xiL6m ( <]D Ji~ z` GOYIMa㢇@e*.u%Qe0M\ SXB}mBhhFpq8.9$[srB%-)&ndN7HHp"PdlN)qY ZV)ݖ@˾ŃxΖE,f0yv9y|3eҙN%eټ _4ݘ]D yTc+SB9ˣF9~YLс]C-mC[4%ݲv|I`',,\37^k?!$ e-l`#&r/K,͵Ұb0 )))Qt^%/rSX2uyCTI*4x %MYtB `%'dah:M'tM:4AH dd_#U9\p)^wg XWr!h<%])h玲$m< &x D=s4Ioa0n$^yd:$2cRQ7(Ѷ!OE@z~XQ 5LDZs1G&=—WAz倊u]Q6)P_bsyL>u1*5@7t˄=ZfNe#ğ,h7 rpkF#5G!N\&R;:ճNrg79a\͏8 X<\q?Qp囉oiFJeN),=;_ZgT㸻Q)'Qi a#jl.Ij`W"ZN)n G6J㣐:4XP˜,{]t%_BHhi >zQZ xw3d]bNO]\?/.53-#*$8(Ga$ҪݵU,A8-$-CuqM'-+Yzxr+A .`ƶLD:ٮ!KY,_!<׶p"X` }{ޒ;0+l\Na&jm{Yzsn,vtibjDQx>Twd8(&MFwO80gS0S83QX&Z}LuERp.,,ڲmcLaX\JBzDTDAqJՖVAJnaWMbcV`p@z9$ɻx/a-&W u+b\̝kqqzdkw@=Ӊޒ7CG}URsb!FH%pلA\ۥ]( Uk~#H]!.mSAxDH*EFA|ܡ]X\lDZZzLDdAVFӒV.l'UuVu{]ՋeHzR+؁zcS5.'2 Ȓ $CAVƍnÚM^P[KGƇ%$Ʀet@Z&"L&cuT ]˻#:ì# ;XT"EI gֆ;&j IzXڲ]W2@ctb~LtJnJt Utf9!R6kkj6TG<zb(7v 3/9udB ^DxlLpU떟bK1EMK y yrw}r;iszg dZܙ|aI1 $G2҃k}}22s+#"!J8+6ͽ-]VV9iDR~C;F[n\|qz랮bԫ.~M?#4ZhQl7BVXdK~03,I(eu n*nhǵ t!Agx%tOր͚۾ ZJ+cwld\⓾"BFdTIEQu8Y$ra {93'O!0)5= Vk`tCRkKь$#*$)5!>=83.[T hskJp*u"Rh3_缙 Olܜi4AzT5Yc]&+$"̷;-$0-"(;ZHJ]jwS)Sk%(ƐՂ>Bq75fI}Ź Y I=Dde]W8'"o_ E 1T6RƆr3 q)U 1+A#pVE_=,خG!m)5㳒NESJѣ*bdM~G~ks5/TO)8H}J ,:B&sDGFPDx5)BZ)a~OsXFZ8ݠ~=?%5D3|,p]!ч<24zGaq;H( v ]M8P2O cA3CΡΜd8,1ߵ@pS>~[ 8SDӁXrnEɊ)<}nN+>x9'I@?v#)rHZiSo甲-V\8I/~y3;WtWtĮ>m3Mӧ!$n{9O@}:UX@:whz|Mr^Z~zIONI ;Eƥs4~;崭tPOCapd|*Q:e/&y=kk:JsmCqy*z{@:jGzs FOOˢtgvSxIa AI%tEXtdate:create2015-04-16T21:06:42+02:00}%tEXtdate:modify2015-04-16T21:06:42+02:00IENDB`zevv-duc-b8f9659/img/palette-rainbow.png000066400000000000000000002121011426703022500202100ustar00rootroot00000000000000PNG  IHDR,-=CʇgAMA a cHRMz&u0`:pQ<bKGD pHYs  tIME8q?IDATx}uǙW8̳3̠3ؒ% 1;\;_.8`_Nllj3$xŰ4T?Vl}虝鮮!q9`xhFQ)FCQyaB(E40i 4&'G6  a9eFo4Դ+Vi $l1JQ@GZi^& xjᰮ^^'ve/v?&ex\G"C(#Da:)Zc2f}{?\є)ir&:j27 Ix@%5#%*K%YVYQDEQEQi ؙ[%!?`6bf8Qk8mIJʜ\/dLQcDBB +B!@&!w0<<͞G~hc0M+>Q:}LSxJBH0О:siL$b&NwZf(@~v%'BH3SKP{dW]"XȘ:K<c[8.JΨ5is1eL3+4)zsRJi^ ]C}==X_EQ<>1ɟ2IbW&cۖN5 F$Y!1/LLDCdh,Rf"e3LIʾú21M+ j5q!TsrQ-=+$26:,{J+Qd"'ٔBd/0=W&Ca}ɉE"a-=YL$. =+$2/]l7^;'AF:$/nFO#1M+Zb1' DNIz:$P_ݾ'[;!]mo?ۺeD\4 $2Ҵ'6tD'R&+#Hs[v%,vGjF6s*?=&i^EһMz#9ğ d"+^bOJ>22<Ҩkb$Il0M+#~Evi%& XjMa8򄟢hsc "!$LKɲ]<?)L DP0 :x㞢(͍$T2 s'n#HgsevJTFi&i{'o N470M+^MeU'f+$d;:YW$4}}7C@EY1'%ѹ`2N7jVhmy/ںyS|gtT34mj*I2i}| uⲓFt$+fM M[tZEa|7iqyT{zf汍A MBBqƙc4r]9ų㞡;Vju I5Ysȧ$t!  f;g;'uug2tzr䥛*DQggL;b a6GWG[S{kΪ~ownzrŒ¢s$tA:E aIb@L}#}h_m QF%kiY\P,fn~|:0U66ȅoKdf]b""3$ZB$\({c=$9=c+!I=Q%NyeEɝ|:r&{JiAad&<k7^JaĆhNye{C|ٍ̲5s8U*i oq9rLAg*x^ӫX@T S1ψ3,hޕd =$!$K:~U1Bnvg%4$+ {8C!ޖXhG.p/LS ǜK!+JQ6iAJZFF3EbӐr~k줺Qa{Ii?jy|,&YawvI谯ͪ>26oFskIi!QPS-huxּGY=mEI]Ys\^f&PICOՍedpy$7$uJ3ٙx;B~:`1MO U$'NF'(|]qGc P^לK.@/?Lep F:d/J2eҊgQKi~*93H 49YKW"zjX'jF3,vמI@踁4=9=1)Hs9IvHNۻȡ%=^SFalӔ0MOFq^t]c!)$рK*TSZqɄF# QPI@H5<35+}Ǡ]Px0%xxh Aa AE IYbrŴQS)1@$966>"7Y:Ɠ f:Ζ;]8mʘ&ᕏ(4晩L$Y?rDsG73 ns(al˱'?1亭 $Y433#aMA`k}i@hIZAO|Oc򘖄 <`xBh EyVq:O9p&eLTPP@E$"Lc X6Y)-M" SYRy炜#nnXR4O=,SzgRŞ$l9/KTO%B.{(;"4f\hU穼 ! !݃M\H6'EPHIlhv=T  M5<L0H}'"Q%l c;:UFj&X*Kc-r]i^nLjU۰N$oѭG|ͣng) OcW> ifIUTjOLZcz q㾇&J Zj,J1@!57͜3h2MHi~`噦&p=T:FgjRLZ{i6F;@Zu^u]W Ū{*[^[okSݟӴڹcjX5< Deߐ\5*s4 ~wèUq }H8îG{Gn{S4 3xQF4"ǕyK I D FۚB67$ axYia2Z;) w"f5ck-3zr$53Қ\`Py1vY Z g*whz񑇾 ~'ciers=@R!.Z8MaVZ'Osg&"Xw-M9A=eEq+"v 䴬O+x׽֖=Ӓ͂9 8-(2` *T8 !7D`IV U,ϛO7$, B᪐f}s]b1'|qL(ֳ 2uM ()CWHKb18n:ySsb"8&Y,EEcD_\Z$xٗz'HW7Ktuy#+%1+%qF~e؟b(2 TX͆¬cjnFŧ9EY5s:z6ܿb"+ޖkX]/Tպ7|^3!dtd[YNw-ˣpdD"=K}o{v5g)6hT<0 p{ @vj҇6vnS}fO9 ?0<Am&9c^{}<|]V*oM} cXS]SЛX\/oج  M־ްRV@zRBz׷U9洚ZU4֮W?>zb@G#pj"胵^;{ޚZwr`j ruFTMx̌3 q=J(<6W{Gm%)M3L2^Qm[? tq  +#F-_Bp(nhc[0#?ph*^vg§, S"\2#\} 5 t Bb (X  @k>Pve?blze*zba pUX̙:rʀz IC4]fDZOPNè03'[5Zͧ,  (!sr,cֶPFq9>ikh'扵d$کF)U+tp|J*)g'hx4&6ę3Xg TLV۷whTcOOpHn<ʒJhpAer E! `0ed|ɑ(:l~wvwn!J/m$F{9.BB DA3wؐsw÷ qGGEԇwh4WΔW]lCL0BFFmm0G}[oo]cu^MJvRJFHH@@ X (< pXeD{0LVJ(j@c-VwΚbw2Jw4Dcv6Qq_sϽQFC#?]m|;"?vvyQFF=A5F=%xFxg/@ 溵k=lc53:9HiPVr+P&P ` 1 `-A  CWz=GebDI V%.jRL5ve{ܼۗB\?v1Wd%W7!B`x݇ P_cb a uiNFCgV',Ni ]@Z'[7 k5 !Hwڼiݵ+˝H==c5uї>wsfypdkW/xO/Vv8Xk!V_ߟbeUUU))){LwwSO=rn喤-kj`ν{[yB/9+/K.%Q9 !}iNFdw]KINYw͸|njᒙe._VRޡv -s4CH<7E eE)m~:[pl$[ŌoԳogd$z^ծ^o`?LNW_doݽjժ_H7yt7_b؋! EQO~iku7g8!Euo?fx,1p|}w\yydd)ZG j&Qä$=Y/D :b[Acl x.3I ׂ,䡖&F}(xQ0.V)gh ,(jox4 ܾfpskWow_5`ɢJY{~ݢ7]1okk{v޶W]=Z6;/7uF|_}饗ر _ž g?=ڴ'~^qB(5+m郫_)KtVKK^;W_ \!egݩOpq9&vUք- +r=c%3!,6 S-:q)3k+!sʖ}m]{Ӗ@SVY(m7]8T_ %3p < kW04=k޺g2ɯ@EbT n:<X*Q "Ă",A,DI!e >-c9~D;CQd7H "b?.@4 0C@8$`HgWlKs5\|a GG8h6xnFvO>2hPUT 7YdG(!%[FIqj 3OSc@AVlaJV#F̫k\-*d qh@'m0e6 (3Pffe" l*P]@@ 5p(ړ)2_|„jI {]1_֝D]qmڬ4! 2f!MLJ%*dOB `5y!a/4ۃs6qJ8`-6xG 6 F(7{~n)15RFB拯/{w~ٙ|jOMIX*o,ȇ"uwɞ7\ZKuIcaq88sRBi&BfUz Fi8M/t]:bc"0 Y c,2U^/}90|vg"rNOg|+jYt&7y끯|3 y+^U55ͱ6z惍{/W~NQԲ E򙷟|o] Q’TK(Lkn]]tcy0}eo~ Nw0B()-y˪^Aj7Vk|/>x|6` :r[LC[#=PDS7utFK|}`c,Ҋ"@flkkVsgV Ȱt^nzm}go߸^X'w$&hf6}ʅIu~;p"Xx,4؍[|=>!gsusw?Y&N'vZ?zn],05f] &w((Scb .?C^ٕ"Z-_~mg@ff,+_.[2KӀ(J,h5p$(DV4tvMDi0Tf\*Ӂހt$;Of}5XYpKKHu\vU;:I,(5A ;}PAW[v]Jf1y0kbq8+%)f5^9bRd:,f}~naLINv!I) $Z4jgksƥNB(ʑ9 ]C P045ĭ5;ࡊPTK$ǹ]R¥@BI؞Dw7E 49}+KͺސS74v8DS8:=ϐadiaElwae(7 6*b1(HMMҫQN*v܂3D|2 HclI:OfF&m;H5⒰um8le.N@AH/T=w9q<"2TU1!1$ ~] @ J>PBxAZP~#erZ}]$ ɐQzj&|ʄƑVZ#F._&Ka"B$QY@kCddNbH{".Ov{kEJa( ,[^<2UxbW`S(aYw#(EI W7dgbDn.Nج0Dwl4YϰJFmL4tH (Dјd6Ha1/R(k^{GҁjYHK=e.5NP^b[1r^_`(7~mǁapn{JrժsIRF\=9K`$2HԬ4V9ysdM>QY}Ј߄t4xw*暎zU`6^D k9T1WvrVeeDB([58>*8b.S/o0dl@ $4W5Hˮ?/b \$qV^>:ă1ު֛NSk5w0 a-₸Iӛ.ںT0۠J."i]#zt t%`Δ6vl "-\=%vvy,t !uͮ= #A*; t##ñVKpNHJ]xi{;lNJ_= @*G#j:4QX6.AW<Ƴ\txR+L0yfPZZ_~zpj]{Gz /^eiV]k+ RMwW2$.KIxjڙCh`k?edv@VcKO  i1FZxv{N"8Q=}}m !1F`$AwvRo_B)B? LM(1M Pi-ϲX<8ߐYC3 (s-6:Z^ QnrDye|ޙ܋OUMu+%ˠȠ((HQ&>Dp8r(1 JJJm/Br(5 ꕴTJu!yHQ`^H9ea:KٗJu8'WCvn‚eFtDW Sguwv׵g܉wtF;Y=fϟkng? '@B/+r}~ϰ Tu Ӳ N>%kZ*U->JQczᣝr~O>AHӐS{u5JjZ$P1P& p5b5լlE ^_*5,uwD(+{)!TjUNw7ط#5/]U8Κbx6Iݡ#f$d'vfkwęZGj_zZ @%84R86-&s]HزG#wJ^``Xtd Kpk3Rx}vSO cժet4 `06Пbqjd1FF3˫|4„0Kmӎui L &?a6%[vVG:ש0gAm<"_1ޤFuhJ!?yC"M+yn-3N>$<" 8< UfwHƺP/hաvOBSX[ZB$3C}!2<{_ ^opkۀF>d4 ]]SD6{ZyOpn?B~_Dl0fŔb 'PVdI%vƨ'bs* 6ؙ9bhtw>qQnj$Eab\n=Jqn$<: Y!P@A/IR@xG陨%2؇3Ugrg;L»Zm6V'%ZjjZ+++=VSΟk zzs[0 FH숧\tax s3VݿYܳ㵿s5ͼmRl4_u-%sf$~!ޓQW3O+hHY<;NcSLL`#~ cGGG/8 ]+;GRN qbo}kknΚ?: `*2${()0H +ѶfEțoȂ@D$AR -v>90CQ9|ng׫3SiiuGmM,^ծsOZ:@Cww:gŕ'ϳMk?efZz#}g/,L%&(Ƥ0_k#3g'R9RcHhg"Ǎ\铄 ^s㚀"HK+Xo-[z˖EQj٪e:%;>|ݶEJ΃_?j#΍BC$e'wl&YQ48jRyy9#ѱt" 0Qzithc"F7Kϩ3᰸w(̏ibϊO$EQ߲`kOꬔp@w'!q<(+=*#5s󴙖a%2K,MIBVw0pit_^w / O"rqqV6ؤ4= là(oix>!CP>@1 À@zy4tFX"Q|@(%դV{eFsŊ3I(JW{WkMK_[,~HƊ1LB Hxye)WQZswHi$@xg,&Cq1ne$$I4vtu`U)}H叛@XdvViaj,&֥*b8yúhŌd/ @%Y!! pXl4@Ʊd|3 ;;Y͏VK+m]uTO?WA>Z1A,Tf萪+9z ۽=h}/rJ/TY^5^S ^Fg9= !) ۔9GNj5Fo,N96~wY,@ᙿ^u,b 뷿ۺxr@&v 9Z(o[ Ζ^ͮh!RIZ "o'=W4|n_ě=U Uevƾu5!J̛ȢCL-2S7O%)Iئ7;)zwtGU*Jq35~kLPd"Λ{"T}%҈$kM.]k;`PQae3/AST4*P,~ e췿}uAY. ̏'\4BWz24li}Q(}%PQ=MLU0KWqBg)yFb|MS@@NT 5K w卍^k{a7#k6bJHOGOpWis+7ܻK lǐLQH5+t3+=t5@/DÒRG ΀ez_ګyՇ;G7?G/5oբ)X0v; %DZbHRy߉gHG;@CA$l.:2 eZ"P}y @9!ExOgm$ݒ Rx+VT(  Pyf1Bc㾆ƞ{]q{F9ٸ˕iIRB!1zm`DXG-*u ]H'KMtۦ=#-[lviJfZ2YLH DB7oۜ){m9< U+33:j4Sb2FO5y*{*~ޢS%suAW]5n1[ NB|.Unf B K ~O0-];0iCg!!:9DBQB7$~#^izMFaD&]c  | 48u%Am4. Dyh[ á :9vaau6#Ϭs820{i% vLJdIHtQqQQqQ$9`G]V1on.g34Co9V)q˦)pƖpkoH|L_ʥ(D)Le&,ٵCTԚGr Frdǣo椬37%˲khZе@!͌XyambWVGp'19DBsT\\~~:oP磌nX^^?Z9$D@ `)o'gN`p&BRNcs)BA f@9--9?_pB8]vy9lO龾P $t 6k3IZ|Ps;oL\Gq28g0ieJ69DRvE>(RkT1GC}C͓5kb|H8[YkWcƛr561VZAW::'ő+s^N߰}M'|02{\ rm7K! ACH# )2 KIX'H Op#8*YRåɻY}k,+/=su1XhD E̠ C&}${FF3-E4S!rDRZ}~ab4 y03o^NY-b$Jx\Y0`DQ(eٙr zN tL8$&2/<°7H)a3{1 j<.+Z 7M !dlv(##)!wUէd&4Yٙ i꺇lYH,fWWwEmߣf+F`rB$҃bXXߺ%kx2#pۄ GS䩓D3Ja$ ?I)5  ӬEoAeBC+%Db  p8fmq^a߫{V;oϞv/; ޺A+.^_feFFŪڵU\\01[%yJqqZ0F@JKsJKu@v^mgLSF!5etJɕ[jKKf^qR8_GDqbJbbJ %i!xszOm`osruR1,!!QRQ[;PUubLmi]?>ַLI֗^z/] 5 @ @B?s{_M@Q(1nܱ2#,LIM+WuvoSWSWvuq6"rNJ1zU}XؘfcJRڣ-O<;G7svO;=sیx/1V?k Vkع fkF\*0s Iy]j%Npύ9kBp$?JB OaIH""@SqS@BHII^<7_ƻt]弊}ͽ׬.YfeuRӬY[ӳ{gOq'2Kj^f&k_f3~bAu[&LyG̀N Ltr!+Usx2Q's'*#T*^m[zv(];7wǙm_rAJZ2EQvFGG0UwVgzoký whr:C]>Z6|.Ȇ/iVΈVxLCQUS4>;T*eRE$|ǚQ2 a$)12b` (fA:~Q*C60 TH ('== P CY@ij\4 hyF !-M\hu_3)dh$Ix&;m ncכ֪7sgr&ZKCkv͛|sx㹲ҲH$PPׯ^t(4cƜ{JsoFVQ΢$F4s;㻿MzȠDV@B2MBJ'#ǕDNؕdI @|¨ SRWg-Z㽷l2/[xb(ã#liiim1;np¢C"@tHN1@HAtڂ,U~5j}k[\b GO>E+*18c U,,Jȴw,YZg%i4;oWUwu⊊,(tU=Uhv&EK"q*|qz !}}%~.E;c^)`Ks sak )z/7Χ 2%d"DA +M"k_(eF a AO%kDPTqU؃3%gM!v]3Z:X4q-;)8:In +ՠn.FB(# {(P!` H 4pA eJՖGFH'@ P.@A9M-|pgEbW*xSQyZ&Y/B_wPLj xS2NMzn6ВO4\PƤR}Y긝#/<`]U@$$aUM,ݤS!9=EsX> QD@P "(L_3}n0)8Ȏz63)!^']3S9(՜ZaKIOGź} MZZGGDY4YLg0ʲ]]/MSebDF #m5."+4.,,I&D^ZmO-@lq~X.j m[s E:\ l&kYviiFMVz F9~ғ@/QBqQ*ĴAeI7F%b0!PQ! C  N E20Xh((`%F`Ðe4oHCDn(B]Di,v$OA<S >+$IpH>TR eY֚`ILLM,JOJvMvuvjéV_ZK@clB:KK =4xw[V:5!YE!B$1_3'*Q8ùf%)BLMGYR\w|{WV|zpV[a.M8ݍc.#k'TRo<<lpߟ u]EyoڒMP h`3AIُ<#CjCϏUWT̷w8u MrnegPtIΊX,VW_;صm[vv3Ҳj |bIb"CdHϕss`pՆ;׷Xȫ̚tL專?2VE'\MHBR`kcxӵrOxݿΟrd#^$ /u~a,[9TM T9+KWfsXw}g+ 3;gqt^$ܛʤd7b1˃ cQ4e'۔ML{{<vv-336jסvE&'cCdN'@F]CwkvŞ?Y}E"a|$0nw\f#D|m}⃊L^ _}T= ǘڮp8^93S;IQ[Z+"FJ4' |UgHHT% >IeEݽCmcANCKXy6,+9%Ibr" 3W'Ύ:jvNfcH`N. # bJ U"֋*7 Q2C &a>n r~~1t<Obc~e;0 (DNe.3"q f p<D$as(% #a늏  X0(hM~iK;퍮JǟWŹj B% /mvRTHn4S]<'$Ā?CQP&va9[!g1ZۺLKU|@QTIv7C]qx" 8ۢ}PypYfTX,65kd,X T#M; lF"1øhI4_qu$V&3V`TY$QKLH8/ah4ҘPRQ1v`T3?]5T%\QTe~7c_5q ^9~}M/Jekg ^e"ڞn֝"g&'"D)]5k*3,4]h$P] koJ୔,N,$&i`P8Ob@:])PTDHozԠ1*͉֣X,.I Mr!ţ"H޶~7AG˄c̢|ݘ=TpIZ@ M[~6@@BŠB2!JP#csW6P@h7> 1o,I%` a-`4sxH@FMO6?c5nh;9&HD%DTstuh,_G'pq|ְ=ɪsWhb c B\6ƶ'!H$AY d̹H 1̈3Ӊrg_x&&Ċ3*,~kۙj7<Ã{i.y䏿~z{#6PBo?d$Bǣ6<箢߿WBĢ뺍b7Ș64yIݥ/W8v0~ ayzV $IH828SpPnw7o}k6?Jp7ڂs}+Pe~ԏnOpp~~z}7Ͼ: Z*3~*Uzw|6)8m7KmcCbIão&5Aش)LA(|hO+#`"q'#EipkM,M>՚GrNEg9++Nڲ^oUL@(^n$t yqeb갸qǣ(F8/$bewkZ0j͋_ 5K+Y!G6д`ƒe+osO`_+xhZ>V?ϜNw=Ukf_m!ʑɶ&8Htl $!͠  %B{8bS:EgNy Zx"Vz Cє3"aYe2#!gjB FQbܬߵx$، ){[?!"JZ`YOw>ݿK>8Xw,nppt[&BG;s%df^S.ƪ!1HC 'yhe+IMQϯ/ŜMy9RLT4yΟ +b4Wi+cѩda\B$9X]g-3Ś4 *A2l&kmGkfΗ~ސw RtGmČ?03=]n;- , eY+.fNZ۱?N"_w$%K>,J@QU4KԦ{{Ohz^=cTU{yit7\ QP':A CC~g)Vc\Jmd E![* ^+13(q =!3E8A2 9H)u&p.ltIi\^@Ϟ/>,4ZgHa|t@ΜBl /ͮ(V*gYcbHQ1r›/H^Kާ*C<$7xX,7tٳ;;;_z%R9(L;2$Pg?, 'mv!F(B@Q|,,LB ieSG'R"a,0T Vs;r̰0Ǥ {}q84zژff |"Ѩ\h(H!B G@ @s1:C\( /)R?d{߱ An` _ڴxZmssw󝫮/NFHo袊N$1fdBsx%S&={b"OIŸ(A%;)JᣱBBGK+qC/H b$Z*}y-U]mArE@@v3ĻKsd"CQ^i5]hTo^xeOOysg>Zr^޲7̨6}@O恁p8|gt;U<">F)z,'LDΗi[Ps!K*T{H@dYRd%áFXDED!.ɲeIEQd B@c`ikP𒙩(L˲R\Xz5!uD!+sl1 B"E+.o ^YdHɌ Ѻgƅt # $e<8ZXLt*N^{;wLOO={ŞBnRn`FsC掑p!H+"p.O!(縮E22npvest՘(@Mq:ƍ}]cZ=Dhx͜ifYcyfT*q,˞lTH FXEٌJвqҲUNKʁ7̢{:(f,<(Dl ߺq''6vŅj HT8+hӄ-0B,j؊~: |=SGb3gqѭ?Xn&`$2QDr ! 2Z)y Z1i)L^2X"l-+d5KŠ4\w ,]5j?rYya)>LF0mnV4&V +vuv&8Fpw7x&u@P\)HQ*PTiiinh4v)=_җN(ښ5kfΜyM7!/aAlrwϜ9s?pKK˙|=<Ȋ+ݻG? 7ꫯ˲flbe$x4'*~D8 Pdx`@et dKB@.VѦv- &U7iZLah '"‘yV\*PB.dLAA?~s3ΗB߼/|2wW6xIf;ٿgqUvoAmք’a"󹈎-\ P439x'xbG#SO=裏\~Bxo ZZZnO_wuE555{n{vuu;SUUec200c3g-16o޼}7>#k֬?޸q$I\sr !e$xQbC&I34%+G.̓!Q8eIA**d1~kW BgFG/ D8Qؠ|i):=#]ǃ Lv|PB@!ɾ;@@50tE= 7~p7gf!@= (>K+x7?ÎUX,k]|+oK+edd?dZWWO~'x"--_O,X@ӽˡP_׿h4ڼymv dD!!DK-`|||Ϟ=&ittt-e={Gvá|EHDAX5<_w 'W߾;ᄌ%Jg )n DR.P#Vgx-˫zSRӟaOt2,rO>s*+v#lLg @0 q g[s;@k|m~s8c"@pkc^ `@At$rQZ@"n_tۜ?k_`w]+Hh5'n?nڴ_O~zon@;vɹ뮻RRR۴iӎ;NI|3&o~Np$$$Ԍ9NEQl٢VMMoU{C&p<<4(?a!9U(Z@3i>k;b7{;npJýZ2mrh`8*%GcG`AE&i :W{n× f]Fͼe_Q5 rV 4R( 0 *8 [۶[B ɄO|QLJ >t1w⮕(,bh41Bw@  A06oɸyi]KJJϟuםLª*gΜ hڻ;==(2cƌKKKyߵk)jժ뮻񜒄N3''g޽GHh2JJJ@BJI,(bf 9A-(,˄B G<(THr "_=x?pj X pZ;6Ÿ0=7|ВʄA@ _ "'mPB !b\W1>tddDwy_K.]^^(J `Yl6OWOQ/|_M&Svvo144(J0ܹs9sΔUë>¸2晀aPRzB_z-_$mL;;CfS"'ZqxG2 9dH='B@!@huUaP=}57MKc@04B1w}ϾDK53mlN-ng+(7]\Ia?qzLOA8Rp3d[ Xl۶mwubٵk׆ L&o~e!tdUò,Bt3ti:??l6.]t@3`ӲgJʙMA|WV~*dz6g7 `OcqE}iNϛ֩XVj'R>]2€)yGkZ$JV%._|%DBBz˲qQ8oCQ9׵un⦎I9#]կ&^0!Aco<κ@@)4Ro.]e˖ oذ?JRT,qa (rcNKK۶m}ݷyfF`3c-4S"Ӆb Jf"+yɌILYnK0ԙ3ϫ֨ʟ~j|cg'eIC/KǢ`9etjwym4[ŷ84WsFt`ˤmI鶲{cY^,p!?844| jegg-[H1X, D"V n[億)Ǧfee꫁@`ݺu*j̙g&2RCC Q y<[H5J0Aw ( Kg x!9hʒ2'.;Q$ID(ʯb´^kH&5wU.1$o2<޿vٝE)}&9h|d 40r8Oy{ B))) ð,;s̎v555XrjS|ii믿׿{ڵ:Yc 00Ǘ+'<\1h-$0z&ҁp !) 01)`X( &S^4(N`'TH#MOY<{MKgMvzayт^Xםo_<3k5zϼ|qhϞ3)m?N=qXѫDS7x_o}[?x7w뭷t:-[nݺ_< kPZZY֧zJKxgCFs(q<CRN$IƓ-a:ZHHV49-%= Zu wv-(ft$fÐq4KP ӇfP ppPEy+4j}Il%id?޴?;NO]5nW$KW̻aN2Lw#_n0Ͽ?HB Xʞ[?~뭷 `0̙/|Ac-[6s̝;w| 7,Zt(o~/>$&&׫#!),1 <د9LS+Ɂ1C명}lA-6{S Q`y~Y>w{=_TXŇȳtWߧnsJ0v$P XT8! ahvE#{.e?ð 77) s& W7UY]I]`0sGc/t4oj.Бpƕ[Y.qC=tr|0++k׮]P(55u͚5999ѬG}t˖-CCC$xGK=PVqz7:pd3ͷzkff^܇zԷCILpINbʂGA^S; Q(Q 1+}9GA.;Ɉ}Ɔt[[!b \P:pH bp 3}m*7 7gEBтҜs\"PH`(Ms/( ETX%8QKA!{d̃|H),{RA@!3SnGIB@%nYNr\`|{uڇ+NP 4043h\B0::S=qT] S8Pb0dOyB.j}X;ȄU. s 2UI_[yg#7>ikg?;A 5%{Bb>NE| J%Z tj\s^ ṭHUh4arw&j0c* aa,Ȅea_3wfS@Q~qξ*NS7rIHN$aUUk(J oݏ',^H4@0BH1FDklĞNɡ,2׀ЄagY3Z>.פ2'`dtdo>IOY8h@$5IDATQkTj#C dZlwx\$YI1JLH.L+Ryg`$Tdz)!Dp_DБTb{ށf1!6Je[ؾckD\@1Yu{mk6EQi&UC:Im1L$˱@Ծ'C ukFm~{r)]Rhnد=VNt/ IhR VպaKy߸|חϻe8;Kf2L:63wO3f4#fX2cN$x J+f1K$3VwuխsAH*$Q+a "Y!`IR6hm(88;Oɴf?q45#lvA듄:7Q"'%ם^w t A"4BvN`. D$He!m8"{1WQpD7cf+yy HL E\-=kh&wegrn/.l:$eGCK65&<@a~ %BD)SujS2_'Sk JPR@m|ުBQw!f8$ /Vr˜3)8~66"R%SB FM֣w}aNF,BB6+S_u IQAfT|hbqX|W:@hQ,QP@F醡}`/3Xh8VE?X7UY^Ol4Zcf z=`|cE$)n)f7PmM1, D(5yZkAGy9.jc+K1Ex`yT:ž@@RNɄ<qPTG&;֐s#@& k & Wat?Y8 バmXg?T F@gL=c{‘'Y4]ߙŊŠOz"oǝm;,i D[2 609 N,^Zsa_ AAifUi,ELZX(r,%T4:0FũI7HIBZ"322t I)*U p,r,&yۈ`4/pz,}ZBq (xsрl1 T14qHr1?R37c-Msʅ|!at/{M>鉼0,} n) fN[eCaЈP @P1}"k(KG@N[*Js 'SXgI9V+K9Ff` (FD ́,~mᲉYAٝpBTd A I4BCbC;RIh9:| $#8&"Բ+% Ó;6OEHMHH)`2P(=2zy Ib87|tvdO#H 'Z-8Rrҗ7"glD=ف_/̾pC=φ^l(Ggd\%ЉCnANiaQ)gau. o1$4Z|!f09AGA(H}<ڷxF6R+S8DՋk<gc!\_,1F-̪/D,ecX0;5% y{iy0\ ,`"6Ǒ`\䧔!%g2goC6z} !ʟ0rDvן[w[#c6ho7sͯ +7w_sO]mLk)f"{X~+$8ID5ˊvxCJ-w}< yZKPAMc*SJUPLWjT2PL4 *t@NNsq͹ O f|RBӴ;}!oMQ,:ێu$y0 J,1pBWZT~\ W֖Лuq)3&%aE(Zs΅ 5'l}kζF43/2M9b]Ub!LD4;!S'`]lٓ+;'v6 E͕<T,%QKE9)\Saf\IP uVL$BΔPql%MwXfOIQ4"1dUK˚U?g#ލk⼈)EOl\qKh4 y>~_f4 Fvmxl(g W'NTxbT͓Ekj}ʒkd͇gG/g8 al=U uW Iayzp!J\ĂvņJט_YA"8&!Fvb4yY`F<`|bB1 rL Eca eU^lxTڍ-w#<,q$ұx:چ&)|jê5 AJRRT0F47[6#!Tg5$!3h_B>l*~jSb0J̕ƌ| w@w=;sCN }Ox$céT_z -˲G/ 8D(&’ s2!!=fLM'u4(<#v> v^R߂@1XfHN?h4Gh6M?s 1)P-WHTDEej@(r8.J.)_ܐ\q@QT,b9z*g=}gMKV$*Q |ßv/ϼ`y +[fY>y=owjfnUr# &k˗ЍlxN*<2¯Jte<&^=n1$-JpnT݁~ MWj Gi\=' Ŀ7#}RH^U+ .bWx)Mj Nf A;b8 }ߏny]K X@P-$?!?ۭ?!Q'|"[ۇJCՂ:BLìp(y&O~$i7[$mXnF<{Cd$ryI^)I$)ݴ~|c`8mN]Nzi.N!86T_XF!7"0B>?^k@Δ<_w''x`ɸ1xOE6RUBQ~'$I,Dv%X!x'& H!,YT!AP Efx;Oݍ47)9kOfKsS (MLS/s{H2i om'qS\Id",k6|횅7D"5yt ayavxHN[JvDx@Ǿ?|LSǯ#ѹ?w6FFqC/eXYdcNVnƿ/d+f$,)_'at$(P64[{_(N$,jtKA_uJ%`PqsD)aRH,$EH b`(fl´$(U:1!ѫ ⓍpH*T$uze qaU|Q57 tww^yl[TI_y6 3Q)BEY8yM5z]'^8@ays/})<, oધotW{7zh ^j=ƁGwRhfIH1Ƞ_WvLRʯɛ pu\/Du`l2Pd8rQJBeAnU}DI( 1\桅ɪ((Zr8nj~{ybQaQ-:aN&w&tgꆜG/(x`jtmEP}THodiS.)LgY5L4;RC1TRwO}@ 'Ks1l, 9nH3@(oɞTkCd1[NJY,V ōBN31_EJ&P5BBqa^$L&SGONuƒ8xIk5LrK^chkDU,C뙗l[ta; l9,CRtzx=susﺇߟQN_o0~G=%y8]4;P Y+rf}kmAE漥m-,}ًz\xSiR)ͪpwĚ*dK)'ZZ ĸ2G 90u\٠?17 q\0defۇۂ,(-˫jkL&V"7=a tB @0Rp_Aܘbps4-T.L NzZ( /cqU`p|CXÖw*;0ݭOX:1&Y @;8"?Xu79N!$;P[cMg@ :G)X+NKAReC\L>J,ѱp]rGT*1_*aՓ+-PJA[S\+iOgmgjx)&N0U65|D'IBlƇ|8)2rF^$GgM. zX!De%ԲטTJ<.HBj(tmOn~Mw,۬ݠqvS:r|5!JDs 8w^7]YCHxעsC0g˅(i˝t 韞zkjeoVt:D3sLpL|)N"p"( Xq*N2'WW-2̷иqeD"N1'wlvMē_miZ\wp^o`{NN9|oIX (5$gZ Lž|XI#fٝ-liTjCC0 PP_s,˲< l;'G OUCNgNqP;!P@ˡ}xw& .CpOEbvLuե0> X?S%Cɋš$㚛5/`]P*)"@(#ezq^c9lk9nZVZT"I$A3c"!˲p4Jm޽;[](9Җ%59S@ں}챍g ERCPXݏ8 t} 2sT\HP~8-oZzZ>*JPTRRH8&CǛ'sTj^T+$D01>&z2J`IadP6:* Th ҆b#*␰7T;,*+q8KZ* P~ :gpAv0bʳbɜ9>XP,Cf%Rd>p$VڤILKP}F*AuvV@]`.(K8Bh5Z G1|8v8~obwgE999z3ZQ]U]9LS{/۸ZS}/Yc.Řؿso`yX(y͝cs3/bNpAR؅<#Q ƭ5(@ø,v@!8|xޓ. ahTCsX/ueJEyH a`~%@05ЗJE*\'"8`^ F@W4i2RhUD0,((㞙qB=! r.S#\]5cҌw.蟊 ?[ThԛrQoײ?*biFtjrU% )i|-8ntluly)a(#KRT da "b?=^qj΁?{x!9 /` .]~Acg^ׄaU/ ,H@l,Ґf0!"9#,qsR__ @=nn MpK\v50ў85RrAkaiL|p""N) TPg]9L9Yʨy"s;T! \Tg^K~d4% ZS9fI]mUxI`AM!Jo*EYZ1cG|.-%b{}7oƒL4"=AT>7Ί>ÒNo;{s?ڙ/݉^( I³ X: ~f^"l=Rw~ZN/)RL e^uf"ub;a3iLLZC@ %j} ůu{:egS eɴT'UIbs“%$+L">zO ClnyేnٞSm}iD,//2 ;,}145֮)gKsO4WVu购+NJӔKL?pӯDD'eb1"}y>NݠuIj O ǟ1\g4󻗡gs/*{^ћyP6K܌HE ݭ-~8a{v,ƵO|Xyi aEj>_ЈvX;Ms:N RTU ?}y$nZ}!o(j($fAG8IyY6T(ʮ~~!a8  z_:] xw$h _;77[TO$h zOih(b/ߋ})Ŵ(@2v {ZwR1{|I^LH CDot/+7? ³bp6s9KVK՝B.%CBBOAŒ  3iͰ{}Y#sc6®> ePT!R(sf=]Bn\)[kflYlF5}6EVpѸ#me, E`bRGg^Iⱜ&sfdA_>8Pm0˻IE( CƏpIc).*qc(pѶΙhT'[,jJByJ7lj׭3<L|xKtb3"q .}dͲ3iYT?ol[vѵxOT:800Cy3'v, tp*VZ),Zb:$Rk.S_ۿ<'bC**qAR7ߵ:+[8.H MάBy^})\bgd9Bl5|(AJ) 8OC%&B }͡o^ӳ&mK̿hg}0%`j˖=])-8Y~ş~ɫr%,;8/#u+j)". F^a}6|4x Z%޸hAmNs: |7PڦDr`|HI5}y훚+.T-fo=q:@<︥FRV(f 8GTrkps,$AȢȵE"ScÄ{(.(Y ?%0Ȱ^j5$dY6oqP)J-nho'twιr6oʯ*3olbQ1Lؑ2JOu e mAJ傑e 47x+Iqhg~PTMP@`j~Zb7u׈+K,w ; +Ђ'(>rhw&e';=O5 \ij|=%ˑ`n"&_SS!*ReUU[r6(ᱡ`$qаlXɉd:\\\gyY21;;wߩjUﯫ(h'Z +\ Kc\ I~ǩξĴWeX%QV|(S?iz2KZ{RHDs#î rҡà4F3ё8b`[Ԛ(o9ň]*%{|FP]w1m(>vX3޳M( B{Z MĽqɳd(D}#cH,+miY'{0CP_@[kи4fyŪzRөtzmU*8xѩ-[Zj <գFQ܄ 1 =V^8>cRaDY$GsRR\50<;#ztJ4WB:5&x& y: 5nXggxK;[f9U,恏c zsCW֣k[ذ?P/s~^.2T'BRe2QXHJEBp^s3zE9i0M[H0$cH($Lsˢ +U2N}q58{CSS=,+.F䩾W^q+9$EQ,wI!8qݙduEf&ѹË-f=GOM{QRXHDG$ۤPCS! '`0.x-L,{;)wl-r]|`xr@9X#[~/^Vo*qe.P_¹t.#k78vBØ4eo˼޽#{z'a""aOUb =x`Lh4ͭʪ^xm"ٹ'?7.+/HPx y> s~͋kd2 tw?앪 Ù?}'pؼ"륪F#w?j{}!)u4 v㚒'챪G6H vUO Sq~"LtBB#3KK"t4&ilѐ&+5a_AgىY@WW6]QWk|XgyRNbcg M!"Q:jnuᐏ_MIHQ驩;x\_,3j=W)J<> :2׬2koMce> 4 CELKKowoM&H*̂UY'wt@^c^WU6soO*I3Bt<=DCBDJah*@dCƮ <>B̪Uݣ-PѭlX20l(BhX9r͆|5Lyj&IZ\eV r=>1=ݓ䄬>.D@h&ƤiՊCL,c(VR}6L;;A_2J14#߲jWm:rsbD'җevc,?4 T%b8@KÎH`$4Y|sՒ1$^$dСme%+*sOS;;9~]()GXEyv]{'i(jV㤚2Խem/{sWdN%XWܘ:"7ժV^.w0,@qBijm*)Ԙ`ɓUy 1 g:$]kn)D'.kEZ (nACJ߬~m *u!w]XN){oȨ_bYxR$1T%c BD!>/3/  vzN'R]@I:RE6촒fy&L,fV^Yc/w$Q8&+0V~R6"kퟞ%w//*o v|@&I嘙g zV[{54& }LS~e٭ۏL059/懫@cҨ\,iʚ̃:/l}$nDy0ЖnŪs`h Ȩ-\l_LA-I܊3^rxXlC'Oh:88A$-0Tc&t[2פ2pgPާ1K-OO o{?*Nde e20F[R>mT,ZR"mN۠cpĮti`d2hYl2Tg%W5W\wPHL-y<&bimA]uyGT a8޶P__\~:Nu~cOuL>wJA^?!}>+ k\t Gt8-lXNZPQ"kү)$sr% >]aIԮݝTBhID_<]R)q}MNAJRNJ.iE%uϯ|J!W@$qzzNSz#ǰ]pb#$7<ϧtN̥afQiӢE N9B5u ,;vBI08~pFiʷae͚{Zd bt?zsrñGXܛ/+3cSl>Jc~ B(sC[qXPBdq k6<˨s| Bߓf A=`5T%*~t(9BӀ%(6Wϝ-?[CA@σ bȗlQ@ #]IYx9^\,B`pDpH  3TLH )<P7г@gZ9.v֮.7,*>rwnFւqD2qιldi8mj;Y!{{^ZT(&Sɑ<58O 4j]fz5Kם'Syܮ~RoT~W}iH*@? ei=pxbV騟$ }/T*Gk^\{&8ܞ9Q,ZӠjҼ_:JJ|n$m?; rIsO4UV(^}gޘPT*M[UpÌTؔ'_?~^XrT^ix&!4j7@:jsl._DQ){&\DE&8,bTvrѻvb~_>ϒJ40>0%.!$$ e,âb 4K:Eh`9LTUPiEH"eٰ˃() JY:ļL!q0j$" %8J ?D'SA*hAthT2a9 GnC9&)jjƧ;rŦRyTc3co) N7Xܳϳ]W7Djy5v}$xo"P5| ix+r78:c/MKTCWz5ʴR,o oKziRj:UI(8 :-o(HNӻoq{E)*Z^yw5rEůAs w;?xSYi! Px7BlP,n(s"\?#.pX~}Fq{|l;5)"OUOD}Ќ'w̴sĐ Q҈@qXʱfp9.ddސ6~n`R6}"Y16WNԡX0r_'xRqA)UowG|i>5<:1JEiQёg^_vOOQҼ[;NG:]#ť}_*i+J"NmQ{ !kҥs<ExrLxJ'3DD!֨ҊF(sp %`|dvvX0кw-Gd"LQiJKၐkε>w7fqVLvi) |$mCoVe)#hx0!R_,wzg}ܵ{W:Adp'IB$ K̑fs6N Tԕٛr&ٔJF},k=9Q6TIYNOm=H2ҭiHY7wʺ6Z/1.&>oƎ~s-YII5\uY uYw8+NEb]ba0G'Aq.lcDXU_v"dl59Mtߐ^H3:߳njDo}m)6 _WXFYс]]QVHzXGvx \9Ϟ|x_jy~ s \W&[: fZ3bq$Z1818DžYUmZG47x'ե[0R s|ohHQ]kBK<˜x\ԜDJ@&8PF}T61jw4q8,5cpL 'yCOYNQ"Rh]L"WU$94i)-A64rխG?oSP*fhD|9#V!*x25~- sLNb͐cayy76ўW-f"gc1ph8){|lh5qhh_ݓ%- `qesb-K4*-fY6ػkq/%]HžVZXs yw}ϼwک=3VX$ b'wvcwߦeKjA68ӹbي[*Iq\$/oHSizbr؃eB}w6.^ p[olܳ>kqc b<(usЧO ;>tgYб_='kE[ 3,N<ݣS o>#MΣ/R_;&6uWor@$Y4v8p@8 t8`& N4 ,Rt@DMDa`'T ?M/Wmkċ % ԭZC<˅'-?\}Q;G7Fʹsib/ENQ33>OxOL&'g!֭x= wu=rZ_eplZW]ZZܼFقl *Ko}maRF]kso퓪sGz1ÌDN3cYWg7z߽w/S3/w;/ f 0B 3ޘg Z sR\Dfj4J4slRg1Pe*%tcf]`џR@Qma! ىUw˭)`0@A׹',]H. p4 pOCvmk-;A X='LrYo:( }3s3YO <:}s.ggm]ɫ9걻{tnx\5kZWdy&O;.sr:z&ܩ%VE 6G:"ЎEu a T>eYl>3?|㉃;131f{6ܼ|xwv۝5͊G_qSoo'b;rȾ#Gچ+2زZxaP(`;H եS3#,0uC;`wP C5Y¥(Hgn蒪+ƮzjȽ[N+U)#.p0 A77N$QXl+pcn,%!yx~vٵfB@wds@噘oݺw}=T25pcֱ]O +{,D=`~dՖYjC귖kԅZjեduؾwO}|1㖄vw ?ywFö,a&#K_Sg] wk?ѓJ$w6_]/xy [ ;j[6D"y}w-j?_i>tҊ)*2 p|wWH \B*W5mdO|ѓnj PɭJ-x|>pʵ+HbRUn1r2_?j?< Ye_x]ӡ=Awu3%]G ٖ_x55w/}?4#w"{yWhUH̐e)iXhAM;Cyrӵ!@/fLĴmӏ<n>j||$dYs߁ɩ[֬nj/cI+Uek4+p(y=(ۘ|IH$y~n')Tt eSѠiX[%Ƈ,3w΅.XOO OZ%bOL{3 n.,cpٮ/Ѽ>ZwZJpϔ ڌenay |ՃT⺦zKAޏ7LC%cL/N&NNX) |I=)$"qRFtG%P@ ɰbe(0iZR%"m 9mRS;w>Ъ= }E I"} %/H!`e |x60?ّX{?)ZLZ$?My)/WǓ6zz*h"L"|5HDO ynJgYU5?:9 2ˌ ǿW.%PI"xᗷ{a?.=1>rIHQ鱱w:Eh_[@~i(k]quUB;~SR>tFE̩_']]\Ԭ# lYY_]E/ʏԖ\k*a[C^! Cy WmrEy"+iQ"܍c9>1?xԎ/s1p n|Y.;~q Y$a,}k'E4ʱ/6=ן..|+Y-w=6ebisB̛Ks&@*G1՟ΕsL %՟H%mLD {mW{:IHmI40dbG_+F w],G?X/>jDN{';k{djvhrh.kxvTdIÍ¿_~𞂂J40"S~q5Of.:2 xH`uyˆby὞,i_6}xQR$%Ep,-z?6èKRoSDLSE?YJp0&FEE( qQZbUDb@vBKá QR$Q bDA>HIH-\f.yqH0P @2#b 8y%@&}a|<9ؖ'b性$A T $ 8G+FEfXDVBrI͆z=6흕r-2n⣒ ÌN37'($XrYY w$cB$%U2D:NM ۔Eո %/")/k`Y@ MtYTH8O<" a,waTE)u#,0Jh"T ȥ̌Qd$B:IR0@ %`Zн0h@$$Q i}-KOOBQPQH; f<B*ɋ N{fo umnE7Xb%0Uѩ :}be2֗(0 wv::LwljZRR]_s˲=#o)P} [ٞų KKMFo值gUѠvw4ȍc}ŕZ=r -M6.+Ǎ:iE„}BWV,eRqesBPQ ,/3oONdtږNeU, fq 8)DP4qBI$gА7YSf#(@D!zvsgJH%Y7IͿZ/Q!hxPi`e@AJ"ZVD"VPb9BeR .,eQI"Dz^MDIaYZ8>#3FDPD |sۡUqIq䩎 EhQZAgYwFܵ>ڶ3"w,,D"H;rҼ3́C' JaΏ\ҌfUl5jWH`zsB>'cjHGä؀$]N`$AZҚhZs(_i.M +Da!8 yUyt 8q,un|ƁU%١Ы  ^JœZLR,p pS@hwܺubQO>X]5]ɴ`Ȼ]F̼TP@UosCpTWeh %NCš u k2oX[IH$}awOT[ָf q/om倸kmE}M إ]']@ug(zs"Z]qõh=<ʦx&Τ#c|VJ!ÖזBX2%: H:Bq297"/#Ac0ҡzĥsfIJ+4[D"B$5ZR!tjp.J(F$5 .I_?68$YX團OHC*bТB{gX{3Ɯɀ$δH~2\@@D,/op10á%e*ytcG@-Xg%n$ #svh_5T.x>RST-9 1(57A%BK5+7.chNQϱ|2.je!^=F_$I[=kϩ,9N}y5\z%wWVV{u홍7NMف }lZU3i麇["ø82@䙚|R5 <7_J(2G;;xBՋW~D{o@LA!@"<|r{dբ5n}Gɘg#m#}~u;؉N0BQE¼|\S'<˿NcB>:ab6@f>R*%Sԍ ̦-DoD!ՆBzᎼ/$bH( yhgm"a_ٖh NOnu r?6&UTФ,8NL&+꾻iTi volTf\hA V;,263~:o:jgҒ?5ׯ%w0l͊K t=5]ZT+J鹽OhNUPͤbV2{lÓcWrl'ɼ.CP2_CVrUK}Dmέ\F^ec|.D6$!;'x,׶I!ҝdc=ɮ ,)8ݸF8F~{Z!2Tp;a_0w>b~mp<M!ޢC1WHE oy|Һ_+(PKוּB!,ՕMMIo̳{jiŝ. }[{v,TV|[['ܓm.+AyJ9Jkef= J嘏XҺmτ LKl=Mq!p}A - B)ѸZ255(H@EkQ2F(lD&G"y6}1 k{~*"4w-_b DaH*V5V@ܱ~ҿW=vWPi&P&NZuU̎.w۴iI 0/a0N[^RՐw;RekJ!%Om$u&pkAQԳoqŰ55ϚmQ+@ܟ"V-*D9j"myxG{[j ʅqXU"`]\K5v6,mN9)աwݸ0'(vzdިi3)ʢC!&g"t09yBzUuT#';DBu#D"5& A<(嫚f MiXL0e!VeP#Q@c+3CB;bB_.AF1liDB%dW:F)ʫ !$Tik)AEL* Q5tוI[;mD\I<`lr։ܬ#9fc֚ Bs|tk _}PXьt0;TVrO<%E7m*+WHfd1My9T2+86p|lTЖk|G\@1'f)x |T4b@<.I/IZ.-2MB@S910W\gZ]h9uTOIL*yqppDbR.\ q`vO@.E0s|&8V. jhv~WNDofjP?#9qj )C6kC*'OOtaJ/7dwfݣ߹TL2Hs6^uhT R iȥ:" P0 tv*Ad2Lc֬ JѪ ahA?Ӝ])<HҡPbκh<'I長T#?y' , , i`hh`P{F mvȉ%tw 2Ef6E^8-Tt^vCxMU6:B 9 q.IZBj]}#Qӗbᑶ`$\tc!ͷ 'Hp8v97nκx~#VS*caDfcogԯH/ jk9*.EXFB'8LNl J.W^QVߏ(!y!UTaOFcǭ/+Q[͂F-JEĝvs,zC_DoB>̀y^HUOҴ%YY+Uѩ83s`2xx&T͟[޼R阥&ˣMh G. V77ϣ̉ɰ2k۩c(U_/ejf p_KP8q']_bl. dDcZeR ϻ|f%ZFPI),+ȾF EQ1Bd3j<(+WS^gFaљYDi<@K2,FlRB2+H\ W#yHд JOG8#/ 9< upS4M,Jy]!0]XhM஄ë6o(Zi(,dgkqWZX~KK *<}\2l`lNk|pAFN"B@OS_6f0,6Y\TXHu07CI˝UOo}f薚Ƭ?l8>ȩM?q,KK[=6E'/8V@ [FX=a& EKhigy&>wgɍ, t5~l1wIqܞ@GGg]c~a8\eM bB gϞ qyq*g=FEU*Sy|o^a  07&Cɨ?Vp,V8o}Yeyx* *JKZ.ENeAFebJ12?#ꤊ¼b025>17 e8<*MqJJDb[ 3Jc&Gb,]w,'; #NTwbr44Tm ɱRա6yv̛ό]Ś2Rh>:18>|yhd%P20ቭ,]Ï<Ƙ ~ʏz &f4BC4rr\ÇqTBmGSBB1Z Qe~)ʙ_r9<6eCNSQb@G⨐ܸX*,1Sg6gd%qgUJUh///d2*A<”WLQK"#* bfVDU]7dDӣdbi]5. #(*D paS*mX#* rZX;2>5?}hlR=>BX:L(YȖ>~MBy6ȱHS\* y?|$ +zjWE2t"! % pl6ƅ"c%VMdd+ ( ą feYE =R&KKEurO&QHjKN|lKf"vY7;cUYBF3huA 4)F34$)ztfuy%ula39mm^kOG$ ; 9)bC}ӊPl~xrL(޹|Cd<2J& 7Rt11A'.H@DjT}噹5`{Cl/V<|ZՊJ~4Hᙜ ChSFq񷢞s<6,o.+' Y)̬YDyUfQ ieYX8A[Gq'/' M\CC IFW^"5$(Eo{?tj(~ 4Wd3DVkVJ2}'ɌV˞ÑhDRjS/`1GuYiw/%aaI)0'.FT9i4HX1arΩe=T k1,!s9m VME3֔-A&WCwLu:u_~@0x{Wy]6Jrh5J?GBq}D(S1RxK _ "j nqъٹY2I%z.vep`I / 8FD '\2ɟ< ev- r͕5Z2{CȄes7dd2*4wYjD!εdXtʪ`Bkă4 ib3lx^g,L9BsDE1) zJ?؜ d/j?E2s6-}c9Ld^_w}˜1 +-QE]9!f8qU' BWwT>ҊO37{&= EQ8: 0}rWTJ)?~5ǩ-@HR:]*{gU=#+.(6{oXpQiYTf2#VK00$$ɁAn`0."e%e,)RO'\IDAT,gEx'ٷ>P[Y-iuLPHr8F8ijրK dт$}5 S#}fN* ̎ռS\2)t fw:T 0;0Sϙͪ+8)⁨=X@j N[> Lg=6Ax*hpvY R}KV\a(al[. ˳_=S2$)*=6@&R(W[zmۯ7xr|XEQ4s|"1vw@aџ=[*",8FӤF3V!}XX~Ϟ쾬Aٙә֫4sqɇGA4VζXc@\p:GliR(%d"9B>Xuye5>bB0it(2!i 1BI}sVuueP8.ώ:6Կ\kvvFf]n@TPX{gř{͌F:a`ήIrlb'UOjS*g^M96>,l@q!4܇깧gAD` K }ߞy}\e73g'n:-۱t&Чs21(\wNQJ*t:lrIx@i~`'/.^~WA3L\J\XW7~ׯ^[*ݼ1rAbt8 c. K4UrX!V Mt,-2A}FӴZlXdJUaq*cb8M( ӲKY_\IOT]NztR`)%rN'f|%QHfе>GϹ0 ?ֻ[=ׇG8+_PNB-XQF81) qX.EJ\kq88˲/.Ȅ)5x +Tj‡\]+)PrgDo~1,aFaDWGqSJ\d*J*Fe$0MTQa|.# FbsL5u"(t<>o=ܬsbC@ e.á_kjGrX =Өe.p9_Tjjsv4'{8 ~ws׻ {ܭNErɜF9YhV=3m-m'VVRѡcbINbhv.ɞMιF^R㋳et~d?ܵuƹ+jO68aE⹳9Hc,nP  8N+BVr:%8efi!QBAtjPRA lF13,͕KI,p,f?sr-vMӕ8].r-uj<БPo㇙_zP'q*d=y}?+MZ,,[%x\@+%0sO> E;[Gku 8p0h+ Xbчh:j47UZWH JE%`*RC+ Wƥtu}KB!ǿ<=P.`,[TA tReK%rZ ByfH@44yE@ AVe%iOTJl|5EЮ_jq_}، N) $si*Ssy-BB*㓑@x[KG鵺% x+"0fO_1u%B. NI{qǑ,^**Hdq>E5B#ZFuj A@#'U5X6-r'}㚦T)"Pi8OO|b N/uJ3_l׻ƠD$w ؅Ҽ?Z%8`,mݳr>7MF_埪\@x}d"T\;Gp]G]6IĒ%՞?&VoF˓J쓏8β~ʯ_ˣ-2PbiOO266vq*eMdUWڝk:omm^QWWgj p\.yq87:RT@ cHK1h¤S?hTȔjVV?rn(Ϋ4H\ fP.^HSx0ϩN] 8 t7u0p4*{> ;k B!,sKX̖oը5N[L;1_/W.]șg|G fM$ܠ@$8\~Gqlmb*~~ol*ݛto]_N +.,pjjz=Uk3OLFf{!T*8md'ML(ӨoA}_s/9! 8X6 ,Ԕ @ڤ@4h*Q8ڡ[6|? Ek ]TRC^+lOgw۪. `{TdW^|%46ҵ2N9fCeHBe N*Z>'IxKބ{"J6_GB&fӚj|GwOsS_,w t(VD(SqGL*k_~/8kDR2&$~\#I%d@#r71dRXr@) e#cxaLO:Va*MrvLlhlKx2%- ښF{}wΦLkì~ވE:܇.Սk;! NߝZV%[."3W&-.x<@՚HOdlO%2S;{X:0gf\9 ]B泾'Ͻ˿}DV3WuVR&ͭB"bS ^d*U|.\|*\ƉD4&G(O eό תMs*2h{or`1x89Kc{D"wFncEf`Y69Z{.2U&9v.n[×jCsT2 Sj1,AH"U. \*8ZJ P,voԸ7{i?srQ޶yn_۹v,1h b-rC'YEZ>"@/ͪFMXsBPO%ƽ?;$'ZRfiWFCz:]!IoǶ-lZ".5IU ; f T& }q$CpaHXLj!x_3 לRw.be'xA!ON,.I9H,B(/8讣qPI%蝚C*Ȇ;2ё&W/b 0zR5'Ӵ=XAo$J{oA]{xt֤U|+4Z >~@CnOyf%J(a Qݺfcٽ޷e] |iE?4ڶ="* ĜJH<:[_FˁLT(`cXChf >#o~5H%QԽX)FN(k:<,\|?U*g3 [v3!pNO v׷O =FA~aE!0}w<\IPȳ,BU<:6VJfJ{=g%Vfى)_.0:[~A47D&=>!!,_7lϮ|59jBͭ-3#DQt}G+XHazl4܎`] ?C۶n40L]Vn%YF=7hߔ?|i›ɒm:h0ج=~W9/S,V"tw:>74JoG(EQT 0} 2YD"Mf5otz勥xeϊ3B@}* B1ŭJd?]>R ".}J{ss%tEXtdate:create2015-04-16T21:06:35+02:00K%tEXtdate:modify2015-04-16T21:06:35+02:00:2VIENDB`zevv-duc-b8f9659/img/palette-size.png000066400000000000000000002121041426703022500175240ustar00rootroot00000000000000PNG  IHDR,-=CʇgAMA a cHRMz&u0`:pQ<bKGD pHYs  tIME8q?IDATx}w|\ՙ{nޛ4ڒ{/`L$KzvMeI#$$@B݀ nUwi4f4z?䆫$6z~9{}{[&q5SSUHdY$IZCq4 @I$EQ4M1c@M&1ZTU'? 0 @haiih4i ^g'z8&IxՀ@a;s7QC"40,4J&Ixc&hvfm=]KMK L?$U^BcBH :KJc2s#hK&JQkuZ1՝NO7LO$j Ke)%!I,+,+(XAEQ( [$00<\OPpZFosLqD_I^50u,S1V1 +c1`1#цor>$D$eh3"D4bMlͬɢ .Yt:'zALERFm5(yzci3||FHt챐EBo4:sf7)aqVv0Ik$A jӦhskSrVD#{N4r jP#ID_5I^ `uϝ1$6mOb$5taFaVr"j";= (,Z=Wva%⚅Lqy19gѾyQbFɌ3$ Y`>Ϸ+Gϧᠢ7Oe]$ N&g~+b21ȴ`A׏$FI^G牟:tohdpNpy/$ MuLZfm2K}6h]φ Й9}Y&&Ixm* p8Vy!QKrV-QĘ0IkM?"!jE~R0Pᅗ zmhǂg&REǴh2q^ Y}M,&Ixm,7oК7?8+Az{z(%^ڼ!HmG{{+1IkTY:] `g[kٟ t9ځ1non^䉯_ݶuH\$ƄI^ IU46lԙTdY|eI~n!9͕b?3]^3B=9Ǎ{4gZ <ԆЀN*z[e%D}ПQPl2n[[ehNs8 $5vEyzB;;2u@;YXyED4>|gJs-^ֽN^mԨZm[m۲y1Ox`hxw6;BAeijI2iCѲyjќQ -;32>?!IRe)-VdH$ڏ(1muk*`'3$j`ЩiӍ#E @ QV|`ڛG^_C_9Y9i* #'FpS{VU{;-ԯYi]6Zmy%Vmt0M̴Y5$?$UF.z ඨ(+X2 \A O[Q~OXc.fYee桜lAcTI. 0ƃqh,kB\ϝճ@B]JMw;?&Ix-" a:&yL=`7Tr8b-LIq,|< Ic]~VZʬO;掵kZiu3mhf9ͨaNQnZ,1IOI_֡-C XF6ZmzMRFVqj*ث3O=H$)M8OgM)i#]ye3!=f4Gji"tgb.Š%%{‡;85 :P۝)z6v}wN@4G6ۜ-jn9 Þ[T\2}*1IO9i=$;-$&R$Vǜd2yjaq ǒ1aF~)0MC9SgUull4Mzh^LS_8/Peֲ\e<4&dUh=;̝!IyKu PH}|we&I)¾\RZ$r5np9&ޥoh]ND(hV崖j+!3TC" U*D_ՁIu=1֪tEW0@A&}^CΞtpODž%e}W &I)BTtqV'QQ RWAIRW̙Ahqδb&܅e ˎDBLS,+i3d#ddeZfm:"3fX`D_ՄI~ZV#G%iYYnyŐ?lp*4Ci&k $`OeSxcgDC,:-lk1w~pЫ>-a1gD_UI~Z勦5xI8NbIHȒX6f0|נp|n2`b$츗})e9lo!?1Гd09%z}/ 0IO 8q<ҲFKZeX81L `0cLd1IOqez O.3crPW]CC$ S̟t&I@]אAGjTK0bW0δvXq@[l0Mm&I7̛Lj;ˁ$d5VϠ#Ul\v4xE*2&I@5*s7_82I+*Y,Hɸ!=`NU^4~*$5.b |hi5T8 4{kugאl᠚bmYƍI^";$+[kb_TK;h1' X,@2Fhtɣ&q&&>)qn l̎rX3mY755tLquMPm2)p$j0F+*ФQ4c8朷o8rI?Gc}W7:T%%[f^Qd>$ p4AE1Dyɓ8,e (bZ:5hN"$1uS+{ʼn?=-[;~вY1VJMǑ'q$jXR1ϳ},?*4x{Y }DjV! 2,,C" D,JJ됡XBEHQ0S]-ޒY)~{$  FRoH1)c6QV<}IpZŢNOgYZZY VN8}^nY{2724m 3pILMuE}/ҡ^5=*hNɬjUSHȔ֢,ʱo\PGCǁ@ӊϘ;d2NHǁI~`PQKLKL {;;k fŤIshuj{ 5euL% t<6UO+kvc`[~Ҍ$ɷ{VSd3ug 'z*/%&IxMb XY7}@`Ja0VI=;z}ټʥsIO+]㔥,O0ұo Vw̌TZ7]֨/~g(js'w_ت{ʦϢBW" EI&$I d/ ֜< DDTAd"G<9z (t9$I)&*Zuа<5VPǸ2-{:Zz׭/\e'dr5,@ȨoМVpOW E޽mkJ{y cݮWmR ^7?~_G_ywIs "yCo~ӢY}h"؝+j$i{u`|=DQh J }E3ʬfCqNƩ SQq)EQV̛vYu-w\8 bJ03;׿ .ɘ1`C{]^L1DÎ&z/ W {?rXOpWǟ|yV;>ںPu7s Gc=kԏoڼȩ}O͞Xe0e8XiyCƺ?|75_^-2MiYzSc9慿]o+hOL&jm%Y gxb9aMܭud:RI77Ͽ鲙Z͹476\r' PufϛU{笸=%=1ܟ+|)r49#EO/^50Е#dDQܻ{O2c{++VM) :lcw-aצum6@ܗmGDɮg9E@$Du5/ gp;ڭ%y/Qq`حgo}^If*# c0t0}`BT#:箮xoamVԒe7j,|/MM=C!Tۙu.ʊ)w͚Reu77oItZ?Vks ok ҝHID^0l%m@J_ΦYiߺԉŒʀtlPɮ}䠙eAJQD6 T,)ZalQt3d rhhڗ[Tz% $DQܼqc{>6kQuDwwew><$D )5=G` Tp7$``1!1>Hct6C< (K rb|tl4Vtf$E*B@Pd )Ud$kU)$ $32356{SK@*xps9խj?<$>@<Fw2mhVIp^*u[@o%Yv[~T FbRrȜ+O@m[ʫ9mr]}[`:׍tvԯ}E6d G8-2@c1RҒǃ5% +@ ah0x2TR8kNMhzX112~uΚ_{hWkgǡڍ{ܵbk?lojnꪘRK7Le-GwϯnCfBfZw55Ilizƍǽk֬).. lx+_ *ĪŚ%:xpڬHd X , h(1Qxc8\UBGItŬYMjաۦaj5@D*ٴqUdakCW7@>Fχfc۩gQ{,+{Iŗi( &(l,)2h{g@/| H$\}MÞB-gj1) $c8- $pZ@@ȬU&@Ѐ#5X1]$V0 VXuZ`(n۳EݮR_ R"Cy/WP{!!qOB͞2A./ȪkҪeϻ!p(ܯD!hii{w7έpM)L"u[Ufgocݔ>?ڦK|hr;m~OkkRW.`MMSۺm{zάGnn5#y͎+Vtvv['OL[oupppݺu}c'BȎ70У4FeS}qߟ97ˬGS]{_׿~ O`x7x1@(D4(N&&ըb,;!![66y#*vjEiշ/'u~(JA'7\vZv8/r 9 2 xiO1Ms!m|iӨh$e9Qwz9p0h,r8,ξA47&IHqX*w`0+/d$icV \7Ɗ$I1E M0 ӨU /ϻW]k#JAG`!Ȣ +"SMqq/_|ʔ)WB _>_Uxx)SΓ!|S z!tswg랍\փ:AMr3Sn>12\;EД t^hY"($QӪ1E0#?{_?wē3t_F ǔ䦫h ),g8Ψך%8jOS`d27T7ܾ|ǐ[ :{q$/:l&!0r4zzGb1յq L8V.,0?4l!dِN_ԨXǰ! ,RqmÞf:zM,7 hd{0Pw߸:*Kg۩F5RnZPI3ܴwX 8ݎbU*L(}5 @\msJbES#uV7ܴxno=VswO$] ۺn_cz&'#(L.1Ui5&cӞC@;n*LkhuzAVQ9駟{W̙3333&NL$ۻ}.$WHm.EQ3 Eca9%ӧse54ص}_bl '\5m]mqTjSUYDֱ0tgEDjDbd@L0q \j;d\v/Z3$J Z3,19@cQc ;dH 4[pZ(2hL?bpw[A+,/9&m-H8жcyvBf6y`5VyM93nd2N Mlx!V79S!NkmҲ,hF&l1Y,Wvr`y" !"2 an!ceb7dn"mש,ȃ L08hAHff 3҂= 4F`q58 } IOQJcu4O'!햌Lπ7iyܴz&BfUJٲw4,0HIM\/KKPɢlH4GQ"lZTl'±gm\,FPa Ρ)`~iŷ5:RȐUȜ? 5'w05G<<:RR5Y!hs1l,|W:;:g/^ @ (CaOn Ѹ _`(&w;)>V@q,CӔe V3gw^ 4MdeV7uy:h8 \pݟ1۷C#\nWjw;%IJYֶ"D_U З/xuOo711^_Xi(H-Wˑ׏Tfʊ'~lɬ:a i^DIbhZRIEjJaζ>A8gT͍u='qő(2pJ{^^󮝻y\ByynhBq0oRYD>00ײ8-GZ46&Aߝ/ҏ%t9SHgz?y*$E(I$4"?XM|nw8}hpܸIAϿsfcmy}ߢ-IEQST*Uuu֭px/*@~:oWgco0" +|2ip"JӴF2贲()&V#IRP]sdUe1(jMs9p"*4M뮐mW( G`wf!wouݺ5qm^vaaw4lcvdEwoî]x˓XɅlPϨRI3cy P dpT7fgϬԪAkS=g5{Jcץ8l::7yPU76h.3;+j{]aAp2ǛV} ,A%%qnqYA*DB@ȰesUDے%f#,-V=-)9Y+TfTIA.+Is9lӔ¼ fYtŨ/tYi.G~Ky)!Q5`Itc%ƕNB IvΞvO}]$5;*3L&{^޶*.ᡊ$W=Do^ HQ!|#n0Yl=ewDS !:OltPQЮ3$|DГON[h-zUdƒ*]a*5hD|2 HAl6KZ`}mgw33\if:]jQfӹhAxLJ@?OXכ=$Y@HP@xD*_R4DG__Iwգgs)zgk rDIfqMwDMiZNQPj^So,8:g88mzW@VL6]H+PkXuD">IɃpG9پ}{lgzep4w$aBȾ*1u341^q,fu J,,)BCR_Ť2S]=xW%z" Q"å H^ʬ*(›=J z'2 5EB lj_(v9XuFi*vwE--ڳΎ!LW{wLSV* ԽC-! )OY*Ual* 3y!Q8obb@Fh1$'#' dCO!rRT0̹{3lH&7Zl 0:@ <0>ycx_-ˋMfƳuZ+Z#!SP6ۛ4Y5۽/>ԺڭRQzz#6oJl4TU]l2ޱd2Ѳ#E $dTXZ:팛8Ix*H f4T%OH qGB: aw$֥Oosoq$a:?Cլ?Rߦ1XdomS6-4) o eM0EQ+>YW~ioPķX_ιvXt׎a 1E_-5GfJ|VC͑ߋby7*@QAIFb̤(67HִՑl KI 2_/cPh7׎-ۈjY_z覝QMBNFʭ+;AVh]GccN@Z>C2^p͒p`gD#^S4SFyD#ϴ5-3Ivۦ׉wFcws F`0J2 Ȣ9(RT z77 ?'Qƒcbqd51YokjJ&>o]} ,jYr]czq9p-@-Zuۢ{#W~nG >+IVM7V\ 믂i+Wn ѷ^ڹrRh#"()9TߴzRr#8kll3Z>ȊtwG;$%Qw7V^K*.B_xx&!0HI AS6]HĊDEu>]耳) 1g H>,At 2Gwʻ2RW>(}8(JXnO@8& ޘ/)JM2l!]|*~`xSwne7hhchh QNl]p'&H6OP v:;}$Iƍj*Z18-Ϙ ܙ?Qz"I ZSajOmJӗΝtT"I $aO}(:7Ɇ06?7Z`ty.Si"k5jj魗QپI(} U&ĥv$t&4/G?&-.EDdZ5=' {ߪzpJ4lضhL  }jK2Ncr9}qHwŘ,O 罬!<oK4K&MefIR3R^?uDeEÝDÒp,3>QOf2N6w'v2Xs;ꚛӊj- kS],_Qe}Ϳ4h$b"tlZ~wW=mWd֣<\*KiWGV)jIٽf,[nf{;:Yxwz^q̐ dZ0ƧD _d %CMэ^Ta+t=0V@|w~+U BrB-1[pIKq^xyN|>-CX _oVL,݂\Y0Fk۽sju…-ZMu*0ƭM/:E L-cGhchͦ74S(y0:;ECU ?AP`_llzu?{Ͻ|[?i>b9 3H2yN'ܔis,> €qK4Չ4b]bT A  HyٓS! ꮈ<808#i )Ny Hh i>h6@hp8X'mfN!~W"bBo,e~T="m7^?g'#- 7{:t3SU:bB oxw:>z3C?ˮ)fH HBE.1@_G"IX8߾ν?z}5kvQɥGfKQ?v](qMA@b[W,:o~mgd:ՙj?oc$D0'~DlLfdkP24zHc9 !&'A,=G?G%Dm2)yCiX}-9 N`B+n9`c[s GH(7 Aq/η3A|&p_ 31ZRURZZRZ<^[cm[lrf,6meBֆIlñMO1+ P廎U` <فl"#O$Á/QTG^]1-.dYz| ||6vX 9E%$X*P!GX ''d >) m9.^*FD\Y[B˦v"JO"4H"@@1P0{w,p4x!!4 OV@mQ;H$]_}߭ ƀ\t_iA__\{8cP"fXЦ&O=!ʇ:}Z!rmۥF;۹~/?i b& 32g̰de3a=~_(Ƣ*fxֽ*MryXX-ҀJv'AE~q5ͧG%@B{DD,(~b(-} {=Cnxء ICl[CazyC Mlw[I\ܜ)ŋ7JV>=|# ieK`N %=R 6wNÞUT&'i!2Jf'X Ҵ:}qZJX}jALL/q'r=b\"ӝ&2/*+ UŤ-MefzyAÊ2,B  @;d hӮ+Mu:oZ~D}K~MCvݮ(ӗZ;+[cwf~+#GyzocMgcP tP>8[ZZLR-"@>UvpЕ}8 3!FZ s3yƷm8R^h }b|p=@H pqy!=2?nE)_kQ 'E)S(8,XbI~́ޛfWd(݋+Vv@m{-hU SRo['Ju% VXfժvm|iJKIyy?dD"1~0rG^S{VN?ShF:]7"n^VqI =Zٟ wZ;MX0V_~թ:kY',|s5z[&.%۶Nf.3d)\ǮOZʐ?*@!i}ZB{K,]4ۧn+Izl(ae1PA9,d$V)OY7ǖǹGb H||8>lU?'%IG{u-c]RΝ5MmKΕkv*HU1̳l)NN*Ϫ>ڻs!;Ю?|-)n}.G>X r.` TSαj󎞁Hu*# 0 8#?l߿o*5i߻ UVΜt^g⣏vgpL.ǐO4zKͰkgP$ES8B[SOHt̪f%'ss/i{2,5U+ɪ%o!/4\rvYP P+I8" E '25A)$IDIB^LŤ,%$;+T/ھl]bwv_93ff8 llj]/fC5VvՂYŸ6 :Ͷ=G|0V€e82 #O36(z,%(,;%@q*RٜΌ\Q[[n<joٷf=7w޲ $/J5H>0'fjUsI|4yX=a BuBk^ 2Gϭ}cfA3(\/U"JիNJp?]"bJ,%eEQqT XfBa `1y\ 2{2;%o*" 1ƻ4%mU OtMi͖9%y^}ZX2(8a^sdbL坝TmmUYrI+ Ud(D4z0Ɵ dT3Ν9wn0 9,WUgewkO*bL `11`p|Ly}[Ri[M}DxOvK%f=1e"m ʺsLV,HM紖&y%}(‷ж-Dg^&$ I48ν  Ga.hBjaJP-n#p)Y 4E,BJ}u3lAXX)o#w2UYe<1:Uyh96UB鑼֙s˴qu}}{}tK1ȝF;b@9iC`K)1lmϘJ4acdw#FK6©ECvvBawZzV^ηZmYtt>tC"kOѪNm7_?iA<9B¨wğSo:0EYPcܮNYwS)32]jJEjij:t ypw5oKf`X5|P:ҩ|oFYlb,C0|Lq/=4+ge (®ú HZ"Ue7Js4ZXM *(*(Xu߱6h>u jxPHBo@`t uKSr0E6P @ CIiE1"8 8]\9`gl==iVNX-fs"SrH˲|9$ _)A Xl씌̼wFk=VC33;Co[Dzq9mTBDTb|X||![bCO>[9<}e+lm;Mb%/:|w7-z}J^2nOɠOS>aƈdFIt_^/i &,^o 8KE`I /xqv WLW,?|g-{zbzjsBxg`EžhÄ,uP`H`ziҏ#LԼ[{o߲aݮ|~FvH+HB$gW$b][׷l[Wg3-7dڴYMT UU{eSrd)mJc 6vÊ,? t&x̦}oyo~hfz{8@Q;+r2U ht,aD p/cz[);ҔApQkLj譻z:>t7zxgT7J?yn/ݶmԿs9)sQ ?, ɌigMjC1PT`ꪾV>Db{:,$ɲK~" $7͙ZT^߳{뺖oyE[JE+TT"H$Ug8b#DҴ EN̠ǹ=!G41 v.` Ű)x󷬾{~_*&|맿;yr^/cE)11xZnw^K,CmbF}t" AHٌe3Q? Yt~Ic&DE/M Ή:Ѻm4%`K(XQ0,]5{XEPi0i onNcM@2a4|,kJ“A,b9Պo]T= ƬŠTsu@ԚJDp&!(Ksy)?j޻?~ijIDM#"^c/)'w6(1"cbp?! j~iows0?^TO?{pn RS,ށM]C4v{dl6T$#7v/223cc !Z!^Yc[$IDBxPp,nimCAZuteotR<W)&X#t \=G;;zB"M-;HSH*' Scc`Pcߧ/d'zf̙>J7٥1D|qKh!ô1֧pZA^wz3[:Ă {OQE~KfK ucE?"XC$ŰѨ]醖KQh$eAT$1{Z>J4αemZ-+ I _$&@w_9S3&'TUB}ɨ i@.MEEI4}*d2<U<}xׁ~]{umnBSloW[/trEz)|CLֽ=190E'xѬejIV @$Wg߿lA}gOUKe6F`a28<^/.ذ8)#a!dTD99{#)&a33Ǻ(q;Y$==X`4^$+iDGU^F]j\Zwa/=By?UN RG,iPk9\NѨo[4$33Ƿ?%T۫R7kTܷlA p c8?#CPRV0y1f:k0<+ BEe+a֟$4~{_n]9i苪8M;GHfh4zU;@XRWpMjv\Z:AE񈷗vaY~5?P+w9:qtuc?I$[R&|G+97qm (kW-6ѷjZaMdO=qnNgi1.w+$o%~YEAK'"+/,:% MʐCaP8$@']i,nШL:iѪhR?~ 6秺+@$|̙(:֜9tDRwZ焙=@y%dhXx_`vO}rBv5XU2qޕ,JO_YF@daŴ#< v@)2:!u>(24U["3=%tSɷ SRABZ]9+fh0?Bjmn4 [n8psD $!-Jі> h8e1DYg֪iZM5gTO$+XJ͜,M+ Ej$asGOs92,[Z3aV`X!O T0Y N%`?|:@(BTxXq%sRj|3hh끏: q"1:?;V9%`a_r:'7%# /.( ](^!uZof@$ګ@ @Q@ EPdť@rFҾCAX)Si!@,T I7Φ!B:"TdFĨB"|Ϸ5;[8N"H+ܰI>-]R0tL{~G+s=]j [JMJmH2)۟Mo,0Οw^"a/-àgWT{%aٕ}/MGn98)%<+9^B`,( q^ұS!ċ@")(v6 >&'Q6Y-u%V$И62OB@:+H2C@';/*#a$֜$IAZXRW؜{? }wpÏ_<̎GRn^NnZ9uNEVp#"\n u lC꟭Η ]qh̲YF$<(^e$(`@W[P\_}?d_~ };6fw͝SS9xx{y!gZ:t…mM-w~w+3Wݷ\EGfԭiw555s='W&P# F) Ì%M,e BbK !K$Dd&=)H-hLqOrGN.*  Ef;\;ubQH  .O5ُP(J*n9mosP8rZEV曅h`mU_W=ģ=L_tGk}/FދZI _]u?+?].w󝉞a?Z6PšI6Q)c8M >!Jf0Gb4JIl jM%UOQ2KQ+"t CQþ!Y2 σ8dDIEѪUdg>zuyX7sq1B(cJY2^g{{'!mWzUE i'rdEk}"={68;;*7GwdvdrD%5%i$$ũIQZFiBf 5GUdRY^t*Չ3Bhc "a-vjt`iT ̓BJ9֪75{7:kƫv? HxI:D!@DVJG7N0 Dzq!Ikb՚,ԌԜZjNe<|TޥtC! Ö t$o˖,:E57>N;5,q{oIKJZorL}_?~s9 xz*##CRMTqCu\.帉0h k,Rn%O;ԣpniIO %\ 6ҾdgD( #Jq <J"a?Ph BTQ^<)^2];غ'LҞA 5ŌtC~2n\;ם<{" dÕr]y쇾P:FTȮDR@wJYR錠OXВQ фL'rm͜9W_5D_ IW~ybpH?& Goud%!aA͹@3 ,י"a /P>Ux|EPIDBC4|<0FziDa5VEgB&XPPj5 àZHDB<0ty`2{t#}d2-=/M4sjz#.#M7Ɉ@E_,Exm۶a9sL3uɍm;6^| 1Y1DREm 鈌1GbXgA QS^Q$"Ib( H+c9oN8c0< DŽjBNpfΙ=(r,7@P1APєktvV]^ᒒ  ,J`(.ߖ-$tZDHs28bYDOE$I;CI͊7nVWEq tIIL|HE"$n_cK Tiԩp00|0Hq,0tܑO+Zf:Qrǖ]}{@n4sԴ^ HH,/gԩYW}|ٍjk|vn?72v1XY{Yt5)+}C& d2ޮj?2wٹ[8qB 2RRT H84$bR&b%y3REDU $`{8Hx;LbMV?}-G;1wΣXGLC}y}ǭ:̖U5o=xX6ޱU;yå Qn?@ьl_ugMno~V|ω`4jJZIS.qe<^gEL(KcrF}RqA`%ylcdDAxIdd_$% K&W ~.AAб*P46^?/-+AX}g9X\^Pij(z#-lOY81g=Qo/2GH7u1҆Xl N'A*ԉ )J1I5YRdEn249 HD*BH l$eY%)Dy!*QAJD2)+ A@ $PDE48$u:dE).+RHy3)ح`|)éAYye2FI !//.eeQ_( FSvzZBǟkQi`u&Z+@JN) Us7޽;33o̙=HWIO,J"(IJ /6P@KDP1P&:.k=x0H@`RN!89D0um[:80Rl s\HRò QRXeLՕBx4 .h)g7&u+NIZ6|f˪;~_; ҳ)7}녗Y8tF Ҋ(i3I I@!$˒Y|gx)SDpy},pʶpcZ[Z1Da1\x _ATX#$iI"U X2[傒QVsR b"^ПLξn߶ RSC47}mݶf͚D☗ [nO>o޼'x<çw?n7xC1 C2͜'6cA $CӁďq Pi,p* 23!  1rgE Ng[lF[j4&4K$FtP '~$PD]֤_۹!+ŗ֛Aٶ&|NjWLWCNvحEeÐgM'tPje)L#=WyNeȩoGy駟>x3w[|?iF566n۶g]z5IG}~H#G{;wZⱁ1}ꩧ^yOK&[lٱcǦM|UV|~nڴIn"H 1NT36YH +'έe=% "1&m%$!Kۀ@@I!oox>V@? <I4 ']_)$Q"B }"(",}D~dX "?}/~񋧟~z޼y:^F_җ'~-[3'7͛o)c%I8QYahhh߾}&i``\Z9{'rQHBAyM3@t~{w/%kW IpF_5%;ZeKpr@!w\t欌eԌ@U9,ʞMTVJ!!X3!5 1 )Axgv i`/;,60  @o l~PS8R⮭E^?wp_A]z}d!Z͟SWo}7oҗ贁ۂ |󟯨ayߵkW^^}ݗ=͛wuV~31L~ /pNpTUU \.EQnݪVKJJ6lpy[mÜZ@|+cxwqtOpL@AR.!˼]|_GWrv͟?ifۺ]X`)274R\c#͌gMqmX݆Lf2-ŝn?@M Sp3Lu#?9Uz%z Ա̐@ɶD>ŲgϞכL_ 2BĪaй6FQTaal^xpee%q-#\"d"XĆM`tח^pe^ !lSiXu6B4u }kל:!2=kG L V% ,nDBfBo|7/epcphΔo EΪnx]Z2Rz{jZ)eNl Þ,q 2K!EQ*ŋ9[dIT*J%24M@<W4葛}zh˖-f޼y}}}"&"-4Tel-_) bYq%wLe,5FjSOB Fjzn 9p,HLT^)$<]̜bj>Abu+^pӾ#Cvi,*WJrHs:%viRa hA!EJIIxweIDH0gΜ>|x޼yhZZM L>b@UUU26mzkGGM7ݤ]%#;&b+^5fUS[qN漩%om1[v9mm__Μj^o-ݜ"s3T]0(dq%$[׿~[qo};Sӱ,dɒkxGA/~H$NXۇ<OFFXgyFŋ_}"E@ocB,].ئg.l1+i< 5Vpo8ovf~x8^ƫy: 6i@cťDIx\1ͲICBQ]רg-=ޡD$K_XOzaܩeɜ%3hxӭ`8g_zb54X#s\i.EDD.@yy?wy a֬Y=^'bɒ%ӧO߽{ 0f[nYX_|櫯zwtEEE)))jq)DTJSG&[CXӢ ӷ>`C ̾7X'ש@-C"x@"#_}~j^eCOܣZO3+L9ȃFKN‰PL1 qL_Bx1˜v nP}hcgS*Fr} ?{[B!ybY?3ڣ>gϞh4jժhNN~[z<In<':qd3wygvv^/,,c#!NJÜ"ǺK8R jC{yPQ_j*&/|ͭzWTc纭Ͻc>}*B}HoWh%AyDꢝ)G$q3N`eD;IjGrX9EL? ͅ%`282gA@y{;| .$$ĈW$ܹs=D$H{nU޿0qyxT#Dt$cp\i :-&0T;?#2cf-AA鬏tWkR0j#NcZd I\du4AQ8IDAT4*meB 4G lV}sַԠxc̥0`Pt&-"P#($G8AH "ubc.4I4֤8rwmqLR ./`ǀwHd榥4w)[ (%*=w)VM˻<(W[֦pLB9u!JK1S#z3ia/c%4Mz?@섶i)xïz, ~4C ď6~7$I>O7 Qc{A7l s Dkt8e0IF_SN8Ԕ_o}w\Wyw^wf{U]ދ b~JH @{/mVJ{}cխ.Vѳh9~y0hUCx[VѰkto0Ӝ/"! b.yt*m1Ϲ/;أ&Ėq'.Cӑ~bfC=ӨNIƥjLy3{BntiXAL0d Pnp7dѥpQ@?S!Q@$8 QԫtD?b`go'~@@ih3B}cS֦ 0>i% ¸B&UȤz>UbǓ't@b(m0 *AfBQ bihT\>+g(COm{n)5zg1oG.EQ@OzJ En:싥'6C 2@/i&a h#M>>L$ F< <%A hI! {C D^Y)5\}eF$$e 0=Np1W*u}kwX85ZHfRH (oH.oW hΨRu#uKdb.("":wrh ⳾7e-BgqHD~'Q7c+0 Hi"S\WK'+n#M'h:m;r~!Bm^qσ IR ǝ3) UZϾ$vgX _{`3{)"RϰRځIHɟϮEPOx 'bW˯;~|ucaWΝRQF$/_MX(Զ ʏ"gx Q!Л ޞE_LItPvnԃc ,G 2j4gM9kJmnkPAHhE*)xE&cPǨ M1%*HHhs-:? T<˜Uz^N=!]b@R4 3mkMн?CޞթoʗS[Ql47ɲ:.e)C3(8p"p"j&z|8ҲFA8٠h; #TK"7٦x%^={\2)&T r $y}TWV 'x$􎵎)wF4m 9c9qjpP" t-I 1cAEA= IY@P@8tR,q /B\)8q|r3Y+$ANLg%vq/57Yqz&"`i ^ F1Ð IؓB=q{ WR,_\eg("KLF]ݒ (ϳtϑ,G%ZX&x@q˴H UBAx.*<ȟN$ q4ͬ\Lʈ"-Bw&d}YBkܬٶa"Zݏެ_{̤ NUJyvjG!p(B<%s $2H`r.e2!d n~CȋpQq#n"WgZPTgYtf-O{]/ãIDVFl6t4ZE@@#Qz[aX2Igc#Ǣe`xxP$QSI5RGW{ uoz3- #|eHȈb(Ba = O|A Clo@fӵ9y>_U(mfMD_oKzge茥RN)Q6BN[!e (̔ Nr| ǵcX.yQ@B"9eի- xd< y=^ &eK+ J%~GP劜ܼs+X,  ;s4Z EŠyKڟޱIcHI9&\TAXBjLVoZƑ 6GZA-r '^|F茷'qw? kSV/n4_]l/wG@R[S--(֊P70&"NBR#goMbAXTN u6'M$p Q*1vj04LBm˯*)x="˂LqIFjPVqJD"r'T\~uԳ-lg b38E4] 4\:?l6K ˲~9{yY:lnH"`P(22T5zSAqU H$2nvO͗`EdaEd\27?- 5+MVu5µF3͆m>y( SП^xlx4zrV~)c4~+ nVJ%(0cW*T2R*+ٸFvN>MӐ2 9SBQS"C1QsH7Y/kVG-bqHTnZ^a^ Vj(p(|3.`_o4f"!im#zMECF6UJ]fVJV%mλ==u탟5cmY&ZlCNV'Sq]Gz^y2="C\ DNpmU٠koVd DG5rY089*ބ4)](i 1B)拢Aɋr5v1 Eur Qq%c efށa(z: AZVA( PcBrk"!% vDXԞ_ Ūj`SeC/fʽR襳MDL]-V,[ >*YD<*ñh"vl;e1Zbt~G w^  ~|a1[z@T"KMv#JH 9c̕V֨$֑Cܿ@vηi]$۬y_pKIKu$a&Z^z& y:_ZJ}Jկn-[!߆)Tܜ,QZPM%`L`Ъ 5T$a*zOLٕU#I-ֺ ntl褙spQ6 $QeqS]} JaO5ɍ&B[,j泍pH*YVXxI/ʤԴʺܛs7yjfkG}$ 'Lu!x0sy?:ƓF|tRuS$|nwão=gGBU(}w7/] ^5. +GZw-5IH}BVrM@:uN a?NJJ"LVBjyy"#v$`@#rQRZs2--#Xy+< L8  Qx7VB5 Uミ"QwFGfr*]4E}&wlgw\'Rƚse9)( Y)ҶIŰ $R($.7 B sBn$}P09c!Y )bUwҔ^:N&,{ Rkdk47vcHHQS fZO"d\l՜6Ro9x]=nn=.H( )P:ұuL5>,E8Gӻ! *RsX K?3vw&rX?nbD7}W ![a8z ah5^ ,rpe>]NkkO\'7rMw旔*;qm'O4@v89 gk`q"Vo$$N.ei04K$0 ~~В\ Q, qzr\6O} 2-a`+ԇ[+S6)d;rV(4E4ŲIfrPIpiNqy͜OHY,I(1u>To?)R>hH$2R ZK+Kl]_Nb']w˿lq~خ]qJeS/cwBlbŮ;f LCN:"8J6ff'_JAT^o!(a(&( |Gwl{-yt>0@Mqm;^-ˉoCz#`|5"E3D@ED@xPpHaHɀf8ubAn ZT/*P \:#xc?7X_=<麛}T"< 7AڊNI5Gb#k,Mej K"ܼ. EFƵ\Lz i2tG=ԙ)jlkY ccr,s}L2&ٍܢJFILzI0>40|^[%:s.iO{491(gjNY &}Ԏ/j>X yx!ΧieHxzr~^=ٟgs3=Rb=n뱩]ɢz]^jx|޸k$U|MƂ ~OoGL6Sl9U k\o1 EQî/d2j e1%fOf\S G=>_uuٜ ]Nn.Öu[b(C `^\.R,I xvsy\=8`p3&ʈ?aB(Q;t +nvks܇{@T=_b{akymNayՆ>OHFF 7f]iU5o"JSay!qSqBMޡ16$}n[2FRL%Y&^VNp6+ DxuV$VQ@ lr{Dݰ=; Ma{XƴOqm& s˪lE4,kZ7O=:0CQIjѢzR)J?<.QNA_އJU[ñ_YXq $!G(!he%@3>Iޤ́&5fDm`S"]8_= JfϽ?/'{j#];)3?M(]<bS-x')Лt _s9Q=o29syQŲ(JQQ{rApO7^IgS :qYq麚/KEa( EOb)Ɯ Ǜۛ~[D^I~`xUeqN4Cѧ;%R8Ҫ?˿Hē`Oϩ#pH+&I n2ش93[J&F{=TFH|j4^Oim+#%ʉJ=W-t,yqg.ȟ/*FOH@ U]Iɝg9btnЌKslHޕ!Y1-(y1\L$E`\W58ѨrzU&Ϛ%EQv8vL /)R$C G6g.4Eq|bk!kb|n)A +mh4O9 B}m ]==?%q\_^b5v <g2jyyh*+o? 0 s'gYK7U}Sʍ r|?E:ul4QHJm75z{! w##gg"?JWy:?WkykǕ%' u{Т Cǡvֹ&/y6EYE0D~4vj<1JE oRtN{]h-fmu&##lP$˲}`nђۡa$t8}|,BBC#a),((M挜\Ju瘚hڿ]]WQឌ2}fHd83%dhMM!:>U!E~KϱR֚ ;{S+(0Nԑ\EjIۥH-FDWdrP_oL3mve%Zd2̷Uɪxd;Bhܺ=+EA MfQPa17okj2+-ZrHEdrb_VY[\ZJJ$RQ;g!b8ۓM ,灪 z䟞0*gj.Xi}s{ǚ,Φ$q]+_tNJ{ 7,%hܑ 2rZPYX*Ix؄D֛uQUT ωj$!]wyiY!WKL|h %+@>}M6%!CS'?;o57>y[Euw?'dKXwZslKV"7ްCҢ,1䰽zaOKjk}%OO't~5vLGFk"MrB[eĔw8&%=42 $@ax?sDDVbS :=hHb$ FS>Y$l_/NiZqS/ %?D>`5 Lz) eS6KiDMI; 0Aibr-ѱh"IՅ%esEvh.J1)rŕj 9#ȳE#?+?Q1kũF"io |r\q˪u\n(^LWñSMB2a-.aS~1S.GCOљ:I7Wzz]Zە IpBSH*%L7u?H8[,3/%t,))u+̩m'鉮dȫL/W[JKcgDJՆ˸1xQ|}q$̐WDg`wq>Q]HLHPL[V=-SHHq\Cc͍A{aI⥹%a,˶;tby욘mow嫙J sԴUTJecGwEBoӉ@o*[M^umߙߐ;̹!JO;a @KӶ - RĀBǿݻGuTUQpk1V8[zubV)W[J8*1޸?ԨY9``r~LKN  I`1E5iu*% o(3ɫS.:_8 '2l9՟TH89>7pX@X{^l> 뵤lU˥z?>[,`;T͎ĸNu~_g<V Ш8*fIaC5d؎ xQ #d~Ͽ~"bEeܦ_?մQtM'5#DT]D!3T댮5> C 4 s app`n0\v\֝ZIp dځ|hʯչ墄^Tͪe 6 @D sfՖiVI5Euu r>X lx*42O0Φ6r,pLϴ vMU =j”|1(cəpb&e^yMiE'T a8>Do3gŪtF8027cn4k6} ,U̙SeKc_}6Kec_0YSB#or-UM4yu7.@N|;BOQln o 4Ee;~+qx{:svYJ$7Wwd?EGg8UsԶ7y(+y E!=V r%(A ۞d?@{ t\{NT^3'l&JG4~1I?vR`^&8xL@2qZ#fU_146juCeƻ3r@f2cZ=/@FQ*G2ْ' D"i0R6X*vDb(qPd r5UsrgLBeۚ>*]!o~dM/nkPc,[L a_c{| c_nvs}~K{L.w]Gh6Y\XRyL(]^OM||D$d&2kt+.*, +}OhВ棙=)bY8.>-6 9n>*"B #GQ*BQb~L$d!y~}■[ ˂{ n, \ i9")%#ωXݸjSp>h] B8 lP.p[ q A$"_@:(A!(|Ld |SuQ!nތ vE!sɂ=kE1L?ubж2s5g"TJ%Gy +VhY]v(&)j5I?pwLPI),GL k͓JG,Ivj`m)vy)IH?uM+Bܜ/X +w|lܵ :˜/(F?s*jaݼyOk-I?"r'܉!Enh wie>w[Z~Z.r˘2Q^D0?~uKK+^d{[EKz'IH],plPoK czkGOJI5 yJIt1OIL վ԰5!,LrG3!EHbL)L:$ARYRJr~Mɍ ( C1 Mwi r_nߑfb`ӎ 8O،}ڥ=r_85-tђBd<;wHKߑk#/Q'Ys.1лߺQ˪Lj\B~Uj/XhxU|. A f0 J.Rp࿶=@C/DTYerm~4egS_C5J -o{3*ʴ:[ mY~O>P& M*p%؏D`p{|}Dψ Q | Ɗ{)w*}iq.\-T1!q05yE,.gD^Zv\xjxQ;Oo?4eQLHF̌$'T }e}{hEG; EK9724];{ :?j{Ֆ5'7[SRt92zCm2=m+H :w;/-p3թ+Ru7W}IH14O&57(LOo2YqEGe`rbC:0fbY76662jxقrj(RHTRiR3K JR$%ȱxRHIW0[&gqIZiHZLZܔ/(3iuNNr.OV)_^`,LJzl9QQKA M (wγs|>+'wvh,PҤ򲞭/@ũ3NL|aXÖ1}.n_F)TɾWt -fYTjptꗬQMmiʻ8q$,wc nr猶&;ɾ#mޙu7KOR^, hllY!UmHn{͜TF.VntNZ~34=:w1.UsW0hK8I"7yK~Y  yEF*`Y5LIMF~ F"ƪW6`Ñ-/XP(XGGj9e"G(72*ժ+8ps쭗P$,+Tݩ IkUWd OKV ܟ}XuZ+ňb(!%cƪ 8R9JnU2Ao7:JҤH5}\,qXA.*3QLwi*do^ƃ.wG i&XRMFeR.Om '=GC,Ɉ28 dlk/JIw%k '籕xqMpօφV  9{AUZ筜S7q p˃yBS{?>c{Enbߨ Rr.]Eǽ-.2wrLc{v (E%I"?F͙+Wtٶ"oMXܕktEwxthRNN3W~o׏ɫ>'3>||WMTv`컙>w4p i$" ~jA$8l`EL ir !:,prB n!&2oWWGN 8kjMz((u))/JP `GI0 mj}'p^K0Rز=쳹+A#8Rc3ોV`ر&]L@I*ˀNIJ;/v?lҖZtbRb@H@` *ZIA!A|!bO ?}aKFqii/X{j;_dfrb<-=S3{fDQ m'8*JkWnE191xbxie([ndAz۷)&u5ًWx^JcqGv^^mڿ}DVՒ{E128pjD4` 7-YX)Tۅ7\mb~̜(bӋ?[*S7wƃ1RJڋ>d_vN 6i|cèN]du!HAqhjظo.݊ekl \ $TJ mTGÀ'  tVPc >^0N//:wP莌!V$IwgCBAFڳr.]w~q}=c'v!Z#-۰rl,0=->NbnwV۾=p|,;||c 6EᚚMY-1̮~كpUj΅.Iɳ-zdYm@\e@u!%;ao80卍:?#hr_VWvi0XJ2LdGW.c;6bN򼬖^n6:'Ƿh^w߮FLZ]Un5(aa}NJ_p -MSk|#o< +ΆegP>:k@^a L| T-Kne`<k9|pj{ifʥ>8сu8bta{ɉ zOI-bӽ ¡P.)R|Z1|?[~jC$ 8̴SDstI|xo|J-0C BY񚲣/䇕kk4)zf>w5&R@ 0 EP$ Ot1 EѲ#B F< $);w !IagƶjHR w }oW  k!/Or<]$l]]?EҊT=v(53p>mIr:m=ң,ԏ+:G ,,[&-;AQBZDʍsVQբ(vzi0ŒUU5wiZDWӑ%_Ym?zrMx7klg'+s mIe^,#+ 5;98C"!Ô1-(h|r*{wS*癲/o4SEA/P4(, 'f y,*kt\z2S,w׺Q̓o~p,CEѨDbK}YQVAҋi:lfuY-QJaoW 6=~oO<Ϸ4sut|=VQO5̔G& EulV C6?DZ8#nZhs/lo'`e |"*E*-DQMpT7DOV<]jz%Gt@n,44*g[iO`?8[WsOuM:4fL%/PoSޔR}H.m{4 #(&P_=5l_DWG+*n|b(]UxO{/-)" i}iRFneZ߮~VAk_nz-]u(KJ xIZJAI@0 ]PQ^ߴeG.L~F{H,n~_߲t IeY`(,U.!\olͯ+O?sʼnP$:vOUFe$T0}IJjۡ˵z3}LS+k/PoOoY8N&,ִgU|%Şvё`om Wp\.EޏwfO~1Ai{Ƞb]\m 1٪ɖJ%4})2%c/|z]2҂>KAf~]#8p+XQ G!F J()9H9]OfBB] 4/ 4JƤj5#jD| UR Hd2IHJ\ D@O:g±x?>4LtAL]T愮8$iULUSd ,2ۢ?N 9ś-(Ǎt5UYWXRzãio/[ `Yeϛ&i=_8Yiعh,)]|6Ȼ̂,g<;=19nB%%JE^0SZcv4jQ!$A*h-%"LP/L/ծw'F4 t F?`oipGDN(&y9!4+0ʀ IQ$A H`EObw}:JCq[}&0o#)id ݠ!jxA@g Ȕ\ *-U߻bP1?h-@JAhw؝ \>Z.m]@2 ~x( bA/ak'v)V+*d=;F$S%&yk,3=xug )!a8mon8-te<ҲmLVslߞx}jFk 8!t 4Mh;53l+󯤈0 .΍9w,ߑTM$4\9!|VjQz%1[avogQ3$h$6^#)rjb@ ! x)RdqݟT T3L@'${dtsTH! fI@JŀbDi= >'p@oX"vĒE:ɝsgrRXk׸d??($}Ar, j*e7l[LBAFGۛ{Lܪs~ :}vA`X%(Fx=Bbcfn>${"w?u(IEdtK+O=s 4Ayx̊qDQ|2LE%Ę( CI-^`GV4%i!ĵμfK6CJP&  3p,LTRr蔜=ff~j>8z#$zn1 <Ud+P X Qީ^6=#ZyHd{vhw{7SU[I3PޮJ BْEsty37[RU3e#ѱcveݒu\3Σm]QIBhY|J_ñ%H OԄ f)%'xN) H /K>{R;&Zij,[HpR(JЈ+B$jCVRCϞ}gT$Nԕ;O9| U@< :_ {Num$/Vck[A3b"J3|L֬Ϲ 6Wl~v:BčKU揶vw2Dq ˟ɖ5w[j}ҍ5DQtNM{5P\]O}^O߁oƸpUyml9o~Z9p74so2-xlG?<*K'Хתkq$<7J/;P\~oUϨrg( $9}OJ*դ"+pCQ6,/GYXIi,p:&DOoo_^! CQ@f?e|8|0dڬH Oټ(z(;Mf>]\DT^կsNTKS]C5f;'ը={@)%fc}o8>4x:oah4ټ~^Qqv>e#l]0 /_Yd֔㸁YyeJ DQ9ҸW`(6H+d_xh=ר80htH9DNSlW=_%p|V%ǣ܌IpEWi-RkʬgLqʋc8Y{-FQ Mp i0ҬSK@CSnǘV՛,*JRYtL+&`2XM|>П"g(p,K)ALHACqH^(L ģaXHdr`hj,1c,)d6USH$B&&d &Ʉb(Dk 2Ģh$I?2$ycA'x:m yTA*~h,}zw5f_\^9zf4˒=:CP<2QJ$G?VtgAsa ~woT<\1;չ 0 O=%BpNb4ýGXeʽPۀ nsb3u*\t^zZkF?)r2WV\S[9˺ވtfARBJTey?9A졈kTCV)8/SɘDBIuJl/ⱨH(f>/E(DsނE5g?1T}S_X *)կ՗Y:YFfS*m(CLHpcKrAFjثQgZuE!{1s#(f0bnp:Űt_;.p/^+%.)-$8 .pZ1 _}w*d=i>W/2 J*Yg7=S>$r24}d65:#p\ZTpoh*L*a5vw cez R [S377lN E sT!_Cg R_W)v궝_&"`(:'۾.Cӿ`KV𿙄<tю$+Y"s./hO狩)hErX"q ^GyzTA:'&" "rz(p)I oeAYм0ߴi4{j Ŧ4 댿3Rws\2At1tX2[w &7D's?ocy}xX`PT1NFw_ZVfWܿj%cUwI: Gwx!-wWZvkW_9ZuYuQd:[CEV:GZlRAQNFNGIF7K y~jtȤ*ԧxDya<# r4CQ{w8rӘ2M24M+3Ѥ!3'Q~:NkҲgm2bZxaitgA4[Uʳ!t_wvmɲyڿ/H\okIhmo=_'q¡X[S!6[=]eCܴ(3f_{vcxR V84R@H<"K%(QT G@Ĉs$iZ.\bT,Gwr/?({PVfZ& pR&QaS|)&|Ʋəf*bJtj|U \kPJNzp5&:xhT*Z|#^)K՝AcSjH?)5):_ws&˜lN{w>xJH)''ۚ].gµ'E8 2 񻦢𧓊𿖄(̖ԴFռs%VC*OS9FN=K#j= 3<(Ւ3XAybEIQ!mAAQL80$Lөfpq듹ICjEmLh$mU^6/w%Lx[,)8* # Euc_RsK4ź<Ĝ5 L%\̛H)&w)ԤfϪ(:E^~RAZj}gF/~he9)'t]+Jv/ݝȢ%Uu/W@AFލ)&nޢy3_KkD[s I5%㒥)> HԺ\5%B:kr/Z:92 |qY)Kc#F E`?:EQH Ry1T dbWZ= ҂}'IɌX_U= *Ep*=s49I&EU2LR 4鋦vc餧<w~k︯2n" HU2,K1,y:9l2,,TWLQL7t/>7+,]kh:."g׻yRe^x_PjWtHFGwsnѦLgX^T k;N> ĢCktX%Ds QTZ>^hT՘ּj5Fxߧ&@2YE,G=ӓI/d, 0ʹtk~*+&V sF&bc*v(/(2w)# 양wJW+$/{0o~]ҒT"ä 6K߱Us{L^N dw%PT`V/}~AjҍC򰰸fݖc$s{k O@wEX @Q4~󽧂ܘ\jo4AjճϝBkZ垼O-. A8oOX|fd Wx˜LhehQLgq,ɥl97~K+E,=21K1HIONqaFxin<;lӘ'~5k>]_B38VK@kVV@bĢK0^W1<-!E h^_Ao~;NF(ȴHofvα téc*掆2406X4_%! BˉcRf1Q=]M}=g[IE<؈"c)H|SIV],{Y}ZFu[:İ'$S̓f|EA(Y|͜הv"vgg&)D\e'YR[Zy#AR!7Ԧg14-cdPޠbB57t}x$$A!H 1-閤ؕ W DUܥ9* b9h5]m4rBB,4l8 ɳrOW|^vGhXmf ~D-L7?.- ŝ'w}p͜N33CE8Zf͟;G%!MC-\4*#D̨4.ζf6>@.E0rmj湂" Lǀ".=MSK<&RyEG/x_qeUj| EQEjār"0R;}j1Ʉ,\G0u鄷ŨΌ$=:GQ]O=VVVQaZG'G[ 036dʋygD$J WHH(ʰLH^i (HN20rVrNRކC3Ӯd톈!ubZpkX4:jPobYATF&9@O4Qp<cQqC&eKHp„(/;gbQNI+&}TYeTm9ScffƮEDEA.LcXQRR_aQ.ؑUa яT+B49N 7|Cn傑8)yjE Z#I#* 6O_/)ښDEq}ZÃHAm#-gcJeU~Z:u^:tdjl Zn}~Y0-Xz}~ $ B4(Hߤ+u#,d=-âj-FH (&JgդL!^TQ <\\jғHpYj2#5"#,$rMF*sꕩȘFfԨ{W޹FͧZfbARosI5e'x]0Ū)X%Ҹ䚚ZxuDJٜP$" M (V"cGs-iqH@T*]nӱ@0xI>+ܴzC,1쾸0 VF/MN_r_%ĉXRSK߹H©VKFTK$O71;}'^kJz<L%(D"'%jq\rVOxAK) $D,#*+"S50h Z:ӱ0di e"h91/8*-BRRRvP-IWz IDATٵҢ9HǯxO/ _z$fʤeDw&)HRO$@$XS2l)C:~ɉqRngv4-^vOȈƚ&?4MOK&/0jpW)K+US^ YYk/ Dn",K Dk7J \D?ǯaAm[. ϴȾ4qΑCB-%Ii`Iʬʬ 7xjzɪ5j (Itw7jΎFQ T4;`*2dʐaԄ'&{;Wۿi:wPԞ;X[QޙFGq] ֮ꥪ7uU־Z& 6 }fd,9'sN>'g`@ffHhku}!6vDwW>u߫zwo{ɢ3,u̓ǽXJ+kK܉c{ț{v|q:] _\n(n;:~6] o9?l)cu%˓򽯾5XUJ89>N`IJ[1h*08žJww$%ZrNOedUM$mōr}8˲<ex<z*@L^PP%%lR, R$ t.: |A3SIyT|%3* e` }ڪP:(AER%?YݚSy @%nj )*!xBPVQEXkFP"s~?]ry0 ojwPHs0T^UW%>PV4}CJ#"tbm]*w_MbZ8 ٫*H$?Zq{u}mQk0e@0rI] +|X0 7w,aX0p *-sPH)-U`_/M*Yd8 R$2p(LlMG "/Wl.%.鵯Y?2ɈׁcuvVFCM5R,v4uq8.NmWmEy~O}KMmk I~rU ʈ[Y:?*TDԑQnK=oBHM[/+7!<{ʎ1lOXFu i<A]8e#0Lh  e9ʤB1L}>̎$5YT=#u ^%`c t8QaowT4<ϧ;` FB8{ q@ ')Zoŵ$)SML}ƮO=F{bU8fR Z??t7VaJ]B@";F st͍kJ8: u?8i0Á7z!dtFQpEU_uϸ:6tJ҇W{X,۷>i0&/0&o?lAC"\_ 5:۶lڴsK}GWUsJI1.B .pH42x%C|P6<$C4| e\<33 tdL7^ò X>աE2+ИiLpSZ3;7wt|GNgl,Q:@d6uVV`i lׇGg^ٟ zwzLT*3RG|aުٰpn 0At atq B|Nz5 Ą;czު)Mqx aD|LH<{ׯ8@{l8،{!(Ϗ>WEol[2O~>vs ]U/?S~ .-Y+cjjjb`+Dꪆ=/ P(9:!+⳯3^JE?g({מ88a$#aR^BƓ)",}"@z>:Ԙ1䋴RpuyTR]- 4nO噶N&t!ɰmpͦf>`sKK*Y#ci_k?ٻD< [w<1kD..cs'ErٲXɧ4,A#"ђJ&sDB|1:٪Se( P\."FJM2U"h8 HWL{fLƉpt]WAL"uXL(.8|a_wzj.d?d+!6Z޻mϽT07Q3< H{ 2>,QGAR*U$bcTЯ"E>kH!TRez$˲fIa*}cꙓ|:ui^nfhiEƦ殍Űl2+;: A:f]٩a+lR٩<Թ[σ\;˄Vyd,0 8&rE@ăBLA/xx*$fF@:UMP,/9s8`0wP1Zǯ_{fJƶ bgG]C`VJxUA(K E6 j'qc/0R qTCyZłA\ vTz%f\(V"T7>2X+B/ϱB]˚|2k:ry&:= ͍-ں'v-k+X-:n453^MJ1B7F/QL;)P 1JnSE5xqNuؑd"6l.Q®)>)g+2{k|VQ ȊŪSB#'Y rOeEz\E!"|2Ddd,"V 3^KH.Ue5*? UD?h6!Pm"ްuo?Joz}M㸠ﶖ]dY;?^\Y7  {UJV5z\ %^ Ao(Ro4qtuWEҥ,SEttvmwkk1 WXmgNon-/iozȬ1L 3qβU㑠;UA+hv k|II` pTՌ"ǎ|JcbG,h2J)CLO+j핕@y׵^ .%LĢ3߈w|f. bŐt{2XՆp6I&%|AbN88k`)| ~YEQk柽 X]с wF%jL~x-PBpZc?^Df>O(0Ϸs I{dh.vJ5lZߢT4=,9Vb{7My[6lZtYn3 ].5Z8}4 Lzx5-fȵR% mb/:.aD9yNT*c(S,~HD;[qJCd;e*J KŢ ĝSw~s_ FA<ˈբDbZJ2?j38Àb2Qt}ތsVawApA9]|300}kׯ7 vXSH,$B ,EK$Z8ё(@(ܵgvB Skr<P<A!)~f ŋZ"a+m/:ǓO~\e#%M[VIbU(!Mn nGS8勬Zo4=gxmK/GRh2կlljڸy#o %Ml9ussZ<\Ь8XD`l.q%?/v+VB gŻv?H$^Ec "BX$C@4z|XEJ8X,8A?&JdʘϪSB@|pYlvK%G,@~GQ(8BX+#gS$%tEXtdate:create2015-04-16T21:06:40+02:00 T%tEXtdate:modify2015-04-16T21:06:40+02:00bWIENDB`zevv-duc-b8f9659/img/ui.png000066400000000000000000000075621426703022500155450ustar00rootroot00000000000000PNG  IHDRJLƼ*gAMA a cHRMz&u0`:pQ<PLTE;r?!7O(1Rmߥ])m^|iJ=zV~7s{$ CiۘsJ_ %}[7Pġq+q JY^J6&w(MQ>tDJ{}J}9sJqEKpNIo#.$(єR4ݧnJ 8wY86ٟ9rbtVc?)hCi44?_ )D)EE5)EM`]e5ϺH, Rn{JV0 ʉԿr")iARUN&C>Y?b9J8& 1%& )1?k6R|DZQߗVOrU Cm'J)̘ی6Vh}ę+8. L| RM@\RډQpE R% N1ubk @+'^ѕ9'>$VDuJo]SZ2ȗl -+=PRܗ$$IN@d潵Nd(2})ɦėU jGHBЄR߾d!$9t9&vlRRǥܱ^4”e]j{9'8.P:tt^=VP)(M$)%i"NJ+r59EZNL0M3sDnj>)5PPB8$5x#ҺZ_JEfJ|OZgr̔OiFN6.c儍hV+2'1Y!(Mn)9MIfJ}NjOhV8-{8J]ʔ:xH9{J %ܛ"t"KI攠L ~ZgJRۚ}ɟU}N1DyӤM>e6c儍(+'t U_u Eėj2 %LS0%G ljbKjSu'G*Di $1"K@9'̜+' %(Sb$6)9{xVs+Y91&2Szr-o$ZǵKEiPK|P$؈KuRQ\ }tu*zYT4r|))RNi_*9qvՇ*24):[c`+9&8]TsbIv%ϧM.c儍H@^#9'e2Ky.ٵuE S8o!V+$͜V>Pb 9雒2sdCtͦpj@Cl%Ҕ&!SjsGbXm)KRGցrXOi'K 9ScJo3VN؊ʽ.ZS:tKMnCQ:LRȦ@&U0_>@9pqƘǕsND*8D0UQ&Ѫe;9ݒRg"hZ;iJȩN)b}rlڟv=rke$<%`Jߦ4gsZ qKf"ڪ&R5zM@?FsJMj JHehJǯPߗΕ=.Y_SBNujL9'llFZǯJ|4u W-9'SzRĩ'vXICʉ=H%[ksk@aݰсtkbT^8UOwU^[':ScJo3VNNr/sNd)/bJߢWNB)'/Hh+'gΚ*'"k5MIRhGdrR9SObΉ q;YJȩ2{ϔrS+ TsLcctF9)JoC({V%~Ni'E EīM v 鸵(cPB@RJl۠0Ii6YJ*[X4ZxCdd*JUU(ewC+ňaVtUbDvMVQA'K_«C, CPBNub{Er9'Š [=|`Х{3ʔ7MRډRzsjt)&9')'vFb)LSszqe!Qjc_֒):EJ3*8s2u$<.Կ/ᜓR=vSeV眼b5:zrZ'HZG+_ڙS:dmk(AZgWt91n(3 pAeJÔX99yJP\=9q0%OɯJg2K}N"T-L)7[{4rw϶ GaRQBաu/jj+JfNgjwBJ:WJ̕Bo+tgjCZG:ҡQJ\(<̽yN9QN :%JyСȗj+trJ*Xd^)[٦0lPX) X8 B):'cQ'!O~~xG9Y|A9ѦjQ:×5|I9I)D(RУdscWC]bq-q(MeJQ9<2%iLqD<\T2%;wvͩLPRdu" ɰR4A@)'i(jLIT߉{uU B)zn ƎEk|:1jbC!Hu`M)%8LL k^5 ;:Ě 'bJA5Ab%rp b ROh>}NrTnޖjM;K}xh>}NB2t_) ta|IQBN)wOҋjGJNlٟ6;rQ:tkdBΉhrNBJqY3ip('a(BúmJgk<CQ DI2kJzR`EJn3߬J>ԡLɜQ>'%JChp0G*'3(@~l[iOm] _z^so'G}iNw4b-hYd)R?-tK(R0H"J6\o)y93Ts>wK#KJ3l5{c'x"q?߳DҼa?~^7pcΊFoGO3)-ȗVtPKΈ}|KvGIf"(/Q R7|)FpK_rL4#c9RfR{\2n1-|7d_[Jl-nl$7 u]YpDM)FAIENDB`zevv-duc-b8f9659/src/000077500000000000000000000000001426703022500144235ustar00rootroot00000000000000zevv-duc-b8f9659/src/duc/000077500000000000000000000000001426703022500151765ustar00rootroot00000000000000zevv-duc-b8f9659/src/duc/cmd-cgi.c000066400000000000000000000343351426703022500166550ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include "cmd.h" #include "duc.h" #include "duc-graph.h" struct param { char *key; char *val; struct param *next; }; static bool opt_apparent = false; static bool opt_count = false; static char *opt_css_url = NULL; static char *opt_database = NULL; static bool opt_bytes = false; static bool opt_list = false; static int opt_size = 800; static bool opt_gradient = false; static char *opt_footer = NULL; static double opt_fuzz = 0.7; static char *opt_header = NULL; static int opt_levels = 4; static char *opt_palette = NULL; static bool opt_tooltip = false; static int opt_ring_gap = 4; static double opt_dpi = 96.0; static struct param *param_list = NULL; static void print_html(const char *s) { while(*s) { switch(*s) { case '<': printf("<"); break; case '>': printf(">"); break; case '&': printf("&"); break; case '"': printf("""); break; default: putchar(*s); break; } s++; } } static int isrfc1738(const char c) { switch (c) { case '$': case '-': case '_': case '.': case '+': case '!': case '*': case '(': case ')': return 1; default: return 0; } return 0; } static void print_cgi(const char *s) { while(*s) { if(*s == '/' || isrfc1738(*s) || isalnum(*s)) { putchar(*s); } else { printf("%%%02x", *(uint8_t *)s); } s++; } } static int hexdigit(char a) { if (a >= 'a') { a -= 'a'-'A'; } if (a >= 'A') { a -= ('A' - 10); } else { a -= '0'; } return a; } void decode_uri(char *src, char *dst) { char a, b; while (*src) { if((*src == '%') && ((a = src[1]) && (b = src[2])) && (isxdigit(a) && isxdigit(b))) { *dst++ = 16 * hexdigit(a) + hexdigit(b); src+=3; } else if (*src == '+') { *dst++ = ' '; src++; } else { *dst++ = *src++; } } *dst++ = '\0'; } static int cgi_parse(void) { char *qs = getenv("QUERY_STRING"); if(qs == NULL) qs = ""; char *p = qs; for(;;) { char *pe = strchr(p, '='); if(!pe) break; char *pn = strchr(pe, '&'); if(!pn) pn = pe + strlen(pe); char *key = p; int keylen = pe-p; char *val = pe+1; int vallen = pn-pe-1; struct param *param = malloc(sizeof(struct param)); assert(param); param->key = malloc(keylen+1); assert(param->key); strncpy(param->key, key, keylen); param->key[keylen] = '\0'; decode_uri(param->key, param->key); param->val = malloc(vallen+1); assert(param->val); strncpy(param->val, val, vallen); param->val[vallen] = '\0'; decode_uri(param->val, param->val); param->next = param_list; param_list = param; if(*pn == 0) break; p = pn+1; } return 0; } static char *cgi_get(const char *key) { struct param *param = param_list; while(param) { if(strcmp(param->key, key) == 0) { return param->val; } param = param->next; } return NULL; } static void print_css(void) { printf( "\n" ); } static void print_script(const char *path) { printf( "\n" ); } static void include_file(const char *fname) { FILE *f = fopen(fname, "rb"); if(f) { printf("\n"); for(;;) { char buf[4096]; size_t n = fread(buf, 1, sizeof(buf), f); if(n == 0) break; fwrite(buf, 1, n, stdout); } printf("\n"); fclose(f); } } static void print_html_header(const char *path) { printf( "Content-Type: text/html\n" "\n" "\n" "\n" " \n" ); if(opt_css_url) { printf("\n", opt_css_url); } else { print_css(); } if(path) { print_script(path); } printf("\n"); printf("\n"); include_file(opt_header); } static void do_index(duc *duc, duc_graph *graph, duc_dir *dir) { char *path = cgi_get("path"); char *script = getenv("SCRIPT_NAME"); if(!script) return; char url[DUC_PATH_MAX]; snprintf(url, sizeof url, "%s?cmd=index", script); /* If 'x' and 'y' CGI parameters are given, lookup the new path in the * database. If found, generate a HTTP redirect to the new path. */ char *xs = cgi_get("x"); char *ys = cgi_get("y"); if(dir && xs && ys) { int x = atoi(xs); int y = atoi(ys); duc_dir *dir2 = duc_graph_find_spot(graph, dir, x, y, NULL); if(dir2) { dir = dir2; path = duc_dir_get_path(dir); printf("Status: 302 Found\n"); printf("Location: ?path=%s\n", path); printf("URI: ?path=%s\n", path); printf("Connection: close\n"); printf("Content-type: text/html\n\n"); printf("\n"); return; } } struct duc_index_report *report; int i = 0; print_html_header(path); printf("

\n"); printf("
"); printf(" \n"); printf(" \n"); printf(" \n"); printf(" \n"); printf(" \n"); printf(" \n"); printf(" \n"); printf(" \n"); printf(" \n"); while( (report = duc_get_report(duc, i)) != NULL) { char ts_date[32]; char ts_time[32]; time_t t = report->time_start.tv_sec; struct tm *tm = localtime(&t); strftime(ts_date, sizeof ts_date, "%Y-%m-%d",tm); strftime(ts_time, sizeof ts_time, "%H:%M:%S",tm); duc_size_type st = opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; char siz[32]; duc_human_size(&report->size, st, 0, siz, sizeof siz); printf(" \n"); printf(" \n"); printf(" \n", siz); printf(" \n", report->file_count); printf(" \n", report->dir_count); printf(" \n", ts_date); printf(" \n", ts_time); printf(" \n"); duc_index_report_free(report); i++; } printf("
PathSizeFilesDirectoriesDateTime
path); printf("\">"); print_html(report->path); printf("%s%zu%zu%s%s
\n"); if(path) { printf("
\n"); duc_graph_draw(graph, dir); printf("
\n"); } if(path && dir && opt_list) { duc_size_type st = opt_count ? DUC_SIZE_TYPE_COUNT : opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; printf("
\n"); printf(" \n"); printf(" \n"); printf(" \n"); printf(" \n"); printf(" \n"); duc_dir_rewind(dir); struct duc_dirent *e; int n = 0; while((n++ < 40) && (e = duc_dir_read(dir, st, DUC_SORT_SIZE)) != NULL) { char siz[32]; duc_human_size(&e->size, st, opt_bytes, siz, sizeof siz); printf(" \n", siz); printf(" \n"); } printf("
FilenameSize
"); if(e->type == DUC_FILE_TYPE_DIR) { printf("name); printf("\">"); } print_html(e->name); if(e->type == DUC_FILE_TYPE_DIR) printf("\n"); printf(" %s
\n"); printf("
\n"); } printf("
\n"); if(opt_tooltip) { printf("
\n"); } printf("
\n"); include_file(opt_footer); printf("\n"); printf("\n"); fflush(stdout); } void do_tooltip(duc *duc, duc_graph *graph, duc_dir *dir) { printf("Content-Type: text/html\n"); printf("\n"); char *xs = cgi_get("x"); char *ys = cgi_get("y"); if(dir && xs && ys) { int x = atoi(xs); int y = atoi(ys); struct duc_dirent *ent = NULL; duc_dir *dir2 = duc_graph_find_spot(graph, dir, x, y, &ent); if(dir2) duc_dir_close(dir2); if(ent) { char siz_app[32], siz_act[32], siz_cnt[32]; duc_human_size(&ent->size, DUC_SIZE_TYPE_APPARENT, opt_bytes, siz_app, sizeof siz_app); duc_human_size(&ent->size, DUC_SIZE_TYPE_ACTUAL, opt_bytes, siz_act, sizeof siz_act); duc_human_size(&ent->size, DUC_SIZE_TYPE_COUNT, opt_bytes, siz_cnt, sizeof siz_cnt); char *typ = duc_file_type_name(ent->type); printf("name: %s
\n" "type: %s
\n" "actual size: %s
\n" "apparent size: %s
\n" "file count: %s", ent->name, typ, siz_act, siz_app, siz_cnt); free(ent->name); free(ent); } } } static int cgi_main(duc *duc, int argc, char **argv) { int r; if(getenv("GATEWAY_INTERFACE") == NULL) { fprintf(stderr, "The 'cgi' subcommand is used for integrating Duc into a web server.\n" "Please refer to the documentation for instructions how to install and configure.\n" ); return(-1); } cgi_parse(); char *cmd = cgi_get("cmd"); if(cmd == NULL) cmd = "index"; r = duc_open(duc, opt_database, DUC_OPEN_RO); if(r != DUC_OK) { printf("Content-Type: text/plain\n\n"); printf("%s\n", duc_strerror(duc)); return -1; } duc_dir *dir = NULL; char *path = cgi_get("path"); if(path) { dir = duc_dir_open(duc, path); if(dir == NULL) { printf("Content-Type: text/plain\n\n"); printf("%s\n", duc_strerror(duc)); print_html(path); return -1; } } static enum duc_graph_palette palette = 0; if(opt_palette) { char c = tolower(opt_palette[0]); if(c == 's') palette = DUC_GRAPH_PALETTE_SIZE; if(c == 'r') palette = DUC_GRAPH_PALETTE_RAINBOW; if(c == 'g') palette = DUC_GRAPH_PALETTE_GREYSCALE; if(c == 'm') palette = DUC_GRAPH_PALETTE_MONOCHROME; if(c == 'c') palette = DUC_GRAPH_PALETTE_CLASSIC; } duc_size_type st = opt_count ? DUC_SIZE_TYPE_COUNT : opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; duc_graph *graph = duc_graph_new_html(duc, stdout, 0); duc_graph_set_size(graph, opt_size, opt_size); duc_graph_set_dpi(graph, opt_dpi); duc_graph_set_max_level(graph, opt_levels); duc_graph_set_fuzz(graph, opt_fuzz); duc_graph_set_palette(graph, palette); duc_graph_set_exact_bytes(graph, opt_bytes); duc_graph_set_size_type(graph, st); duc_graph_set_ring_gap(graph, opt_ring_gap); duc_graph_set_gradient(graph, opt_gradient); if(strcmp(cmd, "index") == 0) do_index(duc, graph, dir); if(strcmp(cmd, "tooltip") == 0) do_tooltip(duc, graph, dir); duc_close(duc); return 0; } static struct ducrc_option options[] = { { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "Show apparent instead of actual file size" }, { &opt_bytes, "bytes", 'b', DUCRC_TYPE_BOOL, "show file size in exact number of bytes" }, { &opt_count, "count", 0, DUCRC_TYPE_BOOL, "show number of files instead of file size" }, { &opt_css_url, "css-url", 0, DUCRC_TYPE_STRING, "url of CSS style sheet to use instead of default CSS" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, { &opt_dpi, "dpi", 0 , DUCRC_TYPE_DOUBLE, "set destination resolution in DPI [96.0]" }, { &opt_footer, "footer", 0, DUCRC_TYPE_STRING, "select HTML file to include as footer" }, { &opt_fuzz, "fuzz", 0, DUCRC_TYPE_DOUBLE, "use radius fuzz factor when drawing graph [0.7]" }, { &opt_gradient, "gradient", 0, DUCRC_TYPE_BOOL, "draw graph with color gradient" }, { &opt_header, "header", 0, DUCRC_TYPE_STRING, "select HTML file to include as header" }, { &opt_levels, "levels", 'l', DUCRC_TYPE_INT, "draw up to ARG levels deep [4]" }, { &opt_list, "list", 0, DUCRC_TYPE_BOOL, "generate table with file list" }, { &opt_palette, "palette", 0, DUCRC_TYPE_STRING, "select palette", "available palettes are: size, rainbow, greyscale, monochrome, classic" }, { &opt_ring_gap, "ring-gap", 0, DUCRC_TYPE_INT, "leave a gap of VAL pixels between rings" }, { &opt_size, "size", 's', DUCRC_TYPE_INT, "image size [800]" }, { &opt_tooltip, "tooltip", 0, DUCRC_TYPE_BOOL, "enable tooltip when hovering over the graph", "enabling the tooltip will cause an asynchronous HTTP request every time the mouse is moved and " "can greatly increase the HTTP traffic to the web server" }, { NULL } }; struct cmd cmd_cgi = { .name = "cgi", .descr_short = "CGI interface wrapper", .usage = "[options] [PATH]", .main = cgi_main, .options = options, }; /* * End */ zevv-duc-b8f9659/src/duc/cmd-graph.c000066400000000000000000000123611426703022500172070ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "duc.h" #include "duc-graph.h" #include "cmd.h" static char *opt_database = NULL; static bool opt_apparent = false; static bool opt_count = false; static int opt_size = 800; static double opt_fuzz = 0.7; static int opt_levels = 4; static char *opt_output = NULL; static char *opt_palette = NULL; static enum duc_graph_palette palette = 0; static int opt_ring_gap = 4; static bool opt_gradient = false; static double opt_dpi = 96.0; #ifdef ENABLE_CAIRO static char *opt_format = "png"; #else static char *opt_format = "svg"; #endif static int graph_main(duc *duc, int argc, char **argv) { char *path_out = opt_output; char *path_out_default = "duc.png"; duc_graph_file_format format = DUC_GRAPH_FORMAT_PNG; if(strcasecmp(opt_format, "html") == 0) { format = DUC_GRAPH_FORMAT_HTML; path_out_default = "duc.html"; } if(strcasecmp(opt_format, "svg") == 0) { format = DUC_GRAPH_FORMAT_SVG; path_out_default = "duc.svg"; } if(strcasecmp(opt_format, "pdf") == 0) { format = DUC_GRAPH_FORMAT_PDF; path_out_default = "duc.pdf"; } if(opt_palette) { char c = tolower(opt_palette[0]); if(c == 's') palette = DUC_GRAPH_PALETTE_SIZE; if(c == 'r') palette = DUC_GRAPH_PALETTE_RAINBOW; if(c == 'g') palette = DUC_GRAPH_PALETTE_GREYSCALE; if(c == 'm') palette = DUC_GRAPH_PALETTE_MONOCHROME; if(c == 'c') palette = DUC_GRAPH_PALETTE_CLASSIC; } if(path_out == NULL) path_out = path_out_default; char *path = "."; if(argc > 0) path = argv[0]; int r = duc_open(duc, opt_database, DUC_OPEN_RO); if(r != DUC_OK) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } duc_dir *dir = duc_dir_open(duc, path); if(dir == NULL) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } FILE *f = NULL; if(strcmp(path_out, "-") == 0) { f = stdout; } else { f = fopen(path_out, "w"); } if(f == NULL) { duc_log(duc, DUC_LOG_FTL, "Error opening output file: %s", strerror(errno)); return -1; } duc_graph *graph; switch(format) { case DUC_GRAPH_FORMAT_SVG: graph = duc_graph_new_svg(duc, f); break; case DUC_GRAPH_FORMAT_HTML: graph = duc_graph_new_html(duc, f, 1); break; #ifdef ENABLE_CAIRO case DUC_GRAPH_FORMAT_PNG: case DUC_GRAPH_FORMAT_PDF: graph = duc_graph_new_cairo_file(duc, format, f); break; #endif default: duc_log(duc, DUC_LOG_FTL, "Requested image format is not supported"); exit(1); break; } duc_size_type st = opt_count ? DUC_SIZE_TYPE_COUNT : opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; duc_graph_set_size(graph, opt_size, opt_size); duc_graph_set_dpi(graph, opt_dpi); duc_graph_set_fuzz(graph, opt_fuzz); duc_graph_set_max_level(graph, opt_levels); duc_graph_set_palette(graph, palette); duc_graph_set_size_type(graph, st); duc_graph_set_ring_gap(graph, opt_ring_gap); duc_graph_set_gradient(graph, opt_gradient); duc_graph_draw(graph, dir); duc_graph_free(graph); duc_dir_close(dir); duc_close(duc); return 0; } static struct ducrc_option options[] = { { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "Show apparent instead of actual file size" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, { &opt_count, "count", 0, DUCRC_TYPE_BOOL, "show number of files instead of file size" }, { &opt_dpi, "dpi", 0 , DUCRC_TYPE_DOUBLE, "set destination resolution in DPI [96.0]" }, { &opt_format, "format", 'f', DUCRC_TYPE_STRING, #ifdef ENABLE_CAIRO "select output format [png]" }, #else "select output format [svg]" }, #endif { &opt_fuzz, "fuzz", 0, DUCRC_TYPE_DOUBLE, "use radius fuzz factor when drawing graph [0.7]" }, { &opt_gradient, "gradient", 0, DUCRC_TYPE_BOOL, "draw graph with color gradient" }, { &opt_levels, "levels", 'l', DUCRC_TYPE_INT, "draw up to ARG levels deep [4]" }, { &opt_output, "output", 'o', DUCRC_TYPE_STRING, "output file name [duc.png]" }, { &opt_palette, "palette", 0, DUCRC_TYPE_STRING, "select palette", "available palettes are: size, rainbow, greyscale, monochrome, classic" }, { &opt_ring_gap, "ring-gap", 0, DUCRC_TYPE_INT, "leave a gap of VAL pixels between rings" }, { &opt_size, "size", 's', DUCRC_TYPE_INT, "image size [800]" }, { NULL } }; struct cmd cmd_graph = { .name = "graph", .descr_short = "Generate a sunburst graph for a given path", .usage = "[options] [PATH]", .main = graph_main, .options = options, .descr_long = "The 'graph' subcommand queries the duc database and generates a sunburst graph\n" "showing the disk usage of the given path. If no path is given a graph is created\n" "for the current working directory.\n" "\n" "By default the graph is written to the file 'duc.png', which can be overridden by\n" "using the -o/--output option. The output can be sent to stdout by using the special\n" "file name '-'.\n" }; /* * End */ zevv-duc-b8f9659/src/duc/cmd-gui.c000066400000000000000000000205351426703022500166740ustar00rootroot00000000000000#include "config.h" #ifdef ENABLE_X11 #include "duc.h" #include "duc-graph.h" #include "ducrc.h" #include "cmd.h" #include #include #include #include #include #include #include #include #include #include #include #include static bool opt_bytes = false; static bool opt_dark = false; static char *opt_database = NULL; static char *opt_palette = NULL; static double opt_fuzz = 0.5; static int opt_levels = 4; static bool opt_apparent = false; static bool opt_count = false; static int opt_ring_gap = 4; static bool opt_gradient = false; static Display *dpy; static Window rootwin; static int redraw = 1; static int tooltip_x = 0; static int tooltip_y = 0; static int tooltip_moved = 0; static struct pollfd pfd; static enum duc_graph_palette palette = 0; static int win_w = 600; static int win_h = 600; static cairo_surface_t *cs; static cairo_t *cr; static duc_dir *dir; static duc_graph *graph; static double fuzz; static Atom wmDeleteMessage; static void draw(void) { if(opt_levels < 1) opt_levels = 1; if(opt_levels > 10) opt_levels = 10; duc_size_type st = opt_count ? DUC_SIZE_TYPE_COUNT : opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; duc_graph_set_size(graph, win_w, win_h); duc_graph_set_position(graph, 0, 0); duc_graph_set_max_level(graph, opt_levels); duc_graph_set_fuzz(graph, fuzz); duc_graph_set_palette(graph, palette); duc_graph_set_max_name_len(graph, 30); duc_graph_set_size_type(graph, st); duc_graph_set_exact_bytes(graph, opt_bytes); duc_graph_set_tooltip(graph, tooltip_x, tooltip_y); duc_graph_set_ring_gap(graph, opt_ring_gap); duc_graph_set_gradient(graph, opt_gradient); cairo_push_group(cr); if(opt_dark) { cairo_set_source_rgb(cr, 0, 0, 0); } else { cairo_set_source_rgb(cr, 1, 1, 1); } cairo_paint(cr); duc_graph_draw(graph, dir); cairo_pop_group_to_source(cr); cairo_paint(cr); cairo_surface_flush(cs); } static int handle_event(XEvent e) { KeySym k; int x, y, b; switch(e.type) { case ConfigureNotify: win_w = e.xconfigure.width; win_h = e.xconfigure.height; cairo_xlib_surface_set_size(cs, win_w, win_h); redraw = 1; break; case Expose: if(e.xexpose.count < 1) redraw = 1; break; case KeyPress: k = XLookupKeysym(&e.xkey, 0); if(k == XK_minus) opt_levels--; if(k == XK_equal) opt_levels++; if(k == XK_0) opt_levels = 4; if(k == XK_Escape) return 1; if(k == XK_q) return 1; if(k == XK_a) opt_apparent = !opt_apparent; if(k == XK_c) opt_count = !opt_count; if(k == XK_b) opt_bytes = !opt_bytes; if(k == XK_f) fuzz = (fuzz == 0) ? opt_fuzz : 0; if(k == XK_g) opt_gradient = !opt_gradient; if(k == XK_comma) if(opt_ring_gap > 0) opt_ring_gap --; if(k == XK_period) opt_ring_gap ++; if(k == XK_p) { palette = (palette + 1) % 5; } if(k == XK_BackSpace) { duc_dir *dir2 = duc_dir_openat(dir, ".."); if(dir2) { duc_dir_close(dir); dir = dir2; } } redraw = 1; break; case ButtonPress: x = e.xbutton.x; y = e.xbutton.y; b = e.xbutton.button; if(b == 1) { duc_dir *dir2 = duc_graph_find_spot(graph, dir, x, y, NULL); if(dir2) { duc_dir_close(dir); dir = dir2; } } if(b == 3) { duc_dir *dir2 = duc_dir_openat(dir, ".."); if(dir2) { duc_dir_close(dir); dir = dir2; } } if(b == 4) opt_levels --; if(b == 5) opt_levels ++; redraw = 1; break; case MotionNotify: tooltip_x = e.xmotion.x; tooltip_y = e.xmotion.y; tooltip_moved = 1; break; case ClientMessage: if ((Atom)e.xclient.data.l[0] == wmDeleteMessage) { return 1; } default: break; } return 0; } static void do_gui(duc *duc, duc_graph *graph, duc_dir *dir) { pfd.fd = ConnectionNumber(dpy); pfd.events = POLLIN | POLLERR; int quit = 0; while(!quit) { if(redraw) { draw(); XFlush(dpy); redraw = 0; } int r = poll(&pfd, 1, 10); if(r == 0) { if(tooltip_moved) { tooltip_moved = 0; redraw = 1; } } while (XEventsQueued(dpy, QueuedAfterReading) > 0) { XEvent e; XNextEvent(dpy, &e); quit = handle_event(e); } } cairo_surface_destroy(cs); XCloseDisplay(dpy); } int gui_main(duc *duc, int argc, char *argv[]) { char *path = "."; if(argc > 0) path = argv[0]; fuzz = opt_fuzz; if(opt_palette) { char c = tolower(opt_palette[0]); if(c == 's') palette = DUC_GRAPH_PALETTE_SIZE; if(c == 'r') palette = DUC_GRAPH_PALETTE_RAINBOW; if(c == 'g') palette = DUC_GRAPH_PALETTE_GREYSCALE; if(c == 'm') palette = DUC_GRAPH_PALETTE_MONOCHROME; if(c == 'c') palette = DUC_GRAPH_PALETTE_CLASSIC; } int r = duc_open(duc, opt_database, DUC_OPEN_RO); if(r != DUC_OK) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } dir = duc_dir_open(duc, path); if(dir == NULL) { if(duc_error(duc) == DUC_E_PATH_NOT_FOUND) { duc_log(duc, DUC_LOG_FTL, "The requested path '%s' was not found in the database,", path); duc_log(duc, DUC_LOG_FTL, "Please run 'duc info' for a list of available directories."); } else { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); } return -1; } dpy = XOpenDisplay(NULL); if(dpy == NULL) { duc_log(duc, DUC_LOG_FTL, "ERROR: Could not open display"); exit(1); } int scr = DefaultScreen(dpy); rootwin = RootWindow(dpy, scr); Window win = XCreateSimpleWindow( dpy, rootwin, 1, 1, win_w, win_h, 0, BlackPixel(dpy, scr), WhitePixel(dpy, scr)); XClassHint ch = { .res_name = "duc", .res_class = "Duc", }; XSetClassHint(dpy, win, &ch); XSelectInput(dpy, win, ExposureMask | ButtonPressMask | StructureNotifyMask | KeyPressMask | PointerMotionMask); XMapWindow(dpy, win); wmDeleteMessage = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, win, &wmDeleteMessage, 1); cs = cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, 0), win_w, win_h); cr = cairo_create(cs); graph = duc_graph_new_cairo(duc, cr); int w_px = DisplayWidth(dpy, 0); int w_mm = DisplayWidthMM(dpy, 0); if(w_px && w_mm) { double dpi = 25.4 * w_px / w_mm; duc_graph_set_dpi(graph, dpi); } do_gui(duc, graph, dir); duc_dir_close(dir); return 0; } static struct ducrc_option options[] = { { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "show apparent instead of actual file size" }, { &opt_bytes, "bytes", 'b', DUCRC_TYPE_BOOL, "show file size in exact number of bytes" }, { &opt_count, "count", 0, DUCRC_TYPE_BOOL, "show number of files instead of file size" }, { &opt_dark, "dark", 0, DUCRC_TYPE_BOOL, "use dark background color" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, { &opt_fuzz, "fuzz", 0, DUCRC_TYPE_DOUBLE, "use radius fuzz factor when drawing graph" }, { &opt_gradient, "gradient", 0, DUCRC_TYPE_BOOL, "draw graph with color gradient" }, { &opt_levels, "levels", 'l', DUCRC_TYPE_INT, "draw up to VAL levels deep [4]" }, { &opt_palette, "palette", 0, DUCRC_TYPE_STRING, "select palette", "available palettes are: size, rainbow, greyscale, monochrome, classic" }, { &opt_ring_gap, "ring-gap", 0, DUCRC_TYPE_INT, "leave a gap of VAL pixels between rings" }, { NULL } }; struct cmd cmd_gui = { .name = "gui", .descr_short = "Interactive X11 graphical interface", .usage = "[options] [PATH]", .main = gui_main, .options = options, .descr_long = "The 'gui' subcommand queries the duc database and runs an interactive graphical\n" "utility for exploring the disk usage of the given path. If no path is given the\n" "current working directory is explored.\n" "\n" "The following keys can be used to navigate and alter the graph:\n" "\n" " + increase maximum graph depth\n" " - decrease maximum graph depth\n" " 0 Set default graph depth\n" " a Toggle between apparent and actual disk usage\n" " b Toggle between exact byte count and abbreviated sizes\n" " c Toggle between file size and file count\n" " f toggle graph fuzz\n" " g toggle graph gradient\n" " p toggle palettes\n" " backspace go up one directory\n" }; #endif /* * End */ zevv-duc-b8f9659/src/duc/cmd-guigl.c000066400000000000000000000167251426703022500172250ustar00rootroot00000000000000#include "config.h" #ifdef ENABLE_OPENGL #include "duc.h" #include "duc-graph.h" #include "ducrc.h" #include "cmd.h" #include #include #include #include #include #include #include #include static bool opt_bytes = false; static bool opt_dark = false; static char *opt_database = NULL; static char *opt_palette = NULL; static double opt_fuzz = 0.5; static int opt_levels = 4; static bool opt_apparent = false; static bool opt_count = false; static int opt_ring_gap = 4; static bool opt_gradient = false; static double tooltip_x = 0; static double tooltip_y = 0; static enum duc_graph_palette palette = 0; static int win_w = 600; static int win_h = 600; static duc_dir *dir; static duc_graph *graph; static double fuzz; static void sc2fb(GLFWwindow* window, double *x, double *y) { int w1, h1, w2, h2; glfwGetFramebufferSize(window, &w1, &h1); glfwGetWindowSize(window, &w2, &h2); if(x) *x *= (double)w1 / (double)w2; if(y) *y *= (double)h1 / (double)h2; } void cb_winsize(GLFWwindow* window, int w, int h) { win_w = w; win_h = h; glViewport(0, 0, win_w, win_h); } static void draw(GLFWwindow *window) { if(opt_levels < 1) opt_levels = 1; if(opt_levels > 10) opt_levels = 10; duc_size_type st = opt_count ? DUC_SIZE_TYPE_COUNT : opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; duc_graph_set_size(graph, win_w, win_h); duc_graph_set_max_level(graph, opt_levels); duc_graph_set_fuzz(graph, fuzz); duc_graph_set_palette(graph, palette); duc_graph_set_max_name_len(graph, 30); duc_graph_set_size_type(graph, st); duc_graph_set_exact_bytes(graph, opt_bytes); duc_graph_set_tooltip(graph, tooltip_x, tooltip_y); duc_graph_set_ring_gap(graph, opt_ring_gap); duc_graph_set_gradient(graph, opt_gradient); if(opt_dark) { glClearColor(0, 0, 0, 1); } else { glClearColor(1, 1, 1, 1); } glClear(GL_COLOR_BUFFER_BIT); duc_graph_draw(graph, dir); glfwSwapBuffers(window); } static void cb_keyboard(GLFWwindow* window, int k, int scancode, int action, int mods) { if(action != 1) return; if(k == '-') opt_levels--; if(k == '=') opt_levels++; if(k == '0') opt_levels = 4; if(k == GLFW_KEY_ESCAPE) exit(0); if(k == 'Q') exit(0); if(k == 'A') opt_apparent = !opt_apparent; if(k == 'C') opt_count = !opt_count; if(k == 'B') opt_bytes = !opt_bytes; if(k == 'F') fuzz = (fuzz == 0) ? opt_fuzz : 0; if(k == 'G') opt_gradient = !opt_gradient; if(k == ',') if(opt_ring_gap > 0) opt_ring_gap --; if(k == '.') opt_ring_gap ++; if(k == 'P') palette = (palette + 1) % 5; if(k == GLFW_KEY_BACKSPACE) { duc_dir *dir2 = duc_dir_openat(dir, ".."); if(dir2) { duc_dir_close(dir); dir = dir2; } } } void cb_mouse_button(GLFWwindow* window, int b, int action, int mods) { if(action != 1) return; double x, y; glfwGetCursorPos(window, &x, &y); sc2fb(window, &x, &y); if(b == 0) { duc_dir *dir2 = duc_graph_find_spot(graph, dir, x, y, NULL); if(dir2) { duc_dir_close(dir); dir = dir2; } } if(b == 3) { duc_dir *dir2 = duc_dir_openat(dir, ".."); if(dir2) { duc_dir_close(dir); dir = dir2; } } } void cb_scroll(GLFWwindow* window, double xoffset, double yoffset) { static double scroll = 0; scroll += yoffset; if(scroll < -1) { opt_levels --; scroll += 1; } if(scroll > +1) { opt_levels ++; scroll -= 1; } } void cb_mouse_motion(GLFWwindow* window, double x, double y) { sc2fb(window, &x, &y); tooltip_x = x; tooltip_y = y; } int guigl_main(duc *duc, int argc, char *argv[]) { char *path = "."; if(argc > 0) path = argv[0]; fuzz = opt_fuzz; if(opt_palette) { char c = tolower(opt_palette[0]); if(c == 's') palette = DUC_GRAPH_PALETTE_SIZE; if(c == 'r') palette = DUC_GRAPH_PALETTE_RAINBOW; if(c == 'g') palette = DUC_GRAPH_PALETTE_GREYSCALE; if(c == 'm') palette = DUC_GRAPH_PALETTE_MONOCHROME; if(c == 'c') palette = DUC_GRAPH_PALETTE_CLASSIC; } int r = duc_open(duc, opt_database, DUC_OPEN_RO); if(r != DUC_OK) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } dir = duc_dir_open(duc, path); if(dir == NULL) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } if(!glfwInit()) { duc_log(duc, DUC_LOG_FTL, "Error initializen glfw"); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); GLFWwindow* window = window = glfwCreateWindow(640, 480, "Duc", NULL, NULL);; if(window == NULL) { duc_log(duc, DUC_LOG_FTL, "Error creating glfw window"); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); gladLoadGLES2Loader((GLADloadproc) glfwGetProcAddress); glfwGetFramebufferSize(window, &win_w, &win_h); double font_scale = 1.0; sc2fb(window, &font_scale, NULL); graph = duc_graph_new_opengl(duc, font_scale); GLFWmonitor* mon = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(mon); if(mode) { int w_mm = 0, h_mm = 0; glfwGetMonitorPhysicalSize(mon, &w_mm, &h_mm); if(mode && mode->width && w_mm) { double dpi = 25.4 * mode->width / w_mm; printf("dpi %f\n", dpi); duc_graph_set_dpi(graph, dpi); } } glfwSetKeyCallback(window, cb_keyboard); glfwSetFramebufferSizeCallback(window, cb_winsize); glfwSetMouseButtonCallback(window, cb_mouse_button); glfwSetCursorPosCallback(window, cb_mouse_motion); glfwSetScrollCallback(window, cb_scroll); while (!glfwWindowShouldClose(window)) { draw(window); glfwWaitEvents(); } glfwTerminate(); return 0; } static struct ducrc_option options[] = { { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "show apparent instead of actual file size" }, { &opt_bytes, "bytes", 'b', DUCRC_TYPE_BOOL, "show file size in exact number of bytes" }, { &opt_count, "count", 0, DUCRC_TYPE_BOOL, "show number of files instead of file size" }, { &opt_dark, "dark", 0, DUCRC_TYPE_BOOL, "use dark background color" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, { &opt_fuzz, "fuzz", 0, DUCRC_TYPE_DOUBLE, "use radius fuzz factor when drawing graph" }, { &opt_gradient, "gradient", 0, DUCRC_TYPE_BOOL, "draw graph with color gradient" }, { &opt_levels, "levels", 'l', DUCRC_TYPE_INT, "draw up to VAL levels deep [4]" }, { &opt_palette, "palette", 0, DUCRC_TYPE_STRING, "select palette", "available palettes are: size, rainbow, greyscale, monochrome, classic" }, { &opt_ring_gap, "ring-gap", 0, DUCRC_TYPE_INT, "leave a gap of VAL pixels between rings" }, { NULL } }; struct cmd cmd_guigl = { .name = "gui", .descr_short = "Interactive OpenGL graphical interface", .usage = "[options] [PATH]", .main = guigl_main, .options = options, .descr_long = "The 'guigl' subcommand queries the duc database and runs an interactive graphical\n" "utility for exploring the disk usage of the given path. If no path is given the\n" "current working directory is explored.\n" "\n" "The following keys can be used to navigate and alter the graph:\n" "\n" " + increase maximum graph depth\n" " - decrease maximum graph depth\n" " 0 Set default graph depth\n" " a Toggle between apparent and actual disk usage\n" " b Toggle between exact byte count and abbreviated sizes\n" " c Toggle between file size and file count\n" " f toggle graph fuzz\n" " g toggle graph gradient\n" " p toggle palettes\n" " backspace go up one directory\n" }; #endif /* * End */ zevv-duc-b8f9659/src/duc/cmd-index.c000066400000000000000000000154741426703022500172250ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "cmd.h" #include "duc.h" #include "ducrc.h" static bool opt_bytes = false; static char *opt_database = NULL; static bool opt_force = false; static bool opt_check_hard_links = false; static bool opt_hide_file_names = false; static char *opt_username = NULL; static int opt_uid = 0; static int opt_max_depth = 0; static bool opt_one_file_system = false; static bool opt_progress = false; static bool opt_uncompressed = false; static bool opt_dryrun = false; static duc_index_req *req; static int index_init(duc *duc, int argc, char **argv) { req = duc_index_req_new(duc); return 0; } void progress_cb(struct duc_index_report *rep, void *ptr) { static int n = 0; char meter[] = "--------"; int i = 7 - abs(n-7); meter[i] = '#'; n = (n+1) % 14; char siz[32], fs[32], ds[32]; duc_human_size(&rep->size, DUC_SIZE_TYPE_ACTUAL, opt_bytes, siz, sizeof siz); duc_human_number(rep->file_count, opt_bytes, fs, sizeof fs); duc_human_number(rep->dir_count, opt_bytes, ds, sizeof ds); printf("\e[K[%s] Indexed %sb in %s files and %s directories\r", meter, siz, fs, ds); fflush(stdout); } static void log_callback(duc_log_level level, const char *fmt, va_list va) { vfprintf(stderr, fmt, va); fprintf(stderr, "\e[K\n"); } static int index_main(duc *duc, int argc, char **argv) { duc_index_flags index_flags = 0; int open_flags = DUC_OPEN_RW | DUC_OPEN_COMPRESS; if(opt_force) open_flags |= DUC_OPEN_FORCE; if(opt_max_depth) duc_index_req_set_maxdepth(req, opt_max_depth); if(opt_one_file_system) index_flags |= DUC_INDEX_XDEV; if(opt_hide_file_names) index_flags |= DUC_INDEX_HIDE_FILE_NAMES; if(opt_check_hard_links) index_flags |= DUC_INDEX_CHECK_HARD_LINKS; if(opt_uncompressed) open_flags &= ~DUC_OPEN_COMPRESS; if(opt_dryrun) index_flags |= DUC_INDEX_DRY_RUN; if(opt_username) duc_index_req_set_username(req, opt_username); if(opt_uid) duc_index_req_set_uid(req, opt_uid); if(argc < 1) { duc_log(duc, DUC_LOG_FTL, "Required index PATH missing."); return -2; } if(opt_progress) { duc_index_req_set_progress_cb(req, progress_cb, NULL); duc_set_log_callback(duc, log_callback); } int r = duc_open(duc, opt_database, open_flags); if(r != DUC_OK) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } /* Index all paths passed on the cmdline */ int i; for(i=0; isize, DUC_SIZE_TYPE_APPARENT, opt_bytes, siz_apparent, sizeof siz_apparent); duc_human_size(&report->size, DUC_SIZE_TYPE_ACTUAL, opt_bytes, siz_actual, sizeof siz_actual); if(r == DUC_OK) { char dur[64]; duc_human_duration(report->time_start, report->time_stop, dur, sizeof dur); duc_log(duc, DUC_LOG_INF, "Indexed %zu files and %zu directories, (%sB apparent, %sB actual) in %s", report->file_count, report->dir_count, siz_apparent, siz_actual, dur); } else { duc_log(duc, DUC_LOG_WRN, "An error occurred while indexing: %s", duc_strerror(duc)); } /* Prevent final output of progress_cb() from being overwritten with the shell's prompt */ if (opt_progress) { fputc ('\n', stdout); fflush (stdout); } duc_index_report_free(report); } duc_close(duc); duc_index_req_free(req); return 0; } static void fn_exclude(const char *val) { duc_index_req_add_exclude(req, val); } static void fn_fs_include(const char *val) { duc_index_req_add_fstype_include(req, val); } static void fn_fs_exclude(const char *val) { duc_index_req_add_fstype_exclude(req, val); } static struct ducrc_option options[] = { { &opt_bytes, "bytes", 'b', DUCRC_TYPE_BOOL, "show file size in exact number of bytes" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "use database file VAL" }, { fn_exclude, "exclude", 'e', DUCRC_TYPE_FUNC, "exclude files matching VAL" }, { &opt_check_hard_links,"check-hard-links",'H', DUCRC_TYPE_BOOL, "count hard links only once", "if two or more hard links point to the same file, only one of the hard links is displayed and counted" }, { &opt_force, "force", 'f', DUCRC_TYPE_BOOL, "force writing in case of corrupted db" }, { fn_fs_exclude, "fs-exclude", 0, DUCRC_TYPE_FUNC, "exclude file system type VAL during indexing", "VAL is a comma separated list of file system types as found in your systems fstab, for example ext3,ext4,dosfs" }, { fn_fs_include, "fs-include", 0, DUCRC_TYPE_FUNC, "include file system type VAL during indexing", "VAL is a comma separated list of file system types as found in your systems fstab, for example ext3,ext4,dosfs" }, { &opt_hide_file_names, "hide-file-names", 0 , DUCRC_TYPE_BOOL, "hide file names in index (privacy)", "the names of directories will be preserved, but the names of the individual files will be hidden" }, { &opt_uid, "uid", 'U', DUCRC_TYPE_INT, "limit index to only files/dirs owned by uid" }, { &opt_username, "username", 'u', DUCRC_TYPE_STRING, "limit index to only files/dirs owned by username" }, { &opt_max_depth, "max-depth", 'm', DUCRC_TYPE_INT, "limit directory names to given depth" , "when this option is given duc will traverse the complete file system, but will only the first VAL " "levels of directories in the database to reduce the size of the index" }, { &opt_one_file_system, "one-file-system", 'x', DUCRC_TYPE_BOOL, "skip directories on different file systems" }, { &opt_progress, "progress", 'p', DUCRC_TYPE_BOOL, "show progress during indexing" }, { &opt_dryrun, "dry-run", 0 , DUCRC_TYPE_BOOL, "do not update database, just crawl" }, { &opt_uncompressed, "uncompressed", 0 , DUCRC_TYPE_BOOL, "do not use compression for database", "Duc enables compression if the underlying database supports this. This reduces index size at the cost " "of slightly longer indexing time" }, { NULL } }; struct cmd cmd_index = { .name = "index", .descr_short = "Scan the filesystem and generate the Duc index", .usage = "[options] PATH ...", .init = index_init, .main = index_main, .options = options, .descr_long = "The 'index' subcommand performs a recursive scan of the given paths on the\n" "filesystem and calculates the inclusive size of all directories. The results\n" "are written to the index, and can later be queried by one of the other duc tools.\n" }; /* * End */ zevv-duc-b8f9659/src/duc/cmd-info.c000066400000000000000000000035501426703022500170410ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include "cmd.h" #include "duc.h" static bool opt_apparent = false; static bool opt_bytes = false; static char *opt_database = NULL; static int info_db(duc *duc, char *file) { struct duc_index_report *report; duc_size_type st = opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; int i = 0; int r = duc_open(duc, file, DUC_OPEN_RO); if(r != DUC_OK) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } printf("Date Time Files Dirs Size Path\n"); while(( report = duc_get_report(duc, i)) != NULL) { char ts[32]; time_t t = report->time_start.tv_sec; struct tm *tm = localtime(&t); strftime(ts, sizeof ts, "%Y-%m-%d %H:%M:%S",tm); char siz[32], fs[32], ds[32]; duc_human_size(&report->size, st, opt_bytes, siz, sizeof siz); duc_human_number(report->file_count, opt_bytes, fs, sizeof fs); duc_human_number(report->dir_count, opt_bytes, ds, sizeof ds); printf("%s %7s %7s %7s %s\n", ts, fs, ds, siz, report->path); duc_index_report_free(report); i++; } duc_close(duc); return 0; } static int info_main(duc *duc, int argc, char **argv) { return(info_db(duc, opt_database)); } static struct ducrc_option options[] = { { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "show apparent instead of actual file size" }, { &opt_bytes, "bytes", 'b', DUCRC_TYPE_BOOL, "show file size in exact number of bytes" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, { NULL } }; struct cmd cmd_info = { .name = "info", .descr_short = "Dump database info", .usage = "[options]", .main = info_main, .options = options, }; /* * End */ zevv-duc-b8f9659/src/duc/cmd-json.c000066400000000000000000000074641426703022500170670ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include "cmd.h" #include "duc.h" static bool opt_apparent = false; static char *opt_database = NULL; static double opt_min_size = 0; static bool opt_exclude_files = false; static void indent(int n) { int i; for(i=0; isize, st); if (!first) printf(",\n"); if(e->type == DUC_FILE_TYPE_DIR && size>= min_size) { duc_dir *dir_child = duc_dir_openent(dir, e); if(dir_child) { indent(depth); printf("{\n"); indent(depth + 2); printf("\"name\": \""); print_escaped(e->name); printf("\",\n"); indent(depth + 2); printf("\"count\": %jd,\n", e->size.count); indent(depth + 2); printf("\"size_apparent\": %jd,\n", e->size.apparent); indent(depth + 2); printf("\"size_actual\": %jd,\n", e->size.actual); indent(depth + 2); printf("\"children\": [\n"); dump(duc, dir_child, depth + 4, min_size, ex_files); printf("\n"); indent(depth + 2); printf("]\n"); indent(depth); printf("}"); } duc_dir_close(dir_child); } else { if(!ex_files && size >= min_size) { indent(depth); printf("{\n"); indent(depth + 2); printf("\"name\": \""); print_escaped(e->name); printf("\",\n"); indent(depth + 2); printf("\"size_apparent\": %jd,\n", e->size.apparent); indent(depth + 2); printf("\"size_actual\": %jd\n", e->size.actual); indent(depth); printf("}"); } } first = false; } } static int json_main(duc *duc, int argc, char **argv) { char *path = "."; if(argc > 0) path = argv[0]; int r = duc_open(duc, opt_database, DUC_OPEN_RO); if(r != DUC_OK) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } duc_dir *dir = duc_dir_open(duc, path); if(dir == NULL) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } struct duc_size size; duc_dir_get_size(dir, &size); printf("{\n"); indent(2); printf("\"name\": \""); print_escaped(path); printf("\",\n"); indent(2); printf("\"count\": %jd,\n", size.count); indent(2); printf("\"size_apparent\": %jd,\n", size.apparent); indent(2); printf("\"size_actual\": %jd,\n", size.actual); indent(2); printf("\"children\": [\n"); dump(duc, dir, 4, (off_t)opt_min_size, opt_exclude_files); printf("\n"); indent(2); printf("]\n"); printf("}\n"); duc_dir_close(dir); duc_close(duc); return 0; } static struct ducrc_option options[] = { { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "interpret min_size/-s value as apparent size" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, { &opt_exclude_files, "exclude-files", 'x', DUCRC_TYPE_BOOL, "exclude file from json output, only include directories" }, { &opt_min_size, "min_size", 's', DUCRC_TYPE_DOUBLE, "specify min size for files or directories" }, { NULL } }; struct cmd cmd_json = { .name = "json", .descr_short = "Dump JSON output", .usage = "[options] [PATH]", .main = json_main, .options = options, }; /* * End */ zevv-duc-b8f9659/src/duc/cmd-ls.c000066400000000000000000000204371426703022500165270ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_IOCTL_H #include #endif #include "cmd.h" #include "duc.h" #define MAX_DEPTH 32 #define COLOR_RESET "\e[0m"; #define COLOR_RED "\e[31m"; #define COLOR_YELLOW "\e[33m"; static char *tree_ascii[] = { "####", " `+-", " |-", " `-", " | ", " ", }; static char *tree_utf8[] = { "####", " ╰┬─", " ├─", " ╰─", " │ ", " ", }; static bool opt_apparent = false; static bool opt_count = false; static bool opt_ascii = false; static bool opt_bytes = false; static bool opt_classify = false; static bool opt_directory = false; static bool opt_color = false; static bool opt_full_path = false; static int width = 80; static bool opt_graph = false; static bool opt_recursive = false; static char *opt_database = NULL; static bool opt_dirs_only = false; static int opt_levels = 4; static bool opt_name_sort = false; /* * Calculate monospace font widht of string for aligning terminal output */ static size_t string_width(char *string) { int w = 0; size_t n = mbstowcs(NULL, string, 0) + 1; wchar_t *wcstring = malloc(n * sizeof *wcstring); if (wcstring) { if (mbstowcs(wcstring, string, n) != (size_t)-1) { w = wcswidth(wcstring, n); } free(wcstring); } if(w <= 0) w = strlen(string); return w; } /* * List one directory. This function is a bit hairy because of the different * ways the output can be formatted with optional color, trees, graphs, etc. * Maybe one day this should be split up for different renderings */ static char parent_path[DUC_PATH_MAX] = ""; static int prefix[MAX_DEPTH + 1] = { 0 }; static void ls_one(duc_dir *dir, int level, size_t parent_path_len) { off_t max_size = 0; size_t max_name_len = 0; int max_size_len = 6; duc_size_type st = opt_count ? DUC_SIZE_TYPE_COUNT : opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; duc_sort sort = opt_name_sort ? DUC_SORT_NAME : DUC_SORT_SIZE; if(level > opt_levels) return; char **tree = opt_ascii ? tree_ascii : tree_utf8; /* Iterate the directory once to get maximum file size and name length */ struct duc_dirent *e; while( (e = duc_dir_read(dir, st, sort)) != NULL) { off_t size = duc_get_size(&e->size, st); if(size > max_size) max_size = size; size_t l = string_width(e->name); if(l > max_name_len) max_name_len = l; } if(opt_bytes) max_size_len = 12; if(opt_classify) max_name_len ++; /* Iterate a second time to print results */ duc_dir_rewind(dir); size_t count = duc_dir_get_count(dir); size_t n = 0; while( (e = duc_dir_read(dir, st, sort)) != NULL) { if(opt_dirs_only && e->type != DUC_FILE_TYPE_DIR) continue; off_t size = duc_get_size(&e->size, st); if(opt_recursive) { if(n == 0) prefix[level] = 1; if(n >= 1) prefix[level] = 2; if(n == count-1) prefix[level] = 3; } char *color_on = ""; char *color_off = ""; if(opt_color) { color_off = COLOR_RESET; if(size >= max_size / 8) color_on = COLOR_YELLOW; if(size >= max_size / 2) color_on = COLOR_RED; } printf("%s", color_on); char siz[32]; duc_human_size(&e->size, st, opt_bytes, siz, sizeof siz); printf("%*s", max_size_len, siz); printf("%s", color_off); if(opt_recursive && !opt_full_path) { int *p = prefix; while(*p) printf("%s", tree[*p++]); } putchar(' '); if(opt_full_path) { printf("%s", parent_path); parent_path_len += strlen(e->name) + 1; if(parent_path_len + 1 < DUC_PATH_MAX) { strcat(parent_path, e->name); strcat(parent_path, "/"); } } size_t l = string_width(e->name) + 1; printf("%s", e->name); if(opt_classify) { putchar(duc_file_type_char(e->type)); l++; } if(opt_graph) { for(;l<=max_name_len; l++) putchar(' '); int w = width - max_name_len - max_size_len - 5; w -= (level + 1) * 4; int l = max_size ? (w * size / max_size) : 0; int j; printf(" [%s", color_on); for(j=0; jtype == DUC_FILE_TYPE_DIR) { if(n == count-1) { prefix[level] = 5; } else { prefix[level] = 4; } duc_dir *dir2 = duc_dir_openent(dir, e); if(dir2) { ls_one(dir2, level+1, parent_path_len); duc_dir_close(dir2); } } if(opt_full_path) { parent_path_len -= strlen(e->name) + 1; parent_path[parent_path_len] = '\0'; } n++; } prefix[level] = 0; } /* * Show size of this directory only */ static void ls_dir_only(const char *path, duc_dir *dir) { struct duc_size size; char siz[32]; duc_size_type st = opt_count ? DUC_SIZE_TYPE_COUNT : opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; duc_dir_get_size(dir, &size); duc_human_size(&size, st, opt_bytes, siz, sizeof siz); printf("%s %s", siz, path); if(opt_classify) { putchar('/'); } putchar('\n'); } static void do_one(struct duc *duc, const char *path) { duc_dir *dir = duc_dir_open(duc, path); if(dir == NULL) { if(duc_error(duc) == DUC_E_PATH_NOT_FOUND) { duc_log(duc, DUC_LOG_FTL, "The requested path '%s' was not found in the database,", path); duc_log(duc, DUC_LOG_FTL, "Please run 'duc info' for a list of available directories."); } else { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); } exit(1); } if(opt_directory) { ls_dir_only(path, dir); } else { ls_one(dir, 0, 0); } duc_dir_close(dir); } static int ls_main(duc *duc, int argc, char **argv) { /* Get terminal width */ #ifdef TIOCGWINSZ if(isatty(STDOUT_FILENO)) { struct winsize w; int r = ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); if(r == 0) width = w.ws_col; } else { char *columns = getenv("COLUMNS"); if(columns) width = atoi(columns); } #endif /* Set locale for wide string calculations */ setlocale(LC_ALL, ""); /* Disable color if output is not a tty */ if(!isatty(1)) { opt_color = 0; } /* Disable graph when --full-path is requested, since there is no good * way to render this */ if(opt_full_path) { opt_graph = 0; } /* Open database */ int r = duc_open(duc, opt_database, DUC_OPEN_RO); if(r != DUC_OK) { return -1; } if(argc > 0) { int i; for(i=0; i #include #include #include #include #include #include #include #include #include #ifdef HAVE_TERMIOS_H #include #endif #include "cmd.h" #include "duc.h" #ifdef HAVE_LIBNCURSES #ifdef HAVE_NCURSES_NCURSES_H #include #else #include #endif #endif #ifdef HAVE_LIBNCURSESW #ifdef HAVE_NCURSESW_NCURSES_H #include #endif #ifdef HAVE_NCURSES_H #include #endif #endif enum { PAIR_SIZE = 1, PAIR_NAME, PAIR_CLASS, PAIR_GRAPH, PAIR_BAR, PAIR_CURSOR, }; static void help(void); static bool opt_apparent = false; static bool opt_count = false; static bool opt_bytes = false; static bool opt_graph = true; static bool opt_nocolor = false; static bool opt_name_sort = false; static char *opt_database = NULL; static int cols = 80; static int rows = 25; static duc_dir *do_dir(duc_dir *dir, int depth) { int top = 0; int cur = 0; for(;;) { int attr_size, attr_name, attr_class, attr_graph, attr_bar, attr_cursor; if(!opt_nocolor) { attr_size = COLOR_PAIR(PAIR_SIZE); attr_name = COLOR_PAIR(PAIR_NAME); attr_bar = COLOR_PAIR(PAIR_BAR); attr_cursor = COLOR_PAIR(PAIR_CURSOR); attr_graph = COLOR_PAIR(PAIR_GRAPH); attr_class = COLOR_PAIR(PAIR_CLASS); } else { attr_size = 0; attr_name = A_BOLD; attr_class = 0; attr_graph = 0; attr_bar = A_REVERSE; attr_cursor = A_REVERSE; use_default_colors(); } duc_size_type st = opt_count ? DUC_SIZE_TYPE_COUNT : opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; /* Iterate all dirents to find largest size */ duc_dir_seek(dir, 0); off_t size_max = 1; int dir_count = 0; int file_count = 0; struct duc_dirent *e; duc_sort sort = opt_name_sort ? DUC_SORT_NAME : DUC_SORT_SIZE; while( (e = duc_dir_read(dir, st, sort)) != NULL) { if(e->type == DUC_FILE_TYPE_DIR) { dir_count ++; } else { file_count ++; } off_t size = duc_get_size(&e->size, st); if(size > size_max) size_max = size; } int count = dir_count + file_count; int pgsize = rows - 2; /* Check boundaries */ if(cur < 0) cur = 0; if(cur > count - 1) cur = count - 1; if(cur < top) top = cur; if(cur > top + pgsize - 1) top = cur - pgsize + 1; if(top < 0) top = 0; /* Draw header */ char *path = duc_dir_get_path(dir); attrset(attr_bar); mvhline(0, 0, ' ', cols); mvprintw(0, 1, " %s ", path); attrset(0); free(path); /* Draw footer */ struct duc_size size; duc_dir_get_size(dir, &size); char siz[32], fcnt[32], dcnt[32]; duc_human_size(&size, st, opt_bytes, siz, sizeof siz); duc_human_number(file_count, opt_bytes, fcnt, sizeof fcnt); duc_human_number(dir_count, opt_bytes, dcnt, sizeof dcnt); attrset(attr_bar); mvhline(rows-1, 0, ' ', cols); if(st == DUC_SIZE_TYPE_COUNT) { mvprintw(rows-1, 0, " Total %s files, %s files and %s directories here", siz, fcnt, dcnt); } else { mvprintw(rows-1, 0, " Total %sB in %s files and %s directories (", siz, fcnt, dcnt); switch(st) { case DUC_SIZE_TYPE_APPARENT: printw("apparent size"); break; case DUC_SIZE_TYPE_ACTUAL: printw("actual size"); break; case DUC_SIZE_TYPE_COUNT: printw("file count"); break; } printw(")"); } attrset(0); /* Draw dirents */ duc_dir_seek(dir, top); int i; int y = 1; for(i=top; isize, st);; size_t max_size_len = opt_bytes ? 12 : 7; char class = duc_file_type_char(e->type); char siz[32]; duc_human_size(&e->size, st, opt_bytes, siz, sizeof siz); if(cur != i) attrset(attr_size); printw("%*s", max_size_len, siz); printw(" "); char *p = e->name; if(cur != i) attrset(attr_name); while(*p) { if(*(uint8_t *)p >= 32) { printw("%c", *p); } else { printw("^%c", *p+64); } p++; } if(cur != i) attrset(attr_class); printw("%c", class); int w = cols - 30; if(w > cols / 2) w = cols / 2; if(opt_graph && w > 2) { int j; off_t g = w * size / size_max; if(cur != i) attrset(attr_graph); mvprintw(y, cols - w - 4, " ["); for(j=0; j 0) { return NULL; } else { dir2 = duc_dir_openat(dir, ".."); if(dir2) { do_dir(dir2, 0); duc_dir_close(dir2); } } break; case KEY_RIGHT: case '\r': case '\n': duc_dir_seek(dir, cur); e = duc_dir_read(dir, st, sort); if(e && e->type == DUC_FILE_TYPE_DIR) { dir2 = duc_dir_openent(dir, e); if(dir2) { do_dir(dir2, depth + 1); duc_dir_close(dir2); } } break; case 'o': duc_dir_seek(dir, cur); e = duc_dir_read(dir, st, sort); if(e) { char cmd[DUC_PATH_MAX] = "true"; char *path = duc_dir_get_path(dir); if(path) { snprintf(cmd, sizeof(cmd), "xdg-open \"%s/%s\"", path, e->name); free(path); } endwin(); int ret = system(cmd); if (ret == -1) { printw("Cannot run command: %s", cmd); } doupdate(); } break; default: break; } } } static void bye(void) { endwin(); } static int ui_main(duc *duc, int argc, char **argv) { char *path = "."; if(argc > 0) path = argv[0]; if(getenv("NO_COLOR")) { opt_nocolor = true; } int r = duc_open(duc, opt_database, DUC_OPEN_RO); if(r != DUC_OK) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } duc_dir *dir = duc_dir_open(duc, path); if(dir == NULL) { if(duc_error(duc) == DUC_E_PATH_NOT_FOUND) { duc_log(duc, DUC_LOG_FTL, "The requested path '%s' was not found in the database,", path); duc_log(duc, DUC_LOG_FTL, "Please run 'duc info' for a list of available directories."); } else { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); } return -1; } setlocale(LC_CTYPE, ""); initscr(); atexit(bye); cbreak(); noecho(); nonl(); keypad(stdscr, 1); //halfdelay(1); curs_set(0); start_color(); getmaxyx(stdscr, rows, cols); init_pair(PAIR_SIZE, COLOR_WHITE, COLOR_BLACK); init_pair(PAIR_NAME, COLOR_GREEN, COLOR_BLACK); init_pair(PAIR_CLASS, COLOR_YELLOW, COLOR_BLACK); init_pair(PAIR_GRAPH, COLOR_CYAN, COLOR_BLACK); init_pair(PAIR_BAR, COLOR_WHITE, COLOR_BLUE); init_pair(PAIR_CURSOR, COLOR_BLACK, COLOR_CYAN); do_dir(dir, 0); duc_dir_close(dir); duc_close(duc); return 0; } static struct ducrc_option options[] = { { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "show apparent instead of actual file size" }, { &opt_bytes, "bytes", 'b', DUCRC_TYPE_BOOL, "show file size in exact number of bytes" }, { &opt_count, "count", 0, DUCRC_TYPE_BOOL, "show number of files instead of file size" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, { &opt_name_sort, "name-sort", 'n', DUCRC_TYPE_BOOL, "sort output by name instead of by size" }, { &opt_nocolor, "no-color", 0 , DUCRC_TYPE_BOOL, "do not use colors on terminal output" }, { NULL } }; struct cmd cmd_ui = { .name = "ui", .descr_short = "Interactive ncurses user interface", .usage = "[options] [PATH]", .main = ui_main, .options = options, .descr_long = "The 'ui' subcommand queries the duc database and runs an interactive ncurses\n" "utility for exploring the disk usage of the given path. If no path is given the\n" "current working directory is explored.\n" "\n" "The following keys can be used to navigate and alter the file system:\n" "\n" " up, pgup, j: move cursor up\n" " down, pgdn, k: move cursor down\n" " home, 0: move cursor to top\n" " end, $: move cursor to bottom\n" " left, backspace: go up to parent directory (..)\n" " right, enter: descent into selected directory\n" " a: toggle between actual and apparent disk usage\n" " b: toggle between exact and abbreviated sizes\n" " c: Toggle between file size and file count\n" " h: show help. press 'q' to return to the main screen\n" " n: toggle sort order between 'size' and 'name'\n" " o: try to open the file using xdg-open\n" " q, escape: quit\n" }; static void help(void) { attrset(0); refresh(); FILE *f = popen("clear; less -", "w"); fputs(cmd_ui.descr_long, f); fclose(f); erase(); redrawwin(stdscr); touchwin(stdscr); refresh(); } #endif /* * End */ zevv-duc-b8f9659/src/duc/cmd-xml.c000066400000000000000000000066341426703022500167140ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include "cmd.h" #include "duc.h" static bool opt_apparent = false; static char *opt_database = NULL; static double opt_min_size = 0; static bool opt_exclude_files = false; static void indent(int n) { int i; for(i=0; i': printf(">"); break; case '&': printf("&"); break; case '"': printf("""); break; case '\t': putchar('\t'); break; case '\n': putchar('\n'); break; case '\r': putchar('\r'); break; default: if(*s >= 0 && *s < 32) { printf("#x%02x", *(uint8_t *)s); } else { putchar(*s); } break; } s++; } } static void dump(duc *duc, duc_dir *dir, int depth, off_t min_size, int ex_files) { struct duc_dirent *e; duc_size_type st = opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; while( (e = duc_dir_read(dir, DUC_SIZE_TYPE_ACTUAL, DUC_SORT_SIZE)) != NULL) { off_t size = duc_get_size(&e->size, st); if(e->type == DUC_FILE_TYPE_DIR && size>= min_size) { duc_dir *dir_child = duc_dir_openent(dir, e); if(dir_child) { indent(depth); printf("name); printf("\" size_apparent=\"%jd\" size_actual=\"%jd\" count=\"%jd\">\n", (intmax_t)e->size.apparent, (intmax_t)e->size.actual, (intmax_t)e->size.count); dump(duc, dir_child, depth + 1, min_size, ex_files); indent(depth); printf("\n"); } duc_dir_close(dir_child); } else { if(!ex_files && size >= min_size) { indent(depth); printf("name); printf("\" size_apparent=\"%jd\" size_actual=\"%jd\" />\n", (intmax_t)e->size.apparent, (intmax_t)e->size.actual); } } } } static int xml_main(duc *duc, int argc, char **argv) { char *path = "."; if(argc > 0) path = argv[0]; int r = duc_open(duc, opt_database, DUC_OPEN_RO); if(r != DUC_OK) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } duc_dir *dir = duc_dir_open(duc, path); if(dir == NULL) { duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc)); return -1; } struct duc_size size; duc_dir_get_size(dir, &size); printf("\n"); printf("\n", path, (intmax_t)size.apparent, (intmax_t)size.actual, (intmax_t)size.count); dump(duc, dir, 1, (off_t)opt_min_size, opt_exclude_files); printf("\n"); duc_dir_close(dir); duc_close(duc); return 0; } static struct ducrc_option options[] = { { &opt_apparent, "apparent", 'a', DUCRC_TYPE_BOOL, "interpret min_size/-s value as apparent size" }, { &opt_database, "database", 'd', DUCRC_TYPE_STRING, "select database file to use [~/.duc.db]" }, { &opt_exclude_files, "exclude-files", 'x', DUCRC_TYPE_BOOL, "exclude file from xml output, only include directories" }, { &opt_min_size, "min_size", 's', DUCRC_TYPE_DOUBLE, "specify min size for files or directories" }, { NULL } }; struct cmd cmd_xml = { .name = "xml", .descr_short = "Dump XML output", .usage = "[options] [PATH]", .main = xml_main, .options = options, }; /* * End */ zevv-duc-b8f9659/src/duc/cmd.h000066400000000000000000000005161426703022500161140ustar00rootroot00000000000000#ifndef ps_h #define ps_h #include #include #include "duc.h" #include "ducrc.h" struct cmd { char *name; int (*init)(duc *duc, int argc, char **argv); int (*main)(duc *duc, int argc, char **argv); char *descr_short; char *descr_long; char *usage; struct ducrc_option *options; int hidden; }; #endif zevv-duc-b8f9659/src/duc/ducrc.c000066400000000000000000000107621426703022500164500ustar00rootroot00000000000000 #include #include #include #include #include #include #include "private.h" #include "duc.h" #include "ducrc.h" #define MAX_OPTIONS 64 struct ducrc { char *section; int noptions; struct ducrc_option *option_list[MAX_OPTIONS]; }; struct ducrc *ducrc_new(const char *section) { struct ducrc *ducrc; ducrc = duc_malloc(sizeof *ducrc); ducrc->noptions = 0; ducrc->section = duc_strdup(section); return ducrc; } void ducrc_free(struct ducrc *ducrc) { duc_free(ducrc->section); duc_free(ducrc); } void ducrc_add_options(struct ducrc *ducrc, struct ducrc_option *o) { while(o && o->longopt) { if(ducrc->noptions < MAX_OPTIONS) { ducrc->option_list[ducrc->noptions++] = o; } o++; } } /* * Trim whitespace off string. Modifies the string, and returns pointer * to first non-whitespace char. */ static char *trim(char *s) { char *e; while(isspace(*s)) s++; if(*s == 0) return s; e = s + strlen(s) - 1; while(e > s && isspace(*e)) e--; *(e+1) = 0; return s; } static void handle_opt(struct ducrc *ducrc, char shortopt, const char *longopt, const char *val) { struct ducrc_option **os = ducrc->option_list; struct ducrc_option *o = NULL; bool *v_bool; int *v_int; double *v_double; const char **v_string; int i; void (*fn)(const char *val); /* Find option */ for(i=0; inoptions; i++) { o = *os; if(shortopt && shortopt == o->shortopt) goto found; if(longopt && strcmp(longopt, o->longopt) == 0) goto found; os++; } if(shortopt) { fprintf(stderr, "Unknown option '%c'\n", shortopt); } else { fprintf(stderr, "Unknown option '%s'\n", longopt); } return; found: /* Handle option */ switch(o->type) { case DUCRC_TYPE_BOOL: v_bool = o->ptr; *v_bool = 1; break; case DUCRC_TYPE_INT: v_int = o->ptr; *v_int = atoi(val); break; case DUCRC_TYPE_DOUBLE: v_double = o->ptr; *v_double = atof(val); break; case DUCRC_TYPE_STRING: v_string = o->ptr; *v_string = strdup(val); break; case DUCRC_TYPE_FUNC: fn = o->ptr; fn(val); break; } } int ducrc_read(struct ducrc *ducrc, const char *path) { FILE *f = fopen(path, "r"); if(f == NULL) { //duc_log(NULL, DUC_LOG_DBG, "Not reading configuration from '%s': %s", path, strerror(errno)); return -1; } char section[256] = ""; char buf[256]; while(fgets(buf, sizeof buf, f) != NULL) { char *l = trim(buf); char *p; /* Strip newlines and comments */ p = strchr(l, '#'); if(p) *p = '\0'; p = strchr(l, '\n'); if(p) *p = '\0'; p = strchr(l, '\r'); if(p) *p = '\0'; /* section? */ if(l[0] == '[') { p = strchr(l, ']'); if(p) { *p = 0; strncpy(section, l+1, sizeof(section)); } continue; } if(strlen(section) == 0 || strcmp(section, "global") == 0 || strcmp(section, ducrc->section) == 0) { /* key + value ? */ p = strchr(l, ' '); if(p) { *p = '\0'; char *longopt = trim(l); char *val = trim(p + 1); handle_opt(ducrc, 0, longopt, val); continue; } /* longopt only */ char *longopt = trim(l); if(strlen(longopt) > 0) { handle_opt(ducrc, 0, longopt, NULL); } } } fclose(f); return 0; } /* * I tried to implement a standard-style getopt_long function for parsing the * command line into duc options. This is hard work, and it has been a long * day. Instead of parsing myself, this function creates a 'struct option' list * from the duc options and relies on POSIX getopt_long() to do the hard work. */ int ducrc_getopt(struct ducrc *ducrc, int *argc, char **argv[]) { struct option longopts[MAX_OPTIONS + 1] = { { NULL } }; char optstr[MAX_OPTIONS*2] = ""; int n = 0; int l = 0; /* Prepare a list of options for getopt_long() */ struct ducrc_option **os = ducrc->option_list; int i; for(i=0; inoptions; i++) { struct ducrc_option *o = *os; longopts[n].name = o->longopt; if(o->shortopt) { l += sprintf(optstr+l, "%c", o->shortopt); longopts[n].val = o->shortopt; } if(o->type == DUCRC_TYPE_BOOL) { longopts[n].has_arg = no_argument; } else { longopts[n].has_arg = required_argument; if(o->shortopt) l += sprintf(optstr+l, ":"); } n++; os++; } /* Rely on libc to do the hard work */ int c; int idx; if(*argc > 1) optind = 2; while( ( c = getopt_long(*argc, *argv, optstr, longopts, &idx)) != -1) { if(c == '?') return -1; handle_opt(ducrc, c, c ? 0 : longopts[idx].name, optarg); } *argc -= optind; *argv += optind; return 0; } /* * End */ zevv-duc-b8f9659/src/duc/ducrc.h000066400000000000000000000011371426703022500164510ustar00rootroot00000000000000#ifndef ducrc_h #define ducrc_h enum ducrc_type { DUCRC_TYPE_BOOL, DUCRC_TYPE_INT, DUCRC_TYPE_DOUBLE, DUCRC_TYPE_STRING, DUCRC_TYPE_FUNC, }; struct ducrc_option { void *ptr; const char *longopt; char shortopt; enum ducrc_type type; const char *descr_short; const char *descr_long; }; struct ducrc; struct ducrc *ducrc_new(const char *section); void ducrc_free(struct ducrc *ducrc); void ducrc_add_options(struct ducrc *ducrc, struct ducrc_option *option_list); int ducrc_read(struct ducrc *ducrc, const char *path); int ducrc_getopt(struct ducrc *ducrc, int *argc, char **argv[]); #endif zevv-duc-b8f9659/src/duc/main.c000066400000000000000000000204161426703022500162710ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include #include #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_TERMIOS_H #include #endif #ifdef HAVE_TERMIOS_H #include #endif #include "duc.h" #include "db.h" #include "cmd.h" #include "ducrc.h" extern struct cmd cmd_help; extern struct cmd cmd_info; extern struct cmd cmd_index; extern struct cmd cmd_manual; extern struct cmd cmd_ls; extern struct cmd cmd_gui; extern struct cmd cmd_guigl; extern struct cmd cmd_graph; extern struct cmd cmd_xml; extern struct cmd cmd_json; extern struct cmd cmd_cgi; extern struct cmd cmd_ui; struct cmd *cmd_list[] = { &cmd_help, &cmd_index, &cmd_info, &cmd_manual, &cmd_ls, &cmd_xml, &cmd_json, &cmd_graph, &cmd_cgi, #ifdef ENABLE_X11 &cmd_gui, #endif #ifdef ENABLE_OPENGL &cmd_guigl, #endif #ifdef ENABLE_UI &cmd_ui, #endif }; #define SUBCOMMAND_COUNT (sizeof(cmd_list) / sizeof(cmd_list[0])) static struct cmd *find_cmd_by_name(const char *name); static void help_cmd(struct cmd *cmd); static void show_version(void); static int opt_debug = 0; static int opt_verbose = 0; static int opt_quiet = 0; static int opt_help = 0; static int opt_version = 0; static struct ducrc_option global_options[] = { { &opt_debug, "debug", 0, DUCRC_TYPE_BOOL, "increase verbosity to debug level" }, { &opt_help, "help", 'h', DUCRC_TYPE_BOOL, "show help" }, { &opt_quiet, "quiet", 'q', DUCRC_TYPE_BOOL, "quiet mode, do not print any warning" }, { &opt_verbose, "verbose", 'v', DUCRC_TYPE_BOOL, "increase verbosity" }, { &opt_version, "version", 0, DUCRC_TYPE_BOOL, "output version information and exit" }, { NULL } }; int main(int argc, char **argv) { int r; /* Open duc context */ duc *duc = duc_new(); if(duc == NULL) { duc_log(duc, DUC_LOG_FTL, "Error creating duc context"); return -1; } /* Find subcommand */ struct cmd *cmd = NULL; if(argc >= 2) { cmd = find_cmd_by_name(argv[1]); if(strcmp(argv[1], "--version") == 0) opt_version = 1; } if(cmd == NULL) { if(getenv("GATEWAY_INTERFACE")) { cmd = &cmd_cgi; } else { cmd = &cmd_help; } } /* Register options */ struct ducrc *ducrc = ducrc_new(cmd->name); ducrc_add_options(ducrc, global_options); ducrc_add_options(ducrc, cmd->options); /* Call init function */ if(cmd->init) { int r = cmd->init(duc, argc, argv); if(r != 0) exit(r); } /* Read configuration files from /etc/ducrc, ~/.config/duc/ducrc, * ~/.ducrc and .ducrc and finally from the command line. Newer options * will override older options */ ducrc_read(ducrc, "/etc/ducrc"); char *home = getenv("HOME"); if(home) { char tmp[DUC_PATH_MAX]; snprintf(tmp, sizeof(tmp), "%s/.config/duc/ducrc", home); ducrc_read(ducrc, tmp); snprintf(tmp, sizeof(tmp), "%s/.ducrc", home); ducrc_read(ducrc, tmp); } ducrc_read(ducrc, "./.ducrc"); r = ducrc_getopt(ducrc, &argc, &argv); /* Error detected on option parsing? */ if(r == -1) { fprintf(stderr, "Try 'duc --help' for more information.\n"); exit(1); } /* Version requested? */ if(opt_version) { show_version(); exit(0); } /* Help requested ? */ if(opt_help) { help_cmd(cmd); return(EXIT_SUCCESS); } /* Set log level */ duc_log_level log_level = DUC_LOG_WRN; if(opt_quiet) log_level = DUC_LOG_FTL; if(opt_verbose) log_level = DUC_LOG_INF; if(opt_debug) log_level = DUC_LOG_DMP; duc_set_log_level(duc, log_level); /* Handle command */ r = cmd->main(duc, argc, argv); if(r == -2) help_cmd(cmd); /* Cleanup */ duc_del(duc); ducrc_free(ducrc); exit((r == 0) ? EXIT_SUCCESS : EXIT_FAILURE); } static struct cmd *find_cmd_by_name(const char *name) { size_t i; for(i=0; iname, name) == 0) { return cmd; } } return NULL; } static void printi(const char *s, int pos, int indent, int max) { const char *p1 = s; const char *p2 = s; int i; while(*p1) { while(*p2 && !isspace(*p2)) p2++; int l = p2 - p1; if(pos + l >= max) { putchar('\n'); for(i=0; ilongopt) { char s[4] = ""; char l[20] = ""; if(o->shortopt) snprintf(s, sizeof(s), "-%c,", o->shortopt); if(o->type != DUCRC_TYPE_BOOL) { snprintf(l, sizeof(l), "%s=VAL", o->longopt); } else { snprintf(l, sizeof(l), "%s", o->longopt); } printf(" %-4.4s --%-20.20s", s, l); if(o->descr_short) printf("%s", o->descr_short); if(show_long && o->descr_long) { printf(". "); printi(o->descr_long, 29 + strlen(o->descr_short), 29, width-2); } printf("\n"); o++; } } static void help_cmd(struct cmd *cmd) { if(cmd->usage) { printf("usage: duc %s %s\n", cmd->name, cmd->usage); printf("\n"); } if(cmd->descr_short) { printf("%s.\n", cmd->descr_short); printf("\n"); } printf("Options for the command '%s':\n", cmd->name); show_options(cmd->options, 1); printf("\n"); printf("Global options:\n"); show_options(global_options, 1); if(cmd->descr_long) { printf("\n%s", cmd->descr_long); } } int opt_all = 0; static int help_main(duc *duc, int argc, char **argv) { struct cmd *cmd = NULL; if(argc > 0) cmd = find_cmd_by_name(argv[0]); if(cmd) { help_cmd(cmd); } else { printf("usage: duc [options] [args]\n" "\n" "Available subcommands:\n" "\n" ); size_t i; for(i=0; ihidden) continue; if(opt_all) { printf("duc %s %s: %s\n", c->name, c->usage, c->descr_short); printf("\n"); show_options(c->options, 0); printf("\n"); } else { printf(" %-10.10s: %s\n", c->name, c->descr_short); } } if(!opt_all) { printf("\n"); printf("Global options:\n"); show_options(global_options, 1); printf( "\n" "Use 'duc help ' or 'duc -h' for a complete list of all\n" "options and detailed description of the subcommand.\n" "\n" "Use 'duc help --all' for a complete list of all options for all subcommands.\n" ); } } return 0; } static void show_options_manual(struct ducrc_option *o) { while(o && o->longopt) { printf(" * "); if(o->shortopt) printf("`-%c`, ", o->shortopt); if(o->type != DUCRC_TYPE_BOOL) { printf("`--%s=VAL`:", o->longopt); } else { printf("`--%s`:", o->longopt); } printf("\n"); printf(" %s", o->descr_short); if(o->descr_long) { printf(". %s\n", o->descr_long); } printf("\n"); printf("\n"); o++; } } static int manual_main(duc *duc, int argc, char **argv) { size_t i; printf("### Global options\n"); printf("\n"); printf("These options apply to all Duc subcommands:\n"); printf("\n"); show_options_manual(global_options); for(i=0; ihidden) continue; printf("### duc %s\n", c->name); printf("\n"); if(c->descr_long) { printf("%s\n", c->descr_long); printf("\n"); } printf("Options for command `duc %s %s`:\n", c->name, c->usage); printf("\n"); show_options_manual(c->options); } return 0; } static void show_version(void) { printf("duc version: %s\n", PACKAGE_VERSION); printf("options: "); #ifdef ENABLE_CAIRO printf("cairo "); #endif #ifdef ENABLE_OPENGL printf("opengl "); #endif #ifdef ENABLE_X11 printf("x11 "); #endif #ifdef ENABLE_UI printf("ui "); #endif printf(DB_BACKEND "\n"); exit(EXIT_SUCCESS); } static struct ducrc_option help_options[] = { { &opt_all, "all", 'a', DUCRC_TYPE_BOOL, "show complete help for all commands" }, { NULL } }; struct cmd cmd_help = { .name = "help", .descr_short = "Show help", .usage = "[options]", .main = help_main, .options = help_options, }; struct cmd cmd_manual = { .name = "manual", .descr_short = "Show manual", .usage = "", .main = manual_main, .hidden = 1, }; /* * End */ zevv-duc-b8f9659/src/glad/000077500000000000000000000000001426703022500153325ustar00rootroot00000000000000zevv-duc-b8f9659/src/glad/KHR/000077500000000000000000000000001426703022500157565ustar00rootroot00000000000000zevv-duc-b8f9659/src/glad/KHR/khrplatform.h000066400000000000000000000234461426703022500204710ustar00rootroot00000000000000#ifndef __khrplatform_h_ #define __khrplatform_h_ /* ** Copyright (c) 2008-2009 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the ** "Materials"), to deal in the Materials without restriction, including ** without limitation the rights to use, copy, modify, merge, publish, ** distribute, sublicense, and/or sell copies of the Materials, and to ** permit persons to whom the Materials are furnished to do so, subject to ** the following conditions: ** ** The above copyright notice and this permission notice shall be included ** in all copies or substantial portions of the Materials. ** ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ /* Khronos platform-specific types and definitions. * * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ * * Adopters may modify this file to suit their platform. Adopters are * encouraged to submit platform specific modifications to the Khronos * group so that they can be included in future versions of this file. * Please submit changes by sending them to the public Khronos Bugzilla * (http://khronos.org/bugzilla) by filing a bug against product * "Khronos (general)" component "Registry". * * A predefined template which fills in some of the bug fields can be * reached using http://tinyurl.com/khrplatform-h-bugreport, but you * must create a Bugzilla login first. * * * See the Implementer's Guidelines for information about where this file * should be located on your system and for more details of its use: * http://www.khronos.org/registry/implementers_guide.pdf * * This file should be included as * #include * by Khronos client API header files that use its types and defines. * * The types in khrplatform.h should only be used to define API-specific types. * * Types defined in khrplatform.h: * khronos_int8_t signed 8 bit * khronos_uint8_t unsigned 8 bit * khronos_int16_t signed 16 bit * khronos_uint16_t unsigned 16 bit * khronos_int32_t signed 32 bit * khronos_uint32_t unsigned 32 bit * khronos_int64_t signed 64 bit * khronos_uint64_t unsigned 64 bit * khronos_intptr_t signed same number of bits as a pointer * khronos_uintptr_t unsigned same number of bits as a pointer * khronos_ssize_t signed size * khronos_usize_t unsigned size * khronos_float_t signed 32 bit floating point * khronos_time_ns_t unsigned 64 bit time in nanoseconds * khronos_utime_nanoseconds_t unsigned time interval or absolute time in * nanoseconds * khronos_stime_nanoseconds_t signed time interval in nanoseconds * khronos_boolean_enum_t enumerated boolean type. This should * only be used as a base type when a client API's boolean type is * an enum. Client APIs which use an integer or other type for * booleans cannot use this as the base type for their boolean. * * Tokens defined in khrplatform.h: * * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. * * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. * * Calling convention macros defined in this file: * KHRONOS_APICALL * KHRONOS_APIENTRY * KHRONOS_APIATTRIBUTES * * These may be used in function prototypes as: * * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( * int arg1, * int arg2) KHRONOS_APIATTRIBUTES; */ /*------------------------------------------------------------------------- * Definition of KHRONOS_APICALL *------------------------------------------------------------------------- * This precedes the return type of the function in the function prototype. */ #if defined(_WIN32) && !defined(__SCITECH_SNAP__) # define KHRONOS_APICALL __declspec(dllimport) #elif defined (__SYMBIAN32__) # define KHRONOS_APICALL IMPORT_C #else # define KHRONOS_APICALL #endif /*------------------------------------------------------------------------- * Definition of KHRONOS_APIENTRY *------------------------------------------------------------------------- * This follows the return type of the function and precedes the function * name in the function prototype. */ #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) /* Win32 but not WinCE */ # define KHRONOS_APIENTRY __stdcall #else # define KHRONOS_APIENTRY #endif /*------------------------------------------------------------------------- * Definition of KHRONOS_APIATTRIBUTES *------------------------------------------------------------------------- * This follows the closing parenthesis of the function prototype arguments. */ #if defined (__ARMCC_2__) #define KHRONOS_APIATTRIBUTES __softfp #else #define KHRONOS_APIATTRIBUTES #endif /*------------------------------------------------------------------------- * basic type definitions *-----------------------------------------------------------------------*/ #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) /* * Using */ #include typedef int32_t khronos_int32_t; typedef uint32_t khronos_uint32_t; typedef int64_t khronos_int64_t; typedef uint64_t khronos_uint64_t; #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 #elif defined(__VMS ) || defined(__sgi) /* * Using */ #include typedef int32_t khronos_int32_t; typedef uint32_t khronos_uint32_t; typedef int64_t khronos_int64_t; typedef uint64_t khronos_uint64_t; #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 #elif defined(_WIN32) && !defined(__SCITECH_SNAP__) /* * Win32 */ typedef __int32 khronos_int32_t; typedef unsigned __int32 khronos_uint32_t; typedef __int64 khronos_int64_t; typedef unsigned __int64 khronos_uint64_t; #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 #elif defined(__sun__) || defined(__digital__) /* * Sun or Digital */ typedef int khronos_int32_t; typedef unsigned int khronos_uint32_t; #if defined(__arch64__) || defined(_LP64) typedef long int khronos_int64_t; typedef unsigned long int khronos_uint64_t; #else typedef long long int khronos_int64_t; typedef unsigned long long int khronos_uint64_t; #endif /* __arch64__ */ #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 #elif 0 /* * Hypothetical platform with no float or int64 support */ typedef int khronos_int32_t; typedef unsigned int khronos_uint32_t; #define KHRONOS_SUPPORT_INT64 0 #define KHRONOS_SUPPORT_FLOAT 0 #else /* * Generic fallback */ #include typedef int32_t khronos_int32_t; typedef uint32_t khronos_uint32_t; typedef int64_t khronos_int64_t; typedef uint64_t khronos_uint64_t; #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 #endif /* * Types that are (so far) the same on all platforms */ typedef signed char khronos_int8_t; typedef unsigned char khronos_uint8_t; typedef signed short int khronos_int16_t; typedef unsigned short int khronos_uint16_t; /* * Types that differ between LLP64 and LP64 architectures - in LLP64, * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears * to be the only LLP64 architecture in current use. */ #ifdef _WIN64 typedef signed long long int khronos_intptr_t; typedef unsigned long long int khronos_uintptr_t; typedef signed long long int khronos_ssize_t; typedef unsigned long long int khronos_usize_t; #else typedef signed long int khronos_intptr_t; typedef unsigned long int khronos_uintptr_t; typedef signed long int khronos_ssize_t; typedef unsigned long int khronos_usize_t; #endif #if KHRONOS_SUPPORT_FLOAT /* * Float type */ typedef float khronos_float_t; #endif #if KHRONOS_SUPPORT_INT64 /* Time types * * These types can be used to represent a time interval in nanoseconds or * an absolute Unadjusted System Time. Unadjusted System Time is the number * of nanoseconds since some arbitrary system event (e.g. since the last * time the system booted). The Unadjusted System Time is an unsigned * 64 bit value that wraps back to 0 every 584 years. Time intervals * may be either signed or unsigned. */ typedef khronos_uint64_t khronos_utime_nanoseconds_t; typedef khronos_int64_t khronos_stime_nanoseconds_t; #endif /* * Dummy value used to pad enum types to 32 bits. */ #ifndef KHRONOS_MAX_ENUM #define KHRONOS_MAX_ENUM 0x7FFFFFFF #endif /* * Enumerated boolean type * * Values other than zero should be considered to be true. Therefore * comparisons should not be made against KHRONOS_TRUE. */ typedef enum { KHRONOS_FALSE = 0, KHRONOS_TRUE = 1, KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM } khronos_boolean_enum_t; #endif /* __khrplatform_h_ */ zevv-duc-b8f9659/src/glad/glad.c000066400000000000000000000443051426703022500164130ustar00rootroot00000000000000#include #include #include struct gladGLversionStruct GLVersion; #if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) #define _GLAD_IS_SOME_NEW_VERSION 1 #endif int GLAD_GL_ES_VERSION_2_0; PFNGLFLUSHPROC glad_glFlush; PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; PFNGLCLEARCOLORPROC glad_glClearColor; PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; PFNGLLINKPROGRAMPROC glad_glLinkProgram; PFNGLBINDTEXTUREPROC glad_glBindTexture; PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; PFNGLGETSTRINGPROC glad_glGetString; PFNGLDETACHSHADERPROC glad_glDetachShader; PFNGLLINEWIDTHPROC glad_glLineWidth; PFNGLUNIFORM2FVPROC glad_glUniform2fv; PFNGLCOMPILESHADERPROC glad_glCompileShader; PFNGLDELETETEXTURESPROC glad_glDeleteTextures; PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; PFNGLDEPTHRANGEFPROC glad_glDepthRangef; PFNGLUNIFORM4IVPROC glad_glUniform4iv; PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; PFNGLCLEARSTENCILPROC glad_glClearStencil; PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; PFNGLGENTEXTURESPROC glad_glGenTextures; PFNGLDEPTHFUNCPROC glad_glDepthFunc; PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; PFNGLUNIFORM1FPROC glad_glUniform1f; PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; PFNGLCREATESHADERPROC glad_glCreateShader; PFNGLISBUFFERPROC glad_glIsBuffer; PFNGLUNIFORM1IPROC glad_glUniform1i; PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; PFNGLDISABLEPROC glad_glDisable; PFNGLUNIFORM2IPROC glad_glUniform2i; PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; PFNGLCOLORMASKPROC glad_glColorMask; PFNGLHINTPROC glad_glHint; PFNGLBLENDEQUATIONPROC glad_glBlendEquation; PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; PFNGLCULLFACEPROC glad_glCullFace; PFNGLUNIFORM4FVPROC glad_glUniform4fv; PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; PFNGLATTACHSHADERPROC glad_glAttachShader; PFNGLUNIFORM3IPROC glad_glUniform3i; PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; PFNGLSHADERBINARYPROC glad_glShaderBinary; PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; PFNGLUNIFORM3FPROC glad_glUniform3f; PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; PFNGLDRAWELEMENTSPROC glad_glDrawElements; PFNGLUNIFORM2IVPROC glad_glUniform2iv; PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; PFNGLUNIFORM1IVPROC glad_glUniform1iv; PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; PFNGLGETSHADERIVPROC glad_glGetShaderiv; PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; PFNGLBLENDCOLORPROC glad_glBlendColor; PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; PFNGLDEPTHMASKPROC glad_glDepthMask; PFNGLUSEPROGRAMPROC glad_glUseProgram; PFNGLSHADERSOURCEPROC glad_glShaderSource; PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; PFNGLDRAWARRAYSPROC glad_glDrawArrays; PFNGLISPROGRAMPROC glad_glIsProgram; PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; PFNGLUNIFORM4IPROC glad_glUniform4i; PFNGLCLEARPROC glad_glClear; PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; PFNGLUNIFORM2FPROC glad_glUniform2f; PFNGLACTIVETEXTUREPROC glad_glActiveTexture; PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; PFNGLBINDBUFFERPROC glad_glBindBuffer; PFNGLISENABLEDPROC glad_glIsEnabled; PFNGLSTENCILOPPROC glad_glStencilOp; PFNGLREADPIXELSPROC glad_glReadPixels; PFNGLUNIFORM4FPROC glad_glUniform4f; PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; PFNGLUNIFORM3FVPROC glad_glUniform3fv; PFNGLBUFFERDATAPROC glad_glBufferData; PFNGLGETERRORPROC glad_glGetError; PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; PFNGLGETFLOATVPROC glad_glGetFloatv; PFNGLUNIFORM3IVPROC glad_glUniform3iv; PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; PFNGLSTENCILFUNCPROC glad_glStencilFunc; PFNGLGETINTEGERVPROC glad_glGetIntegerv; PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; PFNGLUNIFORM1FVPROC glad_glUniform1fv; PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; PFNGLTEXIMAGE2DPROC glad_glTexImage2D; PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; PFNGLSTENCILMASKPROC glad_glStencilMask; PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; PFNGLISTEXTUREPROC glad_glIsTexture; PFNGLISSHADERPROC glad_glIsShader; PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; PFNGLENABLEPROC glad_glEnable; PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; PFNGLGENBUFFERSPROC glad_glGenBuffers; PFNGLFINISHPROC glad_glFinish; PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; PFNGLDELETESHADERPROC glad_glDeleteShader; PFNGLBLENDFUNCPROC glad_glBlendFunc; PFNGLCREATEPROGRAMPROC glad_glCreateProgram; PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; PFNGLVIEWPORTPROC glad_glViewport; PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; PFNGLTEXPARAMETERFPROC glad_glTexParameterf; PFNGLTEXPARAMETERIPROC glad_glTexParameteri; PFNGLFRONTFACEPROC glad_glFrontFace; PFNGLCLEARDEPTHFPROC glad_glClearDepthf; PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; PFNGLSCISSORPROC glad_glScissor; PFNGLGETBOOLEANVPROC glad_glGetBooleanv; PFNGLPIXELSTOREIPROC glad_glPixelStorei; PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; static void load_GL_ES_VERSION_2_0(GLADloadproc load) { if(!GLAD_GL_ES_VERSION_2_0) return; glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture"); glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader"); glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation"); glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer"); glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture"); glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate"); glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc"); glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate"); glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData"); glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData"); glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); glad_glClear = (PFNGLCLEARPROC)load("glClear"); glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor"); glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC)load("glClearDepthf"); glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil"); glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask"); glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader"); glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D"); glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D"); glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram"); glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader"); glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers"); glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram"); glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader"); glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc"); glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask"); glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC)load("glDepthRangef"); glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader"); glad_glDisable = (PFNGLDISABLEPROC)load("glDisable"); glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray"); glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); glad_glEnable = (PFNGLENABLEPROC)load("glEnable"); glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray"); glad_glFinish = (PFNGLFINISHPROC)load("glFinish"); glad_glFlush = (PFNGLFLUSHPROC)load("glFlush"); glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace"); glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers"); glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib"); glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform"); glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders"); glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation"); glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv"); glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv"); glad_glGetError = (PFNGLGETERRORPROC)load("glGetError"); glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv"); glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv"); glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv"); glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog"); glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv"); glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog"); glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)load("glGetShaderPrecisionFormat"); glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource"); glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv"); glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv"); glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv"); glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv"); glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation"); glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv"); glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv"); glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv"); glad_glHint = (PFNGLHINTPROC)load("glHint"); glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer"); glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram"); glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader"); glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth"); glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram"); glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei"); glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels"); glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)load("glReleaseShaderCompiler"); glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage"); glad_glScissor = (PFNGLSCISSORPROC)load("glScissor"); glad_glShaderBinary = (PFNGLSHADERBINARYPROC)load("glShaderBinary"); glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource"); glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc"); glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate"); glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask"); glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate"); glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp"); glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate"); glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D"); glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf"); glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv"); glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri"); glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv"); glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D"); glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f"); glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv"); glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i"); glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv"); glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f"); glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv"); glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i"); glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv"); glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f"); glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv"); glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i"); glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv"); glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f"); glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv"); glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i"); glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv"); glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv"); glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv"); glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv"); glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram"); glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram"); glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f"); glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv"); glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f"); glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv"); glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f"); glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv"); glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f"); glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv"); glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer"); glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); } static void find_extensionsGLES2(void) { } static void find_coreGLES2(void) { /* Thank you @elmindreda * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 * https://github.com/glfw/glfw/blob/master/src/context.c#L36 */ int i, major, minor; const char* version; const char* prefixes[] = { "OpenGL ES-CM ", "OpenGL ES-CL ", "OpenGL ES ", NULL }; version = (const char*) glGetString(GL_VERSION); if (!version) return; for (i = 0; prefixes[i]; i++) { const size_t length = strlen(prefixes[i]); if (strncmp(version, prefixes[i], length) == 0) { version += length; break; } } /* PR #18 */ #ifdef _MSC_VER sscanf_s(version, "%d.%d", &major, &minor); #else sscanf(version, "%d.%d", &major, &minor); #endif GLVersion.major = major; GLVersion.minor = minor; GLAD_GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; } int gladLoadGLES2Loader(GLADloadproc load) { GLVersion.major = 0; GLVersion.minor = 0; glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); if(glGetString == NULL) return 0; if(glGetString(GL_VERSION) == NULL) return 0; find_coreGLES2(); load_GL_ES_VERSION_2_0(load); find_extensionsGLES2(); return GLVersion.major != 0 || GLVersion.minor != 0; } zevv-duc-b8f9659/src/glad/glad/000077500000000000000000000000001426703022500162415ustar00rootroot00000000000000zevv-duc-b8f9659/src/glad/glad/glad.h000066400000000000000000001136531426703022500173320ustar00rootroot00000000000000 #ifndef __glad_h_ #ifdef __gl_h_ #error OpenGL header already included, remove this include, glad already provides it #endif #define __glad_h_ #define __gl_h_ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif #include #endif #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif #ifdef __cplusplus extern "C" { #endif struct gladGLversionStruct { int major; int minor; }; extern struct gladGLversionStruct GLVersion; typedef void* (* GLADloadproc)(const char *name); #ifndef GLAPI # if defined(GLAD_GLAPI_EXPORT) # if defined(WIN32) || defined(__CYGWIN__) # if defined(GLAD_GLAPI_EXPORT_BUILD) # if defined(__GNUC__) # define GLAPI __attribute__ ((dllexport)) extern # else # define GLAPI __declspec(dllexport) extern # endif # else # if defined(__GNUC__) # define GLAPI __attribute__ ((dllimport)) extern # else # define GLAPI __declspec(dllimport) extern # endif # endif # elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD) # define GLAPI __attribute__ ((visibility ("default"))) extern # else # define GLAPI extern # endif # else # define GLAPI extern # endif #endif GLAPI int gladLoadGL(void); GLAPI int gladLoadGLES2Loader(GLADloadproc); #include #include #ifndef GLEXT_64_TYPES_DEFINED /* This code block is duplicated in glxext.h, so must be protected */ #define GLEXT_64_TYPES_DEFINED /* Define int32_t, int64_t, and uint64_t types for UST/MSC */ /* (as used in the GL_EXT_timer_query extension). */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #include #elif defined(__sun__) || defined(__digital__) #include #if defined(__STDC__) #if defined(__arch64__) || defined(_LP64) typedef long int int64_t; typedef unsigned long int uint64_t; #else typedef long long int int64_t; typedef unsigned long long int uint64_t; #endif /* __arch64__ */ #endif /* __STDC__ */ #elif defined( __VMS ) || defined(__sgi) #include #elif defined(__SCO__) || defined(__USLC__) #include #elif defined(__UNIXOS2__) || defined(__SOL64__) typedef long int int32_t; typedef long long int int64_t; typedef unsigned long long int uint64_t; #elif defined(_WIN32) && defined(__GNUC__) #include #elif defined(_WIN32) typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #else /* Fallback if nothing above works */ #include #endif #endif typedef unsigned int GLenum; typedef unsigned char GLboolean; typedef unsigned int GLbitfield; typedef void GLvoid; typedef signed char GLbyte; typedef short GLshort; typedef int GLint; typedef int GLclampx; typedef unsigned char GLubyte; typedef unsigned short GLushort; typedef unsigned int GLuint; typedef int GLsizei; typedef float GLfloat; typedef float GLclampf; typedef double GLdouble; typedef double GLclampd; typedef void *GLeglImageOES; typedef char GLchar; typedef char GLcharARB; #ifdef __APPLE__ typedef void *GLhandleARB; #else typedef unsigned int GLhandleARB; #endif typedef unsigned short GLhalfARB; typedef unsigned short GLhalf; typedef GLint GLfixed; typedef ptrdiff_t GLintptr; typedef ptrdiff_t GLsizeiptr; typedef int64_t GLint64; typedef uint64_t GLuint64; typedef ptrdiff_t GLintptrARB; typedef ptrdiff_t GLsizeiptrARB; typedef int64_t GLint64EXT; typedef uint64_t GLuint64EXT; typedef struct __GLsync *GLsync; struct _cl_context; struct _cl_event; typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); typedef unsigned short GLhalfNV; typedef GLintptr GLvdpauSurfaceNV; #define GL_DEPTH_BUFFER_BIT 0x00000100 #define GL_STENCIL_BUFFER_BIT 0x00000400 #define GL_COLOR_BUFFER_BIT 0x00004000 #define GL_FALSE 0 #define GL_TRUE 1 #define GL_POINTS 0x0000 #define GL_LINES 0x0001 #define GL_LINE_LOOP 0x0002 #define GL_LINE_STRIP 0x0003 #define GL_TRIANGLES 0x0004 #define GL_TRIANGLE_STRIP 0x0005 #define GL_TRIANGLE_FAN 0x0006 #define GL_ZERO 0 #define GL_ONE 1 #define GL_SRC_COLOR 0x0300 #define GL_ONE_MINUS_SRC_COLOR 0x0301 #define GL_SRC_ALPHA 0x0302 #define GL_ONE_MINUS_SRC_ALPHA 0x0303 #define GL_DST_ALPHA 0x0304 #define GL_ONE_MINUS_DST_ALPHA 0x0305 #define GL_DST_COLOR 0x0306 #define GL_ONE_MINUS_DST_COLOR 0x0307 #define GL_SRC_ALPHA_SATURATE 0x0308 #define GL_FUNC_ADD 0x8006 #define GL_BLEND_EQUATION 0x8009 #define GL_BLEND_EQUATION_RGB 0x8009 #define GL_BLEND_EQUATION_ALPHA 0x883D #define GL_FUNC_SUBTRACT 0x800A #define GL_FUNC_REVERSE_SUBTRACT 0x800B #define GL_BLEND_DST_RGB 0x80C8 #define GL_BLEND_SRC_RGB 0x80C9 #define GL_BLEND_DST_ALPHA 0x80CA #define GL_BLEND_SRC_ALPHA 0x80CB #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define GL_BLEND_COLOR 0x8005 #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 #define GL_STREAM_DRAW 0x88E0 #define GL_STATIC_DRAW 0x88E4 #define GL_DYNAMIC_DRAW 0x88E8 #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_CURRENT_VERTEX_ATTRIB 0x8626 #define GL_FRONT 0x0404 #define GL_BACK 0x0405 #define GL_FRONT_AND_BACK 0x0408 #define GL_TEXTURE_2D 0x0DE1 #define GL_CULL_FACE 0x0B44 #define GL_BLEND 0x0BE2 #define GL_DITHER 0x0BD0 #define GL_STENCIL_TEST 0x0B90 #define GL_DEPTH_TEST 0x0B71 #define GL_SCISSOR_TEST 0x0C11 #define GL_POLYGON_OFFSET_FILL 0x8037 #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #define GL_SAMPLE_COVERAGE 0x80A0 #define GL_NO_ERROR 0 #define GL_INVALID_ENUM 0x0500 #define GL_INVALID_VALUE 0x0501 #define GL_INVALID_OPERATION 0x0502 #define GL_OUT_OF_MEMORY 0x0505 #define GL_CW 0x0900 #define GL_CCW 0x0901 #define GL_LINE_WIDTH 0x0B21 #define GL_ALIASED_POINT_SIZE_RANGE 0x846D #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E #define GL_CULL_FACE_MODE 0x0B45 #define GL_FRONT_FACE 0x0B46 #define GL_DEPTH_RANGE 0x0B70 #define GL_DEPTH_WRITEMASK 0x0B72 #define GL_DEPTH_CLEAR_VALUE 0x0B73 #define GL_DEPTH_FUNC 0x0B74 #define GL_STENCIL_CLEAR_VALUE 0x0B91 #define GL_STENCIL_FUNC 0x0B92 #define GL_STENCIL_FAIL 0x0B94 #define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 #define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 #define GL_STENCIL_REF 0x0B97 #define GL_STENCIL_VALUE_MASK 0x0B93 #define GL_STENCIL_WRITEMASK 0x0B98 #define GL_STENCIL_BACK_FUNC 0x8800 #define GL_STENCIL_BACK_FAIL 0x8801 #define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 #define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 #define GL_STENCIL_BACK_REF 0x8CA3 #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 #define GL_VIEWPORT 0x0BA2 #define GL_SCISSOR_BOX 0x0C10 #define GL_COLOR_CLEAR_VALUE 0x0C22 #define GL_COLOR_WRITEMASK 0x0C23 #define GL_UNPACK_ALIGNMENT 0x0CF5 #define GL_PACK_ALIGNMENT 0x0D05 #define GL_MAX_TEXTURE_SIZE 0x0D33 #define GL_MAX_VIEWPORT_DIMS 0x0D3A #define GL_SUBPIXEL_BITS 0x0D50 #define GL_RED_BITS 0x0D52 #define GL_GREEN_BITS 0x0D53 #define GL_BLUE_BITS 0x0D54 #define GL_ALPHA_BITS 0x0D55 #define GL_DEPTH_BITS 0x0D56 #define GL_STENCIL_BITS 0x0D57 #define GL_POLYGON_OFFSET_UNITS 0x2A00 #define GL_POLYGON_OFFSET_FACTOR 0x8038 #define GL_TEXTURE_BINDING_2D 0x8069 #define GL_SAMPLE_BUFFERS 0x80A8 #define GL_SAMPLES 0x80A9 #define GL_SAMPLE_COVERAGE_VALUE 0x80AA #define GL_SAMPLE_COVERAGE_INVERT 0x80AB #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define GL_DONT_CARE 0x1100 #define GL_FASTEST 0x1101 #define GL_NICEST 0x1102 #define GL_GENERATE_MIPMAP_HINT 0x8192 #define GL_BYTE 0x1400 #define GL_UNSIGNED_BYTE 0x1401 #define GL_SHORT 0x1402 #define GL_UNSIGNED_SHORT 0x1403 #define GL_INT 0x1404 #define GL_UNSIGNED_INT 0x1405 #define GL_FLOAT 0x1406 #define GL_FIXED 0x140C #define GL_DEPTH_COMPONENT 0x1902 #define GL_ALPHA 0x1906 #define GL_RGB 0x1907 #define GL_RGBA 0x1908 #define GL_LUMINANCE 0x1909 #define GL_LUMINANCE_ALPHA 0x190A #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define GL_UNSIGNED_SHORT_5_6_5 0x8363 #define GL_FRAGMENT_SHADER 0x8B30 #define GL_VERTEX_SHADER 0x8B31 #define GL_MAX_VERTEX_ATTRIBS 0x8869 #define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB #define GL_MAX_VARYING_VECTORS 0x8DFC #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C #define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 #define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD #define GL_SHADER_TYPE 0x8B4F #define GL_DELETE_STATUS 0x8B80 #define GL_LINK_STATUS 0x8B82 #define GL_VALIDATE_STATUS 0x8B83 #define GL_ATTACHED_SHADERS 0x8B85 #define GL_ACTIVE_UNIFORMS 0x8B86 #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 #define GL_ACTIVE_ATTRIBUTES 0x8B89 #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A #define GL_SHADING_LANGUAGE_VERSION 0x8B8C #define GL_CURRENT_PROGRAM 0x8B8D #define GL_NEVER 0x0200 #define GL_LESS 0x0201 #define GL_EQUAL 0x0202 #define GL_LEQUAL 0x0203 #define GL_GREATER 0x0204 #define GL_NOTEQUAL 0x0205 #define GL_GEQUAL 0x0206 #define GL_ALWAYS 0x0207 #define GL_KEEP 0x1E00 #define GL_REPLACE 0x1E01 #define GL_INCR 0x1E02 #define GL_DECR 0x1E03 #define GL_INVERT 0x150A #define GL_INCR_WRAP 0x8507 #define GL_DECR_WRAP 0x8508 #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 #define GL_EXTENSIONS 0x1F03 #define GL_NEAREST 0x2600 #define GL_LINEAR 0x2601 #define GL_NEAREST_MIPMAP_NEAREST 0x2700 #define GL_LINEAR_MIPMAP_NEAREST 0x2701 #define GL_NEAREST_MIPMAP_LINEAR 0x2702 #define GL_LINEAR_MIPMAP_LINEAR 0x2703 #define GL_TEXTURE_MAG_FILTER 0x2800 #define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_TEXTURE_WRAP_S 0x2802 #define GL_TEXTURE_WRAP_T 0x2803 #define GL_TEXTURE 0x1702 #define GL_TEXTURE_CUBE_MAP 0x8513 #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 #define GL_TEXTURE2 0x84C2 #define GL_TEXTURE3 0x84C3 #define GL_TEXTURE4 0x84C4 #define GL_TEXTURE5 0x84C5 #define GL_TEXTURE6 0x84C6 #define GL_TEXTURE7 0x84C7 #define GL_TEXTURE8 0x84C8 #define GL_TEXTURE9 0x84C9 #define GL_TEXTURE10 0x84CA #define GL_TEXTURE11 0x84CB #define GL_TEXTURE12 0x84CC #define GL_TEXTURE13 0x84CD #define GL_TEXTURE14 0x84CE #define GL_TEXTURE15 0x84CF #define GL_TEXTURE16 0x84D0 #define GL_TEXTURE17 0x84D1 #define GL_TEXTURE18 0x84D2 #define GL_TEXTURE19 0x84D3 #define GL_TEXTURE20 0x84D4 #define GL_TEXTURE21 0x84D5 #define GL_TEXTURE22 0x84D6 #define GL_TEXTURE23 0x84D7 #define GL_TEXTURE24 0x84D8 #define GL_TEXTURE25 0x84D9 #define GL_TEXTURE26 0x84DA #define GL_TEXTURE27 0x84DB #define GL_TEXTURE28 0x84DC #define GL_TEXTURE29 0x84DD #define GL_TEXTURE30 0x84DE #define GL_TEXTURE31 0x84DF #define GL_ACTIVE_TEXTURE 0x84E0 #define GL_REPEAT 0x2901 #define GL_CLAMP_TO_EDGE 0x812F #define GL_MIRRORED_REPEAT 0x8370 #define GL_FLOAT_VEC2 0x8B50 #define GL_FLOAT_VEC3 0x8B51 #define GL_FLOAT_VEC4 0x8B52 #define GL_INT_VEC2 0x8B53 #define GL_INT_VEC3 0x8B54 #define GL_INT_VEC4 0x8B55 #define GL_BOOL 0x8B56 #define GL_BOOL_VEC2 0x8B57 #define GL_BOOL_VEC3 0x8B58 #define GL_BOOL_VEC4 0x8B59 #define GL_FLOAT_MAT2 0x8B5A #define GL_FLOAT_MAT3 0x8B5B #define GL_FLOAT_MAT4 0x8B5C #define GL_SAMPLER_2D 0x8B5E #define GL_SAMPLER_CUBE 0x8B60 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F #define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A #define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B #define GL_COMPILE_STATUS 0x8B81 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_SHADER_SOURCE_LENGTH 0x8B88 #define GL_SHADER_COMPILER 0x8DFA #define GL_SHADER_BINARY_FORMATS 0x8DF8 #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 #define GL_LOW_FLOAT 0x8DF0 #define GL_MEDIUM_FLOAT 0x8DF1 #define GL_HIGH_FLOAT 0x8DF2 #define GL_LOW_INT 0x8DF3 #define GL_MEDIUM_INT 0x8DF4 #define GL_HIGH_INT 0x8DF5 #define GL_FRAMEBUFFER 0x8D40 #define GL_RENDERBUFFER 0x8D41 #define GL_RGBA4 0x8056 #define GL_RGB5_A1 0x8057 #define GL_RGB565 0x8D62 #define GL_DEPTH_COMPONENT16 0x81A5 #define GL_STENCIL_INDEX8 0x8D48 #define GL_RENDERBUFFER_WIDTH 0x8D42 #define GL_RENDERBUFFER_HEIGHT 0x8D43 #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 #define GL_RENDERBUFFER_RED_SIZE 0x8D50 #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 #define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 #define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_DEPTH_ATTACHMENT 0x8D00 #define GL_STENCIL_ATTACHMENT 0x8D20 #define GL_NONE 0 #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD #define GL_FRAMEBUFFER_BINDING 0x8CA6 #define GL_RENDERBUFFER_BINDING 0x8CA7 #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 #ifndef GL_ES_VERSION_2_0 #define GL_ES_VERSION_2_0 1 GLAPI int GLAD_GL_ES_VERSION_2_0; typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum); GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture; #define glActiveTexture glad_glActiveTexture typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint, GLuint); GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader; #define glAttachShader glad_glAttachShader typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint, GLuint, const GLchar*); GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; #define glBindAttribLocation glad_glBindAttribLocation typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum, GLuint); GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer; #define glBindBuffer glad_glBindBuffer typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum, GLuint); GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; #define glBindFramebuffer glad_glBindFramebuffer typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum, GLuint); GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; #define glBindRenderbuffer glad_glBindRenderbuffer typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum, GLuint); GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture; #define glBindTexture glad_glBindTexture typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat); GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor; #define glBlendColor glad_glBlendColor typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum); GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation; #define glBlendEquation glad_glBlendEquation typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum, GLenum); GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; #define glBlendEquationSeparate glad_glBlendEquationSeparate typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum, GLenum); GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc; #define glBlendFunc glad_glBlendFunc typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum); GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; #define glBlendFuncSeparate glad_glBlendFuncSeparate typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum, GLsizeiptr, const void*, GLenum); GLAPI PFNGLBUFFERDATAPROC glad_glBufferData; #define glBufferData glad_glBufferData typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum, GLintptr, GLsizeiptr, const void*); GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; #define glBufferSubData glad_glBufferSubData typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum); GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; #define glCheckFramebufferStatus glad_glCheckFramebufferStatus typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield); GLAPI PFNGLCLEARPROC glad_glClear; #define glClear glad_glClear typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat, GLfloat, GLfloat, GLfloat); GLAPI PFNGLCLEARCOLORPROC glad_glClearColor; #define glClearColor glad_glClearColor typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC)(GLfloat); GLAPI PFNGLCLEARDEPTHFPROC glad_glClearDepthf; #define glClearDepthf glad_glClearDepthf typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint); GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil; #define glClearStencil glad_glClearStencil typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean, GLboolean, GLboolean, GLboolean); GLAPI PFNGLCOLORMASKPROC glad_glColorMask; #define glColorMask glad_glColorMask typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint); GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader; #define glCompileShader glad_glCompileShader typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const void*); GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; #define glCompressedTexImage2D glad_glCompressedTexImage2D typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void*); GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; #define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; #define glCopyTexImage2D glad_glCopyTexImage2D typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; #define glCopyTexSubImage2D glad_glCopyTexSubImage2D typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(); GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram; #define glCreateProgram glad_glCreateProgram typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum); GLAPI PFNGLCREATESHADERPROC glad_glCreateShader; #define glCreateShader glad_glCreateShader typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum); GLAPI PFNGLCULLFACEPROC glad_glCullFace; #define glCullFace glad_glCullFace typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei, const GLuint*); GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; #define glDeleteBuffers glad_glDeleteBuffers typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei, const GLuint*); GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; #define glDeleteFramebuffers glad_glDeleteFramebuffers typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint); GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; #define glDeleteProgram glad_glDeleteProgram typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei, const GLuint*); GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; #define glDeleteRenderbuffers glad_glDeleteRenderbuffers typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint); GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader; #define glDeleteShader glad_glDeleteShader typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei, const GLuint*); GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures; #define glDeleteTextures glad_glDeleteTextures typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum); GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc; #define glDepthFunc glad_glDepthFunc typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean); GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask; #define glDepthMask glad_glDepthMask typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC)(GLfloat, GLfloat); GLAPI PFNGLDEPTHRANGEFPROC glad_glDepthRangef; #define glDepthRangef glad_glDepthRangef typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint, GLuint); GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader; #define glDetachShader glad_glDetachShader typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum); GLAPI PFNGLDISABLEPROC glad_glDisable; #define glDisable glad_glDisable typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint); GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; #define glDisableVertexAttribArray glad_glDisableVertexAttribArray typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum, GLint, GLsizei); GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays; #define glDrawArrays glad_glDrawArrays typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum, GLsizei, GLenum, const void*); GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements; #define glDrawElements glad_glDrawElements typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum); GLAPI PFNGLENABLEPROC glad_glEnable; #define glEnable glad_glEnable typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint); GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; #define glEnableVertexAttribArray glad_glEnableVertexAttribArray typedef void (APIENTRYP PFNGLFINISHPROC)(); GLAPI PFNGLFINISHPROC glad_glFinish; #define glFinish glad_glFinish typedef void (APIENTRYP PFNGLFLUSHPROC)(); GLAPI PFNGLFLUSHPROC glad_glFlush; #define glFlush glad_glFlush typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum, GLenum, GLenum, GLuint); GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; #define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum, GLenum, GLenum, GLuint, GLint); GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; #define glFramebufferTexture2D glad_glFramebufferTexture2D typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum); GLAPI PFNGLFRONTFACEPROC glad_glFrontFace; #define glFrontFace glad_glFrontFace typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei, GLuint*); GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers; #define glGenBuffers glad_glGenBuffers typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum); GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; #define glGenerateMipmap glad_glGenerateMipmap typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei, GLuint*); GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; #define glGenFramebuffers glad_glGenFramebuffers typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei, GLuint*); GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; #define glGenRenderbuffers glad_glGenRenderbuffers typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei, GLuint*); GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures; #define glGenTextures glad_glGenTextures typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; #define glGetActiveAttrib glad_glGetActiveAttrib typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint, GLuint, GLsizei, GLsizei*, GLint*, GLenum*, GLchar*); GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; #define glGetActiveUniform glad_glGetActiveUniform typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint, GLsizei, GLsizei*, GLuint*); GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; #define glGetAttachedShaders glad_glGetAttachedShaders typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint, const GLchar*); GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; #define glGetAttribLocation glad_glGetAttribLocation typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum, GLboolean*); GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv; #define glGetBooleanv glad_glGetBooleanv typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint*); GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; #define glGetBufferParameteriv glad_glGetBufferParameteriv typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(); GLAPI PFNGLGETERRORPROC glad_glGetError; #define glGetError glad_glGetError typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum, GLfloat*); GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv; #define glGetFloatv glad_glGetFloatv typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum, GLenum, GLenum, GLint*); GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; #define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum, GLint*); GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv; #define glGetIntegerv glad_glGetIntegerv typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint, GLenum, GLint*); GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; #define glGetProgramiv glad_glGetProgramiv typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; #define glGetProgramInfoLog glad_glGetProgramInfoLog typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint*); GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; #define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint, GLenum, GLint*); GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv; #define glGetShaderiv glad_glGetShaderiv typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint, GLsizei, GLsizei*, GLchar*); GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; #define glGetShaderInfoLog glad_glGetShaderInfoLog typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum, GLenum, GLint*, GLint*); GLAPI PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; #define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint, GLsizei, GLsizei*, GLchar*); GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; #define glGetShaderSource glad_glGetShaderSource typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGPROC)(GLenum); GLAPI PFNGLGETSTRINGPROC glad_glGetString; #define glGetString glad_glGetString typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum, GLenum, GLfloat*); GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; #define glGetTexParameterfv glad_glGetTexParameterfv typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum, GLenum, GLint*); GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; #define glGetTexParameteriv glad_glGetTexParameteriv typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint, GLint, GLfloat*); GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; #define glGetUniformfv glad_glGetUniformfv typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint, GLint, GLint*); GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; #define glGetUniformiv glad_glGetUniformiv typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint, const GLchar*); GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; #define glGetUniformLocation glad_glGetUniformLocation typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint, GLenum, GLfloat*); GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; #define glGetVertexAttribfv glad_glGetVertexAttribfv typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint, GLenum, GLint*); GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; #define glGetVertexAttribiv glad_glGetVertexAttribiv typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint, GLenum, void**); GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; #define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv typedef void (APIENTRYP PFNGLHINTPROC)(GLenum, GLenum); GLAPI PFNGLHINTPROC glad_glHint; #define glHint glad_glHint typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint); GLAPI PFNGLISBUFFERPROC glad_glIsBuffer; #define glIsBuffer glad_glIsBuffer typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum); GLAPI PFNGLISENABLEDPROC glad_glIsEnabled; #define glIsEnabled glad_glIsEnabled typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint); GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; #define glIsFramebuffer glad_glIsFramebuffer typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint); GLAPI PFNGLISPROGRAMPROC glad_glIsProgram; #define glIsProgram glad_glIsProgram typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint); GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; #define glIsRenderbuffer glad_glIsRenderbuffer typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint); GLAPI PFNGLISSHADERPROC glad_glIsShader; #define glIsShader glad_glIsShader typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint); GLAPI PFNGLISTEXTUREPROC glad_glIsTexture; #define glIsTexture glad_glIsTexture typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat); GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth; #define glLineWidth glad_glLineWidth typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint); GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram; #define glLinkProgram glad_glLinkProgram typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum, GLint); GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei; #define glPixelStorei glad_glPixelStorei typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat, GLfloat); GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; #define glPolygonOffset glad_glPolygonOffset typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void*); GLAPI PFNGLREADPIXELSPROC glad_glReadPixels; #define glReadPixels glad_glReadPixels typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC)(); GLAPI PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; #define glReleaseShaderCompiler glad_glReleaseShaderCompiler typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum, GLenum, GLsizei, GLsizei); GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; #define glRenderbufferStorage glad_glRenderbufferStorage typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat, GLboolean); GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; #define glSampleCoverage glad_glSampleCoverage typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint, GLint, GLsizei, GLsizei); GLAPI PFNGLSCISSORPROC glad_glScissor; #define glScissor glad_glScissor typedef void (APIENTRYP PFNGLSHADERBINARYPROC)(GLsizei, const GLuint*, GLenum, const void*, GLsizei); GLAPI PFNGLSHADERBINARYPROC glad_glShaderBinary; #define glShaderBinary glad_glShaderBinary typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint, GLsizei, const GLchar**, const GLint*); GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource; #define glShaderSource glad_glShaderSource typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum, GLint, GLuint); GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc; #define glStencilFunc glad_glStencilFunc typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum, GLenum, GLint, GLuint); GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; #define glStencilFuncSeparate glad_glStencilFuncSeparate typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint); GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask; #define glStencilMask glad_glStencilMask typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum, GLuint); GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; #define glStencilMaskSeparate glad_glStencilMaskSeparate typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum, GLenum, GLenum); GLAPI PFNGLSTENCILOPPROC glad_glStencilOp; #define glStencilOp glad_glStencilOp typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum, GLenum, GLenum, GLenum); GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; #define glStencilOpSeparate glad_glStencilOpSeparate typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void*); GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D; #define glTexImage2D glad_glTexImage2D typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum, GLenum, GLfloat); GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf; #define glTexParameterf glad_glTexParameterf typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum, GLenum, const GLfloat*); GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; #define glTexParameterfv glad_glTexParameterfv typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum, GLenum, GLint); GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri; #define glTexParameteri glad_glTexParameteri typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum, GLenum, const GLint*); GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; #define glTexParameteriv glad_glTexParameteriv typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void*); GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; #define glTexSubImage2D glad_glTexSubImage2D typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint, GLfloat); GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f; #define glUniform1f glad_glUniform1f typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint, GLsizei, const GLfloat*); GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv; #define glUniform1fv glad_glUniform1fv typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint, GLint); GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i; #define glUniform1i glad_glUniform1i typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint, GLsizei, const GLint*); GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv; #define glUniform1iv glad_glUniform1iv typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint, GLfloat, GLfloat); GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f; #define glUniform2f glad_glUniform2f typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint, GLsizei, const GLfloat*); GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv; #define glUniform2fv glad_glUniform2fv typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint, GLint, GLint); GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i; #define glUniform2i glad_glUniform2i typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint, GLsizei, const GLint*); GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv; #define glUniform2iv glad_glUniform2iv typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint, GLfloat, GLfloat, GLfloat); GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f; #define glUniform3f glad_glUniform3f typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint, GLsizei, const GLfloat*); GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv; #define glUniform3fv glad_glUniform3fv typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint, GLint, GLint, GLint); GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i; #define glUniform3i glad_glUniform3i typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint, GLsizei, const GLint*); GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv; #define glUniform3iv glad_glUniform3iv typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f; #define glUniform4f glad_glUniform4f typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint, GLsizei, const GLfloat*); GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv; #define glUniform4fv glad_glUniform4fv typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint, GLint, GLint, GLint, GLint); GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i; #define glUniform4i glad_glUniform4i typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint, GLsizei, const GLint*); GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv; #define glUniform4iv glad_glUniform4iv typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; #define glUniformMatrix2fv glad_glUniformMatrix2fv typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; #define glUniformMatrix3fv glad_glUniformMatrix3fv typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint, GLsizei, GLboolean, const GLfloat*); GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; #define glUniformMatrix4fv glad_glUniformMatrix4fv typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint); GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram; #define glUseProgram glad_glUseProgram typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint); GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; #define glValidateProgram glad_glValidateProgram typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint, GLfloat); GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; #define glVertexAttrib1f glad_glVertexAttrib1f typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint, const GLfloat*); GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; #define glVertexAttrib1fv glad_glVertexAttrib1fv typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint, GLfloat, GLfloat); GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; #define glVertexAttrib2f glad_glVertexAttrib2f typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint, const GLfloat*); GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; #define glVertexAttrib2fv glad_glVertexAttrib2fv typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint, GLfloat, GLfloat, GLfloat); GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; #define glVertexAttrib3f glad_glVertexAttrib3f typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint, const GLfloat*); GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; #define glVertexAttrib3fv glad_glVertexAttrib3fv typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; #define glVertexAttrib4f glad_glVertexAttrib4f typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint, const GLfloat*); GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; #define glVertexAttrib4fv glad_glVertexAttrib4fv typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint, GLint, GLenum, GLboolean, GLsizei, const void*); GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; #define glVertexAttribPointer glad_glVertexAttribPointer typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint, GLint, GLsizei, GLsizei); GLAPI PFNGLVIEWPORTPROC glad_glViewport; #define glViewport glad_glViewport #endif #ifdef __cplusplus } #endif #endif zevv-duc-b8f9659/src/libduc-graph/000077500000000000000000000000001426703022500167645ustar00rootroot00000000000000zevv-duc-b8f9659/src/libduc-graph/duc-graph.h000066400000000000000000000033061426703022500210110ustar00rootroot00000000000000#include "config.h" #ifndef duc_graph_h #define duc_graph_h #include /* * Graph drawing */ typedef struct duc_graph duc_graph; enum duc_graph_palette { DUC_GRAPH_PALETTE_SIZE, DUC_GRAPH_PALETTE_RAINBOW, DUC_GRAPH_PALETTE_GREYSCALE, DUC_GRAPH_PALETTE_MONOCHROME, DUC_GRAPH_PALETTE_CLASSIC, }; typedef enum { DUC_GRAPH_FORMAT_PNG, DUC_GRAPH_FORMAT_SVG, DUC_GRAPH_FORMAT_PDF, DUC_GRAPH_FORMAT_HTML, } duc_graph_file_format; #ifdef ENABLE_CAIRO #include duc_graph *duc_graph_new_cairo(duc *duc, cairo_t *cr); duc_graph *duc_graph_new_cairo_file(duc *duc, duc_graph_file_format fmt, FILE *fout); #endif #ifdef ENABLE_OPENGL duc_graph *duc_graph_new_opengl(duc *duc, double font_scale); #endif duc_graph *duc_graph_new_svg(duc *duc, FILE *fout); duc_graph *duc_graph_new_html(duc *duc, FILE *fout, int write_body); void duc_graph_free(duc_graph *g); void duc_graph_set_max_level(duc_graph *g, int max_level); void duc_graph_set_size(duc_graph *g, int w, int h); void duc_graph_set_dpi(duc_graph *g, double dpi); void duc_graph_set_position(duc_graph *g, double x, double y); void duc_graph_set_tooltip(duc_graph *g, double x, double y); void duc_graph_set_palette(duc_graph *g, enum duc_graph_palette p); void duc_graph_set_fuzz(duc_graph *g, double fuzz); void duc_graph_set_max_name_len(duc_graph *g, size_t len); void duc_graph_set_size_type(duc_graph *g, duc_size_type st); void duc_graph_set_exact_bytes(duc_graph *g, int exact); void duc_graph_set_ring_gap(duc_graph *g, int gap); void duc_graph_set_gradient(duc_graph *g, int onoff); int duc_graph_draw(duc_graph *g, duc_dir *dir); duc_dir *duc_graph_find_spot(duc_graph *g, duc_dir *dir, double x, double y, struct duc_dirent **ent); #endif zevv-duc-b8f9659/src/libduc-graph/font.c000066400000000000000000005530421426703022500201070ustar00rootroot00000000000000// Font generated by stb_font_inl_generator.c (4/1 bpp) // // Following instructions show how to use the only included font, whatever it is, in // a generic way so you can replace it with any other font by changing the include. // To use multiple fonts, replace STB_SOMEFONT_* below with STB_FONT_arial_40_latin_ext_*, // and separately install each font. Note that the CREATE function call has a // totally different name; it's just 'stb_font_arial_40_latin_ext'. // /* // Example usage: static stb_fontchar fontdata[STB_SOMEFONT_NUM_CHARS]; static void init(void) { // optionally replace both STB_SOMEFONT_BITMAP_HEIGHT with STB_SOMEFONT_BITMAP_HEIGHT_POW2 static unsigned char fontpixels[STB_SOMEFONT_BITMAP_HEIGHT][STB_SOMEFONT_BITMAP_WIDTH]; STB_SOMEFONT_CREATE(fontdata, fontpixels, STB_SOMEFONT_BITMAP_HEIGHT); ... create texture ... // for best results rendering 1:1 pixels texels, use nearest-neighbor sampling // if allowed to scale up, use bilerp } // This function positions characters on integer coordinates, and assumes 1:1 texels to pixels // Appropriate if nearest-neighbor sampling is used static void draw_string_integer(int x, int y, char *str) // draw with top-left point x,y { ... use texture ... ... turn on alpha blending and gamma-correct alpha blending ... glBegin(GL_QUADS); while (*str) { int char_codepoint = *str++; stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR]; glTexCoord2f(cd->s0, cd->t0); glVertex2i(x + cd->x0, y + cd->y0); glTexCoord2f(cd->s1, cd->t0); glVertex2i(x + cd->x1, y + cd->y0); glTexCoord2f(cd->s1, cd->t1); glVertex2i(x + cd->x1, y + cd->y1); glTexCoord2f(cd->s0, cd->t1); glVertex2i(x + cd->x0, y + cd->y1); // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct x += cd->advance_int; } glEnd(); } // This function positions characters on float coordinates, and doesn't require 1:1 texels to pixels // Appropriate if bilinear filtering is used static void draw_string_float(float x, float y, char *str) // draw with top-left point x,y { ... use texture ... ... turn on alpha blending and gamma-correct alpha blending ... glBegin(GL_QUADS); while (*str) { int char_codepoint = *str++; stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR]; glTexCoord2f(cd->s0f, cd->t0f); glVertex2f(x + cd->x0f, y + cd->y0f); glTexCoord2f(cd->s1f, cd->t0f); glVertex2f(x + cd->x1f, y + cd->y0f); glTexCoord2f(cd->s1f, cd->t1f); glVertex2f(x + cd->x1f, y + cd->y1f); glTexCoord2f(cd->s0f, cd->t1f); glVertex2f(x + cd->x0f, y + cd->y1f); // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct x += cd->advance; } glEnd(); } */ #ifndef STB_FONTCHAR__TYPEDEF #define STB_FONTCHAR__TYPEDEF typedef struct { // coordinates if using integer positioning float s0,t0,s1,t1; signed short x0,y0,x1,y1; int advance_int; // coordinates if using floating positioning float s0f,t0f,s1f,t1f; float x0f,y0f,x1f,y1f; float advance; } stb_fontchar; #endif #define STB_FONT_arial_40_latin_ext_BITMAP_WIDTH 512 #define STB_FONT_arial_40_latin_ext_BITMAP_HEIGHT 398 #define STB_FONT_arial_40_latin_ext_BITMAP_HEIGHT_POW2 512 #define STB_FONT_arial_40_latin_ext_FIRST_CHAR 32 #define STB_FONT_arial_40_latin_ext_NUM_CHARS 560 #define STB_FONT_arial_40_latin_ext_LINE_SPACING 26 static unsigned int stb__arial_40_latin_ext_pixels[]={ 0x99999991,0x99999999,0x00199999,0x00000000,0x00000180,0x00000000, 0xcc880000,0x0000003c,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x4cccccc4,0x99880099,0x40099981,0x99881cca,0x31000009, 0x33326033,0x88002ccc,0x32a00999,0x001ccccc,0x31001710,0x99999975, 0x2a399999,0x880001cc,0xffffffff,0xffffffff,0x0000ffff,0x000dfff1, 0x3a200162,0xf910000f,0x7fc401ff,0xfff10001,0x03fec00d,0x407fff20, 0x0004eff8,0x7bdfdb73,0x05fb8015,0x7fed4000,0x00ffb3de,0x7f765cc0, 0x001ceeff,0xfeec9800,0x0000bdef,0x7fff6dc4,0xa8000acd,0x00cefffd, 0xfffffa80,0xfd004fff,0x077fd49f,0x260fff20,0x80005fff,0xf505fff8, 0x009fffff,0x404ffe88,0x2ffffffc,0x809f7000,0xfffffffa,0xffffffff, 0x0007ff92,0xffffff10,0xffffffff,0x01ffffff,0x03fff200,0x001fee00, 0x44000ffe,0x200fffff,0x2e0005fc,0x36000fff,0x3fe2007f,0x3ffe202f, 0xfd1000ef,0xffffffff,0x03fe807f,0xffff5000,0x01ff6bff,0x3ffff6a0, 0xffffffff,0x540000be,0xfffffffe,0x4000bfff,0xffffffd8,0x004fffff, 0xffffffd1,0xea8007ff,0x3eeeeeee,0x13fff100,0xf9003fff,0x3ffea07f, 0x7fe40000,0xffff500e,0xfd8009ff,0xfffc802f,0xb0002fff,0x3ffa203f, 0xffffffff,0x92ffffff,0x100007ff,0x55555555,0x5555dffd,0x20005555, 0x0001fff8,0xf9800fff,0x3ff60005,0xff300dff,0x7ffc0003,0x03fec002, 0x8809ff70,0x803ffffd,0xfffffff9,0x04ffffff,0x00003fea,0x3ffbfffe, 0x5400ffb3,0xceeffffe,0xfffedcbb,0xf90001ef,0xffdfffff,0x001dffff, 0x3fffffea,0xffffffef,0x7fff401e,0x2ffffdcf,0x20000000,0x2ffdeffa, 0x407ff900,0x20004ffc,0x2001fff8,0x2a004ffb,0xff9000de,0xff100009, 0x7ffffe40,0xfbaaafff,0xff90aaef,0x20000007,0x00004ffd,0x0007ff70, 0x2a003ffc,0xff0004df,0x09fd003f,0x01ffdc00,0xf003fec0,0xff9800df, 0x7fffcc07,0x7ff5441b,0x017fa06f,0x43fff300,0x200ffb08,0x01cffffb, 0x4fffeb88,0x7ffff400,0xfffea80b,0xffffb806,0x7ed441ad,0xff702fff, 0xfffd883f,0x90bd5000,0xffc8007d,0x000004ff,0x20001ffb,0x5c003ffb, 0x2f5404ff,0xff901f64,0xbf500009,0x3ffffe60,0x7fc47fff,0x003ffc86, 0x9ffb0000,0x3b600000,0x3ffc0004,0x01fff200,0x2017fe60,0x20000ffb, 0xfb0004ed,0x004cc00f,0x9007ff40,0x3ee00dff,0x5ff501ff,0x2ffe4000, 0xf900ffb0,0x5c0007ff,0xf9004fff,0x3f2009ff,0x3fe604ff,0xff5002ff, 0x13ff60df,0x8017ffc4,0x04fd87fa,0x004ccc80,0x0b322000,0x001e5c00, 0x2a027fdc,0x204fd87f,0x80004ffc,0xfff903fc,0x88ffffff,0x3ffc86ff, 0xfb000000,0x3000009f,0x40003bfb,0x7e4007ff,0xffa8007f,0x005ff804, 0xb04c0000,0x000000ff,0xff807ff6,0x3ff6000f,0x001bfa04,0x3603ffe8, 0x77fec07f,0xfe980001,0x7ffd402f,0x7ffec004,0x0effe880,0x0fffcc00, 0xfb00fff4,0x17aa009f,0x00000fb2,0x00000000,0xffb80000,0x642f5404, 0x13ff203e,0x403fe000,0xfffffffd,0x437fc47f,0x00003ffc,0x009ffb00, 0xf939f000,0x7e64c001,0x400cccff,0xa8004cca,0x7fdc04ff,0xeec98002, 0x981bceff,0x00ffb0ef,0xfc8000d4,0x0fff301f,0x206ffa80,0xf0001ffc, 0x3fec03ff,0x001dff50,0x07ffc400,0x000dffd0,0xf909fff1,0x360003ff, 0x4ffc85ff,0x32202620,0xc98000cc,0x0777444c,0x95009dd7,0x0eee8839, 0xe8813bae,0x13bae0ee,0x6453fee0,0xc98000cc,0x009ff94c,0x6fefec98, 0x3fffffe0,0x7fc47fff,0x733ffc86,0x00017bfb,0x0013ff60,0x03d8f500, 0x3ffffea0,0x00001fff,0x2027fd40,0x754007fe,0xffffffff,0xdff10cff, 0x2a01ff61,0x4000efef,0xff301ffc,0x6f44001f,0x0bff300c,0x3ff332e0, 0x7ec2cccf,0x403ffa07,0x20bdedb8,0x3fea1aa9,0x05fff305,0x20f7f200, 0x20004fff,0xffa85ff9,0xff88002f,0xffa8001f,0x90fffc47,0xff900bff, 0x21fff887,0x3e205ffc,0x17ff21ff,0x7c53fee0,0xfa8001ff,0x009ff97f, 0x3fffffee,0xffe80dff,0x47ffffff,0xffc86ff8,0xffffffab,0x6c0000ef, 0x400004ff,0x3001ec6a,0xdddfffdd,0x3fb2e201,0x059930bd,0xfa80ffea, 0x3ff2005f,0xffffffff,0xffebffff,0x3a01ff60,0xc8007b14,0x3ffe02ff, 0xfd000004,0xfffd001f,0x85ffffff,0x5ff907fd,0x3ffffee0,0x87ff91ff, 0xffc80ffd,0x98020007,0x40001fff,0x27ffec01,0x07ffe200,0x11ffea00, 0x7fe43fff,0x43ffc805,0x3f21fff8,0x3ffe205f,0x2017ff21,0xfff14ffb, 0xfff50003,0x36013ff2,0xffcdffff,0x7fec1eff,0x47ffffff,0xffc86ff8, 0xfdcdfffe,0x6c0005ff,0x800004ff,0x000fb8cf,0xf300fff0,0x3fffffff, 0x3ea07ff5,0x0bff203f,0x5ffffec0,0x3ff66209,0x7ec1ffff,0xd507cc07, 0x02ffc800,0x0033fff6,0x05ff9000,0xffffddd0,0x7fd83ddd,0xf904ff98, 0xfffbbfff,0xf983ffd3,0x06ffe83f,0xfff90000,0xd0000001,0x2003dfff, 0x8001fff8,0x77447ffa,0x013bae0e,0xdd10fff2,0x02775c1d,0x75c1ddd1, 0x4ffb804e,0x0003fff1,0x3ff2fff5,0x5fffdc04,0xbffdff10,0xffffffb8, 0x37fc47ff,0x42ffffe4,0x0004ffe9,0x00013ff6,0x017ffee0,0x5407ff80, 0xfeceffff,0x703ffdff,0x7fec07ff,0xefffc800,0xfffe9800,0xf807fd84, 0xf7001322,0x7ffcc05f,0x0001beff,0x4004ffa8,0x7ec03ffd,0xc80ffc87, 0x7ec43fff,0xdfd07fff,0x000bfff0,0x01bff600,0xff910000,0x1009ffff, 0x50003fff,0x00000fff,0x0001ffe4,0x2e000000,0x3fff14ff,0x2fff5000, 0x3e204ffc,0x567d45ff,0x7ff40fff,0x447fffff,0xfffc86ff,0x0bffe205, 0x027fec00,0x7ffe4000,0x1ffe0006,0x40dfff88,0x03ffffe8,0x7fc05ff7, 0x4fff9807,0x7fffe400,0x6403fec0,0x4001fdcf,0x74403ffb,0xdfffffff, 0xff98001b,0x17ff4005,0x3fa1ff60,0x03fff985,0x641bfffa,0x03fff87f, 0xbffd0000,0x74c00000,0xffffa9ff,0x3ffe202e,0x7ffa8001,0x3f200000, 0x0000003f,0xa7fdc000,0x8001fff8,0x9ff97ffa,0x2077fcc0,0x89ffd2fd, 0xfffffff9,0x6437fc47,0x7e400fff,0xffb0005f,0xff000009,0x20003fff, 0x3ff207ff,0x3fffa205,0x203ffb03,0xfe806ff8,0x3ee000ff,0x7ec3ffff, 0x039b5007,0x009ff300,0xffffff91,0x4007dfff,0x7c006ff8,0x3fec00ff, 0x3fa0bfe6,0x7ffd404f,0xf88ff704,0x000002ff,0x00007fff,0xb1077f40, 0x101bffff,0x50003fff,0x00000fff,0x0001ffe4,0x2e000000,0x3fff14ff, 0x2fff5000,0x3ee04ffc,0x310ff84f,0x3fff6201,0x37fc47ff,0x4402ffe4, 0xfb0006ff,0xa800009f,0x005ffdff,0x3e20fff0,0x7fd401ff,0x06ff883f, 0xf3017fe6,0x7d4007ff,0x20fffccf,0x000007fd,0x4003ffe0,0xfffffdb8, 0xf000dfff,0x3e6001ff,0x46ec807f,0xfff987fc,0x17ffcc00,0x3e20ffb8, 0x000002ff,0xf3007fff,0xffffffff,0x413fe29f,0x40effffb,0x8001fff8, 0x39957ffa,0x20399700,0x39953ffc,0x2a399700,0xccb801cc,0x229ff701, 0xa8001fff,0x09ff97ff,0x3e61ffe4,0xfdb98006,0x437fc47f,0xff003ffc, 0xffb0001f,0xfd800009,0x000fff8f,0xff507ff8,0x0fffa00d,0x5c07ffb3, 0x7fe404ff,0x57fe6006,0x3f63fff9,0x3b72a207,0x2000bcef,0x8000dffb, 0xfffffdb9,0x1ffe801e,0x00dff500,0x7ec37ec0,0xfff8805f,0xf88ff901, 0x000003ff,0xf3007fff,0xffffffff,0x80bfee9f,0x446fffd8,0xa8001fff, 0x07ffb7ff,0x3205ffd0,0x07ffb3ff,0x3f65ffd0,0x2ffe803f,0x3e29ff70, 0xfa8001ff,0x409ff97f,0x1fe41ffe,0x11ffa000,0x5ff90dff,0x007ffa00, 0x0013ff60,0xf96ff880,0xfff0007f,0x4013fee0,0x3ffa3ffc,0x1ffe403f, 0x4013ffa0,0x7ff46ff9,0x7541ff64,0xffffffff,0x3fea003f,0x7540006f, 0xfd807fff,0x9ff7002f,0x42ff4000,0xf8802fff,0x21bfa07f,0x00005fff, 0x3009ffd0,0xffffffff,0x17fea9ff,0x893fff20,0xa8001fff,0x07ffb7ff, 0x3205ffd0,0x07ffb3ff,0x3f65ffd0,0x2ffe803f,0x3e29ff70,0xfa8001ff, 0x409ff97f,0x0ff40fff,0x11ffa000,0x3ff90dff,0x00bff600,0x0013ff60, 0xf34ffb80,0xfff000df,0x400fff60,0x3ffe3ffb,0x03ffd802,0x4401fffc, 0x7fe40eff,0x3f21ff65,0xfeddffff,0x2a003fff,0x900007ff,0xfc805fff, 0x7ffb004f,0x227f4000,0xa800fff8,0x9ff105ff,0x000dffd0,0x017ff600, 0x453ff600,0xfc800fff,0x07ffe27f,0x6dffea00,0xffe803ff,0x367ff902, 0xffe803ff,0xd007ffb2,0x3fee05ff,0x003fff14,0x3f2fff50,0x87ffe04f, 0xe80007f8,0x437fc47f,0xfd001ffc,0xffb0003f,0x7f400009,0x00bffe1f, 0x3fa0fff0,0x7ff7002f,0x6c02fffc,0x3fe203ff,0x7ff4402f,0x367ffb80, 0x67ffcc7f,0x06ffe980,0x22fffd10,0xfb0002aa,0x4ffd809f,0x003ffd00, 0x3e627fc0,0x9ff7007f,0x320ffea0,0x220007ff,0x3fee0ace,0x7ec0000f, 0x07fff64f,0x221fff10,0xa8001fff,0x07ffb7ff,0x3205ffd0,0x07ffb3ff, 0x3f65ffd0,0x2ffe803f,0x3e29ff70,0xfa8001ff,0x409ff97f,0x13ea2fff, 0x11ffa000,0x5ff90dff,0x003ffe00,0x0013ff60,0x323ffcc0,0x7fc005ff, 0x007ffb07,0xfca8ffee,0x3ff200ef,0x07ffe604,0x2a03ffd0,0x8ffb0fff, 0x7c406ffc,0x7fcc01ff,0x1fff11cf,0x0dff7000,0xf003ffe8,0x7c0001ff, 0x037fd44f,0xfb02ffe8,0x3fff301f,0x3ffee000,0x00fffe20,0x449ffb00, 0x7404fffe,0x3fff10ff,0x2fff5000,0xfe803ffd,0x27ff902f,0xfe803ffd, 0x007ffb2f,0x3ee05ffd,0x03fff14f,0x32fff500,0x3ffa04ff,0x9b10bf63, 0x11ffa007,0x7ff90dff,0x00dff100,0x0013ff60,0x2627fec0,0x3e000fff, 0x4ffc80ff,0x707ff900,0x7fe40bff,0x03ffe606,0x2a02ffd8,0x8ffb0fff, 0xfe801ffd,0x17fec01f,0x4001fff4,0x7fc05ffa,0x7ff9802f,0xfe833100, 0x403ffc45,0xfb80fffa,0x17ffe04f,0x42fff400,0x0000fffd,0xfd313ff6, 0xff105dff,0x00fffc4f,0xfdbffd40,0x2ffe803f,0x3f67ff90,0x2ffe803f, 0xfd007ffb,0x53fee05f,0x8001fff8,0x9ff97ffa,0xff2ffe40,0x005ffa81, 0x6ff88ffd,0xb806ffc8,0xfb0005ff,0xf100009f,0x7ffd03ff,0x407ffc00, 0xfd005ffa,0x03ffa07f,0xf103ffdc,0x3ff203ff,0xb3ffdc02,0x6c0020ff, 0x3fe202ff,0x00dff905,0x4407ffb0,0xfa801fff,0x8ffb005f,0x0ffe86fd, 0x5437ff40,0x7fdc06ff,0x7fdc001f,0x5fff982f,0x13ff6000,0x37ffff62, 0xf88fff60,0xfa8001ff,0x007ffb7f,0x3f205ffd,0x007ffb3f,0x3ff65ffd, 0x02ffe803,0x3fe29ff7,0xffa8001f,0x4c09ff97,0x85f99fff,0xfd002ffe, 0xc86ff88f,0x7f402fff,0xffb0003f,0xff700009,0x01ffee0d,0xf882fff8, 0x7fcc01ff,0x05ff903f,0xf803ffea,0x3ffb82ff,0x367ffc80,0xca88007f, 0x3ea02fff,0xdfff303f,0x3ffea001,0x03ffea00,0x4013fee0,0x43fe47fd, 0x3f604ffd,0x7ffcc5ff,0x1fffe801,0x0dfff300,0x0077ffdc,0x09fffd30, 0x5fffffd4,0x7fc44ffe,0xffb8001f,0xd007ffb7,0x3ff205ff,0xd007ffb3, 0x0fff65ff,0x5c0bffa0,0x3fff14ff,0x2fff7000,0x7ec04ffc,0x7e43fcef, 0xffd000ff,0xfc86ff88,0xffb01eff,0x7fec000d,0xffe80004,0x05fff103, 0x3b7fffa0,0xb017ff21,0x3ee07fff,0x07ffe02f,0x7d43fff8,0xdffb004f, 0x75103fec,0xffffffdb,0x17fdc05f,0x15ffffd0,0x1bfff620,0x200dff70, 0xfb003ffd,0x542ffa8f,0x3620cfff,0xf916ffff,0x3e6009ff,0x9102cfff, 0xd801ffff,0x80acffff,0xfffffda8,0x7ffe4402,0xff880dff,0xffc8001f, 0xd007ffb6,0x3ff205ff,0xd007ffb3,0x0fff65ff,0x5c0bffa0,0x3fff14ff, 0x2dff9000,0x7c404ffc,0xfc9affff,0x3a001fff,0x437fc47f,0xacfffffc, 0x02fffeb9,0x013ff600,0x01fff300,0xb802ffec,0x223fffff,0x6c40dfff, 0xf703ffff,0x17fec07f,0x7ccdffb0,0x3ffe005f,0x3221ff64,0xffffffff, 0x3202fffe,0x3fa202ff,0xecdfffff,0x805fffff,0xfd003ffc,0x1ff6003f, 0xff70bff1,0xbbffb9ff,0xffffffff,0xfffa8007,0xfdcbdfff,0x9001ffff, 0xbfffffff,0xfffffffb,0x7f540019,0x3ffe06ff,0x6ffc8002,0xfd007ffb, 0x4fff205f,0xfe803ffd,0x007ffb2f,0x3ee05ffd,0x00bffe4f,0x7e5bff20, 0xffe9804f,0x2fffffff,0x223ff400,0xcffc86ff,0xfffffffe,0x7ec0002f, 0x7e40004f,0x7ffd405f,0xfffd7000,0xeffffa89,0xffefffec,0x407ff503, 0x3ea04ffb,0x06ff99ff,0xd87ffee0,0x7fffc47f,0xfb1aceff,0x17fe405f, 0x3ffff620,0xffffffff,0x03ffb004,0x4003ffe0,0x1ffd87fd,0xffffffc8, 0xffffff54,0x3a60003d,0xffffffff,0x4001efff,0xfffffffa,0x1effffff, 0x3fff6000,0x007fff05,0x3f6bffb0,0x2fff803f,0x3f67ff90,0x2fff803f, 0xff007ffb,0x93fee05f,0xd8003fff,0x09ff95ff,0x3ffff620,0xe8000dff, 0x437fc47f,0xfff93ffc,0x000017df,0xfff80000,0xcccccccd,0x4004fffc, 0xfff30098,0xfb3dffff,0x13fea07f,0x7406ff88,0x00effdff,0xd8dfff10, 0x5ffff47f,0x80bffa01,0x93002ffc,0xdfffffff,0x3fe20059,0x0fff1006, 0x7cc3fec0,0x9df9506f,0xacefeb85,0x80155440,0xffffffda,0x540002ef, 0xfffffffd,0x700002ce,0xffb07fff,0x7fff000b,0xf100fff2,0x3ff205ff, 0x8807ff93,0x7ff92fff,0x02fff880,0x7fec9ff7,0x3fff8005,0x74009ff9, 0x0009aabf,0xff11ffa0,0x987ff90d,0x0000000a,0xffff5000,0xffffffff, 0x0000ffff,0x7bfd9710,0x540bff61,0x7fe404ff,0x3fffea02,0x3ff2000f, 0xf33fec2f,0xfff003ff,0x00ffe405,0x00efecc0,0x003ffb80,0x6c00bff5, 0x0bff507f,0x7f440000,0xefc8002f,0x3000001a,0x40003ff7,0x42ffe400, 0x2001fffb,0xff91fffb,0x2fff9809,0x3f27ffb0,0x7ffcc04f,0x9809ff92, 0xff702fff,0x00fffdc9,0x323fff70,0xff1004ff,0x7f400001,0x6437fc47, 0x000003ff,0x0009ddb0,0x7fffffec,0xffffffff,0xee8802ff,0xffe80006, 0x809ff502,0x7f406ff8,0x3f2004ff,0x27fd84ff,0xf9805ffb,0x3ff202ff, 0x3bff0001,0x01bfe000,0x2004ffb8,0x3ff207fd,0xd8800004,0xfd0004ff, 0x8000001b,0x54001efc,0x7fcc06ff,0x0efff987,0x27ffe880,0x7ec06ffb, 0x5ffb02ff,0xfb01bfee,0x1bfee5ff,0x205fffb0,0x3fe64ffb,0xfe8800ef, 0x013ff27f,0x00002fd4,0xdff11ffa,0x0007ff90,0x17ffa000,0x57ffc400, 0x99999999,0x805ffe99,0x0d447ff8,0x201fff00,0xfb804ff9,0x3fff601f, 0x3fa600df,0x7fd80eff,0x3601bff2,0x3f602fff,0xdc88001f,0x7dc005ff, 0x3ffa001f,0x01ff6002,0x0003dffd,0x017ffea0,0x04ffee80,0x3fb20000, 0xff1000ef,0x37fd403f,0x0aefffc8,0x45ffff50,0xf903fff9,0x3fa05fff, 0x07fff31f,0x4cbffff2,0xff903fff,0x3fee05ff,0x577ffe44,0x5ffff500, 0xc8027fe4,0x7400003f,0x437fc47f,0x00003ffc,0x00bffd00,0x001bfee0, 0x8803fff7,0x0fff87ff,0x103ffd40,0x3fa00fff,0xfffffb05,0xfb97bdff, 0x201bffff,0x3ffee7fd,0x3ffff602,0x001ffe03,0x8003ff20,0x3e6005fe, 0x3f6000ff,0x7fff4407,0xfb50001d,0x00001bff,0x00003ff9,0x003ffa80, 0xfe81bffa,0xfffd104f,0xffdb9dff,0xffd09fff,0xffd957df,0x6cd45ffb, 0x3ffa0fff,0xffecabef,0x3ffa2ffd,0xffecabef,0x55512ffd,0xfe889ffb, 0xedceffff,0x644fffff,0x00aaadff,0x800001ff,0x37fc47fe,0x0001ffe4, 0x05fcb800,0x007ffd00,0x404fff88,0xffe87ea8,0x13ffe204,0x037bffd0, 0x3f20ffd4,0xfffff73f,0x7fffffff,0x3e27fd80,0xba8acfff,0x44fffffe, 0x005ffeb9,0x03ffea20,0x5007fd40,0x0dffd557,0x5007fd80,0x57bffffd, 0x36aa6233,0x001effff,0x03ffb100,0x7e440000,0x3fe6003f,0xfec9acff, 0x3f6201ff,0xffffffff,0xfd303fff,0x3fffffff,0x3fe65ff7,0x7f4c5fff, 0x9fffffff,0x3fa62ffb,0x9fffffff,0xfff52ffb,0xfb109fff,0xffffffff, 0xff907fff,0xf305ffff,0xfd00000d,0xc86ff88f,0x000003ff,0x2000fe60, 0x8000fff9,0xbf007ffc,0x37bfff70,0x1ffffb71,0xfffffa80,0xf993f600, 0x7ff6443f,0x00beffff,0x7fd47fd8,0xefffffff,0x3e26ff9a,0x8002ffff, 0x03ffffff,0xfd013fa0,0x005fffff,0x5c007fd8,0xffffffff,0xffffffff, 0xed80003f,0x0005ffff,0xffffeb80,0xfffb8006,0x2fffffff,0xffffb500, 0x8039ffff,0xdfffffd8,0x3ee5ff71,0xfb105fff,0x2e3bffff,0x7fec42ff, 0xff71dfff,0x3ffffea5,0x3ff6a04f,0x1cffffff,0xffffff90,0x0009d505, 0xf88ffd00,0x03ffc86f,0x3f200000,0x6ffc8001,0x5fff3000,0xfb02fc80, 0xffffffff,0x3ee003df,0x3e600fff,0x26012e0f,0x6c0009aa,0xfffe987f, 0x7ffc4fff,0x07ffff11,0xfffff100,0x07fd4007,0x3fffffe0,0x07fd8004, 0xffedb880,0xffffffff,0xf00000bd,0x001bffff,0xffffb000,0x3660003d, 0x1effffff,0xaa998800,0x35300019,0x06aea200,0x0000d4c0,0x26200353, 0x80099999,0x019aa998,0x99999988,0x40000000,0x80998198,0x00000998, 0x000bfb00,0x8000fffe,0x3e206ffe,0x7fff5402,0x000bdfff,0x20065d44, 0x000001cb,0x2204ca80,0x220009a9,0x40000abc,0x59500018,0x03753300, 0x00265400,0xaaba9880,0x3000001a,0x00001353,0x00cd4c40,0x1baa8800, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0xa8002640,0x20000fff,0x0201fffb,0x01baa980,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x05ffd800,0x27ffc400,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x82620000,0x26000198,0x00000099,0x00000000, 0x10000000,0x30003999,0x00000799,0x1f774c00,0x22099100,0x3bae004c, 0x332a001e,0x00000001,0x00033322,0x66453326,0xcccccccc,0xcccccccc, 0xa8000001,0x000003cc,0x11776400,0x98000ddd,0x40002ccc,0xccccccc8, 0xabcccccc,0x776c4000,0x00000005,0xc882cca8,0x0099933c,0xa8999950, 0x4c0002cc,0x02ff8aff,0x07ffea00,0xff880000,0x5000005f,0x9800dfff, 0x4c006fff,0xa8006fff,0x7cc006ff,0xd10005ff,0x4005ffff,0x06fc83fe, 0x1fffff30,0x00fff600,0x6c3fffa0,0x7c400fff,0xfa8001ff,0xfffff17f, 0xffffffff,0x005fffff,0xffe9bffe,0x06ffb80f,0x05dd7100,0x98fff600, 0x640007ff,0x40006fff,0xfffffff8,0xffffffff,0xffb000df,0xf10009ff, 0x64000dff,0x6ff983ff,0xa800fff5,0x7e41ffff,0xfa80003f,0x80003fef, 0x0000efe9,0x01fff900,0xfff10000,0xfa800bff,0x3e6002ff,0x54004fff, 0x7ec006ff,0xfb0000ef,0x001fff9f,0x36ab3fee,0xff8803ff,0xb006ffbf, 0xf98007ff,0x5fff11ff,0x03fff100,0x22fff500,0xffffffff,0xffffffff, 0xffb802ff,0x03fff30f,0x4001bfee,0x002fbaec,0x3e63ffd8,0x7fc0007f, 0x20001fff,0xfffffff8,0xffffffff,0x7dc00eff,0x002ffddf,0x002fff98, 0xf307ff90,0x01ffeadf,0x81ffffa8,0x00003ffc,0x00007dd7,0x00003ec8, 0x001fff88,0xb5ffd000,0xfb8007ff,0x3fe6006f,0x2a001fff,0x3e2006ff, 0xf70000ff,0x03bfeadf,0x7ffffec0,0x9ffb005f,0x36017ff2,0x7ec003ff, 0x017ff23f,0x000fffc4,0xff8bffd4,0xaaaaaabf,0xaaaaaaaa,0x22ffe800, 0x3ee03ffd,0x1f88006f,0x3b20016e,0x01bba22e,0xffdffa80,0x3fe20005, 0x999999af,0xfffeba99,0x1fff300f,0x0003fff1,0x2000dff5,0xff983ffc, 0x200fff56,0x900efffa,0x540007ff,0x003ec85e,0x3ec85ea8,0x7ff70000, 0x3f200000,0x05fff15f,0x001ffd80,0x1dfffff3,0x01bfea00,0x0002ffc8, 0x7ec3fff3,0x3b6a005f,0xff9002de,0x01fff44d,0x8800fff6,0x3bfe25ff, 0x3fff1000,0x2fff5000,0x0001fff8,0x993fe600,0x7fdc05ff,0x21f88006, 0x0000006a,0xf8ffd800,0xf10000ff,0xfb8003ff,0xfff883ff,0x003bfee3, 0x000bff20,0x3ffd4000,0x077ffd40,0x7d400000,0x8004fd87,0x04fd87fa, 0x009db000,0x3bba6000,0x0037baa0,0x26009db0,0x04ffffff,0x200dff50, 0x20003ed8,0x4cc40998,0x30000001,0x19988133,0x001ffec0,0x77541bd7, 0x3ffe2001,0x7ffa8001,0x0003fff1,0x2e2f5c00,0x7fdc00de,0x31bb0006, 0x0000007d,0x96ff8800,0x220007ff,0xd8001fff,0x199885ff,0x00009998, 0x000009d9,0x501ffea0,0x0001dfff,0x217aa000,0xea8003ec,0x0003ec85, 0x00000000,0x80000000,0xfffcfff9,0x06ffa801,0x00000000,0x00000000, 0x07ffb000,0x44000000,0xa8001fff,0x3fff17ff,0x00000000,0x006ffb80, 0x019ffb10,0x80000000,0xdff34ffb,0x3ffe2000,0x7ffa8001,0x00000000, 0xf5000000,0x7ffd40ff,0x8800000e,0x98000ccc,0x199914cc,0x09993000, 0x3ffb2e60,0x00001cee,0x100ccc88,0x30001999,0x5ffe6999,0x5400effe, 0x199916ff,0x29993000,0x2a004cc9,0x36e601cc,0x59930bdf,0x5efedcc0, 0xfb059930,0xcb98007f,0x01ceeffe,0x003fff10,0x3e2fff50,0x880001ff, 0x98000ccc,0x1bfee4cc,0x88066644,0x26999300,0x32a004cc,0x3ffd001c, 0x40017ffc,0x8001fff8,0x5401fff9,0x730001cc,0x39ddffd9,0x20b32a00, 0xfff53cc8,0x03bffea0,0x40166540,0x8001fff8,0xfff17ffa,0xfff50003, 0xffffd880,0x1dffffff,0x3fe60000,0x3fff100f,0x2fff5000,0xfff37ff9, 0x16ffa809,0x50003fff,0x17ffcfff,0xa80fff80,0xffffffff,0xfa83ffa9, 0x9fffffff,0xffd83ffa,0xfffb1003,0xbfffffff,0x1fff8803,0x17ffa800, 0x00003fff,0x0003fff1,0x7fdcfff5,0x03fff106,0x7cfff500,0xfff002ff, 0x8fff3001,0x88005ffc,0xb8001fff,0x7e400fff,0x7ec4003f,0xffffffff, 0x7fe401df,0xf56ff983,0xdfff50ff,0x1ffe4001,0x00fffc40,0xf8bffd40, 0xfa8001ff,0x3ffea07f,0xffffffff,0x00003fff,0x2201fff3,0xa8001fff, 0x4fff37ff,0x2a01fffc,0x3fff16ff,0x4fff5000,0xfa805ffc,0xffff886f, 0xfdfffece,0x7fffc43f,0xfdfffece,0x03ffd83f,0xffffffa8,0xffffffff, 0x07ffe203,0x45ffea00,0x80001fff,0x8001fff8,0x3fee7ffa,0x03fff106, 0x64fff500,0xffa805ff,0x89ffb006,0x4000fff9,0x8001fff8,0xfc807ffe, 0x3fea003f,0xffffffff,0x3203ffff,0x6ff983ff,0xffa8fff5,0x7e4000ef, 0xfff8803f,0x7ffa8001,0x0003fff1,0x3f60fff5,0x2609cfff,0x05ffffeb, 0x0fff9800,0x003fff10,0x3e6fff50,0x077ff47f,0xff16ffa8,0xff50003f, 0x007ffccf,0x3fa0fff6,0x7ff440df,0x6fff43ff,0x7ffff440,0x403ffd83, 0x09cffffd,0x3ffffae6,0x03fff105,0x22fff500,0x80001fff,0x8001fff8, 0x3fee7ffa,0x03fff106,0x4cfff500,0x7ec00fff,0xfff8803f,0x003ffe81, 0x000fffc4,0x007fffd1,0x36007ff9,0x209cffff,0x5ffffeb9,0xf307ff90, 0xa9ffeadf,0x8000efff,0xf8803ffc,0xfa8001ff,0x03fff17f,0x50fff500, 0x1003dfff,0x0007fffd,0x100fff98,0x50003fff,0x1ffe6fff,0x2a09fff3, 0x3fff16ff,0x8fff5000,0x3e202ffe,0x2ffe40ff,0xc8ffffa0,0x7ff405ff, 0x03ffd83f,0x007bffea,0x20ffffa2,0x8001fff8,0xfff17ffa,0xdddddddd, 0x45dddddd,0x8001fff8,0x3fee7ffa,0x03fff106,0xe8fff500,0x3fe202ff, 0x6ffb800f,0x800fff70,0xaaabfff8,0xfdcaaaaa,0xf9006fff,0xfff5007f, 0xffd1003d,0x07ff907f,0x3feadff3,0x1fffff57,0x07ff9000,0x003fff10, 0x3e2fff50,0xfa8001ff,0x2fffc47f,0x3fff6200,0x3fe60000,0x3fff100f, 0x2fff5000,0xffc87ff9,0x16ffa82f,0x50003fff,0x5ffb8fff,0x3e17fea0, 0x7fd401ff,0x007ffe3f,0xfb07fff5,0x3ffe207f,0x7fec4005,0x0fffc40f, 0x8bffd400,0xffffffff,0xffffffff,0x07ffe22f,0xb9ffea00,0xfff106ff, 0xfff50003,0x2a05ffb8,0xffd005ff,0x0bffe207,0xfffff880,0xffffffff, 0x000dffff,0xf8807ff9,0x6c4005ff,0x7fe40fff,0xf56ff983,0xfffff5ff, 0xff9000df,0x3fff1007,0x2fff5000,0x8001fff8,0x7fe47ffa,0xff88000f, 0x3e60005f,0xfff100ff,0xfff50003,0x7f41ffe6,0xb7fd40ef,0x8001fff8, 0x7fc47ffa,0x85ffb00f,0xfd005ff9,0x017fe67f,0x7ec1fff4,0x1fff903f, 0xbfff1000,0x001fff88,0xff17ffa8,0xffffffff,0x5fffffff,0x000fffc4, 0xff73ffd4,0x07ffe20d,0x11ffea00,0x3f601fff,0xfff9802f,0x017ff600, 0xffffff88,0xffffffff,0x7e4002df,0x7ffe403f,0xfff88000,0x4c1ffe45, 0xffff56ff,0x9fff7bff,0x03ffc800,0x001fff88,0xff17ffa8,0xff50003f, 0x01fffccf,0x01fff700,0x03ffe600,0x000fffc4,0xff9bffd4,0x89fff307, 0xfff16ffa,0xfff50003,0xf107ffb0,0x09ff50ff,0x7d4fff20,0x7ff9004f, 0xf307ffb0,0x5c0007ff,0x3fe20fff,0xffa8001f,0x335fff17,0x33333333, 0x7fc41333,0xffa8001f,0x441bfee7,0xa8001fff,0x3ffd87ff,0x9007ff88, 0xffa80bff,0xfff1000f,0xffb9999b,0x640009ff,0x3fe603ff,0x3ee0003f, 0x0fff20ff,0x7fd5bfe6,0x3ff65fff,0x3ff2002f,0x1fff8803,0x17ffa800, 0x50003fff,0x3ffdcfff,0x3ffe2000,0xfff30003,0x07ffe201,0x4dffea00, 0x3ff207ff,0x45bfea2f,0xa8001fff,0x6ffa87ff,0xfc84ffb8,0x7ff7003f, 0x5c00fff2,0x3ffd83ff,0x0007ffb8,0xf11fffc4,0xf70003ff,0x07ffe2ff, 0x3ffe2000,0x7ffa8001,0x7c41bfee,0xfa8001ff,0x86ffa87f,0xff004ffb, 0x999999bf,0x009fff99,0xb807ffe2,0x8000dfff,0x3ee03ffc,0x7c40007f, 0x0fff23ff,0x7fd5bfe6,0x7ffc44ff,0x7ff9000f,0x03fff100,0x22fff500, 0xa8001fff,0x17ff27ff,0x1bffe000,0x07ffcc00,0x001fff88,0xff37ffa8, 0x0effe80f,0x3fe2dff5,0xffa8001f,0xe83fff07,0x2ffd81ff,0x367ff700, 0xff7002ff,0x907ffb07,0xf0000bff,0x1fff8dff,0x16ffc800,0x00003fff, 0x0003fff1,0x7fdcfff5,0x03fff106,0x20fff500,0x7ff41fff,0xffffa801, 0xffffffff,0xf1007fff,0xffa803ff,0xffc8006f,0x017ff203,0xc9bffe00, 0x6ff983ff,0x2a09fff5,0xf9005fff,0xfff1007f,0xfff50003,0x0007ffe2, 0xffe9ffea,0xffd80004,0xfff30007,0x07ffe201,0x4dffea00,0x7fcc07ff, 0x22dff54f,0xa8001fff,0x9ff907ff,0xfd837fcc,0x7ff7003f,0x5c00fff6, 0x3ffd83ff,0x0004ffe8,0x7fc7ffd8,0xffc8002f,0x003fff15,0x03fff100, 0x5cfff500,0xfff106ff,0xfff50003,0xf993ff20,0xfffb006f,0xffffffff, 0x005fffff,0x7003fff1,0xc800bfff,0x3ffa03ff,0xffd80004,0x260fff27, 0x0fff56ff,0x803fffc8,0xf8803ffc,0xfa8001ff,0x03fff17f,0x7cfff500, 0xc80003ff,0xf30007ff,0x3fe201ff,0xffa8001f,0x900fff37,0xdff55fff, 0x0007ffe2,0x7cc1ffea,0x40fff26f,0xf9004ffc,0x013ff27f,0x7ec1ffe4, 0x03fff83f,0x47ffc800,0xd8003ffe,0x3fff14ff,0xfff10000,0xfff50003, 0xf8837fdc,0xfa8001ff,0x4dff307f,0xf8803ffc,0x99999aff,0xffe99999, 0x1fff8805,0x07fffb00,0xf01ffe40,0x900007ff,0x1ffe4fff,0xffab7fcc, 0x1fffe807,0x401ffe40,0x8001fff8,0xfff17ffa,0xfff50003,0x000bffe2, 0x003ffea0,0x403ffe60,0x8001fff8,0xfff37ffa,0x2bfffa00,0x3fff16ff, 0x0fff5000,0xffe8fff4,0x00bff700,0x7fdcfffa,0x07ffd005,0xff887ffb, 0xfa80002f,0x17ff60ff,0x44fffe00,0x80001fff,0x8001fff8,0x3fee7ffa, 0x03fff106,0x40fff500,0x1ffd1ffe,0x00dff700,0x401fffb8,0x1001fff8, 0x2003ffff,0xff103ffc,0xf500005f,0x0fff21ff,0x7fd5bfe6,0xefff9807, 0x00fff200,0x0007ffe2,0x7fc5ffea,0xffa8001f,0x003fff37,0x03fff300, 0x01fff300,0x0007ffe2,0x7fcdffea,0xdfff3007,0x3ffe2dff,0x7ffa8001, 0x3e6ffee0,0x3ffe205f,0x9fffcc01,0x4c01fff8,0xffd83fff,0x00fffcc3, 0x0fffcc00,0x4003fff7,0xff12fffb,0xf100003f,0xf50003ff,0x837fdcff, 0x8001fff8,0x3ee07ffa,0x005ff9bf,0x88007ffd,0x7c404fff,0x3ea001ff, 0xff9006ff,0x07ffe607,0x3ffe6000,0xf307ff91,0x01ffeadf,0x902fffdc, 0xff1007ff,0xff50003f,0x007ffe2f,0x7c5ffea0,0xa80002ff,0x98000fff, 0xff100fff,0xff50003f,0x801ffe6f,0x16fffffc,0x50003fff,0x7fc40fff, 0x6402ffbe,0x7fec05ff,0x017ff23f,0xfb07fffb,0x2fff887f,0xfffa8000, 0x03fffe20,0x89bffa20,0x80001fff,0x8001fff8,0x3fee7ffa,0x03fff106, 0x40fff500,0x2ffbeff8,0x00fff980,0x407ffc80,0x4001fff8,0xc803fffd, 0xfff103ff,0xff500005,0x20fff21f,0xfff56ff9,0x1ffff400,0x8803ffc8, 0xb8001fff,0x3fff17ff,0x4fff7000,0x80003fff,0x30007ffc,0x3e201fff, 0xfb8001ff,0x00fff37f,0xb7ffff44,0x8001fff8,0x7ec07ffb,0xf8807fff, 0x7ec40dff,0x3fe23fff,0x7fec40df,0x3ffd83ff,0x0003fff8,0xfc87ffc8, 0xf500aeff,0x7fc47fff,0xf880001f,0xfb8001ff,0x41bfee7f,0x8001fff8, 0x7ec07ffb,0xf9007fff,0x3e6000df,0x3fe202ff,0x7fc4001f,0x7fe400ff, 0x00fffe03,0xc9fff200,0x6ff983ff,0x4400fff5,0xfc81ffff,0xfff8803f, 0x6ffc8001,0x0003fff1,0x7ffcdff9,0xffd80004,0xfff30006,0x07ffe201, 0x4dbff200,0x7cc007ff,0xfff16fff,0xdff90003,0x4ffffa80,0xdffff500, 0xffdfffd9,0xeffffa87,0xffefffec,0xf83ffd83,0xd80004ff,0xffe886ff, 0xfedcefff,0x7c44ffff,0xffffffff,0xffffffff,0x03fff17f,0x5cdff900, 0xfff106ff,0xdff90003,0x4ffffa80,0x007fff00,0x1037ff40,0x70003fff, 0xfc80bfff,0x13ffe03f,0x9bff6000,0xff983ffc,0x800fff56,0xfc86fffa, 0x5fff003f,0x4dff9000,0xc8002fff,0x1bff26ff,0x13ffa000,0x07ffcc00, 0x0005fff0,0x3fe6dff9,0xfffc8007,0x000bffe6,0x3e01bff2,0x26001fff, 0xefffffff,0xf983ffd9,0x9effffff,0xffd83ffd,0x006ffc83,0x204ffe80, 0xfffffffc,0x884fffff,0xffffffff,0xffffffff,0x0bffe7ff,0xb9bff200, 0x3ffe06ff,0x6ffc8002,0x01ffff80,0x000fffa8,0x407ffee0,0x0001fff8, 0x6405fffd,0x3ff203ff,0xffe80006,0x260fff24,0x0fff56ff,0x89fffb00, 0xff003ffc,0xffb0007f,0x001fffcb,0xff32ffec,0x7d40003f,0x065d41ff, 0x401fff50,0xd8003fff,0x0fff35ff,0x4dffd100,0xd8003fff,0xffc805ff, 0xecb88006,0x5ffb0bdf,0x37fb2e20,0xb05ffb0b,0xfff307ff,0x7fd40003, 0x7f65401f,0x0cffffff,0xffffff10,0xffffffff,0x7fcfffff,0xffd8003f, 0xf81bfee5,0xfd8003ff,0x6ffc805f,0x00bffb00,0x04fff880,0x0003fff1, 0x403fffe6,0x3e603ffc,0x2a0001ff,0x3ff21fff,0xf56ff983,0xff1000ff, 0x1ffe45ff,0x005ffd80,0x3f63fff8,0xfff8005f,0x0037ffc3,0xfd0dffd0, 0x3ffd403f,0x0017ff60,0x1000fffe,0x5ffd8003,0x03fff800,0x0003ffb8, 0x005ffb00,0x4c17fec0,0x037ffc00,0x00dffd00,0x009efc88,0x06f98000, 0x4002ffec,0x0ff23fff,0x000bffb0,0xf7007fff,0x0000007f,0x0000ff10, 0x64000062,0x7ffc03ff,0x3ffa0006,0x37fcc006,0x20002600,0x3ee002fd, 0x3ee001ff,0x3ffee1ff,0x3ffee001,0x01fffd41,0x41fffdc0,0x3ee02ffd, 0x7ffdc07f,0x3ffee001,0x77fec001,0x1fffb802,0x07ffee00,0x2003ffa0, 0x3fa001a8,0x4003511f,0x7fcc1ffe,0xfffa80df,0xfffb8003,0x03fb8003, 0x17ea0000,0x003fff70,0xfb0fffdc,0x1fffb803,0x07ffee00,0x0003ffa0, 0x17e60000,0x77fec000,0x3ff60002,0x1fffd403,0x1fffdc00,0x01bfea00, 0x00dfff98,0x4c001ff0,0x8800efff,0x7fcc7ffe,0xfe8800ef,0x9fffb07f, 0x2fffe400,0x3a05ffc8,0x7fcc05ff,0xfe8800ef,0xfeb8007f,0x7fcc01ff, 0xfe8800ef,0x4ffa807f,0x003ffe00,0xfff8fff7,0x43ffdc00,0xb05ffed8, 0x64009fff,0x90005fff,0x4000007f,0x7fcc03fb,0xfe8800ef,0x2007fc7f, 0x800efff9,0xa807ffe8,0x000004ff,0x000bf500,0x07fffae0,0x017fec00, 0x0027ffec,0x000bfff9,0x4400bff5,0x8805ffed,0xffc8007f,0xff500aef, 0xfff905ff,0x3fea015d,0xffd102ff,0x7f4c03df,0xff500fff,0xfffc819f, 0xefffc802,0xffff500a,0x7fcc0005,0xefffc805,0xffff500a,0x1ffe8805, 0x813ffa00,0x7f44fff8,0x3ffe204f,0x40ffe404,0x01efffe8,0x03ffffa6, 0x002fec00,0x00dfb000,0x015dfff9,0x88bfffea,0xffc803ff,0xff500aef, 0xfe8805ff,0x0000001f,0x0001ff70,0x002ffcc0,0x8801ffe8,0x201efffe, 0x00ffffe9,0x004ffc80,0x8803ffb0,0x744002ff,0xdcefffff,0x04fffffe, 0xdfffffd1,0xfffffdb9,0xfffe8809,0xffdccdff,0x6c00efff,0xffddffff, 0xfd1005ff,0xdb9dffff,0x009fffff,0x804ffb80,0xefffffe8,0xfffffedc, 0xfffb9b04,0xfffb800b,0xffdb89bd,0xdfffb85f,0xfffdb89b,0x0fff4405, 0xfffffe88,0xffffdccd,0x2e0000ef,0x03a88bff,0x17ff5000,0xfffd10ea, 0xffdb9dff,0xdfd09fff,0xfd106e25,0xdb9dffff,0x209fffff,0x05fffdcd, 0x22000000,0x05b8adff,0x013fee00,0x07ffd9a8,0x3ffffa20,0xfffdccdf, 0x26000eff,0x002fffb9,0x801ffe88,0x03711efe,0xfffffd88,0x3fffffff, 0x7fffec40,0xffffffff,0x3fff2003,0xffffffff,0xfff3004f,0x0bffffff, 0xffffd880,0xffffffff,0xfeea8003,0xb1000fff,0xffffffff,0x7c07ffff, 0x000effff,0xffffffd8,0x3605ffff,0xffffffff,0xffdb05ff,0xff900bff, 0xffffffff,0x100009ff,0x0dffffff,0x3ffe2000,0xfd886fff,0xffffffff, 0xff503fff,0xb107ffff,0xffffffff,0x7c07ffff,0x000effff,0x7f400000, 0x2007ffff,0x0ffffeea,0xfffff300,0xfff90009,0xffffffff,0xffd0009f, 0x36001fff,0x005ffffe,0x7ffffff7,0x3fff6a00,0x01cfffff,0x3ffff6a0, 0x001cffff,0xfffffb88,0x4000bfff,0xefffffc8,0x3f6a0004,0xcfffffff, 0xfff90001,0xb50005df,0xffffffff,0xfffe8039,0x3aa0000e,0x4dffffff, 0xffffea80,0x3fe04dff,0x1000dfff,0xfffffff7,0x4000017f,0x02dfffeb, 0x3ffaa000,0x3f6a03ff,0xcfffffff,0x7fffe401,0x3ff6a01c,0x1cffffff, 0x077fff40,0x40000000,0x02efffc9,0x3bffff20,0x3ffee002,0x710000df, 0xffffffff,0xff100017,0x7c003dff,0x000dffff,0x19dfff91,0xaa998800, 0x4c400019,0x00019aa9,0x026aa620,0x04d4c000,0x53310000,0x10000335, 0x00003353,0x03355331,0x0005d440,0x03775300,0x06eea600,0x004d4cc0, 0x13553100,0x29800000,0x54c00000,0x2a662001,0x1a80019a,0x554cc400, 0x2ea20019,0x00000000,0x22000300,0x880019a9,0x00001aba,0x0026aa62, 0x026eaa00,0x01353300,0x00005400,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x02cca800,0x00999300,0xeeea8000,0x00000002, 0x00000000,0x26201000,0x0a980000,0xa8002644,0x00005fff,0x00000000, 0xf31fffc4,0x220003ff,0x05e980ee,0x00000000,0x00000000,0x00000000, 0x32000000,0x00003fff,0x20000000,0x2002eeea,0x4c001998,0x0000efff, 0x27ffd400,0x001ffe40,0x0007ffa8,0x02fff400,0x0dfff500,0x7ffd4000, 0xfff98004,0xfd98000f,0x013f61cf,0xdfffea80,0x8005fc8a,0x04fffff8, 0xfff98000,0x3fff2005,0x7ffd4003,0x0007ffd0,0x5fd84fe8,0x03fffb80, 0x37ffd400,0x7c400000,0x000005ff,0x000bfff1,0x002fffe8,0xfffff500, 0x7e400005,0x000002ff,0x800fffee,0x22007ffe,0x005fffff,0x2fff4000, 0x003ffc80,0x000fff50,0x07ffd400,0xffff8800,0xfd00005f,0xfd1000bf, 0x8800dfff,0xefffffff,0x3a0001ff,0xffffffff,0xffe8003f,0x0002ffeb, 0x0037fec0,0x40037fec,0x5ffbdffc,0xeffa8000,0x801ffecc,0x40004fff, 0x05fffff9,0x7fe40000,0x9000000e,0x40001fff,0x01fffffc,0x57ffc400, 0x00000fff,0x0001bffa,0x03fffb80,0x801fffa0,0x4ffcbffe,0xff500000, 0x3ff2001d,0xfff50003,0x7f400000,0x3fa0001f,0x003ffdaf,0x007ffcc0, 0x7de7fec0,0x3bea004f,0x6ffffda9,0x43fe6000,0x00dfffca,0xf8affe40, 0x300001ff,0x10001fff,0xb0005ffd,0x000dffff,0x7ffffdc0,0x6ffb803f, 0x7ff44000,0x0003ffda,0x03fff100,0x3fe20000,0x3ea0001f,0x00eff9ef, 0x54fffa00,0x00000eff,0x0003fff1,0x0fffee00,0x007ffe80,0x3fa2dff9, 0xd800002f,0x3f2001ff,0xff50003f,0x2a00000f,0x360003ff,0x3fff15ff, 0x0ffec000,0xd37fdc00,0x3b2007ff,0x000e5c43,0x0540aa20,0x07ffd400, 0x0001dff7,0x0005ff90,0x40037fc4,0x000ffff8,0x5e65c400,0x01ffd000, 0x15ffd800,0x00003fff,0x0007ff90,0x01ffdc00,0x23fff300,0xb0005ffc, 0x5ffd8dff,0x3fe60000,0x31000005,0x76c00133,0xeee9805e,0x0037baa1, 0x02ee8800,0x001ffe40,0x0007ffa8,0x00033100,0xd506f74c,0xd10001bd, 0xdd10005d,0x06f74c3d,0x00000000,0x00000000,0x7dd10000,0x3dd30000, 0x00000000,0x774c0000,0x77540002,0x037baa0d,0x09db0000,0x4ed80000, 0x1f76c000,0x0000bbb6,0xa8000000,0x000000ee,0x00000000,0x00000000, 0x003ffc80,0x000fff50,0x00000000,0x00000000,0xb9800000,0x1ceeffec, 0x01999100,0x80999300,0xbdefedb9,0x0000000a,0x73000000,0x39ddffd9, 0x03332200,0x01332600,0x00000000,0x00000000,0x00000000,0xdd930000, 0x0017bdff,0x00000000,0x3bffbb26,0x665400bd,0xfd973003,0x00039ddf, 0x3ffbb260,0x7e400bde,0x3332203f,0x001ffea3,0x2004cc98,0x99911cca, 0x99930001,0xefedb980,0x54000abd,0x6c4003cc,0xffffffff,0x7c401dff, 0xfa8001ff,0xfffd107f,0x7fffffff,0x00e66540,0x03999500,0xb1007995, 0xffffffff,0xf8803bff,0xfa8001ff,0x30f32a7f,0x64400999,0x664004cc, 0x9999910c,0x99999999,0x99100157,0x99999999,0x99999999,0x33333223, 0xcccccccc,0x401ccccc,0xffffffea,0x000bffff,0x016664c0,0xfffea800, 0xbfffffff,0x80bff900,0xffffffd8,0x001dffff,0xfffffd50,0x017fffff, 0x7440fff2,0x3fea0eff,0x7ffc0007,0x21fff002,0x8001fff8,0xfd107ffa, 0xffffffff,0x7fe4007f,0x3ffea005,0xffffffff,0x3e203fff,0xfa8001ff, 0xffff987f,0xffffffff,0xdfff104f,0x3ffe2000,0x80bff906,0xfffffffa, 0x3fffffff,0x007ffe20,0xfc9ffea0,0x07ffcc5f,0x2ffffa80,0x21fff300, 0xfffffff8,0xffffffff,0x3fe200df,0xffffffff,0xffffffff,0xffffff12, 0xffffffff,0x6405ffff,0xfeffffff,0x00efffff,0x1bfff200,0x3fff2000, 0xffffefff,0xffc80eff,0x3fffea05,0xffffffff,0x7e4003ff,0xffefffff, 0xc80effff,0xffe883ff,0x03ffd40e,0x017ff200,0xff89bfea,0xffa8001f, 0xfffff987,0xffffffff,0x0bff9004,0x33ffff60,0x3ffae609,0xfff105ff, 0xfff50003,0x1bffff98,0x37fff544,0x004fffb8,0x900fffd8,0x7fec0bff, 0x2e609cff,0x105ffffe,0x50003fff,0x2ffe4fff,0xc8017ffc,0x7004ffff, 0x7ffc4dff,0xffffffff,0x0effffff,0xffffff10,0xffffffff,0x3e25ffff, 0xffffffff,0xffffffff,0xffffd02f,0xfffd5017,0x7ffc000d,0x3a0001ff, 0xa80bffff,0xfc86fffe,0xffffb05f,0x7f5cc139,0xfd005fff,0xd5017fff, 0xff90dfff,0x0effe887,0x0007ffa8,0x2007ffcc,0x3fe23ffd,0xffa8001f, 0x5ffffcc7,0x7fff5441,0x05ffc806,0x01efffa8,0x83fffe88,0x8001fff8, 0x7fe47ffa,0x3fff7006,0x007fffa0,0x203fffa8,0xff505ffc,0xfd1003df, 0xfff107ff,0xfff50003,0x7ec2ffe4,0xffff004f,0x3ff600df,0x26bffe23, 0xa9999999,0x80ffffeb,0xaaabfff8,0xaaaaaaaa,0xfff10aaa,0x55555557, 0x15555555,0x009fff90,0x0013fff2,0x17ff7fea,0x27ffe400,0x44fffc80, 0xffa85ffc,0xfe8801ef,0x7fe403ff,0xfff9004f,0x223ffc89,0xf500dffe, 0xfd0000ff,0x7ffc405f,0x007ffe20,0xf91ffea0,0x3fee00df,0x2ffe401f, 0x017ffe20,0x81fffb10,0x8001fff8,0x7ffc7ffa,0x13ff6000,0x8037ffc4, 0x6405fff8,0xfff885ff,0x7fec4005,0x0fffc40f,0x93ffd400,0xdff70bff, 0xfd9ff300,0x3fff001f,0x000fffc4,0x220fffee,0x80001fff,0x0001fff8, 0x013ffea0,0x001fffb0,0xfff8ffd8,0x7ffd4000,0x7ffec004,0xf117ff20, 0xd8800bff,0xff500fff,0xffd8009f,0x44fff20f,0x7d405ffe,0xfb80007f, 0x17fea05f,0x0003fff1,0xfff8fff5,0x13ff6000,0xc80bff90,0x88000fff, 0x7fc45fff,0xffa8001f,0x001ffe67,0x7dc0dff5,0xffd804ff,0x2ffe400f, 0x0007ffe4,0x222fffc4,0xa8001fff,0x17ff27ff,0x7003ffe6,0x07ff95ff, 0x7c47ff98,0xfd8001ff,0x1fff885f,0xfff88000,0x3fa00001,0xff88006f, 0x3fe2004f,0x8007ff96,0x88006ffe,0x3ff24fff,0x007ffe45,0x82fffc40, 0x88006ffe,0x3ff24fff,0x805ffe8b,0x80007ffa,0xfb00fff8,0x1fff885f, 0x27ffa800,0x54007ff9,0x7fe406ff,0x0fffe605,0x0fffb800,0x0007ffe2, 0xff99ffea,0x37a2000f,0x3fffa00c,0x0bffea01,0xf317ff20,0x5c0007ff, 0x3fe20fff,0xffa8001f,0x7c17ff27,0x7fec02ff,0x5c05ff98,0x7ffc45ff, 0x7ffa8001,0x001fff88,0x01fff880,0x5fff3000,0x0f7f2000,0xf34ffb80, 0x7fcc00df,0xbf90002f,0xf32ffe47,0x5c0007ff,0x7fcc0fff,0xbf90002f, 0x7f67fe47,0xffa800ff,0xffb00007,0x10fff107,0x50003fff,0x7ffccfff, 0x337a2000,0x817ff200,0x40007ffb,0x3e23fff8,0xfa8001ff,0x027ffc7f, 0xfff88000,0x0bfff106,0xf717ff20,0xf88000ff,0x3ffe23ff,0x7ffa8001, 0x7ec17ff2,0xf37fc03f,0x3ffd80ff,0x000fffc4,0x220fffcc,0x80001fff, 0x0001fff8,0x000fff90,0xffe80004,0x400bffe1,0x20007ffc,0x5cbff900, 0x440007ff,0x7fe43fff,0x64020007,0x5fffffff,0x007ffa80,0x70dff500, 0xfff109ff,0xfff50003,0x0004fff8,0x40bff900,0x80005ffc,0x3fe26fff, 0xffa8001f,0x067ffec7,0x7fdc0000,0x0fffd83f,0xc8bff900,0xf80005ff, 0x3ffe26ff,0x7ffa8001,0x7d417ff2,0x93fea05f,0x3fe01ffd,0x0fffc40f, 0x07ffdc00,0x0007ffe2,0x007ffe20,0x037ff400,0x3e600000,0x02ffe47f, 0x0006ffe8,0x325ffc80,0xf80005ff,0x37ff46ff,0x7fe40000,0x02fffeff, 0x0003ffd4,0xfe83fff0,0x1fff881f,0x47ffa800,0x000cfffd,0x02ffe400, 0x00009ffd,0x7fc4fffb,0xffa8001f,0x7ffffcc7,0x200001be,0x3e60fffe, 0x3f2002ff,0x027ff45f,0x13ffec00,0x50003fff,0x2ffe4fff,0x3207ff88, 0x13fee1ff,0x7c437fcc,0xfe8001ff,0x1fff887f,0xfff88000,0xfff00001, 0x8000000b,0x7fcc4ffd,0x5fff800f,0xffc80000,0x0013ffa5,0xff1fff60, 0x900000bf,0x3ff2bfff,0x1ffea00f,0x4ffc8000,0x7c41bfe6,0xfa8001ff, 0x7fffcc7f,0x80001bef,0x3fe05ffc,0xfc80003f,0x07ffe27f,0x21ffea00, 0xffffffe8,0x20001bdf,0x3fa5fff8,0x7fe4004f,0x001fffc5,0xf13ffe40, 0xf50003ff,0x02ffe4ff,0x3fa03ffd,0xb837fcc7,0xfff884ff,0x3ffa2001, 0x1fff883f,0xfff88000,0xfff00001,0x40000007,0xfe81fff8,0x3fff803f, 0xffc80000,0x000fffe5,0xff1fff20,0x9000007f,0x7ff44bff,0x01ffea05, 0x26ff9800,0xff103ffc,0xff50003f,0xffffd10f,0x0037bfff,0x220bff90, 0x80002fff,0xff10fffa,0xff50003f,0x3fff220f,0x3effffff,0x5fff7000, 0x9000dff7,0x7ffc4bff,0xffa80002,0x03fff10f,0x64fff500,0x3ff205ff, 0xf85ff883,0x2ffd80ff,0xaabfff88,0xdcaaaaaa,0xf106ffff,0xddddddff, 0xdddddddd,0x777ffc45,0xeeeeeeee,0x3e22eeee,0x000002ff,0x5c1bfee0, 0x7fc407ff,0xc800002f,0x5fff15ff,0xfff50000,0x00bffe21,0x0fff2000, 0x2a05fff5,0x400007ff,0x1ffd1ffe,0x007ffe20,0x441ffea0,0xfffffffc, 0x32003eff,0xfff305ff,0xff300003,0x07ffe23f,0x01ffea00,0xfffffb71, 0x0001bfff,0x3fffdffd,0x4bff9000,0x0001fff9,0xf11fff98,0xf50003ff, 0x02ffe4ff,0xff70bff5,0xf05ff907,0xfff101ff,0xffffffff,0x1bffffff, 0x3ffffe20,0xffffffff,0x3e22ffff,0xffffffff,0xffffffff,0x00bffe22, 0xffe80000,0x05fff103,0x0017ffc4,0x9affe400,0x80001fff,0xff11fff9, 0x9000005f,0xfffb07ff,0x00fff501,0x9bffb800,0x3fe205ff,0xffa8001f, 0x7fedc407,0x0dffffff,0x105ffc80,0x00005fff,0x3e21fff5,0xfa8001ff, 0x6dcc007f,0x01efffff,0x7ffffcc0,0xbff90004,0x0017ffc4,0x887ffd40, 0xa8001fff,0x17ff27ff,0xfd87ff88,0x45ffa80f,0xff106ff9,0xffffffff, 0x05bfffff,0xffffff88,0xffffffff,0x3fe22fff,0xffffffff,0x2fffffff, 0x000fffe2,0x7ffcc000,0x817ff600,0x0003fff8,0xf15ffc80,0x500005ff, 0x3fe21fff,0xc800003f,0xfff883ff,0x007ffa85,0x5f7fc400,0x3fe202ff, 0xffa8001f,0x7edcc007,0x401effff,0x3fe05ffc,0xfc80003f,0x07ffe27f, 0x01ffee00,0xffffd500,0xdfff7000,0x2ffe4000,0x0000fffe,0xff89fff2, 0xffb8001f,0xd017ff27,0x06ff81ff,0xffb8fff1,0x9bfff103,0xffffb999, 0x7ffc4009,0x9999999a,0x20999999,0x999afff8,0x99999999,0x2fffc099, 0xfc800000,0x7ffd405f,0x017ffe00,0x97ff2000,0x80003fff,0x7ffc7ffc, 0xfc800005,0x5fff503f,0x0007ffa8,0x7ffffd80,0x00fffc40,0x003ffdc0, 0x1ffffaa0,0x7c0bff90,0xd80004ff,0x3ffe26ff,0x6ffc8001,0xfff90000, 0x5fff0005,0x2ffe4000,0x00013ffe,0xff89bff6,0xffc8001f,0x9017ff26, 0x27fcc5ff,0x7ec1ffd0,0x3fff101f,0x06fffdc0,0x00fffc40,0x0fffc400, 0x6ffe8000,0xff000000,0x999999bf,0x409fff99,0x00006ffe,0x3fe5ffc8, 0xfd80004f,0x037ff46f,0x1ffe4000,0x541fffb0,0xffffffff,0x4fffffff, 0x27fffd40,0x007ffe20,0x001bff20,0x017ffe40,0x7e40bff9,0xfe80006f, 0x017ffc4f,0xa8b7fe40,0xffb0002a,0x5fff0009,0x2ffe4000,0x0001bff2, 0xfff13ffa,0xdff90005,0x2602ffe4,0x0bff24ff,0x3fe2ffc8,0x07ffe207, 0x00dfff50,0x0003fff1,0x003fff10,0x01fff200,0x00ace880,0xfffffff5, 0xffffffff,0x03ffe40f,0x2159d100,0x3ff25ffc,0xffe80006,0x003ffe44, 0x32159d10,0x3fe203ff,0x3fffea5f,0xffffffff,0xff804fff,0xfff801ff, 0x6ffc8002,0x20005551,0x3f204ffd,0x3ffe605f,0x3fea0001,0x01fffc1f, 0xf8affec0,0xfb8000ff,0xfff8006f,0x3ff20002,0x00fffcc5,0x83fff500, 0xd8003fff,0x17ff25ff,0xffe9bfe0,0x453fe600,0x3fe205ff,0xfffb801f, 0x0fffc405,0x7ffc4000,0xff300001,0x3ee0003f,0xfffb00ff,0xffffffff, 0x205fffff,0x0001fff9,0x3f21fff7,0x07ffe65f,0x1fffa800,0x000fffcc, 0xf90fffb8,0xfffb807f,0xffffff52,0xffffffff,0xdff9009f,0x00fffe00, 0x7c57ff60,0xfb8000ff,0x17ff206f,0x000dfff0,0x7ec37ff4,0xfff8005f, 0x000fffa3,0x20017fea,0x20002fff,0xfff85ffc,0x3ffa0006,0x005ffd86, 0x3f23fff8,0x8ffd805f,0xff805ff8,0x4405ff56,0xfb001fff,0x7fc407ff, 0xf880001f,0x200001ff,0xd0005fff,0x3fe20bff,0x999999af,0x5ffe9999, 0x0017ffe0,0xff92fff4,0x006fff8b,0x7c1bffa0,0xfd0005ff,0x002600bf, 0x00013100,0xb003ffb8,0xff000bff,0x01fff47f,0x902ffd40,0xffa80bff, 0xffb8003f,0x1fffb83f,0x87ffee00,0xd8006ffc,0xff8003ff,0x3f20002f, 0x3fffa85f,0x3fffb800,0x001fffb8,0xfc87ffee,0x9ffb805f,0xfd803ffa, 0x4401ff97,0xf1001fff,0x3e203fff,0x880001ff,0x00001fff,0x0007ffee, 0x2e05fff7,0x7dc006ff,0xfff701ff,0xfffb8003,0xf517ff22,0xf70007ff, 0x3fee07ff,0x7fdc001f,0xfff9802f,0xffa8000d,0xfe8000cf,0xfff7000f, 0x7ffdc003,0x001bff21,0xfc80fff6,0xfffd805f,0x3fff2004,0x1dfff305, 0x8fffd100,0x000efff9,0x0001fff5,0x40005fff,0xffb05ffc,0x7fe4009f, 0xdfff305f,0xfffd1001,0x9805ffc8,0x01ffcbff,0x6fe9ffb8,0x00fffc40, 0x20dfff50,0x0001fff8,0x001fff88,0x0ffff400,0x06fff980,0x1000fffa, 0x7f409fff,0xff3001ff,0x85ffc8df,0x2004fffd,0x7405fffc,0xf3001fff, 0x36200dff,0x98005ffe,0x4004ffed,0x26004ffa,0x8800efff,0x7fcc7ffe, 0xff5000ef,0x2ffe401f,0x77fff440,0x3fffa601,0x3fff200f,0xfff500ae, 0xffffd05f,0x3ff62015,0xfff0006f,0x7fe40005,0xdfffd105,0x7fff4c03, 0x3fff200f,0xfff500ae,0x05ffc85f,0x0ffdbff0,0x3feffe60,0x0fffc404, 0x0ffff600,0x0007ffe2,0x007ffe20,0xffff3000,0x3ff22059,0xfff300ff, 0xfff90001,0x67fffcc0,0xffff9102,0x885ffc81,0x201efffe,0x00ffffe9, 0x167fffcc,0x0ffffc88,0x01ffc800,0x003ff600,0x000fff44,0x02bbfff2, 0x417fffd4,0x00affffe,0x80dfffb1,0xd1005ffc,0x99bfffff,0x1dfffffb, 0xffffe880,0xfffedcef,0xffd104ff,0xfd9bffff,0x000bffff,0x00017ffc, 0x7440bff9,0xccdfffff,0x0efffffd,0x7ffff440,0xfffedcef,0x5ffc84ff, 0x9ffffb00,0x7ffffc00,0x0fffc402,0x3fffe200,0x00fffc40,0x0fffc400, 0x7fd40000,0xdcbdffff,0x201fffff,0x30006ffc,0x7d405fff,0xcbdfffff, 0x81fffffd,0xfd105ffc,0xb99bffff,0x01dfffff,0x3ffffea0,0xfffdcbdf, 0xe88001ff,0xf10001ff,0x6e6c01ff,0x88005fff,0xcefffffe,0x4fffffed, 0xfffffd10,0xffffd9bf,0xbff900bf,0xffffc800,0xffffffff,0x3ff62004, 0xffffffff,0x7ec403ff,0xffffffff,0x40004fff,0x20002fff,0xfc805ffc, 0xffffffff,0x22004fff,0xfffffffd,0x903fffff,0x3ee00bff,0x32002fff, 0x4400ffff,0xb8001fff,0x7fc45fff,0xffffffff,0xffffffff,0xffffff17, 0xffffffff,0x4c0fffff,0xfffffffe,0x401effff,0x20003fff,0x74c06ffe, 0xffffffff,0xf901efff,0xfffc80bf,0xffffffff,0xfe98004f,0xffffffff, 0x36001eff,0x005ffffe,0x27ffff74,0x3bffffe0,0xffb10000,0xffffffff, 0xfd8807ff,0xffffffff,0xf9004fff,0xf71000bf,0x7fffffff,0x3f6a0001, 0xcfffffff,0x3ff26001,0x2cefffff,0x2fff8000,0x17ff2000,0x7fffdc40, 0x000bffff,0xfffffb50,0x64039fff,0xff3005ff,0x7d4001ff,0xff8805ff, 0xffd0001f,0x7fffc45f,0xffffffff,0x17ffffff,0xffffffff,0xffffffff, 0xfb500fff,0x5dffffff,0x01fff500,0x0fffdc00,0x7fffed40,0x6402efff, 0xfb8805ff,0xbfffffff,0x7ed40000,0x2effffff,0xfffff800,0x3fe2000d, 0x7400cfff,0x0000efff,0xfffffda8,0x2001cfff,0xffffffc9,0x32002cef, 0x440005ff,0x00009aa9,0x26aa6620,0xa9980001,0xf800001a,0x320002ff, 0x988005ff,0x000009aa,0x066aa662,0x002ffe40,0x8800dfff,0xf8803fff, 0xf30001ff,0x3fe21fff,0xffffffff,0xffffffff,0xffffff17,0xffffffff, 0x800fffff,0x4001aa99,0x40005ffd,0x4004fff8,0x0001aa99,0x35531000, 0x26000001,0x40001aa9,0x00009a99,0x20013533,0x00000ba8,0x19aa9988, 0xaa998000,0x00000001,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x6c000000,0x005fd03f, 0x21fffa80,0x0000effc,0x00000000,0xffe80000,0x0000000f,0x1ed80000, 0x00003db0,0x00000000,0x745ffd80,0x3a0003ff,0x000005ee,0x3ffa2000, 0x00bffe24,0x00000000,0x00000000,0x00000000,0x88000000,0xcccccccc, 0xfe8002cc,0x0fffe25f,0x77fe4000,0x801bff20,0x2001eeec,0x3fdc0ffb, 0x6ffc8000,0x0001fff3,0x0017ffe6,0x0bfffa00,0x7fe40000,0x400006ff, 0x0004fffc,0xfb86fc80,0xfff98007,0x001bff21,0x007fff60,0x64fffa20, 0x7c0005ff,0xf00006ff,0x20001dff,0xffb1fff9,0x7dc00009,0x320003ff, 0x00001fff,0x0009fffb,0x00ffff44,0xfff90000,0xf1000005,0xffffffff, 0xff1000bf,0x013ff65f,0x29ffb000,0x1000fff9,0x88009fff,0xffecdffe, 0x3fa00003,0x002ffebf,0x00fffd40,0xffff9000,0xb800003f,0x05ffbeff, 0xffff5000,0x9800007f,0xffdbbeff,0xdff70004,0x0003ffe6,0x007fff10, 0x7d7ffcc0,0x7c0000ef,0xb80006ff,0x40001fff,0x6ffaeffb,0x7ffc0000, 0x3fe20004,0xf700003f,0x0005ffff,0x03fffff6,0x3fe20000,0x1000004f, 0xffffffff,0x2a000bff,0x06ffafff,0xfff88000,0x2001ffea,0x30005ffc, 0x09fffffd,0xfff88000,0x900003ff,0x20000bff,0xfff9effa,0xff300000, 0x00fffa3f,0xd3fff300,0x800003ff,0x5ffffffb,0x67fec000,0x80001ffe, 0x80005ffc,0x00fffffb,0x06fff800,0x02ffe800,0xffffb000,0x5c00001f, 0x640006ff,0x300005ff,0x3fff3fff,0xadffb800,0x800006ff,0x00005ffb, 0x80000000,0x00fffffb,0xfff30000,0x7c4007ff,0x540000ef,0x00001acb, 0x00bfff30,0x01ffd800,0x8fffcc00,0x80006ffb,0x3e64ffe8,0xd10001ff, 0x3ffe67ff,0x64400000,0x80002cdd,0x03ffffe8,0x06ff8800,0x3fff6000, 0x33300002,0xffa80001,0x3a200004,0x00001fff,0x00007ff4,0x0001dff1, 0x2a5fff10,0xf3000eff,0x17ff21ff,0x1fff0000,0x00000000,0x3ff60000, 0x4000001f,0x4004fffb,0x00001ffc,0x00000000,0x3b620000,0x77640003, 0x001f76c3,0x40000000,0x77645eeb,0x00000004,0x3bba6000,0xdd500004, 0x00000001,0x80000000,0x000005ec,0x74c00000,0x7540002e,0xd900001e, 0x03eec89d,0x6c47ddb0,0x500002ee,0x000003dd,0xdffd9730,0x0000039d, 0x00000000,0x26000000,0xceeffecb,0xd9300001,0x017bdffd,0x00000000, 0x22000000,0xcdfffedb,0x0000000a,0xdb710000,0x0159bfff,0x00000000, 0x2e600000,0x0abdefed,0xdfdb9800,0x0059930b,0xccc88000,0x4cc98000, 0x00000000,0x00000000,0x00000000,0x10000000,0xfffffffb,0x8803bfff, 0xcccccccc,0x0abccccc,0x33260000,0xcca8002c,0x3ff62001,0xffffffff, 0xfd50001d,0xffffffff,0x3322017f,0xcccccccc,0xcccccccc,0x00399951, 0x00e66540,0x3fffff62,0x04ffffff,0x2ccc9800,0xffb10000,0xffffffff, 0x6664409f,0x3cc98001,0x6666665c,0xcccccccc,0xfd102ccc,0xffffffff, 0x3fea007f,0xa9ffffff,0x399913ff,0x27993000,0x8001fff8,0x4c007ffa, 0x4c002ccc,0x220004cc,0x98000ccc,0x039954cc,0x32e00000,0xcccccccc, 0xcccccccc,0x3ea01ccc,0xffffffff,0x203fffff,0xfffffff8,0xffffffff, 0xc80000df,0xd8006fff,0xff5003ff,0xffffffff,0x8007ffff,0xeffffffc, 0x0effffff,0xffffff88,0xffffffff,0xff12ffff,0x3e2000df,0x7fd406ff, 0xffefffff,0x001effff,0x01bfff20,0x3fffea00,0xffffefff,0xff981eff, 0xffa8006f,0x7ffffec6,0xffffffff,0xf984ffff,0xffffffff,0x4404ffff, 0xfeceffff,0xf33ffdff,0xf5000dff,0x07ffe2df,0x01ffea00,0x00dfff90, 0x0007ffa8,0x0007ffe2,0x7fe5ffea,0x98000003,0xffffffff,0xffffffff, 0xb02fffff,0x4139ffff,0x5ffffeb9,0xffffff10,0xffffffff,0x0001dfff, 0x01fffff8,0x401ffec0,0x09cffffd,0x3ffffae6,0xffffd005,0xfffd5017, 0xfffff10d,0xffffffff,0x5c5fffff,0xd8004fff,0x3ee00fff,0x441adfff, 0x02ffffda,0x3fffff00,0x7ffdc000,0x6d441adf,0x7cc2ffff,0x54004fff, 0x7ffec6ff,0xffffffff,0x44ffffff,0x41bffff9,0x06fffea8,0xd1037ffa, 0x3e67ffff,0x54004fff,0x3fff16ff,0x0fff5000,0x1fffff80,0x01ffea00, 0x01fff880,0xf97ffa80,0x0000007f,0xfffffff9,0xffffffff,0x05ffffff, 0x003dfff5,0x107fffd1,0x33335fff,0xfd753333,0x20001fff,0x05ffdffa, 0x201ffec0,0x801efffa,0x403fffe8,0x9004fffc,0xff889fff,0xaaaaaabf, 0xaaaaaaaa,0x00ffff40,0x407fff50,0x002ffff9,0x000dfff5,0x0bffbff5, 0x3fffe600,0xdfff5002,0x1fffff98,0x51bfea00,0x55555555,0xffd55555, 0x06ffc85f,0x903fff70,0xffe80bff,0xfffff33f,0xb7fd4003,0x8001fff8, 0x2a007ffa,0x005ffdff,0x8001ffea,0x8001fff8,0x7ff97ffa,0xf8800000, 0xfffaacff,0xaaaaaaad,0x440aaaaa,0x44005fff,0x7c40fffd,0x7dc001ff, 0xfb0003ff,0x001fff1f,0xf101ffec,0xd8800bff,0xff500fff,0xffd8009f, 0x07ffe20f,0xfff88000,0xbfff1006,0x077ff440,0x07ffe600,0xff1ffb00, 0xfe88001f,0x7cc000ef,0x3ffe61ff,0xf5000eff,0xf70000df,0x1fff09ff, 0x427fec00,0x7d401fff,0xffff33ff,0x3ea001df,0x03fff16f,0x00fff500, 0x7ffc7fec,0x0fff5000,0x0fffc400,0xcbffd400,0x000003ff,0x3fa3ffe4, 0xfc80003f,0xf88000ff,0x7ffc45ff,0x5ffd8001,0x96ff8800,0x7ec007ff, 0x3fff203f,0xfff88000,0x00dffd05,0x449fff10,0x00001fff,0x4027ffdc, 0x3200fffd,0xb0001fff,0x7c400bff,0x007ff96f,0x001fffc8,0x7ccbffb0, 0x004fffff,0x8000dff5,0xf986fffa,0x7fd4007f,0x802ffcc6,0xfff33ffe, 0x2a009fff,0x3fff16ff,0x0fff5000,0x7e5bfe20,0xfff5003f,0x7ffc4000, 0x7ffa8001,0x00007ff9,0x21fffc40,0x40003ffe,0x0003fff9,0xf883ffee, 0xfa8001ff,0xffb8007f,0x400dff34,0xff303ffd,0x7dc0007f,0x7ffcc0ff, 0x7bf90002,0x000fffc4,0x0ffff400,0x805fff50,0x20004fff,0x2e005ff9, 0x0dff34ff,0x004fff80,0xf997fe60,0x01fffcff,0x0006ffa8,0x203fffe6, 0x2000fff9,0x3ea0cde8,0x7ff9004f,0x3ff3ffe6,0x6ffa801f,0x0003fff1, 0x2e00fff5,0x0dff34ff,0x001ffea0,0x001fff88,0xff97ffa8,0x64000007, 0x7ff40fff,0x7fdc0003,0x7fc40007,0x07ffe23f,0x07ffe600,0x7c3ffd00, 0xffb002ff,0x01ffee07,0x87fff100,0x20007ffc,0x03fff100,0xfff10000, 0x17ffe20d,0x003fff30,0xfe800180,0x00bffe1f,0x000fffcc,0x5ffe6060, 0x5400effe,0xd10006ff,0x7fc03fff,0xf900004f,0x3fee007f,0x3fafff33, 0x7fd400ef,0x003fff16,0x200fff50,0x3ffe1ffe,0x07ffa802,0x07ffe200, 0x65ffea00,0xdd9713ff,0xf1000179,0x7ffd09ff,0x5ffc8000,0x6fff8000, 0x0007ffe2,0x8003ffee,0x7fe47ff9,0x07ffb005,0x00017ff2,0xffd1bffe, 0xf100000d,0x000003ff,0x360fffee,0x7e400fff,0x000000ff,0x323ffcc0, 0xff9005ff,0x3000001f,0x3ffe6fff,0x037fd404,0x03fffd80,0x0067ffec, 0x00bff600,0xff99ffdc,0x809fff37,0xfff16ffa,0xfff50003,0xc8fff300, 0xffa805ff,0x3fe20007,0xffa8001f,0xfd37ff97,0x03ffffff,0x80fffb80, 0x40003ffe,0x80004ffe,0x3fe27ffd,0xffe8001f,0x27fec007,0x2003ffe6, 0xffd03ffd,0xffb00009,0x005fff8f,0x1fff8800,0x3fa00000,0x3ffe60ff, 0x06ffd802,0xfd800000,0x07ffcc4f,0x0037fec0,0x27ff9800,0x2a01fffc, 0xfc8006ff,0xff9804ff,0x001befff,0x7003ffd8,0x9ffe67ff,0x2a01fffc, 0x3fff16ff,0x0fff5000,0xf989ffb0,0x7fd400ff,0x3fe20007,0xffa8001f, 0xfffdff97,0x3fffffdf,0x13ffe200,0x0001fff4,0x0000fffe,0xff89fff2, 0x3fa2001f,0x3e2003ff,0x3ffe81ff,0xf03ffd80,0x900007ff,0x3fff8fff, 0xff880000,0x2000001f,0x3fa5fff8,0xbffd004f,0x88000000,0xffe81fff, 0x05ffe803,0xfff30000,0x500effe8,0xfa800dff,0x3a2006ff,0xdfffffff, 0x4ffc801b,0x267ff900,0x77ff47ff,0x22dff500,0xa8001fff,0x7fc407ff, 0x03ffe81f,0x0003ffd4,0x3335fff1,0x33333333,0x3f2fff73,0x2e21dfff, 0xf7007fff,0x3ffa01ff,0x3fe20003,0xfa80002f,0x7fff10ff,0x55555555, 0x0dffffb9,0x706ffb80,0xffb00fff,0x05fff107,0x1fff5000,0x000bffe2, 0x3bffe200,0xeeeeeeee,0x002eeeee,0xff75fff7,0x1fffc00d,0x2e000000, 0xfff706ff,0x007fff00,0x1ffe6000,0x2a09fff3,0x3e6006ff,0x44000fff, 0xfffffffc,0x3ee03eff,0x7ffd005f,0xff31ffe6,0x5bfea09f,0x8001fff8, 0x7dc07ffa,0x0fff706f,0x0007ffa8,0x3fffffe2,0xffffffff,0xf97fffff, 0x7fcc0dff,0x4fff801f,0x3bbbffa0,0xeeeeeeee,0x07ffe62e,0x3ffe6000, 0xffffff11,0xffffffff,0x8001bfff,0xff103ffe,0x3ffd805f,0x001fff98, 0x11fff980,0x00005fff,0xffffff10,0xffffffff,0x74005fff,0x01fffeff, 0x200fffe0,0xfffffff9,0x7f404fff,0x5fff103f,0x803fff80,0xfffffff9, 0xfff34fff,0x505fff90,0x3a200dff,0x20001fff,0xfffffdb8,0xf880dfff, 0x7fcc01ff,0x90fff33f,0xff505fff,0x007ffe2d,0xd01ffea0,0x3fe207ff, 0x1ffea02f,0xffff8800,0xffffffff,0x7fffffff,0xe801fff9,0x7fdc02ff, 0x3fffa00f,0xffffffff,0x3fe23fff,0xfa80002f,0xffff10ff,0xffffffff, 0x0005bfff,0x6c01fff3,0x7fec05ff,0x02fff883,0x0fffa800,0x0007fff1, 0xfffff100,0xffffffff,0x4005ffff,0x04fffff9,0x401fffc0,0xfffffff9, 0x3e604fff,0x3ff600ff,0x01fffc05,0x7fffffcc,0xff34ffff,0x03bffa0f, 0x3600dff5,0x00002fff,0x7fffedcc,0x5ffc81ef,0x99fffec0,0xdffd07ff, 0xf16ffa81,0xf50003ff,0x7ffcc0ff,0x817ff600,0x20007ffa,0xfffffff8, 0xffffffff,0xff97ffff,0x05ffb00d,0x7404ffe8,0xffffffff,0x43ffffff, 0x80003fff,0x3fe27ffc,0xfdccccdf,0x40004fff,0x7d405ffc,0x3ff600ff, 0x007fff03,0xf8fff900,0x800005ff,0x999afff8,0x99999999,0x7dc00099, 0xfe8006ff,0xfff9804f,0x4fffffff,0x5017ff20,0x7f401fff,0xfff9804f, 0x4fffffff,0x3e60fff3,0x37fd44ff,0x027ffe40,0x7f540000,0xfff887ff, 0x7ffec40d,0x20fff33f,0x7d44fff9,0x03fff16f,0x40fff700,0x7d405ffc, 0xfff500ff,0x7ffc4000,0x7ffa8001,0xf900bff9,0x7ffd407f,0x4e7ff400, 0x99999999,0x27ffc099,0x37fec000,0x5c03fff1,0x0000dfff,0x9999bfff, 0x9fff9999,0xf81ffec0,0xd80004ff,0x37ff46ff,0x7fc40000,0x0000001f, 0x2000bffe,0x80005ffd,0x3fe04ffd,0xccccccdf,0x204fffcc,0x80005ffd, 0xfff34ffd,0x517ffe40,0xffa80dff,0x0000005f,0x5417ffe4,0xfeceffff, 0xf33ffeff,0x7ffe40ff,0x7c5bfea2,0xfc8001ff,0x37ffe06f,0xcccccccc, 0xff504fff,0x7fc4000f,0xffa8001f,0x9009ff97,0x7ff407ff,0xaaaaaaae, 0x0003fffa,0x00037fe4,0xff127ff4,0xfffa803f,0xfffa8006,0xffffffff, 0x3607ffff,0xdff903ff,0x9ffd0000,0x0007ffc8,0x7c42b3a2,0x000001ff, 0x000bffe0,0x0003ffee,0x2a09ffb0,0xffffffff,0x7fffffff,0x003ffee0, 0x269ffb00,0x7ff407ff,0x40dff50e,0x000efff9,0x80015544,0xff304ffd, 0xb3dfffff,0x1ffe67ff,0x2a1dffd0,0x0bffe6ff,0x41bff200,0xfffffffa, 0xffffffff,0x00fff507,0x00fffc40,0xfcbffd40,0x3ffc803f,0xffffff50, 0xffffffff,0xf980007f,0x2a0001ff,0x3fe21fff,0xfffb801f,0x7ffec005, 0xffffffff,0xb02fffff,0x3fe607ff,0x3ea0001f,0x7ffcc1ff,0xfff70001, 0x007ffe21,0xfff80000,0xfff88002,0x7fec0003,0xfffffb04,0xffffffff, 0x3e205fff,0x6c0003ff,0x0fff34ff,0xf54fff98,0x3ffa20df,0xff88001f, 0xffb8000f,0x3fb2e206,0x25ffb0bd,0x7cc07ff9,0x4dff54ff,0xd8003fff, 0xfffb05ff,0xffffffff,0x505fffff,0x44000fff,0xa8001fff,0x07ff97ff, 0x3a07ff90,0xffffffff,0x3fffffff,0x6fff8000,0x1bffa000,0x2003fff1, 0x1003fffd,0x33335fff,0xfd333333,0x0fff60bf,0x0006fff8,0x7fc1bffa, 0xffd0005f,0x00fffc4b,0xfff00000,0x3ff60005,0x3f60000f,0xafff884f, 0x99999999,0x205ffe99,0x0000fffd,0x7fcd3ff6,0xafffc807,0xffb06ffa, 0x7f40005f,0xffa8003f,0x7fec0005,0x900fff32,0xdff55fff,0x4002ffec, 0xff883fff,0x999999af,0x5ffe9999,0x0007ffa8,0x0007ffe2,0x7fe5ffea, 0x83ffc803,0xccccfffa,0xffcccccc,0xfa80003f,0xfb8003ff,0x7ffc43ff, 0xffff1001,0x0dff7003,0x81fffb80,0x3ea03ffd,0xfb8003ff,0xfff703ff, 0xfffb8003,0x007ffe22,0xfff80000,0xfff30002,0x7fec000b,0x006ffb84, 0x980fffdc,0x20005fff,0xfff34ffd,0x2bfffa00,0xfffb86ff,0x7fe40004, 0x3ffd8006,0xfe8006a2,0x00fff31f,0x3febfffa,0x007ffee6,0xb81fffb8, 0x7dc006ff,0x3ffd41ff,0x3fff1000,0x2fff5000,0xfc803ffc,0x05ffe83f, 0x000fffa0,0x027ffec0,0x10bfff90,0x54003fff,0xfe806fff,0x7fc4003f, 0x03ffd84f,0x0027ffec,0xe80bfff9,0xf3001fff,0xfff88dff,0x20000001, 0x20002fff,0x000efffb,0x213fffa6,0x44003ffe,0x3ee04fff,0x26000eff, 0xff34fffe,0x3ffe600f,0x7fd46ffe,0xf980005f,0xf5000eff,0x0fff81ff, 0xf33ffdc0,0x3fe600ff,0x3e66ffef,0xe8800eff,0x7ffd07ff,0x4fff8800, 0x0003ffd4,0x0003fff1,0x3ff2fff5,0x43ffc803,0x2001fff9,0x00003ffe, 0x03dfffd1,0x07ffff4c,0x000fffc4,0x980ffff6,0xc8000fff,0x3ffd87ff, 0x77fff440,0x3fffa601,0x7ffcc00f,0xff9102cf,0xfff881ff,0x20000001, 0x40002fff,0x0acffffd,0xffffda88,0x07ffcc2f,0x03ffe400,0x2b3ffff6, 0xfffda880,0x0fff32ff,0x7ffffe40,0x03bffe26,0x7fff4000,0xffb100af, 0x09ffd0df,0xf327ffc4,0x7fe400ff,0x7fe46fff,0xff500aef,0xfff305ff, 0xfff90001,0x0007ffa8,0x0007ffe2,0x7fe5ffea,0x43ffc803,0x74006ffd, 0x200003ff,0xdfffffe8,0xfffffdcc,0x3fff100e,0xffff8800,0x00dff900, 0xb0bffe60,0xfd1007ff,0xb99bffff,0x01dfffff,0x3ffffea0,0xfffdcbdf, 0xfff881ff,0x20000001,0x80002fff,0xfffffffc,0xffffffdd,0x6ffc80cf, 0x5fff3000,0xfffffc80,0xffffddff,0x3e60cfff,0x3fa2007f,0xffd16fff, 0x4400001d,0xdffffffe,0x5fffffec,0x37bfff70,0x8bfffb71,0x22007ff9, 0x446ffffe,0xcefffffe,0x4fffffed,0x000dff90,0xfa8bffe6,0x3e20007f, 0xfa8001ff,0x007ff97f,0x7fcc7ff9,0x7ff4002f,0xfc800003,0xffffffff, 0x7c404fff,0xfb8001ff,0x7fff05ff,0x37ff4000,0xc800fff6,0xffffffff, 0x8004ffff,0xffffffe9,0x01efffff,0xfffffff1,0xffffffff,0xf800ffff, 0x500002ff,0xffffffff,0x03dfffff,0x0001fffc,0xf500dffd,0xffffffff, 0x303dffff,0xf9800fff,0xfff36fff,0xffffffff,0xffffffff,0xffffb10f, 0xffffffff,0xffffd809,0x85ffffff,0x4c007ff9,0xd886ffff,0xffffffff, 0x3e03ffff,0x3a0003ff,0x3ffea6ff,0xffffffff,0xff14ffff,0xff50003f, 0x200fff2f,0x3ff63ffc,0xfffe8006,0xffffffff,0x8806ffff,0xfffffffb, 0xff8800bf,0xffd0001f,0x0fffa85f,0x3ffee000,0x000fff61,0xffffff71, 0x800017ff,0xffffffda,0x7fc402ef,0xffffffff,0xffffffff,0x17ffc007, 0x3f6a0000,0xceffffff,0x07ffd402,0x3fff7000,0x3fff6a00,0x02ceffff, 0x2001ffe6,0xff36fffc,0xffffffff,0xffffffff,0x7fe4c0ff,0x2cefffff, 0xffffd500,0x3e609bff,0xffc8007f,0x3ff6a06f,0x1cffffff,0x003ffea0, 0x51fffb80,0xffffffff,0x9fffffff,0x0007ffe2,0x7fe5ffea,0x33ffc803, 0xd0005fff,0xffffffff,0xdfffffff,0x9aa98800,0x7ffc4000,0xfff30001, 0x02ffec1f,0x93ffe200,0x20003ffd,0x0009aa98,0x35533000,0x7fffc400, 0xffffffff,0x07ffffff,0x0017ffc0,0x15533000,0x05ffd800,0x27ffc400, 0x0554cc00,0x00fff300,0x26dffd10,0xffffffff,0xffffffff,0x33007fff, 0x98000355,0xf9801bba,0xfe88007f,0xa998806f,0xffb0019a,0xff88000b, 0xfffff54f,0xffffffff,0x3ffe29ff,0x7ffa8001,0xf9007ff9,0x01bff67f, 0x7fffff40,0xffffffff,0x000006ff,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0xcccccca8,0x7cc0cccc,0x3ffe62ff, 0x8bffe601,0x0000fffa,0x98000bf1,0x99999999,0x26200009,0x3e200019, 0x3ffe63ff,0x1dff7001,0x2002ffec,0x05fd03fd,0x13100800,0x00000000, 0x0aa80554,0x7f46ffd8,0xe880004f,0x000bd305,0xdd507774,0x776c0009, 0x0013baa1,0x07ffec00,0x5c0dcc00,0x4c02001c,0x26660001,0x9dd70000, 0x8001eee8,0x776c5ee9,0x77740002,0x2013baa0,0x3baa1eed,0xfffffc85, 0xb81fffff,0x5ffd0fff,0x11fff500,0x20003fff,0x000aefb8,0xffffff88, 0x0005ffff,0x0007fff2,0xfd0fffa8,0xffd8005f,0x001dff54,0x7dc0ffb8, 0xfb30000f,0x01fec39d,0x1dfd9800,0xa84fd800,0x7ffd107f,0x00017fee, 0x5fd83ff8,0x87ffe000,0x20005ffb,0x3fee1fff,0xfb000006,0x744001ff, 0xfaacffff,0x7fdc401f,0x00ff30ad,0x013ffe60,0x3e2ffe40,0xfa8001ff, 0x01fff46f,0xb87ffe00,0xfff805ff,0x321bfea2,0xffffffff,0x9ffb01ff, 0x64009ff9,0x03ffcdff,0xfffffb80,0x22001eff,0xffffffff,0x320005ff, 0x40001fff,0x4ffcdffc,0xafff8800,0x88000fff,0xffecdffe,0xfff10004, 0x3ffdffff,0x273e0000,0x7d4000fc,0x5feb99cf,0x3ebffe60,0x200000ef, 0xfebbdffb,0x3fe0001f,0x017fee1f,0x2e1fff80,0x000006ff,0x4001fffb, 0xffffeffb,0xffd806ff,0x4ffeffff,0x9fff3000,0x17ff2000,0x50003fff, 0x3ffe8dff,0x0fffc000,0xff00bff7,0x037fd45f,0xfffd0000,0xffd000bf, 0xe8800bff,0xffffffff,0x2aa002ff,0xaaaaaaaa,0x3ff20001,0xfd80001f, 0x20005fff,0x02fffff9,0x3fffa600,0x2e0004ff,0xfffda9ef,0xf500006f, 0xfd8003d8,0x00efffff,0x0fffffd4,0x7fec0000,0x0003ffff,0xdd507774, 0x776c0009,0x0013baa1,0x07ffec00,0x2a27fd00,0xf801dffd,0xffffc9bf, 0xff30001f,0x3ae0009f,0x00f7744e,0x362f74c0,0x740002ee,0x13baa0ee, 0xea87bb60,0x2000005e,0x000efff8,0x006fff88,0xfaefffd8,0x01ffffce, 0x20000000,0x0000eeeb,0x00efff88,0x1fffdc00,0xacba8000,0x1f640001, 0x000072e2,0x001ec6a8,0x0ceffea8,0x05fff900,0x6e4c0000,0x000000cd, 0x00000000,0x00000000,0x002202aa,0x5e542f4c,0x3ba60000,0x0000003e, 0x00000000,0x00000000,0xb83bba20,0x000004ee,0xff700000,0x7457e25f, 0x666446ff,0x4cc98000,0x00000000,0x00000000,0x00000000,0x7c000000, 0x0000fb8c,0x00000000,0x88000000,0x98000ccc,0x973004cc,0x039ddffd, 0x3b6e2000,0x00acdfff,0x00000000,0x88000000,0xcccccccc,0xcccccccc, 0x64c001cc,0x654002cc,0x2a0001cc,0xcca81ccc,0x0fffc403,0x9500bff9, 0x33322079,0xcccccccc,0xcccccccc,0x897ff60c,0x83ffea5f,0x8001fff8, 0x665c7ffa,0xcccccccc,0x2ccccccc,0x6666665c,0xcccccccc,0x99912ccc, 0x99999999,0x39999999,0x33333322,0xcccccccc,0x4001cccc,0x0002ccc9, 0x0bfff700,0x03cca800,0x99999991,0x01579999,0x6664c000,0x7ffc4002, 0x7ffa8001,0x7fffec40,0x1dffffff,0xfffb1000,0xffffffff,0x3cca8009, 0x00399910,0x32279930,0xcccccccc,0xcccccccc,0xfffff11c,0xffffffff, 0x005fffff,0x006fffc8,0x0037ffc4,0x906fff88,0xff880bff,0x017ff21f, 0x7c417ff2,0xffffffff,0xffffffff,0x3ffe0fff,0xfff17e21,0x00fffc45, 0x363ffd40,0xffffffff,0xffffffff,0x7fffec4f,0xffffffff,0xf14fffff, 0xffffffff,0xffffffff,0x3fffe25f,0xffffffff,0x02ffffff,0x037ffe40, 0xfffc8000,0x7fe40006,0xfffff305,0xffffffff,0x9000019f,0x8800dfff, 0xa8001fff,0x3fea07ff,0xffffffff,0x4003ffff,0xfffffffa,0xeffffffe, 0x0bff9001,0x001bffe6,0x7fc5bfea,0xffffffff,0xffffffff,0xffffff12, 0xffffffff,0x8005ffff,0x001fffff,0x0027ffdc,0xc807ffec,0x774405ff, 0x013bae0e,0x7c417ff2,0xffffffff,0xffffffff,0xfff10fff,0x40445f88, 0x8001fff8,0x7fec7ffa,0xffffffff,0x4fffffff,0x7fffffec,0xffffffff, 0xfff14fff,0xffffffff,0x5fffffff,0x3fffffe2,0xffffffff,0x4002ffff, 0x001fffff,0xfffff800,0x3ff20001,0xfffff305,0xffffffff,0x80009fff, 0x001fffff,0x0007ffe2,0x7ec1ffea,0x2609cfff,0x05ffffeb,0x5bffff70, 0xfffda883,0x5ffc802f,0x09ffff30,0xf16ffa80,0xffffffff,0xffffffff, 0x2fffe25f,0xaaaaaaaa,0x00aaaaaa,0x3ff7fea0,0xfffe8005,0x3ffea001, 0x017ff203,0xffc80000,0x55555105,0x5dffd555,0x85555555,0x17e22fff, 0x00fffc40,0x2a3ffd40,0xaaaaaaaa,0xffeaaaaa,0x5555542f,0xaaaaaaaa, 0xf12fffea,0x555557ff,0x55555555,0x2fffe215,0xaaaaaaaa,0x00aaaaaa, 0x3ff7fea0,0x7d400005,0x0005ffdf,0x7cc17ff2,0xaaaaabff,0xffffecba, 0xbff50005,0x7c400bff,0xfa8001ff,0xefffa87f,0xfffe8801,0x7fffcc03, 0xdfff5002,0x20bff900,0x01fffff9,0x7c5bfea0,0xaaaaabff,0xaaaaaaaa, 0x03fff10a,0x3f600000,0x000fff8f,0x8037ffc4,0x6405fff8,0x000005ff, 0x0017ff20,0x4004ffd8,0x17e24ffd,0x00fffc40,0x003ffd40,0x027ffdc0, 0x4fffb800,0x0007ffe2,0x007ffe20,0x7fec0000,0x0000fff8,0x3fe3ff60, 0xff90000f,0x03ffe60b,0x27fff4c0,0x7c7fec00,0xff1000ff,0xff50003f, 0x05fff88f,0x07ffec40,0x00effe88,0x00fffcc0,0x7cc17ff2,0x000effff, 0x3fe2dff5,0xf880001f,0x000001ff,0xff96ff88,0xfff70007,0x1fffb009, 0x005ffc80,0x3ff20000,0x3ff60005,0x7ffdc004,0x2200bf13,0xa8001fff, 0x540007ff,0x00006fff,0xf88dfff5,0x880001ff,0x00001fff,0xf96ff880, 0x2200007f,0x07ff96ff,0x417ff200,0x2000fff9,0x000fffe8,0x7fe5bfe2, 0x3fff1003,0x8fff5000,0x8000fffc,0xf905fff8,0x360003ff,0x7fe405ff, 0xfffff305,0x3fea009f,0x003fff16,0x03fff100,0xff700000,0x001bfe69, 0x500ffff4,0xf9005fff,0x0732a0bf,0x640732e0,0x360005ff,0x744004ff, 0x05fbefff,0x003fff10,0x000fff50,0x007fffcc,0x7fffcc00,0x00fffc40, 0x0fffc400,0x7dc00000,0x00dff34f,0x4d3fee00,0xf90006ff,0x3ffe60bf, 0x7ffc4000,0x53fee005,0xf1006ff9,0xf50003ff,0x1fffccff,0x1fff7000, 0x0009fff0,0x3202ffcc,0xfff305ff,0x5003fff9,0x3ffe2dff,0xff880001, 0x8000001f,0x3ffe1ffe,0xfff88002,0x0bfff106,0x6c17ff20,0xffe803ff, 0x00bff902,0x0027fec0,0x7fffff44,0x7fc401bf,0xffa8001f,0xffd10007, 0xd100003f,0xff103fff,0xf100003f,0x000003ff,0x7fc3ffd0,0xfe80002f, 0x00bffe1f,0x4c17ff20,0xc8000fff,0x3fa007ff,0x00bffe1f,0x0007ffe2, 0xffb9ffea,0x7fc40007,0x0fffcc3f,0x64006000,0xfff305ff,0x5003bffa, 0x3ffe2dff,0xff880001,0x4000001f,0x7fe47ff9,0xfff70005,0x01fffb07, 0x6c17ff20,0xffe803ff,0x00bff902,0x0027fec0,0xfffffc88,0xff103fff, 0xff50003f,0x3ff6000f,0xfb00003f,0x3fe207ff,0xf880001f,0x000001ff, 0x3f23ffcc,0x7cc0005f,0x02ffe47f,0x982ffe40,0x98000fff,0xf9801fff, 0x02ffe47f,0x000fffc4,0xff93ffd4,0xfff0000b,0x00fffc8d,0xff900000, 0x4dffe60b,0x7d404fff,0x03fff16f,0x3fff1000,0xfd800000,0x07ffcc4f, 0x0fffe800,0x800bffe6,0xffb05ffc,0x05ffd007,0x80017ff2,0x80004ffd, 0xffffffda,0x0fffc40d,0x03ffd400,0x027ffe40,0x4fffc800,0x007ffe20, 0x07ffe200,0xffb00000,0x00fff989,0x313ff600,0xc8001fff,0xfff305ff, 0x3ffa0001,0x44ffd802,0x4400fff9,0xa8001fff,0x13ffa7ff,0x1fff6000, 0x0000dffb,0x82ffe400,0x3ff27ff9,0x5bfea01f,0x0001fff8,0x001fff88, 0x3ffe2000,0x003ffe81,0x74bfff10,0x7e4004ff,0x07ffb05f,0x3205ffd0, 0x360005ff,0x100004ff,0xbffff9df,0x001fff88,0x4007ffa8,0x0006fffa, 0x80dfff50,0x0001fff8,0x001fff88,0x3ffe2000,0x003ffe81,0xd03fff10, 0xfc8007ff,0x1fff305f,0x0fff6000,0xd03fff10,0xff8807ff,0xffa8001f, 0x000fffe7,0xfd1fff20,0x000000bf,0xf982ffe4,0x077ff47f,0xff16ffa8, 0xf100003f,0xddddddff,0xdddddddd,0x0dff7005,0x8001ffee,0xffbafffb, 0x5ffc8006,0xd007ffb0,0x3ff205ff,0x3ff60005,0xbf100004,0x88ffff22, 0xa8001fff,0x3e6007ff,0x80000fff,0x400ffff9,0xeeeefff8,0xeeeeeeee, 0x3ffe22ee,0xeeeeeeee,0x02eeeeee,0xf706ffb8,0x3ee000ff,0x0fff706f, 0x305ffc80,0x20001fff,0x7dc05ffd,0x0fff706f,0x001fff88,0xff17ffa8, 0xf500005f,0x1fffc1ff,0xf9000000,0x1ffe60bf,0x2a09fff3,0xdfff16ff, 0xdddddddd,0x445ddddd,0xffffffff,0xffffffff,0x3ffe802f,0x005fff10, 0x7ff7ff40,0xffc8001f,0x007ffb05,0x3f205ffd,0x3f60005f,0xf100004f, 0x226ffd8b,0xa8001fff,0xfd1007ff,0x100003ff,0x1003fffd,0xffffffff, 0xffffffff,0x7fffc45f,0xffffffff,0x802fffff,0xff103ffe,0xffd0005f, 0x0bffe207,0x305ffc80,0x20001fff,0x7f406ffc,0x5fff103f,0x00fffc40, 0xf9bffd40,0x980001ff,0x3ffe1fff,0xffff9803,0x04ffffff,0x7cc17ff2, 0x2fffc87f,0xff16ffa8,0xffffffff,0x5fffffff,0x7fffffc4,0xffffffff, 0x7cc02fff,0x3ff600ff,0x3fe60005,0x90004fff,0x3ff60bff,0x02ffe803, 0x4000bff9,0x00004ffd,0x7ffb8bf1,0x0007ffe2,0x6c01ffea,0x00002fff, 0x2005fffb,0xfffffff8,0xffffffff,0x3ffe22ff,0xffffffff,0x02ffffff, 0xb007ffcc,0xf9800bff,0x3ff600ff,0x17ff2005,0x0007ffcc,0x2606ffc8, 0x3f600fff,0x3ffe205f,0x7ffa8001,0x0005fff1,0x7c1fff50,0xff9803ff, 0xffffffff,0x417ff204,0xffd07ff9,0x16ffa81d,0xffffffff,0xffffffff, 0x57ffc45f,0x99999999,0x40099999,0x7d405ffc,0x2e0000ff,0x20006fff, 0xffb05ffc,0x05ffd007,0x80017ff2,0x22004ffd,0x22fc42ba,0xff10fff8, 0xff70003f,0x9fff900f,0x3ff20000,0x3fe2004f,0x999999af,0x09999999, 0x266bffe2,0x99999999,0x7e400999,0x7ffd405f,0x17ff2000,0x001fff50, 0x7cc17ff2,0xfb0000ff,0x2ffe40bf,0x403ffea0,0x8001fff8,0x3ffe7ffb, 0xffc80003,0x4027ff47,0xfffffff9,0x3f204fff,0x0fff305f,0xf513ffe6, 0x2bffe2df,0x99999999,0x22099999,0x00001fff,0x999bfff0,0xfff99999, 0xfff80009,0x3ff20002,0x007ffb05,0x3f205ffd,0x3f60005f,0x3fee004f, 0x3e62fc45,0x3fff10ff,0x0dff9000,0x005fffa8,0x0bfff500,0x01fff880, 0x1fff8800,0xfff00000,0x9999999b,0x4009fff9,0xccccdfff,0x4fffcccc, 0x20bff900,0x0000fff9,0x7fc09ffd,0xccccccdf,0x104fffcc,0x90003fff, 0x27ffcdff,0x37fec000,0x00017ff6,0xfc813ff6,0x0fff305f,0xf517ffe4, 0x07ffe2df,0x3ffe2000,0xfa800001,0xffffffff,0x07ffffff,0x017ffc00, 0x20bff900,0xfe803ffd,0x0bff902f,0x027fec00,0xf88fff30,0x3e3ffe45, 0xfc8002ff,0x3ffe606f,0xf980000e,0x44000eff,0x80001fff,0x0001fff8, 0xfffffa80,0xffffffff,0xff5007ff,0xffffffff,0x00ffffff,0x7cc17ff2, 0xff0000ff,0x3ffea07f,0xffffffff,0x3e07ffff,0xfc8002ff,0x01bff26f, 0x713ffa00,0x80001fff,0x3f204ffd,0x0fff305f,0xf50effe8,0x07ffe2df, 0x3ffe2000,0xfd800001,0xffffffff,0x2fffffff,0x0bffe000,0x05ffc800, 0xff007ffb,0x17ff205f,0x04ffd800,0xf11fffc0,0x7c5ffe8b,0xfd8003ff, 0xfffd105f,0xfd100003,0xf10003ff,0x100003ff,0x00003fff,0xffffffb0, 0xffffffff,0xffb005ff,0xffffffff,0x05ffffff,0x260bff90,0x88000fff, 0xffb02fff,0xffffffff,0x05ffffff,0x2000fffe,0x3fe65ffd,0x3ea0001f, 0x7ffc41ff,0x7fec0003,0x417ff204,0x7cc07ff9,0x2dff54ff,0x0001fff8, 0x001fff88,0x57ffc400,0x99999999,0x005ffe99,0x000bffe0,0xf905ffc8, 0xfff8807f,0x00bff902,0x0027fec0,0x7c47fff2,0x83fff915,0xf8005ffd, 0xfffb03ff,0x3f600005,0xf10002ff,0x100003ff,0x00003fff,0x99afff88, 0x99999999,0x7c405ffe,0x99999aff,0xffe99999,0x05ffc805,0x0001fff3, 0xf101fff7,0x333335ff,0xffd33333,0x017ff60b,0xff0fffe0,0x7f4000df, 0x1fffb06f,0x27fec000,0x260bff90,0xffc807ff,0xf16ffaaf,0x100003ff, 0x00003fff,0x4006ffb8,0x0001fffb,0x40005fff,0xff905ffc,0x2fff9809, 0x000bff90,0x20027fec,0xfacfffe8,0x84ffffbe,0x2001fffb,0xfb81fffb, 0x700004ff,0x40009fff,0x0001fff8,0x001fff88,0x037fdc00,0x807ffee0, 0x5c006ffb,0x7e401fff,0x1fff305f,0x4fff8800,0x800dff70,0xfb81fffb, 0x3ee001ff,0x7ffd41ff,0xfffb8003,0x0bfff303,0x027fec00,0x3e60bff9, 0xfffd007f,0x3fe2dff5,0xf880001f,0x400001ff,0x44003ffe,0xf0004fff, 0x640005ff,0xdff705ff,0x02fffd80,0x4000bff9,0x88004ffd,0xfffffffe, 0xff304fff,0xfd1001df,0xbfff50ff,0x3fea0000,0x7c40005f,0x880001ff, 0x00001fff,0x2001fff4,0x3a04fff8,0x7c4003ff,0x7fe404ff,0x01fff305, 0x01fffd80,0x88007ffd,0xff984fff,0xfe8800ef,0x9fffb07f,0x2fffe400, 0x03bffee0,0x4fffe980,0x4c17ff20,0xff3007ff,0x3e2dffdf,0x880001ff, 0x00001fff,0x0003ffe6,0x4001fff2,0x20002fff,0xff305ffc,0x3fff207f, 0x0bff902f,0x027fec00,0xfffec880,0x6402efff,0x500aefff,0xf885ffff, 0x80000eff,0x000efff8,0x00fffc40,0x0fffc400,0xfff30000,0xfff90001, 0x003ffe60,0x901fff20,0x3fe60bff,0xff91000f,0x3ffe60bf,0x7ffc8000, 0x15dfff90,0x0bfffea0,0x0f7fff44,0x1ffffd30,0x9ffffb00,0xffb51015, 0x7e405fff,0x0fff305f,0x7ffffe40,0x003fff16,0x03fff100,0x37fe4000, 0x2fff9800,0x02fff800,0x817ff200,0xcabefffe,0x02ffdffe,0x4000bff9, 0x80004ffd,0x000aefb8,0xdfffffd1,0xfffffdb9,0x0effe889,0xffe88000, 0xf880000e,0x880001ff,0x00001fff,0x4001bff2,0xfc82fff9,0xff30006f, 0x2ffe405f,0x100fff98,0xdffff753,0x01bff201,0x417ffcc0,0xefffffe8, 0xfffffedc,0x7fff4404,0xffdccdff,0x2000efff,0xfffffffc,0xffffffdd, 0x7fe400cf,0x00fff305,0xb7ffff44,0x0001fff8,0xffffff88,0xffffffff, 0x7fc7ffff,0x3fa0003f,0xfff8006f,0x3ff20002,0x3fffa605,0xfb9fffff, 0x0bff902f,0x027fec00,0x005f8800,0xfffffd88,0x3fffffff,0xffffff98, 0xffffffff,0xf37fffff,0xffffffff,0xffffffff,0x3ffe2fff,0xffffffff, 0x7fffffff,0xfffffff1,0xffffffff,0xfff8ffff,0x3ffa0003,0x003fff86, 0xc81bffa0,0xfff305ff,0xffffffff,0x01dfffff,0x0001fffc,0x3620dffd, 0xffffffff,0x2003ffff,0xfffffffc,0x004fffff,0xffffff50,0xdfffffff, 0x17ff2003,0x2003ffcc,0xf16ffff9,0xffffffff,0xffffffff,0x3fffe2ff, 0xffffffff,0x27ffffff,0x0000fffa,0x0007ffee,0x40005fff,0x6c405ffc, 0x71dfffff,0x3ff205ff,0x3ff60005,0xbf100004,0x7fed4000,0x1cffffff, 0xffffff30,0xffffffff,0x26ffffff,0xffffffff,0xffffffff,0xfff17fff, 0xffffffff,0xffffffff,0x3fffffe2,0xffffffff,0x3ea7ffff,0x2e0000ff, 0x3fea1fff,0x3ee0000f,0xbff901ff,0x3ffffe60,0xffffffff,0x3ea00cff, 0x2e0000ff,0x36a01fff,0xffffffff,0xfb88001c,0xbfffffff,0xfda80000, 0xceffffff,0x2ffe4002,0x8007ff98,0xff16fffc,0xffffffff,0xffffffff, 0x3ffffe2f,0xffffffff,0x367fffff,0x440005ff,0x7c004fff,0x320002ff, 0x2a6005ff,0xbff90001,0x27fec000,0x00790000,0x35533100,0xffff3003, 0xffffffff,0xffffffff,0x3fffffe6,0xffffffff,0xf17fffff,0xffffffff, 0xffffffff,0x3fffe2ff,0xffffffff,0x27ffffff,0x40005ffd,0x3f64fff8, 0x7c40005f,0xbff904ff,0x3ffffe60,0xcdefffff,0x0bffb002,0x4fff8800, 0x9aa99880,0x26200001,0x000009aa,0x002aa660,0x20bff900,0x88007ff9, 0xfff16ffe,0xffffffff,0xffffffff,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x2e199500,0x2a601ced,0xaaaaaaaa, 0x99988002,0x01999999,0xffffffb8,0x0002ffff,0x00009800,0x00000000, 0xa8000000,0x3ae00001,0x000002ee,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x3bfb2e60,0x333260ac, 0xcccccccc,0x0bfd0ccc,0xfdb71000,0x40039ddf,0xfffb8ffc,0xfffb01ff, 0x1fffffff,0xffffd800,0x00ffffff,0x7fffffdc,0x3002ffff,0x79dffdd9, 0x001df303,0x3bfffb26,0x332000bd,0x7fee540c,0x20000cef,0x77d405fd, 0xf80000ef,0xca8805ff,0x0000beee,0x64401dfb,0x2000cefe,0x730006fd, 0x157bdfdb,0x3fae2000,0x1000bdff,0x260005fd,0x730004ff,0x39ddffd9, 0x0bff0000,0xfd101bf6,0x77ec0005,0xedb88000,0x001ceeff,0x7ffffec0, 0xff51ffff,0xffffffff,0x3f21ffff,0x3f220007,0xffffffff,0xffc803ef, 0x06fffffa,0x3ffffff6,0x4000ffff,0xfffffffd,0x64c00fff,0xcccccccc, 0x7ff5401c,0xffffffff,0x01dff10c,0xfffffeb8,0x00dfffff,0xfa8fffc4, 0xffffffff,0x7ff0004f,0x07b14e80,0x0effb800,0xfffffd80,0xffb8005f, 0x3fffa601,0xf9801fff,0x7f44002f,0xffffffff,0x7fdc003f,0x2fffffff, 0x017ffcc0,0x8006fe80,0xffffffd8,0x001dffff,0x3e07ff10,0x3ffe604f, 0x3ff70002,0xfffc8800,0xefffffff,0x7fec4003,0xfffedfff,0xfffffa9f, 0xffffffff,0x003ff30f,0x57dfff50,0xfffb5333,0x7ffe401b,0x203dabdf, 0x99999998,0xa9800199,0xaaaaaaaa,0x0000000a,0xfffffff9,0x7fffffff, 0xfd801ffd,0xffefffff,0x202fffff,0xffc9fff8,0xffffefff,0x7cc005ff, 0xa83e601f,0x7ff40006,0x8affb801,0x2001ffd8,0x7f404ff8,0x06ffc9cf, 0x4c006fd8,0xffffffff,0x004fffff,0xf9bdfff7,0x7105ffff,0x0005ffff, 0xa8001ff9,0xffffffff,0x03ffffff,0x981ffa80,0xffb883ff,0xf88002ff, 0x7fd4004f,0xa999abef,0x800dfffd,0x42dfffe8,0xffcfffc8,0xaaaaaaae, 0x1ffc2aaa,0x077ff600,0x07ffee20,0x002fffe4,0x00000000,0x3cca8000, 0x7ffffb00,0x7fecc413,0x2201ffff,0x09bffffe,0x3ffffb2a,0xfdfff103, 0xfb9859df,0x32004fff,0x322f807f,0x3fea0004,0x88797002,0x3fa004ff, 0x21ffd406,0x3e603ffa,0x3fe6001f,0x75441bff,0x7d406fff,0xffda84ff, 0x37ffe20f,0x7cc002ff,0x7fec003f,0x2e609cff,0x005ffffe,0x7d407fdc, 0x6fffc41f,0xfe8002ff,0x6ffec006,0xfffb8801,0x1fffe401,0x3ffffea0, 0x1bf60005,0x003ffc80,0xc80ffe98,0x32200fff,0xcccccccc,0xcccccccc, 0x664c001c,0x7e40002c,0xfffc805f,0xffe9800e,0x7ffec04f,0xfff9800d, 0xffff881f,0xfff9806f,0x09fd001f,0x03fb9f90,0x000cc400,0x800ffe40, 0x7e400ffc,0x205ff80f,0x7e4006fd,0xfff7006f,0x037ff403,0x7c49fff1, 0x002ff98c,0x50017fa2,0x1003dfff,0x4007fffd,0x0ff906fd,0x5ff319f1, 0x00ffc800,0x000fff20,0x4403ffa6,0xf7003fff,0x4000bfff,0xfa800ffb, 0x7f40002f,0x406ffc86,0xfffffff8,0xffffffff,0x64002fff,0x40006fff, 0x7cc05ffc,0x7e4004ff,0xff500fff,0xfe88009f,0x7ffc40ef,0xff1000ef, 0x5ff100bf,0x00736a00,0x80350000,0x3002fffc,0xffb007ff,0x7cc1bfa0, 0x7ffc001f,0x13ff6000,0x201fffc4,0xf3046ffc,0x7fec005f,0x3ffe2000, 0x7fec4005,0x0bff000f,0xf3041bf6,0x7fcc005f,0x0bfea003,0x37f40188, 0x000fffb8,0x0017fffe,0x4402ff88,0x3bbaa4ff,0x880bcdee,0x2ffe44ff, 0x3ffffe20,0xffffffff,0x002fffff,0x00fffffc,0x80bff900,0x2000fffe, 0x03fffffb,0x2000dfff,0x7c44fff9,0x6c000fff,0x7d400fff,0x0000000f, 0x337bf726,0x7c03ff10,0xe8801dff,0x0dfd005f,0x2ff41ff6,0x01ffe600, 0x260dff50,0x7c400fff,0x5ff300ce,0x00bfea00,0x001fff90,0x00bfff10, 0x3fe07ff1,0x02ff9804,0x400bfd10,0xec984ff8,0x440adfff,0x4ffe84ff, 0x2fffdc00,0x013fa000,0xfffb8df9,0x81efffff,0x3ff20ffa,0x5fffc404, 0xaaaaaaaa,0x00aaaaaa,0x3ff7fea0,0x3ff20005,0x0fffe605,0xfccffa80, 0x7ffd40ff,0x3ff60002,0x02fffc47,0x017ffcc0,0x95101bf2,0x0179dfdb, 0xfffffb10,0x0bfdbfff,0x03ffca98,0xe8007fec,0x50ffb06f,0xf98003ff, 0x3a2000ff,0x7ffa80cd,0x3fe60000,0x04ff8802,0x01fffcc0,0x41fff700, 0xffdcccca,0xffcccccd,0xff301cce,0x03ff6005,0xf986fc80,0x5fffdeff, 0x3e20ffa8,0x7c4002ff,0x640005ff,0x217fc06f,0xb9999efb,0x47fd06ff, 0x7c403ffc,0x000001ff,0xfff1ffb0,0x3ff20001,0x01bff205,0xff35ff98, 0x05ffd87f,0x0fffd400,0x0009fff1,0xff013ffa,0x7fff5409,0x03ffffff, 0x37ffffe6,0x0efffffe,0xa81ff600,0x3f6002ff,0xfd0bfd07,0x3ffe000b, 0x7d400004,0x300000ff,0xdfd005ff,0x0fff7000,0x3fff8800,0x3ffffff2, 0xffffffff,0xf303ffff,0x5ff5005f,0x4c2ff800,0x7fd40dff,0x3e63fe82, 0xff8000ff,0x7d40005f,0x70ff501f,0x07fe60bf,0x3ffc9bee,0x00fffc40, 0x7fc40000,0x0007ff96,0xfe817ff2,0xdff3004f,0x7fc4ffe8,0x7c40003f, 0x3ffe24ff,0xbffb0003,0xc80ffcc0,0xeddfffff,0xfd03ffff,0xffb883ff, 0x4055446f,0xff881ffc,0x0ffdc004,0xff513fe2,0x3ff60003,0x100000cf, 0x00003fff,0xf700bfe6,0xff90003f,0xfff0000b,0x7ffffe4d,0xffffffff, 0x303fffff,0xff8805ff,0x43fd4004,0x3fea05fe,0xff537dc0,0x3ffa000f, 0x7fc40005,0xf709f903,0x207fe20b,0x7ff90ff8,0x01fff880,0xffb80000, 0x000dff34,0xff817ff2,0xeff8803f,0xf12ffe40,0xf00005ff,0x7ffc4bff, 0xdff90002,0xf983fdc0,0xfe980cff,0x0fffb86f,0x47ffff30,0x7fc45fe8, 0x000dfd07,0x3623dff1,0x02ff40ff,0xfffff300,0xe800037d,0x300004ff, 0x7fcc05ff,0x9ffd0003,0xfffb0000,0xfd04ff80,0x0bfe600d,0x9000dfb0, 0x01ff889f,0x87fc404c,0xb0006ffb,0xdddddfff,0x201ddddd,0x07fb05fd, 0x1bf20bf7,0x7ff91ff8,0x01fff880,0xffe80000,0x000bffe1,0x7c417ff2, 0x7f4402ff,0x27ffb80f,0x0001fff9,0x3e26ffd8,0xf90002ff,0x82fec0df, 0x7c406ffc,0x3ffe21ff,0xffdfd103,0xdcfffa8f,0xffb83fff,0xfff70001, 0xfa87fffd,0x7440001f,0xdfffffff,0xfb33001b,0x133333df,0x02ff9800, 0x4000bfd1,0x80003fff,0x3e207ffc,0x009ff03f,0xfb80bfe6,0x3fd8001f, 0x20003fcc,0x0dff91ff,0x3ffff200,0xffffffff,0x20ff701f,0xcefb82fe, 0x02ffeccc,0x1ffe4bfa,0x007ffe20,0xfff30000,0x8005ffc8,0xff305ffc, 0x1ffe803f,0x2a1fff50,0x80000fff,0x3fe27ffc,0xff70001f,0x40ffe20f, 0xfe801ffd,0x81ffe61f,0x1fff8efd,0x7fffffe4,0x003ff983,0x7ffffd40, 0x0005fe82,0xfffff910,0x407dffff,0xfffffff9,0x4002ffff,0xff902ff9, 0x3fe20001,0xfa80002f,0x3ff500ff,0x2005ff30,0xff302ff9,0x0bfa0007, 0xe8000df7,0x00bffb2f,0x3fffff20,0xffffffff,0xd03ff301,0xffff703f, 0xe8019fff,0x807ff92f,0x0001fff8,0x227fec00,0x4000fff9,0xff305ffc, 0x17fec01f,0x2a1fff50,0x80000fff,0x3fe27ffb,0xff70001f,0x003fea0f, 0x8bff6001,0xff705ffa,0x220bff61,0xe8809aaa,0x02cb805f,0x2a026a62, 0xabb980ff,0x3f6e2000,0xdfffffff,0xfffff980,0x02ffffff,0xfa809980, 0xacba882f,0x01fff981,0x1fff9800,0xf701ff90,0x04cc003f,0xcb805fe8, 0x3f20ff42,0x97f40005,0xb0006ffc,0x33333dff,0xf8033333,0xb82fd84f, 0x1efdbaef,0xff91ff80,0x1fff8807,0x3e200000,0x3ffe81ff,0x82ffe400, 0xf901fff8,0x7ffb805f,0x0007ffea,0xf89bff20,0xf70001ff,0x01bf20df, 0xfff95100,0x4c27fdc5,0x0fff22ff,0x00ffc800,0x0001ffe4,0xffd113fa, 0x20003dff,0xfffffdb9,0x7555441e,0x0aaaadff,0x3fe20000,0xfffffb84, 0x17ffc45f,0x7ffd4000,0x320dfb00,0x3200007f,0x7fdc00ff,0x3ee17ec3, 0x8ffc0006,0xd0007ffb,0x20000bff,0x83fc86fc,0x07fdc5fb,0x7fe43fe0, 0x77ffc403,0xeeeeeeee,0x802eeeee,0xff706ffb,0x5ffc800f,0x2e0bffe0, 0xffc803ff,0x00bffe67,0x893ff600,0x90001fff,0x13fa0bff,0x7f6dd440, 0x22ffffff,0x7fc43ffc,0x0027fe44,0x5402ffa8,0x20003fff,0x3fe20ffb, 0x01fffdef,0xfffea800,0x02ffe407,0x3bf60000,0x6677fcc0,0x7ffc3fff, 0xffc80003,0x7413fe07,0xf500005f,0xfffa805f,0x3e61fe43,0xf80bb807, 0x01fff50f,0x00bfff00,0x703fea00,0xb0bf70df,0x93fd40bf,0xff8807ff, 0xffffffff,0x2fffffff,0x103ffe80,0x64005fff,0x3ffe05ff,0x8027fd43, 0x3fe26ffd,0xff80003f,0x07ffe23f,0x427fe400,0x64402ff8,0xffffffff, 0x3f22fffe,0x642fec4f,0xf88003ff,0x7ffcc04f,0x3fe0003f,0xf31ffdc4, 0x640000df,0x3ee02fff,0x2000005f,0x6fe81ffb,0x7ffc6ff8,0xffd80004, 0x3ff332a6,0xffccccce,0x001cccce,0x26027fc4,0x7dc3ffff,0x301ffc46, 0x27fa85ff,0x8000fff9,0x00005fff,0xff885ff1,0x7c42fdc1,0x649fb03f, 0x7fc403ff,0xffffffff,0x2fffffff,0x007ffcc0,0x6400bffb,0x3ff605ff, 0x8017fe66,0x7ff44fff,0x7fc40004,0x07ffe22f,0x427ff400,0x7fc407fb, 0x1aceffff,0x7fdc5ffb,0x3603ff26,0xfd8002ff,0x3bfe200e,0xf70003ff, 0xb85ff81f,0x055511ff,0x813ff600,0x00003ffd,0x2607ff30,0x647fd81a, 0xe80006ff,0x3fff24ff,0xffffffff,0x3fffffff,0x0077ec00,0x87ffdff1, 0x7fdc1ff8,0xd87fe882,0x0fffe24f,0x0bfff500,0x42ff4000,0x82fdc4fd, 0x7fc41ffb,0x22009880,0x9999afff,0x99999999,0x2ffe4009,0x003ffea0, 0xf502ffe4,0x0dff33ff,0x20fffdc0,0x0000fffb,0xf883ffee,0xff0001ff, 0x80bfb07f,0x201bfffe,0x3fea2ffe,0x3e03ff57,0x7dc001ff,0x3bfa201f, 0x88003ff8,0x1ffc44ff,0xff897fcc,0xffb8000f,0x007ffe06,0x037f4000, 0x2627fc40,0x20001fff,0x3f21fffa,0xffffffff,0xffffffff,0x3fee003f, 0x23bfa201,0x84fd83ff,0xfebbdffd,0x07fc41ff,0xd001bff2,0x0000bfff, 0x7fcc3fdc,0xfe817ee2,0xfc82ff45,0xfff883ff,0xff000001,0x999999bf, 0x009fff99,0xfd017ff2,0x001dffbf,0x221bffe2,0x6dc05fff,0x227ffcc0, 0x8001fff8,0xff80fffa,0x07ffe603,0xf88bffe0,0x503ffaff,0xf9800fff, 0x87fec03f,0xfb8003ff,0x41ffcc0f,0x3ffa3ff8,0x5ffa8003,0x000dff30, 0x003ff200,0xf03ffd10,0x74000dff,0x1bf606ff,0x20003fe4,0x7ec03ff9, 0xf307ff0f,0xffff705f,0xbfd03dff,0x005fff10,0x017fffe6,0x81ff9800, 0x03530ffc,0xffc8554c,0x5fffb500,0x001fff88,0xffffa800,0xffffffff, 0xf9007fff,0xfffa80bf,0x3f2000ff,0xfff902ff,0x867ff403,0x7c40fffe, 0xfe8001ff,0x01ff985f,0x26017fee,0x7ff42fff,0x3ffa05ff,0x037f4005, 0x3ff87ff2,0x427fc400,0xff882ff9,0x001bff24,0x7e40fff6,0xa800000f, 0x7cc002ff,0xfff502ff,0xfff70007,0xe827fc07,0x7f40005f,0xf0ffe406, 0x03ff207f,0x40af32a2,0xffb00ffc,0xffe8803d,0x400005ff,0x3ffd03ff, 0x0bff2000,0xf11bfe20,0x000003ff,0xfffffffb,0xffffffff,0xbff9005f, 0x09fffd00,0x027ffe40,0x640ffffa,0xfffeffff,0x01fff882,0x417ffdc0, 0x7fe407fc,0x2fffd806,0x807fffcc,0x2000fffd,0x3ee00ffc,0x001ffc2f, 0x3e203ff2,0x23ff983f,0x000efff9,0xf501fff5,0x1000007f,0xfb800bff, 0x7fec01ef,0x3ff2004f,0x0ffe205f,0x80013fe2,0x3ee00ffc,0xd01ffc2f, 0x320003ff,0x3fe602ff,0xffd302ff,0x0000bffb,0xfd106fd8,0x3a60017f, 0xff5003ff,0x01fff88d,0x7ffc4000,0x9999999a,0x05ffe999,0xd805ffc8, 0x200dffff,0x00efffe9,0x06ffffcc,0x7ffffdc4,0x03fff105,0xffff7062, 0xf7013fa0,0x7fec05ff,0xfffd83ff,0xffeb99cf,0x3fea002f,0x7fffec02, 0x02ffffff,0x3e04ff88,0x42ffa84f,0x00affffe,0x70dfffb1,0x59997fff, 0xb0051013,0x362001df,0xe8800dff,0x2601efff,0x200ffffe,0xff981ffa, 0x5ff30002,0xfffffd80,0x882fffff,0x3000bffe,0xf3007ffd,0xb757bfff, 0xfff57fff,0xffffffff,0xfb809fff,0x3fff600f,0x7f54c09c,0x3ba601ff, 0x7c41ffff,0x400001ff,0x5c006ffb,0x7e401fff,0x7ffec05f,0xcbdeffff, 0x0dfffffd,0xffffd300,0xfffd97bd,0xf1019fff,0x3ff603ff,0x82fffffd, 0x7c402ff8,0xba8acfff,0x44fffffe,0xfffffff9,0x003fffff,0x32017fe2, 0xffeeeeee,0xffc801ee,0xd03ff600,0xfffd10ff,0xffd9bfff,0xff50bfff, 0xffffffff,0x3ffd9bdf,0x000ffdc0,0x88009ffd,0xcdfffffe,0xefffffdc, 0xb83fe400,0xf88000ff,0xeeec805f,0x1eeffeee,0x273fff60,0x7fff54c0, 0x3ffa2001,0x3fffffff,0xfffffff5,0x9fffffff,0x402ff880,0xefffffea, 0x00dfffff,0x1fffffd4,0x000fffc4,0x00fffa00,0x809fff10,0x3f205ffc, 0xfffff73f,0x7fffffff,0xfffb1000,0xffffffff,0x887fffff,0xffa81fff, 0x01ffffff,0xf5001ff5,0xffffffff,0x44dff35d,0xfffd9cfe,0x4000dfff, 0x40000efd,0xff1003ff,0xcfff9807,0xb102ffea,0xffffffff,0x2209ffff, 0xffffffff,0xffffffff,0x09ff104f,0x6677fec0,0x6400cccc,0xffffffff, 0xb004ffff,0x01ff20df,0x00077ec0,0x5400ffe0,0xfefffffe,0x000dffff, 0xffffdb88,0x3ffea2df,0xffffffff,0xfe804fff,0xfffb5004,0x0017dfff, 0x88066a62,0x00001fff,0x0003ffe6,0xf901fff2,0x0ffe60bf,0xfffffd91, 0x800017df,0xffffffc9,0xffd88bef,0x3fff11ef,0xffffd730,0x037ec03b, 0xfffffd30,0x11fff89f,0x1aa988dd,0x03ff7000,0x007ff000,0x2a003ff2, 0x04ffffff,0xfffffc98,0x6c02ceff,0x75cc09cf,0x03efffff,0x7cc00dfd, 0xffffffff,0xffb8801f,0x0bffffff,0x7413fe00,0xffa8005f,0x3ff80001, 0x7ffed400,0x000befff,0x0006a600,0x154c0000,0x004cc400,0x7fc40000, 0x3200001f,0xf30006ff,0x7fe405ff,0x26012e05,0x000009aa,0x01355330, 0x0003ffa6,0xaa800d44,0x9a988001,0x00008000,0x004ff880,0x10059900, 0x64c007ff,0x98002cee,0x44001aa9,0x15551000,0x000ffe40,0x99999995, 0x88001999,0x00009aa9,0x06aa0355,0x009ff100,0x000b3200,0x00009988, 0x00000000,0x00000000,0xff100000,0xffffffff,0xffffffff,0x003fff8f, 0xc81bffa0,0x000005ff,0x00000000,0x00000254,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0xf1000000,0xffffffff,0xffffffff, 0x07ffd4ff,0x3fff7000,0x0017ff20,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x10000000,0xffffffff, 0xffffffff,0x2ffecfff,0x3ffe2000,0x00000004,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00035000,0x00000000, 0x00000000,0x00000000,0x00000000,0x03eeea80,0xd97bba20,0x3baa05ee, 0x037baa0d,0x2732e000,0xd9004cc8,0x664003dd,0x44019900,0x3bae0eee, 0xedca8804,0x0000bcef,0x072e0397,0x00fbbae0,0x0acdca80,0xb80e5c00, 0x1eee801c,0x10013baa,0x88006a60,0x00004eed,0x2003ddd9,0x0004eee9, 0x80799700,0x2defedb9,0xdfdf5000,0x3fae0001,0x00000cef,0x3fffb6e2, 0x40000acd,0xdeffecb9,0x37fdc00c,0xfffeca80,0x300002ce,0x7bdffdd9, 0xffe80001,0x7ffdc006,0x805fff51,0xfff14ffd,0x3f600003,0x807ff8af, 0x00effffa,0xff709fb0,0x21fff880,0x75405ffc,0xffffffff,0x6fc8003f, 0xb000ffa8,0xd5000fff,0x1dffffff,0x2a1bf200,0xfff800ff,0x4017fee1, 0xd0adffea,0x7ff4007f,0x440003ff,0x5c004fff,0x10001fff,0x81bffa0b, 0xfffffffb,0x9f4000df,0x74c003d8,0x1fffffff,0x7fec4000,0xffffffff, 0xfd88004f,0xffffffff,0xdff700cf,0xffffeb80,0x03efffff,0xffffd500, 0x17ffffff,0x1fff5000,0x23ffe800,0xf8804ffd,0x03ffdaff,0x2bff6000, 0x7c407ff8,0x005ffbff,0xf955bff5,0xfff8809f,0xc817ff21,0xeddfffff, 0x4003ffff,0xfcabdff9,0x3fa2005f,0x3fee003f,0xefffffff,0xbdff9800, 0xf005ffca,0x2ffdc3ff,0x7ffffcc0,0x000fffff,0x3ffdbff9,0x37fe4000, 0x05ffd800,0xfd07fb80,0x3ffee0df,0x5ffffddf,0x6a83e600,0x3fffe200, 0x00ffffdd,0xfffff500,0xfffffdff,0x3ea003df,0xffffffff,0xb83fffff, 0x3ff606ff,0xffffffff,0x64005fff,0xfeffffff,0x00efffff,0x000fff40, 0xff997fea,0x3ffe6006,0x400004ff,0x7ec8affd,0xfd9fff40,0xfffb004f, 0xd100bfff,0x2775c1dd,0x80cfff98,0x8006ffe9,0xeffffffb,0x37fcc000, 0x0cfff980,0x003bffaa,0x3fffffee,0x3ddd000e,0x5c027754,0xfffda8df, 0xfff5004f,0x001fff31,0x001fff10,0x000fff40,0x7ff41ffe,0x0bfffa86, 0x000fffdc,0xb002645f,0x7f441bff,0xffb8004f,0x5441adff,0x402ffffd, 0x09bffffd,0x3ffffae6,0xd82ff543,0x221bffff,0x0efffea9,0xbffffe80, 0x6fffea80,0x00ffe600,0xfd83bf60,0x7fdc000f,0xd800006f,0xd81b62ff, 0x3ffe26ff,0xbddb5002,0x20000005,0x7c406ffc,0xd98001ff,0x20003dee, 0xfe802ffa,0x7ffd104f,0x37bb6600,0x00000003,0x01750397,0xc8bffe20, 0xfb8006ff,0x7c40001f,0x3ffc005f,0x04ffd800,0xc800fffa,0x2001fdcf, 0xffb82fff,0x7ffcc006,0xfff5002f,0x77ffd40d,0xfffe8800,0xffb84f83, 0xfff9005f,0x4fffc80b,0x09fff900,0x40006620,0x004cc099,0x00099980, 0x22ffd800,0x0266604f,0x00001331,0xfb000000,0x3ffd003f,0x00000000, 0xff500262,0x37fd401f,0x00000000,0x20000000,0x99981998,0x004c4000, 0x00198800,0x44003ffc,0x3ee00fff,0x66d4003f,0x1ffe2000,0x1003ffcc, 0x8001dffd,0xf881fff9,0xfd8005ff,0x20be60ff,0x54006fff,0xff502fff, 0xffd8009f,0x0000000f,0x00000000,0x4bff6000,0x000002fd,0x00000000, 0xffd80040,0x00000002,0x2ffec000,0x000fffc0,0x00000000,0x00000000, 0x00000000,0x81ffe000,0x07ff8819,0x00017fec,0x03fff000,0x6400bff7, 0xb0001fff,0xfff90bff,0xfff10001,0xf503ba29,0xfb0003ff,0x1bffa0ff, 0x13ffe200,0x9bdd9510,0x7ee54001,0x44001bde,0x00cdeeca,0x8b3bae60, 0x01e8affd,0xcdeeca88,0x3f72a000,0x32a01bde,0x1ccb801c,0x7fe54400, 0x6dcc002f,0x2a01bdee,0xccb801cc,0x200bffa1,0x2a204ffc,0x0bcefedc, 0x3bf72a00,0x654001bd,0x001bdefd,0x5ef7ee54,0x7ee54001,0x54001bde, 0x01bdefdc,0x33fff326,0x30ff10cc,0x7fc40fff,0x00732a07,0x7f40732e, 0x02ffd86f,0x0013ffe0,0x7cc5ff98,0x2a0004ff,0x81ffafff,0x30006fda, 0xff985fff,0xbf90002f,0x3fffa207,0x404fffff,0xffffffd8,0xfe8804ff, 0x4fffffff,0x7ffffd40,0x2ffd8eff,0xffffd100,0x8809ffff,0xfffffffd, 0x07ffb04f,0x2205ffd0,0xffffedba,0x32002fff,0xffffffff,0x007ffb03, 0x3fe25ffd,0x6ffa800f,0xfffffd50,0x8807ffff,0xfffffffd,0xffd8804f, 0x04ffffff,0xfffffd88,0xd8804fff,0xffffffff,0xfffd8804,0x504fffff, 0xffffffff,0xf303fe23,0x1ffe40df,0xd007ffb0,0x3fea05ff,0x0fffb14f, 0x00fffcc0,0x7fdc0600,0x7fc0000f,0x00800dff,0x913ffa00,0x04000fff, 0x3bfffe60,0x04ffffdd,0xbbdffff3,0x201dffff,0xddeffff9,0xf704ffff, 0xffd9dfff,0x3005ffdd,0xfbbdffff,0x3e609fff,0xffddefff,0x7fec0eff, 0x42ffe803,0xffffffc8,0x02fffeff,0xdefffe88,0x40efffed,0xfe803ffd, 0x00fff32f,0x3f21ffe6,0xfeddffff,0xff303fff,0xfffbbdff,0x3fe601df, 0xfffddeff,0xfff300ef,0xffffbbdf,0x3ffe601d,0xffffddef,0xffff300e, 0xdffffbbd,0xfffee981,0x1ff30eee,0xf106ffa8,0x3ffd80ff,0x202ffe80, 0xffecfffc,0x3ff2000e,0x9000000f,0xb0000bff,0x00000dff,0xfd1fff20, 0x400000df,0x6441fffe,0xffe82fff,0x5fffa81e,0x883fffd0,0x7c42fffc, 0x7f4c0dff,0xfe802fff,0x7fe441ff,0x1effe82f,0x6c5fffa8,0xffe803ff, 0x3ffffe22,0xffb1acef,0x3dffb005,0xd89fff30,0xffe803ff,0x200fff52, 0x3e60fff9,0xfe980cff,0x3dffd06f,0x20bfff50,0xfa81effe,0xdffd05ff, 0x0bfff503,0x2a07bffa,0xffd05fff,0xbfff503d,0xf983ffc0,0x837fd41f, 0x7ec03ffd,0x2ffe803f,0x7fffff40,0x6ffd8004,0x3fa00000,0xfb80004f, 0x0000007f,0xfff8fff7,0xf7000005,0x7ff401ff,0x0077fe45,0xfb85fff3, 0x3ffa00ff,0x1037fec5,0xb805fffd,0x3fa00fff,0x077fe45f,0x6c5fff30, 0xffe803ff,0x06ffffa2,0x5402ffe8,0x3e200fff,0x0fff61ff,0x7d4bffa0, 0xfff1006f,0x2037fe41,0x7e41fff8,0x3fe600ef,0x077fe42f,0xc85fff30, 0x3e600eff,0x77fe42ff,0x0bffe600,0x4c01dff9,0xfff02fff,0xf507fea0, 0x1fff10df,0x803ffd80,0x36202ffe,0x0003ffff,0x0000bffd,0x001fffc0, 0x983ffd40,0xeeeeeeee,0xeeeeeeee,0x0fffeeee,0x0000fffe,0x201ffec0, 0xff10fff9,0xdff9005f,0x4c03ffd8,0x3ffe0fff,0x17ffdc02,0x300fff60, 0x3fe21fff,0x6ffc802f,0x3a00fff6,0x3fff32ff,0x805fff00,0xfb802ffe, 0x00fff65f,0x7fdcbffa,0x1fff1006,0x7400ffec,0x3ffe21ff,0x26ffc802, 0xc802fff8,0x3ffe26ff,0x26ffc802,0xc802fff8,0x3ffe26ff,0x06ffc802, 0x3fea0fff,0x4c37fd42,0x7ec00fff,0x2ffe803f,0xffffff70,0x3ffe000d, 0xf1000003,0x500005ff,0xff301fff,0xffffffff,0xffffffff,0x223fffff, 0x00002fff,0x2600fff0,0x8037fcc0,0x3fe0fff8,0xf8813007,0x5fff006f, 0x3007ff80,0x006ff981,0x3f61fff1,0x2ffe803f,0xf300bff7,0x7fcc05ff, 0x4fff1007,0xfe803ffd,0x00bff72f,0x00407ffc,0x3e62ffd8,0xfff1006f, 0x401bfe61,0xff30fff8,0x3ffe200d,0x200dff30,0xff30fff8,0x3ffe200d, 0xf707ff80,0x06ffa87f,0xfd80bfff,0x2ffe803f,0xfcefffd8,0xff8005ff, 0xfff9803f,0x4fffffff,0x0003fff3,0x303fff30,0xffffffff,0xffffffff, 0x3fffffff,0x000bffe2,0x01bfe200,0x005ffb80,0x7fc47ffe,0x3fea0006, 0x05ffd005,0x00037fc4,0x7c00bff7,0x07ffb1ff,0x3f25ffd0,0xfffd806f, 0x01bfea02,0xffb0fff8,0x25ffd007,0xf1005ffa,0xa88001ff,0x3ee2fffc, 0x3ffe005f,0x400bff71,0xbff71fff,0xb8fffc00,0x3fe005ff,0x00bff71f, 0x7fc0fffc,0xa87ff707,0xfff706ff,0x0fff601d,0xfb0bffa0,0x7ffec9ff, 0x202f7e23,0xf9803fff,0xffffffff,0x05fff14f,0x1fff7000,0x266fffe0, 0x99999999,0xffa99999,0x07fff10f,0xbff50000,0x27fe4000,0x2a5ffd00, 0x2e0005ff,0xffb004ff,0x02ffd405,0x009ff900,0xffd97ff4,0x72ffe803, 0x7ec05fff,0x3ee03fff,0xffffffff,0x1fffffff,0xfd007ffb,0x01bfe65f, 0x8807ffc4,0xffffedba,0x3ff22fff,0x4bffa004,0x3a004ffc,0x09ff92ff, 0xfc97ff40,0x3ffa004f,0x4009ff92,0x7ff82ffe,0xfa89ff90,0x3fff206f, 0x03ffd82f,0x3ea2ffe8,0x7ff443ff,0x20fff71f,0xf9804ffe,0xffffffff, 0x00fffe4f,0x81fff200,0x40003fff,0x7ffc7ffa,0xfb800005,0x3f60004f, 0x3ff6003f,0x0009ff73,0xc801ffec,0x3fee02ff,0x3ff60004,0x4fff6003, 0xfe803ffd,0x9ffff12f,0xfffd7515,0x7fe409ff,0xffffffff,0xb2ffffff, 0xffd007ff,0x401ffe65,0xfc887ff9,0xefffffff,0x3ff62fff,0x4fff6003, 0x36003ffd,0x07ffb3ff,0xfd9ffec0,0x3ff6003f,0x4007ffb3,0x7ff83ffd, 0xfa89ff90,0x7ffdc06f,0x01ffec4f,0xfff17ff4,0x3fffe60b,0xfb04ffe8, 0xfb0000bf,0x027ffc9f,0x037fec00,0x80009ffd,0x7ff46ffc,0xfb800006, 0x3f60005f,0x3ff6003f,0x000bff73,0xc8027fe4,0x3fee02ff,0x3ff60005, 0x4fff6003,0xfe803ffd,0x3fffea2f,0x9aefffff,0x3ff206ff,0xccccccce, 0xb1cccccc,0xffd007ff,0x401ffe25,0x7fc47ffa,0x1aceffff,0x7fec5ffb, 0x4fff6003,0x36003ffd,0x07ffb3ff,0xfd9ffec0,0x3ff6003f,0x4007ffb3, 0x7ff83ffd,0xfa8bffb0,0xffe9806f,0x00fff64f,0x7fccbffa,0x3ffea02f, 0xf700fffe,0xd80001ff,0x1bff24ff,0x13ffa000,0x0006ffd8,0x3f22ffec, 0x3a20007f,0x0dff50ac,0x027fe400,0x3ea5ffd0,0x3ea0006f,0x5ffb005f, 0x0037fd40,0x4009ff90,0x7ffb2ffe,0x985fff00,0x4ffffffe,0xfb80fffc, 0x7ec0005f,0x2fff803f,0x2a003ffe,0x7fff45ff,0x8bffa01b,0x3a004ffc, 0x09ff92ff,0xfc97ff40,0x3ffa004f,0x4009ff92,0x9ff92ffe,0x417ff400, 0xbffb07ff,0x1006ffa8,0x7fecfffb,0x52fff803,0xff900fff,0x7c40bfff, 0x6c0003ff,0x3ffe64ff,0x3fea0002,0x3ffee01f,0xfff10000,0x01fff987, 0x21fff700,0x97007ff9,0x017fea39,0xff31fff8,0x4732e00f,0xfd006ff9, 0x3ffcc05f,0xf51ccb80,0x7ffc00bf,0x8807ff91,0x53102fff,0x803fe013, 0x40007ff9,0x7c403ffc,0x0bffa2ff,0xf98fff60,0xfff801ff,0x8017fea2, 0xbff51fff,0xa8fffc00,0x3fe005ff,0x00bff51f,0xffa8fffc,0x07ffe005, 0x7ff41ffe,0x0037fd46,0x7fe4bffa,0x97ffc403,0xd801fffa,0x6c02ffff, 0x20000fff,0x7ffc4ffd,0x3ffa0006,0x05fff806,0x01fff900,0x2000bfff, 0x3fe25ffe,0x1ffe801f,0x5001fff3,0x7ffc4fff,0x21ffe801,0x7c400fff, 0x3fe202ff,0x1ffe801f,0x5001fff3,0x27fe4fff,0x00bffe60,0x4406f880, 0xf9801fff,0x09ff90ce,0x2e2fff98,0x7fc405ff,0x017fee1f,0xf98bffe6, 0xffa800ff,0x003ffe67,0xff99ffea,0x7ffa800f,0x2003ffe6,0x3fe67ffa, 0x7ffa800f,0xff01fff0,0x06ffa8ff,0xfca7fe40,0x7ffcc04f,0x009fff12, 0x805ffff3,0x0005fff9,0xff513ff6,0xff70007f,0xfff7007f,0xfff98003, 0x03fff704,0x42fffb80,0x7cc05ffd,0x02fff47f,0x3f62fff4,0x3ffcc05f, 0xf9017ff6,0xffd805ff,0x23ffcc05,0xfe805ffe,0x01bfee5f,0x0005fffb, 0x7ec037d4,0x6ffe806f,0xfb01bfee,0x0fff85ff,0xf91bfee0,0xfffb00df, 0x805ffe85,0x7ff45ffe,0x45ffe805,0xfe805ffe,0x02fff45f,0x3fa2fff4, 0x5ffe805f,0xff01fff0,0x46ffa8ff,0x9ffb00eb,0xfb01bfee,0x3fffc5ff, 0x3ffffa20,0x7ffdc02f,0x3fa6000e,0xfffd84ff,0x3fff2004,0x3fffe005, 0xfffd3001,0x0ffff401,0x86fff980,0xd103fff8,0xfff989ff,0x1fffb103, 0x103fff88,0xff889ffd,0xffff503f,0x3fff8805,0x989ffd10,0xfb103fff, 0x7ffcc1ff,0x5ffff903,0x0ffd4000,0x813ffe20,0x3e62fffc,0xfff903ff, 0x0effc85f,0x5c2fffa8,0x3f602fff,0x7fcc3fff,0xfffb103f,0x03fff981, 0x981fffb1,0xfb103fff,0xfff981ff,0x1fffb103,0x103fff98,0x3e01fffb, 0x7fff82ff,0xff937fd4,0x25fff30d,0xf903fff9,0x7fd45fff,0xfffd305f, 0xd805ffff,0x80acffff,0xfffffda8,0xeffff882,0x3fffa600,0x3fea000f, 0x7fdc03ff,0x7fcc03ff,0xf9102cff,0x3ee01fff,0xfda9bdff,0xfff906ff, 0xffd7337b,0x3ffee03f,0xfffda9bd,0x5bfff306,0xfffffb53,0xbfff7005, 0xdfffb537,0x2f7fff20,0x1fffeb99,0xabefffe8,0x2ffdffec,0x67ffc000, 0x7fe40fdb,0xfec99bef,0xfffe85ff,0xdffecabe,0x7ffc42ff,0xfffca9be, 0xcffff885,0xfffeba8a,0xfffc84ff,0xffeb99bd,0xbfff901f,0xfffd7337, 0x37fff203,0xfffeb99b,0x7bfff901,0x3fffd733,0x2f7fff20,0x1fffeb99, 0x3b7fffa0,0xfa8ffff1,0x3bffa26f,0x45fffc9b,0xcabefffe,0x42ffdffe, 0xcacefffd,0xfaaffffe,0x7e403fff,0xddffffff,0xcfffffff,0x3fffa200, 0xffdccdff,0x8000efff,0xcefffff9,0xfffffdca,0xffff5002,0xffb97bff, 0xfb803fff,0xffffffff,0x3ffee00e,0x1fffffff,0x7ffffdc0,0x200effff, 0xfffffffb,0x002ffcbf,0xfffffff7,0x7dc01dff,0xffffffff,0xfffd301f, 0xf73fffff,0xfc80005f,0xb80fffff,0xffffffff,0xffd305ff,0x73ffffff, 0xffd305ff,0x0dffffff,0x7fffffd4,0xff9aefff,0xfffff706,0x803fffff, 0xfffffffb,0x7dc01fff,0xffffffff,0x7ffdc01f,0x1fffffff,0x7ffffdc0, 0x401fffff,0xf3fffffb,0x6ffa8fff,0x7fffffc4,0x7f4c0fff,0x9fffffff, 0xffc82ffb,0xefffffff,0x017ffea0,0x3fffffea,0xefffffff,0x3fff2001, 0xffffffff,0x7440004f,0xffffffff,0x4000efff,0xffffffe9,0x01efffff, 0xfffffb30,0x3f66007f,0x00bdffff,0xfffffb30,0x3b26007f,0xff93efff, 0x7fecc005,0x3003ffff,0x7bfffffb,0xfffd8801,0x5ff71dff,0xdfb50000, 0x7fec4039,0x402effff,0xdfffffd8,0x2205ff71,0x3ffffffd,0xffffe980, 0x0fffc4ff,0xfffffd98,0xfb3000bd,0x017bffff,0x3ffff660,0xb3000bdf, 0x17bfffff,0x3fff6600,0x7000bdff,0x3fe9fffd,0x437fd47f,0xcffffec9, 0xffffb100,0x0bfee3bf,0x7fffff54,0x00df304e,0xfffffda8,0x0002ceff, 0xffffff91,0x000017ff,0x7ffff6dc,0x40003def,0xffffffda,0x260002ef, 0x220000aa,0xa980001a,0x2a60000a,0xa9800000,0x2a20000a,0x06a60001, 0x00000000,0x00135510,0x00003530,0x10003551,0x00001353,0x200006a2, 0x880001a8,0xa880001a,0x1a880001,0x004c4000,0x04d44000,0x00035300, 0x26003530,0x2a660000,0x8800000a,0x00009aa9,0x01353000,0x2a660000, 0x0000001a,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x0b332200,0x3331002a,0x33333333, 0x99700003,0x1776c403,0x9503ddb1,0x3bb2a219,0xeee800bd,0x0013baa1, 0x0009ddb1,0x007bbb20,0x0027774c,0x37bb2a20,0x5d44000c,0x32a01acd, 0x32e0003c,0x41ddd01c,0x04004eea,0x22001a98,0x00004eed,0x4003ddd9, 0x0001eeec,0x2f7bb6e6,0x77744001,0x776c0004,0xeed8000d,0x3bb2000d, 0xdb71000d,0x400379df,0x30aceeb9,0x4332a399,0x0aceeca8,0x79b75100, 0xb9510003,0xddb10037,0x7fff300b,0xf9013faa,0xffffffff,0x80003fff, 0x7d402ffe,0x09ffb0ff,0x3fa23ff2,0x02ffffff,0xff70fffc,0xfffe800b, 0x7c40003f,0x7dc004ff,0xe88001ff,0xffffffff,0xffffb004,0xf9019fff, 0x7f4000bf,0x43fff03f,0xd5005ffb,0x17f45bff,0x7ffffd00,0xfff88000, 0x7ff44004,0xfff90005,0x007fffff,0x017ffff4,0x02fffa80,0x02fffa80, 0x1bfffee0,0x3ffffea0,0x4c03ffff,0xefffffff,0xff92ffb8,0xfffffd13, 0xffb805ff,0x01efffff,0xfffffc88,0x7fd404ff,0xffe8802f,0x7402efff, 0xffffffff,0x7001ffff,0xfff99999,0x7fe4079b,0x3206ffad,0xeffffaff, 0x202fffff,0x3fee1fff,0x37ff2005,0x20001ffe,0xb0005ffc,0xf9800bff, 0xffddefff,0x3fa204ff,0xffffffff,0x005ffc86,0x7c0fffa0,0x17fee1ff, 0x3ffffe60,0x000fffff,0x3ffdbff9,0x2ffe4000,0x1fff9800,0x3fffa200, 0xefffedde,0x767fec00,0xfe8001ff,0xffd0004f,0x7ffcc009,0x3ea05ffc, 0xffecdeff,0xfff105ff,0x9dffb9bf,0x2fff25ff,0xfffeeffe,0xfffb01ff, 0x5fffffff,0x7ffff440,0x00dfffff,0x2201bfee,0x002ffffc,0xdddddfff, 0x003ddddd,0x3ffffffa,0x7406ffff,0x200fffff,0x0beffffc,0xe81bffea, 0x13baa1ee,0x4c7ffd40,0x88000fff,0x20000fff,0x3a001ffe,0x7e441fff, 0xfff882ff,0xfff710be,0x005ffc89,0x740fffa0,0x13baa0ee,0x36a37f20, 0x5004ffff,0xfff31fff,0xdff10001,0x7fd40001,0x3bff6005,0x04fff981, 0x3e63bfee,0x3ea000ff,0xff30005f,0x7ff4400b,0x3a07ffb3,0xffc884ff, 0x6fff440f,0x7ffff440,0x1bffff92,0xb87ffe98,0xd712dfff,0x3f601fff, 0xff931cff,0x2ffd80df,0xfdfff910,0xdff1009f,0x99700000,0x9bfff999, 0xffff8807,0x27ffe401,0x003fff50,0xfff98000,0x001bff22,0x00007ff2, 0x2e009ff1,0x3fa00fff,0x0fffb85f,0x641fff50,0x3a0005ff,0x000003ff, 0x2ea20e5c,0x5fff3000,0x40037fe4,0x80001ffc,0xfa800ffc,0x3fe200ff, 0x1fff981f,0xe801bff2,0xfb0000ef,0x7fec001f,0x107ffe25,0xffe80dff, 0x102ffec3,0x3f25ffff,0x3fe605ff,0x027ffc0f,0xff50bfff,0x3ffe203f, 0xf837f402,0xffe88cff,0x02ffd401,0xffd00000,0x04cc4005,0x007ffe40, 0x0000bffe,0x30333100,0x98800133,0x33100000,0x00fff600,0xff81fff3, 0x1fff402f,0x4000bff9,0x00003ffe,0x22000000,0x09998199,0x0004c400, 0xd0013300,0xff7005ff,0x3013310b,0x26600133,0x02660000,0x88133300, 0x37fcc099,0xff06b260,0xfffb803f,0x801fff92,0x3fe61ffe,0x1ffee01f, 0xfb013ff6,0x0198809f,0xfff98197,0x00ffee00,0xffe80000,0x32000002, 0xffe805ff,0x00000002,0x00000000,0x1ffe0000,0x7fdc04c0,0x23eea804, 0x20005ffc,0x00003ffe,0x00000000,0x00000000,0x7ff98000,0x00fff100, 0x00000000,0x40000000,0x8004fff8,0xff006ff8,0x01bff25f,0xffb8bff6, 0x07ffc406,0xf5007ffe,0x260000df,0x4ffc8abb,0x0007ff60,0x2ceeb980, 0x2600bffa,0x01bdeedb,0x36013ff2,0x36e602ff,0x4001bdee,0x1bdeedb9, 0x776dcc00,0x5cc001bd,0x201bdeed,0x40006ff8,0x20001ffe,0x20005ffc, 0x95103ffe,0x0179dfdb,0x3fb72a20,0x51000bce,0x179dfdb9,0x3b72a200, 0x1000bcef,0x79dfdb95,0x01bfea01,0x9950fff8,0x03997003,0x79dfdb71, 0x00732a03,0x2e20732e,0x01bcefed,0x2b7ffff6,0x05ffa800,0x3f25ffb0, 0x3ffc805f,0xf101ffea,0x005301ff,0x6540dff5,0xffff702c,0x03fffdff, 0x00003ffa,0x3fffffea,0x02ffe8ef,0x7fffffe4,0x7ff903ff,0x207ffb00, 0xfffffffc,0xfff9003f,0x007fffff,0x3ffffff2,0xff9003ff,0x07ffffff, 0x00017fea,0xc8000fff,0x3a0005ff,0xffea83ff,0x3fffffff,0x7ffff540, 0x403fffff,0xffffffea,0x75403fff,0xffffffff,0x7ff5403f,0x3fffffff, 0xffffffb8,0xffffffff,0x07ffb1ff,0xfa85ffd0,0xffffffff,0x803ffd83, 0x7fd42ffe,0x3fffffff,0xfffffd10,0x3ee037df,0x5ff9004f,0x32013ff2, 0x17ffc3ff,0x000dff90,0x2e04ffc8,0x7fec44ff,0xfffffeff,0x56ff885f, 0x0059dfd9,0xd9dffff7,0x05ffddff,0x37bfffa2,0x40efffed,0xfd803ffc, 0x7fff443f,0xefffedde,0xdfffd100,0x1dfffdbb,0x3bfffa20,0x0efffedd, 0xbdfffd10,0x81dfffdb,0x20004ffb,0x65445ff8,0x3ff2009b,0x3ffa0005, 0x7ffffe43,0x3ffffedd,0xbfffff90,0x07ffffdb,0x37fffff2,0x03ffffed, 0xbbfffff9,0x207ffffd,0xddfffffc,0x643ffffe,0xffffffff,0xffffffff, 0xd007ffb2,0x7ffd45ff,0xffffecde,0x401ffec5,0x3fea2ffe,0xfffecdef, 0x3fff205f,0x40efffff,0xf7003ffd,0x013ff25f,0xffb0fff2,0x0fffe20b, 0x1fff9800,0xfb13fee0,0x7ecc17ff,0x7fcc0fff,0xffffffee,0xfff100df, 0xfffe981b,0x3dffb02f,0xc89fff30,0xffd803ff,0x40f7fec3,0xfb04fff9, 0xfff303df,0x07bff609,0x6c13ffe6,0xff981eff,0x02ffdc4f,0x229ff300, 0x2ffffffe,0x000bff90,0xff31fff4,0xffd3019f,0x19fff30d,0x30dffd30, 0xd3019fff,0xfff30dff,0xdffd3019,0x019fff30,0xfc8dffd3,0xccccccef, 0x1ccccccc,0xfd007ffb,0x427ff45f,0x360fffc8,0xffe803ff,0x2213ffa2, 0x2200fffc,0xffffffda,0x013ff22f,0xffc97fdc,0x43ffc804,0xa9cfffe8, 0x000dfffd,0x1fffed44,0xfa93fee0,0x3ff201ff,0x7fffdc3f,0xfffffeff, 0x05ffd81f,0x20bfffe2,0x2200fffa,0x3ff21fff,0x23ffd803,0x2200fffa, 0x7fd41fff,0x3ffe200f,0x007ffd41,0xfa83fff1,0x3fe200ff,0x01bfea1f, 0xf9cffa80,0xffffffff,0x005ffc85,0xfc8fffa0,0x7ffc406f,0x2037fe41, 0x7e41fff8,0x7ffc406f,0x2037fe41,0x7e41fff8,0x7ffc406f,0x0017fee1, 0xd007ffb0,0x1bfe25ff,0x7ec7ffd0,0x2ffe803f,0xfe80dff1,0x3ae6003f, 0x3fee7fff,0x25ff9005,0xfc804ffc,0xffff703f,0x0005ffff,0x03fffffd, 0x7f49ff70,0x6ffe803f,0x0577ffe4,0xf0dfff91,0xffb803ff,0x02ffe82f, 0x3f25ffb8,0x3ffd803f,0x2e00bffa,0x17ff45ff,0x3a2ffdc0,0xffb802ff, 0x4017ff45,0x3fe65ffb,0x23997007,0xbeffdffb,0x3fffeb99,0x0002ffe4, 0x7fec7ffd,0x41ffe801,0xfe801ffd,0x00ffec1f,0x3f60fff4,0x1ffe801f, 0x7400ffec,0x1ffe61ff,0x07ffb000,0x3e65ffd0,0x0d64c06f,0xfd007ffb, 0x01bfe65f,0x20003593,0xff51fffb,0x4bff600d,0xfc804ffc,0xfffc883f, 0x002effff,0x77ffffc4,0xa7fdc00b,0xa800fff9,0x3ffa0fff,0x27ffd405, 0x3e00dff1,0x3ffcc2ff,0x327ff880,0xffd803ff,0x200fff33,0x3fe67ff8, 0x4fff1007,0xf1007ff9,0x03ffccff,0x3e27ff88,0xffe801ff,0x0bffff91, 0xf907ffe4,0x7f4000bf,0xfb00083f,0x6c00205f,0x200102ff,0x00102ffd, 0x0040bff6,0x3e22ffd8,0xef9801ff,0x007ffb0c,0x3fe25ffd,0xffd8004f, 0x12ffe803,0x70009fff,0xffd007fb,0x007ffe27,0x3f25fff1,0x3ffc804f, 0x5effffd4,0x00efffdc,0xffd99b10,0x7fdc03ff,0x200bff54,0x0181fff8, 0x7d4fff90,0x5ffd005f,0x2006ffa8,0x7ff90fff,0x2a7ffb00,0x3fe006ff, 0x00dff50f,0xffa87ffc,0x43ffe006,0x3e006ffa,0x17ff60ff,0x7e4fff30, 0xffe806ff,0x0017ff25,0x4003ffe8,0x02fffca8,0xfffca880,0xfca88002, 0xa88002ff,0x8002fffc,0x42fffca8,0xfe806ffd,0x00fff66f,0xffd8bffa, 0xd800adff,0xffe803ff,0x37ffff62,0x7ffb800a,0x90fffc40,0xffc80bff, 0x009ff92f,0x7fcc7ff9,0xffe980df,0xfd30000e,0x3fee01ff,0x400bff74, 0x20002fff,0xff70fff9,0x0bff6009,0xfffffff7,0xffffffff,0x00fff23f, 0x7fdcfff6,0xffffffff,0x71ffffff,0xffffffff,0xffffffff,0x3ffffee3, 0xffffffff,0xfff71fff,0xffffffff,0x443fffff,0xfd103fff,0x17ffdc9f, 0xf937fd40,0x7f4000bf,0xdb75103f,0x5fffffff,0x7f6dd440,0x02ffffff, 0x3ffb6ea2,0x202fffff,0xfffedba8,0x2202ffff,0xffffedba,0x7fc42fff, 0x3fff204f,0x200fff62,0x3fa22ffe,0x1befffff,0xd007ffb0,0x7ff445ff, 0x01beffff,0x5c07fff3,0x7ffc46ff,0x5ffff503,0x32013ff2,0x17ffa3ff, 0x007fff10,0x827ffc40,0x9ff94ffb,0x01fff400,0x6cbffe00,0xff9003ff, 0xfffffc85,0xffffffff,0x7ff92fff,0x327ffb00,0xffffffff,0xffffffff, 0xffffff92,0xffffffff,0x3fff25ff,0xffffffff,0xf92fffff,0xffffffff, 0x5fffffff,0x9bdfffb8,0x546fffda,0xf8800fff,0x0bff90ff,0x21fff400, 0xffffffc8,0x82fffeff,0xffffffc8,0x82fffeff,0xffffffc8,0x82fffeff, 0xffffffc8,0x82fffeff,0xffffffc8,0x82fffeff,0x99befffc,0x6c5fffec, 0xffe803ff,0xfffffc82,0x7ec0efff,0x2ffe803f,0xffffffc8,0xffc80eff, 0xfca9acef,0xfffb83ff,0xfffda9bd,0x09ff92ff,0x3e67ff90,0xffa800ff, 0x7fdc0007,0x329ff707,0x3fa003ff,0x7f40002f,0x007ff92f,0xff90bff2, 0x9999999d,0x23999999,0xfd803ffc,0x99dff93f,0x99999999,0x3ff23999, 0xccccccce,0x91cccccc,0x99999dff,0x99999999,0x333bff23,0xcccccccc, 0xffb81ccc,0xefffffff,0x003ffcc0,0x3ff23fff,0x3ffa0005,0x3ffffe23, 0xffb1acef,0xfffff885,0xffb1acef,0xfffff885,0xffb1acef,0xfffff885, 0xffb1acef,0xfffff885,0xffb1acef,0x3fffee05,0x85ffffff,0xfe803ffd, 0xffb5102f,0x6c5fffff,0xffe803ff,0xfffb5102,0xfd05ffff,0xffffffff, 0x7ffd405f,0xfecfffff,0x009ff92f,0x3fea7ff9,0x1fff1006,0x7ffcc000, 0xf74ffb80,0x7ffc009f,0x7ffc0001,0x2009ff51,0x7fdc2ffd,0x7fe40005, 0x73ffd803,0xb8000bff,0x5c0005ff,0x5c0005ff,0x400005ff,0xffffffd9, 0x01fff103,0x7e43ffe0,0x00e54c5f,0xffe8bffe,0x3ffa01bf,0x0dffff42, 0xfe85ffd0,0x3fa01bff,0x5ffff42f,0xd0bffa01,0x74037fff,0x3f6202ff, 0x02efffff,0xff007ffb,0x3ae6005f,0x3ff67fff,0x02fff803,0xffffd730, 0x3ffffaa0,0xd9801dff,0xfd3effff,0x013ff25f,0x7fdcfff2,0x07ffe005, 0x7ffc4002,0xf54ffb81,0x3fe200df,0x00fdd50f,0x7cc3ffe2,0x5ffd005f, 0x0007ff98,0x26003100,0x4c0007ff,0x4c0007ff,0x4c0007ff,0x000007ff, 0xf0015ff3,0xff1005ff,0x2e2ffe4d,0x3fe204ff,0x03fff32f,0x7cc5fff0, 0xfff801ff,0x007ffe62,0xff98bffe,0x2fff801f,0x2007ffe6,0xb1002fff, 0xffc8017f,0x17ffc403,0x8fffdc00,0x7c403ffc,0xfb8002ff,0x3fe201ff, 0x2a60000b,0x0017ff40,0xff53ffc8,0x87ffc00d,0xf3006fea,0x9ff701ff, 0x2003ffe6,0x3fe27ffb,0x7ffb801f,0x22007ffc,0x7fc42fff,0xcef9801f, 0x177ff400,0x003fff10,0x3e219df3,0xef9801ff,0x03fff10c,0x2219df30, 0xf9801fff,0x7fe400ce,0x4ffc801c,0x324ffa80,0x2ffd45ff,0x2e3fff10, 0xff9805ff,0x017fee2f,0xfb8bffe6,0xfff9805f,0x2017fee2,0x3ee2fff9, 0xfff9805f,0x003fa002,0xf3013ff2,0x0ff6e5ff,0x7e4fffa0,0x7ffcc04f, 0xd007fb72,0x7fc407ff,0xe800002d,0xf90002ff,0x03ffe67f,0xf89ffe60, 0xffb800ff,0x749ff706,0x7fc404ff,0x027ff43f,0xfd0fffe2,0xfffc809f, 0x806ffd82,0xec806ffe,0x3f600fff,0x6ffe806f,0x74037fec,0x37fec6ff, 0x3637ff40,0xffe806ff,0xffeb9806,0x0fffc401,0xfc8bffa0,0x07ffcc5f, 0x3f27ffb8,0xfffd806f,0x201bff22,0x3f22fffd,0xfffd806f,0x201bff22, 0x3f22fffd,0xfffd806f,0x401fe002,0x7ec06ffb,0x0fff72ff,0xf71fff88, 0xfffd80df,0x880fff72,0x2a201fff,0x00004ffc,0x80017ff4,0x3ffe2ffd, 0x45ffd804,0x7c404ffe,0x9ff704ff,0x881fffd4,0xffb86ffd,0xdffd103f, 0x207fff30,0x882ffffb,0x3f204fff,0x3ea002ff,0x3ffe204f,0x0bfff204, 0x6409fff1,0x7fc42fff,0x3fff204f,0x027ffc42,0x4005fff9,0xfd805ff8, 0xdffb00ff,0x7c2ffe41,0x7fd41dff,0x0bffee5f,0x23ffffd8,0x3602fffb, 0x3ee3ffff,0x3ff602ff,0x3ffee3ff,0x3ffff602,0x80bffee3,0x003ffffd, 0xf3005ff3,0x3ff207ff,0x7fff32ff,0xf337fdc0,0x3ff207ff,0x7fff32ff, 0x0037fdc0,0x00001ffd,0x80017ff4,0x3fea1ffe,0x3ffee04f,0x81fffd41, 0x700effd8,0xfffb89ff,0xfffb99ad,0xffffb01f,0xffff7539,0x37ffea03, 0xffffda9a,0xdfff902f,0xfffd9337,0x3ffc800b,0x5f7ffe40,0x5fffec99, 0x37dfff90,0x0bfffd93,0x26fbfff2,0x05fffec9,0x337dfff9,0x80bfffd9, 0x2ffdb998,0xcffff880,0x0effeb9a,0x7dc2ffe4,0xffecefff,0x3ffe20ff, 0xfeba8acf,0x3e24ffff,0xba8acfff,0x24fffffe,0x8acffff8,0xfffffeba, 0x33fffe24,0xfffeba8a,0x3ffe24ff,0xfeba8acf,0x2004ffff,0x03711efe, 0x957dfffd,0x45ffbffd,0x9acefffc,0x743fffca,0xecabefff,0x322ffdff, 0xa9acefff,0x2603fffc,0x005ffca9,0x017ff400,0x1fffb350,0x9bdfffd8, 0x03fffea9,0x539ffffb,0x403ffff7,0xffa84ffb,0xefffffff,0x3fff6201, 0x0effffff,0x7ffffdc0,0x2ffcbfff,0x3ffffee0,0x805fffff,0x0ffffeeb, 0xfffffb80,0x405fffff,0xfffffffb,0x7dc05fff,0xffffffff,0x7ffdc05f, 0x5fffffff,0xfffffc80,0x3ffa2006,0x0fffffff,0xfb05ffc8,0xffffffff, 0xfffff503,0xf35dffff,0xffffa8df,0x9aefffff,0x7ffd46ff,0xaeffffff, 0x7fd46ff9,0xefffffff,0x7d46ff9a,0xffffffff,0x006ff9ae,0x3fffffee, 0xffffe982,0xffb9ffff,0x7fffff42,0x982fffff,0xfffffffe,0x742ffb9f, 0xffffffff,0x3fe602ff,0x0001ffff,0x8017ff40,0x84fffff9,0xffffffc8, 0x6c03ffff,0xffffffff,0x7fdc02ef,0xffffb304,0x754009ff,0x04efffff, 0x3fffb260,0x805ff93e,0xffffffd8,0xfffb002e,0x6c4005df,0x2effffff, 0xffffb100,0x22005dff,0xeffffffd,0xfffb1002,0x2005dfff,0x00beffeb, 0xffffec80,0xbff901ce,0x7ffffdc0,0x3fa601de,0x7c4fffff,0x7ff4c1ff, 0x7fc4ffff,0x7fff4c1f,0x7ffc4fff,0x7ffff4c1,0x0fffc4ff,0x3fffffa6, 0x00fffc4f,0xdffffd88,0xffffb100,0x0bfee3bf,0x3fffffaa,0x3f6201df, 0xf71dffff,0xfffd505f,0x9803bfff,0x001deffe,0x02ffe800,0x1bffff70, 0x7ffff4c0,0xd5000dff,0x09ffffff,0x2013fee0,0x20000aa8,0x00009a98, 0x8000054c,0x40009aa8,0x00019a98,0x0004d544,0x00135510,0x004d5440, 0x01355100,0x10000000,0x00000153,0x88001551,0x200009a9,0x00009a98, 0x00026a62,0x0009a988,0x0026a620,0x026a2000,0x0001a980,0x0002aa62, 0x880006a6,0x00000aa9,0x33100000,0x2aea2001,0x0d54c001,0x15531000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x97000000,0x0deea839, 0x00037baa,0x55101100,0x13326000,0x951cca80,0x37f6e619,0xeed8800b, 0x807bba22,0x019900cc,0xd307774c,0x2e6001bd,0x9930bdfd,0x437bb605, 0x32a0eeec,0x1ccb801c,0x40000000,0xdd901ccb,0xa84eec89,0x220001cc, 0x98000ccc,0x333224cc,0xeea80000,0x6644002e,0xcc98000c,0x40000004, 0x00003ccb,0xc8866644,0x3cc8803c,0x2f36ea20,0x5ddd7000,0xd913bb20, 0xddb0007d,0x5cb32a0b,0xe85881cc,0x5ffd82ff,0x5005fff1,0xbffb3009, 0x4c13f217,0x3e2effec,0xfff002ff,0x3ea7ff21,0x0effffff,0xd877fdc0, 0x27ec04ff,0x7e403fdc,0x00bffa5f,0x3fffffea,0x83ffa9ff,0xff12fff9, 0x03ffd87f,0x2002ffe8,0x00effeca,0x40bffa00,0xff52fff8,0x07ff901f, 0x0fffc400,0x33ffd400,0x00001fff,0x1000dffd,0x50003fff,0x76dc0fff, 0x0002ceff,0x0000dffb,0xf30fff98,0xbff300df,0x3ffffee0,0x7fc00cff, 0x3ffe205f,0x001dff52,0x901fffb8,0x0bff67ff,0x5ffd0ff7,0xf95ffd10, 0x4fd8807f,0xffffff80,0xfa82ffef,0x321fffff,0xffa805ff,0x3ff3ff26, 0x5fffdcdf,0xfacffd80,0xdffa805f,0x004ffcaa,0x9ff97ffd,0xdffff100, 0xffbfffd9,0x649ffb07,0x3ffd85ff,0x002ffe80,0x0ffffff9,0x02ffe800, 0x3fa7ffe6,0x07ff901f,0x0fffc400,0x33ffd400,0x80001fff,0x8000fffa, 0x8001fff8,0xfea87ffa,0xefffffff,0x37fec001,0x3fe60000,0x00dff30f, 0xfe88bff3,0xffffffff,0x1dff701e,0xf9fffa80,0xfe8001ff,0x4fff203f, 0x3fe22ffd,0x302fdb87,0x00bfffff,0xfa809ff7,0xffffc99f,0xfffff886, 0x3ffe60fe,0x91ffec00,0xd30bffff,0xfe8809ff,0x9000efff,0x0bffffff, 0x7ffffc40,0x1bffd005,0x3ffffe88,0xff137fc4,0x07ffb01f,0x5005ffd0, 0x0ddfffff,0x02ffe800,0x17ffffdc,0x0007ff90,0x000fffc4,0xff33ffd4, 0xfe80001f,0xff10001f,0xff50003f,0xdffffa8f,0x1ffffecc,0x01bff600, 0x1fff3000,0x2601bfe6,0x7ffec5ff,0x3fff660c,0x001ffe80,0x05fffff9, 0x80bff500,0x5fb73ffc,0xfb83ffc4,0x3bffee00,0x04ffb800,0x0dcc1654, 0x402fff98,0x3e202ffe,0x3fff20ff,0x0bffe205,0x03ffff30,0x2deeda80, 0xefffa800,0x05ffc800,0x321ffff4,0x0bfee0ff,0x7401ffec,0xffc802ff, 0x3a00001e,0xffd802ff,0x1ffe404f,0x3fff1000,0x0fff5000,0xfa8000f9, 0x3e20003f,0xfa8001ff,0x3bffe27f,0x0effe981,0x80000000,0xff30fff9, 0x4bff300d,0x3203fffa,0x17fd44ff,0x13fff600,0x0077f400,0x1fa8fff2, 0x3e41ffe2,0x8004ccc0,0x00004ffb,0x201bfee0,0x3ea05ffb,0x07ffe45f, 0x2017ff20,0x00000998,0x04cc4000,0x401fff80,0x4c43fffa,0xfb004c40, 0x5ffd007f,0x009ffb00,0x02ffe800,0xf9003330,0x7c40007f,0xfa8001ff, 0x0007d87f,0x20000cc4,0x8001fff8,0x3ff27ffa,0x3ffe200f,0x00000004, 0xf30fff98,0xbff300df,0x2202fff4,0x06621fff,0x00666200,0xc8009980, 0xf11f23ff,0x009f70ff,0x13fee000,0xffc80000,0x0fff8804,0xfc85ffb0, 0x6ff8805f,0x00000000,0x7cc00000,0x7ffd005f,0x7fec0000,0x02ffe803, 0x0001ffe8,0x0017ff40,0x01ffe400,0x03fff100,0xf0fff500,0x0000000b, 0x007ffe20,0xff9ffea0,0x6ffb803f,0x00133100,0x0fff9800,0xf300dff3, 0x03ffe2bf,0x000ffee0,0x00000000,0x9f73ffc8,0x33fff326,0x2203d8cc, 0x1bcefedb,0x9dffb970,0x00e65479,0xffc8e65c,0x07ffb003,0xff90fff1, 0x43ffe007,0xcb801cca,0x0039951c,0x65403997,0x201bdefd,0xf9004ffa, 0x00732a7f,0x7fec732e,0x02ffe803,0x4001ffe8,0x3a2ceeb9,0xb95102ff, 0x20179dfd,0xfb713ffc,0x7fc4059b,0xffa8001f,0x51007ec7,0x15bdffb9, 0xcefedb98,0x07ffe201,0x4dffea00,0xf9800fff,0x9ff7007f,0xff980000, 0x00dff30f,0x3fe6bff3,0x4bff5007,0x99502cca,0x99999999,0x65459999, 0xbdd9510c,0x27ff9017,0x3fffea4c,0x5401ffff,0xffffffff,0xffffd83f, 0x3ff66fff,0x92ffe803,0x3ea007ff,0x84ffb86f,0xfd002ffc,0x00fff63f, 0x7fecbffa,0x82ffe803,0xffffffd8,0x7ff904ff,0x6cffee00,0xffe803ff, 0xd007ffb2,0x332a05ff,0x03ccdfff,0x3fffffea,0x82ffe8ef,0xffffffea, 0xffc83fff,0xffffffab,0xfff880df,0xfffa8001,0x2a01feb8,0xffffffff, 0xffff70ef,0x220bffff,0xa8001fff,0x099517ff,0x401ffe60,0x00003ffc, 0xf987ffcc,0x5ff9806f,0x2600dff7,0x13fee7ff,0x7fffffe4,0xffffffff, 0x3a23ff24,0x2fffffff,0xe981ffe4,0x0eeefffe,0x37bffea0,0x45ffffec, 0xeefffeec,0x200fff64,0x7ff92ffe,0x20fffc00,0xffc81ffe,0x25ffb001, 0xfe803ffd,0x007ffb2f,0xff985ffd,0xfffddeff,0x17fec0ef,0xfb3ffb80, 0x5ffd007f,0x3a00fff6,0xfff902ff,0x20dfffff,0xeceffffb,0x42ffeeff, 0xddfffffc,0x643ffffe,0xcdfffeff,0x440efffe,0xa8001fff,0x00ceffff, 0x33bffff6,0xfdffffed,0xffeddeff,0x1fff884f,0x07ffa800,0x017fee00, 0x00017fec,0x4c3ffe60,0xffa807ff,0x200bff55,0xff70fff9,0x3ffff209, 0xfeffffff,0x2bff23ff,0xfffeffff,0x0fff22ff,0x400fff10,0xfc884ffe, 0x4ffb80ff,0xd007ffb0,0x0fff25ff,0x264ffc80,0x3ff906ff,0x6c7ffa00, 0xffe803ff,0xd007ffb2,0xeffe85ff,0x45fffa81,0xf7003ffd,0x00fff67f, 0x7fecbffa,0x02ffe803,0xddfffdd7,0xbfff10bd,0xffffe981,0x033ffe62, 0xf91bffa6,0xf981bfff,0x7ffc45ff,0xfffa8001,0x2fff9800,0xffffff30, 0x85ffd305,0x8001fff8,0x10007ffa,0xf1007fff,0x800001ff,0xff30fff9, 0x2bff500f,0xf5007ff9,0x13fee3ff,0xbffd1000,0xbeffffc8,0xc9bffea0, 0x7fc403ff,0x0dff1007,0xfb83ffe8,0x07ffb04f,0x3f25ffd0,0x3fe6003f, 0x640fff26,0xfff002ff,0x200fff61,0x7ffb2ffe,0x645ffd00,0x3e600eff, 0x13ff22ff,0xfd9ffe40,0x2ffe803f,0xff007ffb,0x3ffd005f,0x205ffd80, 0x322ffff8,0x7fc406ff,0x17fff21f,0x221fff98,0xa8001fff,0xffb007ff, 0xffffb805,0x83ffe201,0x8001fff8,0x88007ffa,0x4400effe,0x00005ffe, 0xf30fff98,0xbff500ff,0x2007ffe2,0xff71fffd,0xffe80009,0x04fffc86, 0x7e47ffea,0x3ffc403f,0x406ff980,0xffb81ac9,0x007ffb04,0x3ff25ffd, 0x8fff4003,0xff900ffe,0x4dff1007,0xfe803ffd,0x007ffb2f,0x3fe25ffd, 0x6ffc802f,0x74017fee,0x07ffb3ff,0x3f25ffd0,0x2fff803f,0x401ffe80, 0x7dc01fff,0x07ff62ff,0xfc87ffa0,0x7fe400ff,0x007ffe25,0x201ffea0, 0xf9807ff8,0xffb803ff,0x007ffe24,0x001ffea0,0x803fffd1,0x000fffe8, 0x0fff9800,0xb801fff3,0x1bffa5ff,0x25ffff30,0x20004ffb,0xfc80effd, 0x7ffc00ff,0x8807ff92,0xff1007ff,0x7dc0009f,0x07ffb04f,0x3f25ffd0, 0x7fdc003f,0x3205ff9b,0xffb806ff,0x200fff65,0x7ffb2ffe,0x265ffd00, 0xff1006ff,0x07ffe21f,0x367fff30,0xffe803ff,0x9809ff72,0xfe802fff, 0x1bfe201f,0x0417ffc0,0x322ffd80,0xff9805ff,0x007ffe27,0x001ffea0, 0x3fff3001,0x44dff100,0xa8001fff,0x3a2007ff,0x74401fff,0x00002fff, 0x261fff30,0x7ec01fff,0x37ffe65f,0xfffffa80,0x0009ff71,0x6407fff2, 0xffe805ff,0x8807ff92,0x3f6007ff,0x800adfff,0x99dffc98,0x200fff60, 0x7ff92ffe,0xbeff8800,0x3ff202ff,0x1fff402f,0xfd007ffb,0x00fff65f, 0x7fdcbffa,0x87ffe005,0x7ec05ffc,0x07ffb3ff,0x3ea5ffd0,0x7ffec06f, 0x01ffe802,0x74017fea,0x544002ff,0x3f22fffc,0x1fff003f,0x0007ffe2, 0x0001ffea,0x07ffdb98,0xff89ffe0,0xffa8001f,0xfffd1007,0xfffe8803, 0x26000001,0xfff30fff,0x2fffcc0d,0x2f7ffff2,0xffecffec,0x0009ff71, 0x6405fff7,0xffd804ff,0x8807ff92,0x3a2007ff,0xbeffffff,0xfffffb01, 0x1ffecbff,0xfc97ff40,0xffd8003f,0x7fe407ff,0xdffb01ef,0xe803ffd8, 0x07ffb2ff,0x3f25ffd0,0x3ffa004f,0x037ffe22,0x27ffffb1,0xfe803ffd, 0x07fff32f,0x00bffff2,0xfb807ffa,0x5ffb004f,0x3fb6ea20,0x22ffffff, 0xfd002ffc,0x07ffe23f,0x01ffee00,0x7ff6dd40,0xffffffff,0xffffffff, 0x3fff10ff,0x0fff7000,0x007fff20,0x0007fff6,0x1fff3000,0x213fffe6, 0xc85ffff8,0xffffffff,0x3ee1ffd3,0x7fd4004f,0x1ffe403f,0xfc9ffec0, 0x3ffc403f,0x7fffe400,0x6c0effff,0x5fffffff,0x3a00fff6,0x07ff92ff, 0x9ffff500,0xfffffc80,0xfffeb9ac,0x401ffec2,0x7ffb2ffe,0x365ffd00, 0x3f6003ff,0x7fffd43f,0xfefffece,0x007ffb3f,0x7fec5ffd,0xfffcabef, 0xfe802ffd,0x0fff601f,0x2217fe40,0xfffffffc,0x322fffef,0xffd001ff, 0x007ffe25,0x801bff20,0xffffffd8,0xfffffeff,0xffffffff,0xfff12fff, 0xdff90003,0x03fff100,0x005fff70,0xfff30000,0x3ffffe61,0xffffebcf, 0xfffb305f,0x87ffc5bf,0x26004ffb,0xfc804fff,0x3ffd803f,0xf8807ff9, 0xb510007f,0x5fffffff,0x3609ff70,0xffe803ff,0x0007ff92,0x9007fffe, 0xffffd9ff,0xfb05ffff,0x5ffd007f,0x3a00fff6,0x07ffb2ff,0x4c1ffec0, 0xefffffff,0xffb3ffd9,0x45ffd007,0xffffffe8,0x02ffb9ff,0x3201ffe8, 0xff9003ff,0x7ffffc45,0xffb1acef,0x800ffe45,0x3ffe1ffe,0x6ffc8002, 0xffffd100,0xff1157bd,0x9999999f,0x43999999,0xc8002fff,0xffa806ff, 0x07ffb005,0x3e600000,0x9fff30ff,0x5fffffff,0x03300bff,0x7fdcfff1, 0xbfff1004,0x00fff200,0x7fe4fff6,0x03ffc403,0xffeb9800,0x04ffb87f, 0xff007ffb,0x00fff25f,0x4037fe40,0xfff93ffc,0x3f6017df,0x2fff803f, 0xff007ffb,0x013ff25f,0x7102ffe8,0x3617bfd9,0x07ffb2ff,0xc885fff0, 0x71dffffe,0xffd005ff,0x027fd403,0x3fa2ffd8,0x3fa01bff,0x00bff22f, 0xfff07ffc,0xbffb0007,0x2fbffe00,0x00fff101,0x007fff00,0x900bffb0, 0x3fe007ff,0x5013001f,0x7fd40197,0x32dff30f,0xff2effff,0x7fd4000b, 0x2013fee5,0x000effe8,0xfb007ff9,0x00fff27f,0x0000fff1,0xb83fff70, 0x7ff904ff,0x92fff880,0x2e0007ff,0xffc803ff,0x640054c3,0x7fc403ff, 0x807ff92f,0xff52fff8,0x0fffc00b,0x25ffb000,0x7c403ffc,0x06a202ff, 0x7f400ff2,0x17fe601f,0xf997ff40,0xfff801ff,0x200fff22,0x7fec7ff8, 0x3fff8005,0x01fffa80,0x0007ffcc,0x0017ff60,0x3600fffe,0xff8802ff, 0x1fff1007,0xf500fff4,0x237fccff,0x006000a9,0xff71ffe4,0x1fffd009, 0x01ffe400,0xffc9ffec,0x03ffc403,0xe803fdb8,0x2ffdc3ff,0x4c04ffc8, 0x7ff92fff,0x03ffa000,0x000fff20,0x4c04ffc8,0x9ff92fff,0x32fff980, 0xf5001fff,0x000d44ff,0x3ff23ffd,0x17ffcc04,0x002fd800,0xff803ffd, 0x7ffc400f,0x300bff72,0x7fe45fff,0x46ffb806,0x2001fffb,0xc801fffb, 0xffb805ff,0xeffa802f,0x007ffee0,0x801fffb8,0xff001ccb,0xdff7003f, 0x2e02ffd8,0x1bfe67ff,0x02ffe800,0xf70fffc4,0xfffd809f,0x1ffe4001, 0xfc9ffec0,0x0fff803f,0x407ffb80,0x7d41fff8,0x0dff705f,0xf92fffd8, 0xff50007f,0x0fff2009,0x06ffb800,0xfb97ffec,0x7ffec06f,0x2017ffa2, 0x7ffc5ffe,0x73ffdc00,0xffd80dff,0x3fd0002f,0x007ffa00,0xfc809ffd, 0x0dff92ff,0x645fffb0,0x7fc01fff,0x7fffcc2f,0x7ffe8800,0x80bffb00, 0x00effff9,0x3e62fff4,0xe8800eff,0x000007ff,0x3a017ffa,0x2ffe44ff, 0x7ccbffd0,0x3f20006f,0x2ffe405f,0xfc813fee,0xfc8002ff,0x3ffd803f, 0xff007ff9,0xfff3003f,0x437fdc07,0xf980fffa,0xfff903ff,0x00fff25f, 0x003ffd10,0x8000fff2,0xf903fff9,0x3fe65fff,0xffff903f,0x81fffcc5, 0x740fffd8,0x3fe204ff,0x0fffe64f,0x017fffe4,0xd003ff80,0xff9803ff, 0xffff703f,0x80bffee5,0x323ffffd,0xd881ffff,0xfff906ff,0x3fea015d, 0xff7002ff,0x3ffa201f,0x3f205fff,0xfffc82ff,0xfff500ae,0x4000005f, 0x3203fffb,0x7fd41fff,0x7ffe40cf,0x001bfe62,0x701fffa8,0xffb83fff, 0x07fff704,0x00fff200,0x7fe4fff6,0xdfffe803,0x3fff201e,0xffca9ace, 0xffff983f,0x77fff45d,0xfdffecab,0x007ff92f,0x0bfffb9b,0x001ffe40, 0x2fbfffa0,0xffdffeca,0x2fbfffa2,0xffdffeca,0x5efffe42,0x1fffeb99, 0x9bdfffb8,0x85fffdb8,0xcabefffe,0x02ffdffe,0x225dfb00,0x01ffe82a, 0x9adfffa8,0x2fffffda,0x159ffff1,0xfffffd75,0x7ffffe49,0xfffeb9ac, 0xffffd101,0xfffdb9df,0x7c4009ff,0xdb89ceff,0xfff9bfff,0xfffc9ace, 0xfffd104f,0xffdb9dff,0x64009fff,0x3f6002cc,0xea98adff,0xffb03fff, 0xffffbbff,0x006ff98b,0x56fffec0,0x83fffdb9,0xff984ffb,0xeedcccff, 0x90eeeeee,0xffb007ff,0x200fff27,0x02fffffb,0x7ffffff4,0x3602ffff, 0x74c7ffff,0xffffffff,0xff92ffb9,0xfffff007,0x7fe4001d,0x7f4c0003, 0x9fffffff,0x3fa62ffb,0x9fffffff,0xffb82ffb,0xffffffff,0x3ffff601, 0x05ffffff,0xffffffd3,0x05ff73ff,0x3fffea00,0x1ffe84ff,0xfffff700, 0x5ff97fff,0x7fffffd4,0xff9aefff,0x3f6bff26,0x1effffff,0x7fffec40, 0xffffffff,0xfffa8003,0x1effffff,0x3fffffa2,0x4404ffff,0xfffffffd, 0x003fffff,0x10027ffc,0xfffffffb,0x7cc09fff,0xffffffff,0x006ff985, 0x7ffff440,0x703fffff,0xfff309ff,0xffffffff,0x321fffff,0xffd803ff, 0x2007ff93,0x804fffeb,0xffffffea,0x7fec401d,0x7fec41ff,0xff71dfff, 0x200fff25,0x000efffe,0x0001ffe4,0x7ffffec4,0x885ff71d,0x1dfffffd, 0x36605ff7,0x0bdfffff,0xffffea80,0x6c404dff,0x71dfffff,0x640005ff, 0xe81dffff,0x326001ff,0xf93efffe,0xfffe985f,0x7ffc4fff,0x3f23ff91, 0x000dffff,0x3fffff6a,0x0001cfff,0x3fffffa6,0xffd9103e,0x4003bfff, 0xffffffda,0xf8001cff,0xea8004ff,0x1effffff,0xffffc880,0xdff304ef, 0x3fee0000,0x201dffff,0xff984ffb,0xffffffff,0x90ffffff,0xffb007ff, 0x000fff27,0x98800131,0x310000aa,0x20035300,0xa8803ffc,0x3310000b, 0xa9800001,0x06a60001,0x006a2000,0x01bba980,0x00035300,0xe8035000, 0x530001ff,0x35310001,0x2a600001,0x4cc40001,0x000019aa,0x2000d4c4, 0x00009a98,0x066aa662,0x09fff000,0x4d54c400,0x13530000,0x00013300, 0x009aa980,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00037bb6,0x00019991,0x2f76c000,0x85ddd700,0x32a04cc9, 0x8000004c,0x819900cc,0x3622eed8,0x3b2002ee,0x000000ee,0x2a880880, 0x0000e654,0x00005dd9,0x3332e000,0xcccccccc,0xcccccccc,0xcccc881c, 0xbccccccc,0x3326000a,0x665c0004,0x66644002,0x00666442,0x002664c0, 0x3bb62000,0x5c7bb622,0x2775c5ee,0x33260000,0x99100004,0x99999999, 0x95001579,0x75c00039,0x665401ee,0xfffc8001,0x7fcc005f,0x0000000f, 0x2003fff7,0xfa85fff8,0x1fff207f,0xffffff30,0x3a0bffff,0x507fb84f, 0x3ff21fff,0x7ffec005,0xffff5000,0x07ffffff,0x42b7ff66,0x1ffe44fc, 0x07ffd000,0xf3000000,0xffffffff,0xffffffff,0xf305ffff,0xffffffff, 0x019fffff,0x000fff70,0x000fffa8,0xf103ffee,0xf50003ff,0xfffc80ff, 0x2fffffff,0x361fff50,0x3ffa24ff,0x501fff33,0xffffffff,0x7ffa87ff, 0xfff30000,0xffffffff,0x6c019fff,0x320003ff,0x7ec01fff,0x7fd4003f, 0x2003ffce,0x0000fff9,0x07ffd000,0xa837fdc0,0x3ff207ff,0x7fffcc07, 0x05ffffff,0xf955bff7,0x6ffe407f,0xd8006ffa,0xf5000fff,0xffffffff, 0x3fffe07f,0x51ffefff,0x555bffb5,0xffd00555,0x00000007,0xfffffff9, 0xffffffff,0x05ffffff,0xfffffff3,0xffffffff,0x7ffb809f,0x4ffe8000, 0x09fff100,0x0003fff1,0xfc80fff5,0xffffffff,0x37ff202f,0xff986ffa, 0x501ffe9f,0xffffffff,0x7ffa87ff,0xfff30000,0xffffffff,0x209fffff, 0x20003ffd,0x6c01fffc,0x3e2003ff,0x05ffd1ff,0x003ffe60,0x3fea0000, 0x07ffc005,0x3207ffa8,0x664407ff,0xcccccccc,0x3ffff602,0xffe805ff, 0xd8000fff,0x93000fff,0x99999999,0x33df5059,0x74bffff9,0xffffffff, 0xfec807ff,0x40000003,0xfaacfff8,0xaaaaadff,0x0aaaaaaa,0xaabfff98, 0xfecaaaaa,0x3ee05fff,0xf980007f,0xffc801ff,0x1fff880f,0x07ffa800, 0x66666654,0x7401cccc,0x700fffff,0x407fffff,0xccccccc9,0x7fd42ccc, 0xff300007,0x5555557f,0xbffffd95,0x0007ffb0,0x200fffe4,0x3a003ffd, 0x3ffe64ff,0x0fff9801,0xfe800000,0x3fee000e,0x01ffea02,0x000001ba, 0x02deeda8,0x03ffff10,0x00666200,0x2ca80000,0x7ff41b98,0xffffffff, 0x007f5007,0xffc80000,0x001fff47,0x00fff980,0x09ffff50,0x0001ffee, 0x2202ffec,0x77543fff,0xeeeeefff,0xeeeeeeee,0x01eefffe,0x7fc40000, 0x7fe401ff,0x2000005f,0x00007ffa,0x2001fff3,0x6c4ffffa,0x220003ff, 0xffd80199,0x03331003,0xf3001331,0x555557ff,0x00013355,0x220004cc, 0x3ffd4009,0x00017e20,0x88000000,0x00000099,0x00000000,0x001ffe40, 0x00007f20,0x3fff8800,0x0001fff4,0x000fff98,0x203fffa2,0x00307ffb, 0x202fff88,0xffb86ffd,0xffffffff,0xffffffff,0x01ffffff,0x99880000, 0x00333000,0x7ffa8000,0xfff30000,0x7ff44001,0x00fff60f,0xffd80000, 0x00000003,0xfffffff3,0xbfffffff,0x00000005,0x80fff500,0xca8803fb, 0x00bcefed,0x00000000,0xcdeeca88,0x3f72a000,0x00001bde,0x0007ff90, 0x00002fcc,0x03fff200,0x00007ffd,0x0003ffe6,0xf70bfff3,0x000b90ff, 0x3e60dff9,0xfeea82ff,0xeeeeeeff,0xeeeeeeee,0x201eefff,0x1bdeedb9, 0x80000000,0xcb801cca,0x00fff51c,0x03ffe600,0x4bfff300,0x98003ffd, 0x01bdeedb,0xccb8fff6,0x01665c01,0x7fcc732a,0xffffffff,0x06ffffff, 0x99999995,0x59999999,0xedb86654,0x81ffea1c,0x75400efb,0xffffffff, 0x2cca803f,0x2a219950,0x400bdeec,0xffffffe8,0x7ec404ff,0x4fffffff, 0x80599500,0xd9713ffc,0x32f4037d,0x7f654399,0xf88001bd,0x3ffe84ff, 0xfff30000,0xfff90001,0xfd8fff70,0xfff88005,0x405ffd83,0x8001fff8, 0xfc807ffa,0x3fffffff,0x40599500,0x9db70cca,0x401ffec3,0xfff52ffe, 0x3fe60000,0xffc8000f,0x000fff67,0xfffffff9,0x8fff607f,0x7fc04ffc, 0x8ffec06f,0xccccfff9,0xffeccccc,0xfffc85ff,0xffffffff,0x3ff24fff, 0x1fffffb8,0x2cc0fff5,0x7ffffe40,0x3ffffedd,0xc827fdc0,0xfffe88ff, 0xf302ffff,0xffbbdfff,0x3fe609ff,0xfffddeff,0x7fdc00ef,0x4dffe404, 0xfffffffe,0x57fdc183,0xffffffe8,0x7fdc003f,0x03ffe80f,0x1fff3000, 0x3fff3000,0xfd17ffb8,0x3ee0007f,0x3ffe60ff,0x0fffc401,0x03ffd400, 0xbbdfffd1,0x801dfffd,0x3f203ffc,0xfffffb8f,0xd007ffb1,0x1ffea5ff, 0x7ffcc000,0xfff98000,0x2007ffb1,0xddefffe8,0x6c0efffe,0x1bfe63ff, 0x00ffff98,0x7fccfff1,0xffd3000f,0xffffc87f,0xfeffffff,0x2bff23ff, 0x2a6fffff,0x4c0007ff,0xe980cfff,0x7fdc06ff,0xff5ff904,0xfffffdff, 0x83fffd05,0xe82fffc8,0xffa81eff,0x27fdc05f,0x3ffbff20,0xffffeeef, 0x75ffdc01,0xffffefff,0xfff1004f,0x00fffa09,0x07ffcc00,0x42fff800, 0xffe9fffb,0x7ff40002,0x2013ffa3,0x8001fff8,0x3f607ffa,0xfff981ef, 0x01ffe404,0xffff5ff9,0x01ffecdf,0xffa97ff4,0xff300007,0x3fe0001f, 0x007ffb2f,0x2607bff6,0x7fec4fff,0xb80fffc3,0xf502ffff,0x07ffcc9f, 0x0bfff100,0x17ffa200,0x57bffff9,0x03ffd47b,0x01bff200,0x5c03fff1, 0xfff904ff,0x7fd417df,0x07ffdc6f,0xfc8bffd0,0x3fe600ef,0x13fee02f, 0x1bffff90,0x406ffe98,0x0beffffb,0x003fffa6,0x7403ffee,0x300003ff, 0x20001fff,0x7fdc3ffe,0x0001ffff,0xfa8fffa8,0xff8800ff,0x999999af, 0xfb999999,0x1fff507f,0x00fffc40,0x7e407ff9,0x3dabdfff,0x3a00fff6, 0x0fff52ff,0x3ffe6000,0x7ffd0000,0x2a00fff6,0x3e200fff,0x0fff61ff, 0x3f607ff9,0xff904fff,0x007ffcc3,0x001fff20,0x7e437ff4,0x7fd405ff, 0x7fec0007,0x01ffe801,0x7e413fee,0x3fea04ff,0x00fff61f,0x3e21fff3, 0xffc802ff,0x013fee06,0x4c0bfff9,0x3ee00fff,0x3fe606ff,0x4fff802f, 0x3bbbffa0,0xeeeeeeee,0x1fff302e,0x17ff6000,0x01dffff7,0x67fec000, 0xf1003ffe,0xffffffff,0xffffffff,0x3ffa0fff,0x05ffb802,0xfc80fff2, 0x7fec05ff,0x52ffe803,0x774c0fff,0x3ffe601e,0xbffb0000,0xeec8fff6, 0x200bffa4,0x3ff65ffb,0xf82ffd43,0xff06ffcf,0x00fff98f,0x00fffd40, 0x203bff60,0x5400fffc,0x100007ff,0x80bff600,0xff904ffb,0x2fff801f, 0x04c01ffe,0x4401bfe6,0xff700fff,0x0fffc809,0x700fff40,0xfd803fff, 0x7ffdc03f,0x3ffffa00,0xffffffff,0x7fffc3ff,0xffffffff,0x1bff201f, 0x000bfff7,0xfa999988,0x999fffff,0xfff88099,0xffffffff,0xffffffff, 0x007ff987,0x7e40fff1,0x3fff203f,0x01ffec00,0xffa97ff4,0x07ffea07, 0x3ffffffe,0x01ffffff,0x7fedbff2,0x7cdbff63,0xfff1007f,0x3e21ffec, 0xdaff987f,0x2ffcc0ff,0x0003ffe6,0x4003fff3,0xf901fffc,0xfff500df, 0x51000000,0x5c05fff9,0xbff904ff,0x225ffd00,0x2e0006ff,0x3fe005ff, 0x09ff701f,0xd805ffc8,0x3fee02ff,0x04ffc807,0x3a027ff4,0xffffffff, 0x43ffffff,0xffffffff,0x201fffff,0x3f626ffc,0xfe80007f,0xffffffff, 0x5fffffff,0xffffff88,0xffffffff,0xa87fffff,0x3fe006ff,0x07ff900f, 0x6c037fe4,0xffe803ff,0x540fff52,0xfff81fff,0xffffffff,0x3ff201ff, 0x7ec7ffb6,0x00dff56f,0xffd87ffc,0x641ffd83,0x42ffb8ff,0x7fcc2ffc, 0x7fd4000f,0xfff7000f,0x02ffe405,0x0003ffd4,0xffdb7510,0x405fffff, 0xff904ffb,0x25ffb009,0x20005ffa,0x3a004ffc,0x9ff702ff,0x804ffc80, 0x3ee03ffc,0x4ffb806f,0x003ffea0,0x33339ffd,0x13333333,0xbfffbaa8, 0x00aaaaaa,0x7f45bff6,0xe80007ff,0xffffffff,0xffffffff,0x01fff885, 0xb87ffa80,0xffffffff,0xffffffff,0x407ff901,0xfd805ffc,0x2ffe803f, 0x74c0fff5,0xfbaa81ee,0xaaaaabff,0x5bff600a,0x3bb23ffd,0xffffff74, 0xffffffff,0x0fff63ff,0xdfd13fee,0xffd13fe6,0x00fff981,0x8037fec0, 0x6403fffa,0xffa804ff,0xfc880007,0xefffffff,0x3ee02fff,0x07ff904f, 0x3ee7ffb0,0x3f60004f,0x3ff6003f,0x809ff703,0xfc803ffc,0x17fee03f, 0xe813fee0,0xaaaaaeff,0x03fffaaa,0x1fff3000,0x57ffa000,0x007fffff, 0xaaaaaa80,0xaaadffda,0xff881aaa,0xffa8001f,0xfffffc87,0xffffffff, 0xff902fff,0x027fe407,0x7401ffec,0x0fff52ff,0x3ffe6000,0xbffd0000, 0xf900fff6,0xffffffff,0x5fffffff,0x3e20fff6,0xf93fe26f,0x217fe26f, 0x2000fff9,0x9803fffc,0xfc804fff,0x7ffa803f,0x7ffc4000,0xb1acefff, 0x7fdc05ff,0x007ff904,0x3fee7ffb,0x3ff60005,0x0fff6003,0x32027fdc, 0xffc803ff,0x017fee03,0x7d413fee,0xffffffff,0x03ffffff,0x1fff3000, 0x53ffe000,0x007ffcef,0x1ffe4000,0x07ffe200,0x21ffea00,0xcccceffc, 0xcccccccc,0x07ff901c,0x6c01ffe4,0xffe803ff,0x000fff52,0x003ffe60, 0xfda7ffc0,0x77fe403f,0xcccccccc,0xfb1ccccc,0x43ffa07f,0x3ff62ffa, 0xf305ff70,0x333335ff,0xffff9553,0xbfff100d,0x00fff200,0x0001ffea, 0x4037fffd,0x3ee02ffe,0x07ff904f,0x3ea7ffb0,0x3f20006f,0x3ffa004f, 0x809ff702,0xfc803ffc,0x17fee03f,0x7413fee0,0xffffffff,0x3fffffff, 0xfff30000,0xfff10001,0x1ffee3a5,0x26662000,0x9cffd999,0x88099999, 0xa8001fff,0x5ffb87ff,0x7fe40000,0x00fff203,0x3e00fff6,0x0fff52ff, 0x3ffe6000,0xfff88000,0xb807ffb2,0x6c0005ff,0x5ff703ff,0xffb83ff2, 0xf301ffb2,0xffffffff,0xdfffffff,0xeffe8803,0x07ff9000,0x000fff50, 0x400fffcc,0x3ee02fff,0x07ff904f,0x3e67ffb0,0x3997007f,0xf8017fea, 0x9ff701ff,0x803ffc80,0x3ee03ffc,0x4ffb805f,0xcccfffa8,0xfccccccc, 0x300003ff,0x70001fff,0xffb81fff,0xffe80007,0xffffffff,0x85ffffff, 0x8001fff8,0xff987ffa,0x7e400007,0x0fff203f,0x100fff20,0x3fea5fff, 0xff300007,0xff70001f,0x00fff61f,0x8000fff3,0xff303ffd,0xff31bfeb, 0x7cc1bfe9,0xffffffff,0x03ffffff,0x001fffd0,0x5401ffe4,0x2e0007ff, 0xff9805ff,0x13fee02f,0x6c01ffe4,0x3fff13ff,0x263ffd00,0xfa800fff, 0x13fee07f,0x9007ff90,0x7fdc07ff,0x84ffb805,0x3a005ffe,0x300003ff, 0x88001fff,0xffb85fff,0xffe80007,0xffffffff,0x85ffffff,0x8001fff8, 0xff887ffa,0xcef9801f,0x407ff900,0xfc803ffc,0x7ffcc04f,0x000fff52, 0x003ffe60,0x6cbfff10,0x7fc403ff,0xcef9801f,0x7c07ffb0,0xf84ff8ff, 0x303ffaff,0xdddddfff,0x01559bdd,0x007fff60,0x5007ff90,0x64000fff, 0xffd806ff,0x13fee02f,0x6c01ffe4,0x17ff63ff,0xfe8fff30,0x5ffe805f, 0x9013fee0,0xff9007ff,0x02ffdc07,0x3e627fdc,0x3fa001ff,0xf300003f, 0xfd8001ff,0x7ffb82ff,0xaaaa8000,0xadffdaaa,0x881aaaaa,0xa8001fff, 0xdffb07ff,0x40dffd00,0x3f203ffc,0x6ffb803f,0xa97ffec0,0x300007ff, 0xd8001fff,0x3ff62fff,0x06ffd803,0x3f66ffe8,0x33ff203f,0xeffd81ff, 0xfff300ff,0xfc800001,0xfc8002ff,0x7ffa803f,0x3ffee000,0x3ffff602, 0x413fee03,0xfd803ffc,0x0fffe23f,0x2627ff44,0xfb103fff,0x7fdc01ff, 0x01ffe404,0xf701ffe4,0x9ff700bf,0x4006ffd8,0x00003ffe,0x2001fff3, 0x705fffc8,0x00000fff,0x4003ffc8,0x8001fff8,0xff107ffa,0x7ffe409f, 0x80fff202,0xf9803ffc,0xfff903ff,0x01ffea5f,0x07ffcc00,0x5fffc880, 0x4401ffec,0x3f204fff,0x0fff62ff,0x07ffffa8,0x40dffff7,0x0000fff9, 0x00fffee0,0x401ffe40,0x20007ffa,0x8acffff8,0xfffffeba,0x413fee04, 0xfd803ffc,0x6fffdc3f,0x6fffda9b,0x37bfff90,0x03fffd73,0x6404ffb8, 0xffc803ff,0x017fee03,0xff993fee,0x7ff4002f,0xff300003,0x2ea6201f, 0x700fffff,0x00000fff,0x4003ffc8,0x8001fff8,0x3f207ffa,0xec99beff, 0x7e405fff,0x0fff203f,0x5f7fff40,0xffdffeca,0x000fff52,0x403ffe60, 0xffffba98,0x01ffec0f,0x9befffc8,0x45fffec9,0x7fc03ffd,0xfff105ff, 0x7ffcc07f,0xff300000,0xddb999ff,0x21dddddd,0xfa803ffc,0xffffffff, 0x24ffffff,0xfffffffa,0x6ff9aeff,0x6413fee0,0xffd803ff,0xfffffb83, 0x200effff,0xfffffffb,0xfb801fff,0x1ffe404f,0x701ffe40,0xff700bff, 0x0037fec9,0x7ffffff4,0xffffffff,0xffff986f,0xffffffff,0x200fffff, 0xfffffffb,0xffffffff,0x0fff2004,0x03fff100,0x80fff500,0xfffffffb, 0xfc805fff,0x0fff203f,0x7ffff4c0,0xffb9ffff,0xffffff52,0xffffffff, 0xffff309f,0xffffffff,0xb01fffff,0x7dc007ff,0xffffffff,0x03ffd85f, 0xd01fffec,0x7cc03fff,0x300000ff,0xffffffff,0xffffffff,0x200fff21, 0xfffffffa,0xffffffff,0x7ffff4c4,0x0fffc4ff,0xf904ffb8,0x7ffb007f, 0x3ffff660,0xfb3003ff,0x017bffff,0x9013fee0,0xff9007ff,0x02ffdc07, 0xff9a7fdc,0xffe8002f,0xffffffff,0x986fffff,0xffffffff,0x3effffff, 0xfffffb80,0xffffffff,0x3f2004ff,0x7fc4003f,0xffa8001f,0xfffd8807, 0x9002efff,0x7fe407ff,0x3ff62003,0xff71dfff,0x3ffffea5,0xffffffff, 0xfff984ff,0xffffffff,0x3603efff,0x6c4003ff,0x2effffff,0xa807ffb0, 0x3f201fff,0x7ffcc07f,0xff300000,0xffffffff,0x21ffffff,0xfa803ffc, 0xffffffff,0x04ffffff,0x00013531,0xfc827fdc,0x3ffd803f,0x000aa980, 0x40006a20,0x7e404ffb,0x3ffc803f,0x2017fee0,0xdffb4ffb,0x3fffa000, 0xffffffff,0xf986ffff,0xffffffff,0x2002deef,0xfffffffb,0xffffffff, 0x0fff2004,0x03fff100,0x00fff500,0x0009aa88,0xf901ffe4,0x2a60007f, 0xffff5001,0xffffffff,0xff309fff,0xffffffff,0xfb005bdd,0x5440007f, 0x7fec009a,0x00000003,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x80deec80, 0xccccccc8,0xcccccccc,0x200ccccc,0x50155008,0x2eec8399,0x664d7ba6, 0xccca8004,0x00733224,0x400f3260,0x999911ed,0x79999999,0x99910015, 0x99999999,0x39999999,0x66666664,0xcccccccc,0x2ea200cc,0x2600abcc, 0x0003cccc,0xc893332a,0xc98000cc,0x0059954c,0x654f32a0,0x0039952c, 0xccc98000,0xa6664002,0xccccccc8,0x02abcccc,0x000e6654,0x22399950, 0xcccccccc,0x0abccccc,0xccccc880,0xcccccccc,0x0ccccccc,0x26666666, 0x99999999,0x00133261,0x0004cca8,0x0001ccc8,0x6ffffb80,0xffffff88, 0xffffffff,0x80ffffff,0x31beffc8,0x0fff20ff,0x7fd47ffd,0x800fff57, 0x261ffffa,0xa8006fff,0xffd806ff,0xffffff32,0xffffffff,0x7ffc4019, 0xffffffff,0x2fffffff,0x3ffffffe,0xffffffff,0xffc881ff,0x03ffffff, 0x01fffff5,0x3ffffa00,0x003fff10,0x3f2fff50,0xff90003f,0x7e4fff2b, 0x4000003f,0x4006fffc,0xfff37fff,0xffffffff,0x1019ffff,0x2000dfff, 0x3e26fff8,0xffffffff,0xdfffffff,0x3fffe200,0xffffffff,0xffffffff, 0xffffff30,0xffffffff,0x1ffea3ff,0x1fffa800,0x3ffe6000,0xffffff50, 0x4c07ffff,0x44ffcfff,0xfffffff8,0xffffffff,0xc80fffff,0xfeffffff, 0x87ff904f,0x3fea3ffe,0x400fff57,0x4c1ffffa,0x4004ffff,0x7dc06ffa, 0xffff32ff,0xffffffff,0x2209ffff,0xffffffff,0xffffffff,0x3fffe2ff, 0xffffffff,0x441fffff,0xffffffff,0x7d40efff,0x8003ffff,0x10fffff8, 0x50003fff,0x0fff2fff,0xcaffe400,0x07ff93ff,0xfff80000,0x3fe001ff, 0xfffff37f,0xffffffff,0xf701ffff,0xfb0009ff,0x7ffc41ff,0xffffffff, 0x0effffff,0xffffff10,0xffffffff,0x21ffffff,0xfffffff9,0xffffffff, 0x00fff51f,0x004fff80,0xfa97ff20,0xffffffff,0x5fff103f,0xaa88fffa, 0xfeaaaaaa,0xaaaaaaef,0x717ff02a,0x203ffffd,0x77643ffc,0x7d57ba62, 0xfff5007f,0xffff301d,0x7fd4003f,0x3fffea06,0x557fff32,0xfd975555, 0xff10bfff,0x5555557f,0x55555555,0x5567ffc1,0xaaaaaaaa,0x7fec0aaa, 0x3ff220bf,0x7fffd44f,0xffb8006f,0xfff10fff,0xfff50003,0x4000fff2, 0x7ff95ffc,0x0000fff2,0xffdffa80,0x5fffe005,0xaaabfff9,0xffcaaaaa, 0xfffd06ff,0x7ffd4003,0x4d7ffc43,0xa9999999,0x80ffffeb,0xaaaaaaa8, 0xaaaeffea,0x3a62aaaa,0xeeeeeeee,0x0efffeee,0x8000fff5,0x20007ffc, 0x33262fff,0xcccccccc,0x4cbffb01,0x36001fff,0xc88004ff,0x6402b884, 0x2a0003ff,0xffa807ff,0xfff300ef,0x2a001dff,0xffc886ff,0xfff32fff, 0x3ffa6001,0x0fffc44f,0x2fff8000,0xfffb8000,0x8bffea00,0x0ffffffa, 0x7ffff400,0x03fff10f,0x32fff500,0xf90003ff,0x1ffe40bf,0xffb00000, 0x2001fff1,0xfff37fff,0x3ff62001,0x6fff884f,0x0bfff100,0x8003fff1, 0x0003fffb,0x00009ffb,0x50fffcc0,0x98000fff,0xa8001fff,0x800007ff, 0x4cc40999,0x13ff6000,0x64000000,0x2a0003ff,0x7fd407ff,0x3fe600ef, 0x5004ffff,0xfffa8dff,0xff32ffff,0x7f44001f,0x3ffe20ff,0xfff00001, 0xffb00005,0x49ffb007,0x3ffcfffa,0x3f3fe600,0x3fff10ff,0x2fff5000, 0x90003ffc,0x7fe40bff,0xf1000003,0x00fff2df,0xff9bfffc,0x7ff4000f, 0x09fff706,0x101fffb0,0xb0003fff,0x36000bff,0x000004ff,0xff50bffa, 0xffd0000f,0x9ffb0009,0x00000000,0x013ff600,0x7e400000,0x3ea0003f, 0x3ffea07f,0x7ffcc00e,0xa801fffc,0x3fff66ff,0xf32ffebf,0xf88001ff, 0x3ffe25ff,0xfff00001,0xfff00005,0x4dff5001,0x5ff9fffa,0x3e7fee00, 0x3fff10ff,0x2fff5000,0x90003ffc,0x7fe40bff,0xf7000003,0x01bfe69f, 0xff9bfff4,0x7fe4000f,0x07fffa07,0x102fffa8,0x50003fff,0x36000fff, 0x000004ff,0xff509ff9,0xff70000f,0xfff8800f,0x01665401,0x00166540, 0x4009ffb0,0xd9510cca,0x7e4017bd,0x0b32a03f,0x7d41ffea,0xf9800eff, 0x01dffd7f,0xff16ffa8,0x4bffa3df,0x8000fff9,0x3fe27ffc,0xff00001f, 0xe880005f,0xfff3007e,0xfffbffd4,0xf1dfd000,0x3ffe21ff,0x7ffa8001, 0x64407ff9,0x57ff23cc,0x7ff92cca,0x2f3bb2e2,0x1ffe8000,0x3a00bffe, 0x1fff36ff,0x1fff9800,0x20dfff10,0x2205fff8,0x98001fff,0xd8001fff, 0x800004ff,0xfa80fff9,0xf880007f,0x3ee002ff,0x4ffb806f,0x04ffb800, 0x013ff600,0xfe88ffc8,0x02ffffff,0x2e027ff9,0x7ffa84ff,0x00efffa8, 0x3e6fff30,0x7fd404ff,0xfe87ff16,0x01fff32f,0x23fff300,0x0001fff8, 0x0005fff0,0xbff70000,0xffcbffd4,0x8bff9803,0xfff10fff,0xfff50003, 0x7440fff2,0x3ff20eff,0x3f27ff95,0xffffe9bf,0x26001fff,0x2ffe47ff, 0xf9b7fec0,0x7cc000ff,0x3fee01ff,0x0fffd83f,0x007ffe20,0x003ffee0, 0x0013ff60,0x05ffd100,0x0001ffea,0xd002ffec,0xff7005ff,0x9ff70009, 0x27fec000,0xff5ff900,0xfffffdff,0xb57ff905,0xf509ff70,0xefffa8ff, 0x9ffe6000,0x2a01fffc,0x3a0716ff,0x1fff32ff,0x4bffa000,0x0001fff8, 0x0005fff0,0x9ffd0000,0xff9bffd4,0x88ffc805,0xfff10fff,0xfff50003, 0x3a20fff2,0x7fe40eff,0x3f27ff95,0xfeffffef,0xb001ffff,0xfff989ff, 0x9affec00,0x5c000fff,0xffe807ff,0x0bffe60f,0x003fff10,0x000fffd0, 0x00013ff6,0x540bff90,0x500007ff,0xf3001fff,0x3fee00ff,0x4ffb8004, 0x13ff6000,0xeffffc80,0x1bffea0b,0x21bfbff2,0xffa84ffb,0x03bffea7, 0xe8fff300,0xff500eff,0x25ffd00d,0x0000fff9,0x3fe27ffb,0xff00001f, 0x0000005f,0x2a1fffa8,0x03ffe7ff,0x3fe2bfd0,0x35fff10f,0x33333333, 0x2fff7333,0x7f443ffc,0x5ffc80ef,0x3ff27ff9,0x3ee21dff,0xff8807ff, 0x03ffe81f,0xff9affe4,0x3fa2000f,0xfff8806f,0x2013ffa5,0x2001fff8, 0x003fffe8,0x0009ffb0,0x00fffcc0,0x0000fff5,0x6401fff4,0xff7004ff, 0x9ff70009,0x27fec000,0x09fff900,0x320fffd4,0xfb83ffff,0x57ffa84f, 0x001fffff,0x7cc7ff98,0xdff504ff,0x265ffd00,0xb0000fff,0x3ffe2bff, 0xeeeeeeee,0x42eeeeee,0xccccdfff,0x1ccccccc,0x3ffe2000,0xf93ffd44, 0x9ffcc07f,0xff10fff8,0xffffffff,0xffffffff,0x88fff2ff,0xf900dffe, 0x64fff2bf,0x3e606fff,0x7fdc01ff,0x80fff706,0xfff34ffb,0x3ff66001, 0xfff7002f,0x200dff75,0xaaabfff8,0xfdcaaaaa,0x20006fff,0x00004ffd, 0xf501bff6,0x5c0000ff,0xfff805ff,0x09ff7001,0x009ff700,0xfd555553, 0x155555df,0x801fff90,0x7fe42fff,0x09ff702f,0xfff5fff5,0x9800dfff, 0xfffc87ff,0x806ffa82,0xfff32ffe,0x3ff20001,0xffffff16,0xffffffff, 0xfff85fff,0xffffffff,0x0002ffff,0xf50dffd1,0x02ffccff,0x3fe21ff9, 0xfffff10f,0xffffffff,0x2fffffff,0xffd13ffc,0x95ffc80b,0x3fff27ff, 0x017ff400,0x7c40fffa,0x3fee02ff,0x557fff34,0xfd975555,0xe800bfff, 0x01fffeff,0xffffff10,0xffffffff,0x0001bfff,0x00027fec,0x402fff88, 0x00007ffa,0xa803ffe2,0x3ee006ff,0xffb8004f,0xffffb804,0xffffffff, 0x5ffc82ff,0x222ffe80,0x3ee03ffe,0xffffa84f,0x4fffbdff,0x41ffe600, 0x7d40effe,0x2ffe806f,0x0001fff3,0x7fc5bff2,0xffffffff,0x2fffffff, 0x7ffffffc,0xffffffff,0xffe88002,0x47ffa81f,0xbff00fff,0xf887ffc4, 0xffffffff,0xffffffff,0x17ff97ff,0xf900bffd,0x64fff2bf,0xffd806ff, 0x03ffe602,0x2a05ffd8,0xffff33ff,0xffffffff,0x001bffff,0x4fffff98, 0x3fffe200,0xffffffff,0x0002dfff,0x0004ffd8,0x500fff70,0x80000fff, 0x3f603ffd,0x3fee003f,0x4ffb8004,0xfffffb80,0xffffffff,0x04ffc82f, 0xff32ffd8,0x7fdc07ff,0xfffffa84,0x00bfff65,0xf983ffcc,0x37fd44ff, 0xf997ff40,0xfb0000ff,0x2bffe2bf,0x99999999,0x7c099999,0xaaaaacff, 0x00aaaaaa,0x17fff440,0x7e47ffa8,0x22ff983f,0xff10fff8,0xff50003f, 0x3fb3ff2f,0xffc800ff,0x3f27ff95,0x3ffc805f,0x5017ff20,0x3ea01fff, 0xfffff33f,0xffffffff,0x5c0005df,0x44006fff,0xccccdfff,0x004ffffd, 0x027fec00,0x04ffe800,0x0007ffa8,0x8837fd40,0x2e000fff,0xfb8004ff, 0x3f60004f,0x3ff2004f,0xf3ffd803,0x5c07ffff,0xfffa84ff,0x7fffc44f, 0x07ff9800,0xfa8bfff2,0x2ffe806f,0x0001fff3,0x7fc53ffa,0xff00001f, 0x4000005f,0x202ffff9,0x7fcc7ffa,0x220ffc85,0xfff10fff,0xfff50003, 0x3ffffff2,0x5ffc805f,0x3ff27ff9,0x03ffc804,0x33337ffe,0xfffccccc, 0x265ff304,0xcccccfff,0x0009abcc,0x005fff00,0x201fff88,0x000dfffb, 0x009ffb00,0x01fff300,0x000fff50,0x703fff00,0xfb800bff,0xffb8004f, 0x3ff60004,0x0fff2004,0x67cfff60,0x3ee03ffd,0x4fffa84f,0x00bfff50, 0xfe80fff3,0x0dff50ef,0x3e65ffd0,0xff0000ff,0x07ffe27f,0x17ffc000, 0xffa80000,0x7fd401ff,0x7c0ffe87,0x87ffc45f,0x8001fff8,0xfff97ffa, 0x805fffdf,0x7ff95ffc,0x3200fff2,0xfff503ff,0xffffffff,0x260fffff, 0x1fff31ff,0xf8000000,0x7c4002ff,0x7fd401ff,0xfb00006f,0xf900009f, 0x3fea00bf,0xfc800007,0x01ffe84f,0x0027fdc0,0x00027fdc,0x64009ffb, 0xffd803ff,0x80fff273,0xffa84ffb,0x1fffe407,0x301ffe60,0x3fea9fff, 0x32ffe806,0x10001fff,0x3fe25fff,0xff00001f,0x5000005f,0x5001dfff, 0x7ff90fff,0x3e217fcc,0x3fff10ff,0x2fff5000,0xff95fffc,0xaffe401f, 0x7ff93ffc,0x207ff900,0xfffffffd,0xffffffff,0x31ff882f,0x00001fff, 0x02fff800,0x00fffc40,0x002fffdc,0x0027fec0,0x8017ffc0,0x00007ffa, 0x7cc6ff98,0xffb8006f,0x4ffb8004,0x13ff6000,0x803ffc80,0x7fe43ffd, 0x213fee03,0xfe807ffa,0x3fe601ff,0xafffc807,0xfe806ffa,0x01fff32f, 0x21fff700,0x0001fff8,0x0005fff0,0x0dfffb80,0x30fff500,0x43fe4bff, 0xff10fff8,0xff50003f,0xe897ff2f,0x3ff205ff,0x3f27ff95,0x3ffc803f, 0x99afff88,0x99999999,0xff885ffe,0x001fff30,0xfff80000,0x7ffc4002, 0x7fffb001,0x4ffd8000,0x37fd4000,0x00fff500,0x87ffa000,0xb8003ffc, 0xfb8004ff,0x3f60004f,0x3ff2004f,0x43ffd803,0x3ee03ffc,0x07ffa84f, 0x00efff98,0x3a00fff3,0x06ffafff,0xff32ffe8,0xff88001f,0x07ffe24f, 0x17ffc000,0xfff70000,0x7ffa800b,0x3fe1ffd0,0x10fff884,0x50003fff, 0x0fff2fff,0x3205fff5,0x27ff95ff,0xfc803ffc,0x06ffb83f,0x40fffdc0, 0x1fff30cc,0xf8000000,0x7c4002ff,0xff1001ff,0x6c0003ff,0x6c0004ff, 0x3ea004ff,0x7000007f,0x07ffc9ff,0x027fdc00,0x0027fdc0,0x4009ffb0, 0xfd803ffc,0x01ffe43f,0xff509ff7,0x3ffee00f,0x00fff305,0x3ffbffe6, 0x32ffe806,0xd8001fff,0x3fe21fff,0xff00001f,0x2e00005f,0xa8004fff, 0x7ff907ff,0xff105ff5,0x07ffe21f,0x65ffea00,0xfffd83ff,0xf95ffc80, 0x00fff27f,0x3fa0fff2,0x7fc4003f,0xfff9804f,0x40000000,0x44002fff, 0x2a001fff,0x20006fff,0x40004ffd,0x2a003ffe,0x000007ff,0x3fe6fff1, 0x9ff70005,0x09ff7000,0x027fec00,0xb007ff90,0x3ffc87ff,0x2a13fee0, 0x3fa007ff,0x7ff983ff,0x3ffff200,0x2ffe806f,0x2001fff3,0x445fffc8, 0x00001fff,0x00005fff,0x0009fff1,0x7cc1ffea,0xf107fcdf,0x3ffe21ff, 0x7ffa8001,0xff107ff9,0x2bff90bf,0x7ff93ffc,0x987ff900,0xc8000fff, 0xff9807ff,0x0000000f,0x20017ffc,0x4001fff8,0x0003fffd,0x40009ffb, 0x2001fff8,0x00007ffa,0x3f27ff60,0xff70002f,0x9ff70009,0x27fec000, 0x007ff900,0xffc87ffb,0x213fee03,0x22007ffa,0x7cc1ffff,0x3fa2007f, 0xfe806fff,0x01fff32f,0x3ffeea62,0x7ffc40ef,0xfff00001,0xffb00005, 0x7fd4000d,0x3ffffa07,0x21fff104,0x8001fff8,0x7ff97ffa,0x90bffea0, 0x4fff2bff,0xfc803ffc,0x037fe43f,0x22fff980,0xfff33ccb,0x80000001, 0x44002fff,0x44001fff,0x8000ffff,0x20004ffd,0x2000fffa,0x00007ffa, 0x3fb3fe60,0x3fee0007,0x4ffb8004,0x13ff6000,0x803ffc80,0x7fe43ffd, 0x213fee03,0x54007ffa,0x7fcc6fff,0x7ffcc007,0x2ffe806f,0xfffffff3, 0xffffffff,0xfff101df,0xffffffff,0xffffffff,0x00017ffc,0x3fffffea, 0xffffffff,0x81ffea7f,0x101ffffc,0x3fe21fff,0xffa8001f,0x6c07ff97, 0x3ff20fff,0x3f27ff95,0x3ffc803f,0x0001fffc,0x7fecdffd,0x001fff36, 0xfff80000,0x7ffc4002,0xfffb8001,0x4ffd8005,0x1ffee000,0xfffff500, 0xffffffff,0x7f4009ff,0x20004fff,0xb8004ffb,0x360004ff,0x3f2004ff, 0x3ffd803f,0xf701ffe4,0x0fff509f,0x49fffb00,0xc8007ff9,0xfe806fff, 0xfffff32f,0xffffffff,0x3e2019ff,0xffffffff,0xffffffff,0x00bffe7f, 0xfffff900,0xffffffff,0x3ffd4fff,0x40dfff30,0xff10fff8,0xff50003f, 0x880fff2f,0x3ff25fff,0x3f27ff95,0x3ffc803f,0x0003ffea,0xfb1fffb8, 0x03ffe6df,0xff000000,0xff88005f,0xffd0001f,0xffd8005f,0x3ff20004, 0x7ffd4005,0xffffffff,0x2004ffff,0x000ffffb,0x0013fee0,0x80013fee, 0x32004ffd,0xffd803ff,0x701ffe43,0xfff509ff,0xffff1000,0x001ffe65, 0x201bffa2,0xfff32ffe,0xdfffffff,0xff10059b,0xffffffff,0xffffffff, 0x0017ffcf,0x3fffffa0,0xffffffff,0x1ffea7ff,0x4409ffd0,0xfff10fff, 0xfff50003,0xf700fff2,0x57ff25ff,0x7ff93ffc,0x6c7ff900,0x440005ff, 0xdffb4fff,0x0003ffe6,0x5fff0000,0x1fff8800,0xffff3000,0x27fec001, 0x09ff9000,0xfffffa80,0xffffffff,0x3e2004ff,0x000005ff,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x666665c0,0xcccccccc,0x0002cccc, 0x33260599,0x33322004,0x06664004,0x00059993,0xcc98b332,0xcccccccc, 0x3a0001ac,0x997005ee,0x2aaaaa67,0xaaaaaaaa,0x9800aaaa,0x000000aa, 0x000000d4,0xfedca880,0xb8800bce,0x01bcefed,0x37bf72a0,0x6dcc001b, 0x4001bdee,0x0bdeeca8,0x37bb2a20,0x32a2001b,0x40adeffd,0x1cefedb9, 0x77654400,0x399500cd,0x26399700,0x039953cc,0x32639970,0x332e003c, 0xb8039971,0x665402cc,0x2a219951,0xa881beec,0xca82deec,0x039db70c, 0x3ffffff6,0xffffffff,0xc8004fff,0xfff305ff,0x3ffea001,0xfff3002f, 0x00fffe81,0x507ffe40,0xffffffff,0x05ffffff,0x00dfff00,0x4cdd7ffa, 0x99999999,0x2a999999,0x001ffc80,0x9bdfb930,0xa807fe21,0x01bdefdc, 0xfd505fff,0xffffffff,0x7fffd407,0x403fffff,0xffffffd8,0xff9004ff, 0x07ffffff,0xfffffb10,0xfc81dfff,0x3fffffff,0xfffffa80,0xf70effff, 0xbfffffff,0xffffd100,0xfb09ffff,0x5ffd007f,0x7fedbfee,0x12ffe803, 0xf1001fff,0x13ff21ff,0xd80dfff0,0x31ff91ff,0x9fffffff,0x7fffffcc, 0x23ff20df,0x81fffffb,0xfffffffd,0xffffffff,0x7d4004ff,0x3ffe05ff, 0xffff9002,0x1bfee009,0x801bffe2,0x7d42fffa,0xffffffff,0x03ffffff, 0x8037ffc0,0x00075ffe,0xff900510,0xffd88003,0xedffffff,0xfffb105f, 0xf09fffff,0xfffc85ff,0xfffeddff,0xefffa83f,0x5ffffecd,0xbdffff30, 0x01dffffb,0x37bfffa2,0x00efffed,0xbbffffd1,0x361dfffd,0xfeddefff, 0xffb00dff,0xffdb9dff,0xbdfffbff,0x409fffdb,0xddeffff9,0x7ec4ffff, 0x2ffe803f,0x3ff6dff7,0x22ffe803,0xfb803ffd,0x81bfe65f,0x100ffff9, 0x5ffe4fff,0xfffeefff,0xeefff9bf,0x3f24ffff,0x6fffffaf,0x55555550, 0xd5555555,0x44005fff,0x3605ffff,0xfff004ff,0x3f600dff,0x9fff703f, 0x09fff100,0x5555fff5,0xfff97555,0x7ffc009f,0x2bffd006,0x02880003, 0x2001ffc8,0xedfffff9,0x80efffff,0xddeffff9,0x3e0effff,0x3ffe62ff, 0x6ffe980c,0xc884ffe8,0xffe80fff,0x5fffa81e,0x303dffb0,0x3fa09fff, 0x7fcc0bff,0x82fffdef,0xf984ffe9,0xfff302ff,0xfd305fff,0x3fffa05f, 0x17ffe441,0xfd007ffb,0x6dbfee5f,0xffe803ff,0x201bfea2,0x7ffc2ffe, 0x5ffff701,0xfc93fea0,0x7ec1cfff,0x6c44ffff,0xfff90fff,0x007b57bf, 0x27ffdc00,0x3ffff600,0x01bfee05,0x3ffb3fe6,0x01fff800,0xd007fff6, 0x3fea0dff,0xfffd1007,0x004ccc00,0x10000700,0x03ff9005,0x20ffff40, 0xd06fffb8,0xff503dff,0x90fee4df,0xff880dff,0x01bfe21f,0xffc87ffd, 0x3ffe600e,0x007ffd42,0xfa83fff1,0x3fe203ff,0x2201ffff,0x7fec0fff, 0x7fffdc02,0x03ffe201,0x7401fff7,0x0fff65ff,0xdd0bffa0,0x3a00fff6, 0x0fffc2ff,0xf90fff30,0x3fff607f,0x43ff904f,0xf305fffc,0x3e209fff, 0xbfff91ff,0x7d400000,0x7dc006ff,0x2605ffef,0x7dc00fff,0x403ffcaf, 0x7c407ff9,0xff900eff,0x1ffea01f,0x01fff880,0x01c00000,0x64014400, 0xff7001ff,0x3ffe601f,0x077fe43f,0x5c7fff30,0x400ffec7,0x3fe61ffe, 0x10d64c06,0xf9005fff,0x02ffe8df,0x7ec5ffb8,0xfffb805f,0x4ffb804f, 0x2601ffe2,0xfb803fff,0x01ffec4f,0x7ec3ffe6,0x2ffe803f,0x03ffdafc, 0x7e42ffe8,0x13ff204f,0x7fc17fea,0xfff06ffc,0x200fffc8,0x3a00ffff, 0x1fff92ff,0x3e600000,0x22000fff,0x05ffbeff,0x36017ffc,0x05ff98ff, 0x5402ffdc,0xffa84fff,0x1ffea02f,0xa89ffd00,0xcccccccc,0x02cccccc, 0x28800038,0x801ffc80,0xd103fff8,0x7c4fffdf,0xffc802ff,0x80041b66, 0x3fe22ffd,0xff98004f,0x1fff1006,0x4401ffe6,0x0fff47ff,0x01fffe80, 0x0107ff88,0x003fff30,0x7ff8dff1,0xffd81300,0x22ffe803,0x07ffb3f9, 0xf985ffd0,0x07ffe07f,0x3e61ffe2,0x4c0ffdaf,0x37fe45ff,0xb017ff60, 0x1bff27ff,0x7f440000,0x7f4001ff,0x405ffa8f,0x7fc03ffd,0xfb01ffe6, 0x3ff2007f,0x13ffe22f,0x800fff50,0x7fe44ffd,0xffffffff,0x3804ffff, 0x95288000,0xffd99999,0x1999999b,0xfd81ffe6,0xf31fff8e,0x3fe200df, 0x8003fb8f,0x42fffca8,0x0adffffd,0x005ffb80,0x7fd47ffe,0x43ffe006, 0x36007ff8,0x3fe007ff,0x6dcc000f,0x3fe007ff,0x001bfe27,0xe803ffd8, 0x21dd12ff,0xfe803ffd,0x81ffe82f,0x3f606ff9,0x5c7fe41f,0x17fe42ff, 0xf9017ff2,0x3ffc809f,0x0000bff9,0x00ffff60,0x3ea7ff90,0x2ffd405f, 0x7ec9ff50,0x03ffe01f,0xb0fffe80,0xff500dff,0x1fff800f,0x7fffffe4, 0xfffeffff,0x80003803,0xfffff928,0xffffffff,0x3fea3fff,0x361ff705, 0x0bff72ff,0x27f7ffc0,0x3fb6ea20,0x42ffffff,0xffffffe8,0x9ff901be, 0xb97ff400,0xffffffff,0xffffffff,0x400dff31,0xfffffffc,0xffffffff, 0x3b6ea01f,0xffffffff,0xffffffff,0xff50ffff,0x7fec000b,0xbbffe803, 0x0fff60ee,0x2e0bffa0,0x3ffc84ff,0xfd13fee0,0xfd13fe6d,0x04ffc81f, 0x3201ffe4,0x09ff93ff,0xfff90000,0x5ff98009,0xf1017fea,0x0ffe40ff, 0x3e609ff7,0x7fcc006f,0x01fffbdf,0x2007ffa8,0x20007ffa,0x7005ffe8, 0x32510000,0xffffffff,0xffffffff,0xf309ff71,0xc9ffe45f,0x3fa004ff, 0x3f2202ff,0xefffffff,0xff902fff,0x1dffffff,0x2003ffd8,0xfff93ffd, 0xffffffff,0x2e5fffff,0x3ee005ff,0xffffffff,0x2fffffff,0x7ffffec4, 0xffffefff,0xffffffff,0xff72ffff,0x7fec0009,0xefffe803,0x01ffec0c, 0x7c417ff4,0x00fff87f,0xff89bfe2,0xff89bfe4,0x403ffc85,0x7e403ffc, 0x007ff93f,0x6fffa800,0x07ff4400,0xfd00bff5,0x31ffa03f,0x3fee0dff, 0xfffb8004,0xf5003fff,0xff9100ff,0x7f40005f,0x000e006f,0x5554ca20, 0xacffdaaa,0xf90aaaaa,0x44ff887f,0x7ffb4ffc,0x027fec00,0xdffffff1, 0x0bff6359,0xffffda88,0x3ff62fff,0x4fff6003,0xcccceffc,0xcccccccc, 0x00bff71c,0x6667ffdc,0xcccccccc,0x3ffa21cc,0x88abdeff,0xcccccfff, 0xcccccccc,0x000bff71,0x7401ffec,0x3ff603ff,0x02ffe803,0x7fd45ffb, 0x50ffe805,0x87fec5ff,0xffc82ffb,0x01ffe403,0x7fe4fff2,0x3e600003, 0x64000fff,0x2ffd42ff,0x441ffe40,0x0fff85ff,0x0002ffd8,0x00bffffb, 0x7777ffd4,0xfffffeee,0x3f60001f,0x00e000ef,0x3200a200,0xffc801ff, 0x7e42fec4,0x007ffb3f,0xfd01ffec,0x7f4037ff,0x3ae6002f,0x3ff27fff, 0x4bffa004,0x40005ffb,0x32006ffa,0xf80006ff,0xf101beff,0xfa8000ff, 0x3f60006f,0x2fff803f,0x200fff60,0xff502fff,0x4017fecb,0x1ff92ffb, 0xffd97fdc,0x403ffc80,0x7e403ffc,0x007ff93f,0x3fffa200,0x27fd4001, 0x5402ffd4,0x3ffb85ff,0xff82ffc8,0xff10000f,0x7d4001ff,0xffffffff, 0x00cfffff,0x03fff900,0x88000380,0x01ffc802,0x3f26ffb8,0x92ffd80f, 0x7f4009ff,0x3fff302f,0x005fff00,0x547ffee0,0x3fe005ff,0x00fff31f, 0x007ff880,0x0003fffa,0x401fffa8,0x0000fff9,0x5c01ffe6,0x07ff91cc, 0x202fff88,0x7c403ffc,0x3ffe02ff,0x3007ff88,0x31bfebff,0x41bfe9ff, 0x7e403ffc,0x9ffe403f,0x00003ffc,0x8005fffb,0xfa80eff8,0x7ff8805f, 0xfa80ffd8,0x037fcc5f,0xbffff900,0x7fffd400,0xffffffff,0x4003ffff, 0x8002fffb,0x02880003,0xa801ffc8,0x03ff57ff,0x7fd47ffe,0x07ffe005, 0x4c02ffdc,0x3f6e2fff,0x33ffe803,0xf5001fff,0x0fffc4ff,0xf0677cc0, 0xff3005ff,0xdf3005ff,0x402ffe4b,0xa802fffb,0xfff10eff,0x23ffd003, 0x7cc04ffc,0x3ff202ff,0x17ffcc04,0xff75ff90,0x47ffc009,0xafff84ff, 0x7ff903ff,0x403ffc80,0x7ff93ffc,0xfff90000,0x3ffb0009,0x4017fea0, 0x37fc0ffe,0x7dc7ff88,0xff30003f,0x2005ffff,0x9999fffa,0xffcba999, 0xff5003ff,0x00e0007f,0x3200a200,0xff8801ff,0xf503ffaf,0x07ffccff, 0x903ffd40,0xffb00dff,0x03ffdc5f,0xfe87ffe2,0x5ffe805f,0x74037fec, 0x37fe46ff,0x37fffec0,0xfb2fff40,0xfff980bf,0x7ff400ef,0x202ffec5, 0x3fee7ff9,0x17ffec06,0xd80dff70,0x3e602fff,0x001ffddf,0x07ff3ff2, 0x03ffbff6,0x3201ffe4,0x7fe403ff,0x0007ff93,0x005fffa8,0x2a04ffb8, 0xff9005ff,0xd027fcc5,0x0ffec1ff,0x6fffc400,0xa800fffe,0x3a6007ff, 0xff9807ff,0x7997004f,0x0a20000e,0x4007ff20,0x205ffffe,0x7ff45ffe, 0x04ffe805,0xd80bffee,0x3e63ffff,0x3fee03ff,0x81fffcc6,0x440fffd8, 0x3f204fff,0x7ffc42ff,0xffff900d,0x3ee01bff,0x3ffee2ff,0xffffd100, 0x7ffe40bf,0x81fffc42,0x3e64ffe8,0xfff903ff,0x7ffcc05f,0x5ffff903, 0x6ffffe80,0x7fffd400,0xdffff707,0x201ffe40,0x7e403ffc,0x007ff93f, 0x077ffcc0,0x01bfe600,0x2600bff5,0x0bff24ff,0x3fe2ffc8,0xfffb0007, 0x00dfff31,0x8800fff5,0x3e201fff,0x3fa005ff,0x1000075f,0x03ff9005, 0x03fffe60,0x2607ffec,0x3f603fff,0x3fe200ff,0xeba8acff,0x644fffff, 0xa9acefff,0xfc83fffc,0xeb99bdff,0xff901fff,0xfd9337df,0x3fee0bff, 0xfeb99bef,0xffff9bff,0xfffec9ab,0x677ffc44,0xbfffdb89,0x9acefff9, 0x704ffffc,0xb537bfff,0xffd0dfff,0xffd957bf,0xfe805ffb,0xfecabeff, 0x5c02ffdf,0x8003ffff,0xf105ffff,0x7e407fff,0x1ffe403f,0x7e4fff20, 0xfd10003f,0xf70003ff,0xffffffff,0xffffffff,0xfd37fc01,0xa7fcc01f, 0xb8005ff8,0x3fee2fff,0x3ffd403f,0x827ff400,0x000effe8,0x001d7ffa, 0x54c01440,0x3ff6000a,0xfeb99cff,0xfff902ff,0xffd7337b,0xfff5007f, 0x5dffffff,0xffd0dff3,0xffffffff,0x7fffdc05,0x01ffffff,0x7fffffdc, 0x5405ffff,0xffffffff,0x3ffa61ff,0x5fffffff,0xffffff50,0x7443dfff, 0xffffffff,0x7ffdc04f,0x0effffff,0xfffffe98,0x2ffb9fff,0x7ffff4c0, 0xffb9ffff,0x7fffc402,0xfffd8000,0x07fffa03,0x6403ffc8,0x7fe403ff, 0x0007ff93,0x000bfff6,0x7fffffdc,0xffffffff,0x3f600fff,0x805ff88f, 0x05ff56ff,0x84fff980,0x2a01fffe,0xfc8007ff,0x1fffd06f,0x75ffe800, 0x00510000,0x3ffe6000,0xffffffff,0x7ffdc03f,0x2fffffff,0x3fffa600, 0x7ffc4fff,0xffffea81,0xd9801dff,0x0bdfffff,0xffffb100,0x22005dff, 0xdefffffc,0xfffec881,0x74c02eff,0x03efffff,0xfffffd91,0x3f66003b, 0x403fffff,0xdfffffd8,0x1005ff71,0x3bfffffb,0x3600bfee,0xf50005ff, 0x7fe403ff,0x01ffe407,0xf900fff2,0x00fff27f,0x013ffee0,0xeeeeea80, 0xffeeeeee,0x2e00eeef,0x03ffa9ff,0x1ff97fd8,0x37ff4400,0x00efff88, 0xb000fff5,0xfffb0bff,0x53e20003,0x92880003,0xffffffff,0xffffffff, 0x3673fa23,0x0dffffff,0xffffb300,0x200037bf,0x00009a98,0x000554c4, 0x00003510,0x00013551,0x200054c4,0x440009a9,0x4c4001a9,0x2600009a, 0xa98000aa,0x54c00001,0x00000001,0x00000000,0x00000000,0x00bfff50, 0x7fd40000,0x2ffe6005,0xfb801ffc,0x4006fe9f,0x2a01fffd,0xff505fff, 0x7fff000f,0x002fffc8,0x001cfea0,0xfffc9440,0xffffffff,0xd11fffff, 0x01aa988d,0x000d4c00,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x20000000,0x000efff8, 0x3fea0000,0x76ffc005,0x7ff3007f,0x7dc009ff,0xffd803ff,0x07ffa82f, 0x717ffec0,0x80007fff,0x000071fd,0x3ffff251,0xffffffff,0x0041ffff, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x44000000,0x0000effe,0x2ffd4000, 0x3ffff600,0x3fffe004,0xfff3002f,0x3ffe200b,0x03ffd40f,0x2ffff5cc, 0x999ffff3,0xdddddddb,0x9727ec1d,0x99999999,0xb9999999,0x00000005, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x98000000,0xffffffff,0xffffffff, 0xa8007fff,0x7dc005ff,0x32002fff,0xd000ffff,0x54001fff,0x7fd46fff, 0xffffffff,0x0effffff,0x3fffffe6,0xffffffff,0x000ee0ff,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x7fffffcc,0xffffffff, 0x007fffff,0x4005ffa8,0x000ffff9,0x4017ffea,0x8002fffc,0x3ea3fffc, 0xffffffff,0x0dffffff,0x7fffffcc,0xffffffff,0x000000ff,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x30000000,0xffffffff,0xffffffff, 0x5000ffff,0xff000bff,0xff8800df,0xfffa803f,0x3ffa0004,0xfffff51f, 0x9ddfffff,0x00000017,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x86654000, 0x0bdeeca8,0x99999950,0x99999999,0x803ccc85,0x332a4ccb,0x0f332601, 0x32a10000,0x0479972c,0x00000000,0x98000000,0x310cc409,0x00033103, 0x00000000,0x000fbb60,0x3b2a2000,0x00000bee,0xb705fd10,0x00019ddd, 0x00000000,0x32600000,0x4f32e0cc,0x9950ccc9,0x200aa209,0x420009a9, 0x6c05eed8,0x55550dee,0x3bbbbbb6,0x43ddb4ee,0x79954eea,0x22222222, 0x88888888,0x00088888,0x3a23ff20,0x2fffffff,0xffffffc8,0xffffffff, 0x017ffdc4,0x7e45fff5,0xdfff103f,0x36600001,0x3f69ff77,0x00073e6f, 0x00fff000,0xfa8003aa,0x207fe401,0x13fe26fd,0xbb005ff5,0x44013600, 0x3e0006ff,0x6c4004ff,0x3600defe,0x05ffffff,0x33bfff6a,0x0bffe600, 0xfffffffb,0x007fd403,0xffffffff,0xffffffff,0x7fffffcd,0xffffffff, 0x7fecc6ff,0x07ffd42e,0x3feabffd,0x20fff91f,0xffb105fc,0x4405bfff, 0x0bffea2d,0xfb17ffd4,0x3ffffabf,0xffd5ffff,0xfdb7fd43,0xfffff76f, 0xffffffff,0x3fffffff,0x2bff2000,0xfffeffff,0x7ffe42ff,0xefffffff, 0xffd83fff,0x4fff880f,0x7c41ffe4,0x80000eff,0xff77ffeb,0xff9bff69, 0x000002ef,0xff500fff,0x9dfb511d,0x403ffea3,0x7fdc3ff9,0x360ffe42, 0x3ff600ff,0x027fec05,0x0017ffe4,0x2004fff8,0xfffffffa,0x88affb82, 0xffb81ffd,0x40ffffff,0x22ffffb8,0xfb99cffa,0x01fe605f,0xffffffff, 0xffffffff,0x7fffffcd,0xffffffff,0x3ffea6ff,0x3fea4fff,0x557ffa0f, 0xfff91fff,0xf3037fa0,0xffffffff,0xfd73139f,0xd06ffc85,0x5ffd87ff, 0xfffffffd,0xa87ffabf,0x2dffb6ff,0xfffffffb,0xffffffff,0x001fffff, 0x7dffff90,0x037ffd41,0x05ffe880,0xfb0bfff1,0x87ff90df,0x0005ffe8, 0x7ffffe44,0x3f69ff76,0x3ffffe6f,0x200000cf,0xfe8807ff,0xffffffff, 0x105fffff,0x5ff98dfd,0x7cc6ff88,0x3ffee05f,0x05fffb05,0x00bffff0, 0x400fbb60,0xfdadfff8,0x21e5c0ff,0x7fc44ff8,0x49ff711d,0x2ffdfff8, 0x3ff61bfa,0x0c6f9860,0x3ffffffe,0xffffffff,0x3ffffe6f,0xffffffff, 0x7ff16fff,0x7d47fea1,0x57ffa0ff,0xff91fffa,0x9ffdd10f,0x7fffffdc, 0xffffffff,0xffd82fff,0x6c2ffcc1,0x555535ff,0x3b635555,0x6d3baa1e, 0x111116ff,0x11111111,0x11111111,0x7ffe4000,0x07ffea04,0x01bffa00, 0x7dc5fff5,0x3ffc81ff,0x0017ffa2,0xfffffda8,0x013fee2e,0xfffffd71, 0xff00003b,0x3ffa200f,0xfffeefff,0x3ff205ff,0xa80fff42,0x1ffe44ff, 0xd8bfff70,0xfb802fff,0x0001ffef,0x81ff9000,0xf9005ff8,0x80fea83f, 0x233e25fe,0xfb002ff9,0x7c577d4d,0x000feb8e,0x0006ff80,0xfb84fb80, 0x881fff55,0x23fff54f,0x7e407ffb,0x4c3bf70f,0xffffffeb,0xbfd00eff, 0x9880efd8,0x00000009,0x00000000,0x007ffe40,0xb000bffe,0xf9001dff, 0x7fff31ff,0x744fff20,0xb88005ff,0x1cfffffe,0x2004ffb8,0xefffffd9, 0x1ffe0003,0x43fffa80,0x500fffd8,0x4ffb8dff,0xf117ff40,0x7fdc01ff, 0x2fffd8df,0xff3ffd00,0x26666209,0x99999999,0x27f41999,0x7e407fc8, 0x744002ff,0x5ff3046f,0x6c9ff300,0xffffffff,0xf80003ff,0xd800006f, 0xf36f881f,0x267f50ff,0xdff50fff,0xb8fff440,0x7ffe4403,0x408803ef, 0x00000088,0x00000000,0xffc80000,0x02ffe805,0x007fff20,0x7f67ff44, 0x2fff205f,0x4005ffe8,0xefffffc9,0x13fee00b,0x3ffae200,0x4000cfff, 0x3f2007ff,0x0fff202f,0xf987ffe2,0x7fcc00ff,0x01bfee0f,0xfffffff7, 0x53fea005,0xffc80ffe,0xffffffff,0x21ffffff,0x1ff703ff,0x00efffc0, 0xffffd973,0x017fcc0d,0xa883ffea,0xcdffffec,0xff80000a,0xfc800006, 0xff15f983,0x7fc3fb0d,0xdb17fe66,0x0009ffff,0x000000c4,0x00000000, 0x00000000,0x2013ff20,0xf7002ffd,0xf98005ff,0x200effff,0xfffecffc, 0xfffb5000,0x2e003bff,0x540004ff,0x2dfffffd,0x26666666,0x99999fff, 0x202ffc09,0xffd85ff8,0x801fff44,0x7ff45ffd,0x7fffdc03,0x3ff6002f, 0xf907ff50,0xffffffff,0x3fffffff,0x7d40bfe2,0x3f2a601f,0x7ffec43f, 0x206ffeff,0x3f202ff9,0x3fa200ef,0xf800005f,0xa800006f,0x3e4fd86f, 0x3a27ec4f,0x3e1ffc5f,0x000dffff,0x00000000,0x00000000,0x00000000, 0x6c01ffe4,0xffa803ff,0xff90003f,0xffc803ff,0x005fffff,0x017dffff, 0x004ffb80,0xffff9100,0x7fffffcf,0xffffffff,0x0ffe66ff,0xff51ff60, 0x037fe41f,0x545fff10,0x7f401fff,0x3e6006ff,0x5c3ffc5f,0xeeeeeeee, 0xeeeeeeee,0x2e07ff11,0xffb000ff,0x21beffd8,0x3fe606fd,0x0dffd882, 0x3fb3fa20,0x7fc00005,0x26666666,0x99999999,0x2fbfa099,0x3f60ffeb, 0x27e41dc3,0x35330bfa,0x99999501,0x99999999,0x19999999,0x00000000, 0x00000000,0xffc80000,0x03ffd803,0x0027ffcc,0x01dfff10,0xfeffffc8, 0xfff802ff,0xff70001e,0xfa800009,0x3fffe7ff,0xffffffff,0x3ea6ffff, 0x1ffc802f,0xf98bffe2,0xff5000ff,0x037fe41f,0x17fffff6,0x3217fe40, 0x000002ff,0x7fc827fc,0x3f202aa2,0x7417fe1f,0x0bfe606f,0xb007ffd3, 0x09ff31ff,0xf37fc000,0xffffffff,0xdfffffff,0x77fffec4,0x980054c1, 0x00054c1a,0x7fffffdc,0xffffffff,0x01ffffff,0x00000000,0x00000000, 0x1ffe4000,0x101ffec0,0x8000bfff,0x404ffffd,0xff94fffc,0xffff801f, 0x7dc002ef,0xb880004f,0x3a6ffffe,0xffeeeeee,0x5eeeeeef,0x3a013fe2, 0x46ffb87f,0xfd005ffc,0x0fffc45f,0xffbfffb0,0x7ff880bf,0x2006ff88, 0xfb000999,0x25ff883f,0x7fc45fe8,0x7e427fc7,0x8bfe606f,0x9802fff8, 0x03bf22ff,0xf37fc000,0xffffffff,0xdfffffff,0x00059750,0x54000000, 0xcccccccc,0xcccccccc,0x0000cccc,0x00000000,0x00000000,0x401ffe40, 0xfd103ffd,0x5c0001df,0x02ffffff,0xff897ff2,0x7f5c405f,0x800cffff, 0x20004ffb,0xefffffc9,0x01ffe002,0x7cc06fe8,0x87ffb04f,0x7dc01ffe, 0x01ffec5f,0x3ee5fffb,0x3fee05ff,0x003ffb04,0x44013ffe,0xffdadfff, 0x67ffd40f,0x7e43fffd,0xfffda9bf,0xe8bfe607,0xffffffff,0x1222442f, 0x47990000,0xeeeeeeee,0xeeeeeeee,0x00000005,0x00000000,0x00000000, 0x00000000,0x64000000,0xffd803ff,0x01fffd03,0x57ffc400,0xf900fffb, 0x2fffa87f,0xffffb500,0x7fdc05bf,0xffda8004,0x8001dfff,0x3f2007ff, 0x5ffd105f,0x983ffe20,0x3fe206ff,0x81bfe60f,0x7dc2fffd,0x1fff05ff, 0x4017fea0,0x2a004fff,0x2fffffff,0xffffff90,0xfffff107,0x201ff7bf, 0xfff32ff9,0x5fffffff,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x01ffe400,0x7ec1ffec,0x740001ff,0x17ffa5ff, 0x7ec1ffe4,0x322000ff,0x0befffff,0x88027fdc,0xbffffffb,0x1ffe0000, 0xaefffb80,0x1ffffb99,0xf913fea0,0x0bff207f,0x3f601ffd,0xfff702ff, 0x405ffa8b,0xff800ffe,0x76c4004f,0x54400def,0x2a2009aa,0x39912ded, 0x99884cc0,0x99999999,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x0fff2000,0xf90fff60,0xb80005ff,0x3fe60fff, 0x83ffc83f,0x0005fff8,0x9fffffd7,0x3013fee3,0x5dfffffb,0x1ffe0000, 0x7ffffd40,0xffffffff,0x07ff201f,0xff981ffd,0x7017fd44,0xffb805ff, 0x2017ff42,0xaa804ffb,0x0000001a,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0xfc800000,0x3ffd803f, 0x000fffee,0x705fff30,0xffc81fff,0x05fff503,0x7ffecc00,0x2e9ff77f, 0x3fffe3cc,0x400001df,0xffa807ff,0xfffffddf,0x00fffece,0xff98bfd1, 0x7fc37f44,0x7002b805,0x00000005,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xffc80000, 0x33ffd803,0xb999ffff,0xdddddddd,0x205ffe81,0x7fe46ffe,0x03fff603, 0xfff91000,0x7fed3fee,0x002fffe6,0x03ffc000,0x32627f44,0x017fa21b, 0xdeb83dd3,0xea83dd30,0x0000000d,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x03ffc800,0xff33ffd8,0xffffffff,0x41ffffff,0x2600fffc,0x3ff23fff, 0x17ffe203,0xf75b8000,0xe9bff69f,0xe8000002,0x0091005e,0x00000488, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x1ffe4000,0xf99ffec0, 0xffffffff,0x0fffffff,0x9005fff5,0x3ff23fff,0x17ffdc03,0x7fdc0000, 0x000dffb4,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, }; static signed short stb__arial_40_latin_ext_x[560]={ 0,3,1,0,1,2,1,1,2,2,1,1,2,1, 3,0,1,3,1,1,0,1,1,1,1,1,3,2,1,1,1,1,1,-1,2,1,2,2,2,1,2,3,0,2, 2,2,2,1,2,1,2,1,0,2,0,0,0,0,0,2,0,0,0,-1,1,1,2,1,1,1,0,1,2,2, -2,2,2,2,2,1,2,1,2,1,0,2,0,0,0,0,0,0,3,0,1,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,4,1,0,1,-1, 3,1,1,0,0,2,1,1,0,-1,2,1,0,0,3,2,0,3,1,1,0,2,1,1,0,2,-1,-1,-1,-1, -1,-1,0,1,2,2,2,2,0,2,-1,0,-1,2,1,1,1,1,1,2,1,2,2,2,2,0,2,2,1,1, 1,1,1,1,1,1,1,1,1,1,0,3,-1,0,1,2,1,1,1,1,1,1,2,2,2,2,2,0,2,0, -1,1,-1,1,-1,1,1,1,1,1,1,1,1,1,2,1,-1,1,2,1,2,1,2,1,2,1,2,1,1,1, 1,1,1,1,1,1,2,2,0,0,-2,-1,-1,-1,-1,-1,2,1,3,3,3,2,0,-2,2,2,2,2,1,2, -1,2,2,2,2,0,0,2,2,2,2,2,2,1,2,2,1,1,1,1,1,1,2,1,2,2,2,2,2,1, 1,1,1,1,1,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0, 0,0,0,0,0,0,0,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,4,4,0,4,4,4, 4,4,4,4,4,4,4,4,4,4,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,-1,1,-1,-2,1, 1,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,-1,1,0,1,1,2,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 4,4,4,4,4,4, }; static signed short stb__arial_40_latin_ext_y[560]={ 32,6,6,5,4,5,5,6,5,5,5,10,28,21, 28,5,6,6,6,6,6,6,6,6,6,6,13,13,10,13,10,5,5,6,6,5,6,6,6,5,6,6,6,6, 6,6,6,5,6,5,6,5,6,6,6,6,6,6,6,6,5,6,5,36,6,13,6,13,6,13,5,13,6,6, 6,6,6,13,13,13,13,13,13,13,6,13,13,13,13,13,13,5,5,5,16,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,32,13,6,5,10,6, 5,5,6,5,5,14,13,21,5,2,5,10,6,6,6,13,6,17,31,6,5,14,5,5,5,13,-1,-1,-1,0, 1,0,6,5,-1,-1,-1,1,-1,-1,-1,1,6,0,-1,-1,-1,0,1,11,5,-1,-1,-1,1,-1,6,5,6,6, 6,6,6,5,13,13,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,12,12,6,6,6,6,6,6,6, 1,7,0,6,6,13,-1,6,0,6,0,7,0,6,0,6,6,6,1,7,0,6,0,7,6,13,0,6,0,6, 0,6,1,7,5,4,-1,-1,6,6,0,6,2,7,0,6,6,6,0,13,6,6,-1,6,6,6,13,-1,0,6, 6,6,6,6,6,6,6,-1,6,6,13,-1,6,6,5,13,1,7,0,6,-1,6,5,13,-1,6,6,13,0,6, -1,6,0,6,5,13,0,6,6,6,0,6,6,6,0,6,1,7,0,6,-1,5,-1,6,6,13,-1,6,-1,6, 1,-1,6,0,7,0,6,5,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,5,9,9,5,9,9,9, 9,9,9,9,9,9,9,9,9,9,5,12,9,9,9,9,9,9,9,9,9,9,9,9,9,6,13,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,6,0,6,0, 6,0,6,-1,1,-1,-1,-1,-1,-1,-1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,-5,-2,-1,6,-1,6,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9, }; static unsigned short stb__arial_40_latin_ext_w[560]={ 0,4,11,20,18,28,23,5,9,9,12,18,5,10, 4,10,18,11,18,18,19,18,18,18,18,18,4,5,18,18,18,18,35,25,20,24,22,20,19,25,21,4,16,22, 17,26,21,26,21,26,24,22,22,21,24,34,24,24,21,8,10,8,16,22,8,18,17,17,17,18,12,17,16,4, 8,16,4,26,16,18,17,17,11,16,10,16,18,26,18,18,18,12,4,11,19,19,19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,0,4,18,19,18,21, 4,18,10,27,13,16,18,10,27,22,10,18,12,12,8,16,20,4,9,8,13,16,29,29,30,18,25,25,25,25, 25,25,34,24,20,20,20,20,8,7,12,10,25,21,26,26,26,26,26,17,26,21,21,21,21,24,21,19,18,18, 18,18,18,18,30,17,18,18,18,18,8,7,12,10,18,16,18,18,18,18,18,18,18,16,16,16,16,18,17,18, 25,18,25,18,29,22,24,17,24,17,24,17,24,17,22,22,25,19,20,18,20,18,20,18,20,18,20,18,25,17, 25,17,25,17,25,17,21,16,26,18,13,12,12,12,12,12,9,9,4,4,22,12,20,12,22,16,16,17,7,17, 9,17,9,17,10,19,8,21,16,21,16,21,16,21,23,16,26,18,26,18,26,18,33,32,24,11,24,11,24,12, 22,16,22,16,22,16,22,16,22,10,22,14,22,10,21,16,21,16,21,16,21,16,21,16,21,20,34,26,24,18, 24,21,18,21,18,21,18,9,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,19,19,19,19,19,19, 19,19,19,19,19,19,19,19,19,19,29,22,19,19,19,19,19,19,19,19,19,19,19,19,19,28,21,19,19,19, 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,25,18,12,12,26, 18,21,16,21,16,21,16,21,16,21,16,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19,19,19,25,18,34,30,26,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, 19,19,19,19,19,19, }; static unsigned short stb__arial_40_latin_ext_h[560]={ 0,26,10,28,32,28,28,10,35,35,12,18,10,4, 4,28,27,26,26,27,26,27,27,26,27,27,19,25,19,12,19,27,35,26,26,28,26,26,26,28,26,26,27,26, 26,26,26,28,26,29,26,28,26,27,26,26,26,26,26,34,28,34,15,4,6,20,27,20,27,20,27,27,26,26, 34,26,26,19,19,20,27,27,19,20,27,20,19,19,19,27,19,35,35,35,7,23,23,23,23,23,23,23,23,23, 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,0,27,34,28,18,26, 35,35,4,28,14,17,12,4,28,3,11,22,14,14,6,27,34,5,9,14,15,17,28,28,28,27,33,33,33,32, 31,32,26,35,33,33,33,31,33,33,33,31,26,32,34,34,34,33,32,16,29,34,34,34,32,33,26,28,27,27, 27,27,27,28,20,27,27,27,27,27,26,26,26,26,27,26,27,27,27,27,27,15,22,27,27,27,27,34,34,34, 31,26,32,27,34,27,34,27,33,27,33,26,33,27,32,27,26,27,31,26,32,27,32,26,34,27,32,27,33,34, 33,34,32,33,35,36,33,33,26,26,32,26,30,25,32,26,34,34,32,19,27,34,34,34,34,34,19,33,32,34, 34,26,26,26,26,26,26,33,26,34,27,33,26,26,28,27,32,26,33,27,34,27,28,20,33,26,34,27,32,26, 34,27,33,27,35,27,33,27,37,36,32,27,26,27,33,27,32,26,33,27,34,28,34,27,34,27,33,26,33,34, 31,33,26,32,25,32,26,27,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,28,23,23,35,23,23,23, 23,23,23,23,23,23,23,23,23,23,28,21,23,23,23,23,23,23,23,23,23,23,23,23,23,27,20,23,23,23, 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,32,27,32,26,33, 27,33,27,34,32,34,34,34,34,34,34,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, 23,23,23,23,23,23,23,23,23,23,37,35,33,27,35,28,23,23,23,23,23,23,23,23,23,23,23,23,23,23, 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, 23,23,23,23,23,23, }; static unsigned short stb__arial_40_latin_ext_s[560]={ 509,333,384,348,54,219,38,372,92,188,310, 121,378,449,471,139,360,119,195,484,23,20,189,433,465,439,97,143,73,342,102, 367,223,307,103,144,131,154,175,62,241,280,405,74,452,214,97,321,338,88,385, 248,410,345,470,43,78,360,1,442,461,411,211,476,426,230,267,368,230,285,217, 161,290,285,368,263,505,471,1,266,90,430,498,249,493,408,425,444,37,71,18, 79,129,153,406,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,509,504,451, 271,140,320,218,310,460,399,274,159,323,449,472,406,361,169,297,261,435,422,470, 444,396,288,247,176,369,291,188,386,455,306,125,181,448,207,239,259,53,388,409, 427,262,320,152,499,449,384,435,45,1,165,317,193,61,93,137,107,295,237,28, 1,307,288,269,250,231,150,337,171,152,133,114,95,503,458,1,63,1,37,474, 455,436,417,398,228,188,343,379,345,284,88,491,348,22,99,269,379,367,301,28, 169,430,247,481,148,28,206,246,224,274,39,1,369,160,324,406,486,273,326,139, 59,99,196,151,178,344,244,284,61,350,372,342,198,370,185,48,495,233,118,316, 498,506,92,208,462,72,422,475,53,56,332,502,70,214,81,502,431,475,300,54, 262,485,115,78,177,131,217,115,448,424,166,1,265,224,187,427,304,363,69,397, 500,451,401,129,362,214,396,165,413,221,16,1,50,31,1,14,33,192,44,73, 414,298,125,326,21,294,179,251,196,328,1,74,159,474,199,50,95,124,117,466, 61,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,118,149,149,198, 149,149,149,149,149,149,149,149,149,149,149,149,149,88,207,149,149,149,149,149, 149,149,149,149,149,149,149,149,285,386,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,476,248, 18,388,271,142,284,108,329,1,420,394,1,351,23,377,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,24,134,389,314,102,169,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149, }; static unsigned short stb__arial_40_latin_ext_t[560]={ 1,320,374,176,143,176,208,374,1,1,374, 374,374,374,374,176,208,320,320,237,347,237,237,320,237,265,374,347,374,374,374, 265,1,320,347,208,320,320,320,208,320,320,265,320,320,320,320,176,320,176,320, 176,320,265,320,347,347,320,347,1,175,1,374,374,374,347,265,347,265,347,265, 265,320,320,1,320,293,347,374,347,265,237,347,347,208,347,347,347,374,265,374, 1,1,1,374,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347, 347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,1,208,1, 176,374,293,1,1,374,176,374,374,374,374,175,382,374,347,374,374,374,265,1, 374,374,374,374,374,176,176,176,265,74,109,109,143,143,143,293,1,109,74,74, 143,74,74,74,143,293,143,39,39,74,74,143,374,176,39,39,74,143,74,293, 208,237,237,237,237,237,176,347,237,237,237,237,237,237,265,320,320,237,320,208, 208,208,208,208,374,347,208,237,237,208,74,1,39,176,293,143,208,39,208,74, 208,74,208,74,293,109,208,143,208,293,237,176,293,143,208,143,293,39,237,143, 237,109,39,109,39,143,109,1,1,109,109,293,293,143,293,176,320,143,293,39, 39,74,374,237,39,39,39,39,74,374,109,109,74,39,293,265,293,293,293,320, 109,265,39,237,109,293,293,176,237,109,293,109,208,39,208,175,347,74,293,39, 175,109,293,74,237,74,237,1,237,109,265,1,1,143,265,320,265,74,265,143, 293,74,265,39,208,39,265,39,265,74,293,109,39,143,109,293,143,347,143,265, 265,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,208,347,347,1, 347,347,347,347,347,347,347,347,347,347,347,347,347,208,347,347,347,347,347,347, 347,347,347,347,347,347,347,347,265,347,347,347,347,347,347,347,347,347,347,347, 347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,109,265, 143,293,74,265,109,265,1,143,1,1,39,1,39,1,347,347,347,347,347,347, 347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347, 347,347,347,1,1,109,265,1,176,347,347,347,347,347,347,347,347,347,347,347, 347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347, 347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347, 347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347,347, 347,347,347,347,347,347,347,347,347, }; static unsigned short stb__arial_40_latin_ext_a[560]={ 159,159,203,319,319,509,382,109, 191,191,223,335,159,191,159,159,319,319,319,319,319,319,319,319, 319,319,159,159,335,335,335,319,582,382,382,414,414,382,350,446, 414,159,286,382,319,477,414,446,382,446,414,382,350,414,382,541, 382,382,350,159,159,159,269,319,191,319,319,286,319,319,159,319, 319,127,127,286,127,477,319,319,319,319,191,286,159,319,286,414, 286,286,286,191,149,191,335,430,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430,159,191,319,319,319,319,149,319, 191,422,212,319,335,191,422,316,229,314,191,191,191,330,308,159, 191,191,209,319,478,478,478,350,382,382,382,382,382,382,573,414, 382,382,382,382,159,159,159,159,414,414,446,446,446,446,446,335, 446,414,414,414,414,382,382,350,319,319,319,319,319,319,509,286, 319,319,319,319,159,159,159,159,319,319,319,319,319,319,319,314, 350,319,319,319,319,286,319,286,382,319,382,319,382,319,414,286, 414,286,414,286,414,286,414,352,414,319,382,319,382,319,382,319, 382,319,382,319,446,319,446,319,446,319,446,319,414,319,414,319, 159,159,159,159,159,159,159,127,159,159,421,254,286,127,382,286, 286,319,127,319,127,319,167,319,191,319,127,414,319,414,319,414, 319,346,414,319,446,319,446,319,446,319,573,541,414,191,414,191, 414,191,382,286,382,286,382,286,382,286,350,159,350,215,350,159, 414,319,414,319,414,319,414,319,414,319,414,319,541,414,382,286, 382,350,286,350,286,350,286,127,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,431,430,430,319,430,430,430,430,430, 430,430,430,430,430,430,430,430,491,376,430,430,430,430,430,430, 430,430,430,430,430,430,430,489,383,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, 430,430,430,430,430,382,319,159,127,446,319,414,319,414,319,414, 319,414,319,414,319,430,430,430,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, 430,430,382,319,573,509,446,350,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, 430,430,430,430,430,430,430,430, }; // Call this function with // font: NULL or array length // data: NULL or specified size // height: STB_FONT_arial_40_latin_ext_BITMAP_HEIGHT or STB_FONT_arial_40_latin_ext_BITMAP_HEIGHT_POW2 // return value: spacing between lines static void stb_font_arial_40_latin_ext(stb_fontchar font[STB_FONT_arial_40_latin_ext_NUM_CHARS], unsigned char data[STB_FONT_arial_40_latin_ext_BITMAP_HEIGHT][STB_FONT_arial_40_latin_ext_BITMAP_WIDTH], int height) { int i,j; if (data != 0) { unsigned int *bits = stb__arial_40_latin_ext_pixels; unsigned int bitpack = *bits++, numbits = 32; for (i=0; i < STB_FONT_arial_40_latin_ext_BITMAP_WIDTH*height; ++i) data[0][i] = 0; // zero entire bitmap for (j=1; j < STB_FONT_arial_40_latin_ext_BITMAP_HEIGHT-1; ++j) { for (i=1; i < STB_FONT_arial_40_latin_ext_BITMAP_WIDTH-1; ++i) { unsigned int value; if (numbits==0) bitpack = *bits++, numbits=32; value = bitpack & 1; bitpack >>= 1, --numbits; if (value) { if (numbits < 3) bitpack = *bits++, numbits = 32; data[j][i] = (bitpack & 7) * 0x20 + 0x1f; bitpack >>= 3, numbits -= 3; } else { data[j][i] = 0; } } } } // build font description if (font != 0) { float recip_width = 1.0f / STB_FONT_arial_40_latin_ext_BITMAP_WIDTH; float recip_height = 1.0f / height; for (i=0; i < STB_FONT_arial_40_latin_ext_NUM_CHARS; ++i) { // pad characters so they bilerp from empty space around each character font[i].s0 = (stb__arial_40_latin_ext_s[i]) * recip_width; font[i].t0 = (stb__arial_40_latin_ext_t[i]) * recip_height; font[i].s1 = (stb__arial_40_latin_ext_s[i] + stb__arial_40_latin_ext_w[i]) * recip_width; font[i].t1 = (stb__arial_40_latin_ext_t[i] + stb__arial_40_latin_ext_h[i]) * recip_height; font[i].x0 = stb__arial_40_latin_ext_x[i]; font[i].y0 = stb__arial_40_latin_ext_y[i]; font[i].x1 = stb__arial_40_latin_ext_x[i] + stb__arial_40_latin_ext_w[i]; font[i].y1 = stb__arial_40_latin_ext_y[i] + stb__arial_40_latin_ext_h[i]; font[i].advance_int = (stb__arial_40_latin_ext_a[i]+8)>>4; font[i].s0f = (stb__arial_40_latin_ext_s[i] - 0.5f) * recip_width; font[i].t0f = (stb__arial_40_latin_ext_t[i] - 0.5f) * recip_height; font[i].s1f = (stb__arial_40_latin_ext_s[i] + stb__arial_40_latin_ext_w[i] + 0.5f) * recip_width; font[i].t1f = (stb__arial_40_latin_ext_t[i] + stb__arial_40_latin_ext_h[i] + 0.5f) * recip_height; font[i].x0f = stb__arial_40_latin_ext_x[i] - 0.5f; font[i].y0f = stb__arial_40_latin_ext_y[i] - 0.5f; font[i].x1f = stb__arial_40_latin_ext_x[i] + stb__arial_40_latin_ext_w[i] + 0.5f; font[i].y1f = stb__arial_40_latin_ext_y[i] + stb__arial_40_latin_ext_h[i] + 0.5f; font[i].advance = stb__arial_40_latin_ext_a[i]/16.0f; } } } #ifndef STB_SOMEFONT_CREATE #define STB_SOMEFONT_CREATE stb_font_arial_40_latin_ext #define STB_SOMEFONT_BITMAP_WIDTH STB_FONT_arial_40_latin_ext_BITMAP_WIDTH #define STB_SOMEFONT_BITMAP_HEIGHT STB_FONT_arial_40_latin_ext_BITMAP_HEIGHT #define STB_SOMEFONT_BITMAP_HEIGHT_POW2 STB_FONT_arial_40_latin_ext_BITMAP_HEIGHT_POW2 #define STB_SOMEFONT_FIRST_CHAR STB_FONT_arial_40_latin_ext_FIRST_CHAR #define STB_SOMEFONT_NUM_CHARS STB_FONT_arial_40_latin_ext_NUM_CHARS #define STB_SOMEFONT_LINE_SPACING STB_FONT_arial_40_latin_ext_LINE_SPACING #endif zevv-duc-b8f9659/src/libduc-graph/graph-cairo.c000066400000000000000000000146761426703022500213420ustar00rootroot00000000000000 #include "config.h" #ifdef ENABLE_CAIRO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "private.h" #include "duc.h" #include "duc-graph.h" #include "utlist.h" #include "graph-private.h" struct cairo_backend_data { cairo_surface_t *cs; cairo_t *cr; duc_graph_file_format fmt; FILE *fout; }; static cairo_status_t cairo_writer(void *closure, const unsigned char *data, unsigned int length) { FILE *f = closure; fwrite(data, length, 1, f); return CAIRO_STATUS_SUCCESS; } void br_cairo_start(duc_graph *g) { struct cairo_backend_data *bd = g->backend_data; cairo_t *cr = bd->cr; cairo_save(cr); cairo_translate(cr, g->pos_x, g->pos_y); } void br_file_start(duc_graph *g) { struct cairo_backend_data *bd = g->backend_data; switch(bd->fmt) { case DUC_GRAPH_FORMAT_PNG: bd->cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, (int)g->size, (int)g->size); break; case DUC_GRAPH_FORMAT_SVG: bd->cs = cairo_svg_surface_create_for_stream(cairo_writer, bd->fout, (int)g->size, (int)g->size); break; case DUC_GRAPH_FORMAT_PDF: bd->cs = cairo_pdf_surface_create_for_stream(cairo_writer, bd->fout, (int)g->size, (int)g->size); break; default: duc_log(g->duc, DUC_LOG_FTL, "Image format not handled by cairo backend"); exit(1); } bd->cr = cairo_create(bd->cs); cairo_translate(bd->cr, g->pos_x, g->pos_y); } static void br_cairo_draw_text(duc_graph *g, double x, double y, double size, char *text) { struct cairo_backend_data *bd = g->backend_data; cairo_t *cr = bd->cr; char font[32]; snprintf(font, sizeof font, "Arial, Sans, %.0f", size); PangoLayout *layout = pango_cairo_create_layout(cr); PangoFontDescription *desc = pango_font_description_from_string(font); pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); pango_layout_set_text(layout, text, -1); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); pango_cairo_update_layout(cr, layout); int w,h; pango_layout_get_size(layout, &w, &h); x -= ((double)w / PANGO_SCALE / 2); y -= ((double)h / PANGO_SCALE / 2); cairo_move_to(cr, floor(x+0.5), floor(y+0.5)); pango_cairo_layout_path(cr, layout); g_object_unref(layout); /* light grey background */ cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL); cairo_set_source_rgba(cr, 1, 1, 1, 0.6); cairo_set_line_width(cr, 3); cairo_stroke_preserve(cr); /* black text */ cairo_set_source_rgb(cr, 0, 0, 0); cairo_set_line_width(cr, 1); cairo_fill(cr); } static void br_cairo_draw_tooltip(duc_graph *g, double x, double y, char *text) { struct cairo_backend_data *bd = g->backend_data; cairo_t *cr = bd->cr; char font[32]; snprintf(font, sizeof font, "Arial, Sans, %d", FONT_SIZE_TOOLTIP); PangoLayout *layout = pango_cairo_create_layout(cr); PangoFontDescription *desc = pango_font_description_from_string(font); pango_layout_set_text(layout, text, -1); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); pango_cairo_update_layout(cr, layout); int w,h; pango_layout_get_size(layout, &w, &h); w /= PANGO_SCALE; h /= PANGO_SCALE; /* shadow box */ int i; for(i=1; i<3; i++) { cairo_rectangle(cr, x - w - 10 + i, y - h - 10 + i, w + 10 + i, h + 10 + i); cairo_set_source_rgba(cr, 0, 0, 0, 0.25); cairo_fill(cr); } /* tooltip box */ cairo_rectangle(cr, x - w - 10 + 0.5, y - h - 10 + 0.5, w + 10, h + 10); cairo_set_source_rgba(cr, 1, 1, 1, 1); cairo_fill_preserve(cr); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_stroke(cr); /* black text */ cairo_move_to(cr, x - w - 5, y - h - 5); pango_cairo_layout_path(cr, layout); g_object_unref(layout); cairo_set_source_rgb(cr, 0, 0, 0); cairo_set_line_width(cr, 1); cairo_fill(cr); } static void br_cairo_draw_section(duc_graph *g, double a1, double a2, double r1, double r2, double R, double G, double B, double L) { struct cairo_backend_data *bd = g->backend_data; cairo_t *cr = bd->cr; cairo_new_path(cr); cairo_arc(cr, g->cx, g->cy, r1, ang(a1), ang(a2)); cairo_arc_negative(cr, g->cx, g->cy, r2, ang(a2), ang(a1)); cairo_close_path(cr); if(R != 1.0 || G != 1.0 || B != 1.0) { cairo_pattern_t *pat; pat = cairo_pattern_create_radial(g->cx, g->cy, 0, g->cx, g->cy, g->cx-50); double off1 = r2 / g->cx; double off2 = r1 / g->cx; cairo_pattern_add_color_stop_rgb(pat, off1, R, G, B); if(g->gradient) { cairo_pattern_add_color_stop_rgb(pat, off2, R * 0.6, G * 0.6, B * 0.6); } cairo_set_source(cr, pat); cairo_fill(cr); cairo_pattern_destroy(pat); } if(L != 0.0) { cairo_set_line_width(cr, 0.5); cairo_set_source_rgba(cr, L, L, L, 0.9); cairo_stroke(cr); } } void br_cairo_done(duc_graph *g) { struct cairo_backend_data *bd = g->backend_data; cairo_t *cr = bd->cr; cairo_restore(cr); } void br_file_done(duc_graph *g) { struct cairo_backend_data *bd = g->backend_data; switch(bd->fmt) { case DUC_GRAPH_FORMAT_PNG: cairo_surface_write_to_png_stream(bd->cs, cairo_writer, bd->fout); break; default: break; } cairo_destroy(bd->cr); cairo_surface_destroy(bd->cs); } static void br_cairo_free(duc_graph *g) { struct cairo_backend_data *bd = g->backend_data; free(bd); } struct duc_graph_backend duc_graph_backend_cairo = { .start = br_cairo_start, .draw_text = br_cairo_draw_text, .draw_tooltip = br_cairo_draw_tooltip, .draw_section = br_cairo_draw_section, .done = br_cairo_done, .free = br_cairo_free, }; struct duc_graph_backend duc_graph_backend_file = { .start = br_file_start, .draw_text = br_cairo_draw_text, .draw_tooltip = br_cairo_draw_tooltip, .draw_section = br_cairo_draw_section, .done = br_file_done, .free = br_cairo_free, }; duc_graph *duc_graph_new_cairo(duc *duc, cairo_t *cr) { duc_graph *g = duc_graph_new(duc); g->backend = &duc_graph_backend_cairo; struct cairo_backend_data *bd; bd = duc_malloc(sizeof *bd); g->backend_data = bd; bd->cr = cr; return g; } duc_graph *duc_graph_new_cairo_file(duc *duc, duc_graph_file_format fmt, FILE *fout) { duc_graph *g = duc_graph_new(duc); g->backend = &duc_graph_backend_file; struct cairo_backend_data *bd; bd = duc_malloc(sizeof *bd); g->backend_data = bd; bd->fmt = fmt; bd->fout = fout; return g; } #endif /* * End */ zevv-duc-b8f9659/src/libduc-graph/graph-html.c000066400000000000000000000115001426703022500211700ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "private.h" #include "duc.h" #include "duc-graph.h" #include "graph-private.h" #include "utlist.h" struct html_backend_data { FILE *fout; int write_body; }; void br_html_start(duc_graph *g) { struct html_backend_data *bd = g->backend_data; FILE *f = bd->fout; if(bd->write_body) { fprintf(f, "\n"); fprintf(f, "\n"); fprintf(f, "\n"); } fprintf(f, "\n", g->width, g->height); fprintf(f, "Your browser does not support the HTML5 canvas tag.\n"); fprintf(f, "\n"); fprintf(f, "\n"); if(bd->write_body) { fprintf(f, "\n"); } } static void br_html_free(duc_graph *g) { } struct duc_graph_backend duc_graph_backend_html = { .start = br_html_start, .draw_text = br_html_draw_text, .draw_tooltip = br_html_draw_tooltip, .draw_section = br_html_draw_section, .done = br_html_done, .free = br_html_free, }; duc_graph *duc_graph_new_html(duc *duc, FILE *fout, int write_body) { duc_graph *g = duc_graph_new(duc); g->backend = &duc_graph_backend_html; struct html_backend_data *bd; bd = duc_malloc(sizeof *bd); g->backend_data = bd; bd->fout = fout; bd->write_body = write_body; return g; } /* * End */ zevv-duc-b8f9659/src/libduc-graph/graph-opengl.c000066400000000000000000000233111426703022500215130ustar00rootroot00000000000000// http://nothings.org/stb/font/latin_ext/ #include "config.h" #ifdef ENABLE_OPENGL #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "private.h" #include "duc.h" #include "duc-graph.h" #include "graph-private.h" #include "utlist.h" #include "font.c" struct opengl_backend_data { GLuint sp; stb_fontchar fontdata[STB_SOMEFONT_NUM_CHARS]; GLuint font_texid; double font_scale; GLuint loc_pos; GLuint loc_texture; GLuint loc_sampler; GLuint loc_matrix; GLuint loc_color; }; static const GLchar *vshader = "uniform mat4 matrix;\n" "attribute vec4 pos_in;\n" "attribute vec2 tex_in;\n" "attribute vec4 color_in;\n" "varying vec2 tex_out;\n" "varying vec4 color;\n" "void main()\n" "{\n" " gl_Position = matrix * pos_in;\n" " tex_out = tex_in;\n" " color = color_in;\n" "}\n"; static const GLchar *fshader = "uniform sampler2D Texture;\n" "varying vec4 color;\n" "varying vec2 tex_out;\n" "void main()\n" "{\n" " gl_FragColor = color + texture2D(Texture, tex_out);\n" "}\n"; void br_opengl_start(duc_graph *g) { struct opengl_backend_data *bd = g->backend_data; GLuint sp = bd->sp; glUseProgram(sp); GLfloat mv[] = { 1 / g->width*2, 0, 0, 0, 0, -1/g->height*2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; glUniformMatrix4fv(bd->loc_matrix, 1, 0, mv); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); } static double draw_char(duc_graph *g, double x, double y, double size, int c) { struct opengl_backend_data *bd = g->backend_data; if(c < STB_SOMEFONT_FIRST_CHAR || c >= STB_SOMEFONT_FIRST_CHAR + STB_SOMEFONT_NUM_CHARS) return 0; stb_fontchar *cd = &bd->fontdata[c - STB_SOMEFONT_FIRST_CHAR]; double f = size * bd->font_scale; y += f * STB_SOMEFONT_LINE_SPACING * 0.2; GLfloat vVertices[] = { x + cd->x0f * f, y + cd->y0f * f, cd->s0f, cd->t0f, x + cd->x1f * f, y + cd->y0f * f, cd->s1f, cd->t0f, x + cd->x1f * f, y + cd->y1f * f, cd->s1f, cd->t1f, x + cd->x0f * f, y + cd->y1f * f, cd->s0f, cd->t1f, }; GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; glVertexAttribPointer(bd->loc_pos, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), &vVertices[0]); glVertexAttribPointer(bd->loc_texture, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), &vVertices[2]); glEnableVertexAttribArray(bd->loc_pos); glEnableVertexAttribArray(bd->loc_texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, bd->font_texid); glUniform1i(bd->loc_texture, 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); return cd->advance * size * bd->font_scale; } static void text_size(duc_graph *g, char *text, double *w, double *h, double size) { struct opengl_backend_data *bd = g->backend_data; char *p = text; double wmax = 0; *w = *h = 0; while(*p) { int c = *p++; if(c == '\r' || c == '\n') { *h += (int)(size * bd->font_scale * STB_SOMEFONT_LINE_SPACING * 1.5); wmax = 0; } else { stb_fontchar *cd = &bd->fontdata[c - STB_SOMEFONT_FIRST_CHAR]; wmax += size * bd->font_scale * cd->advance; if(wmax > *w) *w = wmax; } } } static void draw_text_line(duc_graph *g, double x, double y, double size, char *text, int l) { int i; for(i=0; ibackend_data; double x = _x - g->cx; double y = _y - g->cy - size * bd->font_scale * STB_SOMEFONT_LINE_SPACING; glDisableVertexAttribArray(bd->loc_color); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); char *p1 = text; char *p2 = text; while(*p2) { while(*p2 && *p2 != '\n' && *p2 != '\r') { p2++; } glVertexAttrib4f(bd->loc_color, 1, 1, 1, 0); draw_text_line(g, x-1, y+0, size, p1, p2-p1); draw_text_line(g, x+1, y-0, size, p1, p2-p1); draw_text_line(g, x-0, y+1, size, p1, p2-p1); draw_text_line(g, x+0, y-1, size, p1, p2-p1); glVertexAttrib4f(bd->loc_color, 0, 0, 0, 0); draw_text_line(g, x+0, y, size, p1, p2-p1); if(!*p2) break; y += size * bd->font_scale * STB_SOMEFONT_LINE_SPACING * 1.5; x = _x - g->cx; p2 ++; p1 = p2; } glBlendFunc(GL_ONE, GL_ZERO); } static void br_opengl_draw_text(duc_graph *g, double x, double y, double size, char *text) { double w, h; text_size(g, text, &w, &h, size); draw_text(g, x - w/2, y - h/2, size, text); } static void br_opengl_draw_tooltip(duc_graph *g, double x, double y, char *text) { struct opengl_backend_data *bd = g->backend_data; double w, h; text_size(g, text, &w, &h, FONT_SIZE_TOOLTIP); GLfloat vVertices[] = { x - g->cx - w - 10, y - g->cy - h - 15, x - g->cx , y - g->cy - h - 15, x - g->cx , y - g->cy , x - g->cx - w - 10, y - g->cy , }; glVertexAttribPointer(bd->loc_pos, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), &vVertices[0]); glDisableVertexAttribArray(bd->loc_color); glDisableVertexAttribArray(bd->loc_texture); glVertexAttrib4f(bd->loc_color, 1, 1, 1, 0); GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); glVertexAttrib4f(bd->loc_color, 0, 0, 0, 0); glDrawArrays(GL_LINE_LOOP, 0, 4); draw_text(g, x - w - 5, y - h - 5, FONT_SIZE_TOOLTIP, text); } static void br_opengl_draw_section(duc_graph *g, double a1, double a2, double r1, double r2, double R, double G, double B, double L) { struct opengl_backend_data *bd = g->backend_data; int i; a1 *= M_PI * 2; a2 *= M_PI * 2; int ss = (int)((a2 - a1) * r2 / 10 + 2); GLfloat vs_fill[ss * 2][6]; GLfloat vs_line[ss * 2][2]; double da = (a2-a1) / (ss-1); for(i=0; igradient ? 0.7 : 1.0); vs_fill[i*2 + 0][3] = G * (g->gradient ? 0.7 : 1.0); vs_fill[i*2 + 0][4] = B * (g->gradient ? 0.7 : 1.0); vs_fill[i*2 + 0][5] = 0; vs_fill[i*2 + 1][0] = x2; vs_fill[i*2 + 1][1] = y2; vs_fill[i*2 + 1][2] = R; vs_fill[i*2 + 1][3] = G; vs_fill[i*2 + 1][4] = B; vs_fill[i*2 + 1][5] = 0; vs_line[i][0] = x1; vs_line[i][1] = y1; vs_line[2*ss-i-1][0] = x2; vs_line[2*ss-i-1][1] = y2; } glDisable(GL_TEXTURE_2D); if(R != 1.0 || G != 1.0 || B != 1.0) { glEnableVertexAttribArray(bd->loc_pos); glEnableVertexAttribArray(bd->loc_color); glVertexAttribPointer(bd->loc_pos, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), &vs_fill[0][0]); glVertexAttribPointer(bd->loc_color, 4, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), &vs_fill[0][2]); glDrawArrays(GL_TRIANGLE_STRIP, 0, ss*2); } if(L != 0.0) { glLineWidth(0.8); glDisableVertexAttribArray(bd->loc_color); glVertexAttrib4f(bd->loc_color, L, L, L, 0); glVertexAttribPointer(bd->loc_pos, 2, GL_FLOAT, GL_FALSE, 0, vs_line); glDrawArrays(GL_LINE_LOOP, 0, ss*2); } } static GLuint load_shader(const GLchar **txt, GLenum type) { GLuint s; s = glCreateShader(type); glShaderSource(s, 1, txt, NULL); glCompileShader(s); GLint ok; GLchar err[512]; glGetShaderiv(s, GL_COMPILE_STATUS, &ok); if(!ok) { glGetShaderInfoLog(s, sizeof(err), NULL, err); printf("shader compile error: %s\n", err); } return s; } static GLuint shaders(void) { /* Load and link shaders */ GLuint vs = load_shader(&vshader, GL_VERTEX_SHADER); GLuint fs = load_shader(&fshader, GL_FRAGMENT_SHADER); GLuint sp = glCreateProgram(); glAttachShader(sp, vs); glAttachShader(sp, fs); glLinkProgram(sp); GLint ok; GLchar err[512]; glGetProgramiv(sp, GL_LINK_STATUS, &ok); if(!ok) { glGetProgramInfoLog(sp, sizeof(err), NULL, err); glGetShaderInfoLog(sp, 512, NULL, err); printf("shader link error: %s\n", err); } glDeleteShader(vs); glDeleteShader(fs); return sp; } void br_opengl_done(duc_graph *g) { } static void br_opengl_free(duc_graph *g) { } struct duc_graph_backend duc_graph_backend_opengl = { .start = br_opengl_start, .draw_text = br_opengl_draw_text, .draw_tooltip = br_opengl_draw_tooltip, .draw_section = br_opengl_draw_section, .done = br_opengl_done, .free = br_opengl_free, }; duc_graph *duc_graph_new_opengl(duc *duc, double font_scale) { duc_graph *g = duc_graph_new(duc); g->backend = &duc_graph_backend_opengl; struct opengl_backend_data *bd; bd = duc_malloc(sizeof *bd); g->backend_data = bd; font_scale = 1; bd->sp = shaders(); bd->loc_pos = glGetAttribLocation(bd->sp, "pos_in"); bd->loc_texture = glGetAttribLocation(bd->sp, "tex_in"); bd->loc_color = glGetAttribLocation(bd->sp, "color_in"); bd->loc_sampler = glGetUniformLocation(bd->sp, "Texture"); bd->loc_matrix = glGetUniformLocation(bd->sp, "matrix"); bd->font_scale = font_scale / STB_SOMEFONT_LINE_SPACING; unsigned char fontpixels[STB_SOMEFONT_BITMAP_HEIGHT][STB_SOMEFONT_BITMAP_WIDTH]; STB_SOMEFONT_CREATE(bd->fontdata, fontpixels, STB_SOMEFONT_BITMAP_HEIGHT); glGenTextures(1, &bd->font_texid); glBindTexture(GL_TEXTURE_2D, bd->font_texid); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, STB_SOMEFONT_BITMAP_WIDTH, STB_SOMEFONT_BITMAP_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, fontpixels ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glGenerateMipmap(GL_TEXTURE_2D); return g; } #endif /* * End */ zevv-duc-b8f9659/src/libduc-graph/graph-private.h000066400000000000000000000027451426703022500217160ustar00rootroot00000000000000 #ifndef graph_private_h #define graph_private_h #include "duc-graph.h" #define FONT_SIZE_LABEL 8 #define FONT_SIZE_TOOLTIP 8 #define FONT_SIZE_CENTER 14 struct label { double x, y; char *text; struct label *next; }; struct duc_graph_backend { void (*free)(duc_graph *g); void (*start)(duc_graph *g); void (*draw_tooltip)(duc_graph *g, double x, double y, char *text); void (*draw_section)(duc_graph *g, double a1, double a2, double r1, double r2, double R, double G, double B, double line); void (*draw_text)(duc_graph *g, double x, double y, double size, char *text); void (*done)(duc_graph *g); }; struct duc_graph { /* Settings */ struct duc *duc; double size; double dpi; double font_scale; double cx, cy; double pos_x, pos_y; double width, height; double tooltip_a, tooltip_r; double tooltip_x, tooltip_y; char tooltip_msg[DUC_PATH_MAX+256]; double r_start; double fuzz; int max_level; enum duc_graph_palette palette; size_t max_name_len; duc_size_type size_type; int bytes; int ring_gap; int gradient; /* format */ /* Reusable runtime info. Cleared after each graph_draw_* call */ struct label *label_list; double spot_a; double spot_r; duc_dir *spot_dir; struct duc_dirent *spot_ent; struct duc_graph_backend *backend; void *backend_data; }; duc_graph *duc_graph_new(duc *duc); double ang(double a); void pol2car(duc_graph *g, double a, double r, double *x, double *y); void car2pol(duc_graph *g, double x, double y, double *a, double *r); #endif zevv-duc-b8f9659/src/libduc-graph/graph-svg.c000066400000000000000000000110541426703022500210270ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "private.h" #include "duc.h" #include "duc-graph.h" #include "graph-private.h" #include "utlist.h" struct svg_backend_data { FILE *fout; int gid; }; void br_svg_start(duc_graph *g) { struct svg_backend_data *bd = g->backend_data; FILE *f = bd->fout; fprintf(f, "\n"); fprintf(f, "\n"); fprintf(f, "width, g->height); fprintf(f, " xmlns='http://www.w3.org/2000/svg'\n"); fprintf(f, " xmlns:xlink='http://www.w3.org/1999/xlink'>\n"); fprintf(f, " \n"); } static void draw_text_aux(int x, const char *s, FILE *f) { char *p = strdup(s); assert(p); double y = 0; char *l = strtok(p, "\n"); while(l != NULL) { fprintf(f, " ", x, y); while(*l) { switch(*l) { case '<': fprintf(f, "<"); break; case '>': fprintf(f, ">"); break; case '&': fprintf(f, "&"); break; case '"': fprintf(f, """); break; default: fputc(*l, f); break; } l++; } fprintf(f, "\n"); y += 1.2; l = strtok(NULL, "\n"); } free(p); } static void br_svg_draw_text(duc_graph *g, double x, double y, double size, char *text) { struct svg_backend_data *bd = g->backend_data; FILE *f = bd->fout; fprintf(f, "\n", x, y, size); draw_text_aux(x, text, f); fprintf(f, "\n"); fprintf(f, "\n", x, y, size); draw_text_aux(x, text, f); fprintf(f, "\n"); } static void br_svg_draw_tooltip(duc_graph *g, double x, double y, char *text) { } static void br_svg_draw_section(duc_graph *g, double a1, double a2, double r1, double r2, double R, double G, double B, double L) { struct svg_backend_data *bd = g->backend_data; FILE *f = bd->fout; if(g->gradient) { fprintf(f, "\n"); fprintf(f, " \n", bd->gid, g->cx, g->cy, r2); fprintf(f, " \n", 100*r1/r2, (int)(R*156), (int)(G*156), (int)(B*156)); fprintf(f, " \n", (int)(R*255), (int)(G*255), (int)(B*255)); fprintf(f, " \n"); fprintf(f, "\n"); fprintf(f, "gid); bd->gid++; } else { fprintf(f, " 0.5; fprintf(f, "d='"); fprintf(f, "M%.0f,%.0f ", g->cx + r1 * sin(a1 * M_PI*2), g->cy - r1 * cos(a1 * M_PI*2)); fprintf(f, "L%.0f,%.0f ", g->cx + r2 * sin(a1 * M_PI*2), g->cy - r2 * cos(a1 * M_PI*2)); fprintf(f, "A %.0f %.0f 0 %d 1 %.0f %.0f ", r2, r2, large, g->cx + r2 * sin(a2 * M_PI*2), g->cy - r2 * cos(a2 * M_PI*2)); fprintf(f, "L%.0f,%.0f ", g->cx + r1 * sin(a2 * M_PI*2), g->cy - r1 * cos(a2 * M_PI*2)); fprintf(f, "A %.0f %.0f 0 %d 0 %.0f %.0f ", r1, r1, large, g->cx + r1 * sin(a1 * M_PI*2), g->cy - r1 * cos(a1 * M_PI*2)); fprintf(f, "'/>\n"); } void br_svg_done(duc_graph *g) { struct svg_backend_data *bd = g->backend_data; FILE *f = bd->fout; fprintf(f, "\n"); } static void br_svg_free(duc_graph *g) { } struct duc_graph_backend duc_graph_backend_svg = { .start = br_svg_start, .draw_text = br_svg_draw_text, .draw_tooltip = br_svg_draw_tooltip, .draw_section = br_svg_draw_section, .done = br_svg_done, .free = br_svg_free, }; duc_graph *duc_graph_new_svg(duc *duc, FILE *fout) { duc_graph *g = duc_graph_new(duc); g->backend = &duc_graph_backend_svg; struct svg_backend_data *bd; bd = duc_malloc(sizeof *bd); g->backend_data = bd; bd->fout = fout; bd->gid = 0; return g; } /* * End */ zevv-duc-b8f9659/src/libduc-graph/graph.c000066400000000000000000000245621426703022500202420ustar00rootroot00000000000000#include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "private.h" #include "duc.h" #include "duc-graph.h" #include "utlist.h" #include "graph-private.h" duc_graph *duc_graph_new(duc *duc) { duc_graph *g; g = duc_malloc0(sizeof *g); g->duc = duc; g->r_start = 100; g->fuzz = 0; duc_graph_set_dpi(g, 96); duc_graph_set_max_level(g, 3); duc_graph_set_size(g, 400, 400); return g; } void duc_graph_free(duc_graph *g) { if(g->backend) g->backend->free(g); free(g); } void duc_graph_set_max_level(duc_graph *g, int max_level) { g->max_level = max_level; } void duc_graph_set_max_name_len(duc_graph *g, size_t len) { g->max_name_len = len; } void duc_graph_set_size(duc_graph *g, int w, int h) { g->width = w; g->height = h; } void duc_graph_set_dpi(duc_graph *g, double dpi) { g->dpi = dpi; g->font_scale = dpi / 96.0; } void duc_graph_set_position(duc_graph *g, double pos_x, double pos_y) { g->pos_x = pos_x; g->pos_y = pos_y; } void duc_graph_set_tooltip(duc_graph *g, double x, double y) { g->tooltip_x = x; g->tooltip_y = y; } void duc_graph_set_palette(duc_graph *g, enum duc_graph_palette p) { g->palette = p; } void duc_graph_set_fuzz(duc_graph *g, double fuzz) { g->fuzz = fuzz; } void duc_graph_set_size_type(duc_graph *g, duc_size_type st) { g->size_type = st; } void duc_graph_set_exact_bytes(duc_graph *g, int exact) { g->bytes = exact; } void duc_graph_set_ring_gap(duc_graph *g, int gap) { g->ring_gap = gap; } void duc_graph_set_gradient(duc_graph *g, int onoff) { g->gradient = onoff; } void pol2car(duc_graph *g, double a, double r, double *x, double *y) { *x = cos(a) * r + g->cx; *y = sin(a) * r + g->cy; } void car2pol(duc_graph *g, double x, double y, double *a, double *r) { x -= g->cx; y -= g->cy; *r = hypot(y, x); *a = atan2(x, -y) / (M_PI*2); if(*a < 0) *a += 1; } static void shorten_name(char *label, size_t maxlen) { if(maxlen == 0) return; size_t n = strlen(label); if(n < maxlen) return; size_t cut1 = maxlen/2; size_t cut2 = n - maxlen/2; for(; cut1>5; cut1--) if(!isalnum(label[cut1])) break; for(; cut2 cut1 && cut1 + n - cut2 + 3 <= n) { label[cut1++] = '.'; label[cut1++] = '.'; label[cut1++] = '.'; memmove(label+cut1, label+cut2+1, n-cut2); } } static void hsv2rgb(double h, double s, double v, double *r, double *g, double *b) { double f, m, n; int i; h *= 6.0; i = (int)floor(h); f = (h) - i; if (!(i & 1)) f = 1 - f; m = v * (1 - s); n = v * (1 - s * f); if(i<0) i=0; if(i>6) i=6; switch (i) { case 6: case 0: *r=v; *g=n, *b=m; break; case 1: *r=n; *g=v, *b=m; break; case 2: *r=m; *g=v, *b=n; break; case 3: *r=m; *g=n, *b=v; break; case 4: *r=n; *g=m, *b=v; break; case 5: *r=v; *g=m, *b=n; break; default: *r=*g=*b=1; } } double ang(double a) { return -M_PI * 0.5 + M_PI * 2 * a; } static void gen_tooltip(duc_graph *g, struct duc_size *size, const char *name, duc_file_type type) { char siz_app[32], siz_act[32], siz_cnt[32]; duc_human_size(size, DUC_SIZE_TYPE_APPARENT, g->bytes, siz_app, sizeof siz_app); duc_human_size(size, DUC_SIZE_TYPE_ACTUAL, g->bytes, siz_act, sizeof siz_act); duc_human_size(size, DUC_SIZE_TYPE_COUNT, g->bytes, siz_cnt, sizeof siz_cnt); char *typ = duc_file_type_name(type); char *p = g->tooltip_msg; int l = sizeof(g->tooltip_msg); if(name) { p += snprintf(p, l, "name: %s\n", name); } p += snprintf(p, l, "type: %s\n" "actual size: %s\n" "apparent size: %s\n" "file count: %s", typ, siz_act, siz_app, siz_cnt); } /* * This function has two purposes: * * - If a backend is provided, a graph will be drawn on that context * - if spot_a and spot_r are defined, it will find the path on the graph * that is below that spot */ static int do_dir(duc_graph *g, duc_dir *dir, int level, double r1, double a1_dir, double a2_dir, struct duc_size *total) { double a_range = a2_dir - a1_dir; double a1 = a1_dir; double a2 = a1_dir; double ring_width = (g->size/2 - g->r_start - 30) / g->max_level; /* Calculate max and total size */ struct duc_size tmp; off_t size_total; if(total) { tmp = *total; } else { duc_dir_get_size(dir, &tmp); } size_total = duc_get_size(&tmp, g->size_type); if(size_total == 0) return 0; struct duc_dirent *e; off_t size_min = size_total; off_t size_max = 0; while( (e = duc_dir_read(dir, g->size_type, DUC_SORT_SIZE)) != NULL) { off_t size = duc_get_size(&e->size, g->size_type); if(size < size_min) size_min = size; if(size > size_max) size_max = size; } /* Rewind and iterate the objects to graph */ duc_dir_rewind(dir); while( (e = duc_dir_read(dir, g->size_type, DUC_SORT_SIZE)) != NULL) { /* size_rel is size relative to total, size_nrel is size relative to min and max */ off_t size = duc_get_size(&e->size, g->size_type); double size_rel = (double)size / size_total; double size_nrel = (size_max - size_min) ? ((double)size - size_min) / (size_max - size_min) : 1; double r2 = r1 + ring_width * (1 - (1 - size_nrel) * g->fuzz); a2 += a_range * size_rel; /* Skip any segments that would be smaller then one pixel */ if(r2 * (a2 - a1) * M_PI * 2 < 1) break; if(a2 <= a1) break; /* Determine section color */ double H = 0; double S = 0; double V = 0; double L = 0; switch(g->palette) { case DUC_GRAPH_PALETTE_SIZE: H = 0.8 - 0.7 * size_nrel - 0.1 * size_rel; S = 1.0 - 0.8 *(double)level / g->max_level; V = 1; L = 0; break; case DUC_GRAPH_PALETTE_RAINBOW: H = (a1 + a2) / 2; S = 1.0 - 0.8 *(double)level / g->max_level; V = 1; L = 0; break; case DUC_GRAPH_PALETTE_GREYSCALE: H = 0; S = 0; V = 1.0 - 0.5 * size_nrel; L = 0; break; case DUC_GRAPH_PALETTE_MONOCHROME: H = 0; S = 0; V = 1; L = 0.01; break; case DUC_GRAPH_PALETTE_CLASSIC: H = (a1 + a2) / 2 + 0.75; if(H > 1.0) H -= 1.0; S = 1.0 - 0.8 *(double)level / g->max_level; V = 1; L = 0.8; break; } double R, G, B; hsv2rgb(H, S, V, &R, &G, &B); if(e->type != DUC_FILE_TYPE_DIR) S *= 0.5; /* Check if the tooltip lies within this section */ { double a = g->tooltip_a; double r = g->tooltip_r; if(a >= a1 && a < a2 && r >= r1 && r < r2) { V -= 0.7; gen_tooltip(g, &e->size, e->name, e->type); } } /* Check if the requested spot lies in this section */ if(g->spot_r > 0) { double a = g->spot_a; double r = g->spot_r; if(a >= a1 && a < a2 && r >= r1 && r < r2) { g->spot_ent = duc_malloc(sizeof *g->spot_ent); *g->spot_ent = *e; g->spot_ent->name = duc_strdup(e->name); if(e->type == DUC_FILE_TYPE_DIR) g->spot_dir = duc_dir_openent(dir, e); } } if(e->type == DUC_FILE_TYPE_DIR) { /* Recurse into subdirectories */ if(level+1 < g->max_level) { duc_dir *dir_child = duc_dir_openent(dir, e); if(!dir_child) continue; do_dir(g, dir_child, level + 1, r2, a1, a2, &e->size); duc_dir_close(dir_child); } else { if(g->backend) g->backend->draw_section(g, a1, a2, r2+2, r2+8, R*0.5, G*0.5, B*0.5, L); } } /* Place labels if there is enough room to display */ if(g->backend) { double area = (r2 - r1) * (a2 - a1); if(area > 1.5) { struct label *label = duc_malloc(sizeof *label); char siz[16]; duc_human_size(&e->size, g->size_type, g->bytes, siz, sizeof siz); char *name = duc_strdup(e->name); shorten_name(name, g->max_name_len); pol2car(g, ang((a1+a2)/2), (r1+r2)/2, &label->x, &label->y); int r = asprintf(&label->text, "%s\n%s", name, siz); if (r < 0) { label->text = "\0"; } LL_APPEND(g->label_list, label); free(name); } } /* Draw section for this object */ if(g->backend) { g->backend->draw_section(g, a1, a2, r1, r2 - g->ring_gap, R, G, B, L); } a1 = a2; } return 0; } int duc_graph_draw(duc_graph *g, duc_dir *dir) { double n = g->width < g->height ? g->width : g->height; g->size = n; g->cx = g->width / 2; g->cy = g->height / 2; g->r_start = g->size / 10; /* Convert tooltip xy to polar coords */ double tooltip_x = g->tooltip_x - g->pos_x; double tooltip_y = g->tooltip_y - g->pos_y; g->tooltip_msg[0] = '\0'; car2pol(g, tooltip_x, tooltip_y, &g->tooltip_a, &g->tooltip_r); /* Recursively draw graph */ duc_dir_rewind(dir); if(g->backend) g->backend->start(g); do_dir(g, dir, 0, g->r_start, 0, 1, NULL); /* Draw collected labels */ struct label *l, *ln; LL_FOREACH_SAFE(g->label_list, l, ln) { if(g->backend) g->backend->draw_text(g, (int)l->x, (int)l->y, FONT_SIZE_LABEL * g->font_scale, l->text); free(l->text); free(l); } char *p = duc_dir_get_path(dir); if(g->backend) g->backend->draw_text(g, (int)g->cx, 10, FONT_SIZE_LABEL * g->font_scale, p); free(p); struct duc_size size; duc_dir_get_size(dir, &size); char siz[16]; duc_human_size(&size, g->size_type, g->bytes, siz, sizeof siz); if(g->backend) g->backend->draw_text(g, (int)g->cx, (int)g->cy, FONT_SIZE_CENTER * g->font_scale, siz); if(g->tooltip_r < g->r_start) { gen_tooltip(g, &size, NULL, DUC_FILE_TYPE_DIR); } /* Draw tooltip */ if(g->tooltip_msg[0]) { g->backend->draw_tooltip(g, (int)tooltip_x, (int)tooltip_y, g->tooltip_msg); } g->label_list = NULL; if(g->backend) g->backend->done(g); return 0; } duc_dir *duc_graph_find_spot(duc_graph *g, duc_dir *dir, double x, double y, struct duc_dirent **ent) { duc_dir *dir2 = NULL; double n = g->width < g->height ? g->width : g->height; g->size = n; g->cx = g->width / 2; g->cy = g->height / 2; g->r_start = g->size / 10; x -= (int)g->pos_x; y -= (int)g->pos_y; car2pol(g, x, y, &g->spot_a, &g->spot_r); if(g->spot_r < g->r_start) { /* If clicked in the center, go up one directory */ dir2 = duc_dir_openat(dir, ".."); } else { /* Find directory at position x,y */ g->spot_dir = NULL; duc_dir_rewind(dir); struct duc_graph_backend *be = g->backend; g->backend = NULL; do_dir(g, dir, 0, g->r_start, 0, 1, NULL); g->backend = be; g->spot_a = 0; g->spot_r = 0; if(ent) *ent = g->spot_ent; dir2 = g->spot_dir; } return dir2; } /* * End */ zevv-duc-b8f9659/src/libduc/000077500000000000000000000000001426703022500156655ustar00rootroot00000000000000zevv-duc-b8f9659/src/libduc/buffer.c000066400000000000000000000112731426703022500173060ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include "private.h" #include "buffer.h" #include "varint.h" /* * Generic buffer manipulation for serialization */ struct buffer *buffer_new(void *data, size_t len) { struct buffer *b; b = duc_malloc(sizeof(struct buffer)); b->ptr = 0; if(data) { b->max = len; b->len = len; b->data = data; } else { b->max = 1024; b->len = 0; b->data = duc_malloc(b->max); } return b; } void buffer_free(struct buffer *b) { duc_free(b->data); duc_free(b); } static int buffer_put(struct buffer *b, const void *data, size_t len) { if(b->ptr + len > b->max) { while(b->len + len > b->max) { b->max *= 2; } b->data = duc_realloc(b->data, b->max); } memcpy(b->data + b->ptr, data, len); b->ptr += len; if(b->ptr > b->len) b->len = b->ptr; return len; } static int buffer_get(struct buffer *b, void *data, size_t len) { if(b->ptr <= b->len - len) { memcpy(data, b->data + b->ptr, len); b->ptr += len; return len; } else { return 0; } } static int buffer_put_varint(struct buffer *b, uint64_t v) { uint8_t buf[9]; int l = PutVarint64(buf, v); buffer_put(b, buf, l); return l; } static int buffer_get_varint(struct buffer *b, uint64_t *v) { uint8_t buf[9]; int r = buffer_get(b, buf, 1); if(r == 0) return 0; int n = 0; if(buf[0] >= 249) { n = buf[0] - 247; } else if(buf[0] >= 241) { n = 1; } if(n > 0) buffer_get(b, buf+1, n); int l = GetVarint64(buf, n+1, v); return l; } static void buffer_put_string(struct buffer *b, const char *s) { size_t len = strlen(s); if(len < 256) { uint8_t l = len; buffer_put(b, &l, sizeof l); buffer_put(b, s, l); } } static void buffer_get_string(struct buffer *b, char **sout) { uint8_t len; buffer_get(b, &len, sizeof len); char *s = duc_malloc(len + 1); if(s) { buffer_get(b, s, len); s[len] = '\0'; *sout = s; } } static void buffer_put_devino(struct buffer *b, const struct duc_devino *devino) { buffer_put_varint(b, devino->dev); buffer_put_varint(b, devino->ino); } static void buffer_get_devino(struct buffer *b, struct duc_devino *devino) { uint64_t v; buffer_get_varint(b, &v); devino->dev = v; buffer_get_varint(b, &v); devino->ino = v; } static void buffer_put_size(struct buffer *b, const struct duc_size *size) { buffer_put_varint(b, size->apparent); buffer_put_varint(b, size->actual); buffer_put_varint(b, size->count); } static void buffer_get_size(struct buffer *b, struct duc_size *size) { uint64_t v; buffer_get_varint(b, &v); size->apparent = v; buffer_get_varint(b, &v); size->actual = v; buffer_get_varint(b, &v); size->count = v; } /* * Serialize data from structs into buffer */ void buffer_put_dir(struct buffer *b, const struct duc_devino *devino, time_t mtime) { buffer_put_devino(b, devino); buffer_put_varint(b, mtime); } void buffer_get_dir(struct buffer *b, struct duc_devino *devino, time_t *mtime) { uint64_t v; buffer_get_devino(b, devino); buffer_get_varint(b, &v); *mtime = v; } void buffer_put_dirent(struct buffer *b, const struct duc_dirent *ent) { buffer_put_string(b, ent->name); buffer_put_size(b, &ent->size); buffer_put_varint(b, ent->type); if(ent->type == DUC_FILE_TYPE_DIR) { buffer_put_devino(b, &ent->devino); } } void buffer_get_dirent(struct buffer *b, struct duc_dirent *ent) { uint64_t v; buffer_get_string(b, &ent->name); buffer_get_size(b, &ent->size); buffer_get_varint(b, &v); ent->type = v; if(ent->type == DUC_FILE_TYPE_DIR) { buffer_get_devino(b, &ent->devino); } } void buffer_put_index_report(struct buffer *b, const struct duc_index_report *report) { buffer_put_string(b, report->path); buffer_put_devino(b, &report->devino); buffer_put_varint(b, report->time_start.tv_sec); buffer_put_varint(b, report->time_start.tv_usec); buffer_put_varint(b, report->time_stop.tv_sec); buffer_put_varint(b, report->time_stop.tv_usec); buffer_put_varint(b, report->file_count); buffer_put_varint(b, report->dir_count); buffer_put_size(b, &report->size); } void buffer_get_index_report(struct buffer *b, struct duc_index_report *report) { char *vs = NULL; buffer_get_string(b, &vs); if(vs == NULL) return; snprintf(report->path, sizeof(report->path), "%s", vs); duc_free(vs); uint64_t vi; buffer_get_devino(b, &report->devino); buffer_get_varint(b, &vi); report->time_start.tv_sec = vi; buffer_get_varint(b, &vi); report->time_start.tv_usec = vi; buffer_get_varint(b, &vi); report->time_stop.tv_sec = vi; buffer_get_varint(b, &vi); report->time_stop.tv_usec = vi; buffer_get_varint(b, &vi); report->file_count = vi; buffer_get_varint(b, &vi); report->dir_count = vi; buffer_get_size(b, &report->size); } /* * End */ zevv-duc-b8f9659/src/libduc/buffer.h000066400000000000000000000012511426703022500173060ustar00rootroot00000000000000#ifndef buffer_h #define buffer_h struct buffer { uint8_t *data; size_t max; size_t len; size_t ptr; }; struct buffer *buffer_new(void *data, size_t len); void buffer_free(struct buffer *b); void buffer_put_dir(struct buffer *b, const struct duc_devino *devino, time_t mtime); void buffer_get_dir(struct buffer *b, struct duc_devino *devino, time_t *mtime); void buffer_put_dirent(struct buffer *b, const struct duc_dirent *ent); void buffer_get_dirent(struct buffer *b, struct duc_dirent *ent); void buffer_put_index_report(struct buffer *b, const struct duc_index_report *report); void buffer_get_index_report(struct buffer *b, struct duc_index_report *report); #endif zevv-duc-b8f9659/src/libduc/canonicalize.c000066400000000000000000000111551426703022500204730ustar00rootroot00000000000000 /* * idea stolen from https://raw.githubusercontent.com/duanev/path-canon-c/master/pathcanon.c */ #include "config.h" #include #include #include #include #include #include #include "private.h" #include "utstring.h" #ifdef TEST /* gcc -Wall -Werror -I. -DTEST -g src/libduc/canonicalize.c && valgrind --quiet --leak-check=full ./a.out x86_64-w64-mingw32-gcc -Wall -Werror -I. -DTEST -g src/libduc/canonicalize.c && wine64 ./a.exe */ #define duc_malloc malloc #define duc_malloc0(n) calloc(n, 1) #define duc_strdup strdup #define duc_free free char *test[][2] = { /* absolute unix paths */ { "/", "/" }, { "//", "/" }, { "/home/ico", "/home/ico" }, { "/home/ico/", "/home/ico" }, { "//home/ico/", "/home/ico" }, { "//home///ico/", "/home/ico" }, { "/home/ico/..", "/home" }, { "/home/ico/../ico", "/home/ico" }, { "/home/ico/../..", "/" }, { "/home/./ico", "/home/ico" }, { "/../..", "/" }, { "//d/./e/.././o/f/g/./h/../../..//./n/././e/./i/..///", "/d/o/n/e" }, /* absolute windows paths */ { "C:\\Windows\\System32", "C:/Windows/System32" }, { "c:/", "C:/" }, { "c:\\..\\..\\..", "C:/" }, { "c:\\", "C:/" }, { "c:\\users\\ico", "C:/users/ico" }, { "c:\\users\\ico\\..", "C:/users" }, #ifdef WIN32 /* relative windows paths */ { ".", "Z:/home/ico/sandbox/prjs/duc" }, { "./..", "Z:/home/ico/sandbox/prjs" }, { "..", "Z:/home/ico/sandbox/prjs" }, { "foo/bar", "Z:/home/ico/sandbox/prjs/duc/foo/bar" }, { "foo/bar/woo/../..", "Z:/home/ico/sandbox/prjs/duc/foo" }, #else /* relative unix paths */ { ".", "/home/ico/sandbox/prjs/duc" }, { "./..", "/home/ico/sandbox/prjs" }, { "..", "/home/ico/sandbox/prjs" }, { "foo/bar", "/home/ico/sandbox/prjs/duc/foo/bar" }, { "foo/bar/woo/../..", "/home/ico/sandbox/prjs/duc/foo" }, #endif { NULL }, }; int main(void) { int i = 0; while(test[i][0]) { char *o = duc_canonicalize_path(test[i][0]); printf("%-40.40s %-40.40s %s\n", o, test[i][1], strcmp(test[i][1], o) ? "ERR" : "ok"); duc_free(o); i++; } return 0; } #endif static int is_sep(char c) { return c == '/' || c == '\\'; } struct component { const char *name; int len; }; struct splitter { struct component *cs; int n; }; static int count(const char *path) { int n = 0; while(*path) { if(is_sep(*path++)) n++; } return n; } static void split(struct splitter *s, const char *path) { const char *p = path; s->cs[s->n].name = path; s->cs[s->n].len = 0; while(*p) { if(is_sep(*p)) { s->n++; s->cs[s->n].name = p + 1; s->cs[s->n].len = 0; } else { s->cs[s->n].len++; } p++; } s->n++; } char *duc_canonicalize_path(const char *in) { char cwd[DUC_PATH_MAX] = ""; char drive = '\0'; int i, j; /* Check if the given path is relative or absolute */ int in_len = strlen(in); int absolute = 0; if(in_len >= 1 && is_sep(in[0])) absolute = 1; if(in_len >= 3 && isalpha(in[0]) && in[1] == ':' && is_sep(in[2])) { drive = in[0]; absolute = 1; } if(!absolute) { if(getcwd(cwd, sizeof(cwd)) == NULL) { return NULL; } #ifdef WIN32 drive = cwd[0]; #endif } /* Estimate number of parts and alloc space */ int parts = count(in) + 2; if(!absolute) parts += count(cwd); struct splitter s; s.n = 0; s.cs = duc_malloc0(parts * sizeof(*s.cs)); /* Split parts */ if(!absolute) split(&s, cwd); split(&s, in); /* canonicalize '.' and '..' */ for(i=0; ilen == 1 && c->name[0] == '.') { c->len = 0; continue; } /* '..' eliminates this and the previous non-empty component */ if(c->len == 2 && c->name[0] == '.' && c->name[1] == '.') { c->len = 0; for(j=i-1; j>=0; j--) { if(s.cs[j].len > 0) { break; } } if(j>=0) s.cs[j].len = 0; } } UT_string out; utstring_init(&out); /* Calculate total length of all collected parts */ if(drive) { utstring_printf(&out, "%c:", toupper(drive)); } int n = 0; for(i=drive ? 1 : 0; ilen > 0) { utstring_printf(&out, "/"); utstring_bincpy(&out, c->name, c->len); n++; } } if(n == 0) utstring_printf(&out, "/"); free(s.cs); return utstring_body(&out); } /* * End */ zevv-duc-b8f9659/src/libduc/db-kyoto.c000066400000000000000000000034201426703022500175600ustar00rootroot00000000000000 #include "config.h" #ifdef ENABLE_KYOTOCABINET #include #include #include #include #include #include #include "duc.h" #include "private.h" #include "db.h" struct db { KCDB* kdb; }; duc_errno tcdb_to_errno(KCDB *kdb) { return DUC_E_UNKNOWN; } struct db *db_open(const char *path_db, int flags, duc_errno *e) { struct db *db; int compress = 0; uint32_t mode = KCOREADER; if(flags & DUC_OPEN_RW) mode |= KCOWRITER | KCOCREATE; if(flags & DUC_OPEN_COMPRESS) compress = 1; db = duc_malloc(sizeof *db); db->kdb = kcdbnew(); db->kdb = kcdbnew(); if(!db->kdb) { *e = DUC_E_DB_BACKEND; goto err1; } char fname[DUC_PATH_MAX]; snprintf(fname, sizeof(fname), "%s#type=kct#opts=c", path_db); int r = kcdbopen(db->kdb, fname, mode); if(r == 0) { perror(kcecodename(kcdbecode(db->kdb))); *e = tcdb_to_errno(db->kdb); goto err2; } size_t vall; char *version = db_get(db, "duc_db_version", 14, &vall); if(version) { if(strcmp(version, DUC_DB_VERSION) != 0) { *e = DUC_E_DB_VERSION_MISMATCH; goto err3; } free(version); } else { db_put(db, "duc_db_version", 14, DUC_DB_VERSION, strlen(DUC_DB_VERSION)); } return db; err3: kcdbclose(db->kdb); err2: kcdbdel(db->kdb); err1: free(db); return NULL; } void db_close(struct db *db) { kcdbclose(db->kdb); kcdbdel(db->kdb); free(db); } duc_errno db_put(struct db *db, const void *key, size_t key_len, const void *val, size_t val_len) { int r = kcdbset(db->kdb, key, key_len, val, val_len); return (r==1) ? DUC_OK : DUC_E_UNKNOWN; } void *db_get(struct db *db, const void *key, size_t key_len, size_t *val_len) { size_t vall; void *val = kcdbget(db->kdb, key, key_len, &vall); *val_len = vall; return val; } #endif /* * End */ zevv-duc-b8f9659/src/libduc/db-leveldb.c000066400000000000000000000034331426703022500200340ustar00rootroot00000000000000 #include "config.h" #ifdef ENABLE_LEVELDB #include #include #include #include #include #include #include "duc.h" #include "private.h" #include "db.h" struct db { leveldb_t *db; leveldb_options_t *options; leveldb_readoptions_t *roptions; leveldb_writeoptions_t *woptions; }; struct db *db_open(const char *path_db, int flags, duc_errno *e) { struct db *db; char *err = NULL; db = duc_malloc(sizeof *db); db->options = leveldb_options_create(); db->woptions = leveldb_writeoptions_create(); db->roptions = leveldb_readoptions_create(); leveldb_options_set_create_if_missing(db->options, 1); leveldb_options_set_compression(db->options, leveldb_snappy_compression); db->db = leveldb_open(db->options, path_db, &err); if (err != NULL) { fprintf(stderr, "%s\n", err); *e = DUC_E_DB_BACKEND; return(NULL); } return db; } void db_close(struct db *db) { free(db); } duc_errno db_put(struct db *db, const void *key, size_t key_len, const void *val, size_t val_len) { char *err = NULL; leveldb_put(db->db, db->woptions, key, key_len, val, val_len, &err); return err ? DUC_E_UNKNOWN : DUC_OK; } duc_errno db_putcat(struct db *db, const void *key, size_t key_len, const void *val, size_t val_len) { void *t; size_t t_len; t = db_get(db, key, key_len, &t_len); if(t) { t = realloc(t, t_len + val_len); memcpy(t+t_len, val, t_len + val_len); db_put(db, key, key_len, t, t_len + val_len); free(t); return DUC_OK; } else { db_put(db, key, key_len, val, val_len); return DUC_OK; } } void *db_get(struct db *db, const void *key, size_t key_len, size_t *val_len) { char *err = NULL; char *val = leveldb_get(db->db, db->roptions, key, key_len, val_len, &err); return val; } #endif /* * End */ zevv-duc-b8f9659/src/libduc/db-lmdb.c000066400000000000000000000043371426703022500173410ustar00rootroot00000000000000 #include "config.h" #ifdef ENABLE_LMDB #include #include #include #include #include #include #include #include "duc.h" #include "private.h" #include "db.h" struct db { MDB_env *env; MDB_dbi dbi; MDB_txn *txn; }; struct db *db_open(const char *path_db, int flags, duc_errno *e) { struct db *db; unsigned int env_flags = MDB_NOSUBDIR; unsigned int open_flags = 0; unsigned int txn_flags = 0; if(flags & DUC_OPEN_RW) { open_flags |= MDB_CREATE; } else { env_flags |= MDB_RDONLY; txn_flags |= MDB_RDONLY; } /* On 32 bit machines the maximum db size is limited to 1GB, for 64 bit * machines we increase to 256 GB */ size_t map_size = 1024u * 1024u * 1024u; if(sizeof(size_t) == 8) map_size *= 256u; db = duc_malloc(sizeof *db); int rc; rc = mdb_env_create(&db->env); if(rc != MDB_SUCCESS) goto out; rc = mdb_env_set_mapsize(db->env, map_size); if(rc != MDB_SUCCESS) goto out; rc = mdb_env_open(db->env, path_db, env_flags, 0664); if(rc != MDB_SUCCESS) goto out; rc = mdb_txn_begin(db->env, NULL, txn_flags, &db->txn); if(rc != MDB_SUCCESS) goto out; rc = mdb_open(db->txn, NULL, open_flags, &db->dbi); if(rc != MDB_SUCCESS) goto out; return db; out: fprintf(stderr, "%s\n", mdb_strerror(rc)); *e = DUC_E_DB_NOT_FOUND; return NULL; } void db_close(struct db *db) { mdb_txn_commit(db->txn); mdb_dbi_close(db->env, db->dbi); mdb_env_close(db->env); free(db); } duc_errno db_put(struct db *db, const void *key, size_t key_len, const void *val, size_t val_len) { MDB_val k, d; int rc; k.mv_size = key_len; k.mv_data = (void *)key; d.mv_size = val_len; d.mv_data = (void *)val; rc = mdb_put(db->txn, db->dbi, &k, &d, 0); if(rc != MDB_SUCCESS) { fprintf(stderr, "%s\n", mdb_strerror(rc)); exit(1); } return DUC_OK; } void *db_get(struct db *db, const void *key, size_t key_len, size_t *val_len) { MDB_val k, d; int rc; k.mv_size = key_len; k.mv_data = (void *)key; rc = mdb_get(db->txn, db->dbi, &k, &d); if(rc == MDB_SUCCESS) { *val_len = d.mv_size; void *data = malloc(d.mv_size); memcpy(data, d.mv_data, d.mv_size); return data; } else { *val_len = 0; return NULL; } } #endif /* * End */ zevv-duc-b8f9659/src/libduc/db-sqlite3.c000066400000000000000000000042101426703022500177750ustar00rootroot00000000000000 #include "config.h" #ifdef ENABLE_SQLITE #include #include #include #include #include #include "duc.h" #include "private.h" #include "db.h" struct db { sqlite3 *s; }; struct db *db_open(const char *path_db, int flags, duc_errno *e) { struct db *db; int sflags = 0; db = duc_malloc(sizeof *db); if(flags & DUC_OPEN_RW) sflags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; else sflags |= SQLITE_OPEN_READONLY; int r = sqlite3_open_v2(path_db, &db->s, sflags, NULL); if(r != SQLITE_OK) goto err1; /* sqlite3_open() does not always notice corrupt database files. We do a bogus query * here to catch this error case */ r = sqlite3_exec(db->s, "select bogus from bogus", 0, 0, 0); if(r != 1) goto err1; char *q = "create table blobs(key unique primary key, value)"; sqlite3_exec(db->s, q, 0, 0, 0); q = "create index keys on blobs(key)"; sqlite3_exec(db->s, q, 0, 0, 0); sqlite3_exec(db->s, "begin", 0, 0, 0); return db; err1: free(db); *e = DUC_E_DB_CORRUPT; if(r == SQLITE_CANTOPEN) *e = DUC_E_DB_NOT_FOUND; return NULL; } void db_close(struct db *db) { sqlite3_exec(db->s, "commit", 0, 0, 0); sqlite3_close(db->s); free(db); } duc_errno db_put(struct db *db, const void *key, size_t key_len, const void *val, size_t val_len) { sqlite3_stmt *pStmt; char *q = "insert or replace into blobs(key, value) values(?, ?)"; sqlite3_prepare(db->s, q, -1, &pStmt, 0); sqlite3_bind_text(pStmt, 1, key, key_len, SQLITE_STATIC); sqlite3_bind_blob(pStmt, 2, val, val_len, SQLITE_STATIC); sqlite3_step(pStmt); sqlite3_finalize(pStmt); return DUC_OK; } void *db_get(struct db *db, const void *key, size_t key_len, size_t *val_len) { sqlite3_stmt *pStmt; char *q = "select value from blobs where key = ?"; char *val = NULL; sqlite3_prepare(db->s, q, -1, &pStmt, 0); sqlite3_bind_text(pStmt, 1, key, key_len, SQLITE_STATIC); int r = sqlite3_step(pStmt); if(r == SQLITE_ROW) { *val_len = sqlite3_column_bytes(pStmt, 0); val = duc_malloc(*val_len); memcpy(val, sqlite3_column_blob(pStmt, 0), *val_len); } sqlite3_finalize(pStmt); return val; } #endif /* * End */ zevv-duc-b8f9659/src/libduc/db-tokyo.c000066400000000000000000000045731426703022500175720ustar00rootroot00000000000000 #include "config.h" #ifdef ENABLE_TOKYOCABINET #include #include #include #include #include #include #include #include "duc.h" #include "private.h" #include "db.h" struct db { TCBDB* hdb; }; duc_errno tcdb_to_errno(TCBDB *hdb) { int ec = tcbdbecode(hdb); switch(ec) { case TCESUCCESS: return DUC_OK; case TCENOFILE: return DUC_E_DB_NOT_FOUND; case TCENOPERM: return DUC_E_PERMISSION_DENIED; case TCEOPEN: return DUC_E_PERMISSION_DENIED; case TCEMETA: return DUC_E_DB_CORRUPT; case TCERHEAD: return DUC_E_DB_CORRUPT; case TCEREAD: return DUC_E_DB_CORRUPT; case TCESEEK: return DUC_E_DB_CORRUPT; default: return DUC_E_UNKNOWN; } } struct db *db_open(const char *path_db, int flags, duc_errno *e) { struct db *db; int compress = 0; uint32_t mode = HDBONOLCK | HDBOREADER; if(flags & DUC_OPEN_RW) mode |= HDBOWRITER | HDBOCREAT; if(flags & DUC_OPEN_COMPRESS) compress = 1; /* If we pass in the -f switch, force opening the DB no matter what */ if(flags & DUC_OPEN_FORCE) { mode |= BDBOTRUNC; } db = duc_malloc(sizeof *db); db->hdb = tcbdbnew(); if(!db->hdb) { *e = DUC_E_DB_BACKEND; goto err1; } int opts = BDBTLARGE; if(compress) opts |= BDBTDEFLATE; int ret = tcbdbtune(db->hdb, 256, 512, 131072, 9, 11, opts); if(ret == 0) { *e = tcdb_to_errno(db->hdb); goto err2; } int r = tcbdbopen(db->hdb, path_db, mode); if(r == 0) { *e = tcdb_to_errno(db->hdb); goto err2; } size_t vall; char *version = db_get(db, "duc_db_version", 14, &vall); if(version) { if(strcmp(version, DUC_DB_VERSION) != 0) { *e = DUC_E_DB_VERSION_MISMATCH; goto err3; } free(version); } else { db_put(db, "duc_db_version", 14, DUC_DB_VERSION, strlen(DUC_DB_VERSION)); } return db; err3: tcbdbclose(db->hdb); err2: tcbdbdel(db->hdb); err1: free(db); return NULL; } void db_close(struct db *db) { tcbdbclose(db->hdb); tcbdbdel(db->hdb); free(db); } duc_errno db_put(struct db *db, const void *key, size_t key_len, const void *val, size_t val_len) { int r = tcbdbput(db->hdb, key, key_len, val, val_len); return (r==1) ? DUC_OK : DUC_E_UNKNOWN; } void *db_get(struct db *db, const void *key, size_t key_len, size_t *val_len) { int vall; void *val = tcbdbget(db->hdb, key, key_len, &vall); *val_len = vall; return val; } #endif /* * End */ zevv-duc-b8f9659/src/libduc/db.c000066400000000000000000000046031426703022500164210ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include "duc.h" #include "db.h" #include "buffer.h" #include "private.h" #define MAGIC_LEN 64 /* * Store report. Add the report index to the 'duc_index_reports' key if not * previously indexed */ duc_errno db_write_report(duc *duc, const struct duc_index_report *report) { size_t tmpl; char *tmp = db_get(duc->db, report->path, strlen(report->path), &tmpl); if(tmp == NULL) { char *tmp = db_get(duc->db, "duc_index_reports", 17, &tmpl); if(tmp) { tmp = duc_realloc(tmp, tmpl + sizeof(report->path)); memcpy(tmp + tmpl, report->path, sizeof(report->path)); db_put(duc->db, "duc_index_reports", 17, tmp, tmpl + sizeof(report->path)); } else { db_put(duc->db, "duc_index_reports", 17, report->path, sizeof(report->path)); } } else { free(tmp); } struct buffer *b = buffer_new(NULL, 0); buffer_put_index_report(b, report); db_put(duc->db, report->path, strlen(report->path), b->data, b->len); buffer_free(b); return 0; } struct duc_index_report *db_read_report(duc *duc, const char *path) { struct duc_index_report *report; size_t vall; char *val = db_get(duc->db, path, strlen(path), &vall); if(val == NULL) { duc->err = DUC_E_PATH_NOT_FOUND; return NULL; } struct buffer *b = buffer_new(val, vall); report = duc_malloc(sizeof *report); buffer_get_index_report(b, report); buffer_free(b); return report; } /* Return what type of DB we think this is. Note, leveldb is a directory... */ char *duc_db_type_check(const char *path_db) { struct stat sb; stat(path_db,&sb); if (S_ISREG(sb.st_mode)) { FILE *f = fopen(path_db,"r"); if(f == NULL) { //duc_log(NULL, DUC_LOG_DBG, "Not reading configuration from '%s': %s", path, streo; return("unknown"); } char buf[MAGIC_LEN]; /* read first MAGIC_LEN bytes of file then look for the strings, etc for each type of DB we support. */ size_t len = fread(buf, 1, sizeof(buf),f); if (strncmp(buf,"Kyoto CaBiNeT",13) == 0) { return("Kyoto Cabinet"); } if (strncmp(buf,"ToKyO CaBiNeT",13) == 0) { return("Tokyo Cabinet"); } if (strncmp(buf,"SQLite format 3",15) == 0) { return("SQLite3"); } } /* Check for DB_PATH that's a directory, and look in there. */ if (S_ISDIR(sb.st_mode)) { return("leveldb"); } return("unknown"); } /* * End */ zevv-duc-b8f9659/src/libduc/db.h000066400000000000000000000007451426703022500164310ustar00rootroot00000000000000 #ifndef db_h #define db_h #include "duc.h" struct db; struct db *db_open(const char *path_db, int flags, duc_errno *e); void db_close(struct db *db); duc_errno db_put(struct db *db, const void *key, size_t key_len, const void *val, size_t val_len); void *db_get(struct db *db, const void *key, size_t key_len, size_t *val_len); duc_errno db_write_report(duc *duc, const struct duc_index_report *rep); struct duc_index_report *db_read_report(duc *duc, const char *path); #endif zevv-duc-b8f9659/src/libduc/dir.c000066400000000000000000000161671426703022500166220ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include #include "duc.h" #include "db.h" #include "buffer.h" #include "private.h" struct duc_dir { struct duc *duc; struct duc_devino devino; struct duc_devino devino_parent; time_t mtime; char *path; struct duc_dirent *ent_list; struct duc_size size; size_t ent_cur; size_t ent_count; size_t ent_pool; duc_size_type size_type; duc_sort sort; }; struct duc_dir *duc_dir_new(struct duc *duc, const struct duc_devino *devino) { size_t vall; char key[32]; size_t keyl = snprintf(key, sizeof(key), "%jx/%jx", (uintmax_t)devino->dev, (uintmax_t)devino->ino); char *val = db_get(duc->db, key, keyl, &vall); if(val == NULL) { duc->err = DUC_E_PATH_NOT_FOUND; return NULL; } struct duc_dir *dir = duc_malloc0(sizeof(struct duc_dir)); dir->duc = duc; dir->devino.dev = devino->dev; dir->devino.ino = devino->ino; dir->path = NULL; dir->ent_pool = 32768; dir->ent_list = duc_malloc(dir->ent_pool); dir->size_type = -1; struct buffer *b = buffer_new(val, vall); /* Read dir header */ buffer_get_dir(b, &dir->devino_parent, &dir->mtime); /* Read all dirents */ while(b->ptr < b->len) { if((dir->ent_count+1) * sizeof(struct duc_dirent) > dir->ent_pool) { dir->ent_pool *= 2; dir->ent_list = duc_realloc(dir->ent_list, dir->ent_pool); } struct duc_dirent *ent = &dir->ent_list[dir->ent_count]; buffer_get_dirent(b, ent); duc_size_accum(&dir->size, &ent->size); dir->ent_count ++; } buffer_free(b); return dir; } void duc_dir_get_size(duc_dir *dir, struct duc_size *size) { *size = dir->size; } size_t duc_dir_get_count(duc_dir *dir) { return dir->ent_count; } char *duc_dir_get_path(duc_dir *dir) { return strdup(dir->path); } duc_dir *duc_dir_openent(duc_dir *dir, const struct duc_dirent *e) { duc_dir *dir2 = duc_dir_new(dir->duc, &e->devino); if(dir2) { int r = asprintf(&dir2->path, "%s/%s", dir->path, e->name); if (r < 0) { dir2->path = '\0'; } } return dir2; } duc_dir *duc_dir_openat(duc_dir *dir, const char *name) { if(strcmp(name, "..") == 0) { /* Special case: go up one directory */ if(dir->devino_parent.dev && dir->devino_parent.ino) { duc_dir *pdir = duc_dir_new(dir->duc, &dir->devino_parent); if(pdir == NULL) return NULL; pdir->path = duc_strdup(dir->path); dirname(pdir->path); return pdir; } } else { /* Find given name in dir */ size_t i; struct duc_dirent *e = dir->ent_list; for(i=0; ient_count; i++) { if(strcmp(e->name, name) == 0) { return duc_dir_openent(dir, e); } e++; } } return NULL; } struct duc_dirent *duc_dir_find_child(duc_dir *dir, const char *name) { size_t i; struct duc_dirent *ent = dir->ent_list; for(i=0; ient_count; i++) { if(strcmp(name, ent->name) == 0) { return ent; } ent++; } dir->duc->err = DUC_E_PATH_NOT_FOUND; return NULL; } duc_dir *duc_dir_open(struct duc *duc, const char *path) { /* Canonicalized path */ char *path_canon = duc_canonicalize_path(path); if(!path_canon) { duc->err = DUC_E_PATH_NOT_FOUND; return NULL; } /* Find top path in database */ char *path_try = duc_strdup(path_canon); int l = strlen(path_try); struct duc_devino devino = { 0, 0 }; while(l > 0) { path_try[l] = '\0'; struct duc_index_report *report; report = db_read_report(duc, path_try); if(report) { devino = report->devino; free(report); break; } l--; } free(path_try); if(l == 0) { duc_log(duc, DUC_LOG_FTL, "Path %s not found in database", path_canon); duc->err = DUC_E_PATH_NOT_FOUND; free(path_canon); return NULL; } struct duc_dir *dir; dir = duc_dir_new(duc, &devino); if(dir == NULL) { duc->err = DUC_E_PATH_NOT_FOUND; free(path_canon); return NULL; } char rest[DUC_PATH_MAX]; strncpy(rest, path_canon+l, sizeof rest); char *name = strtok(rest, "/"); while(dir && name) { struct duc_dirent *ent = duc_dir_find_child(dir, name); struct duc_dir *dir_next = NULL; if(ent) { dir_next = duc_dir_openent(dir, ent); } duc_dir_close(dir); dir = dir_next; name = strtok(NULL, "/"); } if(dir) { dir->path = strdup(path_canon); } free(path_canon); return dir; } static int fn_comp_apparent(const void *a, const void *b) { const struct duc_dirent *ea = a; const struct duc_dirent *eb = b; const struct duc_size *sa = &ea->size; const struct duc_size *sb = &eb->size; if(sa->apparent < sb->apparent) return +1; if(sa->apparent > sb->apparent) return -1; if(sa->actual < sb->actual) return +1; if(sa->actual > sb->actual) return -1; return strcmp(ea->name, eb->name); } static int fn_comp_actual(const void *a, const void *b) { const struct duc_dirent *ea = a; const struct duc_dirent *eb = b; const struct duc_size *sa = &ea->size; const struct duc_size *sb = &eb->size; if(sa->actual < sb->actual) return +1; if(sa->actual > sb->actual) return -1; if(sa->apparent < sb->apparent) return +1; if(sa->apparent > sb->apparent) return -1; return strcmp(ea->name, eb->name); } static int fn_comp_count(const void *a, const void *b) { const struct duc_dirent *ea = a; const struct duc_dirent *eb = b; const struct duc_size *sa = &ea->size; const struct duc_size *sb = &eb->size; if(sa->count < sb->count) return +1; if(sa->count > sb->count) return -1; return strcmp(ea->name, eb->name); } static int fn_comp_name(const void *a, const void *b) { const struct duc_dirent *ea = a; const struct duc_dirent *eb = b; return strcmp(ea->name, eb->name); } struct duc_dirent *duc_dir_read(duc_dir *dir, duc_size_type st, duc_sort sort) { int (*fn_comp)(const void *, const void *); dir->duc->err = 0; if(dir->size_type != st || dir->sort != sort) { switch(sort) { case DUC_SORT_SIZE: switch(st) { case DUC_SIZE_TYPE_APPARENT: fn_comp = fn_comp_apparent; break; case DUC_SIZE_TYPE_ACTUAL: fn_comp = fn_comp_actual; break; case DUC_SIZE_TYPE_COUNT: fn_comp = fn_comp_count; break; } break; case DUC_SORT_NAME: fn_comp = fn_comp_name; break; } qsort(dir->ent_list, dir->ent_count, sizeof(struct duc_dirent), fn_comp); dir->size_type = st; dir->sort = sort; } if(dir->ent_cur < dir->ent_count) { struct duc_dirent *ent = &dir->ent_list[dir->ent_cur]; dir->ent_cur ++; return ent; } else { return NULL; } } int duc_dir_seek(duc_dir *dir, size_t offset) { if(offset < dir->ent_count) { dir->ent_cur = offset; return 0; } else { return -1; } } int duc_dir_rewind(duc_dir *dir) { return duc_dir_seek(dir, 0); } int duc_dir_close(duc_dir *dir) { if(dir->path) free(dir->path); size_t i; for(i=0; ient_count; i++) { free(dir->ent_list[i].name); } free(dir->ent_list); free(dir); return 0; } struct duc_index_report *duc_get_report(duc *duc, size_t id) { size_t indexl; char *index = db_get(duc->db, "duc_index_reports", 17, &indexl); if(index == NULL) return NULL; size_t report_count = indexl / DUC_PATH_MAX; if(id >= report_count) return NULL; char *path = index + id * DUC_PATH_MAX; struct duc_index_report *r = db_read_report(duc, path); free(index); return r; } /* * End */ zevv-duc-b8f9659/src/libduc/duc.c000066400000000000000000000174451426703022500166170ustar00rootroot00000000000000 #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "private.h" #include "duc.h" #include "db.h" static void default_log_callback(duc_log_level level, const char *fmt, va_list va) { vfprintf(stderr, fmt, va); fprintf(stderr, "\n"); } duc *duc_new(void) { duc *duc = duc_malloc(sizeof *duc); memset(duc, 0, sizeof *duc); duc->log_level = DUC_LOG_WRN; duc->log_callback = default_log_callback; return duc; } void duc_del(duc *duc) { if(duc->db) duc_close(duc); free(duc); } void duc_set_log_level(duc *duc, duc_log_level level) { duc->log_level = level; } void duc_set_log_callback(duc *duc, duc_log_callback cb) { duc->log_callback = cb; } int duc_open(duc *duc, const char *path_db, duc_open_flags flags) { char tmp[DUC_PATH_MAX]; /* An empty path means check the ENV path instead */ if(path_db == NULL) { path_db = getenv("DUC_DATABASE"); } #ifdef WIN32 /* If the path is still empty, default to %APPDATA%/duc.db on windows */ if(path_db == NULL) { char *home = getenv("APPDATA"); if(home) { snprintf(tmp, sizeof tmp, "%s/duc.db", home); path_db = tmp; } } #else /* Search for ~/.duc.db and use it if it exists for backwards compatibility reasons. */ if(path_db == NULL) { char *home = getenv("HOME"); if(home) { snprintf(tmp, sizeof tmp, "%s/.duc.db", home); if(access(tmp, R_OK | W_OK) != -1) { // file exists path_db = tmp; duc_log(duc, DUC_LOG_WRN, "Using old database at \"%s\", please move this to \"$XDG_CACHE_HOME/duc/duc.db\"", path_db); } } } /* Otherwise, follow the basedir specification and use $XDG_CACHE_HOME/duc/duc.db*/ if(path_db == NULL) { char *home = getenv("XDG_CACHE_HOME"); if(home) { /* Append parent folder */ snprintf(tmp, sizeof tmp, "%s/duc", home); /* Create if needed */ mkdir(tmp, 0700); /* Append file to folder*/ snprintf(tmp, sizeof tmp, "%s/duc/duc.db", home); path_db = tmp; } } /* Last fallback: ~/.cache/duc/duc.db */ if(path_db == NULL) { char *home = getenv("HOME"); if(home) { /* Append parent folder */ snprintf(tmp, sizeof tmp, "%s/.cache/duc", home); /* Create if needed */ mkdir(tmp, 0700); /* Append file to folder*/ snprintf(tmp, sizeof tmp, "%s/.cache/duc/duc.db", home); path_db = tmp; } } #endif if(path_db == NULL) { duc->err = DUC_E_DB_NOT_FOUND; return -1; } duc_log(duc, DUC_LOG_INF, "%s database \"%s\"", (flags & DUC_OPEN_RO) ? "Reading from" : "Writing to", path_db); duc->db = db_open(path_db, flags, &duc->err); if(duc->db == NULL) { /* Now we can maybe do some quick checks to see if we tried to open a non-supported DB type. */ char *db_type = duc_db_type_check(path_db); if (db_type) { duc_log(duc, DUC_LOG_FTL, "Error opening: %s - unsupported DB type %s, compiled for %s", path_db, db_type, DB_BACKEND); } else { duc_log(duc, DUC_LOG_FTL, "Error opening: %s - %s", path_db, duc_strerror(duc)); } return -1; } return 0; } int duc_close(struct duc *duc) { if(duc->db) { db_close(duc->db); duc->db = NULL; } return 0; } void duc_log(struct duc *duc, duc_log_level level, const char *fmt, ...) { va_list va; va_start(va, fmt); if(duc) { if(duc->log_callback && level <= duc->log_level) { duc->log_callback(level, fmt, va); } } else { default_log_callback(level, fmt, va); } va_end(va); } duc_errno duc_error(duc *duc) { return duc->err; } const char *duc_strerror(duc *duc) { switch(duc->err) { case DUC_OK: return "No error: success"; case DUC_E_DB_NOT_FOUND: return "Database not found"; case DUC_E_DB_CORRUPT: return "Database corrupt and not usable"; case DUC_E_DB_VERSION_MISMATCH: return "Database version mismatch"; case DUC_E_DB_TYPE_MISMATCH: return "Database type mismatch"; case DUC_E_PATH_NOT_FOUND: return "Requested path not found"; case DUC_E_PERMISSION_DENIED: return "Permission denied"; case DUC_E_OUT_OF_MEMORY: return "Out of memory"; case DUC_E_DB_BACKEND: return "An error occurred in the database backend"; default: return "Unknown error, contact the author"; } } static int humanize(double v, int exact, double scale, char *buf, size_t maxlen) { char prefix[] = { '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' }; char *p = prefix; if(exact || v < scale) { return snprintf(buf, maxlen, "%.0f", v); } else { while(v >= scale) { v /= scale; p ++; } return snprintf(buf, maxlen, "%.1f%c", v, *p); } } int duc_human_number(double v, int exact, char *buf, size_t maxlen) { return humanize(v, exact, 1000, buf, maxlen); } int duc_human_size(const struct duc_size *size, duc_size_type st, int exact, char *buf, size_t maxlen) { double v; int base; if(st == DUC_SIZE_TYPE_COUNT) { v = size->count; base = 1000; } if(st == DUC_SIZE_TYPE_APPARENT) { v = size->apparent; base = 1024; } if(st == DUC_SIZE_TYPE_ACTUAL) { v = size->actual; base = 1024; } return humanize(v, exact, base, buf, maxlen); } int duc_human_duration(struct timeval start, struct timeval stop, char *buf, size_t maxlen) { double start_secs, stop_secs, secs; double days, hours, mins; /* fixme: use timersub here */ start_secs = start.tv_sec + (start.tv_usec / 1000000.0); stop_secs = stop.tv_sec + (stop.tv_usec / 1000000.0); secs = stop_secs - start_secs; days = floor(secs / 86400); secs = secs - (days * 86400); hours = floor(secs / 3600); secs = secs - (hours * 3600); mins = floor(secs / 60); secs = secs - (mins * 60); int l; if (days) { l = snprintf(buf, maxlen, "%.0fd, %.0f hours, %.0f minutes, and %.2f seconds.", days, hours, mins, secs); } else if (hours) { l = snprintf(buf, maxlen, "%.0f hours, %.0f minutes, and %.2f seconds.", hours, mins, secs); } else if (mins) { l = snprintf(buf, maxlen, "%.0f minutes, and %.2f seconds.", mins, secs); } else { l = snprintf(buf, maxlen, "%.2f secs.", secs); } return l; } off_t duc_get_size(struct duc_size *size, duc_size_type st) { switch(st) { case DUC_SIZE_TYPE_APPARENT: return size->apparent; case DUC_SIZE_TYPE_ACTUAL: return size->actual; case DUC_SIZE_TYPE_COUNT: return size->count; } return 0; } void *duc_malloc(size_t s) { void *p = malloc(s); if(p == NULL) { duc_log(NULL, DUC_LOG_FTL, "out of memory"); exit(1); } return p; } void *duc_malloc0(size_t s) { void *p = calloc(s, 1); if(p == NULL) { duc_log(NULL, DUC_LOG_FTL, "out of memory"); exit(1); } return p; } void *duc_realloc(void *p, size_t s) { void *p2 = realloc(p, s); if(p2 == NULL) { duc_log(NULL, DUC_LOG_FTL, "out of memory"); exit(1); } return p2; } char *duc_strdup(const char *s) { char *s2 = strdup(s); if(s2 == NULL) { duc_log(NULL, DUC_LOG_FTL, "out of memory"); exit(1); } return s2; } void duc_free(void *p) { free(p); } static struct { char c; char *s; } duc_file_type_list[] = { [DUC_FILE_TYPE_BLK] = { '%', "block device" }, [DUC_FILE_TYPE_CHR] = { '%', "character device" }, [DUC_FILE_TYPE_DIR] = { '/', "directory" }, [DUC_FILE_TYPE_FIFO] = { '|', "fifo" }, [DUC_FILE_TYPE_LNK] = { '>', "soft link" }, [DUC_FILE_TYPE_REG] = { ' ', "regular file" }, [DUC_FILE_TYPE_SOCK] = { '@', "socket" }, [DUC_FILE_TYPE_UNKNOWN] = { '?', "unknown" }, }; char duc_file_type_char(duc_file_type t) { return (t <= DUC_FILE_TYPE_UNKNOWN) ? duc_file_type_list[t].c : ' '; } char *duc_file_type_name(duc_file_type t) { return (t <= DUC_FILE_TYPE_UNKNOWN) ? duc_file_type_list[t].s : " "; } void duc_size_accum(struct duc_size *s1, const struct duc_size *s2) { s1->actual += s2->actual; s1->apparent += s2->apparent; s1->count += s2->count; } /* * End */ zevv-duc-b8f9659/src/libduc/duc.h000066400000000000000000000127631426703022500166220ustar00rootroot00000000000000 #ifndef duc_h #define duc_h #include #include #include #include #include #include #include #include #define DUC_PATH_MAX 16384 #ifdef WIN32 typedef int64_t duc_dev_t; typedef int64_t duc_ino_t; #else typedef dev_t duc_dev_t; typedef ino_t duc_ino_t; #endif typedef struct duc duc; typedef struct duc_dir duc_dir; typedef struct duc_index_req duc_index_req; typedef enum { DUC_OPEN_RO = 1<<0, /* Open read-only (for querying)*/ DUC_OPEN_RW = 1<<1, /* Open read-write (for indexing) */ DUC_OPEN_COMPRESS = 1<<2, /* Create compressed database */ DUC_OPEN_FORCE = 1<<3, /* Force over-write of database for indexing */ } duc_open_flags; typedef enum { DUC_INDEX_XDEV = 1<<0, /* Do not cross device boundaries while indexing */ DUC_INDEX_HIDE_FILE_NAMES = 1<<1, /* Hide file names */ DUC_INDEX_CHECK_HARD_LINKS = 1<<2, /* Count hard links only once during indexing */ DUC_INDEX_DRY_RUN = 1<<3, /* Do not touch the database */ } duc_index_flags; typedef enum { DUC_SIZE_TYPE_APPARENT, DUC_SIZE_TYPE_ACTUAL, DUC_SIZE_TYPE_COUNT, } duc_size_type; typedef enum { DUC_SORT_SIZE = 1, DUC_SORT_NAME = 2, } duc_sort; typedef enum { DUC_OK, /* No error, success */ DUC_E_DB_NOT_FOUND, /* Database not found */ DUC_E_DB_CORRUPT, /* Database corrupt and unusable */ DUC_E_DB_VERSION_MISMATCH, /* Database version mismatch */ DUC_E_DB_TYPE_MISMATCH, /* Database compiled in type mismatch */ DUC_E_PATH_NOT_FOUND, /* Requested path not found */ DUC_E_PERMISSION_DENIED, /* Permission denied */ DUC_E_OUT_OF_MEMORY, /* Out of memory */ DUC_E_DB_BACKEND, /* Unable to initialize database backend */ DUC_E_UNKNOWN, /* Unknown error, contact the author */ } duc_errno; typedef enum { DUC_LOG_FTL, DUC_LOG_WRN, DUC_LOG_INF, DUC_LOG_DBG, DUC_LOG_DMP } duc_log_level; typedef enum { DUC_FILE_TYPE_BLK, DUC_FILE_TYPE_CHR, DUC_FILE_TYPE_DIR, DUC_FILE_TYPE_FIFO, DUC_FILE_TYPE_LNK, DUC_FILE_TYPE_REG, DUC_FILE_TYPE_SOCK, DUC_FILE_TYPE_UNKNOWN, } duc_file_type; struct duc_devino { duc_dev_t dev; duc_ino_t ino; }; struct duc_size { off_t actual; off_t apparent; off_t count; }; struct duc_index_report { char path[DUC_PATH_MAX]; /* Indexed path */ struct duc_devino devino; /* Index top device id and inode number */ struct timeval time_start; /* Index start time */ struct timeval time_stop; /* Index finished time */ size_t file_count; /* Total number of files indexed */ size_t dir_count; /* Total number of directories indexed */ struct duc_size size; /* Total size */ }; struct duc_dirent { char *name; /* File name */ duc_file_type type; /* File type */ struct duc_size size; /* File size */ struct duc_devino devino; /* Device id and inode number */ }; /* * Duc context, logging and error reporting */ typedef void (*duc_log_callback)(duc_log_level level, const char *fmt, va_list va); duc *duc_new(void); void duc_del(duc *duc); void duc_set_log_level(duc *duc, duc_log_level level); void duc_set_log_callback(duc *duc, duc_log_callback cb); duc_errno duc_error(duc *duc); const char *duc_strerror(duc *duc); /* * Open and close database */ int duc_open(duc *duc, const char *path_db, duc_open_flags flags); int duc_close(duc *duc); /* * Index file systems */ typedef void (*duc_index_progress_cb)(struct duc_index_report *report, void *ptr); duc_index_req *duc_index_req_new(duc *duc); int duc_index_req_set_username(duc_index_req *req, const char *username); int duc_index_req_set_uid(duc_index_req *req, int uid); int duc_index_req_add_exclude(duc_index_req *req, const char *pattern); int duc_index_req_add_fstype_include(duc_index_req *req, const char *types); int duc_index_req_add_fstype_exclude(duc_index_req *req, const char *types); int duc_index_req_set_maxdepth(duc_index_req *req, int maxdepth); int duc_index_req_set_progress_cb(duc_index_req *req, duc_index_progress_cb fn, void *ptr); struct duc_index_report *duc_index(duc_index_req *req, const char *path, duc_index_flags flags); int duc_index_req_free(duc_index_req *req); int duc_index_report_free(struct duc_index_report *rep); /* * Querying the duc database */ struct duc_index_report *duc_get_report(duc *duc, size_t id); duc_dir *duc_dir_open(duc *duc, const char *path); duc_dir *duc_dir_openat(duc_dir *dir, const char *name); duc_dir *duc_dir_openent(duc_dir *dir, const struct duc_dirent *e); struct duc_dirent *duc_dir_read(duc_dir *dir, duc_size_type st, duc_sort sort); char *duc_dir_get_path(duc_dir *dir); void duc_dir_get_size(duc_dir *dir, struct duc_size *size); size_t duc_dir_get_count(duc_dir *dir); struct duc_dirent *duc_dir_find_child(duc_dir *dir, const char *name); int duc_dir_seek(duc_dir *dir, size_t offset); int duc_dir_rewind(duc_dir *dir); int duc_dir_close(duc_dir *dir); /* * Helper functions */ off_t duc_get_size(struct duc_size *size, duc_size_type st); int duc_human_number(double v, int exact, char *buf, size_t maxlen); int duc_human_size(const struct duc_size *size, duc_size_type st, int exact, char *buf, size_t maxlen); int duc_human_duration(struct timeval start, struct timeval end, char *buf, size_t maxlen); void duc_log(struct duc *duc, duc_log_level lvl, const char *fmt, ...); char duc_file_type_char(duc_file_type t); char *duc_file_type_name(duc_file_type t); char *duc_db_type_check(const char *path_db); #endif /* ifndef duc_h */ zevv-duc-b8f9659/src/libduc/index.c000066400000000000000000000370651426703022500171530ustar00rootroot00000000000000 /* * To whom it may concern: http://womble.decadent.org.uk/readdir_r-advisory.html */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_FNMATCH_H #include #endif #include "db.h" #include "duc.h" #include "private.h" #include "uthash.h" #include "utlist.h" #include "buffer.h" struct hard_link { struct duc_devino devino; UT_hash_handle hh; }; struct fstype { char *path; char *type; UT_hash_handle hh; }; struct exclude { char *name; struct exclude *next; }; struct duc_index_req { duc *duc; struct exclude *exclude_list; duc_dev_t dev; duc_index_flags flags; int maxdepth; uid_t uid; const char *username; duc_index_progress_cb progress_fn; void *progress_fndata; int progress_n; struct timeval progress_interval; struct timeval progress_time; struct hard_link *hard_link_map; struct fstype *fstypes_mounted; struct fstype *fstypes_include; struct fstype *fstypes_exclude; }; struct scanner { struct scanner *parent; int depth; DIR *d; struct buffer *buffer; struct duc *duc; struct duc_index_req *req; struct duc_index_report *rep; struct duc_dirent ent; }; static void scanner_free(struct scanner *scanner); duc_index_req *duc_index_req_new(duc *duc) { struct duc_index_req *req = duc_malloc0(sizeof(struct duc_index_req)); req->duc = duc; req->progress_interval.tv_sec = 0; req->progress_interval.tv_usec = 100 * 1000; req->hard_link_map = NULL; return req; } int duc_index_req_free(duc_index_req *req) { struct hard_link *h, *hn; struct fstype *f, *fn; struct exclude *e, *en; HASH_ITER(hh, req->hard_link_map, h, hn) { HASH_DEL(req->hard_link_map, h); free(h); } HASH_ITER(hh, req->fstypes_mounted, f, fn) { duc_free(f->type); duc_free(f->path); HASH_DEL(req->fstypes_mounted, f); free(f); } HASH_ITER(hh, req->fstypes_include, f, fn) { duc_free(f->type); HASH_DEL(req->fstypes_include, f); free(f); } HASH_ITER(hh, req->fstypes_exclude, f, fn) { duc_free(f->type); HASH_DEL(req->fstypes_exclude, f); free(f); } LL_FOREACH_SAFE(req->exclude_list, e, en) { free(e->name); free(e); } free(req); return 0; } int duc_index_req_add_exclude(duc_index_req *req, const char *patt) { struct exclude *e = duc_malloc(sizeof(struct exclude)); e->name = duc_strdup(patt); LL_APPEND(req->exclude_list, e); return 0; } static struct fstype *add_fstype(duc_index_req *req, const char *types, struct fstype *list) { char *types_copy = duc_strdup(types); char *type = strtok(types_copy, ","); while(type) { struct fstype *fstype; fstype = duc_malloc(sizeof *fstype); fstype->type = duc_strdup(type); HASH_ADD_KEYPTR(hh, list, fstype->type, strlen(fstype->type), fstype); type = strtok(NULL, ","); } duc_free(types_copy); return list; } int duc_index_req_add_fstype_include(duc_index_req *req, const char *types) { req->fstypes_include = add_fstype(req, types, req->fstypes_include); return 0; } int duc_index_req_add_fstype_exclude(duc_index_req *req, const char *types) { req->fstypes_exclude = add_fstype(req, types, req->fstypes_exclude); return 0; } int duc_index_req_set_maxdepth(duc_index_req *req, int maxdepth) { req->maxdepth = maxdepth; return 0; } /* We set both uid and username, since we cannot use -1 UID to check wether we're limiting the search to just a specific UID, but we use UID for quicker compares. */ int duc_index_req_set_username(duc_index_req *req, const char *username ) { struct passwd *pass; pass = getpwnam(username); req->username = username; req->uid = pass->pw_uid; return 0; } int duc_index_req_set_uid(duc_index_req *req, int uid) { struct passwd *pass; pass = getpwuid(uid); req->uid = uid; req->username = pass->pw_name; return 0; } int duc_index_req_set_progress_cb(duc_index_req *req, duc_index_progress_cb fn, void *ptr) { req->progress_fn = fn; req->progress_fndata = ptr; return DUC_OK; } static int match_exclude(const char *name, struct exclude *list) { struct exclude *e; LL_FOREACH(list, e) { #ifdef HAVE_FNMATCH_H if(fnmatch(e->name, name, 0) == 0) return 1; #else if(strstr(name, e->name) == 0) return 1; #endif } return 0; } /* * Convert st_mode to DUC_FILE_TYPE_* type */ duc_file_type st_to_type(mode_t mode) { if(S_ISBLK(mode)) return DUC_FILE_TYPE_BLK; if(S_ISCHR(mode)) return DUC_FILE_TYPE_CHR; if(S_ISDIR(mode)) return DUC_FILE_TYPE_DIR; if(S_ISFIFO(mode)) return DUC_FILE_TYPE_FIFO; if(S_ISLNK(mode)) return DUC_FILE_TYPE_LNK; if(S_ISREG(mode )) return DUC_FILE_TYPE_REG; if(S_ISSOCK(mode)) return DUC_FILE_TYPE_SOCK; return DUC_FILE_TYPE_UNKNOWN; } static void st_to_size(struct stat *st, struct duc_size *s) { s->apparent = st->st_size; #ifdef HAVE_STRUCT_STAT_ST_BLOCKS s->actual = st->st_blocks * 512; #else s->actual = s->apparent; #endif s->count = 1; } /* * Conver struct stat to duc_devino. Windows does not support inodes * and will always put 0 in st_ino. We fake inodes here by simply using * an incrementing counter. This *will* cause problems when re-indexing * existing databases. If anyone knows a better method to simulate * inodes on windows, please tell me */ static void st_to_devino(struct stat *st, struct duc_devino *devino) { #ifdef WIN32 static duc_ino_t ino_seq = 0; devino->dev = st->st_dev; devino->ino = ++ino_seq; #else devino->dev = st->st_dev; devino->ino = st->st_ino; #endif } /* * Check if the given node is a duplicate. returns 1 if this dev/inode * was seen before */ static int is_duplicate(struct duc_index_req *req, struct duc_devino *devino) { struct hard_link *h; HASH_FIND(hh, req->hard_link_map, devino, sizeof(*devino), h); if(h) return 1; h = duc_malloc(sizeof *h); h->devino = *devino; HASH_ADD(hh, req->hard_link_map, devino, sizeof(h->devino), h); return 0; } static void report_skip(struct duc *duc, const char *name, const char *fmt, ...) { char path_full[DUC_PATH_MAX]; char msg[DUC_PATH_MAX + 128]; char *res = realpath(name, path_full); if (res == NULL) { duc_log(duc, DUC_LOG_WRN, "Cannot determine realpath of: %s", name); } va_list va; va_start(va, fmt); vsnprintf(msg, sizeof(msg), fmt, va); duc_log(duc, DUC_LOG_WRN, "skipping %s: %s", path_full, msg); va_end(va); } /* * Check if this file system type should be scanned, depending on the * fstypes_include and fstypes_exclude lists. If neither has any entries, all * fs types are allowed. return 0 to skip, or 1 to scan */ static int is_fstype_allowed(struct duc_index_req *req, const char *name) { struct duc *duc = req->duc; if((req->fstypes_include == NULL) && (req->fstypes_exclude == NULL)) { return 1; } /* Find file system type */ char path_full[DUC_PATH_MAX]; char *res = realpath(name, path_full); if (res == NULL) { report_skip(duc, name, "Cannot determine realpath result"); return 0; } struct fstype *fstype = NULL; HASH_FIND_STR(req->fstypes_mounted, path_full, fstype); if(fstype == NULL) { report_skip(duc, name, "Unable to determine fs type"); return 0; } const char *type = fstype->type; /* Check if excluded */ if(req->fstypes_exclude) { HASH_FIND_STR(req->fstypes_exclude, type, fstype); if(fstype) { report_skip(duc, name, "File system type '%s' is excluded", type); return 0; } } /* Check if included */ if(req->fstypes_include) { HASH_FIND_STR(req->fstypes_include, type, fstype); if(!fstype) { report_skip(duc, name, "File system type '%s' is not included", type); return 0; } } return 1; } /* * Open dir and read file status */ static struct scanner *scanner_new(struct duc *duc, struct scanner *scanner_parent, const char *path, struct stat *st) { struct scanner *scanner; scanner = duc_malloc0(sizeof *scanner); struct stat st2; struct duc_devino devino_parent = { 0, 0 }; if(scanner_parent) { scanner->depth = scanner_parent->depth + 1; scanner->duc = scanner_parent->duc; scanner->req = scanner_parent->req; scanner->rep = scanner_parent->rep; devino_parent = scanner_parent->ent.devino; } else { int r = lstat(path, &st2); if(r == -1) { duc_log(duc, DUC_LOG_WRN, "Error statting %s: %s", path, strerror(errno)); goto err; } st = &st2; } scanner->d = opendir(path); if(scanner->d == NULL) { report_skip(duc, path, strerror(errno)); goto err; } scanner->duc = duc; scanner->parent = scanner_parent; scanner->buffer = buffer_new(NULL, 32768); scanner->ent.name = duc_strdup(path); scanner->ent.type = DUC_FILE_TYPE_DIR, st_to_devino(st, &scanner->ent.devino); st_to_size(st, &scanner->ent.size); scanner->ent.size.apparent = 0; buffer_put_dir(scanner->buffer, &devino_parent, st->st_mtime); duc_log(duc, DUC_LOG_DMP, ">> %s", scanner->ent.name); return scanner; err: if(scanner->d) closedir(scanner->d); if(scanner) free(scanner); return NULL; } static void scanner_scan(struct scanner *scanner_dir) { int r; struct duc *duc = scanner_dir->duc; struct duc_index_req *req = scanner_dir->req; struct duc_index_report *report = scanner_dir->rep; report->dir_count ++; duc_size_accum(&report->size, &scanner_dir->ent.size); r = chdir(scanner_dir->ent.name); if(r != 0) { report_skip(duc, scanner_dir->ent.name, strerror(errno)); return; } /* Iterate directory entries */ struct dirent *e; while( (e = readdir(scanner_dir->d)) != NULL) { /* Skip . and .. */ char *name = e->d_name; if(name[0] == '.') { if(name[1] == '\0') continue; if((name[1] == '.') && (name[2] == '\0')) continue; } if(match_exclude(name, req->exclude_list)) { report_skip(duc, name, "Excluded by user"); continue; } /* Get file info. Derive the file type from st.st_mode. It * seems that we cannot trust e->d_type because it is not * guaranteed to contain a sane value on all file system types. * See the readdir() man page for more details */ struct stat st_ent; int r = lstat(name, &st_ent); if(r == -1) { duc_log(duc, DUC_LOG_WRN, "Error statting %s: %s", name, strerror(errno)); continue; } /* If this dirent lies on a different device, check the file system type of the new * device and skip if it is not on the list of approved types */ if(st_ent.st_dev != scanner_dir->ent.devino.dev) { if(!is_fstype_allowed(req, name)) { continue; } } /* Are we looking for data for only a specific user? */ if(req->username) { if(st_ent.st_uid != req->uid) { continue; } } /* Create duc_dirent from readdir() and fstatat() results */ struct duc_dirent ent; ent.name = name; ent.type = st_to_type(st_ent.st_mode); st_to_devino(&st_ent, &ent.devino); st_to_size(&st_ent, &ent.size); /* Skip hard link duplicates for any files with more then one hard link */ if((ent.type != DUC_FILE_TYPE_DIR) && (req->flags & DUC_INDEX_CHECK_HARD_LINKS) && (st_ent.st_nlink > 1) && is_duplicate(req, &ent.devino)) { continue; } /* Check if we can cross file system boundaries */ if((ent.type == DUC_FILE_TYPE_DIR) && (req->flags & DUC_INDEX_XDEV) && (st_ent.st_dev != req->dev)) { report_skip(duc, name, "Not crossing file system boundaries"); continue; } /* Calculate size of this dirent */ if(ent.type == DUC_FILE_TYPE_DIR) { /* Open and scan child directory */ struct scanner *scanner_ent = scanner_new(duc, scanner_dir, name, &st_ent); if(scanner_ent == NULL) continue; scanner_scan(scanner_ent); scanner_free(scanner_ent); } else { duc_size_accum(&scanner_dir->ent.size, &ent.size); duc_size_accum(&report->size, &ent.size); report->file_count ++; duc_log(duc, DUC_LOG_DMP, " %c %jd %jd %s", duc_file_type_char(ent.type), ent.size.apparent, ent.size.actual, name); /* Optionally hide file names */ if(req->flags & DUC_INDEX_HIDE_FILE_NAMES) ent.name = ""; /* Store record */ if((req->maxdepth == 0) || (scanner_dir->depth < req->maxdepth)) { buffer_put_dirent(scanner_dir->buffer, &ent); } } } r = chdir(".."); if(r != 0) { report_skip(duc, scanner_dir->ent.name, strerror(errno)); return; } } static void scanner_free(struct scanner *scanner) { struct duc *duc = scanner->duc; struct duc_index_req *req = scanner->req; struct duc_index_report *report = scanner->rep; duc_log(duc, DUC_LOG_DMP, "<< %s actual:%jd apparent:%jd", scanner->ent.name, scanner->ent.size.apparent, scanner->ent.size.actual); if(scanner->parent) { duc_size_accum(&scanner->parent->ent.size, &scanner->ent.size); if((req->maxdepth == 0) || (scanner->depth < req->maxdepth)) { buffer_put_dirent(scanner->parent->buffer, &scanner->ent); } } /* Progress reporting */ if(req->progress_fn) { if((!scanner->parent) || (req->progress_n++ == 100)) { struct timeval t_now; gettimeofday(&t_now, NULL); if(!scanner->parent || timercmp(&t_now, &req->progress_time, > )) { req->progress_fn(report, req->progress_fndata); timeradd(&t_now, &req->progress_interval, &req->progress_time); } req->progress_n = 0; } } if(!(req->flags & DUC_INDEX_DRY_RUN)) { char key[32]; struct duc_devino *devino = &scanner->ent.devino; size_t keyl = snprintf(key, sizeof(key), "%jx/%jx", (uintmax_t)devino->dev, (uintmax_t)devino->ino); int r = db_put(duc->db, key, keyl, scanner->buffer->data, scanner->buffer->len); if(r != 0) duc->err = r; } buffer_free(scanner->buffer); closedir(scanner->d); duc_free(scanner->ent.name); duc_free(scanner); } static void read_mounts(duc_index_req *req) { FILE *f; f = fopen("/proc/mounts", "r"); if(f == NULL) { f = fopen("/etc/mtab", "r"); } if(f == NULL) { duc_log(req->duc, DUC_LOG_FTL, "Unable to get list of mounted file systems"); } char buf[DUC_PATH_MAX]; while(fgets(buf, sizeof(buf)-1, f) != NULL) { (void)strtok(buf, " "); char *path = strtok(NULL, " "); char *type = strtok(NULL, " "); if(path && type) { struct fstype *fstype; fstype = duc_malloc(sizeof *fstype); fstype->type = duc_strdup(type); fstype->path = duc_strdup(path); HASH_ADD_KEYPTR(hh, req->fstypes_mounted, fstype->path, strlen(fstype->path), fstype); } } fclose(f); } struct duc_index_report *duc_index(duc_index_req *req, const char *path, duc_index_flags flags) { duc *duc = req->duc; req->flags = flags; /* Canonicalize index path */ char *path_canon = duc_canonicalize_path(path); if(path_canon == NULL) { duc_log(duc, DUC_LOG_WRN, "Error converting path %s: %s", path, strerror(errno)); duc->err = DUC_E_UNKNOWN; if(errno == EACCES) duc->err = DUC_E_PERMISSION_DENIED; if(errno == ENOENT) duc->err = DUC_E_PATH_NOT_FOUND; return NULL; } /* Create report */ struct duc_index_report *report = duc_malloc0(sizeof(struct duc_index_report)); gettimeofday(&report->time_start, NULL); snprintf(report->path, sizeof(report->path), "%s", path_canon); /* Read mounted file systems to find fs types */ if(req->fstypes_include || req->fstypes_exclude) { read_mounts(req); } /* Recursively index subdirectories */ struct scanner *scanner = scanner_new(duc, NULL, path_canon, NULL); if(scanner) { scanner->req = req; scanner->rep = report; req->dev = scanner->ent.devino.dev; report->devino = scanner->ent.devino; scanner_scan(scanner); gettimeofday(&report->time_stop, NULL); scanner_free(scanner); } /* Store report */ if(!(req->flags & DUC_INDEX_DRY_RUN)) { gettimeofday(&report->time_stop, NULL); db_write_report(duc, report); } free(path_canon); return report; } int duc_index_report_free(struct duc_index_report *rep) { free(rep); return 0; } /* * End */ zevv-duc-b8f9659/src/libduc/list.c000066400000000000000000000011211426703022500167770ustar00rootroot00000000000000 #include "config.h" #include #include #include "list.h" void list_push(struct list **list, void *data) { struct list *ln = malloc(sizeof(struct list)); assert(ln); ln->data = data; ln->next = *list; *list = ln; } void *list_pop(struct list **list) { struct list *tmp = *list; if(tmp) { void *data = tmp->data; *list = tmp->next; free(tmp); return data; } return NULL; } void list_free(struct list *list, void(*fn)(void *data)) { while(list) { if(fn) fn(list->data); struct list *tmp = list; free(list); list = tmp; } } /* * End */ zevv-duc-b8f9659/src/libduc/list.h000066400000000000000000000003511426703022500170100ustar00rootroot00000000000000 #ifndef list_h #define list_h struct list { void *data; struct list *next; }; void list_push(struct list **list, void *data); void *list_pop(struct list **list); void list_free(struct list *list, void(*fn)(void *data)); #endif zevv-duc-b8f9659/src/libduc/private.h000066400000000000000000000017621426703022500175160ustar00rootroot00000000000000#ifndef duc_internal_h #define duc_internal_h #include "duc.h" #define DUC_DB_VERSION "17" #ifndef S_ISLNK #define S_ISLNK(v) 0 #endif #ifndef S_ISSOCK #define S_ISSOCK(v) 0 #endif #ifndef HAVE_LSTAT #define lstat stat #endif #ifndef timeradd # define timeradd(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ if ((result)->tv_usec >= 1000000) \ { \ ++(result)->tv_sec; \ (result)->tv_usec -= 1000000; \ } \ } while (0) #endif struct duc { struct db *db; duc_errno err; duc_log_level log_level; duc_log_callback log_callback; }; void *duc_malloc(size_t s); void *duc_malloc0(size_t s); void *duc_realloc(void *p, size_t s); char *duc_strdup(const char *s); void duc_free(void *p); void duc_size_accum(struct duc_size *s1, const struct duc_size *s2); char *duc_canonicalize_path(const char *dir); #endif zevv-duc-b8f9659/src/libduc/uthash.h000066400000000000000000001633171426703022500173450ustar00rootroot00000000000000/* Copyright (c) 2003-2013, Troy D. Hanson http://uthash.sourceforge.net All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UTHASH_H #define UTHASH_H #include /* memcmp,strlen */ #include /* ptrdiff_t */ #include /* exit() */ /* These macros use decltype or the earlier __typeof GNU extension. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ when compiling c++ source) this code uses whatever method is needed or, for VS2008 where neither is available, uses casting workarounds. */ #ifdef _MSC_VER /* MS compiler */ #if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ #define DECLTYPE(x) (decltype(x)) #else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE #define DECLTYPE(x) #endif #else /* GNU, Sun and other compilers */ #define DECLTYPE(x) (__typeof(x)) #endif #ifdef NO_DECLTYPE #define DECLTYPE_ASSIGN(dst,src) \ do { \ char **_da_dst = (char**)(&(dst)); \ *_da_dst = (char*)(src); \ } while(0) #else #define DECLTYPE_ASSIGN(dst,src) \ do { \ (dst) = DECLTYPE(dst)(src); \ } while(0) #endif /* a number of the hash function use uint32_t which isn't defined on win32 */ #ifdef _MSC_VER typedef unsigned int uint32_t; typedef unsigned char uint8_t; #else #include /* uint32_t */ #endif #define UTHASH_VERSION 1.9.7 #ifndef uthash_fatal #define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ #endif #ifndef uthash_malloc #define uthash_malloc(sz) malloc(sz) /* malloc fcn */ #endif #ifndef uthash_free #define uthash_free(ptr,sz) free(ptr) /* free fcn */ #endif #ifndef uthash_noexpand_fyi #define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ #endif #ifndef uthash_expand_fyi #define uthash_expand_fyi(tbl) /* can be defined to log expands */ #endif /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ #define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ /* calculate the element whose hash handle address is hhe */ #define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) #define HASH_FIND(hh,head,keyptr,keylen,out) \ do { \ unsigned _hf_bkt,_hf_hashv; \ out=NULL; \ if (head) { \ HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ keyptr,keylen,out); \ } \ } \ } while (0) #ifdef HASH_BLOOM #define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) #define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) #define HASH_BLOOM_MAKE(tbl) \ do { \ (tbl)->bloom_nbits = HASH_BLOOM; \ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ } while (0) #define HASH_BLOOM_FREE(tbl) \ do { \ uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ } while (0) #define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) #define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) #define HASH_BLOOM_ADD(tbl,hashv) \ HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #define HASH_BLOOM_TEST(tbl,hashv) \ HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #else #define HASH_BLOOM_MAKE(tbl) #define HASH_BLOOM_FREE(tbl) #define HASH_BLOOM_ADD(tbl,hashv) #define HASH_BLOOM_TEST(tbl,hashv) (1) #endif #define HASH_MAKE_TABLE(hh,head) \ do { \ (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ sizeof(UT_hash_table)); \ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ (head)->hh.tbl->tail = &((head)->hh); \ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl->buckets, 0, \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ HASH_BLOOM_MAKE((head)->hh.tbl); \ (head)->hh.tbl->signature = HASH_SIGNATURE; \ } while(0) #define HASH_ADD(hh,head,fieldname,keylen_in,add) \ HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ do { \ unsigned _ha_bkt; \ (add)->hh.next = NULL; \ (add)->hh.key = (char*)keyptr; \ (add)->hh.keylen = (unsigned)keylen_in; \ if (!(head)) { \ head = (add); \ (head)->hh.prev = NULL; \ HASH_MAKE_TABLE(hh,head); \ } else { \ (head)->hh.tbl->tail->next = (add); \ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ (head)->hh.tbl->tail = &((add)->hh); \ } \ (head)->hh.tbl->num_items++; \ (add)->hh.tbl = (head)->hh.tbl; \ HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ (add)->hh.hashv, _ha_bkt); \ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ HASH_FSCK(hh,head); \ } while(0) #define HASH_TO_BKT( hashv, num_bkts, bkt ) \ do { \ bkt = ((hashv) & ((num_bkts) - 1)); \ } while(0) /* delete "delptr" from the hash table. * "the usual" patch-up process for the app-order doubly-linked-list. * The use of _hd_hh_del below deserves special explanation. * These used to be expressed using (delptr) but that led to a bug * if someone used the same symbol for the head and deletee, like * HASH_DELETE(hh,users,users); * We want that to work, but by changing the head (users) below * we were forfeiting our ability to further refer to the deletee (users) * in the patch-up process. Solution: use scratch space to * copy the deletee pointer, then the latter references are via that * scratch pointer rather than through the repointed (users) symbol. */ #define HASH_DELETE(hh,head,delptr) \ do { \ unsigned _hd_bkt; \ struct UT_hash_handle *_hd_hh_del; \ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ uthash_free((head)->hh.tbl->buckets, \ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ head = NULL; \ } else { \ _hd_hh_del = &((delptr)->hh); \ if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ (head)->hh.tbl->tail = \ (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ (head)->hh.tbl->hho); \ } \ if ((delptr)->hh.prev) { \ ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ } else { \ DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ } \ if (_hd_hh_del->next) { \ ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ (head)->hh.tbl->hho))->prev = \ _hd_hh_del->prev; \ } \ HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ (head)->hh.tbl->num_items--; \ } \ HASH_FSCK(hh,head); \ } while (0) /* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ #define HASH_FIND_STR(head,findstr,out) \ HASH_FIND(hh,head,findstr,strlen(findstr),out) #define HASH_ADD_STR(head,strfield,add) \ HASH_ADD(hh,head,strfield,strlen(add->strfield),add) #define HASH_FIND_INT(head,findint,out) \ HASH_FIND(hh,head,findint,sizeof(int),out) #define HASH_ADD_INT(head,intfield,add) \ HASH_ADD(hh,head,intfield,sizeof(int),add) #define HASH_FIND_PTR(head,findptr,out) \ HASH_FIND(hh,head,findptr,sizeof(void *),out) #define HASH_ADD_PTR(head,ptrfield,add) \ HASH_ADD(hh,head,ptrfield,sizeof(void *),add) #define HASH_DEL(head,delptr) \ HASH_DELETE(hh,head,delptr) /* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. */ #ifdef HASH_DEBUG #define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) #define HASH_FSCK(hh,head) \ do { \ unsigned _bkt_i; \ unsigned _count, _bkt_count; \ char *_prev; \ struct UT_hash_handle *_thh; \ if (head) { \ _count = 0; \ for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ _bkt_count = 0; \ _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ _prev = NULL; \ while (_thh) { \ if (_prev != (char*)(_thh->hh_prev)) { \ HASH_OOPS("invalid hh_prev %p, actual %p\n", \ _thh->hh_prev, _prev ); \ } \ _bkt_count++; \ _prev = (char*)(_thh); \ _thh = _thh->hh_next; \ } \ _count += _bkt_count; \ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ HASH_OOPS("invalid bucket count %d, actual %d\n", \ (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ } \ } \ if (_count != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid hh item count %d, actual %d\n", \ (head)->hh.tbl->num_items, _count ); \ } \ /* traverse hh in app order; check next/prev integrity, count */ \ _count = 0; \ _prev = NULL; \ _thh = &(head)->hh; \ while (_thh) { \ _count++; \ if (_prev !=(char*)(_thh->prev)) { \ HASH_OOPS("invalid prev %p, actual %p\n", \ _thh->prev, _prev ); \ } \ _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ (head)->hh.tbl->hho) : NULL ); \ } \ if (_count != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid app item count %d, actual %d\n", \ (head)->hh.tbl->num_items, _count ); \ } \ } \ } while (0) #else #define HASH_FSCK(hh,head) #endif /* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to * the descriptor to which this macro is defined for tuning the hash function. * The app can #include to get the prototype for write(2). */ #ifdef HASH_EMIT_KEYS #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ do { \ unsigned _klen = fieldlen; \ write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ write(HASH_EMIT_KEYS, keyptr, fieldlen); \ } while (0) #else #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) #endif /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ #ifdef HASH_FUNCTION #define HASH_FCN HASH_FUNCTION #else #define HASH_FCN HASH_JEN #endif /* The Bernstein hash function, used in Perl prior to v5.6 */ #define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hb_keylen=keylen; \ char *_hb_key=(char*)(key); \ (hashv) = 0; \ while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ bkt = (hashv) & (num_bkts-1); \ } while (0) /* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ #define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _sx_i; \ char *_hs_key=(char*)(key); \ hashv = 0; \ for(_sx_i=0; _sx_i < keylen; _sx_i++) \ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ bkt = hashv & (num_bkts-1); \ } while (0) #define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _fn_i; \ char *_hf_key=(char*)(key); \ hashv = 2166136261UL; \ for(_fn_i=0; _fn_i < keylen; _fn_i++) \ hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ bkt = hashv & (num_bkts-1); \ } while(0) #define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _ho_i; \ char *_ho_key=(char*)(key); \ hashv = 0; \ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ hashv += _ho_key[_ho_i]; \ hashv += (hashv << 10); \ hashv ^= (hashv >> 6); \ } \ hashv += (hashv << 3); \ hashv ^= (hashv >> 11); \ hashv += (hashv << 15); \ bkt = hashv & (num_bkts-1); \ } while(0) #define HASH_JEN_MIX(a,b,c) \ do { \ a -= b; a -= c; a ^= ( c >> 13 ); \ b -= c; b -= a; b ^= ( a << 8 ); \ c -= a; c -= b; c ^= ( b >> 13 ); \ a -= b; a -= c; a ^= ( c >> 12 ); \ b -= c; b -= a; b ^= ( a << 16 ); \ c -= a; c -= b; c ^= ( b >> 5 ); \ a -= b; a -= c; a ^= ( c >> 3 ); \ b -= c; b -= a; b ^= ( a << 10 ); \ c -= a; c -= b; c ^= ( b >> 15 ); \ } while (0) #define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hj_i,_hj_j,_hj_k; \ char *_hj_key=(char*)(key); \ hashv = 0xfeedbeef; \ _hj_i = _hj_j = 0x9e3779b9; \ _hj_k = (unsigned)keylen; \ while (_hj_k >= 12) { \ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + ( (unsigned)_hj_key[2] << 16 ) \ + ( (unsigned)_hj_key[3] << 24 ) ); \ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + ( (unsigned)_hj_key[6] << 16 ) \ + ( (unsigned)_hj_key[7] << 24 ) ); \ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + ( (unsigned)_hj_key[10] << 16 ) \ + ( (unsigned)_hj_key[11] << 24 ) ); \ \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ \ _hj_key += 12; \ _hj_k -= 12; \ } \ hashv += keylen; \ switch ( _hj_k ) { \ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ case 5: _hj_j += _hj_key[4]; \ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ case 1: _hj_i += _hj_key[0]; \ } \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ bkt = hashv & (num_bkts-1); \ } while(0) /* The Paul Hsieh hash function */ #undef get16bits #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) #define get16bits(d) (*((const uint16_t *) (d))) #endif #if !defined (get16bits) #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ +(uint32_t)(((const uint8_t *)(d))[0]) ) #endif #define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ do { \ char *_sfh_key=(char*)(key); \ uint32_t _sfh_tmp, _sfh_len = keylen; \ \ int _sfh_rem = _sfh_len & 3; \ _sfh_len >>= 2; \ hashv = 0xcafebabe; \ \ /* Main loop */ \ for (;_sfh_len > 0; _sfh_len--) { \ hashv += get16bits (_sfh_key); \ _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ hashv = (hashv << 16) ^ _sfh_tmp; \ _sfh_key += 2*sizeof (uint16_t); \ hashv += hashv >> 11; \ } \ \ /* Handle end cases */ \ switch (_sfh_rem) { \ case 3: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 16; \ hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ hashv += hashv >> 11; \ break; \ case 2: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 11; \ hashv += hashv >> 17; \ break; \ case 1: hashv += *_sfh_key; \ hashv ^= hashv << 10; \ hashv += hashv >> 1; \ } \ \ /* Force "avalanching" of final 127 bits */ \ hashv ^= hashv << 3; \ hashv += hashv >> 5; \ hashv ^= hashv << 4; \ hashv += hashv >> 17; \ hashv ^= hashv << 25; \ hashv += hashv >> 6; \ bkt = hashv & (num_bkts-1); \ } while(0) #ifdef HASH_USING_NO_STRICT_ALIASING /* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. * MurmurHash uses the faster approach only on CPU's where we know it's safe. * * Note the preprocessor built-in defines can be emitted using: * * gcc -m64 -dM -E - < /dev/null (on gcc) * cc -## a.c (where a.c is a simple test file) (Sun Studio) */ #if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) #define MUR_GETBLOCK(p,i) p[i] #else /* non intel */ #define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) #define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) #define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) #define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) #define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) #if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) #define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) #define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) #define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) #else /* assume little endian non-intel */ #define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) #define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) #define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) #endif #define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ MUR_ONE_THREE(p)))) #endif #define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) #define MUR_FMIX(_h) \ do { \ _h ^= _h >> 16; \ _h *= 0x85ebca6b; \ _h ^= _h >> 13; \ _h *= 0xc2b2ae35l; \ _h ^= _h >> 16; \ } while(0) #define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ do { \ const uint8_t *_mur_data = (const uint8_t*)(key); \ const int _mur_nblocks = (keylen) / 4; \ uint32_t _mur_h1 = 0xf88D5353; \ uint32_t _mur_c1 = 0xcc9e2d51; \ uint32_t _mur_c2 = 0x1b873593; \ uint32_t _mur_k1 = 0; \ const uint8_t *_mur_tail; \ const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ int _mur_i; \ for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ _mur_k1 *= _mur_c1; \ _mur_k1 = MUR_ROTL32(_mur_k1,15); \ _mur_k1 *= _mur_c2; \ \ _mur_h1 ^= _mur_k1; \ _mur_h1 = MUR_ROTL32(_mur_h1,13); \ _mur_h1 = _mur_h1*5+0xe6546b64; \ } \ _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ _mur_k1=0; \ switch((keylen) & 3) { \ case 3: _mur_k1 ^= _mur_tail[2] << 16; \ case 2: _mur_k1 ^= _mur_tail[1] << 8; \ case 1: _mur_k1 ^= _mur_tail[0]; \ _mur_k1 *= _mur_c1; \ _mur_k1 = MUR_ROTL32(_mur_k1,15); \ _mur_k1 *= _mur_c2; \ _mur_h1 ^= _mur_k1; \ } \ _mur_h1 ^= (keylen); \ MUR_FMIX(_mur_h1); \ hashv = _mur_h1; \ bkt = hashv & (num_bkts-1); \ } while(0) #endif /* HASH_USING_NO_STRICT_ALIASING */ /* key comparison function; return 0 if keys equal */ #define HASH_KEYCMP(a,b,len) memcmp(a,b,len) /* iterate over items in a known bucket to find desired item */ #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ do { \ if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ else out=NULL; \ while (out) { \ if ((out)->hh.keylen == keylen_in) { \ if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \ } \ if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ else out = NULL; \ } \ } while(0) /* add an item to a bucket */ #define HASH_ADD_TO_BKT(head,addhh) \ do { \ head.count++; \ (addhh)->hh_next = head.hh_head; \ (addhh)->hh_prev = NULL; \ if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ (head).hh_head=addhh; \ if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ && (addhh)->tbl->noexpand != 1) { \ HASH_EXPAND_BUCKETS((addhh)->tbl); \ } \ } while(0) /* remove an item from a given bucket */ #define HASH_DEL_IN_BKT(hh,head,hh_del) \ (head).count--; \ if ((head).hh_head == hh_del) { \ (head).hh_head = hh_del->hh_next; \ } \ if (hh_del->hh_prev) { \ hh_del->hh_prev->hh_next = hh_del->hh_next; \ } \ if (hh_del->hh_next) { \ hh_del->hh_next->hh_prev = hh_del->hh_prev; \ } /* Bucket expansion has the effect of doubling the number of buckets * and redistributing the items into the new buckets. Ideally the * items will distribute more or less evenly into the new buckets * (the extent to which this is true is a measure of the quality of * the hash function as it applies to the key domain). * * With the items distributed into more buckets, the chain length * (item count) in each bucket is reduced. Thus by expanding buckets * the hash keeps a bound on the chain length. This bounded chain * length is the essence of how a hash provides constant time lookup. * * The calculation of tbl->ideal_chain_maxlen below deserves some * explanation. First, keep in mind that we're calculating the ideal * maximum chain length based on the *new* (doubled) bucket count. * In fractions this is just n/b (n=number of items,b=new num buckets). * Since the ideal chain length is an integer, we want to calculate * ceil(n/b). We don't depend on floating point arithmetic in this * hash, so to calculate ceil(n/b) with integers we could write * * ceil(n/b) = (n/b) + ((n%b)?1:0) * * and in fact a previous version of this hash did just that. * But now we have improved things a bit by recognizing that b is * always a power of two. We keep its base 2 log handy (call it lb), * so now we can write this with a bit shift and logical AND: * * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) * */ #define HASH_EXPAND_BUCKETS(tbl) \ do { \ unsigned _he_bkt; \ unsigned _he_bkt_i; \ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ memset(_he_new_buckets, 0, \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ tbl->ideal_chain_maxlen = \ (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ tbl->nonideal_items = 0; \ for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ { \ _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ while (_he_thh) { \ _he_hh_nxt = _he_thh->hh_next; \ HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ tbl->nonideal_items++; \ _he_newbkt->expand_mult = _he_newbkt->count / \ tbl->ideal_chain_maxlen; \ } \ _he_thh->hh_prev = NULL; \ _he_thh->hh_next = _he_newbkt->hh_head; \ if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ _he_thh; \ _he_newbkt->hh_head = _he_thh; \ _he_thh = _he_hh_nxt; \ } \ } \ uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ tbl->num_buckets *= 2; \ tbl->log2_num_buckets++; \ tbl->buckets = _he_new_buckets; \ tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ (tbl->ineff_expands+1) : 0; \ if (tbl->ineff_expands > 1) { \ tbl->noexpand=1; \ uthash_noexpand_fyi(tbl); \ } \ uthash_expand_fyi(tbl); \ } while(0) /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ /* Note that HASH_SORT assumes the hash handle name to be hh. * HASH_SRT was added to allow the hash handle name to be passed in. */ #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) #define HASH_SRT(hh,head,cmpfcn) \ do { \ unsigned _hs_i; \ unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ if (head) { \ _hs_insize = 1; \ _hs_looping = 1; \ _hs_list = &((head)->hh); \ while (_hs_looping) { \ _hs_p = _hs_list; \ _hs_list = NULL; \ _hs_tail = NULL; \ _hs_nmerges = 0; \ while (_hs_p) { \ _hs_nmerges++; \ _hs_q = _hs_p; \ _hs_psize = 0; \ for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ _hs_psize++; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ if (! (_hs_q) ) break; \ } \ _hs_qsize = _hs_insize; \ while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ if (_hs_psize == 0) { \ _hs_e = _hs_q; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_qsize--; \ } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ _hs_e = _hs_p; \ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ ((void*)((char*)(_hs_p->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_psize--; \ } else if (( \ cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ ) <= 0) { \ _hs_e = _hs_p; \ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ ((void*)((char*)(_hs_p->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_psize--; \ } else { \ _hs_e = _hs_q; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_qsize--; \ } \ if ( _hs_tail ) { \ _hs_tail->next = ((_hs_e) ? \ ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ } else { \ _hs_list = _hs_e; \ } \ _hs_e->prev = ((_hs_tail) ? \ ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ _hs_tail = _hs_e; \ } \ _hs_p = _hs_q; \ } \ _hs_tail->next = NULL; \ if ( _hs_nmerges <= 1 ) { \ _hs_looping=0; \ (head)->hh.tbl->tail = _hs_tail; \ DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ } \ _hs_insize *= 2; \ } \ HASH_FSCK(hh,head); \ } \ } while (0) /* This function selects items from one hash into another hash. * The end result is that the selected items have dual presence * in both hashes. There is no copy of the items made; rather * they are added into the new hash through a secondary hash * hash handle that must be present in the structure. */ #define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ do { \ unsigned _src_bkt, _dst_bkt; \ void *_last_elt=NULL, *_elt; \ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ if (src) { \ for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ _src_hh; \ _src_hh = _src_hh->hh_next) { \ _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ if (cond(_elt)) { \ _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ _dst_hh->key = _src_hh->key; \ _dst_hh->keylen = _src_hh->keylen; \ _dst_hh->hashv = _src_hh->hashv; \ _dst_hh->prev = _last_elt; \ _dst_hh->next = NULL; \ if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ if (!dst) { \ DECLTYPE_ASSIGN(dst,_elt); \ HASH_MAKE_TABLE(hh_dst,dst); \ } else { \ _dst_hh->tbl = (dst)->hh_dst.tbl; \ } \ HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ (dst)->hh_dst.tbl->num_items++; \ _last_elt = _elt; \ _last_elt_hh = _dst_hh; \ } \ } \ } \ } \ HASH_FSCK(hh_dst,dst); \ } while (0) #define HASH_CLEAR(hh,head) \ do { \ if (head) { \ uthash_free((head)->hh.tbl->buckets, \ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ (head)=NULL; \ } \ } while(0) #ifdef NO_DECLTYPE #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) #else #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) #endif /* obtain a count of items in the hash */ #define HASH_COUNT(head) HASH_CNT(hh,head) #define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) typedef struct UT_hash_bucket { struct UT_hash_handle *hh_head; unsigned count; /* expand_mult is normally set to 0. In this situation, the max chain length * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If * the bucket's chain exceeds this length, bucket expansion is triggered). * However, setting expand_mult to a non-zero value delays bucket expansion * (that would be triggered by additions to this particular bucket) * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. * (The multiplier is simply expand_mult+1). The whole idea of this * multiplier is to reduce bucket expansions, since they are expensive, in * situations where we know that a particular bucket tends to be overused. * It is better to let its chain length grow to a longer yet-still-bounded * value, than to do an O(n) bucket expansion too often. */ unsigned expand_mult; } UT_hash_bucket; /* random signature used only to find hash tables in external analysis */ #define HASH_SIGNATURE 0xa0111fe1 #define HASH_BLOOM_SIGNATURE 0xb12220f2 typedef struct UT_hash_table { UT_hash_bucket *buckets; unsigned num_buckets, log2_num_buckets; unsigned num_items; struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ /* in an ideal situation (all buckets used equally), no bucket would have * more than ceil(#items/#buckets) items. that's the ideal chain length. */ unsigned ideal_chain_maxlen; /* nonideal_items is the number of items in the hash whose chain position * exceeds the ideal chain maxlen. these items pay the penalty for an uneven * hash distribution; reaching them in a chain traversal takes >ideal steps */ unsigned nonideal_items; /* ineffective expands occur when a bucket doubling was performed, but * afterward, more than half the items in the hash had nonideal chain * positions. If this happens on two consecutive expansions we inhibit any * further expansion, as it's not helping; this happens when the hash * function isn't a good fit for the key domain. When expansion is inhibited * the hash will still work, albeit no longer in constant time. */ unsigned ineff_expands, noexpand; uint32_t signature; /* used only to find hash tables in external analysis */ #ifdef HASH_BLOOM uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ uint8_t *bloom_bv; char bloom_nbits; #endif } UT_hash_table; typedef struct UT_hash_handle { struct UT_hash_table *tbl; void *prev; /* prev element in app order */ void *next; /* next element in app order */ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ struct UT_hash_handle *hh_next; /* next hh in bucket order */ void *key; /* ptr to enclosing struct's key */ unsigned keylen; /* enclosing struct's key len */ unsigned hashv; /* result of hash-fcn(key) */ } UT_hash_handle; #endif /* UTHASH_H */ zevv-duc-b8f9659/src/libduc/utlist.h000066400000000000000000001524021426703022500173660ustar00rootroot00000000000000/* Copyright (c) 2007-2013, Troy D. Hanson http://uthash.sourceforge.net All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UTLIST_H #define UTLIST_H #define UTLIST_VERSION 1.9.7 #include /* * This file contains macros to manipulate singly and doubly-linked lists. * * 1. LL_ macros: singly-linked lists. * 2. DL_ macros: doubly-linked lists. * 3. CDL_ macros: circular doubly-linked lists. * * To use singly-linked lists, your structure must have a "next" pointer. * To use doubly-linked lists, your structure must "prev" and "next" pointers. * Either way, the pointer to the head of the list must be initialized to NULL. * * ----------------.EXAMPLE ------------------------- * struct item { * int id; * struct item *prev, *next; * } * * struct item *list = NULL: * * int main() { * struct item *item; * ... allocate and populate item ... * DL_APPEND(list, item); * } * -------------------------------------------------- * * For doubly-linked lists, the append and delete macros are O(1) * For singly-linked lists, append and delete are O(n) but prepend is O(1) * The sort macro is O(n log(n)) for all types of single/double/circular lists. */ /* These macros use decltype or the earlier __typeof GNU extension. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ when compiling c++ code), this code uses whatever method is needed or, for VS2008 where neither is available, uses casting workarounds. */ #ifdef _MSC_VER /* MS compiler */ #if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ #define LDECLTYPE(x) decltype(x) #else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE #define LDECLTYPE(x) char* #endif #else /* GNU, Sun and other compilers */ #define LDECLTYPE(x) __typeof(x) #endif /* for VS2008 we use some workarounds to get around the lack of decltype, * namely, we always reassign our tmp variable to the list head if we need * to dereference its prev/next pointers, and save/restore the real head.*/ #ifdef NO_DECLTYPE #define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } #define _NEXT(elt,list,next) ((char*)((list)->next)) #define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } /* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ #define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } #define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } #define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } #else #define _SV(elt,list) #define _NEXT(elt,list,next) ((elt)->next) #define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) /* #define _PREV(elt,list,prev) ((elt)->prev) */ #define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) #define _RS(list) #define _CASTASGN(a,b) (a)=(b) #endif /****************************************************************************** * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * * Unwieldy variable names used here to avoid shadowing passed-in variables. * *****************************************************************************/ #define LL_SORT(list, cmp) \ LL_SORT2(list, cmp, next) #define LL_SORT2(list, cmp, next) \ do { \ LDECLTYPE(list) _ls_p; \ LDECLTYPE(list) _ls_q; \ LDECLTYPE(list) _ls_e; \ LDECLTYPE(list) _ls_tail; \ LDECLTYPE(list) _ls_oldhead; \ LDECLTYPE(list) _tmp; \ int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ if (list) { \ _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ _CASTASGN(_ls_p,list); \ _CASTASGN(_ls_oldhead,list); \ list = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ _ls_nmerges++; \ _ls_q = _ls_p; \ _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ if (_ls_psize == 0) { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ } else if (_ls_qsize == 0 || !_ls_q) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ } else { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ } \ if (_ls_tail) { \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ } else { \ _CASTASGN(list,_ls_e); \ } \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ } \ _ls_insize *= 2; \ } \ } else _tmp=NULL; /* quiet gcc unused variable warning */ \ } while (0) #define DL_SORT(list, cmp) \ DL_SORT2(list, cmp, prev, next) #define DL_SORT2(list, cmp, prev, next) \ do { \ LDECLTYPE(list) _ls_p; \ LDECLTYPE(list) _ls_q; \ LDECLTYPE(list) _ls_e; \ LDECLTYPE(list) _ls_tail; \ LDECLTYPE(list) _ls_oldhead; \ LDECLTYPE(list) _tmp; \ int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ if (list) { \ _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ _CASTASGN(_ls_p,list); \ _CASTASGN(_ls_oldhead,list); \ list = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ _ls_nmerges++; \ _ls_q = _ls_p; \ _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ if (_ls_psize == 0) { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ } else if (_ls_qsize == 0 || !_ls_q) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ } else { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ } \ if (_ls_tail) { \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ } else { \ _CASTASGN(list,_ls_e); \ } \ _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ _CASTASGN(list->prev, _ls_tail); \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ } \ _ls_insize *= 2; \ } \ } else _tmp=NULL; /* quiet gcc unused variable warning */ \ } while (0) #define CDL_SORT(list, cmp) \ CDL_SORT2(list, cmp, prev, next) #define CDL_SORT2(list, cmp, prev, next) \ do { \ LDECLTYPE(list) _ls_p; \ LDECLTYPE(list) _ls_q; \ LDECLTYPE(list) _ls_e; \ LDECLTYPE(list) _ls_tail; \ LDECLTYPE(list) _ls_oldhead; \ LDECLTYPE(list) _tmp; \ LDECLTYPE(list) _tmp2; \ int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ if (list) { \ _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ _CASTASGN(_ls_p,list); \ _CASTASGN(_ls_oldhead,list); \ list = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ _ls_nmerges++; \ _ls_q = _ls_p; \ _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ _SV(_ls_q,list); \ if (_NEXT(_ls_q,list,next) == _ls_oldhead) { \ _ls_q = NULL; \ } else { \ _ls_q = _NEXT(_ls_q,list,next); \ } \ _RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ if (_ls_psize == 0) { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ } else if (_ls_qsize == 0 || !_ls_q) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ } else { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ } \ if (_ls_tail) { \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ } else { \ _CASTASGN(list,_ls_e); \ } \ _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ _CASTASGN(list->prev,_ls_tail); \ _CASTASGN(_tmp2,list); \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp2,next); _RS(list); \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ } \ _ls_insize *= 2; \ } \ } else _tmp=NULL; /* quiet gcc unused variable warning */ \ } while (0) /****************************************************************************** * singly linked list macros (non-circular) * *****************************************************************************/ #define LL_PREPEND(head,add) \ LL_PREPEND2(head,add,next) #define LL_PREPEND2(head,add,next) \ do { \ (add)->next = head; \ head = add; \ } while (0) #define LL_CONCAT(head1,head2) \ LL_CONCAT2(head1,head2,next) #define LL_CONCAT2(head1,head2,next) \ do { \ LDECLTYPE(head1) _tmp; \ if (head1) { \ _tmp = head1; \ while (_tmp->next) { _tmp = _tmp->next; } \ _tmp->next=(head2); \ } else { \ (head1)=(head2); \ } \ } while (0) #define LL_APPEND(head,add) \ LL_APPEND2(head,add,next) #define LL_APPEND2(head,add,next) \ do { \ LDECLTYPE(head) _tmp; \ (add)->next=NULL; \ if (head) { \ _tmp = head; \ while (_tmp->next) { _tmp = _tmp->next; } \ _tmp->next=(add); \ } else { \ (head)=(add); \ } \ } while (0) #define LL_DELETE(head,del) \ LL_DELETE2(head,del,next) #define LL_DELETE2(head,del,next) \ do { \ LDECLTYPE(head) _tmp; \ if ((head) == (del)) { \ (head)=(head)->next; \ } else { \ _tmp = head; \ while (_tmp->next && (_tmp->next != (del))) { \ _tmp = _tmp->next; \ } \ if (_tmp->next) { \ _tmp->next = ((del)->next); \ } \ } \ } while (0) /* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ #define LL_APPEND_VS2008(head,add) \ LL_APPEND2_VS2008(head,add,next) #define LL_APPEND2_VS2008(head,add,next) \ do { \ if (head) { \ (add)->next = head; /* use add->next as a temp variable */ \ while ((add)->next->next) { (add)->next = (add)->next->next; } \ (add)->next->next=(add); \ } else { \ (head)=(add); \ } \ (add)->next=NULL; \ } while (0) #define LL_DELETE_VS2008(head,del) \ LL_DELETE2_VS2008(head,del,next) #define LL_DELETE2_VS2008(head,del,next) \ do { \ if ((head) == (del)) { \ (head)=(head)->next; \ } else { \ char *_tmp = (char*)(head); \ while ((head)->next && ((head)->next != (del))) { \ head = (head)->next; \ } \ if ((head)->next) { \ (head)->next = ((del)->next); \ } \ { \ char **_head_alias = (char**)&(head); \ *_head_alias = _tmp; \ } \ } \ } while (0) #ifdef NO_DECLTYPE #undef LL_APPEND #define LL_APPEND LL_APPEND_VS2008 #undef LL_DELETE #define LL_DELETE LL_DELETE_VS2008 #undef LL_DELETE2 #define LL_DELETE2_VS2008 #undef LL_APPEND2 #define LL_APPEND2 LL_APPEND2_VS2008 #undef LL_CONCAT /* no LL_CONCAT_VS2008 */ #undef DL_CONCAT /* no DL_CONCAT_VS2008 */ #endif /* end VS2008 replacements */ #define LL_FOREACH(head,el) \ LL_FOREACH2(head,el,next) #define LL_FOREACH2(head,el,next) \ for(el=head;el;el=(el)->next) #define LL_FOREACH_SAFE(head,el,tmp) \ LL_FOREACH_SAFE2(head,el,tmp,next) #define LL_FOREACH_SAFE2(head,el,tmp,next) \ for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) #define LL_SEARCH_SCALAR(head,out,field,val) \ LL_SEARCH_SCALAR2(head,out,field,val,next) #define LL_SEARCH_SCALAR2(head,out,field,val,next) \ do { \ LL_FOREACH2(head,out,next) { \ if ((out)->field == (val)) break; \ } \ } while(0) #define LL_SEARCH(head,out,elt,cmp) \ LL_SEARCH2(head,out,elt,cmp,next) #define LL_SEARCH2(head,out,elt,cmp,next) \ do { \ LL_FOREACH2(head,out,next) { \ if ((cmp(out,elt))==0) break; \ } \ } while(0) #define LL_REPLACE_ELEM(head, el, add) \ do { \ LDECLTYPE(head) _tmp; \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ (add)->next = (el)->next; \ if ((head) == (el)) { \ (head) = (add); \ } else { \ _tmp = head; \ while (_tmp->next && (_tmp->next != (el))) { \ _tmp = _tmp->next; \ } \ if (_tmp->next) { \ _tmp->next = (add); \ } \ } \ } while (0) #define LL_PREPEND_ELEM(head, el, add) \ do { \ LDECLTYPE(head) _tmp; \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ (add)->next = (el); \ if ((head) == (el)) { \ (head) = (add); \ } else { \ _tmp = head; \ while (_tmp->next && (_tmp->next != (el))) { \ _tmp = _tmp->next; \ } \ if (_tmp->next) { \ _tmp->next = (add); \ } \ } \ } while (0) \ /****************************************************************************** * doubly linked list macros (non-circular) * *****************************************************************************/ #define DL_PREPEND(head,add) \ DL_PREPEND2(head,add,prev,next) #define DL_PREPEND2(head,add,prev,next) \ do { \ (add)->next = head; \ if (head) { \ (add)->prev = (head)->prev; \ (head)->prev = (add); \ } else { \ (add)->prev = (add); \ } \ (head) = (add); \ } while (0) #define DL_APPEND(head,add) \ DL_APPEND2(head,add,prev,next) #define DL_APPEND2(head,add,prev,next) \ do { \ if (head) { \ (add)->prev = (head)->prev; \ (head)->prev->next = (add); \ (head)->prev = (add); \ (add)->next = NULL; \ } else { \ (head)=(add); \ (head)->prev = (head); \ (head)->next = NULL; \ } \ } while (0) #define DL_CONCAT(head1,head2) \ DL_CONCAT2(head1,head2,prev,next) #define DL_CONCAT2(head1,head2,prev,next) \ do { \ LDECLTYPE(head1) _tmp; \ if (head2) { \ if (head1) { \ _tmp = (head2)->prev; \ (head2)->prev = (head1)->prev; \ (head1)->prev->next = (head2); \ (head1)->prev = _tmp; \ } else { \ (head1)=(head2); \ } \ } \ } while (0) #define DL_DELETE(head,del) \ DL_DELETE2(head,del,prev,next) #define DL_DELETE2(head,del,prev,next) \ do { \ assert((del)->prev != NULL); \ if ((del)->prev == (del)) { \ (head)=NULL; \ } else if ((del)==(head)) { \ (del)->next->prev = (del)->prev; \ (head) = (del)->next; \ } else { \ (del)->prev->next = (del)->next; \ if ((del)->next) { \ (del)->next->prev = (del)->prev; \ } else { \ (head)->prev = (del)->prev; \ } \ } \ } while (0) #define DL_FOREACH(head,el) \ DL_FOREACH2(head,el,next) #define DL_FOREACH2(head,el,next) \ for(el=head;el;el=(el)->next) /* this version is safe for deleting the elements during iteration */ #define DL_FOREACH_SAFE(head,el,tmp) \ DL_FOREACH_SAFE2(head,el,tmp,next) #define DL_FOREACH_SAFE2(head,el,tmp,next) \ for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) /* these are identical to their singly-linked list counterparts */ #define DL_SEARCH_SCALAR LL_SEARCH_SCALAR #define DL_SEARCH LL_SEARCH #define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 #define DL_SEARCH2 LL_SEARCH2 #define DL_REPLACE_ELEM(head, el, add) \ do { \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ if ((head) == (el)) { \ (head) = (add); \ (add)->next = (el)->next; \ if ((el)->next == NULL) { \ (add)->prev = (add); \ } else { \ (add)->prev = (el)->prev; \ (add)->next->prev = (add); \ } \ } else { \ (add)->next = (el)->next; \ (add)->prev = (el)->prev; \ (add)->prev->next = (add); \ if ((el)->next == NULL) { \ (head)->prev = (add); \ } else { \ (add)->next->prev = (add); \ } \ } \ } while (0) #define DL_PREPEND_ELEM(head, el, add) \ do { \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ (add)->next = (el); \ (add)->prev = (el)->prev; \ (el)->prev = (add); \ if ((head) == (el)) { \ (head) = (add); \ } else { \ (add)->prev->next = (add); \ } \ } while (0) \ /****************************************************************************** * circular doubly linked list macros * *****************************************************************************/ #define CDL_PREPEND(head,add) \ CDL_PREPEND2(head,add,prev,next) #define CDL_PREPEND2(head,add,prev,next) \ do { \ if (head) { \ (add)->prev = (head)->prev; \ (add)->next = (head); \ (head)->prev = (add); \ (add)->prev->next = (add); \ } else { \ (add)->prev = (add); \ (add)->next = (add); \ } \ (head)=(add); \ } while (0) #define CDL_DELETE(head,del) \ CDL_DELETE2(head,del,prev,next) #define CDL_DELETE2(head,del,prev,next) \ do { \ if ( ((head)==(del)) && ((head)->next == (head))) { \ (head) = 0L; \ } else { \ (del)->next->prev = (del)->prev; \ (del)->prev->next = (del)->next; \ if ((del) == (head)) (head)=(del)->next; \ } \ } while (0) #define CDL_FOREACH(head,el) \ CDL_FOREACH2(head,el,next) #define CDL_FOREACH2(head,el,next) \ for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) #define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ (el) && ((tmp2)=(el)->next, 1); \ ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) #define CDL_SEARCH_SCALAR(head,out,field,val) \ CDL_SEARCH_SCALAR2(head,out,field,val,next) #define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ do { \ CDL_FOREACH2(head,out,next) { \ if ((out)->field == (val)) break; \ } \ } while(0) #define CDL_SEARCH(head,out,elt,cmp) \ CDL_SEARCH2(head,out,elt,cmp,next) #define CDL_SEARCH2(head,out,elt,cmp,next) \ do { \ CDL_FOREACH2(head,out,next) { \ if ((cmp(out,elt))==0) break; \ } \ } while(0) #define CDL_REPLACE_ELEM(head, el, add) \ do { \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ if ((el)->next == (el)) { \ (add)->next = (add); \ (add)->prev = (add); \ (head) = (add); \ } else { \ (add)->next = (el)->next; \ (add)->prev = (el)->prev; \ (add)->next->prev = (add); \ (add)->prev->next = (add); \ if ((head) == (el)) { \ (head) = (add); \ } \ } \ } while (0) #define CDL_PREPEND_ELEM(head, el, add) \ do { \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ (add)->next = (el); \ (add)->prev = (el)->prev; \ (el)->prev = (add); \ (add)->prev->next = (add); \ if ((head) == (el)) { \ (head) = (add); \ } \ } while (0) \ #endif /* UTLIST_H */ zevv-duc-b8f9659/src/libduc/utstring.h000066400000000000000000000264431426703022500177260ustar00rootroot00000000000000/* Copyright (c) 2008-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* a dynamic string implementation using macros */ #ifndef UTSTRING_H #define UTSTRING_H #define UTSTRING_VERSION 1.9.9 #ifdef __GNUC__ #define _UNUSED_ __attribute__ ((__unused__)) #else #define _UNUSED_ #endif #include #include #include #include #define oom() exit(-1) typedef struct { char *d; size_t n; /* allocd size */ size_t i; /* index of first unused byte */ } UT_string; #define utstring_reserve(s,amt) \ do { \ if (((s)->n - (s)->i) < (size_t)(amt)) { \ (s)->d = (char*)realloc((s)->d, (s)->n + amt); \ if ((s)->d == NULL) oom(); \ (s)->n += amt; \ } \ } while(0) #define utstring_init(s) \ do { \ (s)->n = 0; (s)->i = 0; (s)->d = NULL; \ utstring_reserve(s,100); \ (s)->d[0] = '\0'; \ } while(0) #define utstring_done(s) \ do { \ if ((s)->d != NULL) free((s)->d); \ (s)->n = 0; \ } while(0) #define utstring_free(s) \ do { \ utstring_done(s); \ free(s); \ } while(0) #define utstring_new(s) \ do { \ s = (UT_string*)calloc(sizeof(UT_string),1); \ if (!s) oom(); \ utstring_init(s); \ } while(0) #define utstring_renew(s) \ do { \ if (s) { \ utstring_clear(s); \ } else { \ utstring_new(s); \ } \ } while(0) #define utstring_clear(s) \ do { \ (s)->i = 0; \ (s)->d[0] = '\0'; \ } while(0) #define utstring_bincpy(s,b,l) \ do { \ utstring_reserve((s),(l)+1); \ if (l) memcpy(&(s)->d[(s)->i], b, l); \ (s)->i += l; \ (s)->d[(s)->i]='\0'; \ } while(0) #define utstring_concat(dst,src) \ do { \ utstring_reserve((dst),((src)->i)+1); \ if ((src)->i) memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \ (dst)->i += (src)->i; \ (dst)->d[(dst)->i]='\0'; \ } while(0) #define utstring_len(s) ((unsigned)((s)->i)) #define utstring_body(s) ((s)->d) _UNUSED_ static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) { int n; va_list cp; while (1) { #ifdef _WIN32 cp = ap; #else va_copy(cp, ap); #endif n = vsnprintf (&s->d[s->i], s->n-s->i, fmt, cp); va_end(cp); if ((n > -1) && ((size_t) n < (s->n-s->i))) { s->i += n; return; } /* Else try again with more space. */ if (n > -1) utstring_reserve(s,n+1); /* exact */ else utstring_reserve(s,(s->n)*2); /* 2x */ } } #ifdef __GNUC__ /* support printf format checking (2=the format string, 3=start of varargs) */ static void utstring_printf(UT_string *s, const char *fmt, ...) __attribute__ (( format( printf, 2, 3) )); #endif _UNUSED_ static void utstring_printf(UT_string *s, const char *fmt, ...) { va_list ap; va_start(ap,fmt); utstring_printf_va(s,fmt,ap); va_end(ap); } /******************************************************************************* * begin substring search functions * ******************************************************************************/ /* Build KMP table from left to right. */ _UNUSED_ static void _utstring_BuildTable( const char *P_Needle, size_t P_NeedleLen, long *P_KMP_Table) { long i, j; i = 0; j = i - 1; P_KMP_Table[i] = j; while (i < (long) P_NeedleLen) { while ( (j > -1) && (P_Needle[i] != P_Needle[j]) ) { j = P_KMP_Table[j]; } i++; j++; if (i < (long) P_NeedleLen) { if (P_Needle[i] == P_Needle[j]) { P_KMP_Table[i] = P_KMP_Table[j]; } else { P_KMP_Table[i] = j; } } else { P_KMP_Table[i] = j; } } return; } /* Build KMP table from right to left. */ _UNUSED_ static void _utstring_BuildTableR( const char *P_Needle, size_t P_NeedleLen, long *P_KMP_Table) { long i, j; i = P_NeedleLen - 1; j = i + 1; P_KMP_Table[i + 1] = j; while (i >= 0) { while ( (j < (long) P_NeedleLen) && (P_Needle[i] != P_Needle[j]) ) { j = P_KMP_Table[j + 1]; } i--; j--; if (i >= 0) { if (P_Needle[i] == P_Needle[j]) { P_KMP_Table[i + 1] = P_KMP_Table[j + 1]; } else { P_KMP_Table[i + 1] = j; } } else { P_KMP_Table[i + 1] = j; } } return; } /* Search data from left to right. ( Multiple search mode. ) */ _UNUSED_ static long _utstring_find( const char *P_Haystack, size_t P_HaystackLen, const char *P_Needle, size_t P_NeedleLen, long *P_KMP_Table) { long i, j; long V_FindPosition = -1; /* Search from left to right. */ i = j = 0; while ( (j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen) ) { while ( (i > -1) && (P_Needle[i] != P_Haystack[j]) ) { i = P_KMP_Table[i]; } i++; j++; if (i >= (int)P_NeedleLen) { /* Found. */ V_FindPosition = j - i; break; } } return V_FindPosition; } /* Search data from right to left. ( Multiple search mode. ) */ _UNUSED_ static long _utstring_findR( const char *P_Haystack, size_t P_HaystackLen, const char *P_Needle, size_t P_NeedleLen, long *P_KMP_Table) { long i, j; long V_FindPosition = -1; /* Search from right to left. */ j = (P_HaystackLen - 1); i = (P_NeedleLen - 1); while ( (j >= 0) && (j >= i) ) { while ( (i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j]) ) { i = P_KMP_Table[i + 1]; } i--; j--; if (i < 0) { /* Found. */ V_FindPosition = j + 1; break; } } return V_FindPosition; } /* Search data from left to right. ( One time search mode. ) */ _UNUSED_ static long utstring_find( UT_string *s, long P_StartPosition, /* Start from 0. -1 means last position. */ const char *P_Needle, size_t P_NeedleLen) { long V_StartPosition; long V_HaystackLen; long *V_KMP_Table; long V_FindPosition = -1; if (P_StartPosition < 0) { V_StartPosition = s->i + P_StartPosition; } else { V_StartPosition = P_StartPosition; } V_HaystackLen = s->i - V_StartPosition; if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) ) { V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1)); if (V_KMP_Table != NULL) { _utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table); V_FindPosition = _utstring_find(s->d + V_StartPosition, V_HaystackLen, P_Needle, P_NeedleLen, V_KMP_Table); if (V_FindPosition >= 0) { V_FindPosition += V_StartPosition; } free(V_KMP_Table); } } return V_FindPosition; } /* Search data from right to left. ( One time search mode. ) */ _UNUSED_ static long utstring_findR( UT_string *s, long P_StartPosition, /* Start from 0. -1 means last position. */ const char *P_Needle, size_t P_NeedleLen) { long V_StartPosition; long V_HaystackLen; long *V_KMP_Table; long V_FindPosition = -1; if (P_StartPosition < 0) { V_StartPosition = s->i + P_StartPosition; } else { V_StartPosition = P_StartPosition; } V_HaystackLen = V_StartPosition + 1; if ( (V_HaystackLen >= (long) P_NeedleLen) && (P_NeedleLen > 0) ) { V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1)); if (V_KMP_Table != NULL) { _utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table); V_FindPosition = _utstring_findR(s->d, V_HaystackLen, P_Needle, P_NeedleLen, V_KMP_Table); free(V_KMP_Table); } } return V_FindPosition; } /******************************************************************************* * end substring search functions * ******************************************************************************/ #endif /* UTSTRING_H */ zevv-duc-b8f9659/src/libduc/varint.c000066400000000000000000000146021426703022500173370ustar00rootroot00000000000000 #include "config.h" /* ** 2012 January 17 ** ** The authors renounce all claim of copyright to this code and dedicate ** this code to the public domain. In place of legal notice, here is ** a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains routines used to encode or decode variable-length ** integers. ** ** A variable length integer is an encoding of 64-bit unsigned integers ** into between 1 and 9 bytes. The encoding is designed so that small ** (and common) values take much less space that larger values. Additional ** properties: ** ** * The length of the varint can be determined after examining just ** the first byte of the encoding. ** ** * Varints compare in numerical order using memcmp(). ** ************************************************************************** ** ** Treat each byte of the encoding as an unsigned integer between 0 and 255. ** Let the bytes of the encoding be called A0, A1, A2, ..., A8. ** ** DECODE ** ** If A0 is between 0 and 240 inclusive, then the result is the value of A0. ** ** If A0 is between 241 and 248 inclusive, then the result is ** 240+256*(A0-241)+A1. ** ** If A0 is 249 then the result is 2288+256*A1+A2. ** ** If A0 is 250 then the result is A1..A3 as a 3-byte big-ending integer. ** ** If A0 is 251 then the result is A1..A4 as a 4-byte big-ending integer. ** ** If A0 is 252 then the result is A1..A5 as a 5-byte big-ending integer. ** ** If A0 is 253 then the result is A1..A6 as a 6-byte big-ending integer. ** ** If A0 is 254 then the result is A1..A7 as a 7-byte big-ending integer. ** ** If A0 is 255 then the result is A1..A8 as an 8-byte big-ending integer. ** ** ENCODE ** ** Let the input value be V. ** ** If V<=240 then output a single by A0 equal to V. ** ** If V<=2287 then output A0 as (V-240)/256 + 241 and A1 as (V-240)%256. ** ** If V<=67823 then output A0 as 249, A1 as (V-2288)/256, and A2 ** as (V-2288)%256. ** ** If V<=16777215 then output A0 as 250 and A1 through A3 as a big-endian ** 3-byte integer. ** ** If V<=4294967295 then output A0 as 251 and A1..A4 as a big-ending ** 4-byte integer. ** ** If V<=1099511627775 then output A0 as 252 and A1..A5 as a big-ending ** 5-byte integer. ** ** If V<=281474976710655 then output A0 as 253 and A1..A6 as a big-ending ** 6-byte integer. ** ** If V<=72057594037927935 then output A0 as 254 and A1..A7 as a ** big-ending 7-byte integer. ** ** Otherwise then output A0 as 255 and A1..A8 as a big-ending 8-byte integer. ** ** SUMMARY ** ** Bytes Max Value Digits ** ------- --------- --------- ** 1 240 2.3 ** 2 2287 3.3 ** 3 67823 4.8 ** 4 2**24-1 7.2 ** 5 2**32-1 9.6 ** 6 2**40-1 12.0 ** 7 2**48-1 14.4 ** 8 2**56-1 16.8 ** 9 2**64-1 19.2 ** */ /* ** Decode the varint in the first n bytes z[]. Write the integer value ** into *pResult and return the number of bytes in the varint. ** ** If the decode fails because there are not enough bytes in z[] then ** return 0; */ #include #include "varint.h" int GetVarint64( const uint8_t *z, int n, uint64_t *pResult ){ unsigned int x; if( n<1 ) return 0; if( z[0]<=240 ){ *pResult = z[0]; return 1; } if( z[0]<=248 ){ if( n<2 ) return 0; *pResult = (z[0]-241)*256 + z[1] + 240; return 2; } if( n>24); z[1] = (uint8_t)(y>>16); z[2] = (uint8_t)(y>>8); z[3] = (uint8_t)(y); } /* ** Write a varint into z[]. The buffer z[] must be at least 9 characters ** long to accommodate the largest possible varint. Return the number of ** bytes of z[] used. */ int PutVarint64(uint8_t *z, uint64_t x){ unsigned int w, y; if( x<=240 ){ z[0] = (uint8_t)x; return 1; } if( x<=2287 ){ y = (unsigned int)(x - 240); z[0] = (uint8_t)(y/256 + 241); z[1] = (uint8_t)(y%256); return 2; } if( x<=67823 ){ y = (unsigned int)(x - 2288); z[0] = 249; z[1] = (uint8_t)(y/256); z[2] = (uint8_t)(y%256); return 3; } y = (unsigned int)x; w = (unsigned int)(x>>32); if( w==0 ){ if( y<=16777215 ){ z[0] = 250; z[1] = (uint8_t)(y>>16); z[2] = (uint8_t)(y>>8); z[3] = (uint8_t)(y); return 4; } z[0] = 251; varintWrite32(z+1, y); return 5; } if( w<=255 ){ z[0] = 252; z[1] = (uint8_t)w; varintWrite32(z+2, y); return 6; } if( w<=65535 ){ z[0] = 253; z[1] = (uint8_t)(w>>8); z[2] = (uint8_t)w; varintWrite32(z+3, y); return 7; } if( w<=16777215 ){ z[0] = 254; z[1] = (uint8_t)(w>>16); z[2] = (uint8_t)(w>>8); z[3] = (uint8_t)w; varintWrite32(z+4, y); return 8; } z[0] = 255; varintWrite32(z+1, w); varintWrite32(z+5, y); return 9; } /* ** Return the number of bytes required to encode value v as a varint. */ int VarintLen(uint64_t v){ uint8_t aDummy[9]; return PutVarint64(aDummy, v); } /* ** Read a varint from buffer z and set *pResult to the value read. ** Return the number of bytes read from the buffer. */ int GetVarint32(const uint8_t *z, uint32_t *pResult){ uint64_t iRes; int ret; ret = GetVarint64(z, 9, &iRes); *pResult = (uint32_t)iRes; return ret; } /* ** Encode v as a varint and write the result to buffer p. Return the ** number of bytes written. */ int PutVarint32(uint8_t *p, uint32_t v){ return PutVarint64(p, v); } /* * End */ zevv-duc-b8f9659/src/libduc/varint.h000066400000000000000000000004131426703022500173370ustar00rootroot00000000000000#ifndef varint_h #define varint_h int GetVarint64(const uint8_t *z, int n, uint64_t *pResult); int PutVarint64(uint8_t *z, uint64_t x); int GetVarint32(const uint8_t *z, uint32_t *pResult); int PutVarint32(uint8_t *p, uint32_t v); int VarintLen(uint64_t v); #endif zevv-duc-b8f9659/test.sh000077500000000000000000000123761426703022500151630ustar00rootroot00000000000000#!/bin/sh export DUC_DATABASE=/tmp/duc-test.db DUC_TEST_DIR=/tmp/duc-test # Set to 0 to allow valgrind use DEF_USE_VALGRIND=0 # Run with USE_VALGRIND=1 ./test.sh DO_VALGRIND=${USE_VALGRIND:=$DEF_USE_VALGRIND} valargs="--quiet \ --suppressions=valgrind-suppressions \ --leak-check=full \ --leak-check=full \ --show-leak-kinds=all \ --num-callers=30 \ --error-exitcode=1 \ " # Check for valgrind only if asked to use it. valgrind="" if [ "${DO_VALGRIND}" = "1" ]; then hash valgrind 2>/dev/null if [ $? -eq 1 ]; then echo "Error! Valgrind not installed, can't run with \$DO_VALGRIND set." exit 1 else echo "Using valgrind with : $valargs" echo "" valgrind="valgrind $valargs" fi fi mkfile() { mkdir -p "`dirname \"$1\"`" dd if=/dev/zero of="$1" bs=1 count=$2 2> /dev/null } rm -rf $DUC_DATABASE $DUC_TEST_DIR mkdir $DUC_TEST_DIR # Regular files mkfile ${DUC_TEST_DIR}/tree/one 100 mkfile ${DUC_TEST_DIR}/tree/two 100 mkfile ${DUC_TEST_DIR}/tree/three 100 mkfile ${DUC_TEST_DIR}/tree/four 100 mkfile ${DUC_TEST_DIR}/tree/sub1/alpha 100 mkfile ${DUC_TEST_DIR}/tree/sub1/bravo 1000 mkfile ${DUC_TEST_DIR}/tree/sub1/charlie 1000 mkfile ${DUC_TEST_DIR}/tree/sub1/delta 10000 mkfile ${DUC_TEST_DIR}/tree/sub2/echo 100 mkfile ${DUC_TEST_DIR}/tree/sub2/foxtrot 1000 mkfile ${DUC_TEST_DIR}/tree/sub2/golf 1000 mkfile ${DUC_TEST_DIR}/tree/sub2/hotel 10000 mkfile ${DUC_TEST_DIR}/tree/sub3/india 5000 mkfile ${DUC_TEST_DIR}/tree/sub3/juliet 4000 mkfile ${DUC_TEST_DIR}/tree/sub4/kilo 1000 mkfile ${DUC_TEST_DIR}/tree/sub4/lima 2000 mkfile ${DUC_TEST_DIR}/tree/sub4/mike 3000 mkfile ${DUC_TEST_DIR}/tree/sub4/november 5000 # Hard link mkdir ${DUC_TEST_DIR}/hard-link mkfile ${DUC_TEST_DIR}/hard-link/one 10000 ln ${DUC_TEST_DIR}/hard-link/one ${DUC_TEST_DIR}/hard-link/two ln ${DUC_TEST_DIR}/hard-link/one ${DUC_TEST_DIR}/hard-link/three # Sparse file mkdir ${DUC_TEST_DIR}/sparse dd if=/dev/zero of=${DUC_TEST_DIR}/sparse/first bs=1 count=1 seek=32K 2> /dev/null # Potentional problematic characters mkfile "${DUC_TEST_DIR}/strange/cgi-space-%20-dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/newline- -dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/tab- -dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/space- -dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/carriage-return- -dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/question-mark-?-dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/control-a--dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/escape--dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/less-then-<-dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/more-then->-dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/ampersand-&-dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/single-quote-'-dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/double-quote-\"-dir/file" 100 mkfile "${DUC_TEST_DIR}/strange/backslash-\\-dir/file" 100 # UTF-8 characters mkfile ${DUC_TEST_DIR}/utf-8/оживлённым/foo 100 mkfile ${DUC_TEST_DIR}/utf-8/有朋自遠方來/foo 100 mkfile ${DUC_TEST_DIR}/utf-8/♜♞♝♛♚♝♞♜/foo 100 # Deep and long named directories x=1 long="some_stupidly_long_directory_name_I_just_made_up" current=`pwd` cd $DUC_TEST_DIR while [ $x -le 20 ]; do #echo mkdir ${long}${x} mkdir ${long}${x} #echo cd ${long}${x} cd ${long}${x} dd if=/dev/zero of=longone bs=1 count=40 2> /dev/null dd if=/dev/zero of=longtwo bs=1 count=100 2> /dev/null x=`expr $x + 1` done cd $current # Create index $valgrind ./duc index --debug --check-hard-links --bytes --verbose ${DUC_TEST_DIR} > ${DUC_TEST_DIR}.out 2>&1 if [ "$?" != "0" ]; then echo "valgrind error" cat ${DUC_TEST_DIR}.out exit 1 fi #--------------------------------------------------------------------------------- # Actual tests are below. If you add test cases above, these need to be tweaked. #--------------------------------------------------------------------------------- cat ${DUC_TEST_DIR}.out | grep -q "Indexed 77 files and 47 directories, (91869B apparent, 540672B actual)" if [ "$?" = "0" ]; then echo "report: ok" else echo "-----------------------------" echo "report failed" echo "-----------------------------" echo "" cat ${DUC_TEST_DIR}.out echo "" exit 1 fi $valgrind ./duc ls -aR ${DUC_TEST_DIR} > ${DUC_TEST_DIR}.out 2>&1 if [ "$?" != "0" ]; then echo "valgrind error" cat ${DUC_TEST_DIR}.out exit 1 fi testsum="33e2be27a9e70e81d4006a2d7b555948" md5sum ${DUC_TEST_DIR}.out > /tmp/.duc.md5sum grep -q $testsum /tmp/.duc.md5sum if [ "$?" = "0" ]; then echo "md5sum: ok" else echo "md5sum: failed" echo "expected: " echo "$testsum ${DUC_TEST_DIR}.out" echo "got: " cat /tmp/.duc.md5sum exit 1 fi # Test backend checking. ductype=`./duc --version | tail -1 | awk '{print $NF}'` typemax=5 typecount=0 for type in leveldb lmdb tokyocabinet kyotocabinet sqlite; do if [ "$ductype" != "$type" ]; then #echo "./duc info -d test/dbs/${type}.db" ./duc info -d test/dbs/${type}.db > ${DUC_TEST_DIR}.out 2>&1 if [ "$?" = "1" ]; then typecount=`expr $typecount + 1` fi else echo "skipping DB type $ductype, we are compiled with that type." > ${DUC_TEST_DIR}.out 2>&1 fi done if [ "$typecount" = "4" ]; then echo "DB Types: ok" else echo "Type checks: failed - got $typecount failures instead of expected 4 out of $typemax." fi # end zevv-duc-b8f9659/testing/000077500000000000000000000000001426703022500153115ustar00rootroot00000000000000zevv-duc-b8f9659/testing/dbs/000077500000000000000000000000001426703022500160615ustar00rootroot00000000000000zevv-duc-b8f9659/testing/dbs/kyotocabinet.db000066400000000000000000014210001426703022500210610ustar00rootroot00000000000000KC  1 "!@`@ `#TF3Aif4q#)??R I1cdNK6472230HdBp ̙UL3cdOK6472230HYR.,i9)?Y$&5)DI%BMa5D1$BjPcBS"ԘP̂kL2O`߶*!3!(Sa c/޼XXpӋxЋt'cb?0 x!z'ٜK[yڦ_)Oc{g/3YM%="weؙx#Y~s|gȍ5smc}Zyekշ;ړw3j\-WKϪiM N5% uH}dEdގI{z|VL. R0]R~)jfQK⒒K.^RCYHRcTx09k?VHm%BmQaEAbj fa;:L5*H([+ccӠ I`4PNEʛ(bLW)_A~zZS1x9FYj&*Ac@c>bT)U)/^`PV~r_`YlT`;ݟ{m]6m :2mI$&ZO u㳰"F}CMt!Gw> 0dЊ.Pc;3x E;j|-Y{dгGĶ\gzӦBKW@a峡PSm bL1=o@p'qޚ$- j+SAb a.%qc߹wH TH F># H|T!N <ɾݣj-Sn55,DYSaY77> _^ErT=fV8 \،6k'/јM-rdp1.T] C5FԴ_ ȯWZ:@1'<Q5XMG]rBԻ`:.jQj>\cn!Ǧu}YmW7s!ٖsl8 ĔcpE k6|v WK'.Z#׻WS٬׺;M(/ɌZczFɊMU/i.hކZjDitoFt.g=eq0oOأEG6p|;)9U$qktb]v$9QǜI[SljXͼ q*ޤ} Wv_lgܧҟvg!|\4)E;OkOM\x˕ɼy>f]\VT\ }Bѝd8_يhp( s;A~hP=_`#\`jdxq{]I&snAHS4rLaTNFJ`GOb!BG jfFoZO30ZN9a1%zevv-duc-b8f9659/testing/dbs/lmdb.db000066400000000000000000000272471426703022500173220ustar00rootroot00000000000000@@@@1 Bf*  n D  r H  z 80($  i fc12/22601f""`^rlongone(longtwod1some_stupidly_long_directory_name_I_just_made_up50""` i fc12/226020""`^rlongone(1some_stupidly_long_directory_name_I_just_made_up6D-""`!longtwodi fc12/226021""` ^rlongone(1some_stupidly_long_directory_name_I_just_made_up7*""`"longtwodi fc12/226022""`!^rlongone(longtwod1some_stupidly_long_directory_name_I_just_made_up8,p'""`#i fc12/226023""`"^rlongone(longtwod1some_stupidly_long_directory_name_I_just_made_up9@$""`$j fc12/226024""`#^rlongone(longtwod2some_stupidly_long_directory_name_I_just_made_up10!""`%j fc12/226025""`$^rlongone(longtwod2some_stupidly_long_directory_name_I_just_made_up11""`&j fc12/226026""`%^rlongone(2some_stupidly_long_directory_name_I_just_made_up12""`'longtwodj fc12/226027""`&^rlongone(longtwod2some_stupidly_long_directory_name_I_just_made_up13p""`(j fc12/226028""`'^rlongone(2some_stupidly_long_directory_name_I_just_made_up14P""`)longtwodj fc12/226029""`(^r2some_stupidly_long_directory_name_I_just_made_up15X ""`*longone(longtwodi fc12/22602a""`)^rlongone(longtwod2some_stupidly_long_directory_name_I_just_made_up16""`+i fc12/22602b""`*^rlongone(longtwod2some_stupidly_long_directory_name_I_just_made_up17@ ""`,i fc12/22602c""`+^rlongone(longtwod2some_stupidly_long_directory_name_I_just_made_up18 ""`-i fc12/22602d""`,^rlongone(2some_stupidly_long_directory_name_I_just_made_up19(W""`.longtwodh fc12/22602e""`-^rlongone(longtwod2some_stupidly_long_directory_name_I_just_made_up20'""`/( fc12/20 /tmp/duc-test /tmp/duc-test""`^s^s$LM/f@|"@duc_index_reports2 fc12/226001^rstrange""` sparsew""`treeH""`utf-8-dird""` tab- -dird""` control-a--dird""`double-quote-"-dird""`ampersand-&-dird""` escape--dird""`carriage-return- -dird""` newline- -dird""` backslash-\-dird""`less-then-<-dird""`cgi-space-%20-dird""` space- -dird""` single-quote-'-dird""` fc12/226008""`^rfirstw fc12/226007""`^rthree 'B fc12/226006""`^rkilomikelimanovember ) fc12/226005""`^rindia zevv-duc-b8f9659/testing/dbs/sqlite3.db000066400000000000000000000455231426703022500177650ustar00rootroot00000000000000SQLite format 3@  .B NN4KindexkeysblobsCREATE INDEX keys on blobs(key)GotableblobsblobsCREATE TABLE blobs(key unique primary key, value))=indexsqlite_autoindex_blobs_1blobs, 1 aAq1Q!aq ! 1 A Q a q !1AQ'/tmp/duc-test1/duc_index_reports0#fc12/226001/#fc12/22601c.#fc12/22601d-#fc12/22601e,#fc12/22601f+#fc12/226020*#fc12/226021)#fc12/226022(#fc12/226023'#fc12/226024&#fc12/226025%#fc12/226026$#fc12/226027##fc12/226028"#fc12/226029!#fc12/22602a #fc12/22602b#fc12/22602c#fc12/22602d#fc12/22602e#fc12/22602f#fc12/226007#fc12/226018#fc12/22601b#fc12/22601a#fc12/226019#fc12/226002#fc12/226005#fc12/226006#fc12/226004#fc12/226003#fc12/226008#fc12/226009#fc12/226015#fc12/22600d #fc12/22600a #fc12/226012 #fc12/226017 #fc12/22600b #fc12/22600e#fc12/226011#fc12/226014#fc12/226016#fc12/226010#fc12/22600c#fc12/226013# fc12/22600f 1 aAq1Q!aq ! 1 A Q a q !1AQ'/tmp/duc-test1/duc_index_reports0#fc12/226001/#fc12/22601c.#fc12/22601d-#fc12/22601e,#fc12/22601f+#fc12/226020*#fc12/226021)#fc12/226022(#fc12/226023'#fc12/226024&#fc12/226025%#fc12/226026$#fc12/226027##fc12/226028"#fc12/226029!#fc12/22602a #fc12/22602b#fc12/22602c#fc12/22602d#fc12/22602e#fc12/22602f#fc12/226007#fc12/226018#fc12/22601b#fc12/22601a#fc12/226019#fc12/226002#fc12/226005#fc12/226006#fc12/226004#fc12/226003#fc12/226008#fc12/226009#fc12/226015#fc12/22600d #fc12/22600a #fc12/226012 #fc12/226017 #fc12/22600b #fc12/22600e#fc12/226011#fc12/226014#fc12/226016#fc12/226010#fc12/22600c#fc12/226013# fc12/22600f ,d=zS, ' Y  4  < amy)5y,#`fc12/22601e""`^1some_stupidly_long_directory_name_I_just_made_up4\03""`longone(longtwodx+#^fc12/22601f""`^longone(longtwod1some_stupidly_long_directory_name_I_just_made_up50""` x*#^fc12/226020""`^longone(1some_stupidly_long_directory_name_I_just_made_up6D-""`!longtwodx)#^fc12/226021""` ^longone(1some_stupidly_long_directory_name_I_just_made_up7*""`"longtwodx(#^fc12/226022""`!^longone(longtwod1some_stupidly_long_directory_name_I_just_made_up8,p'""`#x'#^fc12/226023""`"^longone(longtwod1some_stupidly_long_directory_name_I_just_made_up9@$""`$y&#`fc12/226024""`#^longone(longtwod2some_stupidly_long_directory_name_I_just_made_up10!""`%y%#`fc12/226025""`$^longone(longtwod2some_stupidly_long_directory_name_I_just_made_up11""`&y$#`fc12/226026""`%^longone(2some_stupidly_long_directory_name_I_just_made_up12""`'longtwody##`fc12/226027""`&^longone(longtwod2some_stupidly_long_directory_name_I_just_made_up13p""`(y"#`fc12/226028""`'^longone(2some_stupidly_long_directory_name_I_just_made_up14P""`)longtwody!#`fc12/226029""`(^2some_stupidly_long_directory_name_I_just_made_up15X ""`*longone(longtwodx #^fc12/22602a""`)^longone(longtwod2some_stupidly_long_directory_name_I_just_made_up16""`+x#^fc12/22602b""`*^longone(longtwod2some_stupidly_long_directory_name_I_just_made_up17@ ""`,x#^fc12/22602c""`+^longone(longtwod2some_stupidly_long_directory_name_I_just_made_up18 ""`-x#^fc12/22602d""`,^longone(2some_stupidly_long_directory_name_I_just_made_up19(W""`.longtwodw#\fc12/22602e""`-^longone(longtwod2some_stupidly_long_directory_name_I_just_made_up20'""`/6#\fc12/22602f""`.^longone(longtwod(#@fc12/226007""`^three '#tfc12/226018""`^оживлённымd""`有朋自遠方來d""`♜♞♝♛♚♝♞♜d""`$#8fc12/22601b""`^food$#8fc12/22601a""`^food$#8fc12/226019""`^food#fc12/226002""`^fourdthreedsub1&Tg""`sub2&Tg""`twodsub4"W""`onedsub387""`7#^fc12/226005""`^india julietQ#fc12/226006""`^kilomikelimanovember zevv-duc-b8f9659/testing/dbs/tokyocabinet.db000066400000000000000000010144001426703022500210630ustar00rootroot00000000000000ToKyO CaBiNeT 1.0:911  2V3cdgHK6472230HYR.g,i9)?YQ%(E)(J%FQ QdH"#bȄE(2á1=o@p;qiUAb8IK[ *&ؐXb_k;|vfHHLBA8S7{h-[ni z ۷"R'L?wuP՞fpi"$嬹U;;GBɉG]XV\[kjkyf]@]D(NI IZXģC BSLWc'Vإb 9ky|SrRckTKqql2=_*61}dAWR:MnDᾰ|UT/l56n+sqp59fd!b#TD`i;W6Ns{5ÎʼCiԤM':k |㨴1QqƋ b~Wq˝θD[()_YMaw*z-Knj3Sgܪ> 2׷uⶉ/-%m%\ƛ=1CT÷rߗlb}HE9C.}t/x+ T0t'nbzxbq0au~!hzDHl/ia餶`a!($C)eFßAtT՗=$.V"et;pfu) ,nt)AyNR=?t}2O`߶*!3!(Sa c/޼XXpӋxЋt=cx(Y# Ճ=f,nmoi~@锌1Jr=3ډt&GN &o8+oUe㹹fm_U2 |#vV~\+l-R{ys!~]-7jU:8<-A9 Ѹ %I#3"3dR=Y=wGi>+'M)|F.)5 }qI%)ł,$UM)1 * 1jÆylbB41Sap9;^?E4+6nd=w4q7 2MʽC@Uah.S>rƅ":2oI,& 㳸"F}@&; (MڰВ.`c;3xw ,6hB>rC<] t~Z,=%^QiBNI c#1cdNK6472230HdBp zevv-duc-b8f9659/todo000066400000000000000000000002101426703022500145150ustar00rootroot00000000000000 - try to open with O_NOATIME if proper capabilities available - parallel indexing - add import feature for loading output of gnu find zevv-duc-b8f9659/valgrind-suppressions000066400000000000000000000001041426703022500201330ustar00rootroot00000000000000{ all dl_init Memcheck:Leak ... fun:_dl_init obj:* }