diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-15 18:23:18 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-15 18:23:18 +0000 |
commit | 3133bbc63a2d32dac638db58fa13e966488e88b5 (patch) | |
tree | 326595b5fefc87fd7cf5ab3905bc00883fe3c919 /lib | |
download | kchmviewer-3133bbc63a2d32dac638db58fa13e966488e88b5.tar.gz kchmviewer-3133bbc63a2d32dac638db58fa13e966488e88b5.zip |
Added abandoned KDE3 version of kchmviewer
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kchmviewer@1090662 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib')
32 files changed, 9755 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..0a215da --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,17 @@ +if AMC_USE_KDE +SUBDIR_KIO = kio-msits +endif + +if AMC_BUILD_CHMLIB +SUBDIR_CHMLIB = chmlib +endif + +SUBDIRS = $(SUBDIR_CHMLIB) $(SUBDIR_KIO) libchmfile +DIST_SUBDIRS = chmlib kio-msits libchmfile + +package-messages: + $(MAKE) -f admin/Makefile.common package-messages + $(MAKE) -C po merge + +# Uncomment this line before opening the project in kdevelop for the first time! +#SUBDIRS = chmlib kio-msits libchmfile diff --git a/lib/chmlib/AUTHORS b/lib/chmlib/AUTHORS new file mode 100644 index 0000000..431ecc3 --- /dev/null +++ b/lib/chmlib/AUTHORS @@ -0,0 +1,18 @@ +Jed Wing <jedwin@ugcs.caltech.edu> +includes modified LZX code from cabextract-0.5 by Stuart Caie. + +Thanks to: + iDEFENSE for reporting the stack overflow vulnerability. + Palasik Sandor for reporting and fixing the LZX buffer overrun vulnerability. + David Huseby for enhancements to the chm_enumerate functionality. + Vitaly Bursov for compilation fixes for x86-64. + Vadim Zeitlin for a patch to clean up and fix some deficiencies in the + configure script. + Stan Tobias for bugfixes and index-page improvement to chm_http. + Andrew Hodgetts for major portability improvement. + Rich Erwin for his work towards Windows CE support. + Pabs for bug fixes and suggestions. + Antony Dovgal for setting up autoconf/automake based build process. + Ragnar Hojland Espinosa for patches to make chm_http more useful. + Razvan Cojocaru for forwarding along information regarding building on OS X. + Anyone else I've forgotten. diff --git a/lib/chmlib/COPYING b/lib/chmlib/COPYING new file mode 100644 index 0000000..cc6f365 --- /dev/null +++ b/lib/chmlib/COPYING @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. 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 not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the 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 +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/lib/chmlib/INSTALL b/lib/chmlib/INSTALL new file mode 100644 index 0000000..23e5f25 --- /dev/null +++ b/lib/chmlib/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/lib/chmlib/Makefile.am b/lib/chmlib/Makefile.am new file mode 100644 index 0000000..bcbe427 --- /dev/null +++ b/lib/chmlib/Makefile.am @@ -0,0 +1,3 @@ +noinst_LTLIBRARIES = libchm.la +noinst_HEADERS = chm_lib.h lzx.h +libchm_la_SOURCES = chm_lib.c lzx.c diff --git a/lib/chmlib/NEWS b/lib/chmlib/NEWS new file mode 100644 index 0000000..332fd9a --- /dev/null +++ b/lib/chmlib/NEWS @@ -0,0 +1,68 @@ +Changes from 0.37 to 0.38 + - Fix for reading some chm files. Running over a large directory of chm + files, about 1% of them turned out to be unreadable. This resulted from + an incomplete understanding of one of the header fields (index_root). + Apparently, this can take negative values other than -1. + + - Security fix for extract_chmLib. Pathnames containing a ".." element + will not be extracted. There doesn't seem to be a legitimate reason to + use ".." as a path element in a chm file. + +Changes from 0.36 to 0.37 + - Major security fix for stack overflow vulnerability: + http://www.sven-tantau.de/public_files/chmlib/chmlib_20051126.txt + - Corrected the broken Makefile.in. + +Changes from 0.35 to 0.36 + - Major security fix (iDEFENSE Security Advisory IDEF1099 - Stack Overflow + Vulnerability) + - Major security fix from Palasik Sandor (LZX decompression buffer overrun) + - Bugfix/enhancement from David Huseby to make the "what" flags to + chm_enumerate work correctly, and to pass the flags along to the callback + function (via the chmUnitInfo structure) so that the callback doesn't + need to re-parse the filename. + - Compilation fixes for x86-64 from Vitaly V. Bursov. + - Miscellaneous fixes to the configure script, including some significant + cleanup by Vadim Zeitlin. The changes from Vadim should also allow the + configure script to correctly configure the build on OS X, where it was + previously failing to note that pread64 doesn't work. + - Minor update to the Makefile.in to do a mkdir before the install, in case + the specified INSTALLPREFIX directory is non-existent + +Changes from 0.32 to 0.35 + - UTF-8 filenames, while still not handled correctly, are handled a little + more gracefully. That is to say, the library doesn't fail to open files + with filenames using characters outside the ASCII subset. I'm very + interested in any information as to the "right" way to handle filenames + of this sort. + - Files not containing a compressed section are handled properly, such as + .chw files. These files seem to contain information about compression, + but the information is invalid or empty. The library deals gracefully + with this now. + - Files compressed with different options were not being decompressed + properly. In particular, if the "reset interval" for the compressed + section was other than 2 block sizes, it could fail to read some of the + files. + - The caching system was improved slightly, in conjunction with this + previous bugfix. + +Changes from 0.3 to 0.32: + - [Rich Erwin] Minor portability fixes for Windows CE. + - [Pabs] Minor bugfix regarding detecting directory entries versus empty files. + - [Antony Dovgal] autoconf-based build process + - [Ragnar Hojland Espinosa] Feature additions for chm_http: + * Use SO_REUSEADDR + * Allow --bind= and --port= command line arguments + - Simple makefile has been fixed (finally) to use gcc instead of gcc-3.2. (Sorry, everybody!) + +Changes from 0.2 to 0.3: + + - initial attempt at portability to Win32. + - bugfixes from Stan Tobias: + * memory corruption error with caching system + * case insensitivity, to match with the Windows semantics + - modification to chm_http by Stan Tobias: + * when the user requests the page '/', they get a page with links to + all of the files in the archive + - Andrew Hodgetts has ported the library to Solaris and Irix. See README for details. + - Stuart Caie has granted permission to relicense under the LGPL. diff --git a/lib/chmlib/README b/lib/chmlib/README new file mode 100644 index 0000000..d39924b --- /dev/null +++ b/lib/chmlib/README @@ -0,0 +1,141 @@ +CHMLIB 0.38 +=========== + +------- +SUMMARY +------- +chmlib is a small library designed for accessing MS ITSS files. The ITSS file +format is used for Microsoft Html Help files (.chm), which have been the +predominant medium for software documentation from Microsoft during the past +several years, having superceded the previously used .hlp file format. + +Note that this is NOT the same as the OLE structured storage file format used +by MS Excel, Word, and so on. Instead, it is a different file format which +fulfills a similar purpose. Both file formats may be accessed via instances +of the IStorage COM interface, which is essentially an "acts like a +filesystem" interface. + +------- +FILE FORMAT SUPPORT +------- + +Lookup of files in the archive is supported, and should be relatively quick. +Reading of files in the archive is also supported. +Writing is not supported, but may be added in the future. + +In terms of support for the ITSS file format, there are a few places in which +the support provided by this library is not fully general: + +1. ITSS files whose names contain UTF-8 characters which are not part of the + ASCII subset will not currently be dealt with gracefully. Currently, the + filenames are not converted from UTF-8, but are instead returned as-is. I'm + very interested in hearing any suggestions as to the "right" way to handle + this. + +2. Only version 3 ITSS files are supported at present, though some work has + gone towards divining the differences between different versions of the + file format. It is possible that version 2 ITSS files might work properly + with this library, but unconfirmed. + +3. Archives larger than 4 GB should be supported just fine, but if they + contain files larger than 4GB, this library may break. Fortunately, this + seems somewhat unlikely. + +If you run into .chm files (or files you suspect are ITSS files) that this +library doesn't work with, please contact me so I can fix the library. + +------- +PORTABILITY +------- + +This software was originally developed on a Intel x86 Debian Linux machine, +using gcc 3.0. It has since been compiled on various flavors of RedHat as +well, and using versions of gcc from 2.95 through 3.2. Basic Win32 support +should be in this release. (While a port to Win32 may _seem_ like a funny +idea, given that Windows ships with libraries for CHM access, it turns out that +Win CE does not; I've gotten a request for a port to Windows CE.) + +Chmlib apparently works on OS X, with some tweaks. In particular, disabling +pread and io64 apparently works. + +Finally, Andrew Hodgetts has ported to Solaris and IRIX: + +On Monday, 7 Oct 2002, Andrew Hodgetts wrote: +> Solaris(Sun): +> +> I used both SunProC and GCC on the solaris machines to compile. They +> both worked ok. +> However, both required -lsocket on the link line of the Makefile or you +> recieve linking errors. +> +> I have this working on CPUs ranging from Sun4m (Sparc5) through to +> UltraSparcIII (SunFireV880). +> +> Irix (SGI): +> +> I only testing with the MIPS compiler (not GCC). All worked ok - lots of +> warning messages, but it always does that. + +He further noted that: + +> ... for NON GCC compilers, a little tweaking may be required, but nothing too +> complex. ie SunProC doesn't understand -fPIC for library building. Irix +> required -n32 (new 32bit libraries) etc. These are things that someone who +> uses the OS and compiler should be used to dealing with. + +------- +CREDITS +------- + +* Stuart Caie: the LZX decompression code, and for granting permission to + re-license under the LGPL. + +* Sven Tantau: identification of a stack-overflow security flaw and a quick fix + for the problem; identification of a possible security danger in the example + program "extract_chmLib" + +* iDEFENSE Labs: identification of a nasty stack-overflow security flaw + +* Palasik Sandor: identification of a potential security flaw in lzx.c as well + as a quick fix for the problem + +* David Huseby: An excellent patch to the chm_enumerate functionality, relating + to the "what" flags, which didn't work entirely correctly before + +* Vadim Zeitlin: Configure script cleanup, including an important update to + allow detection of platforms where pread64 doesn't work. (OS X) + +* Vitaly V. Bursov: Compilation on x86-64. + +* mc: A suggestion to add a "mkdir" to the install step. + +* Stan Tobias: bugfixes and the added 'index page' feature of chm_http. + +* Andrew Hodgetts: porting to Solaris and IRIX, as well as fixing some + little-endian biases in the code. + +* Rich Erwin: Windows CE support. + +* Pabs: bug fixes and suggestions. + +* Antony Dovgal: setting up autoconf/automake based build process. + +* Ragnar Hojland Espinosa: patches to make chm_http more useful. + +* Razvan Cojocaru: forwarding along information regarding building on OS X. + +* Julien Lemoine: creating and maintaining the Debian package of chmlib. + +* Prarit Bhargava: Compilation on ia64 + +* Jean-Marc Vanel: elimination of compilation warnings in extract_chmLib + +* Sisyphus & Matej Spiller-Muys: Compilation under MinGW32 + +* Kyle Davenport: helper script for using chm_http with mozilla + +* Matthew Daniel & Mark Rosenstand: help to sort out issues with the build + system. + +* Anyone else I've forgotten. (?) + diff --git a/lib/chmlib/chm_lib.c b/lib/chmlib/chm_lib.c new file mode 100644 index 0000000..e7da0b0 --- /dev/null +++ b/lib/chmlib/chm_lib.c @@ -0,0 +1,1917 @@ +/* $Id: chm_lib.c 148 2007-03-07 09:22:36Z gyunaev $ */ +/*************************************************************************** + * chm_lib.c - CHM archive manipulation routines * + * ------------------- * + * * + * author: Jed Wing <jedwin@ugcs.caltech.edu> * + * version: 0.3 * + * notes: These routines are meant for the manipulation of microsoft * + * .chm (compiled html help) files, but may likely be used * + * for the manipulation of any ITSS archive, if ever ITSS * + * archives are used for any other purpose. * + * * + * Note also that the section names are statically handled. * + * To be entirely correct, the section names should be read * + * from the section names meta-file, and then the various * + * content sections and the "transforms" to apply to the data * + * they contain should be inferred from the section name and * + * the meta-files referenced using that name; however, all of * + * the files I've been able to get my hands on appear to have * + * only two sections: Uncompressed and MSCompressed. * + * Additionally, the ITSS.DLL file included with Windows does * + * not appear to handle any different transforms than the * + * simple LZX-transform. Furthermore, the list of transforms * + * to apply is broken, in that only half the required space * + * is allocated for the list. (It appears as though the * + * space is allocated for ASCII strings, but the strings are * + * written as unicode. As a result, only the first half of * + * the string appears.) So this is probably not too big of * + * a deal, at least until CHM v4 (MS .lit files), which also * + * incorporate encryption, of some description. * + * * + * switches: CHM_MT: compile library with thread-safety * + * * + * switches (Linux only): * + * CHM_USE_PREAD: compile library to use pread instead of * + * lseek/read * + * CHM_USE_IO64: compile library to support full 64-bit I/O * + * as is needed to properly deal with the * + * 64-bit file offsets. * + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation; either version 2.1 of the * + * License, or (at your option) any later version. * + * * + ***************************************************************************/ + +#include "chm_lib.h" + +#ifdef CHM_MT +#define _REENTRANT +#endif + +#include "lzx.h" + +#include <stdlib.h> +#include <string.h> +#ifdef CHM_DEBUG +#include <stdio.h> +#endif + +#if __sun || __sgi +#include <strings.h> +#endif + +#ifdef WIN32 +#include <windows.h> +#include <malloc.h> +#ifdef _WIN32_WCE +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#else +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif +#else +/* basic Linux system includes */ +#define _XOPEN_SOURCE 500 +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +/* #include <dmalloc.h> */ +#endif + +/* includes/defines for threading, if using them */ +#ifdef CHM_MT +#ifdef WIN32 +#define CHM_ACQUIRE_LOCK(a) do { \ + EnterCriticalSection(&(a)); \ + } while(0) +#define CHM_RELEASE_LOCK(a) do { \ + EnterCriticalSection(&(a)); \ + } while(0) + +#else +#include <pthread.h> + +#define CHM_ACQUIRE_LOCK(a) do { \ + pthread_mutex_lock(&(a)); \ + } while(0) +#define CHM_RELEASE_LOCK(a) do { \ + pthread_mutex_unlock(&(a)); \ + } while(0) + +#endif +#else +#define CHM_ACQUIRE_LOCK(a) /* do nothing */ +#define CHM_RELEASE_LOCK(a) /* do nothing */ +#endif + +#ifdef WIN32 +#define CHM_NULL_FD (INVALID_HANDLE_VALUE) +#define CHM_USE_WIN32IO 1 +#define CHM_CLOSE_FILE(fd) CloseHandle((fd)) +#else +#define CHM_NULL_FD (-1) +#define CHM_CLOSE_FILE(fd) close((fd)) +#endif + +/* + * defines related to tuning + */ +#ifndef CHM_MAX_BLOCKS_CACHED +#define CHM_MAX_BLOCKS_CACHED 5 +#endif + +/* + * architecture specific defines + * + * Note: as soon as C99 is more widespread, the below defines should + * probably just use the C99 sized-int types. + * + * The following settings will probably work for many platforms. The sizes + * don't have to be exactly correct, but the types must accommodate at least as + * many bits as they specify. + */ + +/* i386, 32-bit, Windows */ +#ifdef WIN32 +typedef unsigned char UChar; +typedef __int16 Int16; +typedef unsigned __int16 UInt16; +typedef __int32 Int32; +typedef unsigned __int32 UInt32; +typedef __int64 Int64; +typedef unsigned __int64 UInt64; + +/* I386, 32-bit, non-Windows */ +/* Sparc */ +/* MIPS */ +/* PPC */ +#elif __i386__ || __sun || __sgi || __ppc__ +typedef unsigned char UChar; +typedef short Int16; +typedef unsigned short UInt16; +typedef long Int32; +typedef unsigned long UInt32; +typedef long long Int64; +typedef unsigned long long UInt64; + +/* x86-64 */ +/* Note that these may be appropriate for other 64-bit machines. */ +#elif __x86_64__ || __ia64__ +typedef unsigned char UChar; +typedef short Int16; +typedef unsigned short UInt16; +typedef int Int32; +typedef unsigned int UInt32; +typedef long Int64; +typedef unsigned long UInt64; + +#else + +/* yielding an error is preferable to yielding incorrect behavior */ +#error "Please define the sized types for your platform in chm_lib.c" +#endif + +/* GCC */ +#ifdef __GNUC__ +#define memcmp __builtin_memcmp +#define memcpy __builtin_memcpy +#define strlen __builtin_strlen + +#elif defined(WIN32) +static int ffs(unsigned int val) +{ + int bit=1, idx=1; + while (bit != 0 && (val & bit) == 0) + { + bit <<= 1; + ++idx; + } + if (bit == 0) + return 0; + else + return idx; +} + +#endif + +/* utilities for unmarshalling data */ +static int _unmarshal_char_array(unsigned char **pData, + unsigned int *pLenRemain, + char *dest, + int count) +{ + if (count <= 0 || (unsigned int)count > *pLenRemain) + return 0; + memcpy(dest, (*pData), count); + *pData += count; + *pLenRemain -= count; + return 1; +} + +static int _unmarshal_uchar_array(unsigned char **pData, + unsigned int *pLenRemain, + unsigned char *dest, + int count) +{ + if (count <= 0 || (unsigned int)count > *pLenRemain) + return 0; + memcpy(dest, (*pData), count); + *pData += count; + *pLenRemain -= count; + return 1; +} + +#if 0 +static int _unmarshal_int16(unsigned char **pData, + unsigned int *pLenRemain, + Int16 *dest) +{ + if (2 > *pLenRemain) + return 0; + *dest = (*pData)[0] | (*pData)[1]<<8; + *pData += 2; + *pLenRemain -= 2; + return 1; +} + +static int _unmarshal_uint16(unsigned char **pData, + unsigned int *pLenRemain, + UInt16 *dest) +{ + if (2 > *pLenRemain) + return 0; + *dest = (*pData)[0] | (*pData)[1]<<8; + *pData += 2; + *pLenRemain -= 2; + return 1; +} +#endif + +static int _unmarshal_int32(unsigned char **pData, + unsigned int *pLenRemain, + Int32 *dest) +{ + if (4 > *pLenRemain) + return 0; + *dest = (*pData)[0] | (*pData)[1]<<8 | (*pData)[2]<<16 | (*pData)[3]<<24; + *pData += 4; + *pLenRemain -= 4; + return 1; +} + +static int _unmarshal_uint32(unsigned char **pData, + unsigned int *pLenRemain, + UInt32 *dest) +{ + if (4 > *pLenRemain) + return 0; + *dest = (*pData)[0] | (*pData)[1]<<8 | (*pData)[2]<<16 | (*pData)[3]<<24; + *pData += 4; + *pLenRemain -= 4; + return 1; +} + +static int _unmarshal_int64(unsigned char **pData, + unsigned int *pLenRemain, + Int64 *dest) +{ + Int64 temp; + int i; + if (8 > *pLenRemain) + return 0; + temp=0; + for(i=8; i>0; i--) + { + temp <<= 8; + temp |= (*pData)[i-1]; + } + *dest = temp; + *pData += 8; + *pLenRemain -= 8; + return 1; +} + +static int _unmarshal_uint64(unsigned char **pData, + unsigned int *pLenRemain, + UInt64 *dest) +{ + UInt64 temp; + int i; + if (8 > *pLenRemain) + return 0; + temp=0; + for(i=8; i>0; i--) + { + temp <<= 8; + temp |= (*pData)[i-1]; + } + *dest = temp; + *pData += 8; + *pLenRemain -= 8; + return 1; +} + +static int _unmarshal_uuid(unsigned char **pData, + unsigned int *pDataLen, + unsigned char *dest) +{ + return _unmarshal_uchar_array(pData, pDataLen, dest, 16); +} + +/* names of sections essential to decompression */ +static const char _CHMU_RESET_TABLE[] = + "::DataSpace/Storage/MSCompressed/Transform/" + "{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/" + "InstanceData/ResetTable"; +static const char _CHMU_LZXC_CONTROLDATA[] = + "::DataSpace/Storage/MSCompressed/ControlData"; +static const char _CHMU_CONTENT[] = + "::DataSpace/Storage/MSCompressed/Content"; +static const char _CHMU_SPANINFO[] = + "::DataSpace/Storage/MSCompressed/SpanInfo"; + +/* + * structures local to this module + */ + +/* structure of ITSF headers */ +#define _CHM_ITSF_V2_LEN (0x58) +#define _CHM_ITSF_V3_LEN (0x60) +struct chmItsfHeader +{ + char signature[4]; /* 0 (ITSF) */ + Int32 version; /* 4 */ + Int32 header_len; /* 8 */ + Int32 unknown_000c; /* c */ + UInt32 last_modified; /* 10 */ + UInt32 lang_id; /* 14 */ + UChar dir_uuid[16]; /* 18 */ + UChar stream_uuid[16]; /* 28 */ + UInt64 unknown_offset; /* 38 */ + UInt64 unknown_len; /* 40 */ + UInt64 dir_offset; /* 48 */ + UInt64 dir_len; /* 50 */ + UInt64 data_offset; /* 58 (Not present before V3) */ +}; /* __attribute__ ((aligned (1))); */ + +static int _unmarshal_itsf_header(unsigned char **pData, + unsigned int *pDataLen, + struct chmItsfHeader *dest) +{ + /* we only know how to deal with the 0x58 and 0x60 byte structures */ + if (*pDataLen != _CHM_ITSF_V2_LEN && *pDataLen != _CHM_ITSF_V3_LEN) + return 0; + + /* unmarshal common fields */ + _unmarshal_char_array(pData, pDataLen, dest->signature, 4); + _unmarshal_int32 (pData, pDataLen, &dest->version); + _unmarshal_int32 (pData, pDataLen, &dest->header_len); + _unmarshal_int32 (pData, pDataLen, &dest->unknown_000c); + _unmarshal_uint32 (pData, pDataLen, &dest->last_modified); + _unmarshal_uint32 (pData, pDataLen, &dest->lang_id); + _unmarshal_uuid (pData, pDataLen, dest->dir_uuid); + _unmarshal_uuid (pData, pDataLen, dest->stream_uuid); + _unmarshal_uint64 (pData, pDataLen, &dest->unknown_offset); + _unmarshal_uint64 (pData, pDataLen, &dest->unknown_len); + _unmarshal_uint64 (pData, pDataLen, &dest->dir_offset); + _unmarshal_uint64 (pData, pDataLen, &dest->dir_len); + + /* error check the data */ + /* XXX: should also check UUIDs, probably, though with a version 3 file, + * current MS tools do not seem to use them. + */ + if (memcmp(dest->signature, "ITSF", 4) != 0) + return 0; + if (dest->version == 2) + { + if (dest->header_len < _CHM_ITSF_V2_LEN) + return 0; + } + else if (dest->version == 3) + { + if (dest->header_len < _CHM_ITSF_V3_LEN) + return 0; + } + else + return 0; + + /* now, if we have a V3 structure, unmarshal the rest. + * otherwise, compute it + */ + if (dest->version == 3) + { + if (*pDataLen != 0) + _unmarshal_uint64(pData, pDataLen, &dest->data_offset); + else + return 0; + } + else + dest->data_offset = dest->dir_offset + dest->dir_len; + + return 1; +} + +/* structure of ITSP headers */ +#define _CHM_ITSP_V1_LEN (0x54) +struct chmItspHeader +{ + char signature[4]; /* 0 (ITSP) */ + Int32 version; /* 4 */ + Int32 header_len; /* 8 */ + Int32 unknown_000c; /* c */ + UInt32 block_len; /* 10 */ + Int32 blockidx_intvl; /* 14 */ + Int32 index_depth; /* 18 */ + Int32 index_root; /* 1c */ + Int32 index_head; /* 20 */ + Int32 unknown_0024; /* 24 */ + UInt32 num_blocks; /* 28 */ + Int32 unknown_002c; /* 2c */ + UInt32 lang_id; /* 30 */ + UChar system_uuid[16]; /* 34 */ + UChar unknown_0044[16]; /* 44 */ +}; /* __attribute__ ((aligned (1))); */ + +static int _unmarshal_itsp_header(unsigned char **pData, + unsigned int *pDataLen, + struct chmItspHeader *dest) +{ + /* we only know how to deal with a 0x54 byte structures */ + if (*pDataLen != _CHM_ITSP_V1_LEN) + return 0; + + /* unmarshal fields */ + _unmarshal_char_array(pData, pDataLen, dest->signature, 4); + _unmarshal_int32 (pData, pDataLen, &dest->version); + _unmarshal_int32 (pData, pDataLen, &dest->header_len); + _unmarshal_int32 (pData, pDataLen, &dest->unknown_000c); + _unmarshal_uint32 (pData, pDataLen, &dest->block_len); + _unmarshal_int32 (pData, pDataLen, &dest->blockidx_intvl); + _unmarshal_int32 (pData, pDataLen, &dest->index_depth); + _unmarshal_int32 (pData, pDataLen, &dest->index_root); + _unmarshal_int32 (pData, pDataLen, &dest->index_head); + _unmarshal_int32 (pData, pDataLen, &dest->unknown_0024); + _unmarshal_uint32 (pData, pDataLen, &dest->num_blocks); + _unmarshal_int32 (pData, pDataLen, &dest->unknown_002c); + _unmarshal_uint32 (pData, pDataLen, &dest->lang_id); + _unmarshal_uuid (pData, pDataLen, dest->system_uuid); + _unmarshal_uchar_array(pData, pDataLen, dest->unknown_0044, 16); + + /* error check the data */ + if (memcmp(dest->signature, "ITSP", 4) != 0) + return 0; + if (dest->version != 1) + return 0; + if (dest->header_len != _CHM_ITSP_V1_LEN) + return 0; + + return 1; +} + +/* structure of PMGL headers */ +static const char _chm_pmgl_marker[4] = "PMGL"; +#define _CHM_PMGL_LEN (0x14) +struct chmPmglHeader +{ + char signature[4]; /* 0 (PMGL) */ + UInt32 free_space; /* 4 */ + UInt32 unknown_0008; /* 8 */ + Int32 block_prev; /* c */ + Int32 block_next; /* 10 */ +}; /* __attribute__ ((aligned (1))); */ + +static int _unmarshal_pmgl_header(unsigned char **pData, + unsigned int *pDataLen, + struct chmPmglHeader *dest) +{ + /* we only know how to deal with a 0x14 byte structures */ + if (*pDataLen != _CHM_PMGL_LEN) + return 0; + + /* unmarshal fields */ + _unmarshal_char_array(pData, pDataLen, dest->signature, 4); + _unmarshal_uint32 (pData, pDataLen, &dest->free_space); + _unmarshal_uint32 (pData, pDataLen, &dest->unknown_0008); + _unmarshal_int32 (pData, pDataLen, &dest->block_prev); + _unmarshal_int32 (pData, pDataLen, &dest->block_next); + + /* check structure */ + if (memcmp(dest->signature, _chm_pmgl_marker, 4) != 0) + return 0; + + return 1; +} + +/* structure of PMGI headers */ +static const char _chm_pmgi_marker[4] = "PMGI"; +#define _CHM_PMGI_LEN (0x08) +struct chmPmgiHeader +{ + char signature[4]; /* 0 (PMGI) */ + UInt32 free_space; /* 4 */ +}; /* __attribute__ ((aligned (1))); */ + +static int _unmarshal_pmgi_header(unsigned char **pData, + unsigned int *pDataLen, + struct chmPmgiHeader *dest) +{ + /* we only know how to deal with a 0x8 byte structures */ + if (*pDataLen != _CHM_PMGI_LEN) + return 0; + + /* unmarshal fields */ + _unmarshal_char_array(pData, pDataLen, dest->signature, 4); + _unmarshal_uint32 (pData, pDataLen, &dest->free_space); + + /* check structure */ + if (memcmp(dest->signature, _chm_pmgi_marker, 4) != 0) + return 0; + + return 1; +} + +/* structure of LZXC reset table */ +#define _CHM_LZXC_RESETTABLE_V1_LEN (0x28) +struct chmLzxcResetTable +{ + UInt32 version; + UInt32 block_count; + UInt32 unknown; + UInt32 table_offset; + UInt64 uncompressed_len; + UInt64 compressed_len; + UInt64 block_len; +}; /* __attribute__ ((aligned (1))); */ + +static int _unmarshal_lzxc_reset_table(unsigned char **pData, + unsigned int *pDataLen, + struct chmLzxcResetTable *dest) +{ + /* we only know how to deal with a 0x28 byte structures */ + if (*pDataLen != _CHM_LZXC_RESETTABLE_V1_LEN) + return 0; + + /* unmarshal fields */ + _unmarshal_uint32 (pData, pDataLen, &dest->version); + _unmarshal_uint32 (pData, pDataLen, &dest->block_count); + _unmarshal_uint32 (pData, pDataLen, &dest->unknown); + _unmarshal_uint32 (pData, pDataLen, &dest->table_offset); + _unmarshal_uint64 (pData, pDataLen, &dest->uncompressed_len); + _unmarshal_uint64 (pData, pDataLen, &dest->compressed_len); + _unmarshal_uint64 (pData, pDataLen, &dest->block_len); + + /* check structure */ + if (dest->version != 2) + return 0; + + return 1; +} + +/* structure of LZXC control data block */ +#define _CHM_LZXC_MIN_LEN (0x18) +#define _CHM_LZXC_V2_LEN (0x1c) +struct chmLzxcControlData +{ + UInt32 size; /* 0 */ + char signature[4]; /* 4 (LZXC) */ + UInt32 version; /* 8 */ + UInt32 resetInterval; /* c */ + UInt32 windowSize; /* 10 */ + UInt32 windowsPerReset; /* 14 */ + UInt32 unknown_18; /* 18 */ +}; + +static int _unmarshal_lzxc_control_data(unsigned char **pData, + unsigned int *pDataLen, + struct chmLzxcControlData *dest) +{ + /* we want at least 0x18 bytes */ + if (*pDataLen < _CHM_LZXC_MIN_LEN) + return 0; + + /* unmarshal fields */ + _unmarshal_uint32 (pData, pDataLen, &dest->size); + _unmarshal_char_array(pData, pDataLen, dest->signature, 4); + _unmarshal_uint32 (pData, pDataLen, &dest->version); + _unmarshal_uint32 (pData, pDataLen, &dest->resetInterval); + _unmarshal_uint32 (pData, pDataLen, &dest->windowSize); + _unmarshal_uint32 (pData, pDataLen, &dest->windowsPerReset); + + if (*pDataLen >= _CHM_LZXC_V2_LEN) + _unmarshal_uint32 (pData, pDataLen, &dest->unknown_18); + else + dest->unknown_18 = 0; + + if (dest->version == 2) + { + dest->resetInterval *= 0x8000; + dest->windowSize *= 0x8000; + } + if (dest->windowSize == 0 || dest->resetInterval == 0) + return 0; + + /* for now, only support resetInterval a multiple of windowSize/2 */ + if (dest->windowSize == 1) + return 0; + if ((dest->resetInterval % (dest->windowSize/2)) != 0) + return 0; + + /* check structure */ + if (memcmp(dest->signature, "LZXC", 4) != 0) + return 0; + + return 1; +} + +/* the structure used for chm file handles */ +struct chmFile +{ +#ifdef WIN32 + HANDLE fd; +#else + int fd; +#endif + +#ifdef CHM_MT +#ifdef WIN32 + CRITICAL_SECTION mutex; + CRITICAL_SECTION lzx_mutex; + CRITICAL_SECTION cache_mutex; +#else + pthread_mutex_t mutex; + pthread_mutex_t lzx_mutex; + pthread_mutex_t cache_mutex; +#endif +#endif + + UInt64 dir_offset; + UInt64 dir_len; + UInt64 data_offset; + Int32 index_root; + Int32 index_head; + UInt32 block_len; + + UInt64 span; + struct chmUnitInfo rt_unit; + struct chmUnitInfo cn_unit; + struct chmLzxcResetTable reset_table; + + /* LZX control data */ + int compression_enabled; + UInt32 window_size; + UInt32 reset_interval; + UInt32 reset_blkcount; + + /* decompressor state */ + struct LZXstate *lzx_state; + int lzx_last_block; + + /* cache for decompressed blocks */ + UChar **cache_blocks; + UInt64 *cache_block_indices; + Int32 cache_num_blocks; +}; + +/* + * utility functions local to this module + */ + +/* utility function to handle differences between {pread,read}(64)? */ +static Int64 _chm_fetch_bytes(struct chmFile *h, + UChar *buf, + UInt64 os, + Int64 len) +{ + Int64 readLen=0, oldOs=0; + if (h->fd == CHM_NULL_FD) + return readLen; + + CHM_ACQUIRE_LOCK(h->mutex); +#ifdef CHM_USE_WIN32IO + /* NOTE: this might be better done with CreateFileMapping, et cetera... */ + { + DWORD origOffsetLo=0, origOffsetHi=0; + DWORD offsetLo, offsetHi; + DWORD actualLen=0; + + /* awkward Win32 Seek/Tell */ + offsetLo = (unsigned int)(os & 0xffffffffL); + offsetHi = (unsigned int)((os >> 32) & 0xffffffffL); + origOffsetLo = SetFilePointer(h->fd, 0, &origOffsetHi, FILE_CURRENT); + offsetLo = SetFilePointer(h->fd, offsetLo, &offsetHi, FILE_BEGIN); + + /* read the data */ + if (ReadFile(h->fd, + buf, + (DWORD)len, + &actualLen, + NULL) == TRUE) + readLen = actualLen; + else + readLen = 0; + + /* restore original position */ + SetFilePointer(h->fd, origOffsetLo, &origOffsetHi, FILE_BEGIN); + } +#else +#ifdef CHM_USE_PREAD +#ifdef CHM_USE_IO64 + readLen = pread64(h->fd, buf, (long)len, os); +#else + readLen = pread(h->fd, buf, (long)len, (unsigned int)os); +#endif +#else +#ifdef CHM_USE_IO64 + oldOs = lseek64(h->fd, 0, SEEK_CUR); + lseek64(h->fd, os, SEEK_SET); + readLen = read(h->fd, buf, len); + lseek64(h->fd, oldOs, SEEK_SET); +#else + oldOs = lseek(h->fd, 0, SEEK_CUR); + lseek(h->fd, (long)os, SEEK_SET); + readLen = read(h->fd, buf, len); + lseek(h->fd, (long)oldOs, SEEK_SET); +#endif +#endif +#endif + CHM_RELEASE_LOCK(h->mutex); + return readLen; +} + +/* open an ITS archive */ +#ifdef PPC_BSTR +/* RWE 6/12/2003 */ +struct chmFile *chm_open(BSTR filename) +#else +struct chmFile *chm_open(const char *filename) +#endif +{ + unsigned char sbuffer[256]; + unsigned int sremain; + unsigned char *sbufpos; + struct chmFile *newHandle=NULL; + struct chmItsfHeader itsfHeader; + struct chmItspHeader itspHeader; +#if 0 + struct chmUnitInfo uiSpan; +#endif + struct chmUnitInfo uiLzxc; + struct chmLzxcControlData ctlData; + + /* allocate handle */ + newHandle = (struct chmFile *)malloc(sizeof(struct chmFile)); + if (newHandle == NULL) + return NULL; + newHandle->fd = CHM_NULL_FD; + newHandle->lzx_state = NULL; + newHandle->cache_blocks = NULL; + newHandle->cache_block_indices = NULL; + newHandle->cache_num_blocks = 0; + + /* open file */ +#ifdef WIN32 +#ifdef PPC_BSTR + if ((newHandle->fd=CreateFile(filename, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) == CHM_NULL_FD) + { + free(newHandle); + return NULL; + } +#else + if ((newHandle->fd=CreateFileA(filename, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL)) == CHM_NULL_FD) + { + free(newHandle); + return NULL; + } +#endif +#else + if ((newHandle->fd=open(filename, O_RDONLY)) == CHM_NULL_FD) + { + free(newHandle); + return NULL; + } +#endif + + /* initialize mutexes, if needed */ +#ifdef CHM_MT +#ifdef WIN32 + InitializeCriticalSection(&newHandle->mutex); + InitializeCriticalSection(&newHandle->lzx_mutex); + InitializeCriticalSection(&newHandle->cache_mutex); +#else + pthread_mutex_init(&newHandle->mutex, NULL); + pthread_mutex_init(&newHandle->lzx_mutex, NULL); + pthread_mutex_init(&newHandle->cache_mutex, NULL); +#endif +#endif + + /* read and verify header */ + sremain = _CHM_ITSF_V3_LEN; + sbufpos = sbuffer; + if (_chm_fetch_bytes(newHandle, sbuffer, (UInt64)0, sremain) != sremain || + !_unmarshal_itsf_header(&sbufpos, &sremain, &itsfHeader)) + { + chm_close(newHandle); + return NULL; + } + + /* stash important values from header */ + newHandle->dir_offset = itsfHeader.dir_offset; + newHandle->dir_len = itsfHeader.dir_len; + newHandle->data_offset = itsfHeader.data_offset; + + /* now, read and verify the directory header chunk */ + sremain = _CHM_ITSP_V1_LEN; + sbufpos = sbuffer; + if (_chm_fetch_bytes(newHandle, sbuffer, + (UInt64)itsfHeader.dir_offset, sremain) != sremain || + !_unmarshal_itsp_header(&sbufpos, &sremain, &itspHeader)) + { + chm_close(newHandle); + return NULL; + } + + /* grab essential information from ITSP header */ + newHandle->dir_offset += itspHeader.header_len; + newHandle->dir_len -= itspHeader.header_len; + newHandle->index_root = itspHeader.index_root; + newHandle->index_head = itspHeader.index_head; + newHandle->block_len = itspHeader.block_len; + + /* if the index root is -1, this means we don't have any PMGI blocks. + * as a result, we must use the sole PMGL block as the index root + */ + if (newHandle->index_root <= -1) + newHandle->index_root = newHandle->index_head; + + /* By default, compression is enabled. */ + newHandle->compression_enabled = 1; + +/* Jed, Sun Jun 27: 'span' doesn't seem to be used anywhere?! */ +#if 0 + /* fetch span */ + if (CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, + _CHMU_SPANINFO, + &uiSpan) || + uiSpan.space == CHM_COMPRESSED) + { + chm_close(newHandle); + return NULL; + } + + /* N.B.: we've already checked that uiSpan is in the uncompressed section, + * so this should not require attempting to decompress, which may + * rely on having a valid "span" + */ + sremain = 8; + sbufpos = sbuffer; + if (chm_retrieve_object(newHandle, &uiSpan, sbuffer, + 0, sremain) != sremain || + !_unmarshal_uint64(&sbufpos, &sremain, &newHandle->span)) + { + chm_close(newHandle); + return NULL; + } +#endif + + /* prefetch most commonly needed unit infos */ + if (CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, + _CHMU_RESET_TABLE, + &newHandle->rt_unit) || + newHandle->rt_unit.space == CHM_COMPRESSED || + CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, + _CHMU_CONTENT, + &newHandle->cn_unit) || + newHandle->cn_unit.space == CHM_COMPRESSED || + CHM_RESOLVE_SUCCESS != chm_resolve_object(newHandle, + _CHMU_LZXC_CONTROLDATA, + &uiLzxc) || + uiLzxc.space == CHM_COMPRESSED) + { + newHandle->compression_enabled = 0; + } + + /* read reset table info */ + if (newHandle->compression_enabled) + { + sremain = _CHM_LZXC_RESETTABLE_V1_LEN; + sbufpos = sbuffer; + if (chm_retrieve_object(newHandle, &newHandle->rt_unit, sbuffer, + 0, sremain) != sremain || + !_unmarshal_lzxc_reset_table(&sbufpos, &sremain, + &newHandle->reset_table)) + { + newHandle->compression_enabled = 0; + } + } + + /* read control data */ + if (newHandle->compression_enabled) + { + sremain = (unsigned int)uiLzxc.length; + if (uiLzxc.length > sizeof(sbuffer)) + { + chm_close(newHandle); + return NULL; + } + + sbufpos = sbuffer; + if (chm_retrieve_object(newHandle, &uiLzxc, sbuffer, + 0, sremain) != sremain || + !_unmarshal_lzxc_control_data(&sbufpos, &sremain, + &ctlData)) + { + newHandle->compression_enabled = 0; + } + + newHandle->window_size = ctlData.windowSize; + newHandle->reset_interval = ctlData.resetInterval; + +/* Jed, Mon Jun 28: Experimentally, it appears that the reset block count */ +/* must be multiplied by this formerly unknown ctrl data field in */ +/* order to decompress some files. */ +#if 0 + newHandle->reset_blkcount = newHandle->reset_interval / + (newHandle->window_size / 2); +#else + newHandle->reset_blkcount = newHandle->reset_interval / + (newHandle->window_size / 2) * + ctlData.windowsPerReset; +#endif + } + + /* initialize cache */ + chm_set_param(newHandle, CHM_PARAM_MAX_BLOCKS_CACHED, + CHM_MAX_BLOCKS_CACHED); + + return newHandle; +} + +/* close an ITS archive */ +void chm_close(struct chmFile *h) +{ + if (h != NULL) + { + if (h->fd != CHM_NULL_FD) + CHM_CLOSE_FILE(h->fd); + h->fd = CHM_NULL_FD; + +#ifdef CHM_MT +#ifdef WIN32 + DeleteCriticalSection(&h->mutex); + DeleteCriticalSection(&h->lzx_mutex); + DeleteCriticalSection(&h->cache_mutex); +#else + pthread_mutex_destroy(&h->mutex); + pthread_mutex_destroy(&h->lzx_mutex); + pthread_mutex_destroy(&h->cache_mutex); +#endif +#endif + + if (h->lzx_state) + LZXteardown(h->lzx_state); + h->lzx_state = NULL; + + if (h->cache_blocks) + { + int i; + for (i=0; i<h->cache_num_blocks; i++) + { + if (h->cache_blocks[i]) + free(h->cache_blocks[i]); + } + free(h->cache_blocks); + h->cache_blocks = NULL; + } + + if (h->cache_block_indices) + free(h->cache_block_indices); + h->cache_block_indices = NULL; + + free(h); + } +} + +/* + * set a parameter on the file handle. + * valid parameter types: + * CHM_PARAM_MAX_BLOCKS_CACHED: + * how many decompressed blocks should be cached? A simple + * caching scheme is used, wherein the index of the block is + * used as a hash value, and hash collision results in the + * invalidation of the previously cached block. + */ +void chm_set_param(struct chmFile *h, + int paramType, + int paramVal) +{ + switch (paramType) + { + case CHM_PARAM_MAX_BLOCKS_CACHED: + CHM_ACQUIRE_LOCK(h->cache_mutex); + if (paramVal != h->cache_num_blocks) + { + UChar **newBlocks; + UInt64 *newIndices; + int i; + + /* allocate new cached blocks */ + newBlocks = (UChar **)malloc(paramVal * sizeof (UChar *)); + if (newBlocks == NULL) return; + newIndices = (UInt64 *)malloc(paramVal * sizeof (UInt64)); + if (newIndices == NULL) { free(newBlocks); return; } + for (i=0; i<paramVal; i++) + { + newBlocks[i] = NULL; + newIndices[i] = 0; + } + + /* re-distribute old cached blocks */ + if (h->cache_blocks) + { + for (i=0; i<h->cache_num_blocks; i++) + { + int newSlot = (int)(h->cache_block_indices[i] % paramVal); + + if (h->cache_blocks[i]) + { + /* in case of collision, destroy newcomer */ + if (newBlocks[newSlot]) + { + free(h->cache_blocks[i]); + h->cache_blocks[i] = NULL; + } + else + { + newBlocks[newSlot] = h->cache_blocks[i]; + newIndices[newSlot] = + h->cache_block_indices[i]; + } + } + } + + free(h->cache_blocks); + free(h->cache_block_indices); + } + + /* now, set new values */ + h->cache_blocks = newBlocks; + h->cache_block_indices = newIndices; + h->cache_num_blocks = paramVal; + } + CHM_RELEASE_LOCK(h->cache_mutex); + break; + + default: + break; + } +} + +/* + * helper methods for chm_resolve_object + */ + +/* skip a compressed dword */ +static void _chm_skip_cword(UChar **pEntry) +{ + while (*(*pEntry)++ >= 0x80) + ; +} + +/* skip the data from a PMGL entry */ +static void _chm_skip_PMGL_entry_data(UChar **pEntry) +{ + _chm_skip_cword(pEntry); + _chm_skip_cword(pEntry); + _chm_skip_cword(pEntry); +} + +/* parse a compressed dword */ +static UInt64 _chm_parse_cword(UChar **pEntry) +{ + UInt64 accum = 0; + UChar temp; + while ((temp=*(*pEntry)++) >= 0x80) + { + accum <<= 7; + accum += temp & 0x7f; + } + + return (accum << 7) + temp; +} + +/* parse a utf-8 string into an ASCII char buffer */ +static int _chm_parse_UTF8(UChar **pEntry, UInt64 count, char *path) +{ + /* XXX: implement UTF-8 support, including a real mapping onto + * ISO-8859-1? probably there is a library to do this? As is + * immediately apparent from the below code, I'm presently not doing + * any special handling for files in which none of the strings contain + * UTF-8 multi-byte characters. + */ + while (count != 0) + { + *path++ = (char)(*(*pEntry)++); + --count; + } + + *path = '\0'; + return 1; +} + +/* parse a PMGL entry into a chmUnitInfo struct; return 1 on success. */ +static int _chm_parse_PMGL_entry(UChar **pEntry, struct chmUnitInfo *ui) +{ + UInt64 strLen; + + /* parse str len */ + strLen = _chm_parse_cword(pEntry); + if (strLen > CHM_MAX_PATHLEN) + return 0; + + /* parse path */ + if (! _chm_parse_UTF8(pEntry, strLen, ui->path)) + return 0; + + /* parse info */ + ui->space = (int)_chm_parse_cword(pEntry); + ui->start = _chm_parse_cword(pEntry); + ui->length = _chm_parse_cword(pEntry); + return 1; +} + +/* find an exact entry in PMGL; return NULL if we fail */ +static UChar *_chm_find_in_PMGL(UChar *page_buf, + UInt32 block_len, + const char *objPath) +{ + /* XXX: modify this to do a binary search using the nice index structure + * that is provided for us. + */ + struct chmPmglHeader header; + unsigned int hremain; + UChar *end; + UChar *cur; + UChar *temp; + UInt64 strLen; + char buffer[CHM_MAX_PATHLEN+1]; + + /* figure out where to start and end */ + cur = page_buf; + hremain = _CHM_PMGL_LEN; + if (! _unmarshal_pmgl_header(&cur, &hremain, &header)) + return NULL; + end = page_buf + block_len - (header.free_space); + + /* now, scan progressively */ + while (cur < end) + { + /* grab the name */ + temp = cur; + strLen = _chm_parse_cword(&cur); + if (strLen > CHM_MAX_PATHLEN) + return NULL; + if (! _chm_parse_UTF8(&cur, strLen, buffer)) + return NULL; + + /* check if it is the right name */ + if (! strcasecmp(buffer, objPath)) + return temp; + + _chm_skip_PMGL_entry_data(&cur); + } + + return NULL; +} + +/* find which block should be searched next for the entry; -1 if no block */ +static Int32 _chm_find_in_PMGI(UChar *page_buf, + UInt32 block_len, + const char *objPath) +{ + /* XXX: modify this to do a binary search using the nice index structure + * that is provided for us + */ + struct chmPmgiHeader header; + unsigned int hremain; + int page=-1; + UChar *end; + UChar *cur; + UInt64 strLen; + char buffer[CHM_MAX_PATHLEN+1]; + + /* figure out where to start and end */ + cur = page_buf; + hremain = _CHM_PMGI_LEN; + if (! _unmarshal_pmgi_header(&cur, &hremain, &header)) + return -1; + end = page_buf + block_len - (header.free_space); + + /* now, scan progressively */ + while (cur < end) + { + /* grab the name */ + strLen = _chm_parse_cword(&cur); + if (strLen > CHM_MAX_PATHLEN) + return -1; + if (! _chm_parse_UTF8(&cur, strLen, buffer)) + return -1; + + /* check if it is the right name */ + if (strcasecmp(buffer, objPath) > 0) + return page; + + /* load next value for path */ + page = (int)_chm_parse_cword(&cur); + } + + return page; +} + +/* resolve a particular object from the archive */ +int chm_resolve_object(struct chmFile *h, + const char *objPath, + struct chmUnitInfo *ui) +{ + /* + * XXX: implement caching scheme for dir pages + */ + + Int32 curPage; + + /* buffer to hold whatever page we're looking at */ + /* RWE 6/12/2003 */ + UChar *page_buf = malloc(h->block_len); + if (page_buf == NULL) + return CHM_RESOLVE_FAILURE; + + /* starting page */ + curPage = h->index_root; + + /* until we have either returned or given up */ + while (curPage != -1) + { + + /* try to fetch the index page */ + if (_chm_fetch_bytes(h, page_buf, + (UInt64)h->dir_offset + (UInt64)curPage*h->block_len, + h->block_len) != h->block_len) + { + free(page_buf); + return CHM_RESOLVE_FAILURE; + } + + /* now, if it is a leaf node: */ + if (memcmp(page_buf, _chm_pmgl_marker, 4) == 0) + { + /* scan block */ + UChar *pEntry = _chm_find_in_PMGL(page_buf, + h->block_len, + objPath); + if (pEntry == NULL) + { + free(page_buf); + return CHM_RESOLVE_FAILURE; + } + + /* parse entry and return */ + _chm_parse_PMGL_entry(&pEntry, ui); + free(page_buf); + return CHM_RESOLVE_SUCCESS; + } + + /* else, if it is a branch node: */ + else if (memcmp(page_buf, _chm_pmgi_marker, 4) == 0) + curPage = _chm_find_in_PMGI(page_buf, h->block_len, objPath); + + /* else, we are confused. give up. */ + else + { + free(page_buf); + return CHM_RESOLVE_FAILURE; + } + } + + /* didn't find anything. fail. */ + free(page_buf); + return CHM_RESOLVE_FAILURE; +} + +/* + * utility methods for dealing with compressed data + */ + +/* get the bounds of a compressed block. return 0 on failure */ +static int _chm_get_cmpblock_bounds(struct chmFile *h, + UInt64 block, + UInt64 *start, + Int64 *len) +{ + UChar buffer[8], *dummy; + unsigned int remain; + + /* for all but the last block, use the reset table */ + if (block < h->reset_table.block_count-1) + { + /* unpack the start address */ + dummy = buffer; + remain = 8; + if (_chm_fetch_bytes(h, buffer, + (UInt64)h->data_offset + + (UInt64)h->rt_unit.start + + (UInt64)h->reset_table.table_offset + + (UInt64)block*8, + remain) != remain || + !_unmarshal_uint64(&dummy, &remain, start)) + return 0; + + /* unpack the end address */ + dummy = buffer; + remain = 8; + if (_chm_fetch_bytes(h, buffer, + (UInt64)h->data_offset + + (UInt64)h->rt_unit.start + + (UInt64)h->reset_table.table_offset + + (UInt64)block*8 + 8, + remain) != remain || + !_unmarshal_int64(&dummy, &remain, len)) + return 0; + } + + /* for the last block, use the span in addition to the reset table */ + else + { + /* unpack the start address */ + dummy = buffer; + remain = 8; + if (_chm_fetch_bytes(h, buffer, + (UInt64)h->data_offset + + (UInt64)h->rt_unit.start + + (UInt64)h->reset_table.table_offset + + (UInt64)block*8, + remain) != remain || + !_unmarshal_uint64(&dummy, &remain, start)) + return 0; + + *len = h->reset_table.compressed_len; + } + + /* compute the length and absolute start address */ + *len -= *start; + *start += h->data_offset + h->cn_unit.start; + + return 1; +} + +/* decompress the block. must have lzx_mutex. */ +static Int64 _chm_decompress_block(struct chmFile *h, + UInt64 block, + UChar **ubuffer) +{ + UChar *cbuffer = malloc(((unsigned int)h->reset_table.block_len + 6144)); + UInt64 cmpStart; /* compressed start */ + Int64 cmpLen; /* compressed len */ + int indexSlot; /* cache index slot */ + UChar *lbuffer; /* local buffer ptr */ + UInt32 blockAlign = (UInt32)(block % h->reset_blkcount); /* reset intvl. aln. */ + UInt32 i; /* local loop index */ + + if (cbuffer == NULL) + return -1; + + /* let the caching system pull its weight! */ + if (block - blockAlign <= h->lzx_last_block && + block >= h->lzx_last_block) + blockAlign = (block - h->lzx_last_block); + + /* check if we need previous blocks */ + if (blockAlign != 0) + { + /* fetch all required previous blocks since last reset */ + for (i = blockAlign; i > 0; i--) + { + UInt32 curBlockIdx = block - i; + + /* check if we most recently decompressed the previous block */ + if (h->lzx_last_block != curBlockIdx) + { + if ((curBlockIdx % h->reset_blkcount) == 0) + { +#ifdef CHM_DEBUG + fprintf(stderr, "***RESET (1)***\n"); +#endif + LZXreset(h->lzx_state); + } + + indexSlot = (int)((curBlockIdx) % h->cache_num_blocks); + if (! h->cache_blocks[indexSlot]) + h->cache_blocks[indexSlot] = (UChar *)malloc((unsigned int)(h->reset_table.block_len)); + if (! h->cache_blocks[indexSlot]) + { + free(cbuffer); + return -1; + } + h->cache_block_indices[indexSlot] = curBlockIdx; + lbuffer = h->cache_blocks[indexSlot]; + + /* decompress the previous block */ +#ifdef CHM_DEBUG + fprintf(stderr, "Decompressing block #%4d (EXTRA)\n", curBlockIdx); +#endif + if (!_chm_get_cmpblock_bounds(h, curBlockIdx, &cmpStart, &cmpLen) || + cmpLen < 0 || + cmpLen > h->reset_table.block_len + 6144 || + _chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen) != cmpLen || + LZXdecompress(h->lzx_state, cbuffer, lbuffer, (int)cmpLen, + (int)h->reset_table.block_len) != DECR_OK) + { +#ifdef CHM_DEBUG + fprintf(stderr, " (DECOMPRESS FAILED!)\n"); +#endif + free(cbuffer); + return (Int64)0; + } + + h->lzx_last_block = (int)curBlockIdx; + } + } + } + else + { + if ((block % h->reset_blkcount) == 0) + { +#ifdef CHM_DEBUG + fprintf(stderr, "***RESET (2)***\n"); +#endif + LZXreset(h->lzx_state); + } + } + + /* allocate slot in cache */ + indexSlot = (int)(block % h->cache_num_blocks); + if (! h->cache_blocks[indexSlot]) + h->cache_blocks[indexSlot] = (UChar *)malloc(((unsigned int)h->reset_table.block_len)); + if (! h->cache_blocks[indexSlot]) + { + free(cbuffer); + return -1; + } + h->cache_block_indices[indexSlot] = block; + lbuffer = h->cache_blocks[indexSlot]; + *ubuffer = lbuffer; + + /* decompress the block we actually want */ +#ifdef CHM_DEBUG + fprintf(stderr, "Decompressing block #%4d (REAL )\n", block); +#endif + if (! _chm_get_cmpblock_bounds(h, block, &cmpStart, &cmpLen) || + _chm_fetch_bytes(h, cbuffer, cmpStart, cmpLen) != cmpLen || + LZXdecompress(h->lzx_state, cbuffer, lbuffer, (int)cmpLen, + (int)h->reset_table.block_len) != DECR_OK) + { +#ifdef CHM_DEBUG + fprintf(stderr, " (DECOMPRESS FAILED!)\n"); +#endif + free(cbuffer); + return (Int64)0; + } + h->lzx_last_block = (int)block; + + /* XXX: modify LZX routines to return the length of the data they + * decompressed and return that instead, for an extra sanity check. + */ + free(cbuffer); + return h->reset_table.block_len; +} + +/* grab a region from a compressed block */ +static Int64 _chm_decompress_region(struct chmFile *h, + UChar *buf, + UInt64 start, + Int64 len) +{ + UInt64 nBlock, nOffset; + UInt64 nLen; + UInt64 gotLen; + UChar *ubuffer; + + if (len <= 0) + return (Int64)0; + + /* figure out what we need to read */ + nBlock = start / h->reset_table.block_len; + nOffset = start % h->reset_table.block_len; + nLen = len; + if (nLen > (h->reset_table.block_len - nOffset)) + nLen = h->reset_table.block_len - nOffset; + + /* if block is cached, return data from it. */ + CHM_ACQUIRE_LOCK(h->lzx_mutex); + CHM_ACQUIRE_LOCK(h->cache_mutex); + if (h->cache_block_indices[nBlock % h->cache_num_blocks] == nBlock && + h->cache_blocks[nBlock % h->cache_num_blocks] != NULL) + { + memcpy(buf, + h->cache_blocks[nBlock % h->cache_num_blocks] + nOffset, + (unsigned int)nLen); + CHM_RELEASE_LOCK(h->cache_mutex); + CHM_RELEASE_LOCK(h->lzx_mutex); + return nLen; + } + CHM_RELEASE_LOCK(h->cache_mutex); + + /* data request not satisfied, so... start up the decompressor machine */ + if (! h->lzx_state) + { + int window_size = ffs(h->window_size) - 1; + h->lzx_last_block = -1; + h->lzx_state = LZXinit(window_size); + } + + /* decompress some data */ + gotLen = _chm_decompress_block(h, nBlock, &ubuffer); + if (gotLen < nLen) + nLen = gotLen; + memcpy(buf, ubuffer+nOffset, (unsigned int)nLen); + CHM_RELEASE_LOCK(h->lzx_mutex); + return nLen; +} + +/* retrieve (part of) an object */ +LONGINT64 chm_retrieve_object(struct chmFile *h, + const struct chmUnitInfo *ui, + unsigned char *buf, + LONGUINT64 addr, + LONGINT64 len) +{ + /* must be valid file handle */ + if (h == NULL) + return (Int64)0; + + /* starting address must be in correct range */ + if ( addr >= ui->length) + return (Int64)0; + + /* clip length */ + if (addr + len > ui->length) + len = ui->length - addr; + + /* if the file is uncompressed, it's simple */ + if (ui->space == CHM_UNCOMPRESSED) + { + /* read data */ + return _chm_fetch_bytes(h, + buf, + (UInt64)h->data_offset + (UInt64)ui->start + (UInt64)addr, + len); + } + + /* else if the file is compressed, it's a little trickier */ + else /* ui->space == CHM_COMPRESSED */ + { + Int64 swath=0, total=0; + + /* if compression is not enabled for this file... */ + if (! h->compression_enabled) + return total; + + do { + + /* swill another mouthful */ + swath = _chm_decompress_region(h, buf, ui->start + addr, len); + + /* if we didn't get any... */ + if (swath == 0) + return total; + + /* update stats */ + total += swath; + len -= swath; + addr += swath; + buf += swath; + + } while (len != 0); + + return total; + } +} + +/* enumerate the objects in the .chm archive */ +int chm_enumerate(struct chmFile *h, + int what, + CHM_ENUMERATOR e, + void *context) +{ + Int32 curPage; + + /* buffer to hold whatever page we're looking at */ + /* RWE 6/12/2003 */ + UChar *page_buf = malloc((unsigned int)h->block_len); + struct chmPmglHeader header; + UChar *end; + UChar *cur; + unsigned int lenRemain; + UInt64 ui_path_len; + + /* the current ui */ + struct chmUnitInfo ui; + int type_bits = (what & 0x7); + int filter_bits = (what & 0xF8); + + if (page_buf == NULL) + return 0; + + /* starting page */ + curPage = h->index_head; + + /* until we have either returned or given up */ + while (curPage != -1) + { + + /* try to fetch the index page */ + if (_chm_fetch_bytes(h, + page_buf, + (UInt64)h->dir_offset + (UInt64)curPage*h->block_len, + h->block_len) != h->block_len) + { + free(page_buf); + return 0; + } + + /* figure out start and end for this page */ + cur = page_buf; + lenRemain = _CHM_PMGL_LEN; + if (! _unmarshal_pmgl_header(&cur, &lenRemain, &header)) + { + free(page_buf); + return 0; + } + end = page_buf + h->block_len - (header.free_space); + + /* loop over this page */ + while (cur < end) + { + ui.flags = 0; + + if (! _chm_parse_PMGL_entry(&cur, &ui)) + { + free(page_buf); + return 0; + } + + /* get the length of the path */ + ui_path_len = strlen(ui.path)-1; + + /* check for DIRS */ + if (ui.path[ui_path_len] == '/') + ui.flags |= CHM_ENUMERATE_DIRS; + + /* check for FILES */ + if (ui.path[ui_path_len] != '/') + ui.flags |= CHM_ENUMERATE_FILES; + + /* check for NORMAL vs. META */ + if (ui.path[0] == '/') + { + + /* check for NORMAL vs. SPECIAL */ + if (ui.path[1] == '#' || ui.path[1] == '$') + ui.flags |= CHM_ENUMERATE_SPECIAL; + else + ui.flags |= CHM_ENUMERATE_NORMAL; + } + else + ui.flags |= CHM_ENUMERATE_META; + + if (! (type_bits & ui.flags)) + continue; + + if (filter_bits && ! (filter_bits & ui.flags)) + continue; + + /* call the enumerator */ + { + int status = (*e)(h, &ui, context); + switch (status) + { + case CHM_ENUMERATOR_FAILURE: + free(page_buf); + return 0; + case CHM_ENUMERATOR_CONTINUE: + break; + case CHM_ENUMERATOR_SUCCESS: + free(page_buf); + return 1; + default: + break; + } + } + } + + /* advance to next page */ + curPage = header.block_next; + } + + free(page_buf); + return 1; +} + +int chm_enumerate_dir(struct chmFile *h, + const char *prefix, + int what, + CHM_ENUMERATOR e, + void *context) +{ + /* + * XXX: do this efficiently (i.e. using the tree index) + */ + + Int32 curPage; + + /* buffer to hold whatever page we're looking at */ + /* RWE 6/12/2003 */ + UChar *page_buf = malloc((unsigned int)h->block_len); + struct chmPmglHeader header; + UChar *end; + UChar *cur; + unsigned int lenRemain; + + /* set to 1 once we've started */ + int it_has_begun=0; + + /* the current ui */ + struct chmUnitInfo ui; + int type_bits = (what & 0x7); + int filter_bits = (what & 0xF8); + UInt64 ui_path_len; + + /* the length of the prefix */ + char prefixRectified[CHM_MAX_PATHLEN+1]; + int prefixLen; + char lastPath[CHM_MAX_PATHLEN+1]; + int lastPathLen; + + if (page_buf == NULL) + return 0; + + /* starting page */ + curPage = h->index_head; + + /* initialize pathname state */ + strncpy(prefixRectified, prefix, CHM_MAX_PATHLEN); + prefixRectified[CHM_MAX_PATHLEN] = '\0'; + prefixLen = strlen(prefixRectified); + if (prefixLen != 0) + { + if (prefixRectified[prefixLen-1] != '/') + { + prefixRectified[prefixLen] = '/'; + prefixRectified[prefixLen+1] = '\0'; + ++prefixLen; + } + } + lastPath[0] = '\0'; + lastPathLen = -1; + + /* until we have either returned or given up */ + while (curPage != -1) + { + + /* try to fetch the index page */ + if (_chm_fetch_bytes(h, + page_buf, + (UInt64)h->dir_offset + (UInt64)curPage*h->block_len, + h->block_len) != h->block_len) + { + free(page_buf); + return 0; + } + + /* figure out start and end for this page */ + cur = page_buf; + lenRemain = _CHM_PMGL_LEN; + if (! _unmarshal_pmgl_header(&cur, &lenRemain, &header)) + { + free(page_buf); + return 0; + } + end = page_buf + h->block_len - (header.free_space); + + /* loop over this page */ + while (cur < end) + { + ui.flags = 0; + + if (! _chm_parse_PMGL_entry(&cur, &ui)) + { + free(page_buf); + return 0; + } + + /* check if we should start */ + if (! it_has_begun) + { + if (ui.length == 0 && strncasecmp(ui.path, prefixRectified, prefixLen) == 0) + it_has_begun = 1; + else + continue; + + if (ui.path[prefixLen] == '\0') + continue; + } + + /* check if we should stop */ + else + { + if (strncasecmp(ui.path, prefixRectified, prefixLen) != 0) + { + free(page_buf); + return 1; + } + } + + /* check if we should include this path */ + if (lastPathLen != -1) + { + if (strncasecmp(ui.path, lastPath, lastPathLen) == 0) + continue; + } + strncpy(lastPath, ui.path, CHM_MAX_PATHLEN); + lastPath[CHM_MAX_PATHLEN] = '\0'; + lastPathLen = strlen(lastPath); + + /* get the length of the path */ + ui_path_len = strlen(ui.path)-1; + + /* check for DIRS */ + if (ui.path[ui_path_len] == '/') + ui.flags |= CHM_ENUMERATE_DIRS; + + /* check for FILES */ + if (ui.path[ui_path_len] != '/') + ui.flags |= CHM_ENUMERATE_FILES; + + /* check for NORMAL vs. META */ + if (ui.path[0] == '/') + { + + /* check for NORMAL vs. SPECIAL */ + if (ui.path[1] == '#' || ui.path[1] == '$') + ui.flags |= CHM_ENUMERATE_SPECIAL; + else + ui.flags |= CHM_ENUMERATE_NORMAL; + } + else + ui.flags |= CHM_ENUMERATE_META; + + if (! (type_bits & ui.flags)) + continue; + + if (filter_bits && ! (filter_bits & ui.flags)) + continue; + + /* call the enumerator */ + { + int status = (*e)(h, &ui, context); + switch (status) + { + case CHM_ENUMERATOR_FAILURE: + free(page_buf); + return 0; + case CHM_ENUMERATOR_CONTINUE: + break; + case CHM_ENUMERATOR_SUCCESS: + free(page_buf); + return 1; + default: + break; + } + } + } + + /* advance to next page */ + curPage = header.block_next; + } + + free(page_buf); + return 1; +} diff --git a/lib/chmlib/chm_lib.h b/lib/chmlib/chm_lib.h new file mode 100644 index 0000000..2fb87a4 --- /dev/null +++ b/lib/chmlib/chm_lib.h @@ -0,0 +1,144 @@ +/* $Id: chm_lib.h 148 2007-03-07 09:22:36Z gyunaev $ */ +/*************************************************************************** + * chm_lib.h - CHM archive manipulation routines * + * ------------------- * + * * + * author: Jed Wing <jedwin@ugcs.caltech.edu> * + * version: 0.3 * + * notes: These routines are meant for the manipulation of microsoft * + * .chm (compiled html help) files, but may likely be used * + * for the manipulation of any ITSS archive, if ever ITSS * + * archives are used for any other purpose. * + * * + * Note also that the section names are statically handled. * + * To be entirely correct, the section names should be read * + * from the section names meta-file, and then the various * + * content sections and the "transforms" to apply to the data * + * they contain should be inferred from the section name and * + * the meta-files referenced using that name; however, all of * + * the files I've been able to get my hands on appear to have * + * only two sections: Uncompressed and MSCompressed. * + * Additionally, the ITSS.DLL file included with Windows does * + * not appear to handle any different transforms than the * + * simple LZX-transform. Furthermore, the list of transforms * + * to apply is broken, in that only half the required space * + * is allocated for the list. (It appears as though the * + * space is allocated for ASCII strings, but the strings are * + * written as unicode. As a result, only the first half of * + * the string appears.) So this is probably not too big of * + * a deal, at least until CHM v4 (MS .lit files), which also * + * incorporate encryption, of some description. * + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation; either version 2.1 of the * + * License, or (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef INCLUDED_CHMLIB_H +#define INCLUDED_CHMLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* RWE 6/12/1002 */ +#ifdef PPC_BSTR +#include <wtypes.h> +#endif + +#ifdef WIN32 +#ifdef __MINGW32__ +#define __int64 long long +#endif +typedef unsigned __int64 LONGUINT64; +typedef __int64 LONGINT64; +#else +typedef unsigned long long LONGUINT64; +typedef long long LONGINT64; +#endif + +/* the two available spaces in a CHM file */ +/* N.B.: The format supports arbitrarily many spaces, but only */ +/* two appear to be used at present. */ +#define CHM_UNCOMPRESSED (0) +#define CHM_COMPRESSED (1) + +/* structure representing an ITS (CHM) file stream */ +struct chmFile; + +/* structure representing an element from an ITS file stream */ +#define CHM_MAX_PATHLEN (512) +struct chmUnitInfo +{ + LONGUINT64 start; + LONGUINT64 length; + int space; + int flags; + char path[CHM_MAX_PATHLEN+1]; +}; + +/* open an ITS archive */ +#ifdef PPC_BSTR +/* RWE 6/12/2003 */ +struct chmFile* chm_open(BSTR filename); +#else +struct chmFile* chm_open(const char *filename); +#endif + +/* close an ITS archive */ +void chm_close(struct chmFile *h); + +/* methods for ssetting tuning parameters for particular file */ +#define CHM_PARAM_MAX_BLOCKS_CACHED 0 +void chm_set_param(struct chmFile *h, + int paramType, + int paramVal); + +/* resolve a particular object from the archive */ +#define CHM_RESOLVE_SUCCESS (0) +#define CHM_RESOLVE_FAILURE (1) +int chm_resolve_object(struct chmFile *h, + const char *objPath, + struct chmUnitInfo *ui); + +/* retrieve part of an object from the archive */ +LONGINT64 chm_retrieve_object(struct chmFile *h, + const struct chmUnitInfo *ui, + unsigned char *buf, + LONGUINT64 addr, + LONGINT64 len); + +/* enumerate the objects in the .chm archive */ +typedef int (*CHM_ENUMERATOR)(struct chmFile *h, + struct chmUnitInfo *ui, + void *context); +#define CHM_ENUMERATE_NORMAL (1) +#define CHM_ENUMERATE_META (2) +#define CHM_ENUMERATE_SPECIAL (4) +#define CHM_ENUMERATE_FILES (8) +#define CHM_ENUMERATE_DIRS (16) +#define CHM_ENUMERATE_ALL (31) +#define CHM_ENUMERATOR_FAILURE (0) +#define CHM_ENUMERATOR_CONTINUE (1) +#define CHM_ENUMERATOR_SUCCESS (2) +int chm_enumerate(struct chmFile *h, + int what, + CHM_ENUMERATOR e, + void *context); + +int chm_enumerate_dir(struct chmFile *h, + const char *prefix, + int what, + CHM_ENUMERATOR e, + void *context); + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDED_CHMLIB_H */ diff --git a/lib/chmlib/lzx.c b/lib/chmlib/lzx.c new file mode 100644 index 0000000..7a5545b --- /dev/null +++ b/lib/chmlib/lzx.c @@ -0,0 +1,812 @@ +/* $Id: lzx.c 148 2007-03-07 09:22:36Z gyunaev $ */ +/*************************************************************************** + * lzx.c - LZX decompression routines * + * ------------------- * + * * + * maintainer: Jed Wing <jedwin@ugcs.caltech.edu> * + * source: modified lzx.c from cabextract v0.5 * + * notes: This file was taken from cabextract v0.5, which was, * + * itself, a modified version of the lzx decompression code * + * from unlzx. * + * * + * platforms: In its current incarnation, this file has been tested on * + * two different Linux platforms (one, redhat-based, with a * + * 2.1.2 glibc and gcc 2.95.x, and the other, Debian, with * + * 2.2.4 glibc and both gcc 2.95.4 and gcc 3.0.2). Both were * + * Intel x86 compatible machines. * + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. Note that an exemption to this * + * license has been granted by Stuart Caie for the purposes of * + * distribution with chmlib. This does not, to the best of my * + * knowledge, constitute a change in the license of this (the LZX) code * + * in general. * + * * + ***************************************************************************/ + +#include "lzx.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef __GNUC__ +#define memcpy __builtin_memcpy +#endif + +/* sized types */ +typedef unsigned char UBYTE; /* 8 bits exactly */ +typedef unsigned short UWORD; /* 16 bits (or more) */ +typedef unsigned int ULONG; /* 32 bits (or more) */ +typedef signed int LONG; /* 32 bits (or more) */ + +/* some constants defined by the LZX specification */ +#define LZX_MIN_MATCH (2) +#define LZX_MAX_MATCH (257) +#define LZX_NUM_CHARS (256) +#define LZX_BLOCKTYPE_INVALID (0) /* also blocktypes 4-7 invalid */ +#define LZX_BLOCKTYPE_VERBATIM (1) +#define LZX_BLOCKTYPE_ALIGNED (2) +#define LZX_BLOCKTYPE_UNCOMPRESSED (3) +#define LZX_PRETREE_NUM_ELEMENTS (20) +#define LZX_ALIGNED_NUM_ELEMENTS (8) /* aligned offset tree #elements */ +#define LZX_NUM_PRIMARY_LENGTHS (7) /* this one missing from spec! */ +#define LZX_NUM_SECONDARY_LENGTHS (249) /* length tree #elements */ + +/* LZX huffman defines: tweak tablebits as desired */ +#define LZX_PRETREE_MAXSYMBOLS (LZX_PRETREE_NUM_ELEMENTS) +#define LZX_PRETREE_TABLEBITS (6) +#define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 50*8) +#define LZX_MAINTREE_TABLEBITS (12) +#define LZX_LENGTH_MAXSYMBOLS (LZX_NUM_SECONDARY_LENGTHS+1) +#define LZX_LENGTH_TABLEBITS (12) +#define LZX_ALIGNED_MAXSYMBOLS (LZX_ALIGNED_NUM_ELEMENTS) +#define LZX_ALIGNED_TABLEBITS (7) + +#define LZX_LENTABLE_SAFETY (64) /* we allow length table decoding overruns */ + +#define LZX_DECLARE_TABLE(tbl) \ + UWORD tbl##_table[(1<<LZX_##tbl##_TABLEBITS) + (LZX_##tbl##_MAXSYMBOLS<<1)];\ + UBYTE tbl##_len [LZX_##tbl##_MAXSYMBOLS + LZX_LENTABLE_SAFETY] + +struct LZXstate +{ + UBYTE *window; /* the actual decoding window */ + ULONG window_size; /* window size (32Kb through 2Mb) */ + ULONG actual_size; /* window size when it was first allocated */ + ULONG window_posn; /* current offset within the window */ + ULONG R0, R1, R2; /* for the LRU offset system */ + UWORD main_elements; /* number of main tree elements */ + int header_read; /* have we started decoding at all yet? */ + UWORD block_type; /* type of this block */ + ULONG block_length; /* uncompressed length of this block */ + ULONG block_remaining; /* uncompressed bytes still left to decode */ + ULONG frames_read; /* the number of CFDATA blocks processed */ + LONG intel_filesize; /* magic header value used for transform */ + LONG intel_curpos; /* current offset in transform space */ + int intel_started; /* have we seen any translatable data yet? */ + + LZX_DECLARE_TABLE(PRETREE); + LZX_DECLARE_TABLE(MAINTREE); + LZX_DECLARE_TABLE(LENGTH); + LZX_DECLARE_TABLE(ALIGNED); +}; + +/* LZX decruncher */ + +/* Microsoft's LZX document and their implementation of the + * com.ms.util.cab Java package do not concur. + * + * In the LZX document, there is a table showing the correlation between + * window size and the number of position slots. It states that the 1MB + * window = 40 slots and the 2MB window = 42 slots. In the implementation, + * 1MB = 42 slots, 2MB = 50 slots. The actual calculation is 'find the + * first slot whose position base is equal to or more than the required + * window size'. This would explain why other tables in the document refer + * to 50 slots rather than 42. + * + * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode + * is not defined in the specification. + * + * The LZX document does not state the uncompressed block has an + * uncompressed length field. Where does this length field come from, so + * we can know how large the block is? The implementation has it as the 24 + * bits following after the 3 blocktype bits, before the alignment + * padding. + * + * The LZX document states that aligned offset blocks have their aligned + * offset huffman tree AFTER the main and length trees. The implementation + * suggests that the aligned offset tree is BEFORE the main and length + * trees. + * + * The LZX document decoding algorithm states that, in an aligned offset + * block, if an extra_bits value is 1, 2 or 3, then that number of bits + * should be read and the result added to the match offset. This is + * correct for 1 and 2, but not 3, where just a huffman symbol (using the + * aligned tree) should be read. + * + * Regarding the E8 preprocessing, the LZX document states 'No translation + * may be performed on the last 6 bytes of the input block'. This is + * correct. However, the pseudocode provided checks for the *E8 leader* + * up to the last 6 bytes. If the leader appears between -10 and -7 bytes + * from the end, this would cause the next four bytes to be modified, at + * least one of which would be in the last 6 bytes, which is not allowed + * according to the spec. + * + * The specification states that the huffman trees must always contain at + * least one element. However, many CAB files contain blocks where the + * length tree is completely empty (because there are no matches), and + * this is expected to succeed. + */ + + +/* LZX uses what it calls 'position slots' to represent match offsets. + * What this means is that a small 'position slot' number and a small + * offset from that slot are encoded instead of one large offset for + * every match. + * - position_base is an index to the position slot bases + * - extra_bits states how many bits of offset-from-base data is needed. + */ +static const UBYTE extra_bits[51] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, + 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17 +}; + +static const ULONG position_base[51] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, + 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, + 65536, 98304, 131072, 196608, 262144, 393216, 524288, 655360, 786432, 917504, 1048576, 1179648, 1310720, 1441792, 1572864, 1703936, + 1835008, 1966080, 2097152 +}; + +struct LZXstate *LZXinit(int window) +{ + struct LZXstate *pState=NULL; + ULONG wndsize = 1 << window; + int i, posn_slots; + + /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */ + /* if a previously allocated window is big enough, keep it */ + if (window < 15 || window > 21) return NULL; + + /* allocate state and associated window */ + pState = (struct LZXstate *)malloc(sizeof(struct LZXstate)); + if (!(pState->window = (UBYTE *)malloc(wndsize))) + { + free(pState); + return NULL; + } + pState->actual_size = wndsize; + pState->window_size = wndsize; + + /* calculate required position slots */ + if (window == 20) posn_slots = 42; + else if (window == 21) posn_slots = 50; + else posn_slots = window << 1; + + /** alternatively **/ + /* posn_slots=i=0; while (i < wndsize) i += 1 << extra_bits[posn_slots++]; */ + + /* initialize other state */ + pState->R0 = pState->R1 = pState->R2 = 1; + pState->main_elements = LZX_NUM_CHARS + (posn_slots << 3); + pState->header_read = 0; + pState->frames_read = 0; + pState->block_remaining = 0; + pState->block_type = LZX_BLOCKTYPE_INVALID; + pState->intel_curpos = 0; + pState->intel_started = 0; + pState->window_posn = 0; + + /* initialise tables to 0 (because deltas will be applied to them) */ + for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) pState->MAINTREE_len[i] = 0; + for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++) pState->LENGTH_len[i] = 0; + + return pState; +} + +void LZXteardown(struct LZXstate *pState) +{ + if (pState) + { + if (pState->window) + free(pState->window); + free(pState); + } +} + +int LZXreset(struct LZXstate *pState) +{ + int i; + + pState->R0 = pState->R1 = pState->R2 = 1; + pState->header_read = 0; + pState->frames_read = 0; + pState->block_remaining = 0; + pState->block_type = LZX_BLOCKTYPE_INVALID; + pState->intel_curpos = 0; + pState->intel_started = 0; + pState->window_posn = 0; + + for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS + LZX_LENTABLE_SAFETY; i++) pState->MAINTREE_len[i] = 0; + for (i = 0; i < LZX_LENGTH_MAXSYMBOLS + LZX_LENTABLE_SAFETY; i++) pState->LENGTH_len[i] = 0; + + return DECR_OK; +} + + +/* Bitstream reading macros: + * + * INIT_BITSTREAM should be used first to set up the system + * READ_BITS(var,n) takes N bits from the buffer and puts them in var + * + * ENSURE_BITS(n) ensures there are at least N bits in the bit buffer + * PEEK_BITS(n) extracts (without removing) N bits from the bit buffer + * REMOVE_BITS(n) removes N bits from the bit buffer + * + * These bit access routines work by using the area beyond the MSB and the + * LSB as a free source of zeroes. This avoids having to mask any bits. + * So we have to know the bit width of the bitbuffer variable. This is + * sizeof(ULONG) * 8, also defined as ULONG_BITS + */ + +/* number of bits in ULONG. Note: This must be at multiple of 16, and at + * least 32 for the bitbuffer code to work (ie, it must be able to ensure + * up to 17 bits - that's adding 16 bits when there's one bit left, or + * adding 32 bits when there are no bits left. The code should work fine + * for machines where ULONG >= 32 bits. + */ +#define ULONG_BITS (sizeof(ULONG)<<3) + +#define INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0) + +#define ENSURE_BITS(n) \ + while (bitsleft < (n)) { \ + bitbuf |= ((inpos[1]<<8)|inpos[0]) << (ULONG_BITS-16 - bitsleft); \ + bitsleft += 16; inpos+=2; \ + } + +#define PEEK_BITS(n) (bitbuf >> (ULONG_BITS - (n))) +#define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n))) + +#define READ_BITS(v,n) do { \ + ENSURE_BITS(n); \ + (v) = PEEK_BITS(n); \ + REMOVE_BITS(n); \ +} while (0) + + +/* Huffman macros */ + +#define TABLEBITS(tbl) (LZX_##tbl##_TABLEBITS) +#define MAXSYMBOLS(tbl) (LZX_##tbl##_MAXSYMBOLS) +#define SYMTABLE(tbl) (pState->tbl##_table) +#define LENTABLE(tbl) (pState->tbl##_len) + +/* BUILD_TABLE(tablename) builds a huffman lookup table from code lengths. + * In reality, it just calls make_decode_table() with the appropriate + * values - they're all fixed by some #defines anyway, so there's no point + * writing each call out in full by hand. + */ +#define BUILD_TABLE(tbl) \ + if (make_decode_table( \ + MAXSYMBOLS(tbl), TABLEBITS(tbl), LENTABLE(tbl), SYMTABLE(tbl) \ + )) { return DECR_ILLEGALDATA; } + + +/* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the + * bitstream using the stated table and puts it in var. + */ +#define READ_HUFFSYM(tbl,var) do { \ + ENSURE_BITS(16); \ + hufftbl = SYMTABLE(tbl); \ + if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) { \ + j = 1 << (ULONG_BITS - TABLEBITS(tbl)); \ + do { \ + j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0; \ + if (!j) { return DECR_ILLEGALDATA; } \ + } while ((i = hufftbl[i]) >= MAXSYMBOLS(tbl)); \ + } \ + j = LENTABLE(tbl)[(var) = i]; \ + REMOVE_BITS(j); \ +} while (0) + + +/* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols + * first to last in the given table. The code lengths are stored in their + * own special LZX way. + */ +#define READ_LENGTHS(tbl,first,last) do { \ + lb.bb = bitbuf; lb.bl = bitsleft; lb.ip = inpos; \ + if (lzx_read_lens(pState, LENTABLE(tbl),(first),(last),&lb)) { \ + return DECR_ILLEGALDATA; \ + } \ + bitbuf = lb.bb; bitsleft = lb.bl; inpos = lb.ip; \ +} while (0) + + +/* make_decode_table(nsyms, nbits, length[], table[]) + * + * This function was coded by David Tritscher. It builds a fast huffman + * decoding table out of just a canonical huffman code lengths table. + * + * nsyms = total number of symbols in this huffman tree. + * nbits = any symbols with a code length of nbits or less can be decoded + * in one lookup of the table. + * length = A table to get code lengths from [0 to syms-1] + * table = The table to fill up with decoded symbols and pointers. + * + * Returns 0 for OK or 1 for error + */ + +static int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table) { + register UWORD sym; + register ULONG leaf; + register UBYTE bit_num = 1; + ULONG fill; + ULONG pos = 0; /* the current position in the decode table */ + ULONG table_mask = 1 << nbits; + ULONG bit_mask = table_mask >> 1; /* don't do 0 length codes */ + ULONG next_symbol = bit_mask; /* base of allocation for long codes */ + + /* fill entries for codes short enough for a direct mapping */ + while (bit_num <= nbits) { + for (sym = 0; sym < nsyms; sym++) { + if (length[sym] == bit_num) { + leaf = pos; + + if((pos += bit_mask) > table_mask) return 1; /* table overrun */ + + /* fill all possible lookups of this symbol with the symbol itself */ + fill = bit_mask; + while (fill-- > 0) table[leaf++] = sym; + } + } + bit_mask >>= 1; + bit_num++; + } + + /* if there are any codes longer than nbits */ + if (pos != table_mask) { + /* clear the remainder of the table */ + for (sym = pos; sym < table_mask; sym++) table[sym] = 0; + + /* give ourselves room for codes to grow by up to 16 more bits */ + pos <<= 16; + table_mask <<= 16; + bit_mask = 1 << 15; + + while (bit_num <= 16) { + for (sym = 0; sym < nsyms; sym++) { + if (length[sym] == bit_num) { + leaf = pos >> 16; + for (fill = 0; fill < bit_num - nbits; fill++) { + /* if this path hasn't been taken yet, 'allocate' two entries */ + if (table[leaf] == 0) { + table[(next_symbol << 1)] = 0; + table[(next_symbol << 1) + 1] = 0; + table[leaf] = next_symbol++; + } + /* follow the path and select either left or right for next bit */ + leaf = table[leaf] << 1; + if ((pos >> (15-fill)) & 1) leaf++; + } + table[leaf] = sym; + + if ((pos += bit_mask) > table_mask) return 1; /* table overflow */ + } + } + bit_mask >>= 1; + bit_num++; + } + } + + /* full table? */ + if (pos == table_mask) return 0; + + /* either erroneous table, or all elements are 0 - let's find out. */ + for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1; + return 0; +} + +struct lzx_bits { + ULONG bb; + int bl; + UBYTE *ip; +}; + +static int lzx_read_lens(struct LZXstate *pState, UBYTE *lens, ULONG first, ULONG last, struct lzx_bits *lb) { + ULONG i,j, x,y; + int z; + + register ULONG bitbuf = lb->bb; + register int bitsleft = lb->bl; + UBYTE *inpos = lb->ip; + UWORD *hufftbl; + + for (x = 0; x < 20; x++) { + READ_BITS(y, 4); + LENTABLE(PRETREE)[x] = y; + } + BUILD_TABLE(PRETREE); + + for (x = first; x < last; ) { + READ_HUFFSYM(PRETREE, z); + if (z == 17) { + READ_BITS(y, 4); y += 4; + while (y--) lens[x++] = 0; + } + else if (z == 18) { + READ_BITS(y, 5); y += 20; + while (y--) lens[x++] = 0; + } + else if (z == 19) { + READ_BITS(y, 1); y += 4; + READ_HUFFSYM(PRETREE, z); + z = lens[x] - z; if (z < 0) z += 17; + while (y--) lens[x++] = z; + } + else { + z = lens[x] - z; if (z < 0) z += 17; + lens[x++] = z; + } + } + + lb->bb = bitbuf; + lb->bl = bitsleft; + lb->ip = inpos; + return 0; +} + +int LZXdecompress(struct LZXstate *pState, unsigned char *inpos, unsigned char *outpos, int inlen, int outlen) { + UBYTE *endinp = inpos + inlen; + UBYTE *window = pState->window; + UBYTE *runsrc, *rundest; + UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */ + + ULONG window_posn = pState->window_posn; + ULONG window_size = pState->window_size; + ULONG R0 = pState->R0; + ULONG R1 = pState->R1; + ULONG R2 = pState->R2; + + register ULONG bitbuf; + register int bitsleft; + ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */ + struct lzx_bits lb; /* used in READ_LENGTHS macro */ + + int togo = outlen, this_run, main_element, aligned_bits; + int match_length, length_footer, extra, verbatim_bits; + + INIT_BITSTREAM; + + /* read header if necessary */ + if (!pState->header_read) { + i = j = 0; + READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); } + pState->intel_filesize = (i << 16) | j; /* or 0 if not encoded */ + pState->header_read = 1; + } + + /* main decoding loop */ + while (togo > 0) { + /* last block finished, new block expected */ + if (pState->block_remaining == 0) { + if (pState->block_type == LZX_BLOCKTYPE_UNCOMPRESSED) { + if (pState->block_length & 1) inpos++; /* realign bitstream to word */ + INIT_BITSTREAM; + } + + READ_BITS(pState->block_type, 3); + READ_BITS(i, 16); + READ_BITS(j, 8); + pState->block_remaining = pState->block_length = (i << 8) | j; + + switch (pState->block_type) { + case LZX_BLOCKTYPE_ALIGNED: + for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; } + BUILD_TABLE(ALIGNED); + /* rest of aligned header is same as verbatim */ + + case LZX_BLOCKTYPE_VERBATIM: + READ_LENGTHS(MAINTREE, 0, 256); + READ_LENGTHS(MAINTREE, 256, pState->main_elements); + BUILD_TABLE(MAINTREE); + if (LENTABLE(MAINTREE)[0xE8] != 0) pState->intel_started = 1; + + READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS); + BUILD_TABLE(LENGTH); + break; + + case LZX_BLOCKTYPE_UNCOMPRESSED: + pState->intel_started = 1; /* because we can't assume otherwise */ + ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */ + if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */ + R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4; + R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4; + R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4; + break; + + default: + return DECR_ILLEGALDATA; + } + } + + /* buffer exhaustion check */ + if (inpos > endinp) { + /* it's possible to have a file where the next run is less than + * 16 bits in size. In this case, the READ_HUFFSYM() macro used + * in building the tables will exhaust the buffer, so we should + * allow for this, but not allow those accidentally read bits to + * be used (so we check that there are at least 16 bits + * remaining - in this boundary case they aren't really part of + * the compressed data) + */ + if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA; + } + + while ((this_run = pState->block_remaining) > 0 && togo > 0) { + if (this_run > togo) this_run = togo; + togo -= this_run; + pState->block_remaining -= this_run; + + /* apply 2^x-1 mask */ + window_posn &= window_size - 1; + /* runs can't straddle the window wraparound */ + if ((window_posn + this_run) > window_size) + return DECR_DATAFORMAT; + + switch (pState->block_type) { + + case LZX_BLOCKTYPE_VERBATIM: + while (this_run > 0) { + READ_HUFFSYM(MAINTREE, main_element); + + if (main_element < LZX_NUM_CHARS) { + /* literal: 0 to LZX_NUM_CHARS-1 */ + window[window_posn++] = main_element; + this_run--; + } + else { + /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */ + main_element -= LZX_NUM_CHARS; + + match_length = main_element & LZX_NUM_PRIMARY_LENGTHS; + if (match_length == LZX_NUM_PRIMARY_LENGTHS) { + READ_HUFFSYM(LENGTH, length_footer); + match_length += length_footer; + } + match_length += LZX_MIN_MATCH; + + match_offset = main_element >> 3; + + if (match_offset > 2) { + /* not repeated offset */ + if (match_offset != 3) { + extra = extra_bits[match_offset]; + READ_BITS(verbatim_bits, extra); + match_offset = position_base[match_offset] - 2 + verbatim_bits; + } + else { + match_offset = 1; + } + + /* update repeated offset LRU queue */ + R2 = R1; R1 = R0; R0 = match_offset; + } + else if (match_offset == 0) { + match_offset = R0; + } + else if (match_offset == 1) { + match_offset = R1; + R1 = R0; R0 = match_offset; + } + else /* match_offset == 2 */ { + match_offset = R2; + R2 = R0; R0 = match_offset; + } + + rundest = window + window_posn; + runsrc = rundest - match_offset; + window_posn += match_length; + if (window_posn > window_size) return DECR_ILLEGALDATA; + this_run -= match_length; + + /* copy any wrapped around source data */ + while ((runsrc < window) && (match_length-- > 0)) { + *rundest++ = *(runsrc + window_size); runsrc++; + } + /* copy match data - no worries about destination wraps */ + while (match_length-- > 0) *rundest++ = *runsrc++; + + } + } + break; + + case LZX_BLOCKTYPE_ALIGNED: + while (this_run > 0) { + READ_HUFFSYM(MAINTREE, main_element); + + if (main_element < LZX_NUM_CHARS) { + /* literal: 0 to LZX_NUM_CHARS-1 */ + window[window_posn++] = main_element; + this_run--; + } + else { + /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */ + main_element -= LZX_NUM_CHARS; + + match_length = main_element & LZX_NUM_PRIMARY_LENGTHS; + if (match_length == LZX_NUM_PRIMARY_LENGTHS) { + READ_HUFFSYM(LENGTH, length_footer); + match_length += length_footer; + } + match_length += LZX_MIN_MATCH; + + match_offset = main_element >> 3; + + if (match_offset > 2) { + /* not repeated offset */ + extra = extra_bits[match_offset]; + match_offset = position_base[match_offset] - 2; + if (extra > 3) { + /* verbatim and aligned bits */ + extra -= 3; + READ_BITS(verbatim_bits, extra); + match_offset += (verbatim_bits << 3); + READ_HUFFSYM(ALIGNED, aligned_bits); + match_offset += aligned_bits; + } + else if (extra == 3) { + /* aligned bits only */ + READ_HUFFSYM(ALIGNED, aligned_bits); + match_offset += aligned_bits; + } + else if (extra > 0) { /* extra==1, extra==2 */ + /* verbatim bits only */ + READ_BITS(verbatim_bits, extra); + match_offset += verbatim_bits; + } + else /* extra == 0 */ { + /* ??? */ + match_offset = 1; + } + + /* update repeated offset LRU queue */ + R2 = R1; R1 = R0; R0 = match_offset; + } + else if (match_offset == 0) { + match_offset = R0; + } + else if (match_offset == 1) { + match_offset = R1; + R1 = R0; R0 = match_offset; + } + else /* match_offset == 2 */ { + match_offset = R2; + R2 = R0; R0 = match_offset; + } + + rundest = window + window_posn; + runsrc = rundest - match_offset; + window_posn += match_length; + if (window_posn > window_size) return DECR_ILLEGALDATA; + this_run -= match_length; + + /* copy any wrapped around source data */ + while ((runsrc < window) && (match_length-- > 0)) { + *rundest++ = *(runsrc + window_size); runsrc++; + } + /* copy match data - no worries about destination wraps */ + while (match_length-- > 0) *rundest++ = *runsrc++; + + } + } + break; + + case LZX_BLOCKTYPE_UNCOMPRESSED: + if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA; + memcpy(window + window_posn, inpos, (size_t) this_run); + inpos += this_run; window_posn += this_run; + break; + + default: + return DECR_ILLEGALDATA; /* might as well */ + } + + } + } + + if (togo != 0) return DECR_ILLEGALDATA; + memcpy(outpos, window + ((!window_posn) ? window_size : window_posn) - outlen, (size_t) outlen); + + pState->window_posn = window_posn; + pState->R0 = R0; + pState->R1 = R1; + pState->R2 = R2; + + /* intel E8 decoding */ + if ((pState->frames_read++ < 32768) && pState->intel_filesize != 0) { + if (outlen <= 6 || !pState->intel_started) { + pState->intel_curpos += outlen; + } + else { + UBYTE *data = outpos; + UBYTE *dataend = data + outlen - 10; + LONG curpos = pState->intel_curpos; + LONG filesize = pState->intel_filesize; + LONG abs_off, rel_off; + + pState->intel_curpos = curpos + outlen; + + while (data < dataend) { + if (*data++ != 0xE8) { curpos++; continue; } + abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24); + if ((abs_off >= -curpos) && (abs_off < filesize)) { + rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize; + data[0] = (UBYTE) rel_off; + data[1] = (UBYTE) (rel_off >> 8); + data[2] = (UBYTE) (rel_off >> 16); + data[3] = (UBYTE) (rel_off >> 24); + } + data += 4; + curpos += 5; + } + } + } + return DECR_OK; +} + +#ifdef LZX_CHM_TESTDRIVER +int main(int c, char **v) +{ + FILE *fin, *fout; + struct LZXstate state; + UBYTE ibuf[16384]; + UBYTE obuf[32768]; + int ilen, olen; + int status; + int i; + int count=0; + int w = atoi(v[1]); + LZXinit(&state, w); + fout = fopen(v[2], "wb"); + for (i=3; i<c; i++) + { + fin = fopen(v[i], "rb"); + ilen = fread(ibuf, 1, 16384, fin); + status = LZXdecompress(&state, ibuf, obuf, ilen, 32768); + switch (status) + { + case DECR_OK: + printf("ok\n"); + fwrite(obuf, 1, 32768, fout); + break; + case DECR_DATAFORMAT: + printf("bad format\n"); + break; + case DECR_ILLEGALDATA: + printf("illegal data\n"); + break; + case DECR_NOMEMORY: + printf("no memory\n"); + break; + default: + break; + } + fclose(fin); + if (++count == 2) + { + count = 0; + LZXreset(&state); + } + } + fclose(fout); +} +#endif diff --git a/lib/chmlib/lzx.h b/lib/chmlib/lzx.h new file mode 100644 index 0000000..26d71a8 --- /dev/null +++ b/lib/chmlib/lzx.h @@ -0,0 +1,62 @@ +/* $Id: lzx.h 148 2007-03-07 09:22:36Z gyunaev $ */ +/*************************************************************************** + * lzx.h - LZX decompression routines * + * ------------------- * + * * + * maintainer: Jed Wing <jedwin@ugcs.caltech.edu> * + * source: modified lzx.c from cabextract v0.5 * + * notes: This file was taken from cabextract v0.5, which was, * + * itself, a modified version of the lzx decompression code * + * from unlzx. * + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. Note that an exemption to this * + * license has been granted by Stuart Caie for the purposes of * + * distribution with chmlib. This does not, to the best of my * + * knowledge, constitute a change in the license of this (the LZX) code * + * in general. * + * * + ***************************************************************************/ + +#ifndef INCLUDED_LZX_H +#define INCLUDED_LZX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* return codes */ +#define DECR_OK (0) +#define DECR_DATAFORMAT (1) +#define DECR_ILLEGALDATA (2) +#define DECR_NOMEMORY (3) + +/* opaque state structure */ +struct LZXstate; + +/* create an lzx state object */ +struct LZXstate *LZXinit(int window); + +/* destroy an lzx state object */ +void LZXteardown(struct LZXstate *pState); + +/* reset an lzx stream */ +int LZXreset(struct LZXstate *pState); + +/* decompress an LZX compressed block */ +int LZXdecompress(struct LZXstate *pState, + unsigned char *inpos, + unsigned char *outpos, + int inlen, + int outlen); + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDED_LZX_H */ diff --git a/lib/kio-msits/Makefile.am b/lib/kio-msits/Makefile.am new file mode 100644 index 0000000..53f5205 --- /dev/null +++ b/lib/kio-msits/Makefile.am @@ -0,0 +1,14 @@ +METASOURCES = AUTO +INCLUDES = $(QT_INCLUDES) $(CHM_INCLUDES) $(KDE_INCLUDES) $(LIBCHMFILE_INCLUDES) + +kde_module_LTLIBRARIES = kio_msits.la + +kio_msits_la_SOURCES = msits.cpp +kio_msits_la_LIBADD = -lkio $(CHM_LIBS) +kio_msits_la_LDFLAGS = -module -avoid-version $(QT_LIBS) $(KDE_LDFLAGS) $(KDE_LIBS) $(KDE_PLUGIN) + +protocol_DATA = msits.protocol +protocoldir = $(kde_servicesdir) + +# Put it here to avoid creating another directory +kde_apps_DATA = kchmviewer.desktop diff --git a/lib/kio-msits/kchmviewer.desktop b/lib/kio-msits/kchmviewer.desktop new file mode 100644 index 0000000..d97098a --- /dev/null +++ b/lib/kio-msits/kchmviewer.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Categories=Qt;KDE;Utility; +Encoding=UTF-8 +Type=Application +Exec=kchmviewer %U +Icon=kchmviewer.png +Comment= +Terminal=0 +Name=KchmViewer +Comment=A viewer of CHM (MS-Help) files +MimeType=application/chm diff --git a/lib/kio-msits/msits.cpp b/lib/kio-msits/msits.cpp new file mode 100755 index 0000000..cf7cf27 --- /dev/null +++ b/lib/kio-msits/msits.cpp @@ -0,0 +1,320 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> + +#include <kapplication.h> +#include <kdebug.h> +#include <kinstance.h> +#include <kurl.h> +#include <kmimemagic.h> + +#include <qfile.h> +#include <qbitarray.h> +#include <qvaluevector.h> + +#include "msits.h" +#include "libchmurlfactory.h" + +using namespace KIO; + +extern "C" +{ + int kdemain( int argc, char **argv ) + { + kdDebug() << "*** kio_msits Init" << endl; + + KInstance instance( "kio_msits" ); + + if ( argc != 4 ) + { + kdDebug() << "Usage: kio_msits protocol domain-socket1 domain-socket2" << endl; + exit (-1); + } + + ProtocolMSITS slave ( argv[2], argv[3] ); + slave.dispatchLoop(); + + kdDebug() << "*** kio_msits Done" << endl; + return 0; + } +} + +ProtocolMSITS::ProtocolMSITS (const QCString &pool_socket, const QCString &app_socket) + : SlaveBase ("kio_msits", pool_socket, app_socket) +{ + m_chmFile = 0; +} + +ProtocolMSITS::~ProtocolMSITS() +{ + if ( !m_chmFile ) + return; + + chm_close (m_chmFile); + m_chmFile = 0; +} + +// A simple stat() wrapper +static bool isDirectory ( const QString & filename ) +{ + return filename[filename.length() - 1] == '/'; +} + + +void ProtocolMSITS::get( const KURL& url ) +{ + QString htmdata, fileName; + chmUnitInfo ui; + QByteArray buf; + + kdDebug() << "kio_msits::get() " << url.path() << endl; + + if ( !parseLoadAndLookup ( url, fileName ) ) + return; // error() has been called by parseLoadAndLookup + + kdDebug() << "kio_msits::get: parseLoadAndLookup returned " << fileName << endl; + + if ( LCHMUrlFactory::handleFileType( url.path(), htmdata ) ) + { + buf = htmdata.utf8(); + kdDebug() << "Using special handling for image pages: " << htmdata << endl; + } + else + { + if ( isDirectory (fileName) ) + { + error( KIO::ERR_IS_DIRECTORY, url.prettyURL() ); + return; + } + + if ( !ResolveObject ( fileName, &ui) ) + { + kdDebug() << "kio_msits::get: could not resolve filename " << fileName << endl; + error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() ); + return; + } + + buf.resize( ui.length ); + + if ( RetrieveObject (&ui, (unsigned char*) buf.data(), 0, ui.length) == 0 ) + { + kdDebug() << "kio_msits::get: could not retrieve filename " << fileName << endl; + error( KIO::ERR_NO_CONTENT, url.prettyURL() ); + return; + } + } + + totalSize( buf.size() ); + KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType( buf, fileName ); + kdDebug() << "Emitting mimetype " << result->mimeType() << endl; + + mimeType( result->mimeType() ); + data( buf ); + processedSize( buf.size() ); + + finished(); +} + + +bool ProtocolMSITS::parseLoadAndLookup ( const KURL& url, QString& abspath ) +{ + kdDebug() << "ProtocolMSITS::parseLoadAndLookup (const KURL&) " << url.path() << endl; + + int pos = url.path().find ("::"); + + if ( pos == -1 ) + { + error( KIO::ERR_MALFORMED_URL, url.prettyURL() ); + return false; + } + + QString filename = url.path().left (pos); + abspath = url.path().mid (pos + 2); // skip :: + + // Some buggy apps add ms-its:/ to the path as well + if ( abspath.startsWith( "ms-its:" ) ) + abspath = abspath.mid( 7 ); + + kdDebug() << "ProtocolMSITS::parseLoadAndLookup: filename " << filename << ", path " << abspath << endl; + + if ( filename.isEmpty() ) + { + error( KIO::ERR_MALFORMED_URL, url.prettyURL() ); + return false; + } + + // If the file has been already loaded, nothing to do. + if ( m_chmFile && filename == m_openedFile ) + return true; + + kdDebug() << "Opening a new CHM file " << filename << endl; + + // First try to open a temporary file + chmFile * tmpchm; + + if ( (tmpchm = chm_open ( QFile::encodeName (filename))) == 0 ) + { + error( KIO::ERR_COULD_NOT_READ, url.prettyURL() ); + return false; + } + + // Replace an existing file by a new one + if ( m_chmFile ) + chm_close (m_chmFile); + + m_chmFile = tmpchm; + m_openedFile = filename; + + kdDebug() << "A CHM file " << filename << " has beed opened successfully" << endl; + return true; +} + +/* + * Shamelessly stolen from a KDE KIO tutorial + */ +static void app_entry(UDSEntry& e, unsigned int uds, const QString& str) +{ + UDSAtom a; + a.m_uds = uds; + a.m_str = str; + e.append(a); +} + + // appends an int with the UDS-ID uds + static void app_entry(UDSEntry& e, unsigned int uds, long l) + { + UDSAtom a; + a.m_uds = uds; + a.m_long = l; + e.append(a); +} + +// internal function +// fills a directory item with its name and size +static void app_dir(UDSEntry& e, const QString & name) +{ + e.clear(); + app_entry(e, KIO::UDS_NAME, name); + app_entry(e, KIO::UDS_FILE_TYPE, S_IFDIR); + app_entry(e, KIO::UDS_SIZE, 1); +} + +// internal function +// fills a file item with its name and size +static void app_file(UDSEntry& e, const QString & name, size_t size) +{ + e.clear(); + app_entry(e, KIO::UDS_NAME, name); + app_entry(e, KIO::UDS_FILE_TYPE, S_IFREG); + app_entry(e, KIO::UDS_SIZE, size); +} + +void ProtocolMSITS::stat (const KURL & url) +{ + QString fileName; + chmUnitInfo ui; + + kdDebug() << "kio_msits::stat (const KURL& url) " << url.path() << endl; + + if ( !parseLoadAndLookup ( url, fileName ) ) + return; // error() has been called by parseLoadAndLookup + + if ( !ResolveObject ( fileName, &ui ) ) + { + error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() ); + return; + } + + kdDebug() << "kio_msits::stat: adding an entry for " << fileName << endl; + UDSEntry entry; + + if ( isDirectory ( fileName ) ) + app_dir(entry, fileName); + else + app_file(entry, fileName, ui.length); + + statEntry (entry); + + finished(); +} + + +// A local CHMLIB enumerator +static int chmlib_enumerator (struct chmFile *, struct chmUnitInfo *ui, void *context) +{ + ((QValueVector<QString> *) context)->push_back (QString::fromLocal8Bit (ui->path)); + return CHM_ENUMERATOR_CONTINUE; +} + + +void ProtocolMSITS::listDir (const KURL & url) +{ + QString filepath; + + kdDebug() << "kio_msits::listDir (const KURL& url) " << url.path() << endl; + + if ( !parseLoadAndLookup ( url, filepath ) ) + return; // error() has been called by parseLoadAndLookup + + filepath += "/"; + + if ( !isDirectory (filepath) ) + { + error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path()); + return; + } + + kdDebug() << "kio_msits::listDir: enumerating directory " << filepath << endl; + + QValueVector<QString> listing; + + if ( chm_enumerate_dir ( m_chmFile, + filepath.local8Bit(), + CHM_ENUMERATE_NORMAL | CHM_ENUMERATE_FILES | CHM_ENUMERATE_DIRS, + chmlib_enumerator, + &listing ) != 1 ) + { + error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path()); + return; + } + + UDSEntry entry; + unsigned int striplength = filepath.length(); + + for ( unsigned int i = 0; i < listing.size(); i++ ) + { + // Strip the direcroty name + QString ename = listing[i].mid (striplength); + + if ( isDirectory ( ename ) ) + app_dir(entry, ename); + else + app_file(entry, ename, 0); + + listEntry(entry, false); + } + + listEntry(entry, true); + finished(); +} diff --git a/lib/kio-msits/msits.h b/lib/kio-msits/msits.h new file mode 100755 index 0000000..3de7719 --- /dev/null +++ b/lib/kio-msits/msits.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef MSITS_H +#define MSITS_H + + +#include <kio/slavebase.h> +#include <kurl.h> + +#include <qstring.h> +#include <qcstring.h> + +#include "config.h" +#include "chm_lib.h" + + +class ProtocolMSITS : public KIO::SlaveBase +{ +public: + ProtocolMSITS ( const QCString&, const QCString& ); + virtual ~ProtocolMSITS(); + + virtual void get ( const KURL& ); + virtual void listDir (const KURL & url); + virtual void stat (const KURL & url); + +private: + // This function does next thing: + // - parses the URL to get a file name and URL inside the file; + // - loads a new CHM file, if needed; + // - returns the parsed URL inside the file; + bool parseLoadAndLookup ( const KURL&, QString& abspath ); + + // Resolve an object inside a CHM file + inline bool ResolveObject (const QString& fileName, chmUnitInfo *ui) + { + return m_chmFile != NULL && ::chm_resolve_object(m_chmFile, fileName.utf8(), ui) == CHM_RESOLVE_SUCCESS; + } + + // Retrieve an object from the CHM file + inline size_t RetrieveObject (const chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize) + { +#if USE_BUILTIN_CHMLIB + return ::chm_retrieve_object(m_chmFile, ui, buffer, + fileOffset, bufferSize); +#else + return ::chm_retrieve_object(m_chmFile, const_cast<chmUnitInfo*>(ui), + buffer, fileOffset, bufferSize); +#endif + } + + // An opened file name, if presend + QString m_openedFile; + + // a CHM structure file pointer (from chmlib) + chmFile * m_chmFile; +}; + + +#endif /* MSITS_H */ diff --git a/lib/kio-msits/msits.protocol b/lib/kio-msits/msits.protocol new file mode 100755 index 0000000..b087903 --- /dev/null +++ b/lib/kio-msits/msits.protocol @@ -0,0 +1,24 @@ +[Protocol] +exec=kio_msits +protocol=ms-its +input=none +output=filesystem +reading=true +listing=Name,Type,Size +defaultMimetype=text/html +Description=A kioslave for displaying WinHelp files +Description[da]=En kioslave til visning af Windows hjælpefiler +Description[de]=Ein Ein-/Ausgabemodul zur Anzeige von WinHelp-Dateien +Description[es]=Un kioslave para mostrar archivos WinHelp +Description[et]=WinHelp-failide kuvamise IO-moodul +Description[fr]=Un module d'entrée / sortie pour l'affichage des fichiers WinHelp +Description[hu]=KDE-protokoll WinHelp-fájlok megjelenítéséhez +Description[it]=Un kioslave per mostrare i file WinHelp +Description[nl]=Een kioslave voor het weergeven van WinHelp-bestanden +Description[pl]=kioslave do pokazywania plików WinHelp +Description[pt]=A 'kioslave' para mostrar ficheiros WinHelp +Description[pt_BR]=Um kioslave para exibir arquivos WinHelp +Description[ru]=Обработчик ввода-вывода для файлов WinHelp +Description[sv]=En I/O-slav för att visa WinHelp-filer +Description[xx]=xxA kioslave for displaying WinHelp filesxx +Icon=help diff --git a/lib/libchmfile/Makefile.am b/lib/libchmfile/Makefile.am new file mode 100644 index 0000000..2e16016 --- /dev/null +++ b/lib/libchmfile/Makefile.am @@ -0,0 +1,10 @@ +lib_LIBRARIES=libchmfile.a +libchmfile_a_SOURCES = libchmfile.cpp libchmfile_search.cpp libchmfileimpl.cpp \ + libchmtextencoding.cpp libchmtocimage.cpp +noinst_HEADERS = libchmfile.h bitfiddle.h libchmfileimpl.h libchmtextencoding.h \ + libchmtocimage.h libchmurlfactory.h + +INCLUDES = $(QT_INCLUDES) $(CHM_INCLUDES) $(KDE_INCLUDES) + +METASOURCES = AUTO +KDE_OPTIONS = qtonly diff --git a/lib/libchmfile/bitfiddle.h b/lib/libchmfile/bitfiddle.h new file mode 100644 index 0000000..cd97b8e --- /dev/null +++ b/lib/libchmfile/bitfiddle.h @@ -0,0 +1,155 @@ +/* + + Copyright (C) 2003 Razvan Cojocaru <razvanco@gmx.net> + Most of the code in this file is a modified version of code from + Pabs' GPL chmdeco project, credits and thanks go to him. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#define UINT16ARRAY(x) ((unsigned char)(x)[0] | ((u_int16_t)(x)[1] << 8)) +#define UINT32ARRAY(x) (UINT16ARRAY(x) | ((u_int32_t)(x)[2] << 16) \ + | ((u_int32_t)(x)[3] << 24)) + +inline unsigned int get_int32_le( void *addr) +{ + unsigned char *p = (unsigned char*) addr; + return (unsigned int) ( p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24) ); +} + + +inline u_int64_t be_encint(unsigned char* buffer, size_t& length) +{ + u_int64_t result = 0; + int shift=0; + length = 0; + + do { + result |= ((*buffer) & 0x7f) << shift; + shift += 7; + ++length; + + } while (*(buffer++) & 0x80); + + return result; +} + + +/* + Finds the first unset bit in memory. Returns the number of set bits found. + Returns -1 if the buffer runs out before we find an unset bit. +*/ +inline int ffus(unsigned char* byte, int* bit, size_t& length) +{ + int bits = 0; + length = 0; + + while(*byte & (1 << *bit)){ + if(*bit) + --(*bit); + else { + ++byte; + ++length; + *bit = 7; + } + ++bits; + } + + if(*bit) + --(*bit); + else { + ++length; + *bit = 7; + } + + return bits; +} + + +inline u_int64_t sr_int(unsigned char* byte, int* bit, + unsigned char s, unsigned char r, size_t& length) +{ + u_int64_t ret; + unsigned char mask; + int n, n_bits, num_bits, base, count; + length = 0; + size_t fflen; + + if(!bit || *bit > 7 || s != 2) + return ~(u_int64_t)0; + ret = 0; + + count = ffus(byte, bit, fflen); + length += fflen; + byte += length; + + n_bits = n = r + (count ? count-1 : 0) ; + + while(n > 0) { + num_bits = n > *bit ? *bit : n-1; + base = n > *bit ? 0 : *bit - (n-1); + + switch(num_bits){ + case 0: + mask = 1; + break; + case 1: + mask = 3; + break; + case 2: + mask = 7; + break; + case 3: + mask = 0xf; + break; + case 4: + mask = 0x1f; + break; + case 5: + mask = 0x3f; + break; + case 6: + mask = 0x7f; + break; + case 7: + mask = 0xff; + break; + default: + mask = 0xff; + break; + } + + mask <<= base; + ret = (ret << (num_bits+1)) | + (u_int64_t)((*byte & mask) >> base); + + if( n > *bit ){ + ++byte; + ++length; + n -= *bit+1; + *bit = 7; + } else { + *bit -= n; + n = 0; + } + } + + if(count) + ret |= (u_int64_t)1 << n_bits; + + return ret; +} diff --git a/lib/libchmfile/lchmurlhandler.cpp b/lib/libchmfile/lchmurlhandler.cpp new file mode 100644 index 0000000..6e905f6 --- /dev/null +++ b/lib/libchmfile/lchmurlhandler.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include "lchmurlhandler.h" + +LCHMUrlHandler::LCHMUrlHandler() +{ +} + + +LCHMUrlHandler::~LCHMUrlHandler() +{ +} + + diff --git a/lib/libchmfile/lchmurlhandler.h b/lib/libchmfile/lchmurlhandler.h new file mode 100644 index 0000000..9eb29ec --- /dev/null +++ b/lib/libchmfile/lchmurlhandler.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef LCHMURLHANDLER_H +#define LCHMURLHANDLER_H + +/** + @author tim <tim@krasnogorsk.ru> +*/ +class LCHMUrlHandler{ +public: + LCHMUrlHandler(); + + ~LCHMUrlHandler(); + +}; + +#endif diff --git a/lib/libchmfile/libchmfile.cpp b/lib/libchmfile/libchmfile.cpp new file mode 100644 index 0000000..7d13aaa --- /dev/null +++ b/lib/libchmfile/libchmfile.cpp @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "libchmfile.h" +#include "libchmfileimpl.h" + + +LCHMFile::LCHMFile( ) +{ + m_impl = new LCHMFileImpl(); +} + +LCHMFile::~ LCHMFile( ) +{ + delete m_impl; +} + +bool LCHMFile::loadFile( const QString & archiveName ) +{ + return m_impl->loadFile( archiveName ); +} + +void LCHMFile::closeAll( ) +{ + m_impl->closeAll(); +} + +QString LCHMFile::title( ) const +{ + return m_impl->title(); +} + +QString LCHMFile::homeUrl( ) const +{ + QString url = m_impl->homeUrl(); + return url.isNull() ? "/" : url; +} + +bool LCHMFile::hasTableOfContents( ) const +{ + return !m_impl->m_topicsFile.isNull(); +} + +bool LCHMFile::hasIndexTable( ) const +{ + return !m_impl->m_indexFile.isNull(); +} + +bool LCHMFile::hasSearchTable( ) const +{ + return m_impl->m_searchAvailable; +} + +bool LCHMFile::parseTableOfContents( QT34VECTOR< LCHMParsedEntry > * topics ) const +{ + return m_impl->parseFileAndFillArray( m_impl->m_topicsFile, topics, false ); +} + +bool LCHMFile::parseIndex( QT34VECTOR< LCHMParsedEntry > * indexes ) const +{ + return m_impl->parseFileAndFillArray( m_impl->m_indexFile, indexes, true ); +} + +bool LCHMFile::getFileContentAsString( QString * str, const QString & url ) +{ + return m_impl->getFileContentAsString( str, url ); +} + +bool LCHMFile::getFileContentAsBinary( QByteArray * data, const QString & url ) +{ + return m_impl->getFileContentAsBinary( data, url ); +} + +bool LCHMFile::enumerateFiles( QStringList * files ) +{ + return m_impl->enumerateFiles( files ); +} + +QString LCHMFile::getTopicByUrl( const QString & url ) +{ + return m_impl->getTopicByUrl( url ); +} + +const QPixmap * LCHMFile::getBookIconPixmap( unsigned int imagenum ) +{ + return m_impl->getBookIconPixmap( imagenum ); +} + +const LCHMTextEncoding * LCHMFile::currentEncoding( ) const +{ + return m_impl->m_currentEncoding; +} + +bool LCHMFile::setCurrentEncoding( const LCHMTextEncoding * encoding ) +{ + return m_impl->setCurrentEncoding( encoding ); +} + +QString LCHMFile::normalizeUrl( const QString & url ) const +{ + return m_impl->normalizeUrl( url ); +} + +bool LCHMFile::getFileSize(unsigned int * size, const QString & url) +{ + return m_impl->getFileSize( size, url ); +} diff --git a/lib/libchmfile/libchmfile.h b/lib/libchmfile/libchmfile.h new file mode 100644 index 0000000..ab129b5 --- /dev/null +++ b/lib/libchmfile/libchmfile.h @@ -0,0 +1,290 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef INCLUDE_LIBCHMFILE_H +#define INCLUDE_LIBCHMFILE_H + +#include <qstring.h> +#include <qcstring.h> +#include <qlistview.h> +#include <qlistbox.h> +#include <qmap.h> +#include <qvaluevector.h> +#include <qtextcodec.h> + +#include "libchmtextencoding.h" + +// Qt3/Qt4 compatibility: in Qt3 QVector stores pointers, not values - so QValueVector should be used. +// In Qt4 QVector stores values, so we can use QVector +#if defined (USE_QT_4) + #define QT34VECTOR QVector +#else + #define QT34VECTOR QValueVector +#endif + + +//! Contains different (non-standard) image types +namespace LCHMBookIcons +{ + const int IMAGE_NONE = -1; + const int IMAGE_AUTO = -2; + const int IMAGE_INDEX = -3; + + const int MAX_BUILTIN_ICONS = 42; +}; + + +//! Contains a single index or TOC entry. See LCHMFile::parseTOC() and LCHMFile::parseIndex() +typedef struct +{ + //! Entry name + QString name; + + //! Entry URLs. The TOC entry should have only one URL; the index entry could have several. + QStringList urls; + + //! Associated image number. Used for TOC only; indexes does not have the image. + //! Use LCHMFile::getBookIconPixmap() to get associated pixmap icon + int imageid; + + //! Indentation level for this entry. + int indent; + +} LCHMParsedEntry; + + +// forward declaration +class LCHMFileImpl; + +//! CHM files processor, heavily based on chmlib. Used search code from xchm. +class LCHMFile +{ + public: + //! Default constructor and destructor. + LCHMFile(); + ~LCHMFile(); + + /*! + * \brief Attempts to load a .chm file. + * \param archiveName The .chm filename. + * \return true on success, false on failure. + * + * Loads a CHM file. Could internally load more than one file, if files linked to + * this one are present locally (like MSDN). + * \ingroup init + */ + bool loadFile( const QString& archiveName ); + + /*! + * \brief Closes all the files, and frees the appropriate data. + * \ingroup init + */ + void closeAll(); + + /*! + * \brief Gets the title name of the opened .chm. + * \return The name of the opened document, or an empty string if no .chm has been loaded. + * \ingroup information + */ + QString title() const; + + /*! + * \brief Gets the URL of the default page in the chm archive. + * \return The home page name, with a '/' added in front and relative to + * the root of the archive filesystem. If no .chm has been opened, + * returns "/". + * \ingroup information + */ + QString homeUrl() const; + + /*! + * \brief Checks whether the Table of Contents is present in this file. + * \return true if it is available; false otherwise. + * \ingroup information + */ + bool hasTableOfContents() const; + + /*! + * \brief Checks whether the Index Table is present in this file. + * \return true if it is available; false otherwise. + * \ingroup information + */ + bool hasIndexTable() const; + + /*! + * \brief Checks whether the Search Table is available in this file. + * \return true if it is available; false otherwise. + * \ingroup information + * + * If the search table is not available, the search is not possible. + */ + bool hasSearchTable() const; + + /*! + * \brief Parses the Table of Contents (TOC) + * \param topics A pointer to the container which will store the parsed results. + * Will be cleaned before parsing. + * \return true if the tree is present and parsed successfully, false otherwise. + * The parser is built to be error-prone, however it still can abort with qFatal() + * by really buggy chm file; please report a bug if the file is opened ok under Windows. + * \ingroup fileparsing + */ + bool parseTableOfContents( QT34VECTOR< LCHMParsedEntry > * topics ) const; + + /*! + * \brief Parses the Index Table + * \param indexes A pointer to the container which will store the parsed results. + * Will be cleaned before parsing. + * \return true if the tree is present and parsed successfully, false otherwise. + * The parser is built to be error-prone, however it still can abort with qFatal() + * by really buggy chm file; so far it never happened on indexes. + * \ingroup fileparsing + */ + bool parseIndex( QT34VECTOR< LCHMParsedEntry > * indexes ) const; + + /*! + * \brief Retrieves the content from url in current chm file to QString. + * \param str A string where the retreived content should be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content is successfully received; false otherwise. + * + * This function retreives the file content (mostly for HTML pages) from the chm archive + * opened by load() function. Because the content in chm file is not stored in Unicode, it + * will be recoded according to current encoding. Do not use for binary data. + * + * \sa setCurrentEncoding() currentEncoding() getFileContentAsBinary() + * \ingroup dataretrieve + */ + bool getFileContentAsString( QString * str, const QString& url ); + + /*! + * \brief Retrieves the content from url in current chm file to QByteArray. + * \param data A data array where the retreived content should be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content is successfully received; false otherwise. + * + * This function retreives the file content from the chm archive opened by load() + * function. The content is not encoded. + * + * \sa getFileContentAsString() + * \ingroup dataretrieve + */ + bool getFileContentAsBinary( QByteArray * data, const QString& url ); + + /*! + * \brief Retrieves the content size. + * \param size A pointer where the size will be stored. + * \param url An URL in chm file to retreive content from. Must be absolute. + * \return true if the content size is successfully stored; false otherwise. + * + * \ingroup dataretrieve + */ + bool getFileSize( unsigned int * size, const QString& url ); + + /*! + * \brief Obtains the list of all the files in current chm file archive. + * \param files An array to store list of URLs (file names) present in chm archive. + * \return true if the enumeration succeed; false otherwise (I could hardly imagine a reason). + * + * \ingroup dataretrieve + */ + bool enumerateFiles( QStringList * files ); + + /*! + * \brief Gets the Title of the HTML page referenced by url. + * \param url An URL in chm file to get title from. Must be absolute. + * \return The title, or QString::null if the URL cannot be found or not a HTML page. + * + * \ingroup dataretrieve + */ + QString getTopicByUrl ( const QString& url ); + + /*! + * \brief Gets the appropriate CHM pixmap icon. + * \param imagenum The image number from TOC. + * \return The pixmap to show in TOC tree. + * + * \ingroup dataretrieve + */ + const QPixmap * getBookIconPixmap( unsigned int imagenum ); + + /*! + * \brief Normalizes the URL, converting relatives, adding "/" in front and removing .. + * \param url The URL to normalize. + * \return The normalized, cleaned up URL. + * + * \ingroup dataretrieve + */ + QString normalizeUrl( const QString& url ) const; + + /*! + * \brief Gets the current CHM archive encoding (set or autodetected) + * \return The current encoding. + * + * \ingroup encoding + */ + const LCHMTextEncoding * currentEncoding() const; + + /*! + * \brief Sets the CHM archive encoding to use + * \param encoding An encoding to use. + * + * \ingroup encoding + */ + bool setCurrentEncoding ( const LCHMTextEncoding * encoding ); + + /*! + * \brief Execute a search query, return the results. + * \param query A search query. + * \param results An array to store URLs where the query was found. + * \return true if search was successful (this does not mean that it returned any results); + * false otherwise. + * + * This function executes a standard search query. The query should consist of one of more + * words separated by a space with a possible prefix. A prefix may be: + * + Plus indicates that the word is required; any page without this word is excluded from the result. + * - Minus indicates that the word is required to be absent; any page with this word is excluded from + * the result. + * "." Quotes indicates a phrase. Anything between quotes is a phrase, which is set of space-separated + * words. Will be in result only if the words in phrase are in page in the same sequence, and + * follow each other. + * + * If there is no prefix, the word considered as required. + * \ingroup search + */ + bool searchQuery ( const QString& query, QStringList * results, unsigned int limit = 100 ); + + //! Access to implementation + LCHMFileImpl * impl() { return m_impl; } + + private: + //! No copy construction allowed. + LCHMFile( const LCHMFile& ); + + //! No assignments allowed. + LCHMFile& operator=( const LCHMFile& ); + + //! Implementation + LCHMFileImpl * m_impl; +}; + + +#endif // INCLUDE_LIBCHMFILE_H diff --git a/lib/libchmfile/libchmfile_search.cpp b/lib/libchmfile/libchmfile_search.cpp new file mode 100644 index 0000000..41acfb3 --- /dev/null +++ b/lib/libchmfile/libchmfile_search.cpp @@ -0,0 +1,289 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <qregexp.h> + +#include "libchmfile.h" +#include "libchmfileimpl.h" + +//#define DEBUG_SEARCH(A) qDebug A +#define DEBUG_SEARCH(A) + + +static inline void validateWord ( QString & word, bool & query_valid ) +{ + QRegExp rxvalid ("[^\\d\\w_\\.]+"); + + QString orig = word; + word.remove ( rxvalid ); + + if ( word != orig ) + query_valid = false; +} + +static inline void validateWords ( QStringList & wordlist, bool & query_valid ) +{ + QRegExp rxvalid ("[^\\d\\w_\\.]+"); + + for ( unsigned int i = 0; i < wordlist.size(); i++ ) + validateWord ( wordlist[i], query_valid ); +} + + +inline static void mergeResults ( LCHMSearchProgressResults & results, const LCHMSearchProgressResults & src, bool add ) +{ + if ( results.empty() && add ) + { + results = src; + return; + } + + for ( unsigned int s1 = 0; s1 < results.size(); s1++ ) + { + bool found = false; + + for ( unsigned int s2 = 0; s2 < src.size(); s2++ ) + { + if ( results[s1].urloff == src[s2].urloff ) + { + found = true; + break; + } + } + + // If we're adding, we only add the items found (i.e. any item, which is not found, is removed. + // But if we're removing, we only remove the items found. + if ( (found && !add) || (!found && add) ) + { + results.erase ( results.begin() + s1 ); + s1--; + } + } +} + + +static inline void findNextWords ( QT34VECTOR<u_int64_t> & src, const QT34VECTOR<u_int64_t> & needle ) +{ + for ( unsigned int s1 = 0; s1 < src.size(); s1++ ) + { + bool found = false; + u_int64_t target_offset = src[s1] + 1; + + DEBUG_SEARCH (("Offset loop: offset at %u is %u, target %u", (unsigned int) s1, + (unsigned int) src[s1], (unsigned int) target_offset)); + + // Search in the offsets list in attempt to find next word + for ( unsigned int s2 = 0; s2 < needle.size(); s2++ ) + { + if ( needle[s2] == target_offset ) + { + found = true; + break; + } + } + + if ( !found ) + { + // Remove this offset, we don't need it anymore + DEBUG_SEARCH (("Offset loop failed: offset %u not found", (unsigned int) target_offset)); + src.erase ( src.begin() + s1 ); + s1--; + } + else + { + DEBUG_SEARCH (("Offset loop succeed: offset %u found", (unsigned int) target_offset)); + src[s1]++; + } + } +} + + +inline bool searchPhrase( LCHMFileImpl * impl, const QStringList & phrase, LCHMSearchProgressResults & results ) +{ + // Accumulate the phrase data here. + LCHMSearchProgressResults phrasekeeper; + + // On the first word, just fill the phrasekeeper with every occupence of the first word + DEBUG_SEARCH (("Search word(0): '%s'", phrase[0].ascii())); + if ( !impl->searchWord ( phrase[0], true, false, phrasekeeper, true ) ) + return false; // the word not found, so the whole phrase is not found either. + + for ( unsigned int i = 1; i < phrase.size(); i++ ) + { + LCHMSearchProgressResults srchtmp; + + DEBUG_SEARCH (("Search word(%d): '%s'", i, phrase[i].ascii())); + if ( !impl->searchWord ( phrase[i], true, false, srchtmp, true ) ) + return false; // the ith word not found, so the whole phrase is not found either. + + // Iterate the both arrays, and remove every word in phrasekeeper, which is not found + // in the srchtmp, or is found on a different position. + for ( unsigned int p1 = 0; p1 < phrasekeeper.size(); p1++ ) + { + bool found = false; + + DEBUG_SEARCH (("Ext loop (it %d): urloff %d", p1, phrasekeeper[p1].urloff)); + + for ( unsigned int p2 = 0; p2 < srchtmp.size(); p2++ ) + { + // look up for words on the the same page + if ( srchtmp[p2].urloff != phrasekeeper[p1].urloff ) + continue; + + // Now check every offset to find the one which is 1 bigger than the + findNextWords ( phrasekeeper[p1].offsets, srchtmp[p2].offsets ); + + // If at least one next word is found, we leave the block intact, otherwise remove it. + if ( !phrasekeeper[p1].offsets.empty() ) + found = true; + } + + if ( !found ) + { + DEBUG_SEARCH (("Ext loop: this word not found on %d, remove it", phrasekeeper[p1].urloff)); + phrasekeeper.erase ( phrasekeeper.begin() + p1 ); + p1--; + } + } + } + + for ( unsigned int o = 0; o < phrasekeeper.size(); o++ ) + results.push_back ( LCHMSearchProgressResult (phrasekeeper[o].titleoff, phrasekeeper[o].urloff) ); + + return !results.empty(); +} + + + +bool LCHMFile::searchQuery( const QString& inquery, QStringList * searchresults, unsigned int limit ) +{ + QStringList words_must_exist, words_must_not_exist, words_highlight; + QT34VECTOR<QStringList> phrases_must_exist; + QString query = inquery; + bool query_valid = true; + LCHMSearchProgressResults results; + int pos; + unsigned int i; + + /* + * Parse the search query with a simple state machine. + * Query should consist of one of more words separated by a space with a possible prefix. + * A prefix may be: + * + indicates that the word is required; any page without this word is excluded from the result. + * - indicates that the word is required to be absent; any page with this word is excluded from + * the result. + * "." indicates a phrase. Anything between quotes indicates a phrase, which is set of space-separated + * words. Will be in result only if the words in phrase are in page in the same sequence, and + * follow each other. + * If there is no prefix, the word considered as required. + */ + + QRegExp rxphrase( "\"(.*)\"" ); + QRegExp rxword( "([^\\s]+)" ); + rxphrase.setMinimal( TRUE ); + + // First, get the phrase queries + while ( (pos = rxphrase.search (query, 0)) != -1 ) + { + // A phrase query found. Locate its boundaries, and parse it. + QStringList plist = QStringList::split ( QRegExp ("\\s+"), rxphrase.cap ( 1 )); + + validateWords ( plist, query_valid ); + + if ( plist.size() > 0 ) + phrases_must_exist.push_back( plist ); + + query.remove (pos, rxphrase.matchedLength()); + } + + // Then, parse the rest query + while ( (pos = rxword.search (query, 0)) != -1 ) + { + // A phrase query found. Locate its boundaries, and parse it. + QString word = rxword.cap ( 1 ); + QChar type = '+'; + + if ( word[0] == '-' || word[0] == '+' ) + { + type = word[0]; + word.remove (0, 1); + } + + validateWord ( word, query_valid ); + + if ( type == '-' ) + words_must_not_exist.push_back ( word ); + else + words_must_exist.push_back ( word ); + + query.remove (pos, rxword.matchedLength()); + } + +#if defined (DUMP_SEARCH_QUERY) + // Dump the search query + QString qdump; + for ( i = 0; i < phrases_must_exist.size(); i++ ) + qdump += QString(" \"") + phrases_must_exist[i].join (" ") + QString ("\""); + + for ( i = 0; i < words_must_not_exist.size(); i++ ) + qdump += QString (" -") + words_must_not_exist[i]; + + for ( i = 0; i < words_must_exist.size(); i++ ) + qdump += QString (" +") + words_must_exist[i]; + + qDebug ("Search query dump: %s", qdump.ascii()); +#endif + + // First search for phrases + if ( phrases_must_exist.size() > 0 ) + { + LCHMSearchProgressResults tempres; + + for ( i = 0; i < phrases_must_exist.size(); i++ ) + { + if ( !searchPhrase ( impl(), phrases_must_exist[i], tempres ) ) + return false; + + mergeResults ( results, tempres, true ); + } + } + + for ( i = 0; i < words_must_exist.size(); i++ ) + { + LCHMSearchProgressResults tempres; + + if ( !m_impl->searchWord ( words_must_exist[i], true, false, tempres, false ) ) + return false; + + mergeResults ( results, tempres, true ); + } + + for ( i = 0; i < words_must_not_exist.size(); i++ ) + { + LCHMSearchProgressResults tempres; + + m_impl->searchWord ( words_must_not_exist[i], true, false, tempres, false ); + mergeResults ( results, tempres, false ); + } + + m_impl->getSearchResults( results, searchresults, limit ); + return true; +} diff --git a/lib/libchmfile/libchmfileimpl.cpp b/lib/libchmfile/libchmfileimpl.cpp new file mode 100644 index 0000000..6f1e052 --- /dev/null +++ b/lib/libchmfile/libchmfileimpl.cpp @@ -0,0 +1,1271 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Portions Copyright (C) 2003 Razvan Cojocaru <razvanco@gmx.net> * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <sys/types.h> + +#include <qcursor.h> +#include <qfile.h> +#include <qapplication.h> + +#include "config.h" +#include "chm_lib.h" +#include "bitfiddle.h" +#include "libchmfile.h" +#include "libchmurlfactory.h" +#include "libchmfileimpl.h" + +// Big-enough buffer size for use with various routines. +#define BUF_SIZE 4096 +#define COMMON_BUF_LEN 1025 + +#define TOPICS_ENTRY_LEN 16 +#define URLTBL_ENTRY_LEN 12 + +//#define DEBUGPARSER(A) qDebug A +#define DEBUGPARSER(A) ; + +class KCHMShowWaitCursor +{ + public: + KCHMShowWaitCursor () { QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); } + ~KCHMShowWaitCursor () { QApplication::restoreOverrideCursor(); } +}; + + +LCHMFileImpl::LCHMFileImpl( ) +{ + m_chmFile = NULL; + m_home = m_filename = m_home = m_topicsFile = m_indexFile = m_font = QString::null; + m_entityDecodeMap.clear(); + m_textCodec = 0; + m_textCodecForSpecialFiles = 0; + m_detectedLCID = 0; + m_currentEncoding = 0; +} + + +LCHMFileImpl::~ LCHMFileImpl( ) +{ + closeAll(); +} + + +bool LCHMFileImpl::loadFile( const QString & archiveName ) +{ + QString filename; + + // If the file has a file:// prefix, remove it + if ( archiveName.startsWith( "file://" ) ) + filename = archiveName.mid( 7 ); // strip it + else + filename = archiveName; + + if( m_chmFile ) + closeAll(); + + m_chmFile = chm_open( QFile::encodeName(filename) ); + + if ( m_chmFile == NULL ) + return false; + + m_filename = filename; + + // Reset encoding + m_textCodec = 0; + m_textCodecForSpecialFiles = 0; + m_currentEncoding = 0; + + // Get information from /#WINDOWS and /#SYSTEM files (encoding, title, context file and so) + // and guess the encoding + getInfoFromWindows(); + getInfoFromSystem(); + guessTextEncoding(); + + // Check whether the search tables are present + if ( ResolveObject("/#TOPICS", &m_chmTOPICS) + && ResolveObject("/#STRINGS", &m_chmSTRINGS) + && ResolveObject("/#URLTBL", &m_chmURLTBL) + && ResolveObject("/#URLSTR", &m_chmURLSTR) ) + { + m_lookupTablesValid = true; + fillTopicsUrlMap(); + } + else + m_lookupTablesValid = false; + + if ( m_lookupTablesValid && ResolveObject ("/$FIftiMain", &m_chmFIftiMain) ) + m_searchAvailable = true; + else + m_searchAvailable = false; + + return true; +} + + +void LCHMFileImpl::closeAll( ) +{ + if ( m_chmFile == NULL ) + return; + + chm_close( m_chmFile ); + + m_chmFile = NULL; + m_home = m_filename = m_home = m_topicsFile = m_indexFile = m_font = QString::null; + m_entityDecodeMap.clear(); + m_textCodec = 0; + m_textCodecForSpecialFiles = 0; + m_detectedLCID = 0; + m_currentEncoding = 0; +} + + +QString LCHMFileImpl::decodeEntity( const QString & entity ) +{ + // Set up m_entityDecodeMap characters according to current textCodec + if ( m_entityDecodeMap.isEmpty() ) + { + m_entityDecodeMap["AElig"] = encodeWithCurrentCodec ("\306"); // capital AE diphthong (ligature) + m_entityDecodeMap["Aacute"] = encodeWithCurrentCodec ("\301"); // capital A, acute accent + m_entityDecodeMap["Acirc"] = encodeWithCurrentCodec ("\302"); // capital A, circumflex accent + m_entityDecodeMap["Agrave"] = encodeWithCurrentCodec ("\300"); // capital A, grave accent + m_entityDecodeMap["Aring"] = encodeWithCurrentCodec ("\305"); // capital A, ring + m_entityDecodeMap["Atilde"] = encodeWithCurrentCodec ("\303"); // capital A, tilde + m_entityDecodeMap["Auml"] = encodeWithCurrentCodec ("\304"); // capital A, dieresis or umlaut mark + m_entityDecodeMap["Ccedil"] = encodeWithCurrentCodec ("\307"); // capital C, cedilla + m_entityDecodeMap["Dstrok"] = encodeWithCurrentCodec ("\320"); // whatever + m_entityDecodeMap["ETH"] = encodeWithCurrentCodec ("\320"); // capital Eth, Icelandic + m_entityDecodeMap["Eacute"] = encodeWithCurrentCodec ("\311"); // capital E, acute accent + m_entityDecodeMap["Ecirc"] = encodeWithCurrentCodec ("\312"); // capital E, circumflex accent + m_entityDecodeMap["Egrave"] = encodeWithCurrentCodec ("\310"); // capital E, grave accent + m_entityDecodeMap["Euml"] = encodeWithCurrentCodec ("\313"); // capital E, dieresis or umlaut mark + m_entityDecodeMap["Iacute"] = encodeWithCurrentCodec ("\315"); // capital I, acute accent + m_entityDecodeMap["Icirc"] = encodeWithCurrentCodec ("\316"); // capital I, circumflex accent + m_entityDecodeMap["Igrave"] = encodeWithCurrentCodec ("\314"); // capital I, grave accent + m_entityDecodeMap["Iuml"] = encodeWithCurrentCodec ("\317"); // capital I, dieresis or umlaut mark + m_entityDecodeMap["Ntilde"] = encodeWithCurrentCodec ("\321"); // capital N, tilde + m_entityDecodeMap["Oacute"] = encodeWithCurrentCodec ("\323"); // capital O, acute accent + m_entityDecodeMap["Ocirc"] = encodeWithCurrentCodec ("\324"); // capital O, circumflex accent + m_entityDecodeMap["Ograve"] = encodeWithCurrentCodec ("\322"); // capital O, grave accent + m_entityDecodeMap["Oslash"] = encodeWithCurrentCodec ("\330"); // capital O, slash + m_entityDecodeMap["Otilde"] = encodeWithCurrentCodec ("\325"); // capital O, tilde + m_entityDecodeMap["Ouml"] = encodeWithCurrentCodec ("\326"); // capital O, dieresis or umlaut mark + m_entityDecodeMap["THORN"] = encodeWithCurrentCodec ("\336"); // capital THORN, Icelandic + m_entityDecodeMap["Uacute"] = encodeWithCurrentCodec ("\332"); // capital U, acute accent + m_entityDecodeMap["Ucirc"] = encodeWithCurrentCodec ("\333"); // capital U, circumflex accent + m_entityDecodeMap["Ugrave"] = encodeWithCurrentCodec ("\331"); // capital U, grave accent + m_entityDecodeMap["Uuml"] = encodeWithCurrentCodec ("\334"); // capital U, dieresis or umlaut mark + m_entityDecodeMap["Yacute"] = encodeWithCurrentCodec ("\335"); // capital Y, acute accent + m_entityDecodeMap["OElig"] = encodeWithCurrentCodec ("\338"); // capital Y, acute accent + m_entityDecodeMap["oelig"] = encodeWithCurrentCodec ("\339"); // capital Y, acute accent + + m_entityDecodeMap["aacute"] = encodeWithCurrentCodec ("\341"); // small a, acute accent + m_entityDecodeMap["acirc"] = encodeWithCurrentCodec ("\342"); // small a, circumflex accent + m_entityDecodeMap["aelig"] = encodeWithCurrentCodec ("\346"); // small ae diphthong (ligature) + m_entityDecodeMap["agrave"] = encodeWithCurrentCodec ("\340"); // small a, grave accent + m_entityDecodeMap["aring"] = encodeWithCurrentCodec ("\345"); // small a, ring + m_entityDecodeMap["atilde"] = encodeWithCurrentCodec ("\343"); // small a, tilde + m_entityDecodeMap["auml"] = encodeWithCurrentCodec ("\344"); // small a, dieresis or umlaut mark + m_entityDecodeMap["ccedil"] = encodeWithCurrentCodec ("\347"); // small c, cedilla + m_entityDecodeMap["eacute"] = encodeWithCurrentCodec ("\351"); // small e, acute accent + m_entityDecodeMap["ecirc"] = encodeWithCurrentCodec ("\352"); // small e, circumflex accent + m_entityDecodeMap["Scaron"] = encodeWithCurrentCodec ("\352"); // small e, circumflex accent + m_entityDecodeMap["egrave"] = encodeWithCurrentCodec ("\350"); // small e, grave accent + m_entityDecodeMap["eth"] = encodeWithCurrentCodec ("\360"); // small eth, Icelandic + m_entityDecodeMap["euml"] = encodeWithCurrentCodec ("\353"); // small e, dieresis or umlaut mark + m_entityDecodeMap["iacute"] = encodeWithCurrentCodec ("\355"); // small i, acute accent + m_entityDecodeMap["icirc"] = encodeWithCurrentCodec ("\356"); // small i, circumflex accent + m_entityDecodeMap["igrave"] = encodeWithCurrentCodec ("\354"); // small i, grave accent + m_entityDecodeMap["iuml"] = encodeWithCurrentCodec ("\357"); // small i, dieresis or umlaut mark + m_entityDecodeMap["ntilde"] = encodeWithCurrentCodec ("\361"); // small n, tilde + m_entityDecodeMap["oacute"] = encodeWithCurrentCodec ("\363"); // small o, acute accent + m_entityDecodeMap["ocirc"] = encodeWithCurrentCodec ("\364"); // small o, circumflex accent + m_entityDecodeMap["ograve"] = encodeWithCurrentCodec ("\362"); // small o, grave accent + m_entityDecodeMap["oslash"] = encodeWithCurrentCodec ("\370"); // small o, slash + m_entityDecodeMap["otilde"] = encodeWithCurrentCodec ("\365"); // small o, tilde + m_entityDecodeMap["ouml"] = encodeWithCurrentCodec ("\366"); // small o, dieresis or umlaut mark + m_entityDecodeMap["szlig"] = encodeWithCurrentCodec ("\337"); // small sharp s, German (sz ligature) + m_entityDecodeMap["thorn"] = encodeWithCurrentCodec ("\376"); // small thorn, Icelandic + m_entityDecodeMap["uacute"] = encodeWithCurrentCodec ("\372"); // small u, acute accent + m_entityDecodeMap["ucirc"] = encodeWithCurrentCodec ("\373"); // small u, circumflex accent + m_entityDecodeMap["ugrave"] = encodeWithCurrentCodec ("\371"); // small u, grave accent + m_entityDecodeMap["uuml"] = encodeWithCurrentCodec ("\374"); // small u, dieresis or umlaut mark + m_entityDecodeMap["yacute"] = encodeWithCurrentCodec ("\375"); // small y, acute accent + m_entityDecodeMap["yuml"] = encodeWithCurrentCodec ("\377"); // small y, dieresis or umlaut mark + + m_entityDecodeMap["iexcl"] = encodeWithCurrentCodec ("\241"); + m_entityDecodeMap["cent"] = encodeWithCurrentCodec ("\242"); + m_entityDecodeMap["pound"] = encodeWithCurrentCodec ("\243"); + m_entityDecodeMap["curren"] = encodeWithCurrentCodec ("\244"); + m_entityDecodeMap["yen"] = encodeWithCurrentCodec ("\245"); + m_entityDecodeMap["brvbar"] = encodeWithCurrentCodec ("\246"); + m_entityDecodeMap["sect"] = encodeWithCurrentCodec ("\247"); + m_entityDecodeMap["uml"] = encodeWithCurrentCodec ("\250"); + m_entityDecodeMap["ordf"] = encodeWithCurrentCodec ("\252"); + m_entityDecodeMap["laquo"] = encodeWithCurrentCodec ("\253"); + m_entityDecodeMap["not"] = encodeWithCurrentCodec ("\254"); + m_entityDecodeMap["shy"] = encodeWithCurrentCodec ("\255"); + m_entityDecodeMap["macr"] = encodeWithCurrentCodec ("\257"); + m_entityDecodeMap["deg"] = encodeWithCurrentCodec ("\260"); + m_entityDecodeMap["plusmn"] = encodeWithCurrentCodec ("\261"); + m_entityDecodeMap["sup1"] = encodeWithCurrentCodec ("\271"); + m_entityDecodeMap["sup2"] = encodeWithCurrentCodec ("\262"); + m_entityDecodeMap["sup3"] = encodeWithCurrentCodec ("\263"); + m_entityDecodeMap["acute"] = encodeWithCurrentCodec ("\264"); + m_entityDecodeMap["micro"] = encodeWithCurrentCodec ("\265"); + m_entityDecodeMap["para"] = encodeWithCurrentCodec ("\266"); + m_entityDecodeMap["middot"] = encodeWithCurrentCodec ("\267"); + m_entityDecodeMap["cedil"] = encodeWithCurrentCodec ("\270"); + m_entityDecodeMap["ordm"] = encodeWithCurrentCodec ("\272"); + m_entityDecodeMap["raquo"] = encodeWithCurrentCodec ("\273"); + m_entityDecodeMap["frac14"] = encodeWithCurrentCodec ("\274"); + m_entityDecodeMap["frac12"] = encodeWithCurrentCodec ("\275"); + m_entityDecodeMap["frac34"] = encodeWithCurrentCodec ("\276"); + m_entityDecodeMap["iquest"] = encodeWithCurrentCodec ("\277"); + m_entityDecodeMap["times"] = encodeWithCurrentCodec ("\327"); + m_entityDecodeMap["divide"] = encodeWithCurrentCodec ("\367"); + + m_entityDecodeMap["copy"] = encodeWithCurrentCodec ("\251"); // copyright sign + m_entityDecodeMap["reg"] = encodeWithCurrentCodec ("\256"); // registered sign + m_entityDecodeMap["nbsp"] = encodeWithCurrentCodec ("\240"); // non breaking space + + m_entityDecodeMap["fnof"] = QChar((unsigned short) 402); + + m_entityDecodeMap["Delta"] = QChar((unsigned short) 916); + m_entityDecodeMap["Pi"] = QChar((unsigned short) 928); + m_entityDecodeMap["Sigma"] = QChar((unsigned short) 931); + + m_entityDecodeMap["beta"] = QChar((unsigned short) 946); + m_entityDecodeMap["gamma"] = QChar((unsigned short) 947); + m_entityDecodeMap["delta"] = QChar((unsigned short) 948); + m_entityDecodeMap["eta"] = QChar((unsigned short) 951); + m_entityDecodeMap["theta"] = QChar((unsigned short) 952); + m_entityDecodeMap["lambda"] = QChar((unsigned short) 955); + m_entityDecodeMap["mu"] = QChar((unsigned short) 956); + m_entityDecodeMap["nu"] = QChar((unsigned short) 957); + m_entityDecodeMap["pi"] = QChar((unsigned short) 960); + m_entityDecodeMap["rho"] = QChar((unsigned short) 961); + + m_entityDecodeMap["lsquo"] = QChar((unsigned short) 8216); + m_entityDecodeMap["rsquo"] = QChar((unsigned short) 8217); + m_entityDecodeMap["rdquo"] = QChar((unsigned short) 8221); + m_entityDecodeMap["bdquo"] = QChar((unsigned short) 8222); + m_entityDecodeMap["trade"] = QChar((unsigned short) 8482); + m_entityDecodeMap["ldquo"] = QChar((unsigned short) 8220); + m_entityDecodeMap["ndash"] = QChar((unsigned short) 8211); + m_entityDecodeMap["mdash"] = QChar((unsigned short) 8212); + m_entityDecodeMap["bull"] = QChar((unsigned short) 8226); + m_entityDecodeMap["hellip"] = QChar((unsigned short) 8230); + m_entityDecodeMap["emsp"] = QChar((unsigned short) 8195); + m_entityDecodeMap["rarr"] = QChar((unsigned short) 8594); + m_entityDecodeMap["rArr"] = QChar((unsigned short) 8658); + m_entityDecodeMap["crarr"] = QChar((unsigned short) 8629); + m_entityDecodeMap["le"] = QChar((unsigned short) 8804); + m_entityDecodeMap["ge"] = QChar((unsigned short) 8805); + m_entityDecodeMap["lte"] = QChar((unsigned short) 8804); // wrong, but used somewhere + m_entityDecodeMap["gte"] = QChar((unsigned short) 8805); // wrong, but used somewhere + m_entityDecodeMap["dagger"] = QChar((unsigned short) 8224); + m_entityDecodeMap["Dagger"] = QChar((unsigned short) 8225); + m_entityDecodeMap["euro"] = QChar((unsigned short) 8364); + m_entityDecodeMap["asymp"] = QChar((unsigned short) 8776); + m_entityDecodeMap["isin"] = QChar((unsigned short) 8712); + m_entityDecodeMap["notin"] = QChar((unsigned short) 8713); + m_entityDecodeMap["prod"] = QChar((unsigned short) 8719); + m_entityDecodeMap["ne"] = QChar((unsigned short) 8800); + + m_entityDecodeMap["amp"] = "&"; // ampersand + m_entityDecodeMap["gt"] = ">"; // greater than + m_entityDecodeMap["lt"] = "<"; // less than + m_entityDecodeMap["quot"] = "\""; // double quote + m_entityDecodeMap["apos"] = "'"; // single quote + m_entityDecodeMap["frasl"] = "/"; + m_entityDecodeMap["minus"] = "-"; + m_entityDecodeMap["oplus"] = "+"; + m_entityDecodeMap["Prime"] = "\""; + } + + // If entity is an ASCII code like 〽 - just decode it + if ( entity[0] == '#' ) + { + bool valid; + unsigned int ascode = entity.mid(1).toUInt( &valid ); + + if ( !valid ) + { + qWarning ( "LCHMFileImpl::decodeEntity: could not decode HTML entity '%s'", entity.ascii() ); + return QString::null; + } + + return (QString) (QChar( ascode )); + } + else + { + QMap<QString, QString>::const_iterator it = m_entityDecodeMap.find( entity ); + + if ( it == m_entityDecodeMap.end() ) + { + qWarning ("LCHMFileImpl::decodeEntity: could not decode HTML entity '%s'", entity.ascii()); + return QString::null; + } + + return *it; + } +} + + +inline int LCHMFileImpl::findStringInQuotes (const QString& tag, int offset, QString& value, bool firstquote, bool decodeentities) +{ + int qbegin = tag.find ('"', offset); + + if ( qbegin == -1 ) + qFatal ("LCHMFileImpl::findStringInQuotes: cannot find first quote in <param> tag: '%s'", tag.ascii()); + + int qend = firstquote ? tag.find ('"', qbegin + 1) : tag.findRev ('"'); + + if ( qend == -1 || qend <= qbegin ) + qFatal ("LCHMFileImpl::findStringInQuotes: cannot find last quote in <param> tag: '%s'", tag.ascii()); + + // If we do not need to decode HTML entities, just return. + if ( decodeentities ) + { + QString htmlentity = QString::null; + bool fill_entity = false; + + value.reserve (qend - qbegin); // to avoid multiple memory allocations + + for ( int i = qbegin + 1; i < qend; i++ ) + { + if ( !fill_entity ) + { + if ( tag[i] == '&' ) // HTML entity starts + fill_entity = true; + else + value.append (tag[i]); + } + else + { + if ( tag[i] == ';' ) // HTML entity ends + { + // If entity is an ASCII code, just decode it + QString decode = decodeEntity( htmlentity ); + + if ( decode.isNull() ) + break; + + value.append ( decode ); + htmlentity = QString::null; + fill_entity = false; + } + else + htmlentity.append (tag[i]); + } + } + } + else + value = tag.mid (qbegin + 1, qend - qbegin - 1); + + return qend + 1; +} + + +bool LCHMFileImpl::searchWord (const QString& text, + bool wholeWords, + bool titlesOnly, + LCHMSearchProgressResults& results, + bool phrase_search) +{ + bool partial = false; + + if ( text.isEmpty() || !m_searchAvailable ) + return false; + + QString searchword = (QString) convertSearchWord (text); + +#define FTS_HEADER_LEN 0x32 + unsigned char header[FTS_HEADER_LEN]; + + if ( RetrieveObject (&m_chmFIftiMain, header, 0, FTS_HEADER_LEN) == 0 ) + return false; + + unsigned char doc_index_s = header[0x1E], doc_index_r = header[0x1F]; + unsigned char code_count_s = header[0x20], code_count_r = header[0x21]; + unsigned char loc_codes_s = header[0x22], loc_codes_r = header[0x23]; + + if(doc_index_s != 2 || code_count_s != 2 || loc_codes_s != 2) + { + // Don't know how to use values other than 2 yet. Maybe next chmspec. + return false; + } + + unsigned char* cursor32 = header + 0x14; + u_int32_t node_offset = UINT32ARRAY(cursor32); + + cursor32 = header + 0x2e; + u_int32_t node_len = UINT32ARRAY(cursor32); + + unsigned char* cursor16 = header + 0x18; + u_int16_t tree_depth = UINT16ARRAY(cursor16); + + unsigned char word_len, pos; + QString word; + u_int32_t i = sizeof(u_int16_t); + u_int16_t free_space; + + QMemArray<unsigned char> buffer(node_len); + + node_offset = GetLeafNodeOffset (searchword, node_offset, node_len, tree_depth); + + if ( !node_offset ) + return false; + + do + { + // got a leaf node here. + if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), node_offset, node_len) == 0 ) + return false; + + cursor16 = buffer.data() + 6; + free_space = UINT16ARRAY(cursor16); + + i = sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int16_t); + u_int64_t wlc_count, wlc_size; + u_int32_t wlc_offset; + + while (i < node_len - free_space) + { + word_len = *(buffer.data() + i); + pos = *(buffer.data() + i + 1); + + char *wrd_buf = new char[word_len]; + memcpy (wrd_buf, buffer.data() + i + 2, word_len - 1); + wrd_buf[word_len - 1] = 0; + + if ( pos == 0 ) + word = wrd_buf; + else + word = word.mid (0, pos) + wrd_buf; + + delete[] wrd_buf; + + i += 2 + word_len; + unsigned char title = *(buffer.data() + i - 1); + + size_t encsz; + wlc_count = be_encint (buffer.data() + i, encsz); + i += encsz; + + cursor32 = buffer.data() + i; + wlc_offset = UINT32ARRAY(cursor32); + + i += sizeof(u_int32_t) + sizeof(u_int16_t); + wlc_size = be_encint (buffer.data() + i, encsz); + i += encsz; + + cursor32 = buffer.data(); + node_offset = UINT32ARRAY(cursor32); + + if ( !title && titlesOnly ) + continue; + + if ( wholeWords && searchword == word ) + return ProcessWLC(wlc_count, wlc_size, + wlc_offset, doc_index_s, + doc_index_r,code_count_s, + code_count_r, loc_codes_s, + loc_codes_r, results, phrase_search); + + if ( !wholeWords ) + { + if ( word.startsWith (searchword)) + { + partial = true; + + ProcessWLC(wlc_count, wlc_size, + wlc_offset, doc_index_s, + doc_index_r,code_count_s, + code_count_r, loc_codes_s, + loc_codes_r, results, phrase_search); + + } + else if ( QString::compare (searchword, word.mid(0, searchword.length())) < -1 ) + break; + } + } + } + while ( !wholeWords && word.startsWith (searchword) && node_offset ); + + return partial; +} + + +bool LCHMFileImpl::ResolveObject(const QString& fileName, chmUnitInfo *ui) const +{ + return m_chmFile != NULL + && ::chm_resolve_object(m_chmFile, fileName.ascii(), ui) == + CHM_RESOLVE_SUCCESS; +} + + +size_t LCHMFileImpl::RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer, + LONGUINT64 fileOffset, LONGINT64 bufferSize) const +{ +#if USE_BUILTIN_CHMLIB + return ::chm_retrieve_object(m_chmFile, ui, buffer, + fileOffset, bufferSize); +#else + return ::chm_retrieve_object(m_chmFile, const_cast<chmUnitInfo*>(ui), + buffer, fileOffset, bufferSize); +#endif +} + + +inline u_int32_t LCHMFileImpl::GetLeafNodeOffset(const QString& text, + u_int32_t initialOffset, + u_int32_t buffSize, + u_int16_t treeDepth) +{ + u_int32_t test_offset = 0; + unsigned char* cursor16, *cursor32; + unsigned char word_len, pos; + u_int32_t i = sizeof(u_int16_t); + QMemArray<unsigned char> buffer(buffSize); + QString word; + + while(--treeDepth) + { + if ( initialOffset == test_offset ) + return 0; + + test_offset = initialOffset; + if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), initialOffset, buffSize) == 0 ) + return 0; + + cursor16 = buffer.data(); + u_int16_t free_space = UINT16ARRAY(cursor16); + + while (i < buffSize - free_space ) + { + word_len = *(buffer.data() + i); + pos = *(buffer.data() + i + 1); + + char *wrd_buf = new char[word_len]; + memcpy ( wrd_buf, buffer.data() + i + 2, word_len - 1 ); + wrd_buf[word_len - 1] = 0; + + if ( pos == 0 ) + word = wrd_buf; + else + word = word.mid(0, pos) + wrd_buf; + + delete[] wrd_buf; + + if ( text <= word ) + { + cursor32 = buffer.data() + i + word_len + 1; + initialOffset = UINT32ARRAY(cursor32); + break; + } + + i += word_len + sizeof(unsigned char) + + sizeof(u_int32_t) + sizeof(u_int16_t); + } + } + + if ( initialOffset == test_offset ) + return 0; + + return initialOffset; +} + + +inline bool LCHMFileImpl::ProcessWLC (u_int64_t wlc_count, u_int64_t wlc_size, + u_int32_t wlc_offset, unsigned char ds, + unsigned char dr, unsigned char cs, + unsigned char cr, unsigned char ls, + unsigned char lr, + LCHMSearchProgressResults& results, + bool phrase_search) +{ + int wlc_bit = 7; + u_int64_t index = 0, count; + size_t length, off = 0; + QMemArray<unsigned char> buffer (wlc_size); + unsigned char *cursor32; + + unsigned char entry[TOPICS_ENTRY_LEN]; + unsigned char combuf[13]; + + if ( RetrieveObject (&m_chmFIftiMain, buffer.data(), wlc_offset, wlc_size) == 0 ) + return false; + + for ( u_int64_t i = 0; i < wlc_count; ++i ) + { + if ( wlc_bit != 7 ) + { + ++off; + wlc_bit = 7; + } + + index += sr_int (buffer.data() + off, &wlc_bit, ds, dr, length); + off += length; + + if ( RetrieveObject (&m_chmTOPICS, entry, index * 16, TOPICS_ENTRY_LEN) == 0 ) + return false; + + LCHMSearchProgressResult progres; + + cursor32 = entry + 4; + progres.titleoff = UINT32ARRAY(cursor32); + + cursor32 = entry + 8; + progres.urloff = UINT32ARRAY(cursor32); + + if ( RetrieveObject (&m_chmURLTBL, combuf, progres.urloff, 12) == 0 ) + return false; + + cursor32 = combuf + 8; + progres.urloff = UINT32ARRAY (cursor32); + + count = sr_int (buffer.data() + off, &wlc_bit, cs, cr, length); + off += length; + + if ( phrase_search ) + progres.offsets.reserve (count); + + for (u_int64_t j = 0; j < count; ++j) + { + u_int64_t lcode = sr_int (buffer.data() + off, &wlc_bit, ls, lr, length); + off += length; + + if ( phrase_search ) + progres.offsets.push_back (lcode); + } + + results.push_back (progres); + } + + return true; +} + + +bool LCHMFileImpl::getInfoFromWindows() +{ +#define WIN_HEADER_LEN 0x08 + unsigned char buffer[BUF_SIZE]; + unsigned int factor; + chmUnitInfo ui; + long size = 0; + + if ( ResolveObject("/#WINDOWS", &ui) ) + { + if ( !RetrieveObject(&ui, buffer, 0, WIN_HEADER_LEN) ) + return false; + + u_int32_t entries = get_int32_le( (u_int32_t *)(buffer) ); + u_int32_t entry_size = get_int32_le( (u_int32_t *)(buffer + 0x04) ); + + QByteArray uptr(entries * entry_size); + unsigned char* raw = (unsigned char*) uptr.data(); + + if ( !RetrieveObject (&ui, raw, 8, entries * entry_size) ) + return false; + + if( !ResolveObject ("/#STRINGS", &ui) ) + return false; + + for ( u_int32_t i = 0; i < entries; ++i ) + { + u_int32_t offset = i * entry_size; + + u_int32_t off_title = get_int32_le( (u_int32_t *)(raw + offset + 0x14) ); + u_int32_t off_home = get_int32_le( (u_int32_t *)(raw + offset + 0x68) ); + u_int32_t off_hhc = get_int32_le( (u_int32_t *)(raw + offset + 0x60) ); + u_int32_t off_hhk = get_int32_le( (u_int32_t *)(raw + offset + 0x64) ); + + factor = off_title / 4096; + + if ( size == 0 ) + size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); + + if ( size && off_title ) + m_title = QString ((const char*) (buffer + off_title % 4096)); + + if ( factor != off_home / 4096) + { + factor = off_home / 4096; + size = RetrieveObject (&ui, buffer, factor * 4096, BUF_SIZE); + } + + if ( size && off_home ) + m_home = QString("/") + QString( (const char*) buffer + off_home % 4096); + + if ( factor != off_hhc / 4096) + { + factor = off_hhc / 4096; + size = RetrieveObject(&ui, buffer, factor * 4096, BUF_SIZE); + } + + if ( size && off_hhc ) + m_topicsFile = QString("/") + QString ((const char*) buffer + off_hhc % 4096); + + if ( factor != off_hhk / 4096) + { + factor = off_hhk / 4096; + size = RetrieveObject (&ui, buffer, factor * 4096, BUF_SIZE); + } + + if ( size && off_hhk ) + m_indexFile = QString("/") + QString((const char*) buffer + off_hhk % 4096); + } + } + return true; +} + + + +bool LCHMFileImpl::getInfoFromSystem() +{ + unsigned char buffer[BUF_SIZE]; + chmUnitInfo ui; + + int index = 0; + unsigned char* cursor = NULL, *p; + u_int16_t value = 0; + long size = 0; + + // Run the first loop to detect the encoding. We need this, because title could be + // already encoded in user encoding. Same for file names + if ( !ResolveObject ("/#SYSTEM", &ui) ) + return false; + + // Can we pull BUFF_SIZE bytes of the #SYSTEM file? + if ( (size = RetrieveObject (&ui, buffer, 4, BUF_SIZE)) == 0 ) + return false; + + buffer[size - 1] = 0; + + // First loop to detect the encoding + for ( index = 0; index < (size - 1 - (long)sizeof(u_int16_t)) ;) + { + cursor = buffer + index; + value = UINT16ARRAY(cursor); + + switch(value) + { + case 0: + index += 2; + cursor = buffer + index; + + if(m_topicsFile.isEmpty()) + m_topicsFile = QString("/") + QString((const char*) buffer + index + 2); + + break; + + case 1: + index += 2; + cursor = buffer + index; + + if(m_indexFile.isEmpty()) + m_indexFile = QString("/") + QString ((const char*)buffer + index + 2); + break; + + case 2: + index += 2; + cursor = buffer + index; + + if(m_home.isEmpty() || m_home == "/") + m_home = QString("/") + QString ((const char*) buffer + index + 2); + break; + + case 3: + index += 2; + cursor = buffer + index; + m_title = QString((const char*) (buffer + index + 2)); + break; + + case 4: + index += 2; + cursor = buffer + index; + + p = buffer + index + 2; + m_detectedLCID = (short) (p[0] | (p[1]<<8)); + + break; + + case 6: + index += 2; + cursor = buffer + index; + + if(m_topicsFile.isEmpty()) { + QString topicAttempt = "/", tmp; + topicAttempt += QString ((const char*) buffer +index +2); + + tmp = topicAttempt + ".hhc"; + + if ( ResolveObject( tmp, &ui) ) + m_topicsFile = tmp; + + tmp = topicAttempt + ".hhk"; + + if ( ResolveObject( tmp, &ui) ) + m_indexFile = tmp; + } + break; + + case 16: + index += 2; + cursor = buffer + index; + + m_font = QString ((const char*) buffer + index + 2); + break; + + default: + index += 2; + cursor = buffer + index; + } + + value = UINT16ARRAY(cursor); + index += value + 2; + } + + return true; +} + + +QCString LCHMFileImpl::convertSearchWord( const QString & src ) +{ + static const char * searchwordtable[128] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "s", 0, "oe", 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "s", 0, "oe", 0, 0, "y", + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", + "d", "n", "o", "o", "o", "o", "o", 0, "o", "u", "u", "u", "u", "y", "\xDE", "ss", + "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", + "o", "n", "o", "o", "o", "o", "o", 0, "o", "u", "u", "u", "u", "y", "\xFE", "y" + }; + + if ( !m_textCodec ) + return (QCString) src.lower(); + + QCString dest = m_textCodec->fromUnicode (src); + + for ( unsigned int i = 0; i < dest.size(); i++ ) + { + if ( dest[i] & 0x80 ) + { + int index = dest[i] & 0x7F; + if ( searchwordtable[index] ) + dest.replace (i, 1, searchwordtable[index]); + else + dest.remove (i, 1); + } + } + + return dest.lower(); +} + + + +void LCHMFileImpl::getSearchResults( const LCHMSearchProgressResults& tempres, + QStringList * results, + unsigned int limit_results ) +{ + unsigned char combuf [COMMON_BUF_LEN]; + QMap<u_int32_t, u_int32_t> urlsmap; // used to prevent duplicated urls + + for ( unsigned int i = 0; i < tempres.size(); i++ ) + { + if ( urlsmap.find (tempres[i].urloff) != urlsmap.end() ) + continue; + + urlsmap[tempres[i].urloff] = 1; + + if ( RetrieveObject (&m_chmURLSTR, combuf, tempres[i].urloff + 8, COMMON_BUF_LEN - 1) == 0 ) + continue; + + combuf[COMMON_BUF_LEN - 1] = 0; + results->push_back( LCHMUrlFactory::makeURLabsoluteIfNeeded( (const char*) combuf ) ); + + if ( --limit_results == 0 ) + break; + } +} + + +QString LCHMFileImpl::normalizeUrl( const QString & path ) const +{ + int pos = path.find ('#'); + QString fixedpath = pos == -1 ? path : path.left (pos); + + return LCHMUrlFactory::makeURLabsoluteIfNeeded( fixedpath ); +} + + +/* + * FIXME: <OBJECT type="text/sitemap"><param name="Merge" value="hhaxref.chm::/HHOCX_c.hhc"></OBJECT> + * (from htmlhelp.chm) +*/ +bool LCHMFileImpl::parseFileAndFillArray( const QString & file, QT34VECTOR< LCHMParsedEntry > * data, bool asIndex ) +{ + QString src; + const int MAX_NEST_DEPTH = 256; + + if ( !getFileContentAsString( &src, file ) || src.isEmpty() ) + return false; + + KCHMShowWaitCursor wc; + +/* + // Save the index for debugging purposes + QFile outfile( "parsed.htm" ); + + if ( outfile.open( IO_WriteOnly ) ) + { + QTextStream textstream( &outfile ); + textstream << src; + outfile.close(); + } +*/ + + unsigned int defaultimagenum = asIndex ? LCHMBookIcons::IMAGE_INDEX : LCHMBookIcons::IMAGE_AUTO; + int pos = 0, indent = 0, root_indent_offset = 0; + bool in_object = false, root_indent_offset_set = false; + + LCHMParsedEntry entry; + entry.imageid = defaultimagenum; + + // Split the HHC file by HTML tags + int stringlen = src.length(); + + while ( pos < stringlen && (pos = src.find ('<', pos)) != -1 ) + { + int i, word_end = 0; + + for ( i = ++pos; i < stringlen; i++ ) + { + // If a " or ' is found, skip to the next one. + if ( (src[i] == '"' || src[i] == '\'') ) + { + // find where quote ends, either by another quote, or by '>' symbol (some people don't know HTML) + int nextpos = src.find (src[i], i+1); + if ( nextpos == -1 && (nextpos = src.find ('>', i+1)) == -1 ) + { + qWarning ("LCHMFileImpl::ParseHhcAndFillTree: corrupted TOC: %s", src.mid(i).ascii()); + return false; + } + + i = nextpos; + } + else if ( src[i] == '>' ) + break; + else if ( !src[i].isLetterOrNumber() && src[i] != '/' && !word_end ) + word_end = i; + } + + QString tagword, tag = src.mid (pos, i - pos); + + if ( word_end ) + tagword = src.mid (pos, word_end - pos).lower(); + else + tagword = tag.lower(); + + //qDebug ("tag: '%s', tagword: '%s'\n", tag.ascii(), tagword.ascii()); + + // <OBJECT type="text/sitemap"> - a topic entry + if ( tagword == "object" && tag.find ("text/sitemap", 0, false) != -1 ) + in_object = true; + else if ( tagword == "/object" && in_object ) + { + // a topic entry closed. Add a tree item + if ( entry.name ) + { + if ( !root_indent_offset_set ) + { + root_indent_offset_set = true; + root_indent_offset = indent; + + if ( root_indent_offset > 1 ) + qWarning("CHM has improper index; root indent offset is %d", root_indent_offset); + } + + int real_indent = indent - root_indent_offset; + + entry.indent = real_indent; + data->push_back( entry ); + } + else + { + if ( !entry.urls.isEmpty() ) + qDebug ("LCHMFileImpl::ParseAndFillTopicsTree: <object> tag with url \"%s\" is parsed, but name is empty.", entry.urls[0].ascii()); + else + qDebug ("LCHMFileImpl::ParseAndFillTopicsTree: <object> tag is parsed, but both name and url are empty."); + } + + entry.name = QString::null; + entry.urls.clear(); + entry.imageid = defaultimagenum; + in_object = false; + } + else if ( tagword == "param" && in_object ) + { + // <param name="Name" value="First Page"> + int offset; // strlen("param ") + QString name_pattern = "name=", value_pattern = "value="; + QString pname, pvalue; + + if ( (offset = tag.find (name_pattern, 0, FALSE)) == -1 ) + qFatal ("LCHMFileImpl::ParseAndFillTopicsTree: bad <param> tag '%s': no name=\n", tag.ascii()); + + // offset+5 skips 'name=' + offset = findStringInQuotes (tag, offset + name_pattern.length(), pname, TRUE, FALSE); + pname = pname.lower(); + + if ( (offset = tag.find (value_pattern, offset, FALSE)) == -1 ) + qFatal ("LCHMFileImpl::ParseAndFillTopicsTree: bad <param> tag '%s': no value=\n", tag.ascii()); + + // offset+6 skips 'value=' + findStringInQuotes (tag, offset + value_pattern.length(), pvalue, FALSE, TRUE); + + //qDebug ("<param>: name '%s', value '%s'", pname.ascii(), pvalue.ascii()); + + if ( pname == "name" ) + { + // Some help files contain duplicate names, where the second name is empty. Work it around by keeping the first one + if ( !pvalue.isEmpty() ) + entry.name = pvalue; + } + else if ( pname == "local" ) + { + // Check for URL duplication + QString url = LCHMUrlFactory::makeURLabsoluteIfNeeded( pvalue ); + + if ( entry.urls.find( url ) == entry.urls.end() ) + entry.urls.push_back( url ); + } + else if ( pname == "see also" && asIndex && entry.name != pvalue ) + entry.urls.push_back (":" + pvalue); + else if ( pname == "imagenumber" ) + { + bool bok; + int imgnum = pvalue.toInt (&bok); + + if ( bok && imgnum >= 0 && imgnum < LCHMBookIcons::MAX_BUILTIN_ICONS ) + entry.imageid = imgnum; + } + } + else if ( tagword == "ul" ) // increase indent level + { + // Fix for buggy help files + if ( ++indent >= MAX_NEST_DEPTH ) + qFatal("LCHMFileImpl::ParseAndFillTopicsTree: max nest depth (%d) is reached, error in help file", MAX_NEST_DEPTH); + + // This intended to fix <ul><ul>, which was seen in some buggy chm files, + // and brokes rootentry[indent-1] check + } + else if ( tagword == "/ul" ) // decrease indent level + { + if ( --indent < root_indent_offset ) + indent = root_indent_offset; + + DEBUGPARSER(("</ul>: new intent is %d\n", indent - root_indent_offset)); + } + + pos = i; + } + + return true; +} + + +bool LCHMFileImpl::getFileContentAsBinary( QByteArray * data, const QString & url ) const +{ + chmUnitInfo ui; + + if( !ResolveObject( url, &ui ) ) + return false; + + data->resize( ui.length ); + + if ( RetrieveObject( &ui, (unsigned char*) data->data(), 0, ui.length ) ) + return true; + else + return false; +} + + +bool LCHMFileImpl::getFileContentAsString( QString * str, const QString & url, bool internal_encoding ) +{ + QByteArray buf; + + if ( getFileContentAsBinary( &buf, url ) ) + { + unsigned int length = buf.size(); + + if ( length > 0 ) + { + buf.resize( length + 1 ); + buf [length] = '\0'; + + *str = internal_encoding ? (QString)((const char*) buf) : encodeWithCurrentCodec((const char*) buf); + return true; + } + } + + return false; +} + + +QString LCHMFileImpl::getTopicByUrl( const QString & url ) const +{ + QMap< QString, QString >::const_iterator it = m_url2topics.find( url ); + + if ( it == m_url2topics.end() ) + return QString::null; + + return it.data(); +} + + +static int chm_enumerator_callback( struct chmFile*, struct chmUnitInfo *ui, void *context ) +{ + ((QStringList*) context)->push_back( ui->path ); + return CHM_ENUMERATOR_CONTINUE; +} + +bool LCHMFileImpl::enumerateFiles( QStringList * files ) +{ + files->clear(); + return chm_enumerate( m_chmFile, CHM_ENUMERATE_ALL, chm_enumerator_callback, files ); +} + +const QPixmap * LCHMFileImpl::getBookIconPixmap( unsigned int imagenum ) +{ + return m_imagesKeeper.getImage( imagenum ); +} + +bool LCHMFileImpl::setCurrentEncoding( const LCHMTextEncoding * encoding ) +{ + m_currentEncoding = encoding; + return changeFileEncoding( encoding->qtcodec ); +} + + +bool LCHMFileImpl::guessTextEncoding( ) +{ + const LCHMTextEncoding * enc = 0; + + if ( !m_detectedLCID || (enc = lookupByLCID (m_detectedLCID)) == 0 ) + qFatal ("Could not detect text encoding by LCID"); + + if ( changeFileEncoding (enc->qtcodec) ) + { + m_currentEncoding = enc; + return true; + } + + return false; +} + +bool LCHMFileImpl::changeFileEncoding( const char *qtencoding ) +{ + // Encoding could be either simple Qt codepage, or set like CP1251/KOI8, which allows to + // set up encodings separately for text (first) and internal files (second) + const char * p = strchr( qtencoding, '/' ); + if ( p ) + { + char buf[128]; // much bigger that any encoding possible. No DoS; all encodings are hardcoded. + strcpy( buf, qtencoding ); + buf[p - qtencoding] = '\0'; + + m_textCodec = QTextCodec::codecForName( buf ); + + if ( !m_textCodec ) + { + qWarning( "Could not set up Text Codec for encoding '%s'", buf ); + return false; + } + + m_textCodecForSpecialFiles = QTextCodec::codecForName( p + 1 ); + + if ( !m_textCodecForSpecialFiles ) + { + qWarning( "Could not set up Text Codec for encoding '%s'", p + 1 ); + return false; + } + } + else + { + m_textCodecForSpecialFiles = m_textCodec = QTextCodec::codecForName (qtencoding); + + if ( !m_textCodec ) + { + qWarning( "Could not set up Text Codec for encoding '%s'", qtencoding ); + return false; + } + } + + m_entityDecodeMap.clear(); + return true; +} + + +void LCHMFileImpl::fillTopicsUrlMap() +{ + if ( !m_lookupTablesValid ) + return; + + // Read those tables + QByteArray topics( m_chmTOPICS.length ), urltbl( m_chmURLTBL.length ), urlstr( m_chmURLSTR.length ), strings( m_chmSTRINGS.length ); + + if ( !RetrieveObject( &m_chmTOPICS, (unsigned char*) topics.data(), 0, m_chmTOPICS.length ) + || !RetrieveObject( &m_chmURLTBL, (unsigned char*) urltbl.data(), 0, m_chmURLTBL.length ) + || !RetrieveObject( &m_chmURLSTR, (unsigned char*) urlstr.data(), 0, m_chmURLSTR.length ) + || !RetrieveObject( &m_chmSTRINGS, (unsigned char*) strings.data(), 0, m_chmSTRINGS.length ) ) + return; + + for ( unsigned int i = 0; i < m_chmTOPICS.length; i += TOPICS_ENTRY_LEN ) + { + u_int32_t off_title = get_int32_le( (u_int32_t *)(topics.data() + i + 4) ); + u_int32_t off_url = get_int32_le( (u_int32_t *)(topics.data() + i + 8) ); + off_url = get_int32_le( (u_int32_t *)( urltbl.data() + off_url + 8) ) + 8; + + QString url = LCHMUrlFactory::makeURLabsoluteIfNeeded( (const char*) urlstr.data() + off_url ); + + if ( off_title < strings.size() ) + m_url2topics[url] = encodeWithCurrentCodec ( (const char*) strings.data() + off_title ); + else + m_url2topics[url] = "Untitled"; + } +} + + +bool LCHMFileImpl::getFileSize(unsigned int * size, const QString & url) +{ + chmUnitInfo ui; + + if( !ResolveObject( url, &ui ) ) + return false; + + *size = ui.length; + return true; +} diff --git a/lib/libchmfile/libchmfileimpl.h b/lib/libchmfile/libchmfileimpl.h new file mode 100644 index 0000000..b609b16 --- /dev/null +++ b/lib/libchmfile/libchmfileimpl.h @@ -0,0 +1,286 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Portions Copyright (C) 2003 Razvan Cojocaru <razvanco@gmx.net> * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "chm_lib.h" + +#include "libchmfile.h" +#include "libchmtocimage.h" + +#include <sys/types.h> /* for u_int{32,64}_t */ + +//! Keeps the intermediate search result +class LCHMSearchProgressResult +{ + public: + inline LCHMSearchProgressResult() {} + inline LCHMSearchProgressResult( u_int32_t t, u_int32_t u ) : titleoff(t),urloff(u) {} + + QValueVector<u_int64_t> offsets; + u_int32_t titleoff; + u_int32_t urloff; +}; + +//! An array to keeps the intermediate search results +typedef QT34VECTOR<LCHMSearchProgressResult> LCHMSearchProgressResults; + + +//! CHM files processor; the implementation +class LCHMFileImpl +{ + public: + LCHMFileImpl(); + ~LCHMFileImpl(); + + // Implementations for LCHMFile members + bool loadFile( const QString& archiveName ); + void closeAll(); + + QString title() const { return encodeWithCurrentCodec( m_title ); } + QString homeUrl() const { return encodeWithCurrentCodec( m_home ); } + + bool getFileContentAsString( QString * str, const QString& url, bool internal_encoding = false ); + bool getFileContentAsBinary( QByteArray * data, const QString& url ) const; + bool getFileSize( unsigned int * size, const QString& url ); + + bool enumerateFiles( QStringList * files ); + QString getTopicByUrl ( const QString& url ) const; + + const QPixmap * getBookIconPixmap( unsigned int imagenum ); + + bool setCurrentEncoding( const LCHMTextEncoding * encoding ); + + //! Parse the HHC or HHS file, and fill the context (asIndex is false) or index (asIndex is true) array. + bool parseFileAndFillArray (const QString& file, QT34VECTOR< LCHMParsedEntry > * data, bool asIndex ); + + /*! + * \brief Fast search using the $FIftiMain file in the .chm. + * \param text The text we're looking for. + * \param wholeWords Are we looking for whole words only? + * \param titlesOnly Are we looking for titles only? + * \param results A string-string hashmap that will hold + * the results in case of successful search. The keys are + * the URLs and the values are the page titles. + * \param phrase_search Indicates that word offset information should be kept. + * \return true if the search found something, false otherwise. + */ + bool searchWord( const QString& word, + bool wholeWords, + bool titlesOnly, + LCHMSearchProgressResults& results, + bool phrase_search ); + + /*! + * \brief Finalize the search, resolve the matches, the and generate the results array. + * \param tempres Temporary search results from SearchWord. + * \param results A string-string hashmap that will hold the results in case of successful search. + * The keys are the URLs and the values are the page titles. + */ + void getSearchResults( const LCHMSearchProgressResults& tempres, + QStringList * results, + unsigned int limit_results = 500 ); + + //! Looks up fileName in the archive. + bool ResolveObject( const QString& fileName, chmUnitInfo *ui ) const; + + //! Retrieves an uncompressed chunk of a file in the .chm. + size_t RetrieveObject(const chmUnitInfo *ui, unsigned char *buffer, LONGUINT64 fileOffset, LONGINT64 bufferSize) const; + + //! Encode the string with the currently selected text codec, if possible. Or return as-is, if not. + inline QString encodeWithCurrentCodec (const QString& str) const + { + return (m_textCodec ? m_textCodec->toUnicode (str) : str); + } + + //! Encode the string with the currently selected text codec, if possible. Or return as-is, if not. + inline QString encodeWithCurrentCodec (const char * str) const + { + return (m_textCodec ? m_textCodec->toUnicode (str) : (QString) str); + } + + //! Encode the string from internal files with the currently selected text codec, if possible. + //! Or return as-is, if not. + inline QString encodeInternalWithCurrentCodec (const QString& str) const + { + return (m_textCodecForSpecialFiles ? m_textCodecForSpecialFiles->toUnicode (str) : str); + } + + //! Encode the string from internal files with the currently selected text codec, if possible. + //! Or return as-is, if not. + inline QString encodeInternalWithCurrentCodec (const char * str) const + { + return (m_textCodecForSpecialFiles ? m_textCodecForSpecialFiles->toUnicode (str) : (QString) str); + } + + //! Helper. Translates from Win32 encodings to generic wxWidgets ones. + const char * GetFontEncFromCharSet (const QString& font) const; + + //! Helper. Returns the $FIftiMain offset of leaf node or 0. + u_int32_t GetLeafNodeOffset(const QString& text, + u_int32_t initalOffset, + u_int32_t buffSize, + u_int16_t treeDepth ); + + //! Helper. Processes the word location code entries while searching. + bool ProcessWLC(u_int64_t wlc_count, + u_int64_t wlc_size, + u_int32_t wlc_offset, + unsigned char ds, + unsigned char dr, + unsigned char cs, + unsigned char cr, + unsigned char ls, + unsigned char lr, + LCHMSearchProgressResults& results, + bool phrase_search ); + + //! Looks up as much information as possible from #WINDOWS/#STRINGS. + bool getInfoFromWindows(); + + //! Looks up as much information as possible from #SYSTEM. + bool getInfoFromSystem(); + + //! Fill the topic-url map + void fillTopicsUrlMap(); + + //! Sets up textCodec + void setupTextCodec (const char * name); + + //! Guess used text encoding, using m_detectedLCID and m_font. Set up m_textCodec + bool guessTextEncoding (); + + //! Change the current CHM encoding for internal files and texts. + //! Encoding could be either simple Qt codepage, or set like CP1251/KOI8, which allows to + //! set up encodings separately for text (first) and internal files (second) + bool changeFileEncoding( const char *qtencoding ); + + //! Convert the word, so it has an appropriate encoding + QCString convertSearchWord ( const QString &src ); + + /*! + * Helper procedure in TOC parsing, decodes the string between the quotes (first or last) with decoding HTML + * entities like í + */ + int findStringInQuotes (const QString& tag, int offset, QString& value, bool firstquote, bool decodeentities ); + + /*! + * Decodes Unicode HTML entities according to current encoding. + */ + QString decodeEntity (const QString& entity ); + + /*! + * \brief Returns the list of all available text encodings. + * \return A pointer to the beginning of the text encoding table. The table could be + * enumerated until language == 0, which means end of table. + * + * \ingroup encoding + */ + static const LCHMTextEncoding * getTextEncodingTable(); + + /*! + * \brief Looks up for encoding by LCID + * \param lcid LCID to look up + * \return A pointer to encoding structure. + * + * \ingroup encoding + */ + static const LCHMTextEncoding * lookupByLCID( short lcid ); + + /*! + * \brief Get the encoding index + * \param enc Encoding + * \return An index in encoding table. getTextEncodingTable() + i gets the encoding. + * + * \ingroup encoding + */ + static int getEncodingIndex( const LCHMTextEncoding * enc); + + /*! + * Normalizes path to search in internal arrays + */ + QString normalizeUrl (const QString& path ) const; + + + // Members + + //! Pointer to the chmlib structure + chmFile * m_chmFile; + + //! Opened file name + QString m_filename; + + //! Home url, got from CHM file + QString m_home; + + //! Context tree filename. Got from CHM file + QString m_topicsFile; + + //! Index filename. Got from CHM file + QString m_indexFile; + + //! Chm Title. Got from CHM file + QString m_title; + + // Localization stuff + //! LCID from CHM file, used in encoding detection + short m_detectedLCID; + + //! font charset from CHM file, used in encoding detection + QString m_font; + + //! Chosen text codec + QTextCodec * m_textCodec; + QTextCodec * m_textCodecForSpecialFiles; + + //! Current encoding + const LCHMTextEncoding * m_currentEncoding; + + //! Map to decode HTML entitles like ´ based on current encoding + QMap<QString, QString> m_entityDecodeMap; + + //! TRUE if /#TOPICS, /#STRINGS, /#URLTBL and /#URLSTR are resolved, and the members below are valid + bool m_lookupTablesValid; + + //! pointer to /#TOPICS + chmUnitInfo m_chmTOPICS; + + //! pointer to /#STRINGS + chmUnitInfo m_chmSTRINGS; + + //! pointer to /#URLTBL + chmUnitInfo m_chmURLTBL; + + //! pointer to /#URLSTR + chmUnitInfo m_chmURLSTR; + + //! Indicates whether the built-in search is available. This is true only when m_lookupTablesValid + //! is TRUE, and m_chmFIftiMain is resolved. + bool m_searchAvailable; + + //! pointer to /$FIftiMain + chmUnitInfo m_chmFIftiMain; + + //! Book TOC icon images storage + LCHMTocImageKeeper m_imagesKeeper; + + //! Map url->topic + QMap< QString, QString > m_url2topics; +}; diff --git a/lib/libchmfile/libchmtextencoding.cpp b/lib/libchmfile/libchmtextencoding.cpp new file mode 100644 index 0000000..9ba35ee --- /dev/null +++ b/lib/libchmfile/libchmtextencoding.cpp @@ -0,0 +1,197 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "libchmfileimpl.h" +#include "libchmtextencoding.h" + +static const LCHMTextEncoding text_encoding_table [] = +{ + { "Afrikaans",0, 0x0436, 1252, 0, "CP1252" }, + { "Albanian", 0, 0x041C, 1250, 238, "CP1250" }, + { "Arabic", "Algeria", 0x1401, 1256, 0, "CP1256" }, + { "Arabic", "Bahrain", 0x3C01, 1256, 0, "CP1256" }, + { "Arabic", "Egypt", 0x0C01, 1256, 0, "CP1256" }, + { "Arabic", "Iraq", 0x0801, 1256, 0, "CP1256" }, + { "Arabic", "Jordan", 0x2C01, 1256, 0, "CP1256" }, + { "Arabic", "Kuwait", 0x3401, 1256, 0, "CP1256" }, + { "Arabic", "Lebanon", 0x3001, 1256, 0, "CP1256" }, + { "Arabic", "Libya", 0x1001, 1256, 0, "CP1256" }, + { "Arabic", "Morocco", 0x1801, 1256, 0, "CP1256" }, + { "Arabic", "Oman", 0x2001, 1256, 0, "CP1256" }, + { "Arabic", "Qatar", 0x4001, 1256, 0, "CP1256" }, + { "Arabic", "Saudi Arabia", 0x0401, 1256, 0, "CP1256" }, + { "Arabic", "Syria", 0x2801, 1256, 0, "CP1256" }, + { "Arabic", "Tunisia", 0x1C01, 1256, 0, "CP1256" }, + { "Arabic", "United Arab Emirates", 0x3801, 1256, 178, "CP1256" }, + { "Arabic", "Yemen", 0x2401, 1256, 0, "CP1256" }, + { "Armenian", 0, 0x042B, 0, 0, "Latin1" }, + { "Azeri", "Cyrillic", 0x082C, 1251, 0, "CP1251" }, + { "Azeri", "Latin", 0x042C, 1254, 162, "CP1254" }, + { "Basque", 0, 0x042D, 1252, 0, "CP1252" }, + { "Belarusian", 0, 0x0423, 1251, 0, "CP1251" }, + { "Bulgarian", 0, 0x0402, 1251, 0, "CP1251" }, + { "Catalan", 0, 0x0403, 1252, 0, "CP1252" }, + { "Chinese", "China", 0x0804, 936, 134, "GBK" }, + { "Chinese", "Hong Kong SAR", 0x0C04, 950, 136, "Big5" }, + { "Chinese", "Macau SAR", 0x1404, 950, 136, "Big5" }, + { "Chinese", "Singapore", 0x1004, 936, 134, "GB2313" }, + { "Chinese", "Taiwan", 0x0404, 950, 136, "Big5" }, // traditional + { "Chinese", "Taiwan - Big5-HKSCS", 0x0404, 950, 136, "Big5-HKSCS" }, + { "Chinese", "Taiwan - GB18030", 0x0404, 950, 136, "GB18030" }, + { "Croatian", 0, 0x041A, 1250, 238, "CP1250" }, + { "Czech", 0, 0x0405, 1250, 238, "CP1250" }, + { "Danish", 0, 0x0406, 1252, 0, "CP1252" }, + { "Dutch", "Belgium", 0x0813, 1252, 0, "CP1252" }, + { "Dutch", "The Netherlands", 0x0413, 1252, 0, "CP1252" }, + { "English", "Australia", 0x0C09, 1252, 0, "CP1252" }, + { "English", "Belize", 0x2809, 1252, 0, "CP1252" }, + { "English", "Canada", 0x1009, 1252, 0, "CP1252" }, + { "English", "Caribbean", 0x2409, 1252, 0, "CP1252" }, + { "English", "Ireland", 0x1809, 1252, 0, "CP1252" }, + { "English", "Jamaica", 0x2009, 1252, 0, "CP1252" }, + { "English", "New Zealand", 0x1409, 1252, 0, "CP1252" }, + { "English", "Phillippines", 0x3409, 1252, 0, "CP1252" }, + { "English", "South Africa", 0x1C09, 1252, 0, "CP1252" }, + { "English", "Trinidad", 0x2C09, 1252, 0, "CP1252" }, + { "English", "United Kingdom", 0x0809, 1252, 0, "CP1252" }, + { "English", "United States", 0x0409, 1252, 0, "CP1252" }, + { "Estonian", 0, 0x0425, 1257, 186, "CP1257" }, + { "FYRO Macedonian", 0, 0x042F, 1251, 0, "CP1251" }, + { "Faroese", 0, 0x0438, 1252, 0, "CP1252" }, + { "Farsi", 0, 0x0429, 1256, 178, "CP1256" }, + { "Finnish", 0, 0x040B, 1252, 0, "CP1252" }, + { "French", "Belgium", 0x080C, 1252, 0, "CP1252" }, + { "French", "Canada", 0x0C0C, 1252, 0, "CP1252" }, + { "French", "France", 0x040C, 1252, 0, "CP1252" }, + { "French", "Luxembourg", 0x140C, 1252, 0, "CP1252" }, + { "French", "Switzerland", 0x100C, 1252, 0, "CP1252" }, + { "German", "Austria", 0x0C07, 1252, 0, "CP1252" }, + { "German", "Germany", 0x0407, 1252, 0, "CP1252" }, + { "German", "Liechtenstein", 0x1407, 1252, 0, "CP1252" }, + { "German", "Luxembourg", 0x1007, 1252, 0, "CP1252" }, + { "German", "Switzerland", 0x0807, 1252, 0, "CP1252" }, + { "Greek", 0, 0x0408, 1253, 161, "CP1253" }, + { "Hebrew", 0, 0x040D, 1255, 177, "CP1255" }, + { "Hindi", 0, 0x0439, 0, 0, "Latin1" }, + { "Hungarian", 0, 0x040E, 1250, 238, "CP1250" }, + { "Icelandic", 0, 0x040F, 1252, 0, "CP1252" }, + { "Indonesian", 0, 0x0421, 1252, 0, "CP1252" }, + { "Italian", "Italy", 0x0410, 1252, 0, "CP1252" }, + { "Italian", "Switzerland", 0x0810, 1252, 0, "CP1252" }, + { "Japanese", "Shift-JIS", 0x0411, 932, 128, "Shift-JIS" }, + { "Japanese", "JIS7", 0x0411, 932, 128, "JIS7" }, + { "Japanese", "eucJP", 0x0411, 932, 128, "eucJP" }, + { "Korean", 0, 0x0412, 949, 129, "eucKR" }, + { "Latvian", 0, 0x0426, 1257, 186, "CP1257" }, + { "Lithuanian", 0, 0x0427, 1257, 186, "CP1257" }, + { "Malay", "Brunei", 0x083E, 1252, 0, "CP1252" }, + { "Malay", "Malaysia", 0x043E, 1252, 0, "CP1252" }, + { "Maltese", 0, 0x043A, 0, 0, "Latin1" }, + { "Marathi", 0, 0x044E, 0, 0, "Latin1" }, + { "Norwegian", "Bokmal", 0x0414, 1252, 0, "CP1252" }, + { "Norwegian", "Nynorsk", 0x0814, 1252, 0, "CP1252" }, + { "Polish", 0, 0x0415, 1250, 238, "CP1250" }, + { "Portuguese", "Brazil", 0x0416, 1252, 0, "CP1252" }, + { "Portuguese", "Portugal", 0x0816, 1252, 0, "CP1252" }, + { "Romanian", "Romania", 0x0418, 1250, 238, "CP1250" }, + { "Russian", "Cyrillic", 0x0419, 1251, 204, "CP1251" }, + { "Russian", "KOI-8", 0x7001, 2251, 204, "KOI8-R" }, + { "Russian", "KOI-8 (TOC 1251)", 0x7002, 3251, 0, "CP1251/KOI8-R" }, + { "Russian", "Cyrillic (TOC KOI8)", 0x7003, 3251, 0, "KOI8-R/CP1251" }, + { "Sanskrit", 0, 0x044F, 0, 0, "Latin1" }, + { "Serbian", "Cyrillic", 0x0C1A, 1251, 0, "CP1251" }, + { "Serbian", "Latin", 0x081A, 1250, 238, "CP1250" }, + { "Setsuana", 0, 0x0432, 1252, 0, "CP1252" }, + { "Slovak", 0, 0x041B, 1250, 238, "CP1250" }, + { "Slovenian", 0, 0x0424, 1250, 238, "CP1250" }, + { "Spanish", "Argentina", 0x2C0A, 1252, 0, "CP1252" }, + { "Spanish", "Bolivia", 0x400A, 1252, 0, "CP1252" }, + { "Spanish", "Chile", 0x340A, 1252, 0, "CP1252" }, + { "Spanish", "Colombia", 0x240A, 1252, 0, "CP1252" }, + { "Spanish", "Costa Rica", 0x140A, 1252, 0, "CP1252" }, + { "Spanish", "Dominican Republic", 0x1C0A, 1252, 0, "CP1252" }, + { "Spanish", "Ecuador", 0x300A, 1252, 0, "CP1252" }, + { "Spanish", "El Salvador", 0x440A, 1252, 0, "CP1252" }, + { "Spanish", "Guatemala", 0x100A, 1252, 0, "CP1252" }, + { "Spanish", "Honduras", 0x480A, 1252, 0, "CP1252" }, + { "Spanish", "Mexico", 0x080A, 1252, 0, "CP1252" }, + { "Spanish", "Nicaragua", 0x4C0A, 1252, 0, "CP1252" }, + { "Spanish", "Panama", 0x180A, 1252, 0, "CP1252" }, + { "Spanish", "Paraguay", 0x3C0A, 1252, 0, "CP1252" }, + { "Spanish", "Peru", 0x280A, 1252, 0, "CP1252" }, + { "Spanish", "Puerto Rico", 0x500A, 1252, 0, "CP1252" }, + { "Spanish", "Spain", 0x0C0A, 1252, 0, "CP1252" }, + { "Spanish", "Uruguay", 0x380A, 1252, 0, "CP1252" }, + { "Spanish", "Venezuela", 0x200A, 1252, 0, "CP1252" }, + { "Swahili", 0, 0x0441, 1252, 0, "CP1252" }, + { "Swedish", "Finland", 0x081D, 1252, 0, "CP1252" }, + { "Swedish", "Sweden", 0x041D, 1252, 0, "CP1252" }, + { "Tamil", 0, 0x0449, 0, 0, "TSCII" }, + { "Tatar", 0, 0x0444, 1251, 204, "CP1251" }, + { "Thai", 0, 0x041E, 874, 222, "TIS-620" }, + { "Turkish", 0, 0x041F, 1254, 162, "CP1254" }, + { "Ukrainian", "Cyrillic", 0x0422, 1251, 0, "CP1251" }, + { "Ukrainian", "KOI-8", 0x8422, 2251, 204, "KOI8-U" }, + { "Unicode", "UTF-8", 0x7010, 0, 0, "UTF-8" }, + { "Unicode", "UTF-16", 0x7011, 0, 0, "UTF-16" }, + { "Urdu", 0, 0x0420, 1256, 178, "CP1256" }, + { "Uzbek", "Cyrillic", 0x0843, 1251, 0, "CP1251" }, + { "Uzbek", "Latin", 0x0443, 1254, 162, "CP1254" }, + { "Vietnamese", 0, 0x042A, 1258, 163, "CP1258" }, + { "Xhosa", 0, 0x0434, 1252, 0, "CP1252" }, + { "Zulu", 0, 0x0435, 1252, 0, "CP1252" }, + { 0, 0, 0, 0, 0, 0 } +}; + + +const LCHMTextEncoding * LCHMFileImpl::getTextEncodingTable() +{ + return text_encoding_table; +} + +const LCHMTextEncoding * LCHMFileImpl::lookupByLCID( short lcid ) +{ + for ( const LCHMTextEncoding * t = text_encoding_table; t->language; t++ ) + if ( t->winlcid == lcid ) + return t; + + return 0; +} + +/* +const LCHMTextEncoding * LCHMFileImpl::lookupByWinCharset( int charset ) +{ + for ( const text_encoding_t * t = text_encoding_table; t->charset; t++ ) + if ( t->wincharset == charset ) + return t; + + return 0; +} +*/ + +int LCHMFileImpl::getEncodingIndex( const LCHMTextEncoding * enc) +{ + for ( int i = 0; text_encoding_table[i].language; i++ ) + if ( (text_encoding_table + i) == enc ) + return i; + + return -1; +} diff --git a/lib/libchmfile/libchmtextencoding.h b/lib/libchmfile/libchmtextencoding.h new file mode 100644 index 0000000..ff34736 --- /dev/null +++ b/lib/libchmfile/libchmtextencoding.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef LIBCHMTEXTENCODING_H +#define LIBCHMTEXTENCODING_H + + +/*! + * Represents a text encoding of CHM file; also has some useful routines. + */ +typedef struct LCHMTextEncoding +{ + const char * language; //! French, English, etc. language == 0 represents the end of table. + const char * sublanguage; //! French:Canada, French:France etc. May be 0 - no sublanguage + int winlcid; //! Windows LCID for this language + int wincodepage; //! Windows codepage for this language. + int wincharset; //! Windows charset. + const char * qtcodec; //! Qt text codec to use +}; + + +#endif /* LIBCHMTEXTENCODING_H */ diff --git a/lib/libchmfile/libchmtocimage.cpp b/lib/libchmfile/libchmtocimage.cpp new file mode 100644 index 0000000..c272b10 --- /dev/null +++ b/lib/libchmfile/libchmtocimage.cpp @@ -0,0 +1,2112 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include "libchmfile.h" +#include "libchmtocimage.h" + +typedef struct +{ + unsigned int size; + const char * data; +} png_memory_image_t; + + +static const png_memory_image_t png_image_bookarray[42] = +{ +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x00" + "\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x80" + "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\xFF\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\xC0\xC0\xC0\x00\xC0\x40\xC0\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x40\xC0" + "\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\xFF\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00" + "\x80\x80\x80\x00\x00\x00\x00\x01\x02\x00\x00\x00\x01\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80" + "\x00\x80\x00\x80\x00\x80\x00\x80\x80\x80\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x40\xC0\x40\x00\x40\x40\x40\x00\x00\x00\x00\x00\x80\x80\x80\x00\x40\x40\x40\x00\x3F\x3F\x3F" + "\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x80\x00\x80\xFF\x80\x00\x80\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF" + "\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80" + "\x00\x80\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\xFF\x00\x00\x00" + "\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x19\x71\xA3\xBE\x36\x4F\x5A\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80" + "\xFF\x40\x40\x40\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x80\x00\x00\x3F\xFF\x3F\x00\x00\x00\x00\x00\x80" + "\x80\x80\xFF\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x81\x81\x81\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x40\x40\x40\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x80\x80" + "\x80\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\xFF\xFF\xFF\x00\x80\x00\x80\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x40" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80" + "\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x81\x81\x81\x00\x81\x81\x81\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80\xFF\x80\x00\x80\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x80\x00\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xEC\xAF\x46\xD5\x91\xC8\xE3\xA4\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00" + "\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00" + "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x00" + "\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x81\x00\x80" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x01" + "\x00\x00\x00\x81\x00\x80\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00" + "\x80\x00\x00\x00\x00\x00\x7F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x40\x40" + "\x00\x00\x00\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x80\x00\x81\x00\x80\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x00\x00\x00\xFF\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x80\x00\x40\xC0\x40\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\xC0\x40\xC0\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00" + "\x80\x80\x80\x00\x00\x00\x00\x01\x02\x00\x00\x00\x01\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xC0\x40\xC0\x00\x40\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80" + "\x00\x80\x00\x80\x00\x80\x00\x80\x80\x80\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x40\xC0\x40\x00\x40\x40\x40\x00\x00\x00\x00\x00\x80\x80\x80\x00\x40\x40\x40\x00\x3F\x3F\x3F" + "\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x80\x00\x80\xFF\x80\x00\x80\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF" + "\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80" + "\x00\x80\xFF\x80\x00\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\xFF\x00\x00\x00" + "\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0B\x78\x8F\xD2\x1A\xFF\x32\x3B\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00" + "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x80\x80" + "\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x80\x80\x80\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x7F\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x80\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x02\x01" + "\x00\x00\x01\x01\x00\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\xFF\xFF\xFF\x00\x80\x00\x80\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x7F\x00\x80" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\x00\xFF\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x81\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x40" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80" + "\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x81\x81\x81\x00\x81\x81\x81\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80\xFF\x80\x00\x80\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x80\x00\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xB6\x69\xF8\x9A\x72\x7B\xFD\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x80\x80\x80\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00" + "\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x80\x80\x80\xFF\x7F\x7F\x80\x00\xC1\xC1\xC0\x00" + "\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x7F\x7F\x40\x00\x00\x00\x80\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00" + "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00" + "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0" + "\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80" + "\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00" + "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF" + "\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF" + "\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF" + "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0" + "\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF" + "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF" + "\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF" + "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF" + "\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x80\x80" + "\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\x7B\x78\xBB\x65\xD9\x1C\xEF\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x80\x80\x80\xFF\x7F\x7F\x7F\x00\x00\x00\x01\x00" + "\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\x7F\x7F\xFF\x00\x00\x00\x00\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00" + "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF" + "\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\xC1\xC1\xC0\x00\x3F\x3F\x40\x00\xC1\xC1\xC1\x00" + "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x80\x00\x81\x81\x80\x00\x80\x80\x80\x00\x04\x00\x00\x00\x00\x7F\x7F" + "\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00" + "\x00\x00\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00" + "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00" + "\x00\x01\x00\x7F\x7F\x80\x00\x80\x80\x80\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0" + "\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF" + "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF" + "\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF" + "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF" + "\x00\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xCA\x77\x06\x21\xB0\x9C\x3D\x2E\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00" + "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00" + "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00" + "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00" + "\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x81\x81\x80\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00" + "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01" + "\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\xFF\x00\x00\xC1\xC0\xC0\x00" + "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xFF" + "\x00\x00\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80" + "\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00" + "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF" + "\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF" + "\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF" + "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0" + "\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF" + "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF" + "\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF" + "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF" + "\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x80\x80" + "\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x67\x79\x5A\x0A\xDD\xD6\x45\x4D\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00" + "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00" + "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00" + "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x7F\xFF\xFF\x00\x00\x00\x00\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\xFF" + "\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF" + "\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01" + "\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\xFF\x00\x00\xC1\xC0\xC0\x00" + "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x81\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\xC0\xC0\x00\x3F" + "\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0\x80\x00\x00\x00\xC0\x00\xC0\xC0\x80\x00\x00\x00\xC0\x00\xC0\xC0" + "\x80\x00\x00\x00\xC0\x00\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\xC0\xC0\xC0\xFF" + "\x80\x80\x80\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00" + "\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\xC1\xC1\xC1\x00\x00" + "\x00\x01\x00\x7F\x7F\x80\x00\x80\x80\x80\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0" + "\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF" + "\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF" + "\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF" + "\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF" + "\x00\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94\x33\x28\x09\x1C\xAE\x31\x32\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\xFF\x00\x00\x00\xFF\x00\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x00\x00\x01\x00\xFF\xFF\xFF\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00" + "\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\x01\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE8\x04\x5D\xFD\xA0\x80\xC9\x63\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x81\x81\x80\x00\x00\x00\x00\x00\x80" + "\x80\x80\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00" + "\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\xFF\x00" + "\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x01\x01\x00\x01\x01\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x00\x00\x01\x00\xFF\xFF\xFF\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\x00\x00\x00\x00\x00\xFF\x00\x01\x00\xFF" + "\xFF\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\xFF\x00\x00\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00" + "\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\x01\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x22\x4F\x1D\x9B\xFC\x6D\x6C\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01" + "\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x01\x01\x00\x00" + "\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\xFF\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE3\xD9\x62\x47\xFA\x28\x6C\x06\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00" + "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x01" + "\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00" + "\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\xFF\xFF\x00\xFF\xFF\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2D\x7C\x8C\x20\x93\x9B\xCB\xA7\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0" + "\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x3F\x00\x00\x80\x81\x00\x00\x00\x00\x00\x00\x80" + "\x7F\x00\x00\x00\x00\x00\xC0\xC0\xC1\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF" + "\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x80\x00\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x00\x80\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF" + "\x7F\x7F\x7F\x00\xC1\xC1\xC1\x00\x40\xC0\xC0\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x01\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x01\x81" + "\x01\x00\x80\x00\x80\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC0" + "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0" + "\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\xC1\xC1\xC1\x00\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\xC0" + "\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\xC0\x00\x00\x00\x40" + "\x40\x3F\x00\xC0\xC0\xC1\x00\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xC0\x40\x40\x00\x40\x40\x3F\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x01\x00\x3F\x3F\x3F\x00\xFF\xFF\xFF\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\x40\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7F\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01" + "\x01\x00\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x80\xFF\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40" + "\x01\x00\x00\x81\x00\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\x00\x00\x81\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\xC0\x00\x00\x00\x00\x00\x80\x80\x00" + "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x32\x9B\x2E\x2D\x01\x77\x57\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00" + "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00" + "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x80\x80\xFF\x00\x80\x80\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x80\x00\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x00\x80\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x01\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x3F\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80" + "\x00\x00\xFF\x80\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC0" + "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x40\x40" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x80\xFF\x00\x81\x80\x80\x00\x00\xFF\xFF\x00" + "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\xC0" + "\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x80\x00\xC0\xC1\xC1\x00\x3F" + "\x00\x00\x00\xC0\xC0\xC1\x00\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\xC0\x40\x40\x00\x40\x40\x3F\x00\x01\x00\xFF\x00\x40\xC0\xC0\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x3F\x3F\x3F\x00\xFF\xFF\xFF\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\x40\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7F\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01" + "\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x80\xFF\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40" + "\x01\x00\x00\x81\x00\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\x00\x00\x81\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\xC0\x00\x00\x00\x00\x00\x80\x80\x00" + "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x2B\xAD\x4B\x8B\x6D\x23\xB6\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0" + "\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x3F\x00\x00\x80\x81\x00\x00\x00\x00\x00\x00\x80" + "\x7F\x00\x00\x00\x00\x00\xC0\xC0\xC1\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF" + "\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x80\x00\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x00\x80\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF" + "\x7F\x7F\x7F\x00\xC1\xC1\xC1\x00\x40\xC0\xC0\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x01\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x01\x81" + "\x01\x00\x80\x00\x80\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC0" + "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0" + "\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\xC1\xC1\xC1\x00\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\xC0" + "\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\xC0\x00\x00\x00\x40" + "\x40\x3F\x00\xC0\xC0\xC1\x00\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x81\x81\x00\x00\x00" + "\x00\x00\xC0\x40\x40\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xC0\x40\x40\x00\x40\x40\x3F\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x81\x80\x00\xFF\x7F\x7F\x00\x80\x00\x00\x00\x40\x40\xC0\x00\xC0\xC0\xC0\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\x40\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81" + "\x81\x81\x00\x80\x00\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x80\xFF\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x7F\x00\x00\x80\xFF\x00\x00\x00\x00" + "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x80\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\x00\x00\x80\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\x40\x40\x81\x00\x00" + "\x00\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x7F\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\xC0\x00\x00\x00\x00\x00\x80\x80\x00" + "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xF5\x35\xB3\xDB\x47\x22\xC5\x3E\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00" + "\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x01\x00\x00" + "\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x80\x80\xFF\x00\x80\x80\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x80\x00\xFF\x00\x80\x00\xFF\x00\x00\xFF\xFF\x00\x00\x80\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x01\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x01\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x3F\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80" + "\x00\x00\xFF\x80\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\xC1\xC1\xC0" + "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x40\x40" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x80\xFF\x00\x81\x80\x80\x00\x00\xFF\xFF\x00" + "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\xC0" + "\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x80\x00\xC0\xC1\xC1\x00\x3F" + "\x00\x00\x00\xC0\xC0\xC1\x00\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x81\x81\x00\x00\x00" + "\x00\x00\xC0\x40\x40\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\xC0\x40\x40\x00\x40\x40\x3F\x00\x01\x00\xFF\x00\x40\xC0\xC0\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x81\x80\x00\xFF\x7F\x7F\x00\x80\x00\x00\x00\x40\x40\xC0\x00\xC0\xC0\xC0\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\xC0\x40\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81" + "\x81\x81\x00\x80\x00\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x80\xFF\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x7F\x00\x00\x80\xFF\x00\x00\x00\x00" + "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x80\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\x00\x00\x80\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\x40\x40\x81\x00\x00" + "\x00\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x7F\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\xC0\x00\x00\x00\x00\x00\x80\x80\x00" + "\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD7\xDE\xC4\xFF\x42\xC7\x9B\xA9\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x80" + "\x80\x80\x00\xC1\xC1\xC1\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x80\x80\x80\x00\x3F\x3F\x3F\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x01\x00" + "\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x7F\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00" + "\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\xFF\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x75\x7A\xA1\xB2\x30\x65\x74\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80" + "\x80\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00" + "\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\xFF\x00\x00\x00\x81\x80\x80\x00\x3F\x3F\x3F\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x00\x01\x01\x00\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\xFF\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xA2\xDD\xCE\xCA\x46\xBC\x69\xD0\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x7F\xFF\x7F\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x81\x01\x81\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x7F\xFF" + "\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x01\x00\x00\x00\x00\x00\x7F\xFF\x80\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x7F\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00" + "\x81\x01\x81\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7E\x13\x5A\xB8\x0F\x88\x51\xFF\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80" + "\x80\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x80\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x02\x00" + "\x00\x00\x00\x01\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x7F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x81\x00\x80\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x80\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x81\x01\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x7F\xFF" + "\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x01\x00\x00\x00\x00\x00\x7F\xFF\x80\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x7F\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00" + "\x81\x01\x81\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD9\x8B\x81\x99\x2A\x3C\x4C\x83\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00" + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x80\x00\x80" + "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00" + "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x80\x80" + "\x80\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\xC0\xC0\xC0" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x80\x80\x80\x00\xFF\xFF\xFF\x00\xC1\xC1\xC1\x00\x40" + "\x40\x40\x00\x01\x80\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC9\x37\xA7\x79\xF8\x99\x78\xFD\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x81\x80\x80\x00" + "\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x81\x81\x80\x00\x81\x81\x81\x00\x01" + "\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00" + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x80\x00\x80" + "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00" + "\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x80\x80" + "\x80\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\xC0\xC0\xC0" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x80\x80\x80\x00\xFF\xFF\xFF\x00\xC1\xC1\xC1\x00\x40" + "\x40\x40\x00\x01\x80\x00\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x80\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\xFF\x7F\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7E\xFB\xBE\x76\x34\x86\xB8\x07\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x40\x40\x40\x00\xC0\xC0\xC0\x00\x40\x40" + "\x40\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x80\x80\x80" + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x01\x00\x00" + "\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x80\x80\x80\x00\x00\x00\x00\x00\x04\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0" + "\xFF\x40\x40\x40\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x01\x01\x01\x00\xFF" + "\xFF\xFF\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x01\x00\x00\x00\xFF\x00\x40\x40\x40\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\x01\x00\xFF\xFF\x00" + "\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\x00\x01\x01\x01\x00\x80\x80\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00" + "\x3F\x3F\x40\x00\xC0\xC0\xC0\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x3F\x3F\x3F\x00\x80\x80" + "\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x00\x00\x00\x01\x00\x81\x81\x01\x00\x40\x40\xC0\x00\x80\x80\x00\x00\x01\x01\x01\x00" + "\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0\x00\xC0\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x40" + "\x40\xC0\x00\x00\x00\x00\x00\x40\x40\xC0\x00\x80\x80\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00" + "\x00\x00\x40\x40\xC0\x00\xC0\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x80\x80\x00\xC0\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD7\x04\xC0\x9D\x86\xE8\xEF\xDB\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\x00\x00\xFF\xFF\x00" + "\x00\xFF\x80\x80\x80\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xC0\xC0\xC0" + "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x02\x01" + "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0" + "\xC0\x00\x00\x00\x00\x00\x00\x01\x01\x00\x01\x01\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x3F\x3F\x40\x00\x00\xFF\xFF\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\xFF" + "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF" + "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x80\x80\x00\xFF" + "\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00" + "\x3F\x3F\x40\x00\xC0\xC0\xC0\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x3F\x3F\x3F\x00\x80\x80" + "\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x00\x00\x00\x01\x00\x81\x81\x01\x00\x40\x40\xC0\x00\x80\x80\x00\x00\x01\x01\x01\x00" + "\x01\x01\x01\x00\x80\x80\x00\x00\x40\x40\xC0\x00\xC0\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x40" + "\x40\xC0\x00\x00\x00\x00\x00\x40\x40\xC0\x00\x80\x80\xC0\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00" + "\x00\x00\x40\x40\xC0\x00\xC0\xC0\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x80\x80\x00\xC0\xC0\xC0\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xAA\x18\xF9\xFF\xA4\xB4\xD4\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x80\x80\x80\xFF\x80\x80\x80\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\xFF\xFF\x00" + "\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x40\x40\x40\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0" + "\x00\x40\x40\x40\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x01\x01\x00\x80\x80\x80\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x80\x80\x80\x00\x01\x01\x01\x00\x00\x00\x00\x00\x01\x01\x01" + "\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00" + "\x40\x40\x40\x00\x80\x80\x80\x00\x01\x01\x01\x00\x80\x80\x80\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00" + "\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\xC0\xC0" + "\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00" + "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x80\x80\x80\x00\xFF" + "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD1\xD0\x9F\x60\xE3\xE0\x4D\xCB\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01" + "\x00\x00\x01\xC1\xC0\xC0\x00\xC1\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0" + "\xC0\x00\x00\x00\x00\x00\x00\x01\x01\x00\xC1\xC1\xC1\x00\x01\x01\x00\x00\x01\x01\x01\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\x01\x01\x01\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\x00\x3F\x3F\x3F\x00\x80\x80\x80\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01" + "\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00" + "\x40\x40\x40\x00\x80\x80\x80\x00\x01\x01\x01\x00\x80\x80\x80\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00" + "\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\xC0\xC0" + "\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00" + "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x80\x80\x80\x00\xFF" + "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE9\xB2\xE9\x24\xBC\x59\xC0\x67\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" + "\x01\x81\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xC0\xC0\xC0" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x80\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" + "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0" + "\xFF\x00\x00\x80\xFF\x80\x80\x00\x00\x00\x00\x00\x00\x01\x01\x81\x00\x01\x01\x81\x00\xC1\xC1\xC0\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\xFF\x00\xFF\xFF" + "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00" + "\x80\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00" + "\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00\x00\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x80\x80\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x01\x01\x80\x00\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80\x80\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x80\xFF\x00\xFF\x00\xFF\x00\x00\x00\xFF\x00\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00" + "\x00\x01\x80\x00\x00\x00\x00\x00\x00\x01\x00\x00\x80\x80\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x89\x0B\xF3\xB4\x69\x4F\x85\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\x80\x80\x80\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x80\xFF\xFF\xFF\x00" + "\xFF\x00\x00\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x80" + "\x80\xFF\x00\x00\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" + "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\x00\x00\x00\x00\xC1\xC0\xC0\x00\x40\x40\xC0\x00\x00\x80\x00\x00\x00\x00\x00\x00\x01\x01\x81\x00" + "\x00\x00\x00\x00\xC0\xC0\x40\x00\x3F\x3F\x3F\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x80\xFF\xFF" + "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xFF\xFF\x00\xFF\x00\xFF\x00" + "\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x00\x00\x00\x01\x80\x00\x00\x00\x00\x00\xFF\x00" + "\x00\x00\x01\x01\x80\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x80\x80\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x80\xFF\x00\xFF\x00\xFF\x00\x00\x00\xFF\x00\xFF\x00\xFF" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x00\x00\x80" + "\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\x2A\x21\x92\x43\x90\x14\x7B\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x80\x80\x00" + "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x01\x00\x7F\x7F" + "\xFF\x00\x80\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x7F\x7F\xFF\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xC0\xC0\x40\x00\x7F\x7F\xFF\x00\x00" + "\x00\x01\x00\x80\x80\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01" + "\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\x40\x00\x7F\x7F\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x80\x80\x00\x00\xC0\xC0\xC0" + "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xFF\x00\x81\x81\x81\x00\x01\x01\x01\x00\x81\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\xFF\x80\x80\x00\xFF\xFF\xFF\x00\xFF\x00\x00" + "\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x00\xFF\x80\x80\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80" + "\x80\x00\xFF\x00\x00\x00\x00\x40\x40\xC1\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF" + "\xFF\x00\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\xC0\xC0\x40" + "\x00\x00\x00\xC0\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\xC1\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x34\xE6\xE2\x1F\x81\x45\x95\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x80\x00" + "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x00\x00\x00\x81\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01" + "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x81\x80\x00\x00\x7F\x7F" + "\xFF\x00\x80\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\x00\xFF\xFF\x00\x81\x80\x00\x00\x7F\x7F\xFF\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC0\xC0\x00\xC0\x81\x01\x00\x7F\x7F\xFF\x00\x00" + "\x00\x01\x00\x80\x80\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x01" + "\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\x40\x00\x7F\x7F\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x80\x80\x00\x00\xC0\xC0\xC0" + "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\xFF\x00\x81\x81\x81\x00\x01\x01\x01\x00\x81\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\xFF\x80\x80\x00\xFF\xFF\xFF\x00\xFF\x00\x00" + "\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x00\xFF\x80\x80\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80" + "\x80\x00\xFF\x00\x00\x00\x00\x40\x40\xC1\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF" + "\xFF\x00\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\xC0\xC0\x40" + "\x00\x00\x00\xC0\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\xC1\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x80\x80\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD0\x0C\x16\x8A\x64\xF0\xC0\x3D\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF" + "\x00\x00\x00\x00\x01\x01\x01\x00\x01\x01\x01\x00\x81\x81\x81\x00\x01\x01\x00\x00\xC1\xC1\xC1\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x04\x00" + "\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\x40\x00\x00\xFF\xFF\x00\x80\x00\x00\x00\x40\x40" + "\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\xC0\xC0\x80\x00\x7F\x7F\x00\x00\x00\x00\x01" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00" + "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0" + "\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0" + "\xC0\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\xFF\x80\x80\x00\xFF\x00\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x80\x80\x80" + "\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x81\x00\x00" + "\x40\x00\xC0\x00\x00\x80\x80\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\xC0\xC0\xC0\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00" + "\x00\x00\x00\x00\x80\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC0\x80\x80\x00\x40\x40" + "\x40\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\xFF\x7F\x80\x00\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x80\x00\x00\x00\xC0\xC0\xC0" + "\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00" + "\xC1\xC1\xC0\x00\x80\x7F\x3F\x00\x00\x80\x01\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\x80\x80\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F" + "\x00\x00\x00\x00\x00\x00\x81\x81\x00\x00\x80\x80\x00\x00\xC0\xC0\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x40" + "\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xBE\x4D\x07\xF0\xED\x63\x0A\xFD\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\xC1\xC0\xC0\x00" + "\x81\x81\x81\x00\x01\x00\x00\x00\x01\x00\x00\x00\x81\x81\x81\x00\x01\x01\x00\x00\xC1\xC1\xC1\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x04\x01" + "\x00\x00\x01\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x40\x40\x40\x00\x00\xFF\xFF\x00\x80\x00\x00\x00\x40\x40" + "\x40\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\xC0\xC0\x40\x00\xC0\xC0\x80\x00\x7F\x7F\x00\x00\x00\x00\x01" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00" + "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0" + "\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\xC0\xC0" + "\xC0\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\xFF\x80\x80\x00\xFF\x00\xFF\x00\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x80\x80\x80" + "\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x81\x00\x00" + "\x40\x00\xC0\x00\x00\x80\x80\x00\xC0\xC0\xC0\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\xC0\xC0\xC0\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00" + "\x00\x00\x00\x00\x80\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC0\x80\x80\x00\x40\x40" + "\x40\x00\x00\x00\x00\x00\x40\xC0\xC0\x00\xFF\x7F\x80\x00\x81\x81\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x80\x00\x00\x00\xC0\xC0\xC0" + "\x00\x7F\x7F\x7F\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00" + "\xC1\xC1\xC0\x00\x80\x7F\x3F\x00\x00\x80\x01\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\x80\x80\xFF\xC0\xC0" + "\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F" + "\x00\x00\x00\x00\x00\x00\x81\x81\x00\x00\x80\x80\x00\x00\xC0\xC0\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x40" + "\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x76\x2F\x35\xC9\x77\x48\x56\x41\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x80" + "\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x80\x80\xFF\x00\x00\x00\x00\x40\x40\x40" + "\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x7F\x7F\x80\x00\x00\x00\xFF\x00\x81\x81\x81\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40" + "\x40\x40\x00\x04\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x40\x40\x40\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x81\x81\x81\x00\x01\x01\x00\x00\x80\x80" + "\x81\x00\x00\x00\x00\x00\x80\x80\x80\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0" + "\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x01\x00\x00\x00\x00\x80\x80\x80\x00\x40\x40\x40\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x01\x01\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40" + "\x40\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x80\x80\x80" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80" + "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xB6\x05\xC9\xAB\x7C\x77\xA6\xA1\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01" + "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x80\x80\x80\xFF\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x01\x80\x80\x80\xFF\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x00\x00" + "\x00\x00\x81\x81\x81\x00\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40\x00\x04\x00\x00\x00\x00\x80\x80" + "\x80\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x81\x81\x81\x00\x01\x01\x01\x00\x80\x80\x80\x00\x00\x00\x00\x00\x80\x80\x80\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00" + "\x00\x00\x01\x00\x00\x00\x00\x80\x80\x80\x00\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x80\x80\x80" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x3F\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00\x40\x40\x40\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x40\x40\x40\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x40\x40\x40\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\x35\xD6\xA3\x81\xA7\xB0\x8B\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\x00\x00\xFF\x00" + "\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x81\x81\x00\x40\x40\x3F" + "\x00\x81\x81\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x01\x01\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00" + "\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00" + "\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x67\x35\x86\x1E\xD6\xF6\xF1\x59\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x00\xFF" + "\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01" + "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\x00\x00\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00" + "\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x81\x81\x81\x00\x40\x40\x3F" + "\x00\x81\x81\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x01\x01\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00" + "\x00\x00\x00\x00\x01\x01\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x01\x00\x00\x00" + "\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\xC0\x00\x00\x00\xC1" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\x34\xBA\xF9\x00\x88\x01\xD9\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x3F\x3F\x3F\x00\x01\x01" + "\x00\x00\xFF\xFF\x00\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\x00\x00\x00\x00\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xFF\xFF\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\xC0\xC0\x80\x00\x00\x00\x81" + "\x00\x7F\x7F\x80\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x7F\x7F\x80\x00\x00\x00\xFF\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xC0\xC0\xC0\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x80\x80\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x3F\x3F\x3F\x00\xC1" + "\xC1\xC0\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x40\x40\x40\x00\x81\x81\x80\x00\x00\x00\x01\x00\xC0\xC0\xC0\x00\x7F\x7F\x80\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x40\x40\x40\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF" + "\x80\x80\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x7F" + "\x7F\x80\x00\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x81\x81\x80\x00\x80\x80\x80\x00\x80\x80\x80" + "\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\xD9\xC6\x01\x2A\xF1\x62\x54\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xC1\xC0\xC0\x00\x3F\x40\x40\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x80\x80\x80" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF" + "\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x01" + "\x00\x00\x01\x01\x00\x00\x01\x81\x80\x80\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xC0\xC0\xC0\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\xFF\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\xC1\xC1\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x80\x80\x80\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x3F\x3F\x3F\x00\xC1" + "\xC1\xC0\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x40\x40\x40\x00\x81\x81\x80\x00\x00\x00\x01\x00\xC0\xC0\xC0\x00\x7F\x7F\x80\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x40\x40\x40\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF" + "\x80\x80\x80\xFF\xC0\xC0\xC0\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x40\x40\x40\x00\xC0\xC0\xC0\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" + "\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\x00\x7F" + "\x7F\x80\x00\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x40\x40\x00\x81\x81\x80\x00\x80\x80\x80\x00\x80\x80\x80" + "\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x35\x50\x04\xC5\x7F\x63\x55\x6E\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x7F\x7F\x7F\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x40\x40\x40\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x01\x01\x00\x00\xFF\xFF" + "\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00" + "\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x02\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x01\x01" + "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00" + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x40\x40\x40\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x01\x01\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x80\x80\x80\x00\xC1\xC1\xC1\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00" + "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40" + "\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00" + "\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7C\xD8\x09\x7C\xF1\x24\x22\x3A\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01" + "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x01\x01\x00\x00\xFF\xFF" + "\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\xFF\x00\x00\x00\xFF\xFF\x00\x00" + "\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\xC1\xC0\xC0\x00\x00\xFF\xFF\x00" + "\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\xFF\x00\x00\x01\x01\x01\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x02\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\xFF\xFF\xFF\x00\x00" + "\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x01\x01" + "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00" + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x40\x40\x40\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x01\x01\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x80\x80\x80\x00\xC1\xC1\xC1\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00" + "\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x40\x40\x40\x00\x40\x40\x40" + "\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00" + "\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x3F\x3F\x3F\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC0\xC0\xC0\xFF" + "\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00" + "\x00\x00\xFF\x80\x80\x80\xFF\x80\x80\x80\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\xE9\x1F\xBE\x0F\x02\xCD\x5F\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xFF\x80\x80\x80\xFF\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xFF\xFF\x00\x00\x01\x01\x00\xFF\xFF\xFF" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x01\x00\x01\x01\x00\x00\xFF\xFF\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\xFF\x00\x00\x00\xFF\x80\x80\x80\x00\x00\x00" + "\x00\x00\x80\x80\x80\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\x80\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\xFF\x80\x80\x80\x00\x80" + "\x80\x80\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x40\x40\x40\xFF\xFF\xFF\xFF\x00\x01\x01\x01\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\xC1\xC1\xC1\x00\x3F\x3F\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x01\x01\x00\x00\x7F\x7F\x00\x00\x80\x80\x00\x01" + "\x01\x01\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\xFF\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x80\x7F\x7F\x00\x00\xFF\xFF" + "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x80\x80\x80\x00" + "\x00\x7F\x7F\x00\x80\x81\x81\x00\x00\x01\x01\x00\x00\x01\x01\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\xC1\xC1\xC0\x00\xC1\xC1\xC1" + "\x00\xC0\xC0\xC0\x00\x00\x01\x01\x00\x00\xFF\xFF\x00\x01\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80" + "\x80\x80\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFC\x80\xFB\x9C\x8E\x95\x3D\x08\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +}, + +{ + 1108, + "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00\x00\x10\x00\x00\x00\x10\x08" + "\x06\x00\x00\x00\x1F\xF3\xFF\x61\x00\x00\x04\x1B\x49\x44\x41\x54\x18\x19\x01\x10\x04\xEF\xFB\x01\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\x81\x80\x80\x00\x7F\x80\x80\x00\x00\x00" + "\x00\x00\x81\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x80\x80\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00" + "\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xC0\xC0\xC0\xFF\xFF\xFF\xFF\xFF\x80\x80\x80\xFF\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\xFF\x00\x00\xFF\xFF\x00\x00\xFF\x00\x00\x00\x00\x00\xFF\xFF\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x01\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xC0\xC0\xC0\x00\x00\x00\x00\x00\x02\x01" + "\x00\x00\x01\xC1\xC0\xC0\x00\x81\x80\x80\x00\x01\x01\x01\x00\x01\x01\x01\x00\x80\x80\x80\x00\x01\xFF" + "\xFF\x00\x80\x80\x80\x00\xC1\xC1\xC1\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\x80\x80\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC0\xC0\xC0\xFF\x00" + "\x00\x00\xFF\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01\x01\xFF\x80\x80\x80\x00\x80" + "\x80\x80\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\x00\x00\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x01\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x40\x40\x40\xFF\xFF\xFF\xFF\x00\x01\x01\x01\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\x00\x01\x01\x01\x00\xFF\xFF\xFF\x00\xC1\xC1\xC1\x00\x3F\x3F\xFF\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xC0\xC0\xC0\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00\x00\x01\x01\x00\x00\x7F\x7F\x00\x00\x80\x80\x00\x01" + "\x01\x01\x00\xC0\xC0\xC0\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\xFF\xFF\xFF\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x80\x7F\x7F\x00\x00\xFF\xFF" + "\x00\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\xC1\xC1\xC1\x00\x80\x80\x80\x00" + "\x00\x7F\x7F\x00\x80\x81\x81\x00\x00\x01\x01\x00\x00\x01\x01\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x80\x80\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\x00\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xC0\xC0\xC0\xFF\x00\x00\x00\xFF\x02\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC1\xC1\xC1\x00\xC1\xC1\xC0\x00\xC1\xC1\xC1" + "\x00\xC0\xC0\xC0\x00\x00\x01\x01\x00\x00\xFF\xFF\x00\x01\x01\x01\x00\x00\x00\x00\x00\xFF\xFF\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80" + "\x80\x80\x00\x00\x00\x00\x00\x80\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x98\x02\xAF\x81\x39\xA0\x85\x00\x00\x00\x00" + "\x49\x45\x4E\x44\xAE\x42\x60\x82" +} + +}; + + +LCHMTocImageKeeper::LCHMTocImageKeeper( ) +{ + for ( int i = 0; i < LCHMBookIcons::MAX_BUILTIN_ICONS; i++ ) + { + const png_memory_image_t * image = png_image_bookarray + i; + + if ( !m_images[i].loadFromData ((const uchar*)image->data, image->size, "PNG") ) + qFatal ( "Could not load image %d", i ); + } +} + +const QPixmap * LCHMTocImageKeeper::getImage( int id ) +{ + if ( id < 0 || id > LCHMBookIcons::MAX_BUILTIN_ICONS ) + qFatal("LCHMTocImageKeeper::getImage: requested image id (%d) is out of range (%d)", id, LCHMBookIcons::MAX_BUILTIN_ICONS ); + + return &m_images[id]; +} diff --git a/lib/libchmfile/libchmtocimage.h b/lib/libchmfile/libchmtocimage.h new file mode 100644 index 0000000..73f84da --- /dev/null +++ b/lib/libchmfile/libchmtocimage.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + + +//! This class is used to retrieve the book TOC icons associated with images +class LCHMTocImageKeeper +{ + public: + LCHMTocImageKeeper(); + const QPixmap * getImage( int id ); + + private: + QPixmap m_images[LCHMBookIcons::MAX_BUILTIN_ICONS]; +}; diff --git a/lib/libchmfile/libchmurlfactory.h b/lib/libchmfile/libchmurlfactory.h new file mode 100644 index 0000000..29ac433 --- /dev/null +++ b/lib/libchmfile/libchmurlfactory.h @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <qdir.h> +#include <qstring.h> +#include <qregexp.h> + +namespace LCHMUrlFactory +{ + +static inline bool isRemoteURL( const QString & url, QString & protocol ) +{ + // Check whether the URL is external + QRegExp uriregex ( "^(\\w+):\\/\\/" ); + QRegExp mailtoregex ( "^(mailto):" ); + + // mailto: can also have different format, so handle it + if ( url.startsWith( "mailto:" ) ) + { + protocol = "mailto"; + return true; + } + else if ( uriregex.search ( url ) != -1 ) + { + QString proto = uriregex.cap ( 1 ).lower(); + + // Filter the URLs which need to be opened by a browser + if ( proto == "http" + || proto == "ftp" + || proto == "mailto" + || proto == "news" ) + { + protocol = proto; + return true; + } + } + + return false; +} + +// Some JS urls start with javascript:// +static inline bool isJavascriptURL( const QString & url ) +{ + return url.startsWith ("javascript://"); +} + +// Parse urls like "ms-its:file name.chm::/topic.htm" +static inline bool isNewChmURL( const QString & url, QString & chmfile, QString & page ) +{ + QRegExp uriregex ( "^ms-its:(.*)::(.*)$" ); + + if ( uriregex.search ( url ) != -1 ) + { + chmfile = uriregex.cap ( 1 ); + page = uriregex.cap ( 2 ); + + return true; + } + + return false; +} + +static inline QString makeURLabsoluteIfNeeded( const QString & url ) +{ + QString p1, p2, newurl = url; + + if ( !isRemoteURL (url, p1) + && !isJavascriptURL (url) + && !isNewChmURL (url, p1, p2) ) + { + newurl = QDir::cleanDirPath (url); + + // Normalize url, so it becomes absolute + if ( newurl[0] != '/' ) + newurl = "/" + newurl; + } + + //qDebug ("makeURLabsolute (%s) -> (%s)", url.ascii(), newurl.ascii()); + return newurl; +} + + +// Returns a special string, which allows the kio-slave, or viewwindow-browser iteraction +// to regognize our own internal urls, which is necessary to show image-only pages. +static inline QString getInternalUriExtension() +{ + return ".KCHMVIEWER_SPECIAL_HANDLER"; +} + + +static inline bool handleFileType( const QString& link, QString& generated ) +{ + QString intext = getInternalUriExtension(); + + if ( !link.endsWith( intext ) ) + return false; + + QString filelink = link.left( link.length() - strlen( intext ) ); + generated = "<html><body><img src=\"" + filelink + "\"></body></html>"; + return true; +} + + +}; diff --git a/lib/libchmfile/qt34.cpp b/lib/libchmfile/qt34.cpp new file mode 100644 index 0000000..fd7028a --- /dev/null +++ b/lib/libchmfile/qt34.cpp @@ -0,0 +1,259 @@ +/*************************************************************************** + * Copyright (C) 2007 by Albert Astals Cid, aacid@kde.org * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include <qdir.h> + +#include "qt34.h" + +LIBCHMCString::LIBCHMCString() +{ +} + +LIBCHMCString::LIBCHMCString(const char *string) +{ +#if defined (USE_QT_4) + cs = QByteArray(string); +#else + cs = QCString(string); +#endif +} + + +const char *LIBCHMCString::toCString() const +{ + return cs.data(); +} + + +void LIBCHMCString::clear() +{ +#if defined (USE_QT_4) + cs = QByteArray(); +#else + cs = QCString(); +#endif +} + +bool LIBCHMCString::operator==(const QString &string) const +{ + return QString(cs) == string; +} + +uint LIBCHMCString::length() const +{ + return cs.length(); +} + +bool LIBCHMCString::isEmpty() const +{ + return cs.isEmpty(); +} + +void LIBCHMCString::prepend(char c) +{ + cs = c + cs; +} + +char LIBCHMCString::at(uint i) const +{ + return cs.at(i); +} + +void LIBCHMCString::replace(uint index, uint len, const char *str) +{ + cs.replace(index, len, str); +} + +void LIBCHMCString::remove(uint index, uint len) +{ + cs.remove(index, len); +} + +LIBCHMCString LIBCHMCString::lower() +{ +#if defined (USE_QT_4) + return cs.toLower().data(); +#else + return cs.lower().data(); +#endif +} + + + +LIBCHMRegExp::LIBCHMRegExp(const QString ®exp) +{ + re = QRegExp(regexp); +} + +int LIBCHMRegExp::search(const QString &str, int offset) +{ +#if defined (USE_QT_4) + return re.indexIn(str, offset); +#else + return re.search(str, offset); +#endif +} + +QString LIBCHMRegExp::cap(int nth) +{ + return re.cap(nth); +} + +void LIBCHMRegExp::setMinimal(bool minimal) +{ + return re.setMinimal(minimal); +} + +int LIBCHMRegExp::matchedLength() const +{ + return re.matchedLength(); +} + + + + +LIBCHMString::LIBCHMString() +{ +} + +LIBCHMString::LIBCHMString(const QString &string) +{ + s = string; +} + +LIBCHMString::LIBCHMString(const char *string) +{ + s = QString(string); +} + +QString LIBCHMString::lower() const +{ +#if defined (USE_QT_4) + return s.toLower(); +#else + return s.lower(); +#endif +} + +const char *LIBCHMString::ascii() const +{ +#if defined (USE_QT_4) + return s.toAscii(); +#else + return s.ascii(); +#endif +} + +int LIBCHMString::find(char c, int index) const +{ +#if defined (USE_QT_4) + return s.indexOf(c, index); +#else + return s.find(c, index); +#endif +} + +int LIBCHMString::find(const QChar &c, int index) const +{ +#if defined (USE_QT_4) + return s.indexOf(c, index); +#else + return s.find(c, index); +#endif +} + +int LIBCHMString::find(const QString &string, int index, bool cs) const +{ +#if defined (USE_QT_4) + Qt::CaseSensitivity cse; + if (cs) cse = Qt::CaseSensitive; + else cse = Qt::CaseInsensitive; + return s.indexOf(string, index, cse); +#else + return s.find(string, index, cs); +#endif +} + +int LIBCHMString::findRev(char c) const +{ +#if defined (USE_QT_4) + return s.lastIndexOf(c); +#else + return s.findRev(c); +#endif +} + +QChar LIBCHMString::at(uint i) const +{ + return s.at(i); +} + +QString LIBCHMString::left(uint len) const +{ + return s.left(len); +} + +LIBCHMString LIBCHMString::mid(uint index, uint len) const +{ + return s.mid(index, len); +} + +bool LIBCHMString::isEmpty() const +{ + return s.isEmpty(); +} + +QString LIBCHMString::toString() const +{ + return s; +} + +bool LIBCHMString::operator==(const QString &string) const +{ + return s == string; +} + + + +QString LIBCHMDir::cleanDirPath(const QString &dir) +{ +#if defined (USE_QT_4) + return QDir::cleanPath(dir); +#else + return QDir::cleanDirPath(dir); +#endif +} + + + +bool LIBCHMStringList::contains(const QStringList &list, const QString &string) +{ + return list.contains(string); +} + +QStringList LIBCHMStringList::split(const QRegExp ®exp, const QString &string) +{ +#if defined (USE_QT_4) + return string.split(regexp, QString::SkipEmptyParts); +#else + return QStringList::split(regexp, string); +#endif +} diff --git a/lib/libchmfile/qt34.h b/lib/libchmfile/qt34.h new file mode 100644 index 0000000..0835b0a --- /dev/null +++ b/lib/libchmfile/qt34.h @@ -0,0 +1,123 @@ +/*************************************************************************** + * Copyright (C) 2007 by Albert Astals Cid, aacid@kde.org * + * Please do not use email address above for bug reports; see * + * the README file * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#ifndef INCLUDE_QT34_H +#define INCLUDE_QT34_H + +#include <qregexp.h> +#include <qstring.h> + +// Qt3/Qt4 compatibility: in Qt3 QVector stores pointers, not values - so QValueVector should be used. +// In Qt4 QVector stores values, so we can use QVector +#if defined (USE_QT_4) + #define LIBCHMVector QVector +#else +#include <qvaluevector.h> + #define LIBCHMVector QValueVector +#endif + +#if defined (USE_QT_4) + #define LIBCHMMemArray QVector +#else + #define LIBCHMMemArray QMemArray +#endif + +class LIBCHMCString +{ + public: + LIBCHMCString(); + LIBCHMCString(const char *string); + + const char *toCString() const; + + void clear(); + + bool operator==(const QString &string) const; + uint length() const; + bool isEmpty() const; + void prepend(char c); + char at(uint i) const; + void replace(uint index, uint len, const char *str); + void remove(uint index, uint len); + LIBCHMCString lower(); + + private: +#if defined (USE_QT_4) + QByteArray cs; +#else + QCString cs; +#endif +}; + +class LIBCHMRegExp +{ + public: + LIBCHMRegExp(const QString ®exp); + + int search(const QString &str, int offset = 0); + QString cap(int nth); + void setMinimal(bool minimal); + int matchedLength() const; + + private: + QRegExp re; +}; + +class LIBCHMString +{ + public: + LIBCHMString(); + LIBCHMString(const QString &string); + LIBCHMString(const char *string); + + QString lower() const; + const char *ascii() const; + int find(char c, int index = -1) const; + int find(const QChar &c, int index) const; + int find(const QString &string, int index, bool cs) const; + int findRev(char c) const; + QChar at(uint i) const; + QString left(uint len) const; + LIBCHMString mid(uint index, uint len = 0xffffffff) const; + bool isEmpty() const; + + QString toString() const; + + bool operator==(const QString &string) const; + + private: + QString s; +}; + +class LIBCHMDir +{ + public: + static QString cleanDirPath(const QString &dir); +}; + +class LIBCHMStringList +{ + public: + static bool contains(const QStringList &list, const QString &string); + static QStringList split(const QRegExp ®exp, const QString &string); +}; + +#endif |