loganalyzer-3.6.5/0000755000175000017500000000000012225176641013334 5ustar danieldanielloganalyzer-3.6.5/COPYING0000644000175000017500000010525112225176641014373 0ustar danieldanielThis work is released to the free software world via the GNU GPLv3, which can be found below. However, Adiscon GmbH also offers commercial licenses for those in the need. For questions, please contact info@adiscon.com or visit http://loganalyzer.adiscon.com/commercial ------------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . loganalyzer-3.6.5/contrib/0000755000175000017500000000000012225176641014774 5ustar danieldanielloganalyzer-3.6.5/contrib/secure.sh0000644000175000017500000000003712225176641016616 0ustar danieldaniel#!/bin/sh chmod 644 config.php loganalyzer-3.6.5/contrib/configure.sh0000644000175000017500000000006112225176641017306 0ustar danieldaniel#!/bin/sh touch config.php chmod 666 config.php loganalyzer-3.6.5/src/0000755000175000017500000000000012225177166014126 5ustar danieldanielloganalyzer-3.6.5/src/include/0000755000175000017500000000000012225176641015546 5ustar danieldanielloganalyzer-3.6.5/src/include/functions_common.php0000644000175000017500000023024412225176641021644 0ustar danieldaniel * * * * All directives are explained within this file * * * Copyright (C) 2008-2012 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes include_once($gl_root_path . 'include/constants_general.php'); include_once($gl_root_path . 'include/constants_logstream.php'); include_once($gl_root_path . 'classes/class_template.php'); include_once($gl_root_path . 'include/functions_themes.php'); include_once($gl_root_path . 'include/functions_db.php'); include_once($gl_root_path . 'include/functions_config.php'); // --- // --- Define Basic vars $RUNMODE = RUNMODE_WEBSERVER; $DEBUGMODE = DEBUG_INFO; // --- Change some runtime variables // Disable ARGV setting @webserver! @ini_set( "register_argc_argv", "Off" ); // Enable error tracking @ini_set( "track_errors", "On" ); // --- // Default language $LANG_EN = "en"; // Used for fallback $LANG = "en"; // Default language // Default Template vars $content['BUILDNUMBER'] = "3.6.5"; $content['UPDATEURL'] = "http://loganalyzer.adiscon.com/files/version.txt"; $content['TITLE'] = "Adiscon LogAnalyzer :: Release " . $content['BUILDNUMBER']; // Default page title $content['BASEPATH'] = $gl_root_path; $content['SHOW_DONATEBUTTON'] = true; // Default = true! // Hardcoded DEFINES define('URL_ONLINEREPORTS', 'http://tools.adiscon.net/listreports.php'); // PreInit overall user variables $content['EXTRA_PHPLOGCON_LOGO'] = $content['BASEPATH'] . "images/main/Header-Logo.png"; $content['EXTRA_METATAGS'] = ""; $content['EXTRA_JAVASCRIPT'] = ""; $content['EXTRA_STYLESHEET'] = ""; $content['EXTRA_HTMLHEAD'] = ""; $content['EXTRA_HEADER'] = ""; $content['EXTRA_FOOTER'] = ""; $content['CURRENTURL'] = ""; // --- // --- Check PHP Version! If lower the 5, LogAnalyzer will not work proberly! $myPhpVer = phpversion(); $myPhpVerArray = explode('.', $myPhpVer); if ( $myPhpVerArray[0] < 5 ) DieWithErrorMsg( 'Error, the PHP Version on this Server does not meet the installation requirements.
PHP5 or higher is needed. Current installed Version is: ' . $myPhpVer . ''); // --- function InitBasicPhpLogCon() { // Needed to make global global $gl_root_path, $content; // Check RunMode first! CheckAndSetRunMode(); // Set the default line sep SetLineBreakVar(); // Start the PHP Session StartPHPSession(); // Init View Configs prior loading config.php! InitViewConfigs(); } function InitUserSystemPhpLogCon() { // global vars needed global $gl_root_path, $content; if ( GetConfigSetting("UserDBEnabled", false) ) { // Include User Functions include_once($gl_root_path . 'include/functions_users.php'); } } function CheckForInstallPhp() { global $content; // Check for installscript! if ( file_exists($content['BASEPATH'] . "install.php") ) $strinstallmsg = '

' . '
Click here to Install Adiscon LogAnalyzer!

' // . 'See the Installation Guides for more Details!
' // . 'English Installation Guide | ' // . 'German Installation Guide

' // . 'Also take a look to the Readme for some basics around LogAnalyzer!
' . '
'; else $strinstallmsg = ""; DieWithErrorMsg( 'Error, main configuration file is missing!' . $strinstallmsg ); } function GetFileLength($szFileName) { if ( is_file($szFileName) ) return filesize($szFileName); else return 0; } function InitPhpLogCon() { // Needed to make global global $gl_root_path, $content, $CFG; // Abort if already defined if ( defined('PHPLOGCON_INITIALIZED') ) return; // Init Basics which do not need a database InitBasicPhpLogCon(); // Will init the config file! InitPhpLogConConfigFile(); // Init UserDB related stuff! InitUserSystemPhpLogCon(); // Establish DB Connection if ( GetConfigSetting("UserDBEnabled", false) ) DB_Connect(); // Now load the Page configuration values InitConfigurationValues(); // Moved here, because we do not need if GZIP needs to be enabled before the config is loaded! InitRuntimeInformations(); // Now Create Themes List because we haven't the config before! CreateThemesList(); // Create Language List CreateLanguageList(); // Init Predefined Searches List CreatePredefinedSearches(); // Init predefined paging sizes CreatePagesizesList(); // Init predefined reload times CreateReloadTimesList(); // Init predefined reload times CreateExportFormatList(); // --- Enable PHP Debug Mode InitPhpDebugMode(); // --- // --- Init Allowed directories for DiskSources InitDiskAllowedSources(); // --- // --- Check and Remove Magic Quotes! RemoveMagicQuotes(); // --- // Finally defined PHPLOGCON_INITIALIZED! define( 'PHPLOGCON_INITIALIZED', TRUE ); } function CreateLogLineTypesList( $selectedType ) { global $content; // syslog $content['LOGLINETYPES']["syslog"]['type'] = "syslog"; $content['LOGLINETYPES']["syslog"]['DisplayName'] = "Syslog / RSyslog"; if ( $selectedType == $content['LOGLINETYPES']["syslog"]['type'] ) { $content['LOGLINETYPES']["syslog"]['selected'] = "selected"; } else { $content['LOGLINETYPES']["syslog"]['selected'] = ""; } // Adiscon Winsyslog $content['LOGLINETYPES']["winsyslog"]['type'] = "winsyslog"; $content['LOGLINETYPES']["winsyslog"]['DisplayName'] = "Adiscon WinSyslog"; if ( $selectedType == $content['LOGLINETYPES']["winsyslog"]['type'] ) { $content['LOGLINETYPES']["winsyslog"]['selected'] = "selected"; } else { $content['LOGLINETYPES']["winsyslog"]['selected'] = ""; } // Misc logline Types $content['LOGLINETYPES']["misc"]['type'] = "misc"; $content['LOGLINETYPES']["misc"]['DisplayName'] = "Miscellaneous logfiles"; if ( $selectedType == $content['LOGLINETYPES']["misc"]['type'] ) { $content['LOGLINETYPES']["misc"]['selected'] = "selected"; } else { $content['LOGLINETYPES']["misc"]['selected'] = ""; } // RSyslog Format23 $content['LOGLINETYPES']["syslog23"]['type'] = "syslog23"; $content['LOGLINETYPES']["syslog23"]['DisplayName'] = "RSyslog Format23 (RFC 5424)"; if ( $selectedType == $content['LOGLINETYPES']["syslog23"]['type'] ) { $content['LOGLINETYPES']["syslog23"]['selected'] = "selected"; } else { $content['LOGLINETYPES']["syslog23"]['selected'] = ""; } // Syslog-NG $content['LOGLINETYPES']["syslogng"]['type'] = "syslogng"; $content['LOGLINETYPES']["syslogng"]['DisplayName'] = "Syslog NG Format (Custom)"; if ( $selectedType == $content['LOGLINETYPES']["syslogng"]['type'] ) { $content['LOGLINETYPES']["syslogng"]['selected'] = "selected"; } else { $content['LOGLINETYPES']["syslogng"]['selected'] = ""; } } function CreateSourceTypesList( $selectedSource ) { global $content; // SOURCE_DISK $content['SOURCETYPES'][SOURCE_DISK]['type'] = SOURCE_DISK; $content['SOURCETYPES'][SOURCE_DISK]['DisplayName'] = $content['LN_GEN_SOURCE_DISK']; if ( $selectedSource == $content['SOURCETYPES'][SOURCE_DISK]['type'] ) { $content['SOURCETYPES'][SOURCE_DISK]['selected'] = "selected"; } else { $content['SOURCETYPES'][SOURCE_DISK]['selected'] = ""; } // SOURCE_DB ( MYSQL NATIVE ) $content['SOURCETYPES'][SOURCE_DB]['type'] = SOURCE_DB; $content['SOURCETYPES'][SOURCE_DB]['DisplayName'] = $content['LN_GEN_SOURCE_DB']; if ( $selectedSource == $content['SOURCETYPES'][SOURCE_DB]['type'] ) { $content['SOURCETYPES'][SOURCE_DB]['selected'] = "selected"; } else { $content['SOURCETYPES'][SOURCE_DB]['selected'] = ""; } // SOURCE_PDO ( PDO DB Wrapper) $content['SOURCETYPES'][SOURCE_PDO]['type'] = SOURCE_PDO; $content['SOURCETYPES'][SOURCE_PDO]['DisplayName'] = $content['LN_GEN_SOURCE_PDO']; if ( $selectedSource == $content['SOURCETYPES'][SOURCE_PDO]['type'] ) { $content['SOURCETYPES'][SOURCE_PDO]['selected'] = "selected"; } else { $content['SOURCETYPES'][SOURCE_PDO]['selected'] = ""; } // SOURCE_MONGODB ( MONGODB Wrapper) $content['SOURCETYPES'][SOURCE_MONGODB]['type'] = SOURCE_MONGODB; $content['SOURCETYPES'][SOURCE_MONGODB]['DisplayName'] = $content['LN_GEN_SOURCE_MONGODB']; if ( $selectedSource == $content['SOURCETYPES'][SOURCE_MONGODB]['type'] ) { $content['SOURCETYPES'][SOURCE_MONGODB]['selected'] = "selected"; } else { $content['SOURCETYPES'][SOURCE_MONGODB]['selected'] = ""; } } function CreateAuthTypesList( $selectedAuth ) { global $content; // SOURCE_DISK $content['AUTHTYPES'][USERDB_AUTH_INTERNAL]['type'] = USERDB_AUTH_INTERNAL; $content['AUTHTYPES'][USERDB_AUTH_INTERNAL]['DisplayName'] = $content['LN_GEN_AUTH_INTERNAL']; if ( $selectedAuth == $content['AUTHTYPES'][USERDB_AUTH_INTERNAL]['type'] ) { $content['AUTHTYPES'][USERDB_AUTH_INTERNAL]['selected'] = "selected"; } else { $content['AUTHTYPES'][USERDB_AUTH_INTERNAL]['selected'] = ""; } // SOURCE_DB ( MYSQL NATIVE ) $content['AUTHTYPES'][USERDB_AUTH_LDAP]['type'] = USERDB_AUTH_LDAP; $content['AUTHTYPES'][USERDB_AUTH_LDAP]['DisplayName'] = $content['LN_GEN_AUTH_LDAP']; if ( $selectedAuth == $content['AUTHTYPES'][USERDB_AUTH_LDAP]['type'] ) { $content['AUTHTYPES'][USERDB_AUTH_LDAP]['selected'] = "selected"; } else { $content['AUTHTYPES'][USERDB_AUTH_LDAP]['selected'] = ""; } } function CreateFieldAlignmentList( $selectedAlignment ) { global $content; // ALIGN_CENTER $content['ALIGMENTS'][ALIGN_CENTER]['type'] = ALIGN_CENTER; $content['ALIGMENTS'][ALIGN_CENTER]['DisplayName'] = $content['LN_ALIGN_CENTER']; if ( $selectedAlignment == $content['ALIGMENTS'][ALIGN_CENTER]['type'] ) { $content['ALIGMENTS'][ALIGN_CENTER]['selected'] = "selected"; } else { $content['ALIGMENTS'][ALIGN_CENTER]['selected'] = ""; } // ALIGN_LEFT $content['ALIGMENTS'][ALIGN_LEFT]['type'] = ALIGN_LEFT; $content['ALIGMENTS'][ALIGN_LEFT]['DisplayName'] = $content['LN_ALIGN_LEFT']; if ( $selectedAlignment == $content['ALIGMENTS'][ALIGN_LEFT]['type'] ) { $content['ALIGMENTS'][ALIGN_LEFT]['selected'] = "selected"; } else { $content['ALIGMENTS'][ALIGN_LEFT]['selected'] = ""; } // ALIGN_RIGHT $content['ALIGMENTS'][ALIGN_RIGHT]['type'] = ALIGN_RIGHT; $content['ALIGMENTS'][ALIGN_RIGHT]['DisplayName'] = $content['LN_ALIGN_RIGHT']; if ( $selectedAlignment == $content['ALIGMENTS'][ALIGN_RIGHT]['type'] ) { $content['ALIGMENTS'][ALIGN_RIGHT]['selected'] = "selected"; } else { $content['ALIGMENTS'][ALIGN_RIGHT]['selected'] = ""; } } function CreateFieldTypesList( $selectedType ) { global $content; // FILTER_TYPE_STRING $content['FILTERTYPES'][FILTER_TYPE_STRING]['type'] = FILTER_TYPE_STRING; $content['FILTERTYPES'][FILTER_TYPE_STRING]['DisplayName'] = $content['LN_FILTER_TYPE_STRING']; if ( $selectedType == $content['FILTERTYPES'][FILTER_TYPE_STRING]['type'] ) { $content['FILTERTYPES'][FILTER_TYPE_STRING]['selected'] = "selected"; } else { $content['FILTERTYPES'][FILTER_TYPE_STRING]['selected'] = ""; } // FILTER_TYPE_NUMBER $content['FILTERTYPES'][FILTER_TYPE_NUMBER]['type'] = FILTER_TYPE_NUMBER; $content['FILTERTYPES'][FILTER_TYPE_NUMBER]['DisplayName'] = $content['LN_FILTER_TYPE_NUMBER']; if ( $selectedType == $content['FILTERTYPES'][FILTER_TYPE_NUMBER]['type'] ) { $content['FILTERTYPES'][FILTER_TYPE_NUMBER]['selected'] = "selected"; } else { $content['FILTERTYPES'][FILTER_TYPE_NUMBER]['selected'] = ""; } // FILTER_TYPE_DATE $content['FILTERTYPES'][FILTER_TYPE_DATE]['type'] = FILTER_TYPE_DATE; $content['FILTERTYPES'][FILTER_TYPE_DATE]['DisplayName'] = $content['LN_FILTER_TYPE_DATE']; if ( $selectedType == $content['FILTERTYPES'][FILTER_TYPE_DATE]['type'] ) { $content['FILTERTYPES'][FILTER_TYPE_DATE]['selected'] = "selected"; } else { $content['FILTERTYPES'][FILTER_TYPE_DATE]['selected'] = ""; } } function CreateChartTypesList( $selectedChart ) { global $content; // CHART_CAKE $content['CHARTTYPES'][CHART_CAKE]['type'] = CHART_CAKE; $content['CHARTTYPES'][CHART_CAKE]['DisplayName'] = $content['LN_CHART_TYPE_CAKE']; if ( $selectedChart == $content['CHARTTYPES'][CHART_CAKE]['type'] ) { $content['CHARTTYPES'][CHART_CAKE]['selected'] = "selected"; } else { $content['CHARTTYPES'][CHART_CAKE]['selected'] = ""; } // CHART_BARS_VERTICAL $content['CHARTTYPES'][CHART_BARS_VERTICAL]['type'] = CHART_BARS_VERTICAL; $content['CHARTTYPES'][CHART_BARS_VERTICAL]['DisplayName'] = $content['LN_CHART_TYPE_BARS_VERTICAL']; if ( $selectedChart == $content['CHARTTYPES'][CHART_BARS_VERTICAL]['type'] ) { $content['CHARTTYPES'][CHART_BARS_VERTICAL]['selected'] = "selected"; } else { $content['CHARTTYPES'][CHART_BARS_VERTICAL]['selected'] = ""; } // CHART_BARS_HORIZONTAL $content['CHARTTYPES'][CHART_BARS_HORIZONTAL]['type'] = CHART_BARS_HORIZONTAL; $content['CHARTTYPES'][CHART_BARS_HORIZONTAL]['DisplayName'] = $content['LN_CHART_TYPE_BARS_HORIZONTAL']; if ( $selectedChart == $content['CHARTTYPES'][CHART_BARS_HORIZONTAL]['type'] ) { $content['CHARTTYPES'][CHART_BARS_HORIZONTAL]['selected'] = "selected"; } else { $content['CHARTTYPES'][CHART_BARS_HORIZONTAL]['selected'] = ""; } } function CreateChartFields( $selectedChartField) { global $content, $fields; // Process all fields foreach ( $fields as $myField ) { $myFieldID = $myField['FieldID']; // Add new entry to array $content['CHARTFIELDS'][$myFieldID]['ID'] = $myFieldID; if ( isset($myField['FieldCaption']) ) $content['CHARTFIELDS'][$myFieldID]['DisplayName'] = $myField['FieldCaption']; else $content['CHARTFIELDS'][$myFieldID]['DisplayName'] = $myFieldID; // set selected state if ( $selectedChartField == $content['CHARTFIELDS'][$myFieldID]['ID'] ) { $content['CHARTFIELDS'][$myFieldID]['selected'] = "selected"; } else { $content['CHARTFIELDS'][$myFieldID]['selected'] = ""; } } } /* * Helper function to generate a dbmappings list */ function CreateDBMappingsList( $selectedDBTableType ) { global $content, $dbmapping; // Process all mappings foreach ( $dbmapping as $mykey => $myMapping ) { $content['DBMAPPINGS'][$mykey]['type'] = $mykey; if ( isset($myMapping['DisplayName']) ) {$content['DBMAPPINGS'][$mykey]['DisplayName'] = $myMapping['DisplayName']; } else { $content['DBMAPPINGS'][$mykey]['DisplayName'] = $mykey; } if ( $selectedDBTableType == $mykey ) { $content['DBMAPPINGS'][$mykey]['selected'] = "selected"; } else { $content['DBMAPPINGS'][$mykey]['selected'] = ""; } } } function CreateDBTypesList( $selectedDBType ) { global $content; // DB_MYSQL $content['DBTYPES'][DB_MYSQL]['type'] = DB_MYSQL; $content['DBTYPES'][DB_MYSQL]['typeastext'] = "DB_MYSQL"; $content['DBTYPES'][DB_MYSQL]['DisplayName'] = $content['LN_GEN_DB_MYSQL']; if ( $selectedDBType == $content['DBTYPES'][DB_MYSQL]['type'] ) { $content['DBTYPES'][DB_MYSQL]['selected'] = "selected"; } else { $content['DBTYPES'][DB_MYSQL]['selected'] = ""; } // DB_MSSQL $content['DBTYPES'][DB_MSSQL]['type'] = DB_MSSQL; $content['DBTYPES'][DB_MSSQL]['typeastext'] = "DB_MSSQL"; $content['DBTYPES'][DB_MSSQL]['DisplayName'] = $content['LN_GEN_DB_MSSQL']; if ( $selectedDBType == $content['DBTYPES'][DB_MSSQL]['type'] ) { $content['DBTYPES'][DB_MSSQL]['selected'] = "selected"; } else { $content['DBTYPES'][DB_MSSQL]['selected'] = ""; } // DB_ODBC $content['DBTYPES'][DB_ODBC]['type'] = DB_ODBC; $content['DBTYPES'][DB_ODBC]['typeastext'] = "DB_ODBC"; $content['DBTYPES'][DB_ODBC]['DisplayName'] = $content['LN_GEN_DB_ODBC']; if ( $selectedDBType == $content['DBTYPES'][DB_ODBC]['type'] ) { $content['DBTYPES'][DB_ODBC]['selected'] = "selected"; } else { $content['DB_ODBC'][DB_ODBC]['selected'] = ""; } // DB_PGSQL $content['DBTYPES'][DB_PGSQL]['type'] = DB_PGSQL; $content['DBTYPES'][DB_PGSQL]['typeastext'] = "DB_PGSQL"; $content['DBTYPES'][DB_PGSQL]['DisplayName'] = $content['LN_GEN_DB_PGSQL']; if ( $selectedDBType == $content['DBTYPES'][DB_PGSQL]['type'] ) { $content['DBTYPES'][DB_PGSQL]['selected'] = "selected"; } else { $content['DB_ODBC'][DB_PGSQL]['selected'] = ""; } // DB_OCI $content['DBTYPES'][DB_OCI]['type'] = DB_OCI; $content['DBTYPES'][DB_OCI]['typeastext'] = "DB_OCI"; $content['DBTYPES'][DB_OCI]['DisplayName'] = $content['LN_GEN_DB_OCI']; if ( $selectedDBType == $content['DBTYPES'][DB_OCI]['type'] ) { $content['DBTYPES'][DB_OCI]['selected'] = "selected"; } else { $content['DB_ODBC'][DB_OCI]['selected'] = ""; } // DB_DB2 $content['DBTYPES'][DB_DB2]['type'] = DB_DB2; $content['DBTYPES'][DB_DB2]['typeastext'] = "DB_DB2"; $content['DBTYPES'][DB_DB2]['DisplayName'] = $content['LN_GEN_DB_DB2']; if ( $selectedDBType == $content['DBTYPES'][DB_DB2]['type'] ) { $content['DBTYPES'][DB_DB2]['selected'] = "selected"; } else { $content['DB_ODBC'][DB_DB2]['selected'] = ""; } // DB_FIREBIRD $content['DBTYPES'][DB_FIREBIRD]['type'] = DB_FIREBIRD; $content['DBTYPES'][DB_FIREBIRD]['typeastext'] = "DB_FIREBIRD"; $content['DBTYPES'][DB_FIREBIRD]['DisplayName'] = $content['LN_GEN_DB_FIREBIRD']; if ( $selectedDBType == $content['DBTYPES'][DB_FIREBIRD]['type'] ) { $content['DBTYPES'][DB_FIREBIRD]['selected'] = "selected"; } else { $content['DB_ODBC'][DB_FIREBIRD]['selected'] = ""; } // DB_INFORMIX $content['DBTYPES'][DB_INFORMIX]['type'] = DB_INFORMIX; $content['DBTYPES'][DB_INFORMIX]['typeastext'] = "DB_INFORMIX"; $content['DBTYPES'][DB_INFORMIX]['DisplayName'] = $content['LN_GEN_DB_INFORMIX']; if ( $selectedDBType == $content['DBTYPES'][DB_INFORMIX]['type'] ) { $content['DBTYPES'][DB_INFORMIX]['selected'] = "selected"; } else { $content['DB_ODBC'][DB_INFORMIX]['selected'] = ""; } // DB_SQLITE $content['DBTYPES'][DB_SQLITE]['type'] = DB_SQLITE; $content['DBTYPES'][DB_SQLITE]['typeastext'] = "DB_SQLITE"; $content['DBTYPES'][DB_SQLITE]['DisplayName'] = $content['LN_GEN_DB_SQLITE']; if ( $selectedDBType == $content['DBTYPES'][DB_SQLITE]['type'] ) { $content['DBTYPES'][DB_SQLITE]['selected'] = "selected"; } else { $content['DB_ODBC'][DB_SQLITE]['selected'] = ""; } } function CreateOutputformatList( $selectedOutputformat ) { global $content; // REPORT_OUTPUT_HTML $content['OUTPUTFORMATS'][REPORT_OUTPUT_HTML]['formatid'] = REPORT_OUTPUT_HTML; $content['OUTPUTFORMATS'][REPORT_OUTPUT_HTML]['formatdisplayname'] = $content['LN_GEN_REPORT_OUTPUT_HTML']; if ( $selectedOutputformat == $content['OUTPUTFORMATS'][REPORT_OUTPUT_HTML]['formatid'] ) { $content['OUTPUTFORMATS'][REPORT_OUTPUT_HTML]['formatselected'] = "selected"; } else { $content['OUTPUTFORMATS'][REPORT_OUTPUT_HTML]['formatselected'] = ""; } // REPORT_OUTPUT_PDF $content['OUTPUTFORMATS'][REPORT_OUTPUT_PDF]['formatid'] = REPORT_OUTPUT_PDF; $content['OUTPUTFORMATS'][REPORT_OUTPUT_PDF]['formatdisplayname'] = $content['LN_GEN_REPORT_OUTPUT_PDF']; if ( $selectedOutputformat == $content['OUTPUTFORMATS'][REPORT_OUTPUT_PDF]['formatid'] ) { $content['OUTPUTFORMATS'][REPORT_OUTPUT_PDF]['formatselected'] = "selected"; } else { $content['OUTPUTFORMATS'][REPORT_OUTPUT_PDF]['formatselected'] = ""; } } function CreateOutputtargetList( $selectedOutputtarget ) { global $content; // REPORT_TARGET_STDOUT $content['OUTPUTTARGETS'][REPORT_TARGET_STDOUT]['targetid'] = REPORT_TARGET_STDOUT; $content['OUTPUTTARGETS'][REPORT_TARGET_STDOUT]['targetdisplayname'] = $content['LN_GEN_REPORT_TARGET_STDOUT']; if ( $selectedOutputtarget == $content['OUTPUTTARGETS'][REPORT_TARGET_STDOUT]['targetid'] ) { $content['OUTPUTTARGETS'][REPORT_TARGET_STDOUT]['targetselected'] = "selected"; } else { $content['OUTPUTTARGETS'][REPORT_TARGET_STDOUT]['targetselected'] = ""; } // REPORT_TARGET_FILE $content['OUTPUTTARGETS'][REPORT_TARGET_FILE]['targetid'] = REPORT_TARGET_FILE; $content['OUTPUTTARGETS'][REPORT_TARGET_FILE]['targetdisplayname'] = $content['LN_GEN_REPORT_TARGET_FILE']; if ( $selectedOutputtarget == $content['OUTPUTTARGETS'][REPORT_TARGET_FILE]['targetid'] ) { $content['OUTPUTTARGETS'][REPORT_TARGET_FILE]['targetselected'] = "selected"; } else { $content['OUTPUTTARGETS'][REPORT_TARGET_FILE]['targetselected'] = ""; } // // REPORT_TARGET_EMAIL // $content['OUTPUTTARGETS'][REPORT_TARGET_EMAIL]['targetid'] = REPORT_TARGET_EMAIL; // $content['OUTPUTTARGETS'][REPORT_TARGET_EMAIL]['targetdisplayname'] = $content['LN_GEN_REPORT_TARGET_EMAIL']; // if ( $selectedOutputtarget == $content['OUTPUTTARGETS'][REPORT_TARGET_EMAIL]['targetid'] ) { $content['OUTPUTTARGETS'][REPORT_TARGET_EMAIL]['targetselected'] = "selected"; } else { $content['OUTPUTTARGETS'][REPORT_TARGET_EMAIL]['targetselected'] = ""; } } function CreatePagesizesList() { global $content; $tmpViewsPerPage = GetConfigSetting("ViewEntriesPerPage", 50, CFGLEVEL_USER); $iCounter = 0; $content['pagesizes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => $content['LN_GEN_PRECONFIGURED'] . " (" . $tmpViewsPerPage . ")", "Value" => $tmpViewsPerPage ); $iCounter++; $content['pagesizes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 25 " . $content['LN_GEN_RECORDSPERPAGE'], "Value" => 25 ); $iCounter++; $content['pagesizes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 50 " . $content['LN_GEN_RECORDSPERPAGE'], "Value" => 50 ); $iCounter++; $content['pagesizes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 75 " . $content['LN_GEN_RECORDSPERPAGE'], "Value" => 75 ); $iCounter++; $content['pagesizes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 100 " . $content['LN_GEN_RECORDSPERPAGE'], "Value" => 100 ); $iCounter++; $content['pagesizes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 250 " . $content['LN_GEN_RECORDSPERPAGE'], "Value" => 250 ); $iCounter++; $content['pagesizes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 500 " . $content['LN_GEN_RECORDSPERPAGE'], "Value" => 500 ); $iCounter++; // Set default selected pagesize $content['pagesizes'][ $_SESSION['PAGESIZE_ID'] ]["Selected"] = "selected"; // The content variable will now contain the user selected oaging size $content["CurrentViewEntriesPerPage"] = $content['pagesizes'][ $_SESSION['PAGESIZE_ID'] ]["Value"]; } function CreateReloadTimesList() { global $content; $iCounter = 0; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => $content['LN_AUTORELOAD_DISABLED'], "Value" => 0 ); $iCounter++; $tmpReloadSeconds = GetConfigSetting("ViewEnableAutoReloadSeconds", "", CFGLEVEL_USER); if ( $tmpReloadSeconds > 0 ) { $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => $content['LN_AUTORELOAD_PRECONFIGURED'] . " (" . $tmpReloadSeconds . " " . $content['LN_AUTORELOAD_SECONDS'] . ") ", "Value" => $tmpReloadSeconds ); $iCounter++; } $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 5 " . $content['LN_AUTORELOAD_SECONDS'], "Value" => 5 ); $iCounter++; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 10 " . $content['LN_AUTORELOAD_SECONDS'], "Value" => 10 ); $iCounter++; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 15 " . $content['LN_AUTORELOAD_SECONDS'], "Value" => 15 ); $iCounter++; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 30 " . $content['LN_AUTORELOAD_SECONDS'], "Value" => 30 ); $iCounter++; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 60 " . $content['LN_AUTORELOAD_SECONDS'], "Value" => 60 ); $iCounter++; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 5 " . $content['LN_AUTORELOAD_MINUTES'], "Value" => 300 ); $iCounter++; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 10 " . $content['LN_AUTORELOAD_MINUTES'], "Value" => 600 ); $iCounter++; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 15 " . $content['LN_AUTORELOAD_MINUTES'], "Value" => 900 ); $iCounter++; $content['reloadtimes'][$iCounter] = array( "ID" => $iCounter, "Selected" => "", "DisplayName" => " 30 " . $content['LN_AUTORELOAD_MINUTES'], "Value" => 1800 ); $iCounter++; // Set default selected autoreloadid $content['reloadtimes'][ $_SESSION['AUTORELOAD_ID'] ]["Selected"] = "selected"; // The content variable will now contain the user selected oaging size $content["ViewEnableAutoReloadSeconds"] = $content['reloadtimes'][ $_SESSION['AUTORELOAD_ID'] ]["Value"]; } function CreateExportFormatList() { global $content; // Add basic formats! $content['EXPORTTYPES'][EXPORT_CVS] = array( "ID" => EXPORT_CVS, "Selected" => "", "DisplayName" => $content['LN_GEN_EXPORT_CVS'] ); $content['EXPORTTYPES'][EXPORT_XML] = array( "ID" => EXPORT_XML, "Selected" => "", "DisplayName" => $content['LN_GEN_EXPORT_XML'] ); // TODO: Add formats by loaded extensions } function CreatePredefinedSearches() { global $CFG, $content; if ( isset($CFG['Search']) ) { // Enable predefined searches $content['EnablePredefinedSearches'] = true; // Loop through all predefined searches! foreach ($CFG['Search'] as $mykey => $mySearch) { // Copy configured searches into content array! $content['Search'][$mykey]["ID"] = $mykey; $content['Search'][$mykey]["Selected"] = false; // --- Set CSS Class if ( $mykey % 2 == 0 ) $content['Search'][$mykey]['cssclass'] = "line1"; else $content['Search'][$mykey]['cssclass'] = "line2"; // --- } } else // Disable predefined searches $content['EnablePredefinedSearches'] = false; } function InitPhpDebugMode() { global $content; // --- Set Global DEBUG Level! if ( GetConfigSetting("MiscShowDebugMsg", 0, CFGLEVEL_USER) == 1 ) ini_set( "error_reporting", E_ALL ); // ALL PHP MESSAGES! else ini_set( "error_reporting", E_ERROR ); // ONLY PHP ERROR'S! // --- } function CheckAndSetRunMode() { global $content, $RUNMODE; // Set to command line mode if argv is set! if ( !isset($_SERVER["SERVER_SOFTWARE"]) ) $RUNMODE = RUNMODE_COMMANDLINE; // Check if we require the command line mode! if ( defined("IN_PHPLOGCON_COMMANDLINE") && $RUNMODE != RUNMODE_COMMANDLINE ) DieWithErrorMsg( "This PHP Script cannot be run within the webserver process, it designed to run over command line." ); // Obtain max_execution_time $content['MaxExecutionTime'] = ini_get("max_execution_time"); // Define and Inits Syslog variables now! // DEPRECIATED! define_syslog_variables(); // Syslog Constants are defined by default anyway! $syslogOpened = openlog("LogAnalyzer", LOG_PID, LOG_USER); // --- Check necessary PHP Extensions! $loadedExtensions = get_loaded_extensions(); // Check for GD libary if ( in_array("gd", $loadedExtensions) ) $content['GD_IS_ENABLED'] = true; else $content['GD_IS_ENABLED'] = false; // Check MYSQL Extension if ( in_array("mysql", $loadedExtensions) ) { $content['MYSQL_IS_ENABLED'] = true; } else { $content['MYSQL_IS_ENABLED'] = false; } // Check PDO Extension if ( in_array("PDO", $loadedExtensions) ) { $content['PDO_IS_ENABLED'] = true; } else { $content['PDO_IS_ENABLED'] = false; } // Check sockets Extension if ( in_array("sockets", $loadedExtensions) ) { $content['SOCKETS_IS_ENABLED'] = true; } else { $content['SOCKETS_IS_ENABLED'] = false; } // --- } /* * This helper function removes all magic quotes from input Parameters! */ function RemoveMagicQuotes() { if (get_magic_quotes_gpc()) { $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); while (list($key, $val) = each($process)) { foreach ($val as $k => $v) { unset($process[$key][$k]); if (is_array($v)) { $process[$key][stripslashes($k)] = $v; $process[] = &$process[$key][stripslashes($k)]; } else { $process[$key][stripslashes($k)] = stripslashes($v); } } } unset($process); } } function InitRuntimeInformations() { global $gl_root_path, $content; // Enable GZIP Compression if enabled! if ( isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false && GetConfigSetting("MiscEnableGzipCompression", 1, CFGLEVEL_USER) == 1 ) { // This starts gzip compression! ob_start("ob_gzhandler"); $content['GzipCompressionEnmabled'] = "yes"; } else $content['GzipCompressionEnmabled'] = "no"; // --- Check and Set manual link if ( is_dir($gl_root_path . "doc") ) $content['PHPLOGCON_HELPLINK'] = $content['BASEPATH'] . "doc/manual.html"; else $content['PHPLOGCON_HELPLINK'] = "http://loganalyzer.adiscon.com/doc"; // --- // --- Try to extend the script timeout if possible! $iTmp = GetConfigSetting("MiscMaxExecutionTime", 30, CFGLEVEL_GLOBAL); if ( $iTmp != $content['MaxExecutionTime'] && $iTmp > 10 ) { //Try to extend the runtime in this case! if ( !isset($content['IN_PHPLOGCON_COMMANDLINE']) ) @ini_set("max_execution_time", $iTmp); // Get ini setting $content['MaxExecutionTime'] = ini_get("max_execution_time"); } // --- // --- Set Database Update Warning if necessary if ( GetConfigSetting("UserDBEnabled", false) && $content['database_internalversion'] > $content['database_installedversion'] && !defined('IS_UPRGADEPAGE') ) { $content['dbupgrade_warning'] = true; $content['WARNING_DBUPGRADE_TEXT'] = GetAndReplaceLangStr( $content['LN_WARNING_DBUPGRADE_TEXT'], $content['database_installedversion'], $content['database_internalversion'] ); } } function CreateDebugModes() { global $content; $content['DBGMODES'][0]['DisplayName'] = STR_DEBUG_ULTRADEBUG; if ( $content['parser_debugmode'] == $content['DBGMODES'][0]['DisplayName'] ) { $content['DBGMODES'][0]['selected'] = "selected"; } else { $content['DBGMODES'][0]['selected'] = ""; } $content['DBGMODES'][1]['DisplayName'] = STR_DEBUG_DEBUG; if ( $content['parser_debugmode'] == $content['DBGMODES'][1]['DisplayName'] ) { $content['DBGMODES'][1]['selected'] = "selected"; } else { $content['DBGMODES'][1]['selected'] = ""; } $content['DBGMODES'][2]['DisplayName'] = STR_DEBUG_INFO; if ( $content['parser_debugmode'] == $content['DBGMODES'][2]['DisplayName'] ) { $content['DBGMODES'][2]['selected'] = "selected"; } else { $content['DBGMODES'][2]['selected'] = ""; } $content['DBGMODES'][3]['DisplayName'] = STR_DEBUG_WARN; if ( $content['parser_debugmode'] == $content['DBGMODES'][3]['DisplayName'] ) { $content['DBGMODES'][3]['selected'] = "selected"; } else { $content['DBGMODES'][3]['selected'] = ""; } $content['DBGMODES'][4]['DisplayName'] = STR_DEBUG_ERROR; if ( $content['parser_debugmode'] == $content['DBGMODES'][4]['DisplayName'] ) { $content['DBGMODES'][4]['selected'] = "selected"; } else { $content['DBGMODES'][4]['selected'] = ""; } } function InitFrontEndVariables() { global $content; $content['MENU_FOLDER_OPEN'] = $content['BASEPATH'] . "images/icons/folder_closed.png"; $content['MENU_FOLDER_CLOSED'] = $content['BASEPATH'] . "images/icons/folder.png"; $content['MENU_HOMEPAGE'] = $content['BASEPATH'] . "images/icons/home.png"; $content['MENU_LINK'] = $content['BASEPATH'] . "images/icons/link.png"; $content['MENU_LINK_VIEW'] = $content['BASEPATH'] . "images/icons/link_view.png"; $content['MENU_VIEW'] = $content['BASEPATH'] . "images/icons/view.png"; $content['MENU_PREFERENCES'] = $content['BASEPATH'] . "images/icons/preferences.png"; $content['MENU_ADMINENTRY'] = $content['BASEPATH'] . "images/icons/star_blue.png"; $content['MENU_ADMINLOGOFF'] = $content['BASEPATH'] . "images/icons/exit.png"; $content['MENU_ADMINUSERS'] = $content['BASEPATH'] . "images/icons/businessman.png"; $content['MENU_ADMINGROUPS'] = $content['BASEPATH'] . "images/icons/businessmen.png"; $content['MENU_SEARCH'] = $content['BASEPATH'] . "images/icons/view.png"; $content['MENU_SELECTION_DISABLED'] = $content['BASEPATH'] . "images/icons/selection.png"; $content['MENU_SELECTION_ENABLED'] = $content['BASEPATH'] . "images/icons/selection_delete.png"; $content['MENU_TEXT_FIND'] = $content['BASEPATH'] . "images/icons/text_find.png"; $content['MENU_EARTH_FIND'] = $content['BASEPATH'] . "images/icons/earth_find.png"; $content['MENU_FIND'] = $content['BASEPATH'] . "images/icons/find.png"; $content['MENU_NEXT_FIND'] = $content['BASEPATH'] . "images/icons/find_next.png"; $content['MENU_NETWORK'] = $content['BASEPATH'] . "images/icons/earth_network.png"; $content['MENU_HELP'] = $content['BASEPATH'] . "images/icons/help.png"; $content['MENU_HELP_BLUE'] = $content['BASEPATH'] . "images/icons/help2.png"; $content['MENU_HELP_ORANGE'] = $content['BASEPATH'] . "images/icons/help3.png"; $content['MENU_KB'] = $content['BASEPATH'] . "images/icons/books.png"; $content['MENU_DOCUMENTVIEW'] = $content['BASEPATH'] . "images/icons/document_view.png"; $content['MENU_DATAEDIT'] = $content['BASEPATH'] . "images/icons/data_edit.png"; $content['MENU_ADDUSER'] = $content['BASEPATH'] . "images/icons/businessman_add.png"; $content['MENU_DELUSER'] = $content['BASEPATH'] . "images/icons/businessman_delete.png"; $content['MENU_ADD'] = $content['BASEPATH'] . "images/icons/add.png"; $content['MENU_EDIT'] = $content['BASEPATH'] . "images/icons/edit.png"; $content['MENU_DELETE'] = $content['BASEPATH'] . "images/icons/delete.png"; $content['MENU_GLOBAL'] = $content['BASEPATH'] . "images/icons/earth.png"; $content['MENU_INTERNAL'] = $content['BASEPATH'] . "images/icons/gear.png"; $content['MENU_EDIT_DISABLED'] = $content['BASEPATH'] . "images/icons/edit_disabled.png"; $content['MENU_DELETE_DISABLED'] = $content['BASEPATH'] . "images/icons/delete_disabled.png"; $content['MENU_MOVE_UP'] = $content['BASEPATH'] . "images/icons/nav_up_blue.png"; $content['MENU_MOVE_DOWN'] = $content['BASEPATH'] . "images/icons/nav_down_blue.png"; $content['MENU_SOURCE_DISK'] = $content['BASEPATH'] . "images/icons/document_text.png"; $content['MENU_SOURCE_DB'] = $content['BASEPATH'] . "images/icons/data_table.png"; $content['MENU_SOURCE_PDO'] = $content['BASEPATH'] . "images/icons/data_gear.png"; $content['MENU_SOURCE_MONGODB'] = $content['BASEPATH'] . "images/icons/mongodb.png"; $content['MENU_MAXIMIZE'] = $content['BASEPATH'] . "images/icons/table_selection_all.png"; $content['MENU_NORMAL'] = $content['BASEPATH'] . "images/icons/table_selection_block.png"; $content['MENU_USEROPTIONS'] = $content['BASEPATH'] . "images/icons/businessman_preferences.png"; $content['MENU_EXPORT'] = $content['BASEPATH'] . "images/icons/export1.png"; $content['MENU_CHARTS'] = $content['BASEPATH'] . "images/icons/line-chart.png"; $content['MENU_CHART_CAKE'] = $content['BASEPATH'] . "images/icons/pie-chart.png"; $content['MENU_CHART_BARSVERT'] = $content['BASEPATH'] . "images/icons/column-chart.png"; $content['MENU_CHART_BARSHORI'] = $content['BASEPATH'] . "images/icons/column-chart-hori.png"; $content['MENU_CHART_PREVIEW'] = $content['BASEPATH'] . "images/icons/pie-chart_view.png"; $content['MENU_FIELDS'] = $content['BASEPATH'] . "images/icons/tables.png"; $content['MENU_DELETE_FROMDB'] = $content['BASEPATH'] . "images/icons/data_delete.png"; $content['MENU_DELETE_FROMDB_DISABLED'] = $content['BASEPATH'] . "images/icons/data_delete_disabled.png"; $content['MENU_INFORMATION'] = $content['BASEPATH'] . "images/icons/information2.png"; $content['MENU_PARSER_DELETE'] = $content['BASEPATH'] . "images/icons/gear_delete.png"; $content['MENU_PARSER_INIT'] = $content['BASEPATH'] . "images/icons/gear_new.png"; $content['MENU_RECYCLE'] = $content['BASEPATH'] . "images/icons/recycle.png"; $content['MENU_TRASH'] = $content['BASEPATH'] . "images/icons/garbage_empty.png"; $content['MENU_REPORTS'] = $content['BASEPATH'] . "images/icons/document_chart.png"; $content['MENU_CHARTPRESENTATION'] = $content['BASEPATH'] . "images/icons/presentation_chart.png"; $content['MENU_NETDOWNLOAD'] = $content['BASEPATH'] . "images/icons/download.png"; $content['MENU_DOCUMENTLIST'] = $content['BASEPATH'] . "images/icons/documents.png"; $content['MENU_WINDOWLIST'] = $content['BASEPATH'] . "images/icons/windows.png"; $content['MENU_CHECKED'] = $content['BASEPATH'] . "images/icons/check.png"; $content['MENU_PLAY_GREEN'] = $content['BASEPATH'] . "images/icons/bullet_triangle_green.png"; $content['MENU_PLAY_GREEN_WINDOW'] = $content['BASEPATH'] . "images/icons/table_sql_run.png"; $content['MENU_PAGER_BEGIN'] = $content['BASEPATH'] . "images/icons/media_beginning.png"; $content['MENU_PAGER_PREVIOUS'] = $content['BASEPATH'] . "images/icons/media_rewind.png"; $content['MENU_PAGER_NEXT'] = $content['BASEPATH'] . "images/icons/media_fast_forward.png"; $content['MENU_PAGER_END'] = $content['BASEPATH'] . "images/icons/media_end.png"; $content['MENU_NAV_LEFT'] = $content['BASEPATH'] . "images/icons/navigate_left.png"; $content['MENU_NAV_RIGHT'] = $content['BASEPATH'] . "images/icons/navigate_right.png"; $content['MENU_NAV_CLOSE'] = $content['BASEPATH'] . "images/icons/navigate_close.png"; $content['MENU_NAV_OPEN'] = $content['BASEPATH'] . "images/icons/navigate_open.png"; $content['MENU_PAGER_BEGIN_GREY'] = $content['BASEPATH'] . "images/icons/grey/media_beginning.png"; $content['MENU_PAGER_PREVIOUS_GREY'] = $content['BASEPATH'] . "images/icons/grey/media_rewind.png"; $content['MENU_PAGER_NEXT_GREY'] = $content['BASEPATH'] . "images/icons/grey/media_fast_forward.png"; $content['MENU_PAGER_END_GREY'] = $content['BASEPATH'] . "images/icons/grey/media_end.png"; $content['MENU_BULLET_BLUE'] = $content['BASEPATH'] . "images/icons/bullet_ball_glass_blue.png"; $content['MENU_BULLET_GREEN'] = $content['BASEPATH'] . "images/icons/bullet_ball_glass_green.png"; $content['MENU_BULLET_RED'] = $content['BASEPATH'] . "images/icons/bullet_ball_glass_red.png"; $content['MENU_BULLET_YELLOW'] = $content['BASEPATH'] . "images/icons/bullet_ball_glass_yellow.png"; $content['MENU_BULLET_GREY'] = $content['BASEPATH'] . "images/icons/bullet_ball_glass_grey.png"; $content['MENU_ICON_GOOGLE'] = $content['BASEPATH'] . "images/icons/googleicon.png"; } // Lang Helper for Strings with ONE variable function GetAndReplaceLangStr( $strlang, $param1 = "", $param2 = "", $param3 = "", $param4 = "", $param5 = "" ) { $strfinal = str_replace ( "%1", $param1, $strlang ); if ( strlen($param2) > 0 ) $strfinal = str_replace ( "%2", $param2, $strfinal ); if ( strlen($param3) > 0 ) $strfinal = str_replace ( "%3", $param3, $strfinal ); if ( strlen($param4) > 0 ) $strfinal = str_replace ( "%4", $param4, $strfinal ); if ( strlen($param5) > 0 ) $strfinal = str_replace ( "%5", $param5, $strfinal ); // And return return $strfinal; } function InitConfigurationValues() { global $content, $CFG, $LANG, $gl_root_path; // To avoid this code in case of conversion if ( !defined('IN_PHPLOGCON_CONVERT') ) { // If Database is enabled, try to read from database! if ( GetConfigSetting("UserDBEnabled", false) ) { // Get configuration variables $result = DB_Query("SELECT * FROM `" . DB_CONFIG . "` WHERE is_global = true"); if ( $result ) { $rows = DB_GetAllRows($result, true); // Read results from DB and overwrite in $CFG Array! if ( isset($rows ) ) { for($i = 0; $i < count($rows); $i++) { // Obtain the right value if ( isset($rows[$i]['propvalue_text']) && strlen($rows[$i]['propvalue_text']) > 0 ) $myValue = $rows[$i]['propvalue_text']; else $myValue = $rows[$i]['propvalue']; $CFG[ $rows[$i]['propname'] ] = $myValue; $content[ $rows[$i]['propname'] ] = $myValue; } } } else // Critical ERROR HERE! DieWithFriendlyErrorMsg( "Critical Error occured while trying to access the database in table '" . DB_CONFIG . "'" ); // Database Version Checker! if ( $content['database_internalversion'] > $content['database_installedversion'] ) { // Database is out of date, we need to upgrade $content['database_forcedatabaseupdate'] = "yes"; } // Now we init the user session stuff InitUserSession(); if ( !$content['SESSION_LOGGEDIN'] ) { // Check if user needs to be logged in if ( GetConfigSetting("UserDBLoginRequired", false) ) { // Redirect USER if not on loginpage or installpage! if ( !defined("IS_NOLOGINPAGE") && !defined("IN_PHPLOGCON_INSTALL") && !defined("IN_PHPLOGCON_COMMANDLINE") ) RedirectToUserLogin(); } else if ( defined('IS_ADMINPAGE') ) { // Language System not initialized yet DieWithFriendlyErrorMsg( "You need to be logged in in order to access the admin pages.", "login.php", "Click here to login" ); } } // Load field definitions from DB, very first thing todo! LoadFieldsFromDatabase(); // Load Configured Searches LoadSearchesFromDatabase(); // Load Configured Charts LoadChartsFromDatabase(); // Load Configured Views LoadViewsFromDatabase(); // Load Configured Mappings LoadDBMappingsFromDatabase(); // Load Configured Sources LoadSourcesFromDatabase(); } else { if ( defined('IS_ADMINPAGE') || defined("IS_NOLOGINPAGE") ) // Language System not initialized yet DieWithFriendlyErrorMsg( "The LogAnalyzer user system is currently disabled or not installed." ); } } // --- Language Handling // Set gen language default $content['gen_lang'] = GetConfigSetting("ViewDefaultLanguage", "en", CFGLEVEL_GLOBAL); // Now check for current used language if ( isset($_SESSION['CUSTOM_LANG']) && VerifyLanguage($_SESSION['CUSTOM_LANG']) ) { $content['user_lang'] = $_SESSION['CUSTOM_LANG']; $LANG = $content['user_lang']; } else if ( isset($content['gen_lang']) && VerifyLanguage($content['gen_lang'])) { $content['user_lang'] = $content['gen_lang']; $LANG = $content['user_lang']; } else // Failsave! { $content['user_lang'] = GetConfigSetting("ViewDefaultLanguage", "en", CFGLEVEL_USER) /*"en"*/; $LANG = $content['user_lang']; $content['gen_lang'] = $content['user_lang']; } // --- // Paging Size handling! if ( !isset($_SESSION['PAGESIZE_ID']) ) { // Default is 0! $_SESSION['PAGESIZE_ID'] = 0; } // Auto reload handling! if ( !isset($_SESSION['AUTORELOAD_ID']) ) { if ( GetConfigSetting("ViewEnableAutoReloadSeconds", 0, CFGLEVEL_USER) > 0 ) $_SESSION['AUTORELOAD_ID'] = 1; // Autoreload ID will be the first item! else // Default is 0, which means auto reload disabled $_SESSION['AUTORELOAD_ID'] = 0; } // --- Theme Handling if ( !isset($content['web_theme']) ) { $content['web_theme'] = GetConfigSetting("ViewDefaultTheme", "default", CFGLEVEL_USER); } if ( isset($_SESSION['CUSTOM_THEME']) && VerifyTheme($_SESSION['CUSTOM_THEME']) ) $content['user_theme'] = $_SESSION['CUSTOM_THEME']; else $content['user_theme'] = $content['web_theme']; // Init Theme About Info ^^ InitThemeAbout($content['user_theme']); // --- // --- Handle HTML Injection stuff if ( strlen(GetConfigSetting("InjectHtmlHeader", false)) > 0 ) $content['EXTRA_HTMLHEAD'] .= $CFG['InjectHtmlHeader']; else $content['InjectHtmlHeader'] = ""; // Init Option if ( strlen(GetConfigSetting("InjectBodyHeader", false)) > 0 ) $content['EXTRA_HEADER'] .= $CFG['InjectBodyHeader']; else $content['InjectBodyHeader'] = ""; // Init Option if ( strlen(GetConfigSetting("InjectBodyFooter", false)) > 0 ) $content['EXTRA_FOOTER'] .= $CFG['InjectBodyFooter']; else $content['InjectBodyFooter'] = ""; // Init Option // --- // --- Handle Optional Logo URL! if ( strlen(GetConfigSetting("PhplogconLogoUrl", false)) > 0 ) $content['EXTRA_PHPLOGCON_LOGO'] = $CFG['PhplogconLogoUrl']; else $content['PhplogconLogoUrl'] = ""; // Init Option // --- // --- Set Proxy Option if ( strlen(GetConfigSetting("UseProxyServerForRemoteQueries", false)) <= 0 ) $content['UseProxyServerForRemoteQueries'] = ""; // Init Option // --- // --- Read Encoding Option, and set default! $content['HeaderDefaultEncoding'] = GetConfigSetting("HeaderDefaultEncoding", ENC_ISO_8859_1); // --- // --- Read ContextLinks Option, and set default! $content['EnableContextLinks'] = GetConfigSetting("EnableContextLinks", 1); // --- // Init main langauge file now! IncludeLanguageFile( $gl_root_path . '/lang/' . $LANG . '/main.php' ); // Init other things which are needed InitFrontEndVariables(); } function SetDebugModeFromString( $facility ) { global $DEBUGMODE; switch ( $facility ) { case STR_DEBUG_ULTRADEBUG: $DEBUGMODE = DEBUG_ULTRADEBUG; break; case STR_DEBUG_DEBUG: $DEBUGMODE = DEBUG_DEBUG; break; case STR_DEBUG_INFO: $DEBUGMODE = DEBUG_INFO; break; case STR_DEBUG_WARN: $DEBUGMODE = DEBUG_WARN; break; case STR_DEBUG_ERROR: $DEBUGMODE = DEBUG_ERROR; break; } } function InitPageRenderStats() { global $gl_starttime, $querycount; $gl_starttime = microtime_float(); $querycount = 0; } function FinishPageRenderStats( &$mycontent) { global $gl_starttime, $querycount; $endtime = microtime_float(); $mycontent['PAGERENDERTIME'] = number_format($endtime - $gl_starttime, 4, '.', ''); $mycontent['TOTALQUERIES'] = $querycount; } function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } function SetLineBreakVar() { // Used for some functions global $RUNMODE, $linesep; if ( $RUNMODE == RUNMODE_COMMANDLINE ) $linesep = "\r\n"; else if ( $RUNMODE == RUNMODE_WEBSERVER ) $linesep = "
"; } function CheckUrlOrIP($ip) { $long = ip2long($ip); if ( $long == -1 ) return false; else return true; } function DieWithErrorMsg( $szerrmsg ) { global $RUNMODE, $content, $gl_root_path; if ( $RUNMODE == RUNMODE_COMMANDLINE ) { print("\n\n\tCritical Error occured\t-\tErrordetails:\n"); print("\t" . $szerrmsg . "\n\n"); print("\tTerminating now!\n"); } else if ( $RUNMODE == RUNMODE_WEBSERVER ) { // Print main error! print ( "Adiscon LogAnalyzer :: Critical Error occured" . "

" . "". "" . "" . "
" . "

Critical Error occured

" . "
Errordetails:
" . $szerrmsg . "

"); // Print Detail error's if available if ( isset($content['detailederror']) ) { print ("". "" . "
Additional Errordetails:
" . $content['detailederror'] . "

"); } // End HTML Body print( "" ); } // Abort further execution exit; } function DieWithFriendlyErrorMsg( $szerrmsg, $szLink = "", $szLinkLable = "" ) { global $RUNMODE, $content, $gl_root_path; if ( $RUNMODE == RUNMODE_COMMANDLINE ) { print("\n\n\t\tError occured\n"); print("\t\tErrordetails:\t" . $szerrmsg . "\n"); print("\t\tTerminating now!\n"); } else if ( $RUNMODE == RUNMODE_WEBSERVER ) { echo "Adiscon LogAnalyzer :: Error occured" . "

" . "". "" . "" . ""; if ( strlen($szLink) > 0 && strlen($szLinkLable) > 0 ) echo ""; echo "
" . "

Error occured

" . "
Errordetails:
" . $szerrmsg . "

$szLinkLable
" . ""; } // Abort further execution exit; } /* * Helper function to initialize the page title! */ function InitPageTitle() { global $content, $currentSourceID; $tmpTitle = GetConfigSetting("PrependTitle", "", CFGLEVEL_USER); if ( strlen($tmpTitle) > 0 ) $szReturn = $tmpTitle . " :: "; else $szReturn = ""; if ( !defined('IS_ADMINPAGE') ) { if ( isset($currentSourceID) && isset($content['Sources'][$currentSourceID]['Name']) ) $szReturn .= "Source '" . $content['Sources'][$currentSourceID]['Name'] . "' :: "; } // Append LogAnalyzer $szReturn .= "Adiscon LogAnalyzer"; if ( defined('IS_ADMINPAGE') ) $szReturn .= " :: " . $content['LN_ADMIN_CENTER'] . " :: "; // return result return $szReturn; } function ReplaceLineBreaksInString($myStr) { // Add linebreaks! return str_replace( "\n", "
", $myStr ); } function GetStringWithHTMLCodes($myStr) { global $content; // Replace all special characters with valid html representations return htmlentities($myStr, ENT_NOQUOTES, $content['HeaderDefaultEncoding']); //"UTF-8"); } function InitTemplateParser() { global $page, $gl_root_path, $content; // ----------------------------------------------- // Create Template Object and set some variables for the templates // ----------------------------------------------- $page = new Template(); $page -> set_path ( $gl_root_path . "templates/" ); // Append correct Character encoding to HTML Header $content['EXTRA_METATAGS'] .= ''; } function VerifyLanguage( $mylang ) { global $gl_root_path; if ( is_dir( $gl_root_path . 'lang/' . $mylang ) ) return true; else return false; } function IncludeLanguageFile( $langfile, $failOnError = true ) { global $LANG, $LANG_EN; // If english is not selected, we load ENGLISH first - then overwrite with configured language if ( $LANG != "en" ) $langengfile = str_replace( $LANG, $LANG_EN, $langfile ); else $langengfile = $langfile; if ( file_exists($langengfile) ) include( $langengfile ); else { if ( $failOnError ) DieWithErrorMsg( "FATAL Error initialzing sublanguage system. Please make sure that all files have been uploaded correctly." ); else return false; } // If nto english, load the additional translations if ( $LANG != "en" ) { if ( file_exists( $langfile ) ) include( $langfile ); else { if ( $failOnError ) OutputDebugMessage("FATAL Error reading the configured language $LANG. Please make sure that all files have been uploaded correctly.", DEBUG_ERROR); else return false; } } } function RedirectPage( $newpage ) { header("Location: $newpage"); exit; } function RedirectResult( $szMsg, $newpage ) { global $content; if ( defined('PHPLOGCON_INERROR') ) DieWithErrorMsg( GetAndReplaceLangStr($content["LN_ERROR_REDIRECTABORTED"], $newpage) ); // Perform redirect! header("Location: result.php?msg=" . urlencode($szMsg) . "&redir=" . urlencode($newpage)); exit; } /* * GetEventTime * * Helper function to parse and obtain a valid EventTime Array from the input string. * Return value: EventTime Array! * */ function GetEventTime($szTimStr) { // Sample: Mar 10 14:45:44 if ( preg_match("/(...) ([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/", $szTimStr, $out ) ) { // RFC 3164 typical timestamp $eventtime[EVTIME_TIMESTAMP] = mktime($out[3], $out[4], $out[5], GetMonthFromString($out[1]), $out[2], date("Y") ); // If the current time is if ( $eventtime[EVTIME_TIMESTAMP] > time() ) { // rare case on new year only! $eventtime[EVTIME_TIMESTAMP] = mktime($out[3], $out[4], $out[5], GetMonthFromString($out[1]), $out[2], date("Y")-1 ); } $eventtime[EVTIME_TIMEZONE] = date('O'); // Get default Offset $eventtime[EVTIME_MICROSECONDS] = 0; // echo gmdate(DATE_RFC822, $eventtime[EVTIME_TIMESTAMP]) . "
"; // print_r ( $eventtime ); // exit; } // Sample: 2008-04-02T11:12:32+02:00 else if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2})T([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})([+-])([0-9]{1,2}):([0-9]{1,2})/", $szTimStr, $out ) ) { // RFC 3164 typical timestamp $eventtime[EVTIME_TIMESTAMP] = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]); $eventtime[EVTIME_TIMEZONE] = $out[7] . $out[8] . $out[9]; $eventtime[EVTIME_MICROSECONDS] = 0; } // Sample: 2008-04-02T11:12:32.380449+02:00 else if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2})T([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})\.([0-9]{1,6})([+-])([0-9]{1,2}):([0-9]{1,2})/", $szTimStr, $out ) ) { // RFC 3164 typical timestamp $eventtime[EVTIME_TIMESTAMP] = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]); $eventtime[EVTIME_TIMEZONE] = $out[8] . $out[9] . $out[10]; $eventtime[EVTIME_MICROSECONDS] = $out[7]; } // Sample: 2008-04-02,15:19:06 else if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2}),([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/", $szTimStr, $out ) ) { // RFC 3164 typical timestamp $eventtime[EVTIME_TIMESTAMP] = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]); $eventtime[EVTIME_TIMEZONE] = date('O'); // Get default Offset $eventtime[EVTIME_MICROSECONDS] = 0; } // Sample: 2008-02-19 12:52:37 else if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/", $szTimStr, $out ) ) { // RFC 3164 typical timestamp $eventtime[EVTIME_TIMESTAMP] = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]); $eventtime[EVTIME_TIMEZONE] = date('O'); // Get default Offset $eventtime[EVTIME_MICROSECONDS] = 0; } // Sample: 2007-4-18T00:00:00 else if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2})T([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})/", $szTimStr, $out ) ) { // RFC 3164 typical timestamp $eventtime[EVTIME_TIMESTAMP] = mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]); $eventtime[EVTIME_TIMEZONE] = date('O'); // Get default Offset $eventtime[EVTIME_MICROSECONDS] = 0; } // Sample: 16/Sep/2008:13:37:47 +0200 else if ( preg_match("/([0-9]{1,2})\/(...)\/([0-9]{1,4}):([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}) ([+-])([0-9]{1,4})/", $szTimStr, $out ) ) { // Apache Logfile typical timestamp $eventtime[EVTIME_TIMESTAMP] = mktime($out[4], $out[5], $out[6], GetMonthFromString($out[2]), $out[1], $out[3]); $eventtime[EVTIME_TIMEZONE] = $out[7] . $out[8]; // Get Offset from MSG $eventtime[EVTIME_MICROSECONDS] = 0; } // Sample: 2008-02-19 else if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2})/", $szTimStr, $out ) ) { // RFC 3164 typical timestamp $eventtime[EVTIME_TIMESTAMP] = mktime(0, 0, 0, $out[2], $out[3], $out[1]); $eventtime[EVTIME_TIMEZONE] = date('O'); // Get default Offset $eventtime[EVTIME_MICROSECONDS] = 0; } else { $eventtime[EVTIME_TIMESTAMP] = 0; $eventtime[EVTIME_TIMEZONE] = date('O'); // Get default Offset $eventtime[EVTIME_MICROSECONDS] = 0; // Print Error! OutputDebugMessage("GetEventTime got an unparsable time '" . $szTimStr . "', returning 0", DEBUG_WARN); } // return result! return $eventtime; } /* * Helper function to output debug messages */ function OutputDebugMessage($szDbg, $szDbgLevel = DEBUG_INFO) { global $content; // Check if we should print the Error! if ( GetConfigSetting("MiscShowDebugMsg", 0, CFGLEVEL_USER) == 1 ) { // Also enable the template helper variable here! $content['SHOWDEBUGMSG'] = true; $content['DEBUGMSG'][] = array( "DBGLEVEL" => $szDbgLevel, "DBGLEVELTXT" => GetDebugModeString($szDbgLevel), "DBGLEVELBG" => GetDebugBgColor($szDbgLevel), "DBGMSG" => strip_dangerous_html_tags($szDbg) ); } // Check if the user wants to syslog the error! if ( GetConfigSetting("MiscDebugToSyslog", 0, CFGLEVEL_GLOBAL) == 1 ) { if ( $content['SOCKETS_IS_ENABLED'] ) { // Send using UDP ourself! $sock = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); $stprifac = (SYSLOG_LOCAL0 << 3); if ( $szDbgLevel == DEBUG_ERROR_WTF ) $stprifac += SYSLOG_CRIT; else if ( $szDbgLevel == DEBUG_ERROR ) $stprifac += SYSLOG_ERR; else if ( $szDbgLevel == DEBUG_WARN ) $stprifac += SYSLOG_WARNING; else if ( $szDbgLevel == DEBUG_INFO ) $stprifac += SYSLOG_NOTICE; else if ( $szDbgLevel == DEBUG_DEBUG ) $stprifac += SYSLOG_INFO; else if ( $szDbgLevel == DEBUG_ULTRADEBUG ) $stprifac += SYSLOG_DEBUG; // Generate RFC5424 Syslog MSG $szsyslogmsg = "<" . $stprifac . ">" . date("c") . " " . php_uname ("n") . " " . "loganalyzer - - - " . $szDbg ; @socket_sendto($sock, $szsyslogmsg, strlen($szsyslogmsg), 0, '127.0.0.1', 514); @socket_close($sock); } else // Use PHP System function to send via syslog $syslogSend = syslog(GetPriorityFromDebugLevel($szDbgLevel), $szDbg); } } /* * GetMonthFromString * * Simple Helper function to obtain the numeric represantation of the month */ function GetMonthFromString($szMonth) { switch($szMonth) { case "Jan": return 1; case "Feb": return 2; case "Mar": return 3; case "Apr": return 4; case "May": return 5; case "Jun": return 6; case "Jul": return 7; case "Aug": return 8; case "Sep": return 9; case "Oct": return 10; case "Nov": return 11; case "Dec": return 12; } } /* * AddContextLinks */ function AddContextLinks(&$sourceTxt) { global $szTLDDomains; // Return if not enabled! if ( GetConfigSetting("EnableIPAddressResolve", 0, CFGLEVEL_USER) == 1 ) { // Search for IP's and Add Reverse Lookup first! $sourceTxt = preg_replace( '/([^\[])\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/ie', "'\\1\\2.\\3.\\4.\\5' . ReverseResolveIP('\\2.\\3.\\4.\\5', ' {', '} ')", $sourceTxt ); } // check if user disabled Context Links. if ( GetConfigSetting("EnableContextLinks", 1, CFGLEVEL_USER) == 0 ) return; // Create if not set! if ( !isset($szTLDDomains) ) CreateTopLevelDomainSearch(); // Create Search Array $search = array ( '/\.([\w\d\_\-]+)\.(' . $szTLDDomains . ')([^a-zA-Z0-9\.])/ie', /* (?:127)| */ '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/ie', ); // Create Replace Array $replace = array ( "'.' . InsertLookupLink(\"\", \"\\1.\\2\", \"\", \"\\3\")", "InsertLookupLink(\"\\1.\\2.\\3.\\4\", \"\", \"\", \"\")", ); // Replace and return! $sourceTxt = preg_replace( $search, $replace, $sourceTxt ); //echo $outTxt . "
" ; //return $outTxt; } /* * Helper to create a Lookup Link! */ function InsertLookupLink( $szIP, $szDomain, $prepend, $append ) { global $content, $uID; // Create string $szReturn = $prepend; // Set IUD property if available if ( isset($uID) ) $includeLinkUID = "&uid=" . $uID; else $includeLinkUID = ""; // check if it is an IP or domain if ( strlen($szIP) > 0 ) { /* // Split IP into array $IPArray = explode(".", $szIP); if ( (intval($IPArray[0]) == 10 ) || (intval($IPArray[0]) == 127 ) || (intval($IPArray[0]) == 172 && intval($IPArray[1]) >= 16 && intval($IPArray[1]) <= 31) || (intval($IPArray[0]) == 192 && intval($IPArray[1]) == 168) || (intval($IPArray[0]) == 255 ) ) */ if ( IsInternalIP($szIP) ) // Do not create a LINK in this case! $szReturn .= '' . $szIP . ''; else // Normal LINK! $szReturn .= '' . $szIP . ''; // Add InfoSearch Link $szReturn .= ''; } else if ( strlen($szDomain) > 0 ) { $szReturn .= '' . $szDomain . ''; // Add InfoSearch Link $szReturn .= ''; } // Append the append string now $szReturn .= $append; // return result return $szReturn; } /* * Helper function to check, if an IP Address is within private address space! */ function IsInternalIP($szIPAddress) { // Split IP into array $IPArray = explode(".", $szIPAddress); if ( (intval($IPArray[0]) == 10 ) || (intval($IPArray[0]) == 127 ) || (intval($IPArray[0]) == 172 && intval($IPArray[1]) >= 16 && intval($IPArray[1]) <= 31) || (intval($IPArray[0]) == 192 && intval($IPArray[1]) == 168) || (intval($IPArray[0]) == 255 ) ) // return true in this case return true; else // This is an external IP return false; } /* * Reserve Resolve IP Address! */ function ReverseResolveIP( $szIP, $prepend, $append ) { global $gl_starttime, $content; // Substract 5 seconds we need to finish processing! $scriptruntime = intval(microtime_float() - $gl_starttime); if ( $content['MaxExecutionTime'] > 0 && $scriptruntime > ($content['MaxExecutionTime']-5) ) return ""; // Abort if these IP's are postet if ( strpos($szIP, "0.0.0.0") !== false | strpos($szIP, "127.") !== false | strpos($szIP, "255.255.255.255") !== false ) return ""; else { // Resolve name if needed if ( !isset($_SESSION['dns_cache'][$szIP]) ) $_SESSION['dns_cache'][$szIP] = @gethostbyaddr($szIP); // Suppress error messages by gethostbyaddr // Abort if IP and RESOLVED name are the same ^^! if ( $_SESSION['dns_cache'][$szIP] == $szIP || strlen($_SESSION['dns_cache'][$szIP]) <= 0 ) return; // Create string $szReturn = $prepend; $szReturn .= $_SESSION['dns_cache'][$szIP]; $szReturn .= $append; // return result return $szReturn; } } /* * Helper function to create a top level domain search string ONCE per process! */ function CreateTopLevelDomainSearch() { // Current list taken from http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains! global $szTLDDomains; $szTLDDomains = "co.th|com.au|co.uk|co.jp"; $szTLDDomains .= "aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|cTLD|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw"; } /* * This Functions starts the main PHP Session if necessary */ function StartPHPSession() { global $RUNMODE; if ( $RUNMODE == RUNMODE_WEBSERVER ) { // This will start the session @session_start(); if ( !isset($_SESSION['SESSION_STARTED']) ) $_SESSION['SESSION_STARTED'] = "true"; } } /* * This Functions starts the main PHP Session if necessary */ function WriteClosePHPSession() { global $RUNMODE; if ( $RUNMODE == RUNMODE_WEBSERVER ) { @session_write_close(); } } function PrintSecureUserCheck( $warningtext, $yesmsg, $nomsg ) { global $content, $page; // Copy properties $content['warningtext'] = $warningtext; $content['yesmsg'] = $yesmsg; $content['nomsg'] = $nomsg; // Handle GET and POST input! $content['form_url'] = $_SERVER['SCRIPT_NAME'] . "?"; foreach ($_GET as $varname => $varvalue) $content['form_url'] .= $varname . "=" . $varvalue . "&"; $content['form_url'] .= "verify=yes"; // Append verify! foreach ($_POST as $varname => $varvalue) $content['POST_VARIABLES'][] = array( "varname" => $varname, "varvalue" => $varvalue ); // --- BEGIN CREATE TITLE $content['TITLE'] = InitPageTitle(); $content['TITLE'] .= " :: Confirm Action"; // --- END CREATE TITLE // --- Parsen and Output InitTemplateParser(); $page -> parser($content, "admin/admin_securecheck.html"); $page -> output(); // --- // Exit script execution exit; } function SaveGeneralSettingsIntoDB($bForceStripSlahes = false) { WriteConfigValue( "ViewDefaultLanguage", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewDefaultTheme", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewUseTodayYesterday", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewEnableDetailPopups", true, null, null,$bForceStripSlahes ); WriteConfigValue( "EnableContextLinks", true, null, null,$bForceStripSlahes ); WriteConfigValue( "EnableIPAddressResolve", true, null, null,$bForceStripSlahes ); WriteConfigValue( "MiscShowDebugMsg", true, null, null,$bForceStripSlahes ); WriteConfigValue( "MiscShowDebugGridCounter", true, null, null,$bForceStripSlahes ); WriteConfigValue( "MiscShowPageRenderStats", true, null, null,$bForceStripSlahes ); WriteConfigValue( "MiscEnableGzipCompression", true, null, null,$bForceStripSlahes ); WriteConfigValue( "SuppressDuplicatedMessages", true, null, null,$bForceStripSlahes ); WriteConfigValue( "TreatNotFoundFiltersAsTrue", true, null, null,$bForceStripSlahes ); WriteConfigValue( "InlineOnlineSearchIcons", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewMessageCharacterLimit", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewStringCharacterLimit", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewEntriesPerPage", true, null, null,$bForceStripSlahes ); WriteConfigValue( "ViewEnableAutoReloadSeconds", true, null, null,$bForceStripSlahes ); WriteConfigValue( "AdminChangeWaitTime", true, null, null,$bForceStripSlahes ); WriteConfigValue( "PopupMenuTimeout", true, null, null,$bForceStripSlahes ); WriteConfigValue( "PrependTitle", true, null, null,$bForceStripSlahes ); WriteConfigValue( "SearchCustomButtonCaption", true, null, null,$bForceStripSlahes ); WriteConfigValue( "SearchCustomButtonSearch", true, null, null,$bForceStripSlahes ); // Extra Fields WriteConfigValue( "DefaultViewsID", true, null, null,$bForceStripSlahes ); WriteConfigValue( "DefaultSourceID", true, null, null,$bForceStripSlahes ); // GLOBAL ONLY WriteConfigValue( "DebugUserLogin", true, null, null,$bForceStripSlahes ); WriteConfigValue( "MiscDebugToSyslog", true, null, null,$bForceStripSlahes ); WriteConfigValue( "MiscMaxExecutionTime", true, null, null,$bForceStripSlahes ); WriteConfigValue( "UseProxyServerForRemoteQueries", true, null, null,$bForceStripSlahes ); WriteConfigValue( "HeaderDefaultEncoding", true, null, null,$bForceStripSlahes ); // Custom HTML Code WriteConfigValue( "InjectHtmlHeader", true, null, null,$bForceStripSlahes ); WriteConfigValue( "InjectBodyHeader", true, null, null,$bForceStripSlahes ); WriteConfigValue( "InjectBodyFooter", true, null, null ,$bForceStripSlahes ); WriteConfigValue( "PhplogconLogoUrl", true, null, null ,$bForceStripSlahes ); } function SaveUserGeneralSettingsIntoDB() { global $content; WriteConfigValue( "ViewDefaultLanguage", false, $content['SESSION_USERID']); WriteConfigValue( "ViewDefaultTheme", false, $content['SESSION_USERID'] ); WriteConfigValue( "ViewUseTodayYesterday", false, $content['SESSION_USERID'] ); WriteConfigValue( "ViewEnableDetailPopups", false, $content['SESSION_USERID'] ); WriteConfigValue( "EnableContextLinks", false, $content['SESSION_USERID'] ); WriteConfigValue( "EnableIPAddressResolve", false, $content['SESSION_USERID'] ); WriteConfigValue( "MiscShowDebugMsg", false, $content['SESSION_USERID'] ); WriteConfigValue( "MiscShowDebugGridCounter", false, $content['SESSION_USERID'] ); WriteConfigValue( "MiscShowPageRenderStats", false, $content['SESSION_USERID'] ); WriteConfigValue( "MiscEnableGzipCompression", false, $content['SESSION_USERID'] ); WriteConfigValue( "SuppressDuplicatedMessages", false, $content['SESSION_USERID'] ); WriteConfigValue( "TreatNotFoundFiltersAsTrue", false, $content['SESSION_USERID'] ); WriteConfigValue( "InlineOnlineSearchIcons", false, $content['SESSION_USERID'] ); WriteConfigValue( "ViewMessageCharacterLimit", false, $content['SESSION_USERID'] ); WriteConfigValue( "ViewStringCharacterLimit", false, $content['SESSION_USERID'] ); WriteConfigValue( "ViewEntriesPerPage", false, $content['SESSION_USERID'] ); WriteConfigValue( "ViewEnableAutoReloadSeconds", false, $content['SESSION_USERID'] ); WriteConfigValue( "AdminChangeWaitTime", false, $content['SESSION_USERID'] ); WriteConfigValue( "PopupMenuTimeout", false, $content['SESSION_USERID'] ); WriteConfigValue( "PrependTitle", false, $content['SESSION_USERID'] ); WriteConfigValue( "SearchCustomButtonCaption", false, $content['SESSION_USERID'] ); WriteConfigValue( "SearchCustomButtonSearch", false, $content['SESSION_USERID'] ); // Extra Fields WriteConfigValue( "DefaultViewsID", false, $content['SESSION_USERID'] ); WriteConfigValue( "DefaultSourceID", false, $content['SESSION_USERID'] ); } function GetConfigSetting($szSettingName, $szDefaultValue = "", $DesiredConfigLevel = CFGLEVEL_GLOBAL) { global $content, $CFG, $USERCFG; if ( isset($CFG['UserDBEnabled']) && $CFG['UserDBEnabled'] ) { if ( $DesiredConfigLevel == CFGLEVEL_USER ) { // only use user settings if desired by the user if ( isset($USERCFG['UserOverwriteOptions']) && $USERCFG['UserOverwriteOptions'] == 1 ) { // return user specific setting if available if ( isset($USERCFG[$szSettingName]) ) return $USERCFG[$szSettingName]; } } } // Either UserDB disabled, or global setting wanted - easier handling if ( isset($CFG[$szSettingName]) ) return $CFG[$szSettingName]; else return $szDefaultValue; } /* * Helper function to get all directory from a folder */ function list_directories($directory, $failOnError = true) { $result = array(); if ( !$directoryHandler = @opendir ($directory) ) { if ( $failOnError ) DieWithFriendlyErrorMsg( "list_directories: directory \"$directory\" doesn't exist!"); else return null; } while (false !== ($fileName = @readdir ($directoryHandler))) { if ( is_dir( $directory . $fileName ) && ( $fileName != "." && $fileName != ".." )) @array_push ($result, $fileName); } if ( @count ($result) === 0 ) { if ( $failOnError ) DieWithFriendlyErrorMsg( "list_directories: no directories in \"$directory\" found!"); else return null; } else { sort ($result); return $result; } } /* * Helper function to get all files from a directory */ function list_files($directory, $failOnError = true) { $result = array(); if ( !$directoryHandler = @opendir ($directory) ) { if ( $failOnError ) DieWithFriendlyErrorMsg( "list_directories: directory \"$directory\" doesn't exist!"); else return null; } while (false !== ($fileName = @readdir ($directoryHandler))) { if ( is_file( $directory . $fileName ) && ( $fileName != "." && $fileName != ".." )) @array_push ($result, $fileName); } if ( @count ($result) === 0 ) { if ( $failOnError ) DieWithFriendlyErrorMsg( "list_directories: no files in \"$directory\" found!"); else return null; } else { sort ($result); return $result; } } /* * Helper function to prepend the current global root path if necessary! */ function CheckAndPrependRootPath( $szFileName) { global $gl_root_path; // Get plain filename for testing! $szNewFileName = $szFileName; // Take as it is if rootpath! if ( ( ($pos = strpos($szFileName, "/")) !== FALSE && $pos == 0) || ( ($pos = strpos($szFileName, "\\\\")) !== FALSE && $pos == 0) || ( ($pos = strpos($szFileName, ":\\")) !== FALSE ) || ( ($pos = strpos($szFileName, ":/")) !== FALSE ) ) { // Nothing really todo true; } else { // replace ./ with gl_root_path in this case if ( ($pos = strpos($szFileName, "./")) !== FALSE ) $szNewFileName = str_replace( "./", $gl_root_path, $szFileName ); else // prepend basepath! $szNewFileName = $gl_root_path . $szFileName; } // return result return $szNewFileName; } /* * Helper function to flush html output to avoid redirects if errors happen! */ function FlushHtmlOutput() { global $RUNMODE; // not needed in console mode if ( $RUNMODE == RUNMODE_COMMANDLINE ) return; //Flush php output @flush(); @ob_flush(); } /* * Helper function to get the errorCode */ function GetErrorMessage($errorCode) { global $content; switch( $errorCode ) { case ERROR_FILE_NOT_FOUND: return $content['LN_ERROR_FILE_NOT_FOUND']; case ERROR_FILE_NOT_READABLE: return $content['LN_ERROR_FILE_NOT_READABLE']; case ERROR_FILE_EOF: return $content['LN_ERROR_FILE_EOF']; case ERROR_FILE_BOF: return $content['LN_ERROR_FILE_BOF']; case ERROR_FILE_CANT_CLOSE: return $content['LN_ERROR_FILE_CANT_CLOSE']; case ERROR_UNDEFINED: return $content['LN_ERROR_UNDEFINED']; case ERROR_EOS: return $content['LN_ERROR_EOS']; case ERROR_NOMORERECORDS: return $content['LN_ERROR_NORECORDS']; case ERROR_FILTER_NOT_MATCH: return $content['LN_ERROR_FILTER_NOT_MATCH']; case ERROR_DB_CONNECTFAILED: return $content['LN_ERROR_DB_CONNECTFAILED']; case ERROR_DB_CANNOTSELECTDB: return $content['LN_ERROR_DB_CANNOTSELECTDB']; case ERROR_DB_QUERYFAILED: return isset($content['LN_ERROR_DB_QUERYFAILED']) ? $content['LN_ERROR_DB_QUERYFAILED'] : $errorCode; case ERROR_DB_NOPROPERTIES: return $content['LN_ERROR_DB_NOPROPERTIES']; case ERROR_DB_INVALIDDBMAPPING: return $content['LN_ERROR_DB_INVALIDDBMAPPING']; case ERROR_DB_INVALIDDBDRIVER: return $content['LN_ERROR_DB_INVALIDDBDRIVER']; case ERROR_DB_TABLENOTFOUND: return $content['LN_ERROR_DB_TABLENOTFOUND']; case ERROR_DB_DBFIELDNOTFOUND: return $content['LN_ERROR_DB_DBFIELDNOTFOUND']; case ERROR_CHARTS_NOTCONFIGURED: return $content['LN_ERROR_CHARTS_NOTCONFIGURED']; case ERROR_FILE_NOMORETIME: return $content['LN_ERROR_FILE_NOMORETIME']; case ERROR_SOURCENOTFOUND: return $content['LN_GEN_ERROR_SOURCENOTFOUND']; case ERROR_REPORT_NODATA: return $content['LN_GEN_ERROR_REPORT_NODATA']; case ERROR_PATH_NOT_ALLOWED: return $content['LN_ERROR_PATH_NOT_ALLOWED']; default: return GetAndReplaceLangStr( $content['LN_ERROR_UNKNOWN'], $errorCode ); } } // --- Static Sorter helper function! /** * Helper function for multisorting multidimensional arrays */ function MultiSortArrayByItemCountDesc( $arrayFirst, $arraySecond ) { // Do not sort in this case if ($arrayFirst['itemcount'] == $arraySecond['itemcount']) return 0; // Move up or down return ($arrayFirst['itemcount'] < $arraySecond['itemcount']) ? 1 : -1; } /** * Helper function for multisorting multidimensional arrays */ function MultiSortArrayByItemCountAsc( $arrayFirst, $arraySecond ) { // Do not sort in this case if ($arrayFirst['itemcount'] == $arraySecond['itemcount']) return 0; // Move up or down return ($arrayFirst['itemcount'] < $arraySecond['itemcount']) ? -1 : 1; } /** * Helper function to remove dangerous HTML Tags */ function strip_dangerous_html_tags( $text ) { $text = preg_replace( array( // Remove invisible content '@]*?>@siu', '@@siu', '@]*?>@siu', '@@siu', '@]*?>@siu', '@@siu', '@]*?>@siu', '@/script>@siu', '@]*?>@siu', '@@siu', '@]*?>@siu', '@@siu', '@]*?>@siu', '@@siu', '@]*?>@siu', '@@siu', '@]*?>@siu', '@@siu', '@]*?>@siu', '@@siu', ), array( ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ), $text ); return $text; } // --- ?>loganalyzer-3.6.5/src/include/db_update_v8.txt0000644000175000017500000000045112225176641020653 0ustar danieldaniel-- New Database Structure Updates CREATE TABLE `logcon_dbmappings` ( `ID` int(11) NOT NULL auto_increment, `DisplayName` varchar(64) NOT NULL, `Mappings` varchar(1024) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/functions_frontendhelpers.php0000644000175000017500000002073512225176641023560 0ustar danieldaniel * * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- function InitFrontEndDefaults() { global $content; // To create the current URL CreateCurrentUrl(); // --- BEGIN Main Info Area $content['MAXURL'] = $content['BASEPATH'] . "userchange.php?"; if ( isset($_SESSION['SESSION_MAXIMIZED']) && $_SESSION['SESSION_MAXIMIZED'] == true ) { $content['MAXIMIZED'] = true; $content['MAXIMAGE'] = $content['MENU_NORMAL']; $content['MAXLANGTEXT'] = $content['LN_MENU_NORMALVIEW']; $content['MAXURL'] .= "op=maximize&max=0"; } else { $content['MAXIMIZED'] = false; $content['MAXIMAGE'] = $content['MENU_MAXIMIZE']; $content['MAXLANGTEXT'] = $content['LN_MENU_MAXVIEW']; $content['MAXURL'] .= "op=maximize&max=1"; } // --- END Main Info Area // Check if install file still exists // NOT NEEDED ANYMORE InstallFileReminder(); } function InstallFileReminder() { global $content; if ( is_file($content['BASEPATH'] . "install.php") ) { // No Servers - display warning! $content['error_installfilereminder'] = "true"; } } function GetAdditionalUrl($skipParam, $appendParam = "") { global $content; //echo $content['additional_url_full']; if ( isset($content['additional_url_full']) && strlen($content['additional_url_full']) > 0 ) { if ( strlen($skipParam) > 0 ) { // remove parameters from string! $szReturn = preg_replace("#(&{$skipParam}=[\w]+)#is", '', $content['additional_url_full']); if ( strlen($szReturn) > 0 ) { if ( strlen($appendParam) > 0 ) return $szReturn . "&" . $appendParam; else return $szReturn; } else if ( strlen($appendParam) > 0 ) return "?" . $appendParam; else return ""; } else return $content['additional_url_full']; } else { if ( strlen($appendParam) > 0 ) return "?" . $appendParam; else return ""; } } function CreateCurrentUrl() { global $content; $content['CURRENTURL'] = $_SERVER['PHP_SELF']; // . "?" . $_SERVER['QUERY_STRING'] // Init additional_url helper variable $content['additional_url'] = ""; $content['additional_url_full'] = ""; $content['additional_url_uidonly'] = ""; $content['additional_url_sortingonly'] = ""; $content['additional_url_sourceonly'] = ""; // Hidden Vars Counter $hvCounter = 0; // Append SourceID into everything! $tmpDefSourceID = GetConfigSetting("DefaultSourceID", "", CFGLEVEL_USER); if ( isset($content['Sources'][ $tmpDefSourceID ]) && isset($_SESSION['currentSourceID']) ) { // If the DefaultSourceID differes from the SourceID in our Session, we will append the sourceid within all URL's! if ( $tmpDefSourceID != $_SESSION['currentSourceID'] ) { // $content['additional_url'] .= "&sourceid=" . $_SESSION['currentSourceID']; $content['additional_url_uidonly'] = "&sourceid=" . $_SESSION['currentSourceID']; $content['additional_url_sortingonly'] = "&sourceid=" . $_SESSION['currentSourceID']; $content['additional_url_sourceonly'] = "&sourceid=" . $_SESSION['currentSourceID']; // For forms! $content['HIDDENVARS_SOURCE'][$hvCounter]['varname'] = "sourceid"; $content['HIDDENVARS_SOURCE'][$hvCounter]['varvalue'] = $_SESSION['currentSourceID']; $hvCounter++; } } // Now the query string: if ( isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 ) { // Append ? $content['CURRENTURL'] .= "?"; $queries = explode ("&", $_SERVER['QUERY_STRING']); for ( $i = 0; $i < count($queries); $i++ ) { // Some properties need to be filtered out. if ( strpos($queries[$i], "direction") === false && strpos($queries[$i], "skipone") === false ) { $tmpvars = explode ("=", $queries[$i]); if ( isset($tmpvars[1]) ) // Only if value param is set! { // For forms! $content['HIDDENVARS'][$hvCounter]['varname'] = $tmpvars[0]; $content['HIDDENVARS'][$hvCounter]['varvalue'] = $tmpvars[1]; if ( strlen($tmpvars[1]) > 0 ) { // Append For URL's if ( $tmpvars[0] == "uid" ) { // only add once if ( strlen($content['additional_url_uidonly']) <= 0 ) $content['additional_url_uidonly'] .= "&" . $tmpvars[0] . "=" . $tmpvars[1]; } else if ( $tmpvars[0] == "sorting" ) { // only add once if ( strlen($content['additional_url_sortingonly']) <= 0 ) $content['additional_url_sortingonly'] .= "&" . $tmpvars[0] . "=" . $tmpvars[1]; } else if ( $tmpvars[0] == "sourceid" ) { // Skip this entry continue; } else $content['additional_url'] .= "&" . $tmpvars[0] . "=" . $tmpvars[1]; // always append to this URL! $content['additional_url_full'] .= "&" . $tmpvars[0] . "=" . $tmpvars[1]; } $hvCounter++; } } } } // done } function GetFormatedDate($evttimearray) { global $content; if ( is_array($evttimearray) ) { if ( GetConfigSetting("ViewUseTodayYesterday", 0, CFGLEVEL_USER) == 1 && ( date('m', $evttimearray[EVTIME_TIMESTAMP]) == date('m') && date('Y', $evttimearray[EVTIME_TIMESTAMP]) == date('Y') ) ) { if ( date('d', $evttimearray[EVTIME_TIMESTAMP]) == date('d') ) return "Today " . date("H:i:s", $evttimearray[EVTIME_TIMESTAMP] ); else if ( date('d', $evttimearray[EVTIME_TIMESTAMP] + 86400) == date('d') ) return "Yesterday " . date("H:i:s", $evttimearray[EVTIME_TIMESTAMP] ); } // Copy to local variable $nMyTimeStamp = $evttimearray[EVTIME_TIMESTAMP]; } else { $nMyTimeStamp = strtotime($evttimearray); if ( $nMyTimeStamp === FALSE ) // Could not convert into timestamp so return original! return $evttimearray; } // Reach return normal format! return $szDateFormatted = date("Y-m-d H:i:s", $nMyTimeStamp ); } function GetDebugBgColor( $szDebugMode ) { global $severity_colors; switch ( $szDebugMode ) { case DEBUG_ULTRADEBUG: $szReturn = $severity_colors[SYSLOG_DEBUG]; break; case DEBUG_DEBUG: $szReturn = $severity_colors[SYSLOG_INFO]; break; case DEBUG_INFO: $szReturn = $severity_colors[SYSLOG_NOTICE]; break; case DEBUG_WARN: $szReturn = $severity_colors[SYSLOG_WARNING]; break; case DEBUG_ERROR: $szReturn = $severity_colors[SYSLOG_ERR]; break; default: $szReturn = $severity_colors[SYSLOG_NOTICE]; } // Return string result return $szReturn; } function GetDebugModeString( $szDebugMode ) { switch ( $szDebugMode ) { case DEBUG_ULTRADEBUG: $szReturn = STR_DEBUG_ULTRADEBUG; break; case DEBUG_DEBUG: $szReturn = STR_DEBUG_DEBUG; break; case DEBUG_INFO: $szReturn = STR_DEBUG_INFO; break; case DEBUG_WARN: $szReturn = STR_DEBUG_WARN; break; case DEBUG_ERROR: $szReturn = STR_DEBUG_ERROR; break; default: $szReturn = STR_DEBUG_INFO; } // Return string result return $szReturn; } function GetPriorityFromDebugLevel( $DebugLevel ) { switch ( $DebugLevel ) { case DEBUG_ULTRADEBUG: return LOG_DEBUG; case DEBUG_DEBUG: return LOG_INFO; case DEBUG_INFO: return LOG_NOTICE; case DEBUG_WARN: return LOG_WARNING; case DEBUG_ERROR: return LOG_ERR; case DEBUG_ERROR_WTF: return LOG_CRIT; } } ?>loganalyzer-3.6.5/src/include/functions_filters.php0000644000175000017500000003441412225176641022025 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Perform necessary includes require_once($gl_root_path . 'include/constants_filters.php'); // --- function InitFilterHelpers() { global $content, $filters; // Init Default DateMode from SESSION! if ( isset($_SESSION['filter_datemode']) ) $filters['filter_datemode'] = intval($_SESSION['filter_datemode']); else $filters['filter_datemode'] = DATEMODE_ALL; // Init TimeFilter Helper Array $content['datemodes'][0]['ID'] = DATEMODE_ALL; $content['datemodes'][0]['DisplayName'] = $content['LN_DATEMODE_ALL']; if ( $filters['filter_datemode'] == DATEMODE_ALL ) { $content['datemodes'][0]['selected'] = "selected"; } else { $content['datemodes'][0]['selected'] = ""; } $content['datemodes'][1]['ID'] = DATEMODE_RANGE; $content['datemodes'][1]['DisplayName'] = $content['LN_DATEMODE_RANGE']; if ( $filters['filter_datemode'] == DATEMODE_RANGE ) { $content['datemodes'][1]['selected'] = "selected"; } else { $content['datemodes'][1]['selected'] = ""; } $content['datemodes'][2]['ID'] = DATEMODE_LASTX; $content['datemodes'][2]['DisplayName'] = $content['LN_DATEMODE_LASTX']; if ( $filters['filter_datemode'] == DATEMODE_LASTX ) { $content['datemodes'][2]['selected'] = "selected"; } else { $content['datemodes'][2]['selected'] = ""; } // Init Date Range Parameters global $currentTime, $currentDay, $currentMonth, $currentYear, $tomorrowTime, $tomorrowDay, $tomorrowMonth, $tomorrowYear; $currentTime = time(); $currentDay = date("d", $currentTime); $currentMonth = date("m", $currentTime); $currentYear = date("Y", $currentTime); $tomorrowTime = time(); // + 86400; // Add one day! $tomorrowDay = date("d", $tomorrowTime); $tomorrowMonth = date("m", $tomorrowTime); $tomorrowYear = date("Y", $tomorrowTime); // Init Year, month and day array! for ( $i = $currentYear-5; $i <= $currentYear+5; $i++ ) $content['years'][] = $i; for ( $i = 1; $i <= 12; $i++ ) $content['months'][] = $i; for ( $i = 1; $i <= 31; $i++ ) $content['days'][] = $i; // Init Hour, minute and second array for ( $i = 0; $i <= 23; $i++ ) { if ($i < 10) $content['hours'][] = '0' . $i; else $content['hours'][] = $i; } for ( $i = 0; $i <= 59; $i++ ) { if ($i < 10) $content['minutes'][] = '0' . $i; else $content['minutes'][] = $i; } for ( $i = 0; $i <= 59; $i++ ) { if ($i < 10) $content['seconds'][] = '0' . $i; else $content['seconds'][] = $i; } // Init filter_daterange_from_year if ( isset($_SESSION['filter_daterange_from_year']) ) $filters['filter_daterange_from_year'] = intval($_SESSION['filter_daterange_from_year']); else $filters['filter_daterange_from_year'] = $currentYear-1; FillDateRangeArray($content['years'], "filter_daterange_from_year_list", "filter_daterange_from_year"); // Init filter_daterange_from_month if ( isset($_SESSION['filter_daterange_from_month']) ) $filters['filter_daterange_from_month'] = intval($_SESSION['filter_daterange_from_month']); else $filters['filter_daterange_from_month'] = $currentMonth; FillDateRangeArray($content['months'], "filter_daterange_from_month_list", "filter_daterange_from_month"); // Init filter_daterange_from_day if ( isset($_SESSION['filter_daterange_from_day']) ) $filters['filter_daterange_from_day'] = intval($_SESSION['filter_daterange_from_day']); else $filters['filter_daterange_from_day'] = $currentDay; FillDateRangeArray($content['days'], "filter_daterange_from_day_list", "filter_daterange_from_day"); // Init filter_daterange_to_year if ( isset($_SESSION['filter_daterange_to_year']) ) $filters['filter_daterange_to_year'] = intval($_SESSION['filter_daterange_to_year']); else $filters['filter_daterange_to_year'] = $tomorrowYear; FillDateRangeArray($content['years'], "filter_daterange_to_year_list", "filter_daterange_to_year"); // Init filter_daterange_to_month if ( isset($_SESSION['filter_daterange_to_month']) ) $filters['filter_daterange_to_month'] = intval($_SESSION['filter_daterange_to_month']); else $filters['filter_daterange_to_month'] = $tomorrowMonth; FillDateRangeArray($content['months'], "filter_daterange_to_month_list", "filter_daterange_to_month"); // Init filter_daterange_to_day if ( isset($_SESSION['filter_daterange_to_day']) ) $filters['filter_daterange_to_day'] = intval($_SESSION['filter_daterange_to_day']); else $filters['filter_daterange_to_day'] = $tomorrowDay; FillDateRangeArray($content['days'], "filter_daterange_to_day_list", "filter_daterange_to_day"); // Init filter_daterange_from_hour if ( isset($_SESSION['filter_daterange_from_hour']) ) $filters['filter_daterange_from_hour'] = intval($_SESSION['filter_daterange_from_hour']); else $filters['filter_daterange_from_hour'] = 0; FillDateRangeArray($content['hours'], "filter_daterange_from_hour_list", "filter_daterange_from_hour"); // Init filter_daterange_from_minute if ( isset($_SESSION['filter_daterange_from_minute']) ) $filters['filter_daterange_from_minute'] = intval($_SESSION['filter_daterange_from_minute']); else $filters['filter_daterange_from_minute'] = 0; FillDateRangeArray($content['minutes'], "filter_daterange_from_minute_list", "filter_daterange_from_minute"); // Init filter_daterange_from_second if ( isset($_SESSION['filter_daterange_from_second']) ) $filters['filter_daterange_from_second'] = intval($_SESSION['filter_daterange_from_second']); else $filters['filter_daterange_from_second'] = 0; FillDateRangeArray($content['seconds'], "filter_daterange_from_second_list", "filter_daterange_from_second"); // Init filter_daterange_to_hour if ( isset($_SESSION['filter_daterange_to_hour']) ) $filters['filter_daterange_to_hour'] = intval($_SESSION['filter_daterange_to_hour']); else $filters['filter_daterange_to_hour'] = 23; FillDateRangeArray($content['hours'], "filter_daterange_to_hour_list", "filter_daterange_to_hour"); // Init filter_daterange_to_minute if ( isset($_SESSION['filter_daterange_to_minute']) ) $filters['filter_daterange_to_minute'] = intval($_SESSION['filter_daterange_to_minute']); else $filters['filter_daterange_to_minute'] = 59; FillDateRangeArray($content['minutes'], "filter_daterange_to_minute_list", "filter_daterange_to_minute"); // Init filter_daterange_to_second if ( isset($_SESSION['filter_daterange_to_second']) ) $filters['filter_daterange_to_second'] = intval($_SESSION['filter_daterange_to_second']); else $filters['filter_daterange_to_second'] = 59; FillDateRangeArray($content['seconds'], "filter_daterange_to_second_list", "filter_daterange_to_second"); // --- Define LASTX Array // Init Default DateMode from SESSION! if ( isset($_SESSION['filter_lastx_default']) ) $filters['filter_lastx_default'] = intval($_SESSION['filter_lastx_default']); else $filters['filter_lastx_default'] = DATE_LASTX_24HOURS; $content['filter_daterange_last_x_list'][0]['ID'] = DATE_LASTX_HOUR; $content['filter_daterange_last_x_list'][0]['DisplayName'] = $content['LN_DATE_LASTX_HOUR']; if ( $filters['filter_lastx_default'] == DATE_LASTX_HOUR ) { $content['filter_daterange_last_x_list'][0]['selected'] = "selected"; } else { $content['filter_daterange_last_x_list'][0]['selected'] = ""; } $content['filter_daterange_last_x_list'][1]['ID'] = DATE_LASTX_12HOURS; $content['filter_daterange_last_x_list'][1]['DisplayName'] = $content['LN_DATE_LASTX_12HOURS']; if ( $filters['filter_lastx_default'] == DATE_LASTX_12HOURS ) { $content['filter_daterange_last_x_list'][1]['selected'] = "selected"; } else { $content['filter_daterange_last_x_list'][1]['selected'] = ""; } $content['filter_daterange_last_x_list'][2]['ID'] = DATE_LASTX_24HOURS; $content['filter_daterange_last_x_list'][2]['DisplayName'] = $content['LN_DATE_LASTX_24HOURS']; if ( $filters['filter_lastx_default'] == DATE_LASTX_24HOURS ) { $content['filter_daterange_last_x_list'][2]['selected'] = "selected"; } else { $content['filter_daterange_last_x_list'][2]['selected'] = ""; } $content['filter_daterange_last_x_list'][3]['ID'] = DATE_LASTX_7DAYS; $content['filter_daterange_last_x_list'][3]['DisplayName'] = $content['LN_DATE_LASTX_7DAYS']; if ( $filters['filter_lastx_default'] == DATE_LASTX_7DAYS ) { $content['filter_daterange_last_x_list'][3]['selected'] = "selected"; } else { $content['filter_daterange_last_x_list'][3]['selected'] = ""; } $content['filter_daterange_last_x_list'][4]['ID'] = DATE_LASTX_31DAYS; $content['filter_daterange_last_x_list'][4]['DisplayName'] = $content['LN_DATE_LASTX_31DAYS']; if ( $filters['filter_lastx_default'] == DATE_LASTX_31DAYS ) { $content['filter_daterange_last_x_list'][4]['selected'] = "selected"; } else { $content['filter_daterange_last_x_list'][4]['selected'] = ""; } // --- // --- Init Default Syslog Facility from SESSION! if ( isset($_SESSION['filter_facility']) ) $filters['filter_facility'] = intval($_SESSION['filter_facility']); else $filters['filter_facility'] = array ( SYSLOG_KERN, SYSLOG_USER, SYSLOG_MAIL, SYSLOG_DAEMON, SYSLOG_AUTH, SYSLOG_SYSLOG, SYSLOG_LPR, SYSLOG_NEWS, SYSLOG_UUCP, SYSLOG_CRON, SYSLOG_SECURITY, SYSLOG_FTP, SYSLOG_NTP, SYSLOG_LOGAUDIT, SYSLOG_LOGALERT, SYSLOG_CLOCK, SYSLOG_LOCAL0, SYSLOG_LOCAL1, SYSLOG_LOCAL2, SYSLOG_LOCAL3, SYSLOG_LOCAL4, SYSLOG_LOCAL5, SYSLOG_LOCAL6, SYSLOG_LOCAL7 ); $iCount = count($content['filter_facility_list']); for ( $i = 0; $i < $iCount; $i++ ) { if ( in_array($content['filter_facility_list'][$i]["ID"], $filters['filter_facility']) ) $content['filter_facility_list'][$i]["selected"] = "selected"; } // --- // --- Init Default Syslog Severity from SESSION! if ( isset($_SESSION['filter_severity']) ) $filters['filter_severity'] = intval($_SESSION['filter_severity']); else $filters['filter_severity'] = array ( SYSLOG_EMERG, SYSLOG_ALERT, SYSLOG_CRIT, SYSLOG_ERR, SYSLOG_WARNING, SYSLOG_NOTICE, SYSLOG_INFO, SYSLOG_DEBUG ); $iCount = count($content['filter_severity_list']); for ( $i = 0; $i < $iCount; $i++ ) { if ( in_array( $content['filter_severity_list'][$i]["ID"], $filters['filter_severity']) ) $content['filter_severity_list'][$i]["selected"] = "selected"; } // --- // --- Init Default Message Type from SESSION! if ( isset($_SESSION['filter_messagetype']) ) $filters['filter_messagetype'] = intval($_SESSION['filter_messagetype']); else $filters['filter_messagetype'] = array ( IUT_Syslog, IUT_NT_EventReport, IUT_File_Monitor, IUT_WEBSERVERLOG ); $iCount = count($content['filter_messagetype_list']); for ( $i = 0; $i < $iCount; $i++ ) { if ( in_array( $content['filter_messagetype_list'][$i]["ID"], $filters['filter_messagetype']) ) $content['filter_messagetype_list'][$i]["selected"] = "selected"; } // --- } function FillDateRangeArray($sourcearray, $szArrayListName, $szFilterName) // $content['years'], "filter_daterange_from_year_list", "filter_daterange_from_year") { global $content, $filters; $iCount = count($sourcearray); for ( $i = 0; $i < $iCount; $i++) { $content[$szArrayListName][$i]['value'] = $sourcearray[$i]; if ( $filters[$szFilterName] == $sourcearray[$i] ) $content[$szArrayListName][$i]['selected'] = "selected"; else $content[$szArrayListName][$i]['selected'] = ""; } } function GetFacilityDisplayName( $nFacilityID ) { global $content; foreach( $content['filter_facility_list'] as $myfacility ) { if ( $myfacility['ID'] == $nFacilityID ) return $myfacility['DisplayName']; } // Default return "Unknown Facility($nFacilityID)"; } function GetSeverityDisplayName( $nSeverityID ) { global $content; foreach( $content['filter_severity_list'] as $myseverity ) { if ( $myseverity['ID'] == $nSeverityID ) return $myseverity['DisplayName']; } // Default return "Unknown Severity($nSeverityID)"; } function GetMessageTypeDisplayName( $nMsgTypeID ) { global $content; foreach( $content['filter_messagetype_list'] as $mymsgtype ) { if ( $mymsgtype['ID'] == $nMsgTypeID ) return $mymsgtype['DisplayName']; } // Default return "Unknown MessageType($nMsgTypeID)"; } function GetTimeStampFromTimeString($szTimeString) { //Sample: 2008-4-1T00:00:00 if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2})T([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})$/", $szTimeString, $out) ) { // return new timestamp return mktime($out[4], $out[5], $out[6], $out[2], $out[3], $out[1]); } //Sample: 2008-04-01 else if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2})$/", $szTimeString, $out) ) { // return new timestamp return mktime(0,0,0, $out[2], $out[3], $out[1]); } else { OutputDebugMessage("Unparseable Time in GetTimeStampFromTimeString - '" . $szTimeString . "'", DEBUG_WARN); return $szTimeString; } } function GetDateTimeDetailsFromTimeString($szTimeString, &$second, &$minute, &$hour, &$day, &$month, &$year) { //Sample: 2008-4-1T00:00:00 if ( preg_match("/([0-9]{4,4})-([0-9]{1,2})-([0-9]{1,2})T([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})$/", $szTimeString, $out) ) { // Assign parameters $second = $out[6]; $minute = $out[5]; $hour = $out[4]; $day = $out[3]; $month = $out[2]; $year = $out[1]; // Success! return true; } else // Failed return false; } ?>loganalyzer-3.6.5/src/include/db_update_v4.txt0000644000175000017500000000021712225176641020647 0ustar danieldaniel-- New Database Structure Updates ALTER TABLE `logcon_sources` ADD `Description` TEXT NOT NULL AFTER `Name` ; -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/db_update_v6.txt0000644000175000017500000000022612225176641020651 0ustar danieldaniel-- New Database Structure Updates ALTER TABLE `logcon_config` ADD `propvalue_text` TEXT NOT NULL AFTER `propvalue` ; -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/functions_reports.php0000644000175000017500000002051412225176641022047 0ustar danieldaniel * * * * All directives are explained within this file * * * Copyright (C) 2008-2011 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- // --- BEGIN Helper functions // --- function CreateCronCommand( $myReportID, $mySavedReportID = null ) { global $content, $gl_root_path, $myReport; if ( isset($mySavedReportID) ) { // Get Reference to report! $myReport = $content['REPORTS'][ $myReportID ]; // Get reference to savedreport $mySavedReport = $myReport['SAVEDREPORTS'][ $mySavedReportID ]; // Get configured Source for savedreport $myReportSource = null; if ( isset($content['Sources'][ $mySavedReport['sourceid'] ]) ) $myReportSource = $content['Sources'][ $mySavedReport['sourceid'] ]; $pos = strpos( strtoupper(PHP_OS), "WIN"); if ($pos !== false) { // Running on Windows $phpCmd = PHP_BINDIR . "\\php.exe"; $phpScript = realpath($gl_root_path) . "\\cron\\cmdreportgen.php"; } else { // Running on LINUX $phpCmd = PHP_BINDIR . "/php"; $phpScript = realpath($gl_root_path) . "/cron/cmdreportgen.php"; } // Enable display of report command $content['enableCronCommand'] = true; $szCommand = $phpCmd . " " . $phpScript . " runreport " . $myReportID . " " . $mySavedReportID; // --- Check for user or group sources if ( $myReportSource['userid'] != null ) { $szCommand .= " " . "userid=" . $myReportSource['userid']; } else if ( $myReportSource['groupid'] != null ) { $szCommand .= " " . "groupid=" . $myReportSource['groupid']; } // --- } else { // Disable display of report command $content['enableCronCommand'] = false; $szCommand = ""; } // return result return $szCommand; } function InitOnlineReports() { global $content; $xmlArray = xml2array( URL_ONLINEREPORTS ); if ( is_array($xmlArray) && isset($xmlArray['reports']['report']) && count($xmlArray['reports']['report']) > 0 ) { foreach( $xmlArray['reports']['report'] as $myOnlineReport ) { // Copy to OnlineReports Array $content['ONLINEREPORTS'][] = $myOnlineReport; } // Success! return true; } else // Failure return false; } // Helper function from php doc function xml2array($url, $get_attributes = 1, $priority = 'tag') { $contents = ""; if (!function_exists('xml_parser_create')) { return false; } $parser = xml_parser_create(''); if (!($fp = @ fopen($url, 'rb'))) { return false; } while (!feof($fp)) { $contents .= fread($fp, 8192); } fclose($fp); xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); xml_parse_into_struct($parser, trim($contents), $xml_values); xml_parser_free($parser); if (!$xml_values) return; //Hmm... $xml_array = array (); $parents = array (); $opened_tags = array (); $arr = array (); $current = & $xml_array; $repeated_tag_index = array (); foreach ($xml_values as $data) { unset ($attributes, $value); extract($data); $result = array (); $attributes_data = array (); if (isset ($value)) { if ($priority == 'tag') $result = $value; else $result['value'] = $value; } if (isset ($attributes) and $get_attributes) { foreach ($attributes as $attr => $val) { if ($priority == 'tag') $attributes_data[$attr] = $val; else $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr' } } if ($type == "open") { $parent[$level -1] = & $current; if (!is_array($current) or (!in_array($tag, array_keys($current)))) { $current[$tag] = $result; if ($attributes_data) $current[$tag . '_attr'] = $attributes_data; $repeated_tag_index[$tag . '_' . $level] = 1; $current = & $current[$tag]; } else { if (isset ($current[$tag][0])) { $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result; $repeated_tag_index[$tag . '_' . $level]++; } else { $current[$tag] = array ( $current[$tag], $result ); $repeated_tag_index[$tag . '_' . $level] = 2; if (isset ($current[$tag . '_attr'])) { $current[$tag]['0_attr'] = $current[$tag . '_attr']; unset ($current[$tag . '_attr']); } } $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1; $current = & $current[$tag][$last_item_index]; } } elseif ($type == "complete") { if (!isset ($current[$tag])) { $current[$tag] = $result; $repeated_tag_index[$tag . '_' . $level] = 1; if ($priority == 'tag' and $attributes_data) $current[$tag . '_attr'] = $attributes_data; } else { if (isset ($current[$tag][0]) and is_array($current[$tag])) { $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result; if ($priority == 'tag' and $get_attributes and $attributes_data) { $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data; } $repeated_tag_index[$tag . '_' . $level]++; } else { $current[$tag] = array ( $current[$tag], $result ); $repeated_tag_index[$tag . '_' . $level] = 1; if ($priority == 'tag' and $get_attributes) { if (isset ($current[$tag . '_attr'])) { $current[$tag]['0_attr'] = $current[$tag . '_attr']; unset ($current[$tag . '_attr']); } if ($attributes_data) { $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data; } } $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken } } } elseif ($type == 'close') { $current = & $parent[$level -1]; } } return ($xml_array); } ?>loganalyzer-3.6.5/src/include/functions_db.php0000644000175000017500000003021612225176641020736 0ustar danieldaniel Needed to establish and maintain the DB connetion * * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- $userdbconn = 0; $errdesc = ""; $errno = 0; // --- Current Database Version, this is important for automated database Updates! $content['database_internalversion'] = "10"; // Whenever incremented, a database upgrade is needed $content['database_installedversion'] = "0"; // 0 is default which means Prior Versioning Database // --- function DB_Connect() { global $userdbconn; // Avoid if already OPEN if ($userdbconn) return; $userdbconn = @mysql_connect( GetConfigSetting("UserDBServer") . ":" . GetConfigSetting("UserDBPort"), GetConfigSetting("UserDBUser"), GetConfigSetting("UserDBPass")); if (!$userdbconn) { // Create Error Msg $szErrorMsg = "Failed to establish a connection to the configured MYSQL Server.
LogAnalyzer is not able to initialize the user system."; if ( isset($php_errormsg) ) $szErrorMsg .= "

Extra Error Details:
" . $php_errormsg; DieWithErrorMsg( $szErrorMsg ); } //TODO: Check variables first // --- Now, check Mysql DB Version! $strmysqlver = mysql_get_server_info(); if ( strpos($strmysqlver, "-") !== false ) { $sttmp = explode("-", $strmysqlver ); $szVerInfo = $sttmp[0]; } else $szVerInfo = $strmysqlver; $szVerSplit = explode(".", $szVerInfo ); //Now check for Major Version if ( $szVerSplit[0] <= 3 ) { //Unfortunatelly MYSQL 3.x is NOT Supported dude! DieWithFriendlyErrorMsg( "You are running an MySQL 3.x Database Server Version. Unfortunately MySQL 3.x is NOT supported by LogAnalyzer due the limited SQL Statement support. If this is a commercial webspace, contact your webhoster in order to upgrade to a higher MySQL Database Version. If this is your own rootserver, consider updating your MySQL Server."); } // --- $db_selected = mysql_select_db( GetConfigSetting("UserDBName"), $userdbconn ); if(!$db_selected) DB_PrintError("Cannot use database '" .GetConfigSetting("UserDBName") . "'", true); // :D Success connecting to db // TODO Do some more validating on the database } function DB_Disconnect() { global $userdbconn; mysql_close($userdbconn); } function DB_Query($query_string, $bProcessError = true, $bCritical = false) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- global $userdbconn, $querycount; $query_id = mysql_query($query_string,$userdbconn); if (!$query_id && $bProcessError) DB_PrintError("Invalid SQL: ".$query_string, $bCritical); // For the Stats ;) $querycount++; return $query_id; } function DB_FreeQuery($query_id) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- if ($query_id != false && $query_id != 1 ) mysql_free_result($query_id); } function DB_GetRow($query_id) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- $tmp = mysql_fetch_row($query_id); $results[] = $tmp; return $results[0]; } function DB_GetSingleRow($query_id, $bClose) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- if ($query_id != false && $query_id != 1 ) { $row = mysql_fetch_array($query_id, MYSQL_ASSOC); if ( $bClose ) DB_FreeQuery ($query_id); if ( isset($row) ) // Return array return $row; else return; } } function DB_GetAllRows($query_id, $bClose) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- if ($query_id != false && $query_id != 1 ) { while ($row = mysql_fetch_array($query_id, MYSQL_ASSOC)) $var[] = $row; if ( $bClose ) DB_FreeQuery ($query_id); if ( isset($var) ) { // Return array return $var; } else return; } } function DB_GetMysqlStats() { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- global $userdbconn; $status = explode(' ', mysql_stat($userdbconn)); return $status; } function DB_ReturnSimpleErrorMsg() { // Return Mysql Error return "Mysql Error " . mysql_errno() . " - Description: " . mysql_error(); } function DB_PrintError($MyErrorMsg, $DieOrNot) { global $content, $n,$HTTP_COOKIE_VARS, $errdesc, $errno, $linesep; $errdesc = mysql_error(); $errno = mysql_errno(); // Define global variable so we know an error has occured! if ( !defined('PHPLOGCON_INERROR') ) define('PHPLOGCON_INERROR', true); $errormsg="Database error: $MyErrorMsg $linesep"; $errormsg.="mysql error: $errdesc $linesep"; $errormsg.="mysql error number: $errno $linesep"; $errormsg.="Date: ".date("d.m.Y @ H:i").$linesep; $errormsg.="Script: ".getenv("REQUEST_URI").$linesep; $errormsg.="Referer: ".getenv("HTTP_REFERER").$linesep; if ($DieOrNot == true) DieWithErrorMsg( "$linesep" . $errormsg ); else { OutputDebugMessage("DB_PrintError: $errormsg", DEBUG_ERROR); if ( !isset($content['detailederror']) ) { $content['detailederror_code'] = ERROR_DB_QUERYFAILED; $content['detailederror'] = GetErrorMessage(ERROR_DB_QUERYFAILED); } else $content['detailederror'] .= "

" . GetErrorMessage(ERROR_DB_QUERYFAILED); // Append SQL Detail Error $content['detailederror'] .= "

" . $errormsg; } } function DB_RemoveParserSpecialBadChars($myString) { // DO NOT REPLACE! $returnstr = str_replace("\\","\\\\",$myString); $returnstr = str_replace("'","\\'",$myString); return $returnstr; } function DB_RemoveBadChars($myValue, $dbEngine = DB_MYSQL, $bForceStripSlahes = false) { // Check if Array if ( is_array($myValue) ) { // Array value $retArray = array(); foreach( $myValue as $mykey => $myString ) { if ( $dbEngine == DB_MSSQL ) { // MSSQL needs special treatment -.- $retArray[$mykey] = str_replace("'","''",$myString); } else { // Replace with internal PHP Functions! $retArray[$mykey] = addslashes($myString); } } // Return fixed array! return $retArray; } else { // Single value if ( $dbEngine == DB_MSSQL ) { // MSSQL needs special treatment -.- return str_replace("'","''",$myValue); } else { // Replace with internal PHP Functions! return addslashes($myValue); } } } function DB_StripSlahes($myString) { // Replace with internal PHP Functions! // if ( get_magic_quotes_gpc() ) return stripslashes($myString); // else // return $myString; } function DB_ReturnLastInsertID($myResult = false) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- global $userdbconn; return mysql_insert_id($userdbconn); } function DB_GetRowCount($query) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- if ($result = mysql_query($query)) { $num_rows = mysql_num_rows($result); mysql_free_result ($result); } return $num_rows; } function DB_GetRowCountByResult($myresult) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- if ($myresult) return mysql_num_rows($myresult); } function DB_Exec($query) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- if(mysql_query($query)) return true; else return false; } function PrepareValueForDB($szValue, $bForceStripSlahes = false) { // Wrapper for this function return DB_RemoveBadChars($szValue, null, $bForceStripSlahes); } function WriteConfigValue($szPropName, $is_global = true, $userid = false, $groupid = false, $bForceStripSlahes = false) { global $content; // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- if ( $is_global ) { if ( isset($content[$szPropName]) ) { // Copy value for DB and check for BadDB Chars! $szDbValue = PrepareValueForDB( $content[$szPropName], $bForceStripSlahes ); } else { // Set empty in this case $szDbValue = ""; $content[$szPropName] = ""; } // Copy to $CFG array as well $CFG[$szPropName] = $content[$szPropName]; // Check if we need to INSERT or UPDATE $result = DB_Query("SELECT propname FROM `" . DB_CONFIG . "` WHERE propname = '" . $szPropName . "' AND is_global = " . $is_global); $rows = DB_GetAllRows($result, true); if ( !isset($rows) ) { // New Entry if ( strlen($szDbValue) < 255 ) $result = DB_Query("INSERT INTO `" . DB_CONFIG . "` (propname, propvalue, is_global) VALUES ( '" . $szPropName . "', '" . $szDbValue . "', " . $is_global . ")"); else $result = DB_Query("INSERT INTO `" . DB_CONFIG . "` (propname, propvalue_text, is_global) VALUES ( '" . $szPropName . "', '" . $szDbValue . "', " . $is_global . ")"); DB_FreeQuery($result); } else { // Update Entry if ( strlen($szDbValue) < 255 ) $result = DB_Query("UPDATE `" . DB_CONFIG . "` SET propvalue = '" . $szDbValue . "', propvalue_text = '' WHERE propname = '" . $szPropName . "' AND is_global = " . $is_global); else $result = DB_Query("UPDATE `" . DB_CONFIG . "` SET propvalue_text = '" . $szDbValue . "', propvalue = '' WHERE propname = '" . $szPropName . "' AND is_global = " . $is_global); DB_FreeQuery($result); } } else if ( $userid != false ) { global $USERCFG; if ( isset($USERCFG[$szPropName]) ) { // Copy value for DB and check for BadDB Chars! $szDbValue = PrepareValueForDB( $USERCFG[$szPropName], $bForceStripSlahes ); } else { // Set empty in this case $szDbValue = ""; $USERCFG[$szPropName] = ""; } // Check if we need to INSERT or UPDATE $result = DB_Query("SELECT propname FROM `" . DB_CONFIG . "` WHERE propname = '" . $szPropName . "' AND userid = " . $userid); $rows = DB_GetAllRows($result, true); if ( !isset($rows) ) { // New Entry $result = DB_Query("INSERT INTO `" . DB_CONFIG . "` (propname, propvalue, userid) VALUES ( '" . $szPropName . "', '" . $szDbValue . "', " . $userid . ")"); DB_FreeQuery($result); } else { // Update Entry $result = DB_Query("UPDATE `" . DB_CONFIG . "` SET propvalue = '" . $szDbValue . "' WHERE propname = '" . $szPropName . "' AND userid = " . $userid); DB_FreeQuery($result); } } else if ( $groupid != false ) DieWithFriendlyErrorMsg( "Critical Error occured in WriteConfigValue, writing GROUP specific properties is not supported yet!" ); } function GetSingleDBEntryOnly( $myqry ) { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- $result = DB_Query( $myqry ); $row = DB_GetRow($result); DB_FreeQuery ($query_id); if ( isset($row) ) return $row[0]; else return -1; } function GetRowsAffected() { // --- Abort in this case! if ( GetConfigSetting("UserDBEnabled", false) == false ) return; // --- return mysql_affected_rows(); } ?>loganalyzer-3.6.5/src/include/functions_themes.php0000644000175000017500000001071312225176641021636 0ustar danieldaniel * * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- function CreateLanguageList() { global $gl_root_path, $content; $alldirectories = list_directories( $gl_root_path . "lang/"); for($i = 0; $i < count($alldirectories); $i++) { // --- gen_lang $content['LANGUAGES'][$i]['langcode'] = $alldirectories[$i]; if ( $content['gen_lang'] == $alldirectories[$i] ) $content['LANGUAGES'][$i]['selected'] = "selected"; else $content['LANGUAGES'][$i]['selected'] = ""; // --- // --- user_lang $content['USERLANG'][$i]['langcode'] = $alldirectories[$i]; if ( $content['user_lang'] == $alldirectories[$i] ) $content['USERLANG'][$i]['is_selected'] = "selected"; else $content['USERLANG'][$i]['is_selected'] = ""; // --- // Init Language DisplayName $content['USERLANG'][$i]['DisplayName'] = GetLanguageDisplayName( $alldirectories[$i] ); $content['LANGUAGES'][$i]['DisplayName'] = GetLanguageDisplayName( $alldirectories[$i] ); } } function CreateThemesList() { global $gl_root_path, $content; $alldirectories = list_directories( $gl_root_path . "themes/"); for($i = 0; $i < count($alldirectories); $i++) { // --- web_theme $content['STYLES'][$i]['StyleName'] = $alldirectories[$i]; if ( $content['web_theme'] == $alldirectories[$i] ) $content['STYLES'][$i]['selected'] = "selected"; else $content['STYLES'][$i]['selected'] = ""; // --- // --- user_theme $content['USERSTYLES'][$i]['StyleName'] = $alldirectories[$i]; if ( $content['user_theme'] == $alldirectories[$i] ) $content['USERSTYLES'][$i]['is_selected'] = "selected"; else $content['USERSTYLES'][$i]['is_selected'] = ""; // --- } } function VerifyTheme( $newtheme ) { global $gl_root_path; if ( is_dir( $gl_root_path . "themes/" . $newtheme ) ) return true; else return false; } function InitThemeAbout( $themename ) { global $content, $gl_root_path; $szAboutFile = $gl_root_path . "themes/" . $themename . "/about.txt"; if ( is_file( $szAboutFile ) ) { //Read About Info! $aboutfile = fopen($szAboutFile, 'r'); if (!feof ($aboutfile)) { while (!feof ($aboutfile)) { $tmpline = fgets($aboutfile, 1024); if (!isset($content["theme_madeby"]) ) $content["theme_madeby"] = substr( trim($tmpline), 0, 25); else if (!isset($content["theme_madebylink"]) ) $content["theme_madebylink"] = substr( trim($tmpline), 0, 256); else { $content["theme_madebyenable"] = "true"; break; } } } fclose($aboutfile); } else $content["theme_madebyenable"] = "false"; } function GetLanguageDisplayName( $szLangID ) { global $content, $gl_root_path; $szInfoFile = $gl_root_path . "lang/" . $szLangID . "/info.txt"; if ( is_file( $szInfoFile ) ) { //Read InfoFile! $infofile = fopen($szInfoFile, 'r'); if (!feof ($infofile)) { while (!feof ($infofile)) { // Return max 32 characters $tmpline = fgets($infofile, 1024); return substr( trim($tmpline), 0, 32); } } fclose($infofile); } else // No Info, return ID as DisplayName return $szLangID; } ?> loganalyzer-3.6.5/src/include/db_update_v2.txt0000644000175000017500000000040312225176641020642 0ustar danieldaniel-- New Database Structure Updates ALTER TABLE `logcon_sources` ADD `MsgParserList` VARCHAR( 255 ) NOT NULL AFTER `SourceType` ; ALTER TABLE `logcon_sources` ADD `MsgNormalize` BOOL NOT NULL DEFAULT '0' AFTER `MsgParserList` ; -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/constants_filters.php0000644000175000017500000001510212225176641022022 0ustar danieldaniel Stuff which has to be static and predefined * * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Some custom defines define('DATEMODE_ALL', 1); define('DATEMODE_RANGE', 2); define('DATEMODE_LASTX', 3); define('DATEMODE_RANGE_FROM', 4); define('DATEMODE_RANGE_TO', 5); define('DATEMODE_RANGE_DATE', 6); define('DATE_LASTX_HOUR', 1); define('DATE_LASTX_12HOURS', 2); define('DATE_LASTX_24HOURS', 3); define('DATE_LASTX_7DAYS', 4); define('DATE_LASTX_31DAYS', 5); // --- // Helper constants needed for parsing filters define('FILTER_TMP_KEY', 0); define('FILTER_TMP_VALUE', 1); define('FILTER_TMP_MODE', 2); define('FILTER_DATEMODE', 'datemode'); define('FILTER_TYPE', 'filtertype'); define('FILTER_DATEMODENAME', 'datemodename'); define('FILTER_VALUE', 'value'); define('FILTER_MODE', 'filtermode'); define('FILTER_MODE_INCLUDE', 1); define('FILTER_MODE_EXCLUDE', 2); define('FILTER_MODE_SEARCHFULL', 4); define('FILTER_MODE_SEARCHREGEX', 8); // --- Init Facility LIST $content['filter_facility_list'][] = array( "ID" => SYSLOG_KERN, "DisplayName" => "KERN", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_USER, "DisplayName" => "USER", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_MAIL, "DisplayName" => "MAIL", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_DAEMON, "DisplayName" => "DAEMON", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_AUTH, "DisplayName" => "AUTH", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_SYSLOG, "DisplayName" => "SYSLOG", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LPR, "DisplayName" => "LPR", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_NEWS, "DisplayName" => "NEWS", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_UUCP, "DisplayName" => "UUCP", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_CRON, "DisplayName" => "CRON", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_SECURITY, "DisplayName" => "SECURITY", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_FTP, "DisplayName" => "FTP", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_NTP, "DisplayName" => "NTP", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOGAUDIT, "DisplayName" => "LOGAUDIT", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOGALERT, "DisplayName" => "LOGALERT", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_CLOCK, "DisplayName" => "CLOCK", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOCAL0, "DisplayName" => "LOCAL0", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOCAL1, "DisplayName" => "LOCAL1", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOCAL2, "DisplayName" => "LOCAL2", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOCAL3, "DisplayName" => "LOCAL3", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOCAL4, "DisplayName" => "LOCAL4", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOCAL5, "DisplayName" => "LOCAL5", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOCAL6, "DisplayName" => "LOCAL6", "selected" => "" ); $content['filter_facility_list'][] = array( "ID" => SYSLOG_LOCAL7, "DisplayName" => "LOCAL7", "selected" => "" ); // --- // Init Severity LIST $content['filter_severity_list'][] = array( "ID" => SYSLOG_EMERG, "DisplayName" => "EMERG", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_ALERT, "DisplayName" => "ALERT", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_CRIT, "DisplayName" => "CRIT", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_ERR, "DisplayName" => "ERR", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_WARNING, "DisplayName" => "WARNING", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_NOTICE, "DisplayName" => "NOTICE", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_INFO, "DisplayName" => "INFO", "selected" => "" ); $content['filter_severity_list'][] = array( "ID" => SYSLOG_DEBUG, "DisplayName" => "DEBUG", "selected" => "" ); // --- // Init MessageType LIST //$content['filter_messagetype_list'][] = array( "ID" => IUT_Unknown, "DisplayName" => "Unknown", "selected" => "" ); $content['filter_messagetype_list'][] = array( "ID" => IUT_Syslog, "DisplayName" => "Syslog", "selected" => "" ); $content['filter_messagetype_list'][] = array( "ID" => IUT_NT_EventReport, "DisplayName" => "WinEventLog", "selected" => "" ); $content['filter_messagetype_list'][] = array( "ID" => IUT_File_Monitor, "DisplayName" => "File Monitor", "selected" => "" ); $content['filter_messagetype_list'][] = array( "ID" => IUT_WEBSERVERLOG, "DisplayName" => "Webserver Logfile", "selected" => "" ); ?>loganalyzer-3.6.5/src/include/db_update_v10.txt0000644000175000017500000000041612225176641020725 0ustar danieldaniel-- New Database Structure Updates ALTER TABLE `logcon_charts` ADD `chart_defaultfilter` VARCHAR( 1024 ) NOT NULL AFTER `chart_field` ; ALTER TABLE `logcon_sources` ADD `defaultfilter` VARCHAR( 1024 ) NOT NULL AFTER `DBRecordsPerQuery` ; -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/constants_general.php0000644000175000017500000001642012225176641021773 0ustar danieldaniel Stuff which has to be static and predefined * * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Some custom defines define('RUNMODE_COMMANDLINE', 1); define('RUNMODE_WEBSERVER', 2); define('DEBUG_ULTRADEBUG', 5); define('DEBUG_DEBUG', 4); define('DEBUG_INFO', 3); define('DEBUG_WARN', 2); define('DEBUG_ERROR', 1); define('DEBUG_ERROR_WTF', 0); define('STR_DEBUG_ULTRADEBUG', "UltraDebug"); define('STR_DEBUG_DEBUG', "Debug"); define('STR_DEBUG_INFO', "Information"); define('STR_DEBUG_WARN', "Warning"); define('STR_DEBUG_ERROR', "Error"); define('STR_DEBUG_ERROR_WTF', "WTF OMFG"); // --- Config Level defines define('CFGLEVEL_GLOBAL', 0); define('CFGLEVEL_GROUP', 1); define('CFGLEVEL_USER', 2); // --- // --- Source Type defines define('SOURCE_DISK', '1'); define('SOURCE_DB', '2'); define('SOURCE_PDO', '3'); define('SOURCE_MONGODB', '4'); // --- // --- Exportformat defines define('EXPORT_CVS', 'CVS'); define('EXPORT_XML', 'XML'); // --- // --- GFX Chart Types define('CHART_CAKE', 1); define('CHART_BARS_VERTICAL', 2); define('CHART_BARS_HORIZONTAL', 3); define('CHARTDATA_NAME', 'NAME'); define('CHARTDATA_COUNT', 'COUNT'); // --- // --- define('UID_UNKNOWN', -1); // --- // --- Define possible database types define('DB_MYSQL', 0); define('DB_MSSQL', 1); define('DB_ODBC', 2); define('DB_PGSQL', 3); define('DB_OCI', 4); define('DB_DB2', 5); define('DB_FIREBIRD', 6); define('DB_INFORMIX', 7); define('DB_SQLITE', 8); // --- // --- Define supported AUTH Methods define('USERDB_AUTH_INTERNAL', 0); define('USERDB_AUTH_LDAP', 1); // --- // --- Syslog specific defines! define('SYSLOG_KERN', 0); define('SYSLOG_USER', 1); define('SYSLOG_MAIL', 2); define('SYSLOG_DAEMON', 3); define('SYSLOG_AUTH', 4); define('SYSLOG_SYSLOG', 5); define('SYSLOG_LPR', 6); define('SYSLOG_NEWS', 7); define('SYSLOG_UUCP', 8); define('SYSLOG_CRON', 9); define('SYSLOG_SECURITY', 10); define('SYSLOG_FTP', 11); define('SYSLOG_NTP', 12); define('SYSLOG_LOGAUDIT', 13); define('SYSLOG_LOGALERT', 14); define('SYSLOG_CLOCK', 15); define('SYSLOG_LOCAL0', 16); define('SYSLOG_LOCAL1', 17); define('SYSLOG_LOCAL2', 18); define('SYSLOG_LOCAL3', 19); define('SYSLOG_LOCAL4', 20); define('SYSLOG_LOCAL5', 21); define('SYSLOG_LOCAL6', 22); define('SYSLOG_LOCAL7', 23); $facility_colors[SYSLOG_KERN] = "#F1BEA7"; $facility_colors[SYSLOG_USER] = "#F1D0A7"; $facility_colors[SYSLOG_MAIL] = "#F1E3A7"; $facility_colors[SYSLOG_DAEMON] = "#E5F1A7"; $facility_colors[SYSLOG_AUTH] = "#D3F1A7"; $facility_colors[SYSLOG_SYSLOG] = "#C1F1A7"; $facility_colors[SYSLOG_LPR] = "#A7F1D6"; $facility_colors[SYSLOG_NEWS] = "#A7F1E8"; $facility_colors[SYSLOG_UUCP] = "#A7E1F1"; $facility_colors[SYSLOG_CRON] = "#A7C8F1"; $facility_colors[SYSLOG_SECURITY] = "#F2ECD8"; $facility_colors[SYSLOG_FTP] = "#ECE3C4"; $facility_colors[SYSLOG_NTP] = "#E7DAB1"; $facility_colors[SYSLOG_LOGAUDIT] = "#F2D8E2"; $facility_colors[SYSLOG_LOGALERT] = "#ECC4D3"; $facility_colors[SYSLOG_CLOCK] = "#E7B1C5"; $facility_colors[SYSLOG_LOCAL0] = "#F2F2F2"; $facility_colors[SYSLOG_LOCAL1] = "#E4E5E6"; $facility_colors[SYSLOG_LOCAL2] = "#D6D9DA"; $facility_colors[SYSLOG_LOCAL3] = "#C9CDCF"; $facility_colors[SYSLOG_LOCAL4] = "#BEC2C4"; $facility_colors[SYSLOG_LOCAL5] = "#B1B6B9"; $facility_colors[SYSLOG_LOCAL6] = "#A3AAAD"; $facility_colors[SYSLOG_LOCAL7] = "#969DA1"; define('SYSLOG_EMERG', 0); define('SYSLOG_ALERT', 1); define('SYSLOG_CRIT', 2); define('SYSLOG_ERR', 3); define('SYSLOG_WARNING', 4); define('SYSLOG_NOTICE', 5); define('SYSLOG_INFO', 6); define('SYSLOG_DEBUG', 7); $severity_colors[SYSLOG_EMERG] = "#840A15"; $severity_colors[SYSLOG_ALERT] = "#BA0716"; $severity_colors[SYSLOG_CRIT] = "#CE0819"; $severity_colors[SYSLOG_ERR] = "#FF0A1F"; $severity_colors[SYSLOG_WARNING] = "#EF8200"; $severity_colors[SYSLOG_NOTICE] = "#14AD42"; $severity_colors[SYSLOG_INFO] = "#0C9C91"; $severity_colors[SYSLOG_DEBUG] = "#119BDE"; // --- // --- MonitorWare InfoUnit Defines | Messagetypes define('IUT_Unknown', '0'); define('IUT_Syslog', '1'); define('IUT_Heartbeat', '2'); define('IUT_NT_EventReport', '3'); define('IUT_SNMP_Trap', '4'); define('IUT_File_Monitor', '5'); define('IUT_PingProbe', '8'); define('IUT_Port_Probe', '9'); define('IUT_NTService_Monitor', '10'); define('IUT_DiskSpace_Monitor', '11'); define('IUT_DB_Monitor', '12'); define('IUT_Serial_Monitor', '13'); define('IUT_CPU_Monitor', '14'); define('IUT_AliveMonRequest', '16'); define('IUT_SMTPProbe', '17'); define('IUT_FTPProbe', '18'); define('IUT_HTTPProbe', '19'); define('IUT_POP3Probe', '20'); define('IUT_IMAPProbe', '21'); define('IUT_NNTPProbe', '22'); define('IUT_WEVTMONV2', '23'); define('IUT_SMTPLISTENER', '24'); define('IUT_WEBSERVERLOG', '10001'); $msgtype_colors[IUT_Unknown] = "#D0FBDC"; $msgtype_colors[IUT_Syslog] = "#D0FBF1"; $msgtype_colors[IUT_Heartbeat] = "#D0EEFB"; $msgtype_colors[IUT_NT_EventReport] = "#D0E5FB"; $msgtype_colors[IUT_SNMP_Trap] = "#D0DBFB"; $msgtype_colors[IUT_File_Monitor] = "#DAD0FB"; $msgtype_colors[IUT_PingProbe] = "#E0D0FB"; $msgtype_colors[IUT_Port_Probe] = "#F6D0FB"; $msgtype_colors[IUT_NTService_Monitor] = "#FBD0E7"; $msgtype_colors[IUT_DiskSpace_Monitor] = "#FBD0D3"; $msgtype_colors[IUT_DB_Monitor] = "#FBD8D0"; $msgtype_colors[IUT_Serial_Monitor] = "#FBE0D0"; $msgtype_colors[IUT_CPU_Monitor] = "#FBEBD0"; $msgtype_colors[IUT_AliveMonRequest] = "#FBF6D0"; $msgtype_colors[IUT_SMTPProbe] = "#F5FBD0"; $msgtype_colors[IUT_FTPProbe] = "#EBFBD0"; $msgtype_colors[IUT_HTTPProbe] = "#E1FBD0"; $msgtype_colors[IUT_POP3Probe] = "#D0FBD4"; $msgtype_colors[IUT_IMAPProbe] = "#D0FBE8"; $msgtype_colors[IUT_NNTPProbe] = "#D0F7FB"; $msgtype_colors[IUT_WEVTMONV2] = "#CCE4D2"; $msgtype_colors[IUT_SMTPLISTENER] = "#CCE4DE"; $msgtype_colors[IUT_WEBSERVERLOG] = "#E1FBD0"; // --- // Supported Encodings define('ENC_ISO_8859_1', "ISO-8859-1"); define('ENC_UTF8', "utf-8"); $encodings[ENC_ISO_8859_1] = array("ID" => ENC_ISO_8859_1); $encodings[ENC_UTF8] = array("ID" => ENC_UTF8); ?>loganalyzer-3.6.5/src/include/functions_debugoutput.php0000644000175000017500000001331312225176641022717 0ustar danieldaniel * * All directives are explained within this file * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- function CreateHTMLHeader() { global $RUNMODE, $content, $gl_root_path; // not needed in console mode if ( $RUNMODE == RUNMODE_COMMANDLINE ) return; global $currentclass, $currentmenuclass; $currentclass = "line0"; $currentmenuclass = "cellmenu1"; print ('
'); } function PrintDebugInfoHeader() { global $RUNMODE; global $currentmenuclass; if ( $RUNMODE == RUNMODE_COMMANDLINE ) print ( "Num.\tFacility . \tDebug Message\n" ); else if ( $RUNMODE == RUNMODE_WEBSERVER ) { print('
Number DebugLevel Facility DebugMessage
'); } } function PrintHTMLDebugInfo( $facility, $fromwhere, $szDbgInfo ) { global $content, $currentclass, $currentmenuclass, $gldbgcounter, $DEBUGMODE, $RUNMODE; // No output in this case if ( $facility > $DEBUGMODE ) return; if ( !isset($gldbgcounter) ) $gldbgcounter = 0; $gldbgcounter++; if ( $RUNMODE == RUNMODE_COMMANDLINE ) print ( $gldbgcounter . ". \t" . GetFacilityAsString($facility) . ". \t" . $fromwhere . ". \t" . $szDbgInfo . "\n" ); else if ( $RUNMODE == RUNMODE_WEBSERVER ) { print ('
' . $gldbgcounter . ' ' . GetFacilityAsString($facility) . ' ' . $fromwhere . '   ' . $szDbgInfo . '
'); // Set StyleSheetclasses if ( $currentclass == "line0" ) $currentclass = "line1"; else $currentclass = "line0"; if ( $currentmenuclass == "cellmenu1" ) $currentmenuclass = "cellmenu2"; else $currentmenuclass = "cellmenu1"; } //Flush output FlushHtmlOutput(); } function GetFacilityAsString( $facility ) { switch ( $facility ) { case DEBUG_ULTRADEBUG: return STR_DEBUG_ULTRADEBUG; case DEBUG_DEBUG: return STR_DEBUG_DEBUG; case DEBUG_INFO: return STR_DEBUG_INFO; case DEBUG_WARN: return STR_DEBUG_WARN; case DEBUG_ERROR: return STR_DEBUG_ERROR; case DEBUG_ERROR_WTF: return STR_DEBUG_ERROR_WTF; } // reach here = unknown return "*Unknown*"; } function GetDebugClassFacilityAsString( $facility ) { switch ( $facility ) { case DEBUG_ULTRADEBUG: return "debugultradebug"; case DEBUG_DEBUG: return "debugdebug"; case DEBUG_INFO: return "debuginfo"; case DEBUG_WARN: return "debugwarn"; case DEBUG_ERROR: return "debugerror"; case DEBUG_ERROR_WTF: return "debugerrorwtf"; } // reach here = unknown return "*Unknown*"; } function CreateHTMLFooter() { global $content, $ParserStart, $RUNMODE; $RenderTime = number_format( microtime_float() - $ParserStart, 4, '.', ''); // not needed in console mode if ( $RUNMODE == RUNMODE_COMMANDLINE ) return; print ('

Finished

Total running time was ' . $RenderTime . ' seconds


'); } ?>loganalyzer-3.6.5/src/include/functions_users.php0000644000175000017500000004017312225176641021515 0ustar danieldaniel * * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes //include($gl_root_path . 'include/constants_general.php'); ///include($gl_root_path . 'include/constants_logstream.php'); // --- // --- Define User System initialized! define('IS_USERSYSTEMENABLED', true); $content['IS_USERSYSTEMENABLED'] = true; // --- // --- BEGIN Usermanagement Function --- function InitUserSession() { global $USERCFG, $content; // --- Hide donate Button if not on Admin Page if ( !defined('IS_ADMINPAGE') ) $content['SHOW_DONATEBUTTON'] = false; // --- if ( isset($_SESSION['SESSION_LOGGEDIN']) ) { if ( !$_SESSION['SESSION_LOGGEDIN'] || !isset($_SESSION['SESSION_USERID']) /* Check if UserID is set! */ ) { $content['SESSION_LOGGEDIN'] = false; // Not logged in return false; } else { // Copy variables from session! $content['SESSION_LOGGEDIN'] = true; $content['SESSION_USERNAME'] = $_SESSION['SESSION_USERNAME']; $content['SESSION_USERID'] = $_SESSION['SESSION_USERID']; $content['SESSION_ISADMIN'] = $_SESSION['SESSION_ISADMIN']; $content['SESSION_ISREADONLY'] = $_SESSION['SESSION_ISREADONLY']; if ( isset($_SESSION['SESSION_GROUPIDS']) ) $content['SESSION_GROUPIDS'] = $_SESSION['SESSION_GROUPIDS']; // --- Now we obtain user specific general settings from the DB for the user! $result = DB_Query("SELECT * FROM `" . DB_CONFIG . "` WHERE userid = " . $content['SESSION_USERID']); if ( $result ) { $rows = DB_GetAllRows($result, true); // Read results from DB and overwrite in $CFG Array! if ( isset($rows ) ) { for($i = 0; $i < count($rows); $i++) { // Store and overwrite settings from the user here! $USERCFG[ $rows[$i]['propname'] ] = $rows[$i]['propvalue']; // $content[ $rows[$i]['propname'] ] = $rows[$i]['propvalue']; } } } else // Critical ERROR HERE! DieWithFriendlyErrorMsg( "Critical Error occured while trying to access the database in table '" . DB_CONFIG . "'" ); // --- if ( isset($_SESSION['UPDATEAVAILABLE']) && $_SESSION['UPDATEAVAILABLE'] ) { // Check Version numbers again to avoid update notification if update was done during meantime! if ( CompareVersionNumbers($content['BUILDNUMBER'], $_SESSION['UPDATEVERSION']) ) { $content['UPDATEVERSION'] = $_SESSION['UPDATEVERSION']; $content['isupdateavailable'] = true; $content['isupdateavailable_updatelink'] = $_SESSION['UPDATELINK']; $content['UPDATE_AVAILABLETEXT'] = GetAndReplaceLangStr($content['LN_UPDATE_AVAILABLETEXT'], $content['BUILDNUMBER'], $_SESSION['UPDATEVERSION']); } } // --- Extracheck for available database updates! if ( isset($content['database_forcedatabaseupdate']) && $content['database_forcedatabaseupdate'] == "yes" && !defined('IS_UPRGADEPAGE') ) RedirectToDatabaseUpgrade(); // --- // Successfully logged in return true; } } else { $content['SESSION_LOGGEDIN'] = false; // Not logged in ^^ return false; } } function CreateUserName( $username, $password, $is_admin ) { /* DB_RemoveBadChars() needs to be done here to maintain backwards compatibility even if it is not needed here*/ $md5pass = md5(DB_RemoveBadChars($password)); $result = DB_Query("SELECT username FROM `" . DB_USERS . "` WHERE username = '" . $username . "'"); $rows = DB_GetAllRows($result, true); if ( isset($rows) ) { DieWithFriendlyErrorMsg( "User $username already exists!" ); // User not created! return false; } else { // Create User $result = DB_Query("INSERT INTO `" . DB_USERS . "` (username, password, is_admin) VALUES ('$username', '$md5pass', $is_admin)"); DB_FreeQuery($result); // Success return true; } } function CheckUserLogin( $username, $password ) { global $content; // Check if LDAP Auth has to be used! if ( GetConfigSetting("UserDBAuthMode", USERDB_AUTH_INTERNAL) == USERDB_AUTH_LDAP) { // perform user auth using LDAP, will add user record to loganalyzer DB if necessary $myrow = CheckLDAPUserLogin( $username, $password ); } else // Normal MYSQL Login! { // TODO: SessionTime and AccessLevel check $md5pass = md5(DB_RemoveBadChars($password)); /* DB_RemoveBadChars() needs to be done here to maintain backwards compatibility even if it is not needed here*/ $sqlquery = "SELECT * FROM `" . DB_USERS . "` WHERE username = '" . $username . "' and password = '" . $md5pass . "'"; $result = DB_Query($sqlquery); $myrow = DB_GetSingleRow($result, true); } // The admin field must be set! if ( isset($myrow['is_admin']) ) { $_SESSION['SESSION_LOGGEDIN'] = true; $_SESSION['SESSION_USERNAME'] = $username; $_SESSION['SESSION_USERID'] = $myrow['ID']; $_SESSION['SESSION_ISADMIN'] = $myrow['is_admin']; // Check Readonly setting if ( $content['database_installedversion'] > 8 ) $_SESSION['SESSION_ISREADONLY'] = $myrow['is_readonly']; else $_SESSION['SESSION_ISREADONLY'] = false; $content['SESSION_LOGGEDIN'] = $_SESSION['SESSION_LOGGEDIN']; $content['SESSION_USERNAME'] = $_SESSION['SESSION_USERNAME']; $content['SESSION_USERID'] = $_SESSION['SESSION_USERID']; $content['SESSION_ISADMIN'] = $_SESSION['SESSION_ISADMIN']; $content['SESSION_ISREADONLY'] = $_SESSION['SESSION_ISREADONLY']; // --- Read Groupmember ship for the user! $sqlquery = "SELECT " . DB_GROUPMEMBERS . ".groupid, " . DB_GROUPMEMBERS . ".is_member " . "FROM `" . DB_GROUPMEMBERS . "` WHERE userid = " . $content['SESSION_USERID'] . " AND `" . DB_GROUPMEMBERS . "`.is_member = 1"; $result = DB_Query($sqlquery); $myrows = DB_GetAllRows($result, true); if ( isset($myrows ) && count($myrows) > 0 ) { for($i = 0; $i < count($myrows); $i++) { if ( isset($content['SESSION_GROUPIDS']) ) $content['SESSION_GROUPIDS'] .= ", " . $myrows[$i]['groupid']; else $content['SESSION_GROUPIDS'] = $myrows[$i]['groupid']; } } // Copy into session as well $_SESSION['SESSION_GROUPIDS'] = $content['SESSION_GROUPIDS']; // --- // ---Set LASTLOGIN Time! $result = DB_Query("UPDATE `" . DB_USERS . "` SET last_login = " . time() . " WHERE ID = " . $content['SESSION_USERID']); DB_FreeQuery($result); // --- // --- Extracheck for available database updates! if ( isset($content['database_forcedatabaseupdate']) && $content['database_forcedatabaseupdate'] == "yes" && !defined('IS_UPRGADEPAGE') ) RedirectToDatabaseUpgrade(); // --- // --- Now we check for an PhpLogCon Update $iProxyLen = strlen(GetConfigSetting("UseProxyServerForRemoteQueries", "")); if ( $iProxyLen > 0 ) { // Proxy Server configured, create a context with proxy option! $opts = array('http' => array('proxy' => 'tcp://' . GetConfigSetting("UseProxyServerForRemoteQueries", ""), 'request_fulluri' => true)); $context = stream_context_create($opts); // Create handle with my context! $myHandle = @fopen($content['UPDATEURL'], "r", false, $context); } else $myHandle = @fopen($content['UPDATEURL'], "r"); if( $myHandle ) { $myBuffer = ""; while (!feof ($myHandle)) $myBuffer .= fgets($myHandle, 4096); fclose($myHandle); $myLines = explode("\n", $myBuffer); // Compare Version numbers! if ( CompareVersionNumbers($content['BUILDNUMBER'], $myLines[0]) ) { // True means new version available! $_SESSION['UPDATEAVAILABLE'] = true; $_SESSION['UPDATEVERSION'] = $myLines[0]; if ( isset($myLines[1]) ) $_SESSION['UPDATELINK'] = $myLines[1]; else $_SESSION['UPDATELINK'] = "http://www.phplogcon.org"; } } // --- // Success ! return true; } else { /* if (isset($myrow) && is_numeric($myrow) ) { //return error code! return $myrow; } */ if ( GetConfigSetting("DebugUserLogin", 0) == 1 ) DieWithFriendlyErrorMsg( "Debug Error: Could not find user '" . $username . "'

Sessionarray
" . var_export($_SESSION, true) . "
"); // Default return false return false; } } function DoLDAPConnect() { global $content; // Open LDAP connection if (!($ldapConn=@ldap_connect($content['LDAPServer'],$content['LDAPPort']))) return false; ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3); // reached this point means success! return $ldapConn; } function DoLDAPBind($ldapConn) { global $content; // Bind as the privilegied user return ldap_bind($ldapConn, $content['LDAPBindDN'], $content['LDAPBindPassword']); } function CheckLDAPUserLogin( $username, $password ) { global $content; // Create LDAP Searchfilter $ldap_filter='(&'.$content['LDAPSearchFilter'].'('.$content['LDAPUidAttribute'].'='.$username.'))'; // Get LDAP Connection $ldapConn = DoLDAPConnect(); if ( $ldapConn ) { if ( !DoLDAPBind($ldapConn) ) { if ( GetConfigSetting("DebugUserLogin", 0) == 1 ) { // Die with error DebugLDAPErrorAndDie( GetAndReplaceLangStr($content['LN_LOGIN_LDAP_USERBINDFAILED'], $content['LDAPBindDN'], ldap_err2str(ldap_errno($ldapConn))), $ldap_filter ); } return false; } } else { if ( GetConfigSetting("DebugUserLogin", 0) == 1 ) { // Die with error DebugLDAPErrorAndDie( GetAndReplaceLangStr($content['LN_LOGIN_LDAP_SERVERFAILED'], $content['LDAPServer'] . ":" . $content['LDAPPort'], ldap_err2str(ldap_errno($ldapConn))), $ldap_filter ); } // return false in this case return false; } // Search for the user if (!($r=@ldap_search( $ldapConn, $content['LDAPBaseDN'], $ldap_filter, array("uid","cn","localentryid","userpassword") ))) { if ( GetConfigSetting("DebugUserLogin", 0) == 1 ) { // Die with error DebugLDAPErrorAndDie( GetAndReplaceLangStr($content['LN_LOGIN_LDAP_USERCOULDNOTLOGIN'], $username, ldap_err2str(ldap_errno($ldapConn))), $ldap_filter ); } // return false in this case return false; } $info = ldap_get_entries($ldapConn, $r); if (!$info || $info["count"] != 1) { if ( GetConfigSetting("DebugUserLogin", 0) == 1 ) { // Die with error DebugLDAPErrorAndDie( GetAndReplaceLangStr( $content['LN_LOGIN_LDAP_USERNOTFOUND'], $username ), $ldap_filter ); } // return false in this case return false; } // now we have the user data. Do a bind to check for his password if (!($r=@ldap_bind( $ldapConn, $info[0]['dn'],$password))) { if ( GetConfigSetting("DebugUserLogin", 0) == 1 ) { // Die with error DebugLDAPErrorAndDie( GetAndReplaceLangStr( $content['LN_LOGIN_LDAP_PASSWORDFAIL'], $username ), $ldap_filter ); } // return false in this case return false; } // for the moment when a user logs in from LDAP, create it in the DB. // then the prefs and group management is done in the DB and we don't rewrite the whole Loganalyzer code… /* DB_RemoveBadChars() needs to be done here to maintain backwards compatibility even if it is not needed here*/ $md5pass = md5(DB_RemoveBadChars($password)); // check if the user already exist $sqlquery = "SELECT * FROM `" . DB_USERS . "` WHERE username = '" . $username . "'"; $result = DB_Query($sqlquery); $myrow = DB_GetSingleRow($result, true); if (!isset($myrow['is_admin']) ) { // Create User | use password to create MD5 Hash, so technically the user could login without LDAP as well $sqlcmd = "INSERT INTO `" . DB_USERS . "` (username, password, is_admin, is_readonly) VALUES ('" . $username . "', '" . $md5pass . "', 0, 1)"; $result = DB_Query($sqlcmd); DB_FreeQuery($result); $myrow['is_admin'] = 0; $myrow['last_login'] = 0; $myrow['is_readonly'] = 1; } // Construct Row and return $myrowfinal['username'] = $username; $myrowfinal['password'] = $md5pass; $myrowfinal['dn'] = $info[0]['dn']; if ( isset($myrow['ID']) ) $myrowfinal['ID'] = $myrow['ID']; // Get from SELECT else $myrowfinal['ID'] = DB_ReturnLastInsertID(); // Get from last insert! $myrowfinal['is_admin'] = $myrow['is_admin']; $myrowfinal['is_readonly'] = $myrow['is_readonly']; $myrowfinal['last_login'] = $myrow['last_login']; return $myrowfinal; } /* * LDAP Debug Helpre function */ function DebugLDAPErrorAndDie($szErrorMsg, $szLdapFilter) { global $content; // Add extra debug if wanted! if ( GetConfigSetting("MiscShowDebugMsg", 0, CFGLEVEL_USER) == 1 ) { $szErrorMsg .= "

LDAPBind DN: " . $content['LDAPBindDN'] . "
Search Filter: " . $szLdapFilter . "
Session Array: 
" . var_export($_SESSION, true) . "
"; } // USER NOT FOUND DieWithFriendlyErrorMsg( $szErrorMsg ); } function DoLogOff() { global $content; unset( $_SESSION['SESSION_LOGGEDIN'] ); unset( $_SESSION['SESSION_USERNAME'] ); unset( $_SESSION['SESSION_USERID'] ); unset( $_SESSION['SESSION_ACCESSLEVEL'] ); // Redir to Index Page RedirectPage( "index.php"); } function RedirectToUserLogin() { global $content; // build referer $referer = $_SERVER['PHP_SELF']; if ( isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 ) $referer .= "?" . $_SERVER['QUERY_STRING']; header("Location: " . $content['BASEPATH'] . "login.php?referer=" . urlencode($referer) ); exit; } function RedirectToDatabaseUpgrade() { global $content; // build referer $referer = $_SERVER['PHP_SELF']; if ( isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 ) $referer .= "?" . $_SERVER['QUERY_STRING']; header("Location: " . $content['BASEPATH'] . "admin/upgrade.php?referer=" . urlencode($referer) ); exit; } // --- END Usermanagement Function --- /* * Helper function to obtain a list of groups for display */ function GetGroupsForSelectfield() { global $content; $sqlquery = "SELECT " . DB_GROUPS . ".ID as mygroupid, " . DB_GROUPS . ".groupname " . "FROM `" . DB_GROUPS . "`" . " ORDER BY `" . DB_GROUPS . "`.groupname"; $result = DB_Query($sqlquery); $mygroups = DB_GetAllRows($result, true); if ( isset($mygroups) && count($mygroups) > 0 ) { // Process All Groups for($i = 0; $i < count($mygroups); $i++) $mygroups[$i]['group_selected'] = ""; // Enable Group Selection array_unshift( $mygroups, array ("mygroupid" => -1, "groupname" => $content['LN_SEARCH_SELGROUPENABLE'], "group_selected" => "") ); // return result return $mygroups; } else return false; // --- } // Helper function to compare versions function CompareVersionNumbers( $oldVer, $newVer ) { // Split version numbers $currentVersion = explode(".", trim($oldVer) ); $newVersion = explode(".", trim($newVer) ); // Check if the format is correct! if ( count($newVersion) != 3 ) return false; // check for update if ( isset($newVersion[0]) && $newVersion[0] > $currentVersion[0] ) return true; else if ( isset($newVersion[1]) && $newVersion[0] == $currentVersion[0] && $newVersion[1] > $currentVersion[1] ) return true; else if ( isset($newVersion[2]) && $newVersion[0] == $currentVersion[0] && $newVersion[1] == $currentVersion[1] && $newVersion[2] > $currentVersion[2] ) return true; else return false; } ?>loganalyzer-3.6.5/src/include/db_update_v5.txt0000644000175000017500000000106612225176641020653 0ustar danieldaniel-- New Database Structure Updates CREATE TABLE `logcon_fields` ( `FieldID` varchar(64) NOT NULL, `FieldDefine` varchar(64) NOT NULL, `FieldCaption` varchar(255) NOT NULL, `FieldType` int(11) NOT NULL, `Sortable` tinyint(1) NOT NULL, `DefaultWidth` int(11) NOT NULL, `FieldAlign` varchar(32) NOT NULL, `SearchField` varchar(64) NOT NULL, `SearchOnline` tinyint(1) NOT NULL, `Trunscate` int(11) NOT NULL, PRIMARY KEY (`FieldID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='This table stores custom fields'; -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/config.sample.php0000644000175000017500000002502512225176641021010 0ustar danieldaniel Configuration need variables for the Database connection * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- UserDB options /* If UserDB is enabled, all options will and have to be configured in the database. * All Options below the UserDB options here will not be used, unless a setting * is missing in the database. */ $CFG['UserDBEnabled'] = false; $CFG['UserDBServer'] = ""; $CFG['UserDBPort'] = 3306; $CFG['UserDBName'] = ""; $CFG['UserDBPref'] = ""; $CFG['UserDBUser'] = ""; $CFG['UserDBPass'] = ""; $CFG['UserDBLoginRequired'] = false; $CFG['UserDBAuthMode'] = USERDB_AUTH_INTERNAL; // USERDB_AUTH_INTERNAL means LogAnalyzer Internal Auth // USERDB_AUTH_LDAP means Auth via LDAP Server // LDAP Auth options $CFG['LDAPServer'] = "127.0.0.1"; // LDAP server hostname or IP $CFG['LDAPPort'] = 389; // LDAP port, 389 or 636 for SSL $CFG['LDAPBaseDN'] = 'CN=Users,DC=domain,DC=local'; // Base DN for LDAP Search, this is a typical ActiveDirectory sample $CFG['LDAPSearchFilter'] = '(objectClass=user)'; // Basic Search filter $CFG['LDAPUidAttribute'] = "sAMAccountName"; // The LDAP attribute used in the search to find the user, example: uid, cn or sAMAccountName (Active Directory) // DN of the privileged user for the search $CFG['LDAPBindDN'] = 'CN=Searchuser,CN=Users,DC=domain,DC=local'; // "Searchuser" = the privilegied user used to query LDAP Directory $CFG['LDAPBindPassword'] = 'Password'; // Password of the privilegied user // --- // --- Misc Options $CFG['MiscShowDebugMsg'] = 0; // if enabled, you will get additional output on certain places $CFG['MiscDebugToSyslog'] = 0; // if enabled, debug messages from LogAnalyzer will be send to syslog on linux, and into the EventLog on Windows $CFG['MiscShowDebugGridCounter'] = 0; // Only for debugging purposes, will add a counter column into the grid! $CFG["MiscShowPageRenderStats"] = 1; // If enabled, you will see Pagerender Settings $CFG['MiscEnableGzipCompression'] = 1; // If enabled, LogAnalyzer will use gzip compression for output, we recommend // to have this option enabled, it will highly reduce bandwith usage. $CFG['MiscMaxExecutionTime'] = 30; // LogAnalyzer will try to overwrite the default script timeout with this value during runtime! // This can of course only work if LogAnalyzer is allowed to changed the script timeout. $CFG['DebugUserLogin'] = 0; // if enabled, you will see additional informations on failed logins // --- // --- Default Frontend Options $CFG['PrependTitle'] = ""; // If set, this text will be prepended withint the title tag $CFG['ViewUseTodayYesterday'] = 1; // If enabled, the date from today and yesterday is displayed as "today" and "yesterday" $CFG['ViewMessageCharacterLimit'] = 80; // Default character limit for the message gets trunscated! 0 means NO trunscation. $CFG['ViewStringCharacterLimit'] = 30; // Default character limit for all other string type fields before they get trunscated! 0 means NO trunscation. $CFG['ViewEntriesPerPage'] = 50; // Default number of syslog entries shown per page $CFG['ViewEnableDetailPopups'] = 1; // If enabled, you will see additional Details for each syslog message on mouse over. $CFG['ViewDefaultTheme'] = "default"; // This sets the default theme the user is going to see when he opens LogAnalyzer the first time. // Currently only "default" and "dark" are available. $CFG['ViewDefaultLanguage'] = "en"; // Sets the default display language $CFG['ViewEnableAutoReloadSeconds'] = 0; // If "ViewEnableAutoReloadSeconds" is set to anything higher the 0 (which means disabled), this means auto reload is enabled by default. $CFG['SearchCustomButtonCaption'] = "I'd like to feel sad"; // Default caption for the custom fast search button $CFG['SearchCustomButtonSearch'] = "error"; // Default search string for the custom search button $CFG['EnableContextLinks'] = 1; // if enabled, context links within the messages will automatically be created and added. Set this to 0 to disable all context links. $CFG['EnableIPAddressResolve'] = 1; // If enabled, IP Addresses inline messages are automatically resolved and the result is added in brackets {} behind the IP Address $CFG['SuppressDuplicatedMessages'] = 0; // If enabled, duplicated messages will be suppressed in the main display. $CFG['TreatNotFoundFiltersAsTrue'] = 0; // If you filter / search for messages, and the fields you are filtering for is not found, the filter result is treaten as TRUE! $CFG['PopupMenuTimeout'] = 3000; // This variable defines the default timeout value for popup menus in milliseconds. (those menus which popup when you click on the value of a field. $CFG['PhplogconLogoUrl'] = ""; // Put an Url to a custom toplogo you want to use. $CFG['InlineOnlineSearchIcons'] = 1; // Show online search icons $CFG['UseProxyServerForRemoteQueries'] = "";// If empty no proxy server will be used. If set to a proxy server url like 127.0.0.1:8080, LogAnalyzer will use this server for url queries like the updatecheck. $CFG['HeaderDefaultEncoding'] = ENC_ISO_8859_1; // Set default character encoding // --- // --- Custom HTML Code $CFG['InjectHtmlHeader'] = ""; // Use this variable to inject custom html into the html area! $CFG['InjectBodyHeader'] = ""; // Use this variable to inject custom html into the begin of the area! $CFG['InjectBodyFooter'] = ""; // Use this variable to inject custom html into the end of the area! // --- // --- Define which fields you want to see //$CFG['ShowMessage'] = true; // If enabled, the Message column will be appended to the columns list. //Eventlog based fields: $CFG['Columns'] = array ( SYSLOG_DATE, SYSLOG_HOST, SYSLOG_EVENT_LOGTYPE, SYSLOG_EVENT_SOURCE, /*SYSLOG_EVENT_CATEGORY, */SYSLOG_EVENT_ID, SYSLOG_MESSAGE ); //$CFG['Columns'] = array ( SYSLOG_DATE, SYSLOG_FACILITY, SYSLOG_SEVERITY, SYSLOG_HOST, SYSLOG_SYSLOGTAG, SYSLOG_MESSAGETYPE, SYSLOG_MESSAGE ); $CFG['DefaultViewsID'] = ""; // --- // --- Predefined Searches! $CFG['Search'][] = array ( "DisplayName" => "Syslog Warnings and Errors", "SearchQuery" => "filter=severity%3A0%2C1%2C2%2C3%2C4&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "Syslog Errors", "SearchQuery" => "filter=severity%3A0%2C1%2C2%2C3&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "All messages from the last hour", "SearchQuery" => "filter=datelastx%3A1&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "All messages from last 12 hours", "SearchQuery" => "filter=datelastx%3A2&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "All messages from last 24 hours", "SearchQuery" => "filter=datelastx%3A3&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "All messages from last 7 days", "SearchQuery" => "filter=datelastx%3A4&search=Search" ); $CFG['Search'][] = array ( "DisplayName" => "All messages from last 31 days", "SearchQuery" => "filter=datelastx%3A5&search=Search" ); // $CFG['Search'][] = array ( "DisplayName" => "", "SearchQuery" => "" ); // --- // --- Predefined Charts! $CFG['Charts'][] = array ( "DisplayName" => "Top Hosts", "chart_type" => CHART_BARS_HORIZONTAL, "chart_width" => 400, "chart_field" => SYSLOG_HOST, "maxrecords" => 10, "showpercent" => 0, "chart_enabled" => 1 ); $CFG['Charts'][] = array ( "DisplayName" => "SyslogTags", "chart_type" => CHART_CAKE, "chart_width" => 400, "chart_field" => SYSLOG_SYSLOGTAG, "maxrecords" => 10, "showpercent" => 0, "chart_enabled" => 1 ); $CFG['Charts'][] = array ( "DisplayName" => "Severity Occurences", "chart_type" => CHART_BARS_VERTICAL, "chart_width" => 400, "chart_field" => SYSLOG_SEVERITY, "maxrecords" => 10, "showpercent" => 1, "chart_enabled" => 1 ); $CFG['Charts'][] = array ( "DisplayName" => "Usage by Day", "chart_type" => CHART_CAKE, "chart_width" => 400, "chart_field" => SYSLOG_DATE, "maxrecords" => 10, "showpercent" => 1, "chart_enabled" => 1 ); // --- // --- Configure allowed directories for File base logstream sources $CFG['DiskAllowed'][] = "/var/log/"; // --- // --- Source Options /* Example for DiskType Source: $CFG['Sources']['Source1']['ID'] = "Source1"; $CFG['Sources']['Source1']['Name'] = "Syslog Disk File"; $CFG['Sources']['Source1']['Description'] = "More details you want to see about this source"; $CFG['Sources']['Source1']['SourceType'] = SOURCE_DISK; $CFG['Sources']['Source1']['LogLineType'] = "syslog"; $CFG['Sources']['Source1']['MsgParserList'] = ""; $CFG['Sources']['Source1']['MsgNormalize'] = 0; $CFG['Sources']['Source1']['DiskFile'] = "/var/log/syslog"; $CFG['Sources']['Source1']['ViewID'] = "SYSLOG"; $CFG['Sources']['Source2']['ID'] = "Source5"; $CFG['Sources']['Source2']['Name'] = "WinSyslog DB"; $CFG['Sources']['Source1']['Description'] = ""; $CFG['Sources']['Source2']['SourceType'] = SOURCE_DB; $CFG['Sources']['Source1']['MsgParserList'] = ""; $CFG['Sources']['Source2']['DBTableType'] = "winsyslog"; $CFG['Sources']['Source2']['DBType'] = DB_MYSQL; $CFG['Sources']['Source2']['DBServer'] = "localhost"; $CFG['Sources']['Source2']['DBName'] = "loganalyzer"; $CFG['Sources']['Source2']['DBUser'] = "root"; $CFG['Sources']['Source2']['DBPassword'] = ""; $CFG['Sources']['Source2']['DBTableName'] = "systemevents"; $CFG['Sources']['Source2']['ViewID'] = "SYSLOG"; */ // --- %Insert Source Here% // --- ?>loganalyzer-3.6.5/src/include/constants_errors.php0000644000175000017500000000560612225176641021676 0ustar danieldaniel Stuff which has to be static and predefined * * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- define('SUCCESS', 0); define('ERROR', 1); // This is a simple helper constant! which we can use to check if there even was an error! Any result code above 0 is an error! define('ERROR_FILE_NOT_FOUND', 2); define('ERROR_FILE_CANT_CLOSE', 3); define('ERROR_FILE_EOF', 4); define('ERROR_FILE_BOF', 5); define('ERROR_FILE_NOT_READABLE', 15); define('ERROR_FILE_NOMORETIME', 22); define('ERROR_UNDEFINED', 6); define('ERROR_EOS', 7); define('ERROR_NOMORERECORDS', 8); define('ERROR_FILTER_NOT_MATCH', 9); define('ERROR_SOURCENOTFOUND', 24); define('ERROR_DB_CONNECTFAILED', 10); define('ERROR_DB_CANNOTSELECTDB', 11); define('ERROR_DB_QUERYFAILED', 12); define('ERROR_DB_NOPROPERTIES', 13); define('ERROR_DB_INVALIDDBMAPPING', 14); define('ERROR_DB_INVALIDDBDRIVER', 16); define('ERROR_DB_TABLENOTFOUND', 17); define('ERROR_DB_DBFIELDNOTFOUND', 19); define('ERROR_MSG_NOMATCH', 18); define('ERROR_CHARTS_NOTCONFIGURED', 20); define('ERROR_MSG_SKIPMESSAGE', 21); define('ERROR_MSG_SCANABORTED', 23); define('ERROR_REPORT_NODATA', 25); define('ERROR_DB_INDEXESMISSING', 26); define('ERROR_DB_TRIGGERMISSING', 27); define('ERROR_DB_INDEXFAILED', 28); define('ERROR_DB_TRIGGERFAILED', 29); define('ERROR_DB_CHECKSUMERROR', 30); define('ERROR_DB_CHECKSUMCHANGEFAILED', 31); define('ERROR_DB_ADDDBFIELDFAILED', 32); define('ERROR_DB_TIMEOUTFAILED', 34); define('ERROR_PATH_NOT_ALLOWED', 33); ?>loganalyzer-3.6.5/src/include/functions_installhelpers.php0000644000175000017500000002047712225176641023412 0ustar danieldaniel Functions in this file are only used by the installer * and converter script. * * All directives are explained within this file * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- BEGIN Installer Helper Functions --- function ImportDataFile($szFileName) { global $content, $totaldbdefs; // Lets read the table definitions :) $handle = @fopen($szFileName, "r"); if ($handle === false) RevertOneStep( $content['INSTALL_STEP']-1, GetAndReplaceLangStr($content['LN_INSTALL_ERRORREADINGDBFILE'], $szFileName) ); else { while (!feof($handle)) { $buffer = fgets($handle, 4096); $pos = strpos($buffer, "--"); if ($pos === false) $totaldbdefs .= $buffer; else if ( $pos > 2 && strlen( trim($buffer) ) > 1 ) $totaldbdefs .= $buffer; } fclose($handle); } } function RevertOneStep($stepback, $errormsg) { header("Location: " . STEPSCRIPTNAME . "?step=" . $stepback . "&errormsg=" . urlencode($errormsg) ); exit; } function ForwardOneStep() { global $content; header("Location: " . STEPSCRIPTNAME . "?step=" . ($content['INSTALL_STEP']+1) ); exit; } function ConvertGeneralSettings() { global $content; // Only call the same function as in admin index! SaveGeneralSettingsIntoDB(true); } /* * Convert Custom searches into DB */ function ConvertCustomSearches() { global $CFG, $content; // Insert all searches into the DB! foreach($CFG['Search'] as $searchid => &$mySearch) { // New Entry $result = DB_Query("INSERT INTO `" . DB_SEARCHES . "` (DisplayName, SearchQuery) VALUES ( '" . PrepareValueForDB($mySearch['DisplayName']) . "', '" . PrepareValueForDB($mySearch['SearchQuery']) . "')"); $mySearch['DBID'] = DB_ReturnLastInsertID($result); DB_FreeQuery($result); } } /* * Convert Custom Charts into DB */ function ConvertCustomCharts() { global $CFG, $content; // Insert all searches into the DB! foreach($CFG['Charts'] as $chartid => &$myChart) { // New Entry $result = DB_Query("INSERT INTO `" . DB_CHARTS . "` (DisplayName, chart_enabled, chart_type, chart_width, chart_field, maxrecords, showpercent) VALUES ( '" . PrepareValueForDB($myChart['DisplayName']) . "', " . intval($myChart['chart_enabled']) . ", " . intval($myChart['chart_type']) . ", " . intval($myChart['chart_width']) . ", '" . PrepareValueForDB($myChart['chart_field']) . "', " . intval($myChart['maxrecords']) . ", " . intval($myChart['showpercent']) . " )"); $myChart['DBID'] = DB_ReturnLastInsertID($result); DB_FreeQuery($result); } } /* * Convert Custom Views into DB */ function ConvertCustomViews() { global $CFG, $content; // Insert all searches into the DB! foreach($CFG['Views'] as $viewid => &$myView) { if ( is_numeric($viewid) || $viewid == "LEGACY" ) { // Create Columns String foreach ($myView['Columns'] as $myCol ) { if ( isset($myView['ColumnsAsString']) ) $myView['ColumnsAsString'] .= ", " . $myCol; else $myView['ColumnsAsString'] = $myCol; } // New Entry $result = DB_Query("INSERT INTO `" . DB_VIEWS . "` (DisplayName, Columns) VALUES ( '" . PrepareValueForDB($myView['DisplayName']) . "', '" . PrepareValueForDB($myView['ColumnsAsString']) . "')"); $myView['DBID'] = DB_ReturnLastInsertID($result); DB_FreeQuery($result); } } // --- Check and set DefaultViewID! if ( (isset($content['DefaultViewsID']) && strlen($content['DefaultViewsID']) > 0) && (isset($CFG['Views'][$content['DefaultViewsID']]['DBID'])) ) { // Copy the new DefaultViewID back! $content['DefaultViewsID'] = $CFG['Views'][$content['DefaultViewsID']]['DBID']; $CFG['DefaultViewsID'] = $content['DefaultViewsID']; } // --- } function ConvertCustomSources() { global $CFG, $content; // Insert all searches into the DB! foreach($CFG['Sources'] as $sourceid => &$mySource) { // Correct VIEWID! if ( isset($mySource['ViewID']) ) { if ( isset($CFG['Views'][$mySource['ViewID']]['DBID']) ) $mySource['ViewID'] = $CFG['Views'][$mySource['ViewID']]['DBID']; } else $mySource['ViewID'] = ""; // Set empty default // Add New Entry if ( $mySource['SourceType'] == SOURCE_DISK ) { $result = DB_Query("INSERT INTO `" . DB_SOURCES . "` (Name, Description, SourceType, MsgParserList, MsgNormalize, ViewID, LogLineType, DiskFile) VALUES ( " . "'" . PrepareValueForDB($mySource['Name']) . "', " . "'" . PrepareValueForDB($mySource['Description']) . "', " . " " . PrepareValueForDB($mySource['SourceType']) . " , " . "'" . PrepareValueForDB($mySource['MsgParserList']) . "', " . " " . PrepareValueForDB($mySource['MsgNormalize']) . " , " . "'" . PrepareValueForDB($mySource['ViewID']) . "', " . "'" . PrepareValueForDB($mySource['LogLineType']) . "', " . "'" . PrepareValueForDB($mySource['DiskFile']) . "'" . ")"); } else if ( $mySource['SourceType'] == SOURCE_DB || $mySource['SourceType'] == SOURCE_PDO ) { // Set Default for number fields if ( !isset($mySource['DBEnableRowCounting']) ) $mySource['DBEnableRowCounting'] = 0; else // Force to number $mySource['DBEnableRowCounting'] = intval($mySource['DBEnableRowCounting']); if ( !isset($mySource['DBType']) ) $mySource['DBType'] = DB_MYSQL; // Perform the insert $result = DB_Query("INSERT INTO `" . DB_SOURCES . "` (Name, Description, SourceType, MsgParserList, MsgNormalize, ViewID, DBTableType, DBType, DBServer, DBName, DBUser, DBPassword, DBTableName, DBEnableRowCounting) VALUES ( " . "'" . PrepareValueForDB($mySource['Name']) . "', " . "'" . PrepareValueForDB($mySource['Description']) . "', " . " " . PrepareValueForDB($mySource['SourceType']) . " , " . "'" . PrepareValueForDB($mySource['MsgParserList']) . "', " . " " . PrepareValueForDB($mySource['MsgNormalize']) . " , " . "'" . PrepareValueForDB($mySource['ViewID']) . "', " . "'" . PrepareValueForDB($mySource['DBTableType']) . "', " . " " . PrepareValueForDB($mySource['DBType']) . " , " . "'" . PrepareValueForDB($mySource['DBServer']) . "', " . "'" . PrepareValueForDB($mySource['DBName']) . "', " . "'" . PrepareValueForDB($mySource['DBUser']) . "', " . "'" . PrepareValueForDB($mySource['DBPassword']) . "', " . "'" . PrepareValueForDB($mySource['DBTableName']) . "', " . " " . PrepareValueForDB($mySource['DBEnableRowCounting']) . " " . ")"); } else DieWithFriendlyErrorMsg( GetAndReplaceLangStr($content['LN_CONVERT_ERROR_SOURCEIMPORT'], $mySource['SourceType']) ); // Copy DBID! $mySource['DBID'] = DB_ReturnLastInsertID($result); DB_FreeQuery($result); } // --- Check and set DefaultSourceID! if ( (isset($content['DefaultSourceID']) && strlen($content['DefaultSourceID']) > 0) && (isset($CFG['Sources'][$content['DefaultSourceID']]['DBID'])) ) { // Copy the new DefaultSourceID back! $content['DefaultSourceID'] = $CFG['Sources'][$content['DefaultSourceID']]['DBID']; $CFG['DefaultSourceID'] = $content['DefaultSourceID']; } // --- } // --- ?>loganalyzer-3.6.5/src/include/db_update_v1.txt0000644000175000017500000000010312225176641020636 0ustar danieldaniel-- New Database Structure Updates -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/constants_logstream.php0000644000175000017500000004710112225176641022353 0ustar danieldaniel Stuff which has to be static and predefined * * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Define properties names of all know fields define('SYSLOG_UID', 'uID'); define('SYSLOG_DATE', 'timereported'); define('SYSLOG_HOST', 'FROMHOST'); define('SYSLOG_MESSAGETYPE', 'IUT'); define('SYSLOG_MESSAGE', 'msg'); // Syslog specific define('SYSLOG_FACILITY', 'syslogfacility'); define('SYSLOG_SEVERITY', 'syslogseverity'); define('SYSLOG_SYSLOGTAG', 'syslogtag'); define('SYSLOG_PROCESSID', 'procid'); // EventLog specific define('SYSLOG_EVENT_ID', 'id'); define('SYSLOG_EVENT_LOGTYPE', 'NTEventLogType'); define('SYSLOG_EVENT_SOURCE', 'sourceproc'); define('SYSLOG_EVENT_CATEGORY', 'category'); define('SYSLOG_EVENT_USER', 'user'); // Weblog specific define('SYSLOG_WEBLOG_USER', 'http_user'); define('SYSLOG_WEBLOG_METHOD', 'http_method'); define('SYSLOG_WEBLOG_URL', 'http_url'); define('SYSLOG_WEBLOG_QUERYSTRING', 'http_querystring'); define('SYSLOG_WEBLOG_PVER', 'http_ver'); define('SYSLOG_WEBLOG_STATUS', 'http_status'); define('SYSLOG_WEBLOG_BYTESSEND', 'http_bytessend'); define('SYSLOG_WEBLOG_REFERER', 'http_referer'); define('SYSLOG_WEBLOG_USERAGENT', 'http_useragent'); // Other fields define('MISC_SYSTEMID', 'misc_systenid'); define('MISC_CHECKSUM', 'misc_checksum'); // --- // Define possible FIELD Types define('FILTER_TYPE_STRING', 0); define('FILTER_TYPE_NUMBER', 1); define('FILTER_TYPE_DATE', 2); define('FILTER_TYPE_BOOL', 3); define('FILTER_TYPE_UNKNOWN', 99); // Define possible alignments define('ALIGN_CENTER', 'center'); define('ALIGN_LEFT', 'left'); define('ALIGN_RIGHT', 'right'); // Defines for Report output types define('REPORT_OUTPUT_HTML', 'html'); define('REPORT_OUTPUT_PDF', 'pdf'); // Defines for Report output targets define('REPORT_TARGET_STDOUT', 'stdout'); define('REPORT_TARGET_FILE', 'file'); define('REPORT_TARGET_EMAIL', 'mail'); // Further helper defines for output targets define('REPORT_TARGET_TYPE', 'type'); define('REPORT_TARGET_FILENAME', 'filename'); // Defines for sorting define('SORTING_ORDER_ASC', 'asc'); define('SORTING_ORDER_DESC', 'desc'); // --- Predefine fields array! $fields[SYSLOG_UID]['FieldID'] = SYSLOG_UID; $fields[SYSLOG_UID]['FieldDefine'] = 'SYSLOG_UID'; $fields[SYSLOG_UID]['FieldCaption'] = 'uID'; $fields[SYSLOG_UID]['FieldType'] = FILTER_TYPE_NUMBER; $fields[SYSLOG_UID]['Sortable'] = false; $fields[SYSLOG_UID]['DefaultWidth'] = "50"; $fields[SYSLOG_UID]['FieldAlign'] = "center"; $fields[SYSLOG_UID]['SearchOnline'] = false; $fields[SYSLOG_DATE]['FieldID'] = SYSLOG_DATE; $fields[SYSLOG_DATE]['FieldDefine'] = 'SYSLOG_DATE'; $fields[SYSLOG_DATE]['FieldCaption'] = 'Date'; $fields[SYSLOG_DATE]['FieldType'] = FILTER_TYPE_DATE; $fields[SYSLOG_DATE]['Sortable'] = true; $fields[SYSLOG_DATE]['DefaultWidth'] = "115"; $fields[SYSLOG_DATE]['FieldAlign'] = "center"; $fields[SYSLOG_DATE]['SearchOnline'] = false; $fields[SYSLOG_HOST]['FieldID'] = SYSLOG_HOST; $fields[SYSLOG_HOST]['FieldDefine'] = 'SYSLOG_HOST'; $fields[SYSLOG_HOST]['FieldCaption'] = 'Host'; $fields[SYSLOG_HOST]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_HOST]['Sortable'] = true; $fields[SYSLOG_HOST]['DefaultWidth'] = "80"; $fields[SYSLOG_HOST]['FieldAlign'] = "left"; $fields[SYSLOG_HOST]['SearchField'] = "source"; $fields[SYSLOG_HOST]['SearchOnline'] = false; $fields[SYSLOG_MESSAGETYPE]['FieldID'] = SYSLOG_MESSAGETYPE; $fields[SYSLOG_MESSAGETYPE]['FieldDefine'] = 'SYSLOG_MESSAGETYPE'; $fields[SYSLOG_MESSAGETYPE]['FieldCaption'] = 'Messagetype'; $fields[SYSLOG_MESSAGETYPE]['FieldType'] = FILTER_TYPE_NUMBER; $fields[SYSLOG_MESSAGETYPE]['Sortable'] = true; $fields[SYSLOG_MESSAGETYPE]['DefaultWidth'] = "90"; $fields[SYSLOG_MESSAGETYPE]['FieldAlign'] = "center"; $fields[SYSLOG_MESSAGETYPE]['SearchField'] = "messagetype"; $fields[SYSLOG_MESSAGETYPE]['SearchOnline'] = false; // Syslog specific $fields[SYSLOG_FACILITY]['FieldID'] = SYSLOG_FACILITY; $fields[SYSLOG_FACILITY]['FieldDefine'] = 'SYSLOG_FACILITY'; $fields[SYSLOG_FACILITY]['FieldCaption'] = 'Facility'; $fields[SYSLOG_FACILITY]['FieldType'] = FILTER_TYPE_NUMBER; $fields[SYSLOG_FACILITY]['Sortable'] = true; $fields[SYSLOG_FACILITY]['DefaultWidth'] = "50"; $fields[SYSLOG_FACILITY]['FieldAlign'] = "center"; $fields[SYSLOG_FACILITY]['SearchField'] = "facility"; $fields[SYSLOG_FACILITY]['SearchOnline'] = true; $fields[SYSLOG_SEVERITY]['FieldID'] = SYSLOG_SEVERITY; $fields[SYSLOG_SEVERITY]['FieldDefine'] = 'SYSLOG_SEVERITY'; $fields[SYSLOG_SEVERITY]['FieldCaption'] = 'Severity'; $fields[SYSLOG_SEVERITY]['FieldType'] = FILTER_TYPE_NUMBER; $fields[SYSLOG_SEVERITY]['Sortable'] = true; $fields[SYSLOG_SEVERITY]['DefaultWidth'] = "50"; $fields[SYSLOG_SEVERITY]['FieldAlign'] = "center"; $fields[SYSLOG_SEVERITY]['SearchField'] = "severity"; $fields[SYSLOG_SEVERITY]['SearchOnline'] = true; $fields[SYSLOG_SYSLOGTAG]['FieldID'] = SYSLOG_SYSLOGTAG; $fields[SYSLOG_SYSLOGTAG]['FieldDefine'] = 'SYSLOG_SYSLOGTAG'; $fields[SYSLOG_SYSLOGTAG]['FieldCaption'] = 'Syslogtag'; $fields[SYSLOG_SYSLOGTAG]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_SYSLOGTAG]['Sortable'] = true; $fields[SYSLOG_SYSLOGTAG]['DefaultWidth'] = "85"; $fields[SYSLOG_SYSLOGTAG]['FieldAlign'] = "left"; $fields[SYSLOG_SYSLOGTAG]['SearchField'] = "syslogtag"; $fields[SYSLOG_SYSLOGTAG]['SearchOnline'] = true; $fields[SYSLOG_PROCESSID]['FieldID'] = SYSLOG_PROCESSID; $fields[SYSLOG_PROCESSID]['FieldDefine'] = 'SYSLOG_PROCESSID'; $fields[SYSLOG_PROCESSID]['FieldCaption'] = 'ProcessID'; $fields[SYSLOG_PROCESSID]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_PROCESSID]['Sortable'] = true; $fields[SYSLOG_PROCESSID]['DefaultWidth'] = "65"; $fields[SYSLOG_PROCESSID]['FieldAlign'] = "center"; $fields[SYSLOG_PROCESSID]['SearchField'] = "processid"; $fields[SYSLOG_PROCESSID]['SearchOnline'] = false; // EventLog specific $fields[SYSLOG_EVENT_ID]['FieldID'] = SYSLOG_EVENT_ID; $fields[SYSLOG_EVENT_ID]['FieldDefine'] = 'SYSLOG_EVENT_ID'; $fields[SYSLOG_EVENT_ID]['FieldCaption'] = 'Event ID'; $fields[SYSLOG_EVENT_ID]['FieldType'] = FILTER_TYPE_NUMBER; $fields[SYSLOG_EVENT_ID]['Sortable'] = true; $fields[SYSLOG_EVENT_ID]['DefaultWidth'] = "65"; $fields[SYSLOG_EVENT_ID]['FieldAlign'] = "center"; $fields[SYSLOG_EVENT_ID]['SearchField'] = "eventid"; $fields[SYSLOG_EVENT_ID]['SearchOnline'] = true; $fields[SYSLOG_EVENT_LOGTYPE]['FieldID'] = SYSLOG_EVENT_LOGTYPE; $fields[SYSLOG_EVENT_LOGTYPE]['FieldDefine'] = 'SYSLOG_EVENT_LOGTYPE'; $fields[SYSLOG_EVENT_LOGTYPE]['FieldCaption'] = 'Eventlog Type'; $fields[SYSLOG_EVENT_LOGTYPE]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_EVENT_LOGTYPE]['Sortable'] = true; $fields[SYSLOG_EVENT_LOGTYPE]['DefaultWidth'] = "100"; $fields[SYSLOG_EVENT_LOGTYPE]['FieldAlign'] = "left"; $fields[SYSLOG_EVENT_LOGTYPE]['SearchField'] = "eventlogtype"; $fields[SYSLOG_EVENT_LOGTYPE]['SearchOnline'] = true; $fields[SYSLOG_EVENT_SOURCE]['FieldID'] = SYSLOG_EVENT_SOURCE; $fields[SYSLOG_EVENT_SOURCE]['FieldDefine'] = 'SYSLOG_EVENT_SOURCE'; $fields[SYSLOG_EVENT_SOURCE]['FieldCaption'] = 'Event Source'; $fields[SYSLOG_EVENT_SOURCE]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_EVENT_SOURCE]['Sortable'] = true; $fields[SYSLOG_EVENT_SOURCE]['DefaultWidth'] = "100"; $fields[SYSLOG_EVENT_SOURCE]['FieldAlign'] = "left"; $fields[SYSLOG_EVENT_SOURCE]['SearchField'] = "eventlogsource"; $fields[SYSLOG_EVENT_SOURCE]['SearchOnline'] = true; $fields[SYSLOG_EVENT_CATEGORY]['FieldID'] = SYSLOG_EVENT_CATEGORY; $fields[SYSLOG_EVENT_CATEGORY]['FieldDefine'] = 'SYSLOG_EVENT_CATEGORY'; $fields[SYSLOG_EVENT_CATEGORY]['FieldCaption'] = 'Event Category'; $fields[SYSLOG_EVENT_CATEGORY]['FieldType'] = FILTER_TYPE_NUMBER; $fields[SYSLOG_EVENT_CATEGORY]['Sortable'] = true; $fields[SYSLOG_EVENT_CATEGORY]['DefaultWidth'] = "50"; $fields[SYSLOG_EVENT_CATEGORY]['FieldAlign'] = "center"; $fields[SYSLOG_EVENT_CATEGORY]['SearchField'] = "eventcategory"; $fields[SYSLOG_EVENT_CATEGORY]['SearchOnline'] = false; $fields[SYSLOG_EVENT_USER]['FieldID'] = SYSLOG_EVENT_USER; $fields[SYSLOG_EVENT_USER]['FieldDefine'] = 'SYSLOG_EVENT_USER'; $fields[SYSLOG_EVENT_USER]['FieldCaption'] = 'Event User'; $fields[SYSLOG_EVENT_USER]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_EVENT_USER]['Sortable'] = true; $fields[SYSLOG_EVENT_USER]['DefaultWidth'] = "85"; $fields[SYSLOG_EVENT_USER]['FieldAlign'] = "left"; $fields[SYSLOG_EVENT_USER]['SearchField'] = "eventuser"; $fields[SYSLOG_EVENT_USER]['SearchOnline'] = false; // Weblogfile specific $fields[SYSLOG_WEBLOG_USER]['FieldID'] = SYSLOG_WEBLOG_USER; $fields[SYSLOG_WEBLOG_USER]['FieldDefine'] = 'SYSLOG_WEBLOG_USER'; $fields[SYSLOG_WEBLOG_USER]['FieldCaption'] = 'HTTP User'; $fields[SYSLOG_WEBLOG_USER]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_WEBLOG_USER]['Sortable'] = false; $fields[SYSLOG_WEBLOG_USER]['DefaultWidth'] = "75"; $fields[SYSLOG_WEBLOG_USER]['FieldAlign'] = "left"; $fields[SYSLOG_WEBLOG_USER]['SearchField'] = SYSLOG_WEBLOG_USER; $fields[SYSLOG_WEBLOG_USER]['SearchOnline'] = false; $fields[SYSLOG_WEBLOG_METHOD]['FieldID'] = SYSLOG_WEBLOG_METHOD; $fields[SYSLOG_WEBLOG_METHOD]['FieldDefine'] = 'SYSLOG_WEBLOG_METHOD'; $fields[SYSLOG_WEBLOG_METHOD]['FieldCaption'] = 'Method'; $fields[SYSLOG_WEBLOG_METHOD]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_WEBLOG_METHOD]['Sortable'] = false; $fields[SYSLOG_WEBLOG_METHOD]['DefaultWidth'] = "50"; $fields[SYSLOG_WEBLOG_METHOD]['FieldAlign'] = "center"; $fields[SYSLOG_WEBLOG_METHOD]['SearchField'] = SYSLOG_WEBLOG_METHOD; $fields[SYSLOG_WEBLOG_METHOD]['SearchOnline'] = false; $fields[SYSLOG_WEBLOG_URL]['FieldID'] = SYSLOG_WEBLOG_URL; $fields[SYSLOG_WEBLOG_URL]['FieldDefine'] = 'SYSLOG_WEBLOG_URL'; $fields[SYSLOG_WEBLOG_URL]['FieldCaption'] = 'URL'; $fields[SYSLOG_WEBLOG_URL]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_WEBLOG_URL]['Sortable'] = false; $fields[SYSLOG_WEBLOG_URL]['DefaultWidth'] = "200"; $fields[SYSLOG_WEBLOG_URL]['FieldAlign'] = "left"; $fields[SYSLOG_WEBLOG_URL]['SearchField'] = SYSLOG_WEBLOG_URL; $fields[SYSLOG_WEBLOG_URL]['SearchOnline'] = false; $fields[SYSLOG_WEBLOG_QUERYSTRING]['FieldID'] = SYSLOG_WEBLOG_QUERYSTRING; $fields[SYSLOG_WEBLOG_QUERYSTRING]['FieldDefine'] = 'SYSLOG_WEBLOG_QUERYSTRING'; $fields[SYSLOG_WEBLOG_QUERYSTRING]['FieldCaption'] = 'Querystring'; $fields[SYSLOG_WEBLOG_QUERYSTRING]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_WEBLOG_QUERYSTRING]['Sortable'] = false; $fields[SYSLOG_WEBLOG_QUERYSTRING]['DefaultWidth'] = "200"; $fields[SYSLOG_WEBLOG_QUERYSTRING]['FieldAlign'] = "left"; $fields[SYSLOG_WEBLOG_QUERYSTRING]['SearchField'] = SYSLOG_WEBLOG_QUERYSTRING; $fields[SYSLOG_WEBLOG_QUERYSTRING]['SearchOnline'] = false; $fields[SYSLOG_WEBLOG_PVER]['FieldID'] = SYSLOG_WEBLOG_PVER; $fields[SYSLOG_WEBLOG_PVER]['FieldDefine'] = 'SYSLOG_WEBLOG_PVER'; $fields[SYSLOG_WEBLOG_PVER]['FieldCaption'] = 'Version'; $fields[SYSLOG_WEBLOG_PVER]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_WEBLOG_PVER]['Sortable'] = false; $fields[SYSLOG_WEBLOG_PVER]['DefaultWidth'] = "50"; $fields[SYSLOG_WEBLOG_PVER]['FieldAlign'] = "center"; $fields[SYSLOG_WEBLOG_PVER]['SearchField'] = SYSLOG_WEBLOG_PVER; $fields[SYSLOG_WEBLOG_PVER]['SearchOnline'] = false; $fields[SYSLOG_WEBLOG_STATUS]['FieldID'] = SYSLOG_WEBLOG_STATUS; $fields[SYSLOG_WEBLOG_STATUS]['FieldDefine'] = 'SYSLOG_WEBLOG_STATUS'; $fields[SYSLOG_WEBLOG_STATUS]['FieldCaption'] = 'Status'; $fields[SYSLOG_WEBLOG_STATUS]['FieldType'] = FILTER_TYPE_NUMBER; $fields[SYSLOG_WEBLOG_STATUS]['Sortable'] = false; $fields[SYSLOG_WEBLOG_STATUS]['DefaultWidth'] = "50"; $fields[SYSLOG_WEBLOG_STATUS]['FieldAlign'] = "center"; $fields[SYSLOG_WEBLOG_STATUS]['SearchField'] = SYSLOG_WEBLOG_STATUS; $fields[SYSLOG_WEBLOG_STATUS]['SearchOnline'] = false; $fields[SYSLOG_WEBLOG_BYTESSEND]['FieldID'] = SYSLOG_WEBLOG_BYTESSEND; $fields[SYSLOG_WEBLOG_BYTESSEND]['FieldDefine'] = 'SYSLOG_WEBLOG_BYTESSEND'; $fields[SYSLOG_WEBLOG_BYTESSEND]['FieldCaption'] = 'Bytes Send'; $fields[SYSLOG_WEBLOG_BYTESSEND]['FieldType'] = FILTER_TYPE_NUMBER; $fields[SYSLOG_WEBLOG_BYTESSEND]['Sortable'] = false; $fields[SYSLOG_WEBLOG_BYTESSEND]['DefaultWidth'] = "75"; $fields[SYSLOG_WEBLOG_BYTESSEND]['FieldAlign'] = "left"; $fields[SYSLOG_WEBLOG_BYTESSEND]['SearchField'] = SYSLOG_WEBLOG_BYTESSEND; $fields[SYSLOG_WEBLOG_BYTESSEND]['SearchOnline'] = false; $fields[SYSLOG_WEBLOG_REFERER]['FieldID'] = SYSLOG_WEBLOG_REFERER; $fields[SYSLOG_WEBLOG_REFERER]['FieldDefine'] = 'SYSLOG_WEBLOG_REFERER'; $fields[SYSLOG_WEBLOG_REFERER]['FieldCaption'] = 'Referer'; $fields[SYSLOG_WEBLOG_REFERER]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_WEBLOG_REFERER]['Sortable'] = false; $fields[SYSLOG_WEBLOG_REFERER]['DefaultWidth'] = "200"; $fields[SYSLOG_WEBLOG_REFERER]['FieldAlign'] = "left"; $fields[SYSLOG_WEBLOG_REFERER]['SearchField'] = SYSLOG_WEBLOG_REFERER; $fields[SYSLOG_WEBLOG_REFERER]['SearchOnline'] = true; $fields[SYSLOG_WEBLOG_USERAGENT]['FieldID'] = SYSLOG_WEBLOG_USERAGENT; $fields[SYSLOG_WEBLOG_USERAGENT]['FieldDefine'] = 'SYSLOG_WEBLOG_USERAGENT'; $fields[SYSLOG_WEBLOG_USERAGENT]['FieldCaption'] = 'User Agent'; $fields[SYSLOG_WEBLOG_USERAGENT]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_WEBLOG_USERAGENT]['Sortable'] = false; $fields[SYSLOG_WEBLOG_USERAGENT]['DefaultWidth'] = "100"; $fields[SYSLOG_WEBLOG_USERAGENT]['FieldAlign'] = "left"; $fields[SYSLOG_WEBLOG_USERAGENT]['SearchField'] = SYSLOG_WEBLOG_USERAGENT; $fields[SYSLOG_WEBLOG_USERAGENT]['SearchOnline'] = true; // Misc fields $fields[MISC_SYSTEMID]['FieldID'] = MISC_SYSTEMID; $fields[MISC_SYSTEMID]['FieldDefine'] = 'MISC_SYSTEMID'; $fields[MISC_SYSTEMID]['FieldCaption'] = 'SystemID'; $fields[MISC_SYSTEMID]['FieldType'] = FILTER_TYPE_NUMBER; $fields[MISC_SYSTEMID]['Sortable'] = false; $fields[MISC_SYSTEMID]['DefaultWidth'] = "50"; $fields[MISC_SYSTEMID]['FieldAlign'] = "center"; $fields[MISC_SYSTEMID]['SearchField'] = MISC_SYSTEMID; $fields[MISC_SYSTEMID]['SearchOnline'] = false; $fields[MISC_CHECKSUM]['FieldID'] = MISC_CHECKSUM; $fields[MISC_CHECKSUM]['FieldDefine'] = 'MISC_CHECKSUM'; $fields[MISC_CHECKSUM]['FieldCaption'] = 'Checksum'; $fields[MISC_CHECKSUM]['FieldType'] = FILTER_TYPE_NUMBER; $fields[MISC_CHECKSUM]['Sortable'] = false; $fields[MISC_CHECKSUM]['DefaultWidth'] = "50"; $fields[MISC_CHECKSUM]['FieldAlign'] = "center"; $fields[MISC_CHECKSUM]['SearchField'] = MISC_CHECKSUM; $fields[MISC_CHECKSUM]['SearchOnline'] = false; // Message is the last element, this order is important for the Detail page for now! $fields[SYSLOG_MESSAGE]['FieldID'] = SYSLOG_MESSAGE; $fields[SYSLOG_MESSAGE]['FieldDefine'] = 'SYSLOG_MESSAGE'; $fields[SYSLOG_MESSAGE]['FieldCaption'] = 'Message'; $fields[SYSLOG_MESSAGE]['FieldType'] = FILTER_TYPE_STRING; $fields[SYSLOG_MESSAGE]['Sortable'] = false; $fields[SYSLOG_MESSAGE]['DefaultWidth'] = "100%"; $fields[SYSLOG_MESSAGE]['FieldAlign'] = "left"; // $fields[SYSLOG_MESSAGE]['SearchField'] = ""; $fields[SYSLOG_MESSAGE]['SearchField'] = SYSLOG_MESSAGE; $fields[SYSLOG_MESSAGE]['SearchOnline'] = false; // --- // --- Define default Database field mappings! $dbmapping['monitorware']['ID'] = "monitorware"; $dbmapping['monitorware']['DisplayName'] = "MonitorWare"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_UID] = "ID"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_DATE] = "DeviceReportedTime"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_HOST] = "FromHost"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_MESSAGETYPE] = "InfoUnitID"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_MESSAGE] = "Message"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_FACILITY] = "Facility"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_SEVERITY] = "Priority"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_SYSLOGTAG] = "SysLogTag"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_PROCESSID] = "ProcessID"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_EVENT_ID] = "EventID"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_EVENT_LOGTYPE] = "EventLogType"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_EVENT_SOURCE] = "EventSource"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_EVENT_CATEGORY] = "EventCategory"; $dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_EVENT_USER] = "EventUser"; $dbmapping['monitorware']['DBMAPPINGS'][MISC_SYSTEMID] = "SystemID"; $dbmapping['monitorware']['DBMAPPINGS'][MISC_CHECKSUM] = "Checksum"; //$dbmapping['monitorware']['DBMAPPINGS'][SYSLOG_PROCESSID] = "ProcessID"; $dbmapping['syslogng']['ID'] = "syslogng"; $dbmapping['syslogng']['DisplayName'] = "SyslogNG"; $dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_UID] = "seq"; $dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_DATE] = "datetime"; $dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_HOST] = "host"; $dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_MESSAGE] = "msg"; //NOT POSSIBLE YET $dbmapping['syslogng'][SYSLOG_FACILITY] = "Facility"; //NOT POSSIBLE YET $dbmapping['syslogng'][SYSLOG_SEVERITY] = "Priority"; $dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_SYSLOGTAG] = "tag"; $dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_PROCESSID] = "program"; $dbmapping['mongodb']['ID'] = "mongodb"; $dbmapping['mongodb']['DisplayName'] = "MongoDB"; $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_UID] = "_id"; $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_DATE] = "time"; $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_HOST] = "sys"; $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_MESSAGE] = "msg"; $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_FACILITY] = "syslog_fac"; $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_SEVERITY] = "syslog_sever"; $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_SYSLOGTAG] = "procid"; // not using syslog_tag because of PID in it $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_PROCESSID] = "pid"; $dbmapping['mongodb']['DBMAPPINGS'][MISC_CHECKSUM] = "Checksum"; $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_EVENT_LOGTYPE] = "nteventlogtype"; // Convert all fieldnames to lowercase to avoid problems with case sensitive array keys later foreach( $dbmapping as &$myMapping ) { foreach( $myMapping['DBMAPPINGS'] as &$myField ) $myField = strtolower($myField); } // --- // EventTime Constants define('EVTIME_TIMESTAMP', '0'); define('EVTIME_TIMEZONE', '1'); define('EVTIME_MICROSECONDS', '2'); ?>loganalyzer-3.6.5/src/include/db_update_v3.txt0000644000175000017500000000302212225176641020643 0ustar danieldaniel-- New Database Structure Updates CREATE TABLE IF NOT EXISTS `logcon_charts` ( `ID` int(11) NOT NULL auto_increment, `DisplayName` varchar(255) NOT NULL, `chart_enabled` tinyint(1) NOT NULL default '1', `chart_type` int(11) NOT NULL, `chart_width` int(11) NOT NULL, `chart_field` varchar(255) NOT NULL, `maxrecords` int(11) NOT NULL, `showpercent` tinyint(1) NOT NULL, `userid` int(11) default NULL, `groupid` int(11) default NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='This table contains all configured charts' AUTO_INCREMENT=1 ; -- Insert data INSERT INTO `logcon_charts` (`ID`, `DisplayName`, `chart_enabled`, `chart_type`, `chart_width`, `chart_field`, `maxrecords`, `showpercent`, `userid`, `groupid`) VALUES (1, 'Top Hosts', 1, 3, 400, 'FROMHOST', 10, 0, NULL, NULL); INSERT INTO `logcon_charts` (`ID`, `DisplayName`, `chart_enabled`, `chart_type`, `chart_width`, `chart_field`, `maxrecords`, `showpercent`, `userid`, `groupid`) VALUES (2, 'SyslogTags', 1, 1, 400, 'syslogtag', 10, 0, NULL, NULL); INSERT INTO `logcon_charts` (`ID`, `DisplayName`, `chart_enabled`, `chart_type`, `chart_width`, `chart_field`, `maxrecords`, `showpercent`, `userid`, `groupid`) VALUES (3, 'Severity Occurences', 1, 2, 400, 'syslogseverity', 10, 1, NULL, NULL); INSERT INTO `logcon_charts` (`ID`, `DisplayName`, `chart_enabled`, `chart_type`, `chart_width`, `chart_field`, `maxrecords`, `showpercent`, `userid`, `groupid`) VALUES (4, 'Usage by Day', 1, 1, 400, 'timereported', 10, 1, NULL, NULL); -- Updated Data loganalyzer-3.6.5/src/include/db_template.txt0000644000175000017500000001365612225176641020602 0ustar danieldaniel-- phpMyAdmin SQL Dump -- version 2.10.1 -- http://www.phpmyadmin.net SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -- -- Table structure for table `logcon_config` -- DROP TABLE IF EXISTS `logcon_config`; CREATE TABLE `logcon_config` ( `propname` varchar(32) NOT NULL, `propvalue` varchar(255) NULL, `propvalue_text` text NULL, `is_global` tinyint(1) NOT NULL, `userid` int(11) default NULL, `groupid` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Table to store global and user specific configurations'; -- -- Table structure for table `logcon_groupmembers` -- DROP TABLE IF EXISTS `logcon_groupmembers`; CREATE TABLE IF NOT EXISTS `logcon_groupmembers` ( `userid` int(11) NOT NULL, `groupid` int(11) NOT NULL, `is_member` tinyint(1) NOT NULL default '1' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Helpertable to store which users are in which group'; -- -- Table structure for table `logcon_groups` -- DROP TABLE IF EXISTS `logcon_groups`; CREATE TABLE IF NOT EXISTS `logcon_groups` ( `ID` int(11) NOT NULL auto_increment, `groupname` varchar(32) NOT NULL, `groupdescription` varchar(255) NOT NULL, `grouptype` int(11) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Table for phplogcon groups' AUTO_INCREMENT=1 ; -- -- Table structure for table `logcon_searches` -- DROP TABLE IF EXISTS `logcon_searches`; CREATE TABLE IF NOT EXISTS `logcon_searches` ( `ID` int(11) NOT NULL auto_increment, `DisplayName` varchar(255) NOT NULL, `SearchQuery` varchar(1024) NOT NULL, `userid` int(11) default NULL, `groupid` int(11) default NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Stores custom user searches' AUTO_INCREMENT=1 ; -- -- Table structure for table `logcon_sources` -- DROP TABLE IF EXISTS `logcon_sources`; CREATE TABLE `logcon_sources` ( `ID` int(11) NOT NULL auto_increment, `Name` varchar(255) NOT NULL, `Description` text NOT NULL, `SourceType` tinyint(4) NOT NULL, `MsgParserList` varchar(255) NOT NULL, `MsgNormalize` tinyint(1) NOT NULL default '0', `MsgSkipUnparseable` tinyint(1) NOT NULL default '0', `ViewID` varchar(64) NOT NULL, `LogLineType` varchar(64) default NULL, `DiskFile` varchar(255) default NULL, `DBTableType` varchar(64) default NULL, `DBType` tinyint(4) default NULL, `DBServer` varchar(255) default NULL, `DBName` varchar(64) default NULL, `DBUser` varchar(64) default NULL, `DBPassword` varchar(255) default NULL, `DBTableName` varchar(64) default NULL, `DBEnableRowCounting` tinyint(1) default NULL, `DBRecordsPerQuery` int(11) NOT NULL default '100', `defaultfilter` VARCHAR(1024) NOT NULL, `userid` int(11) default NULL, `groupid` int(11) default NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Table to store datasources in phplogcon' AUTO_INCREMENT=1 ; -- -- Table structure for table `logcon_users` -- DROP TABLE IF EXISTS `logcon_users`; CREATE TABLE IF NOT EXISTS `logcon_users` ( `ID` int(11) NOT NULL auto_increment, `username` varchar(32) NOT NULL, `password` varchar(32) NOT NULL, `is_admin` tinyint(1) NOT NULL default '0', `is_readonly` tinyint(1) NOT NULL DEFAULT '0', `last_login` int(4) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Table for the phplogcon users' AUTO_INCREMENT=1 ; -- -- Table structure for table `logcon_views` -- DROP TABLE IF EXISTS `logcon_views`; CREATE TABLE IF NOT EXISTS `logcon_views` ( `ID` int(11) NOT NULL auto_increment, `DisplayName` varchar(255) NOT NULL, `Columns` text NOT NULL, `userid` int(11) default NULL, `groupid` int(11) default NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Stores custom defined user views.' AUTO_INCREMENT=1 ; -- -- Table structure for table `logcon_charts` -- DROP TABLE IF EXISTS `logcon_charts`; CREATE TABLE IF NOT EXISTS `logcon_charts` ( `ID` int(11) NOT NULL auto_increment, `DisplayName` varchar(255) NOT NULL, `chart_enabled` tinyint(1) NOT NULL default '1', `chart_type` int(11) NOT NULL, `chart_width` int(11) NOT NULL, `chart_field` varchar(255) NOT NULL, `chart_defaultfilter` VARCHAR(1024) NOT NULL, `maxrecords` int(11) NOT NULL, `showpercent` tinyint(1) NOT NULL, `userid` int(11) default NULL, `groupid` int(11) default NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='This table contains all configured charts' AUTO_INCREMENT=1 ; -- -- Table structure for table `logcon_fields` -- DROP TABLE IF EXISTS `logcon_fields`; CREATE TABLE `logcon_fields` ( `FieldID` varchar(64) NOT NULL, `FieldDefine` varchar(64) NOT NULL, `FieldCaption` varchar(255) NOT NULL, `FieldType` int(11) NOT NULL, `Sortable` tinyint(1) NOT NULL, `DefaultWidth` int(11) NOT NULL, `FieldAlign` varchar(32) NOT NULL, `SearchField` varchar(64) NOT NULL, `SearchOnline` tinyint(1) NOT NULL, `Trunscate` int(11) NOT NULL, PRIMARY KEY (`FieldID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='This table stores custom fields'; -- -- Table structure for table `logcon_dbmappings` -- DROP TABLE IF EXISTS `logcon_dbmappings`; CREATE TABLE `logcon_dbmappings` ( `ID` int(11) NOT NULL auto_increment, `DisplayName` varchar(64) NOT NULL, `Mappings` varchar(1024) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; -- -- Table structure for table `logcon_savedreports` -- CREATE TABLE `logcon_savedreports` ( `ID` int(11) NOT NULL auto_increment, `reportid` varchar(255) NOT NULL, `sourceid` int(11) NOT NULL, `customTitle` varchar(255) NOT NULL, `customComment` text NOT NULL, `filterString` text NOT NULL, `customFilters` text NOT NULL, `outputFormat` varchar(64) NOT NULL, `outputTarget` varchar(64) NOT NULL, `outputTargetDetails` text NOT NULL, `scheduleSettings` text NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT = 'Table to store saved reports' AUTO_INCREMENT=1 ; loganalyzer-3.6.5/src/include/db_update_v7.txt0000644000175000017500000000043012225176641020647 0ustar danieldaniel-- New Database Structure Updates ALTER TABLE `logcon_sources` ADD `MsgSkipUnparseable` BOOL NOT NULL DEFAULT '0' AFTER `MsgNormalize` ; ALTER TABLE `logcon_sources` ADD `DBRecordsPerQuery` INT NOT NULL DEFAULT '100' AFTER `DBEnableRowCounting` ; -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/db_update_v0.txt0000644000175000017500000000010312225176641020635 0ustar danieldaniel-- New Database Structure Updates -- Insert data -- Updated Data loganalyzer-3.6.5/src/include/functions_config.php0000644000175000017500000010250312225176641021615 0ustar danieldaniel Configuration need variables for the Database connection * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Perform necessary includes require_once($gl_root_path . 'classes/logstreamconfig.class.php'); // --- function InitSource(&$mysource) { global $CFG, $content, $gl_root_path, $currentSourceID; if ( isset($mysource['SourceType']) ) { // Set Array Index, TODO: Check for invalid characters! $iSourceID = $mysource['ID']; // --- Set defaults if not set! if ( !isset($mysource['LogLineType']) ) { $CFG['Sources'][$iSourceID]['LogLineType'] = "syslog"; $content['Sources'][$iSourceID]['LogLineType'] = "syslog"; } if ( !isset($mysource['userid']) ) { $CFG['Sources'][$iSourceID]['userid'] = null; $content['Sources'][$iSourceID]['userid'] = null; } if ( !isset($mysource['groupid']) ) { $CFG['Sources'][$iSourceID]['groupid'] = null; $content['Sources'][$iSourceID]['groupid'] = null; } if ( !isset($mysource['MsgParserList']) ) { $CFG['Sources'][$iSourceID]['MsgParserList'] = null; $content['Sources'][$iSourceID]['MsgParserList'] = null; } if ( !isset($mysource['MsgNormalize']) ) { $CFG['Sources'][$iSourceID]['MsgNormalize'] = 0; $content['Sources'][$iSourceID]['MsgNormalize'] = 0; } if ( !isset($mysource['MsgSkipUnparseable']) ) { $CFG['Sources'][$iSourceID]['MsgSkipUnparseable'] = 0; $content['Sources'][$iSourceID]['MsgSkipUnparseable'] = 0; } if ( !isset($mysource['Description']) ) { $CFG['Sources'][$iSourceID]['Description'] = ""; $content['Sources'][$iSourceID]['Description'] = ""; } if ( !isset($mysource['defaultfilter']) ) { $CFG['Sources'][$iSourceID]['defaultfilter'] = ""; $content['Sources'][$iSourceID]['defaultfilter'] = ""; } // --- // Set default view id to source $tmpVar = GetConfigSetting("DefaultViewsID", "", CFGLEVEL_USER); $szDefaultViewID = strlen($tmpVar) > 0 ? $tmpVar : "SYSLOG"; if ( isset($_SESSION[$iSourceID . "-View"]) ) { // check if view is valid $UserSessionViewID = $_SESSION[$iSourceID . "-View"]; if ( isset($content['Views'][$UserSessionViewID]) ) { // Overwrite configured view! $content['Sources'][$iSourceID]['ViewID'] = $_SESSION[$iSourceID . "-View"]; } else $content['Sources'][$iSourceID]['ViewID'] = $szDefaultViewID; } else { if ( isset($mysource['ViewID']) && strlen($mysource['ViewID']) > 0 && isset($content['Views'][ $mysource['ViewID'] ]) ) // Set to configured Source ViewID $content['Sources'][$iSourceID]['ViewID'] = $mysource['ViewID']; else // Not configured, maybe old legacy cfg. Set default view. $content['Sources'][$iSourceID]['ViewID'] = $szDefaultViewID; } // Only for the display box $content['Sources'][$iSourceID]['selected'] = ""; // Create Config instance! if ( $mysource['SourceType'] == SOURCE_DISK ) { // Perform necessary include require_once($gl_root_path . 'classes/logstreamconfigdisk.class.php'); $mysource['ObjRef'] = new LogStreamConfigDisk(); $mysource['ObjRef']->SetFileName( $mysource['DiskFile'] ); $mysource['ObjRef']->LineParserType = $mysource['LogLineType']; } else if ( $mysource['SourceType'] == SOURCE_DB ) { // Perform necessary include require_once($gl_root_path . 'classes/logstreamconfigdb.class.php'); $mysource['ObjRef'] = new LogStreamConfigDB(); $mysource['ObjRef']->DBServer = $mysource['DBServer']; $mysource['ObjRef']->DBName = $mysource['DBName']; // Workaround a little bug from the installer script if ( isset($mysource['DBType']) ) $mysource['ObjRef']->DBType = $mysource['DBType']; else $mysource['ObjRef']->DBType = DB_MYSQL; $mysource['ObjRef']->DBTableName = $mysource['DBTableName']; // Legacy handling for tabletype! if ( isset($mysource['DBTableType']) && strtolower($mysource['DBTableType']) == "winsyslog" ) $mysource['ObjRef']->DBTableType = "monitorware"; // Convert to MonitorWare! else $mysource['ObjRef']->DBTableType = strtolower($mysource['DBTableType']); // Optional parameters! if ( isset($mysource['DBPort']) ) { $mysource['ObjRef']->DBPort = $mysource['DBPort']; } if ( isset($mysource['DBUser']) ) { $mysource['ObjRef']->DBUser = $mysource['DBUser']; } if ( isset($mysource['DBPassword']) ) { $mysource['ObjRef']->DBPassword = $mysource['DBPassword']; } if ( isset($mysource['DBEnableRowCounting']) ) { $mysource['ObjRef']->DBEnableRowCounting = $mysource['DBEnableRowCounting']; } if ( isset($mysource['DBRecordsPerQuery']) ) { $mysource['ObjRef']->RecordsPerQuery = $mysource['DBRecordsPerQuery']; } } else if ( $mysource['SourceType'] == SOURCE_PDO ) { // Perform necessary include require_once($gl_root_path . 'classes/logstreamconfigpdo.class.php'); $mysource['ObjRef'] = new LogStreamConfigPDO(); $mysource['ObjRef']->DBServer = $mysource['DBServer']; $mysource['ObjRef']->DBName = $mysource['DBName']; $mysource['ObjRef']->DBType = $mysource['DBType']; $mysource['ObjRef']->DBTableName = $mysource['DBTableName']; $mysource['ObjRef']->DBTableType = strtolower($mysource['DBTableType']); // Optional parameters! if ( isset($mysource['DBPort']) ) { $mysource['ObjRef']->DBPort = $mysource['DBPort']; } if ( isset($mysource['DBUser']) ) { $mysource['ObjRef']->DBUser = $mysource['DBUser']; } if ( isset($mysource['DBPassword']) ) { $mysource['ObjRef']->DBPassword = $mysource['DBPassword']; } if ( isset($mysource['DBEnableRowCounting']) ) { $mysource['ObjRef']->DBEnableRowCounting = $mysource['DBEnableRowCounting']; } } else if ( $mysource['SourceType'] == SOURCE_MONGODB) { // Perform necessary include require_once($gl_root_path . 'classes/logstreamconfigmongodb.class.php'); $mysource['ObjRef'] = new LogStreamConfigMongoDB(); $mysource['ObjRef']->DBServer = $mysource['DBServer']; $mysource['ObjRef']->DBName = $mysource['DBName']; $mysource['ObjRef']->DBCollection = $mysource['DBTableName']; $mysource['ObjRef']->DBTableType = strtolower($mysource['DBTableType']); // Optional parameters! if ( isset($mysource['DBPort']) ) { $mysource['ObjRef']->DBPort = $mysource['DBPort']; } if ( isset($mysource['DBUser']) ) { $mysource['ObjRef']->DBUser = $mysource['DBUser']; } if ( isset($mysource['DBPassword']) ) { $mysource['ObjRef']->DBPassword = $mysource['DBPassword']; } // if ( isset($mysource['DBEnableRowCounting']) ) { $mysource['ObjRef']->DBEnableRowCounting = $mysource['DBEnableRowCounting']; } } else { // UNKNOWN, remove config entry! unset($content['Sources'][$iSourceID]); // Output Debug Warning only! OutputDebugMessage( GetAndReplaceLangStr($content['LN_GEN_CRITERROR_UNKNOWNTYPE'], $mysource['SourceType']), DEBUG_ERROR); // DieWithFriendlyErrorMsg( GetAndReplaceLangStr($content['LN_GEN_CRITERROR_UNKNOWNTYPE'], $mysource['SourceType']) ); return ERROR; } // Set generic configuration options $mysource['ObjRef']->_pageCount = GetConfigSetting("ViewEntriesPerPage", 50); if ( isset($mysource['MsgParserList']) ) $mysource['ObjRef']->SetMsgParserList( $mysource['MsgParserList'] ); if ( isset($mysource['MsgNormalize']) ) $mysource['ObjRef']->SetMsgNormalize( $mysource['MsgNormalize'] ); if ( isset($mysource['MsgSkipUnparseable']) ) $mysource['ObjRef']->SetSkipUnparseable( $mysource['MsgSkipUnparseable'] ); if ( isset($mysource['defaultfilter']) ) $mysource['ObjRef']->SetDefaultfilter( $mysource['defaultfilter'] ); // Set default SourceID here! if ( isset($content['Sources'][$iSourceID]) && !isset($currentSourceID) ) $currentSourceID = $iSourceID; // Copy Object REF into CFG and content Array as well! $content['Sources'][$iSourceID]['ObjRef'] = $mysource['ObjRef']; $CFG['Sources'][$iSourceID]['ObjRef'] = $mysource['ObjRef']; } } /* * This function reads and generates a list of available message parsers */ function InitMessageParsers() { global $content, $gl_root_path; $szDirectory = $gl_root_path . 'classes/msgparsers/'; // msgparser.' . $szParser . '.class.php'; $aFiles = list_files($szDirectory, true); if ( isset($aFiles) && count($aFiles) > 0 ) { foreach( $aFiles as $myFile ) { // Check if file is valid msg parser! if ( preg_match("/msgparser\.(.*?)\.class\.php$/", $myFile, $out ) ) { // Set ParserID! $myParserID = $out[1]; // Check if parser file include exists $szIncludeFile = $szDirectory . $myFile; if ( file_exists($szIncludeFile) ) { // Try to include if ( include_once($szIncludeFile) ) { // Set ParserClassName $szParserClass = "MsgParser_" . $myParserID; /// echo $szParserClass . "
"; // Create Instance and get properties $tmpParser = new $szParserClass(); // Create an instance $szParserName = $tmpParser->_ClassName; $szParserDescription = $tmpParser->_ClassDescription; $szParserHelpArticle = $tmpParser->_ClassHelpArticle; // check for required fields! if ( $tmpParser->_ClassRequiredFields != null && count($tmpParser->_ClassRequiredFields) > 0 ) { $bCustomFields = true; $aCustomFieldList = $tmpParser->_ClassRequiredFields; // print_r ( $aCustomFieldList ); } else { $bCustomFields = false; $aCustomFieldList = null; } // Add entry to msg parser list! $content['PARSERS'][$myParserID] = array ( "ID" => $myParserID, "DisplayName" => $szParserName, "Description" => $szParserDescription, "CustomFields" => $bCustomFields, "CustomFieldsList" => $aCustomFieldList, "ParserHelpArticle" => $szParserHelpArticle, ); } else { // DEBUG ERROR OutputDebugMessage("InitMessageParsers: Failed including msgparser file '" . $szIncludeFile . "' with error: '" . $php_errormsg . "'", DEBUG_ERROR); } } else { // DEBUG ERROR OutputDebugMessage("InitMessageParsers: MsgParserfile '" . $szIncludeFile . "' does not exist!", DEBUG_ERROR); } } } } } /* * This function generates a list of available reports modules and custom reports */ function InitReportModules($szRootPath = "") { global $content, $gl_root_path; // Check for parameter if ( strlen($szRootPath) == 0 ) $szRootPath = $gl_root_path; $szDirectory = $szRootPath . 'classes/reports/'; $aFiles = list_files($szDirectory, true); if ( isset($aFiles) && count($aFiles) > 0 ) { foreach( $aFiles as $myFile ) { // Check if file is valid msg parser! if ( preg_match("/report\.(.*?)\.(.*?)\.class\.php$/", $myFile, $out ) ) { // Set ParserID! $myReportCat = $out[1]; $myReportID = $out[2]; // Check if parser file include exists $szIncludeFile = $szDirectory . $myFile; if ( file_exists($szIncludeFile) ) { // Try to include if ( include_once($szIncludeFile) ) { // Set ParserClassName $szReportClass = "Report_" . $myReportID; // Create Instance and get properties $tmpReport = new $szReportClass(); // Create an instance $szReportName = $tmpReport->_reportTitle; $szReportDescription = $tmpReport->_reportDescription; $szReportVersion= $tmpReport->_reportVersion; $szReportHelpArticle = $tmpReport->_reportHelpArticle; $bNeedsInit = $tmpReport->_reportNeedsInit; $bInitialized = $tmpReport->_reportInitialized; $aRequiredFieldsList = $tmpReport->GetRequiredProperties(); /* // check for required fields! if ( $tmpReport->_ClassRequiredFields != null && count($tmpParser->_ClassRequiredFields) > 0 ) { $bCustomFields = true; $aCustomFieldList = $tmpParser->_ClassRequiredFields; // print_r ( $aCustomFieldList ); } else { $bCustomFields = false; $aCustomFieldList = null; } */ // Add entry to report modules list! $content['REPORTS'][$myReportID] = array ( "ID" => $myReportID, "Category" => $myReportCat, "DisplayName" => $szReportName, "Description" => $szReportDescription, "ReportVersion" => $szReportVersion, "ReportHelpArticle" => $szReportHelpArticle, "NeedsInit" => $bNeedsInit, "Initialized" => $bInitialized, "ObjRef" => $tmpReport, // "CustomFields" => $bCustomFields, "RequiredFieldsList" => $aRequiredFieldsList, ); // --- Now Search and populate savedReports | but only if DB Version is 9 or higher. if ( $content['database_installedversion'] >= 9 ) { // --- Create SQL Query $sqlquery = " SELECT " . DB_SAVEDREPORTS . ".ID as SavedReportID, " . DB_SAVEDREPORTS . ".sourceid, " . DB_SAVEDREPORTS . ".customTitle, " . DB_SAVEDREPORTS . ".customComment, " . DB_SAVEDREPORTS . ".filterString, " . DB_SAVEDREPORTS . ".customFilters, " . DB_SAVEDREPORTS . ".outputFormat, " . DB_SAVEDREPORTS . ".outputTarget, " . DB_SAVEDREPORTS . ".outputTargetDetails, " . DB_SAVEDREPORTS . ".scheduleSettings " . " FROM `" . DB_SAVEDREPORTS . "`" . " WHERE `" . DB_SAVEDREPORTS . "`.reportid = '" . $myReportID . "' " . " ORDER BY `" . DB_SAVEDREPORTS . "`.customTitle"; // Get Views from DB now! $result = DB_Query($sqlquery); $myrows = DB_GetAllRows($result, true); if ( isset($myrows) && count($myrows) > 0 ) { // Set to true! $content['REPORTS'][$myReportID]['HASSAVEDREPORTS'] = true; // Add all savedreports foreach ($myrows as &$mySavedReport) { // Set default properties if not set! if (!isset($mySavedReport['outputTarget']) || strlen($mySavedReport['outputTarget']) <= 0 ) $mySavedReport['outputTarget'] = REPORT_TARGET_STDOUT; // Add saved report into global array $content['REPORTS'][$myReportID]['SAVEDREPORTS'][ $mySavedReport['SavedReportID'] ] = $mySavedReport; } } } // --- } else { // DEBUG ERROR OutputDebugMessage("InitReportModules: Failed including report file '" . $szIncludeFile . "' with error: '" . $php_errormsg . "'", DEBUG_ERROR); } } else { // DEBUG ERROR OutputDebugMessage("InitReportModules: Reportfile '" . $szIncludeFile . "' does not exist!", DEBUG_ERROR); } } } } // TODO: compare update report modules registered in database } /* * Init Source configs */ function InitSourceConfigs() { global $CFG, $content, $currentSourceID; // Init Source Configs! if ( isset($CFG['Sources']) ) { foreach( $CFG['Sources'] as &$mysource ) { // Init each source using this function! InitSource($mysource); } } // Read SourceID from GET Querystring if ( isset($_GET['sourceid']) && isset($content['Sources'][$_GET['sourceid']]) ) { $currentSourceID = $_GET['sourceid']; $_SESSION['currentSourceID'] = $currentSourceID; } else { // Set Source from session if available! if ( isset($_SESSION['currentSourceID']) && isset($content['Sources'][$_SESSION['currentSourceID']]) ) $currentSourceID = $_SESSION['currentSourceID']; else { $tmpVar = GetConfigSetting("DefaultSourceID", "", CFGLEVEL_USER); if ( isset($content['Sources'][ $tmpVar ]) ) // Set Source to preconfigured sourceID! $_SESSION['currentSourceID'] = $tmpVar; else // No Source stored in session, then to so now! $_SESSION['currentSourceID'] = $currentSourceID; } } // Set for the selection box in the header $content['Sources'][$currentSourceID]['selected'] = "selected"; // Set Description properties! if ( isset($content['Sources'][$currentSourceID]['Description']) && strlen($content['Sources'][$currentSourceID]['Description']) > 0 ) { $content['SourceDescriptionEnabled'] = true; $content['SourceDescription'] = $content['Sources'][$currentSourceID]['Description']; } // --- Additional handling needed for the current view! global $currentViewID; $currentViewID = $content['Sources'][$currentSourceID]['ViewID']; // Set selected state for correct View, for selection box ^^ $content['Views'][ $currentViewID ]['selected'] = "selected"; // If DEBUG Mode is enabled, we prepend the UID field into the col list! if ( GetConfigSetting("MiscShowDebugMsg", 0, CFGLEVEL_USER) == 1 && isset($content['Views'][$currentViewID]) ) array_unshift( $content['Views'][$currentViewID]['Columns'], SYSLOG_UID); // --- } /* * This function Inits preconfigured Views. */ function InitViewConfigs() { global $CFG, $content, $currentViewID; // Predefined LogAnalyzer Views $CFG['Views']['SYSLOG']= array( 'ID' => "SYSLOG", 'DisplayName' =>"Syslog Fields", 'Columns' => array ( SYSLOG_DATE, SYSLOG_FACILITY, SYSLOG_SEVERITY, SYSLOG_HOST, SYSLOG_SYSLOGTAG, SYSLOG_PROCESSID, SYSLOG_MESSAGETYPE, SYSLOG_MESSAGE ), 'userid' => null, 'groupid' => null, ); $CFG['Views']['EVTRPT']= array( 'ID' => "EVTRPT", 'DisplayName' =>"EventLog Fields", 'Columns' => array ( SYSLOG_DATE, SYSLOG_HOST, SYSLOG_SEVERITY, SYSLOG_EVENT_LOGTYPE, SYSLOG_EVENT_SOURCE, SYSLOG_EVENT_ID, SYSLOG_EVENT_USER, SYSLOG_MESSAGE ), 'userid' => null, 'groupid' => null, ); $CFG['Views']['WEBLOG']= array( 'ID' => "WEBLOG", 'DisplayName' =>"Webserver Fields", 'Columns' => array ( SYSLOG_DATE, SYSLOG_HOST, SYSLOG_WEBLOG_URL, SYSLOG_WEBLOG_USERAGENT, SYSLOG_WEBLOG_STATUS, SYSLOG_WEBLOG_BYTESSEND, SYSLOG_MESSAGE ), 'userid' => null, 'groupid' => null, ); // Set default of 'DefaultViewsID' only if not set already! if ( !isset($CFG['DefaultViewsID']) ) $CFG['DefaultViewsID'] = "SYSLOG"; // Loop through views now and copy into content array! foreach ( $CFG['Views'] as $key => $view ) $content['Views'][$key] = $view; } /* * This function Inits preconfigured Views. */ function AppendLegacyColumns() { global $CFG, $content; // Init View from legacy Columns $CFG['Views']['LEGACY']= array( 'ID' => "LEGACY", 'DisplayName' =>"Legacy Columns Configuration", 'Columns' => $CFG['Columns'], ); // set default to legacy of no default view is specified! $tmpVar = GetConfigSetting("DefaultViewsID", "", CFGLEVEL_USER); if ( strlen($tmpVar) <= 0 ) $CFG['DefaultViewsID'] = "LEGACY"; } function InitPhpLogConConfigFile($bHandleMissing = true) { // Needed to make global global $CFG, $gl_root_path, $content; // Bugfix for race conditions, clear file stats cache! clearstatcache(); if ( file_exists($gl_root_path . 'config.php') && GetFileLength($gl_root_path . 'config.php') > 0 ) { // Include the main config include_once($gl_root_path . 'config.php'); // Easier DB Access $tblPref = GetConfigSetting("UserDBPref", "logcon"); define('DB_CONFIG', $tblPref . "config"); define('DB_GROUPS', $tblPref . "groups"); define('DB_GROUPMEMBERS', $tblPref . "groupmembers"); define('DB_FIELDS', $tblPref . "fields"); define('DB_SEARCHES', $tblPref . "searches"); define('DB_SOURCES', $tblPref . "sources"); define('DB_USERS', $tblPref . "users"); define('DB_VIEWS', $tblPref . "views"); define('DB_CHARTS', $tblPref . "charts"); define('DB_MAPPINGS', $tblPref . "dbmappings"); define('DB_SAVEDREPORTS', $tblPref . "savedreports"); // Legacy support for old columns definition format! if ( isset($CFG['Columns']) && is_array($CFG['Columns']) ) AppendLegacyColumns(); // --- Now Copy all entries into content variable foreach ($CFG as $key => $value ) $content[$key] = $value; // --- // For MiscShowPageRenderStats if ( GetConfigSetting("MiscShowPageRenderStats", 1) ) { $content['ShowPageRenderStats'] = "true"; InitPageRenderStats(); } // return result return true; } else { // if handled ourselfe, we die in CheckForInstallPhp. if ( $bHandleMissing == true ) { // Check for installscript! CheckForInstallPhp(); } else return false; } } /* * Helper function to load configured dbmappings from the database */ function InitDiskAllowedSources() { global $CFG, $content; // Init Source Configs! if ( isset($CFG['DiskAllowed']) ) { // Copy Array to content array $content['DiskAllowed'] = $CFG['DiskAllowed']; } else { // Set default $content['DiskAllowed'][] = "/var/log/"; } } /* * Helper function to load configured dbmappings from the database */ function LoadDBMappingsFromDatabase() { // Needed to make global global $dbmapping, $content, $fields; // Abort reading fields if the database version is below version 8!, because prior v8, there were no dbmappings table if ( $content['database_installedversion'] < 8 ) return; // --- Preprocess fields in loop foreach ($dbmapping as &$myMapping ) { // Set Field to be internal! $myMapping['IsInternalMapping'] = true; $myMapping['MappingFromDB'] = false; } // --- // --- Create SQL Query $sqlquery = " SELECT " . DB_MAPPINGS . ".ID, " . DB_MAPPINGS . ".DisplayName, " . DB_MAPPINGS . ".Mappings " . " FROM `" . DB_MAPPINGS . "`" . " ORDER BY `" . DB_MAPPINGS . "`.DisplayName"; // Get Views from DB now! $result = DB_Query($sqlquery); $myrows = DB_GetAllRows($result, true); if ( isset($myrows) && count($myrows) > 0 ) { // Unpack the Columns and append to Views Array foreach ($myrows as &$myMappings) { // Split into array $tmpMappings = explode( ",", $myMappings['Mappings'] ); //Loop through mappings foreach ($tmpMappings as &$myMapping ) { // Split subvalues $tmpMapping = explode( "=>", $myMapping ); // check if field is valid $fieldId = trim($tmpMapping[0]); if ( isset($fields[$fieldId]) ) { // Assign mappings $myMappings['DBMAPPINGS'][$fieldId] = trim($tmpMapping[1]); } } // Add Mapping to array $dbmapping[ $myMappings['ID'] ] = $myMappings; // Set FromDB to true $dbmapping[ $myMappings['ID'] ]['MappingFromDB'] = true; } } // --- } /* * Helper function to load configured fields from the database */ function LoadFieldsFromDatabase() { // Needed to make global global $fields, $content; // Abort reading fields if the database version is below version 5!, because prior v5, there were no fields table if ( $content['database_installedversion'] < 5 ) return; // --- Preprocess fields in loop foreach ($fields as &$myField ) { // Set Field to be internal! $myField['IsInternalField'] = true; $myField['FieldFromDB'] = false; // Set some other defaults! if ( !isset($myField['Trunscate']) ) $myField['Trunscate'] = 30; if ( !isset($myField['SearchOnline']) ) $myField['SearchOnline'] = false; if ( !isset($myField['SearchField']) ) $myField['SearchField'] = $myField['FieldID']; } // --- // --- Create SQL Query $sqlquery = " SELECT " . DB_FIELDS . ".FieldID, " . DB_FIELDS . ".FieldDefine, " . DB_FIELDS . ".FieldCaption, " . DB_FIELDS . ".FieldType, " . DB_FIELDS . ".FieldAlign, " . DB_FIELDS . ".SearchField, " . DB_FIELDS . ".DefaultWidth, " . DB_FIELDS . ".SearchOnline, " . DB_FIELDS . ".Trunscate, " . DB_FIELDS . ".Sortable " . " FROM `" . DB_FIELDS . "`" . " ORDER BY `" . DB_FIELDS . "`.FieldCaption"; // --- // Get Searches from DB now! $result = DB_Query($sqlquery); $myrows = DB_GetAllRows($result, true); if ( isset($myrows ) && count($myrows) > 0 ) { // Loop through all data rows foreach ($myrows as &$myField ) { // Read and Set from db! $fieldId = $myField['FieldID']; $fieldDefine = $myField['FieldDefine']; // Set define needed in certain code places! if ( !defined($fieldDefine) ) { define($fieldDefine, $fieldId); $fields[$fieldId]['IsInternalField'] = false; } // Copy values $fields[$fieldId]['FieldID'] = $myField['FieldID']; $fields[$fieldId]['FieldDefine'] = $myField['FieldDefine']; $fields[$fieldId]['FieldCaption'] = $myField['FieldCaption']; $fields[$fieldId]['FieldType'] = $myField['FieldType']; $fields[$fieldId]['FieldAlign'] = $myField['FieldAlign']; $fields[$fieldId]['SearchField'] = $myField['SearchField']; $fields[$fieldId]['DefaultWidth'] = $myField['DefaultWidth']; $fields[$fieldId]['SearchOnline'] = $myField['SearchOnline']; $fields[$fieldId]['Trunscate'] = $myField['Trunscate']; $fields[$fieldId]['Sortable'] = $myField['Sortable']; // Set FromDB to true $fields[$fieldId]['FieldFromDB'] = true; } // print_r ( $fields ); } } /* * Helper function to load configured Searches from the database */ function LoadSearchesFromDatabase() { // Needed to make global global $CFG, $content; // --- Create SQL Query // Create Where for USERID if ( isset($content['SESSION_LOGGEDIN']) && $content['SESSION_LOGGEDIN'] ) $szWhereUser = " OR `" . DB_SEARCHES . "`.userid = " . $content['SESSION_USERID'] . " "; else $szWhereUser = ""; if ( isset($content['SESSION_GROUPIDS']) ) $szGroupWhere = " OR `" . DB_SEARCHES . "`.groupid IN (" . $content['SESSION_GROUPIDS'] . ")"; else $szGroupWhere = ""; $sqlquery = " SELECT " . DB_SEARCHES . ".ID, " . DB_SEARCHES . ".DisplayName, " . DB_SEARCHES . ".SearchQuery, " . DB_SEARCHES . ".userid, " . DB_SEARCHES . ".groupid, " . DB_USERS . ".username, " . DB_GROUPS . ".groupname " . " FROM `" . DB_SEARCHES . "`" . " LEFT OUTER JOIN (`" . DB_USERS . "`) ON (`" . DB_SEARCHES . "`.userid=`" . DB_USERS . "`.ID ) " . " LEFT OUTER JOIN (`" . DB_GROUPS . "`) ON (`" . DB_SEARCHES . "`.groupid=`" . DB_GROUPS . "`.ID ) " . " WHERE (`" . DB_SEARCHES . "`.userid IS NULL AND `" . DB_SEARCHES . "`.groupid IS NULL) " . $szWhereUser . $szGroupWhere . " ORDER BY `" . DB_SEARCHES . "`.userid, `" . DB_SEARCHES . "`.groupid, `" . DB_SEARCHES . "`.DisplayName"; // --- // Get Searches from DB now! $result = DB_Query($sqlquery); $myrows = DB_GetAllRows($result, true); if ( isset($myrows ) && count($myrows) > 0 ) { // Overwrite existing Charts array unset($CFG['Search']); // Loop through all data rows foreach ($myrows as &$mySearch ) { // Append to Chart Array $CFG['Search'][ $mySearch['ID'] ] = $mySearch; } // Copy to content array! $content['Search'] = $CFG['Search']; // // Overwrite Search Array with Database one // $CFG['Search'] = $myrows; // $content['Search'] = $myrows; } } /* * Helper function to load configured Searches from the database */ function LoadChartsFromDatabase() { // Needed to make global global $CFG, $content; // Abort reading charts if the database version is below 3, because prior v3, there were no charts table if ( $content['database_installedversion'] < 3 ) return; // Add new fields depending on DB Version! // --- Create SQL Query // Create Where for USERID if ( isset($content['SESSION_LOGGEDIN']) && $content['SESSION_LOGGEDIN'] ) $szWhereUser = " OR `" . DB_CHARTS . "`.userid = " . $content['SESSION_USERID'] . " "; else $szWhereUser = ""; if ( isset($content['SESSION_GROUPIDS']) ) $szGroupWhere = " OR `" . DB_CHARTS . "`.groupid IN (" . $content['SESSION_GROUPIDS'] . ")"; else $szGroupWhere = ""; $sqlquery = " SELECT " . DB_CHARTS . ".ID, " . DB_CHARTS . ".DisplayName, " . DB_CHARTS . ".chart_enabled, " . DB_CHARTS . ".chart_type, " . DB_CHARTS . ".chart_width, " . DB_CHARTS . ".chart_field, " . DB_CHARTS . ".chart_defaultfilter, " . DB_CHARTS . ".maxrecords, " . DB_CHARTS . ".showpercent, " . DB_CHARTS . ".userid, " . DB_CHARTS . ".groupid, " . DB_USERS . ".username, " . DB_GROUPS . ".groupname " . " FROM `" . DB_CHARTS . "`" . " LEFT OUTER JOIN (`" . DB_USERS . "`) ON (`" . DB_CHARTS . "`.userid=`" . DB_USERS . "`.ID ) " . " LEFT OUTER JOIN (`" . DB_GROUPS . "`) ON (`" . DB_CHARTS . "`.groupid=`" . DB_GROUPS . "`.ID ) " . " WHERE (`" . DB_CHARTS . "`.userid IS NULL AND `" . DB_CHARTS . "`.groupid IS NULL) " . $szWhereUser . $szGroupWhere . " ORDER BY `" . DB_CHARTS . "`.userid, `" . DB_CHARTS . "`.groupid, `" . DB_CHARTS . "`.DisplayName"; // --- // Get Searches from DB now! $result = DB_Query($sqlquery); $myrows = DB_GetAllRows($result, true); if ( isset($myrows ) && count($myrows) > 0 ) { // Overwrite existing Charts array unset($CFG['Charts']); // Loop through all data rows foreach ($myrows as &$myChart ) { // Append to Chart Array $CFG['Charts'][ $myChart['ID'] ] = $myChart; } // Copy to content array! $content['Charts'] = $CFG['Charts']; } } function LoadViewsFromDatabase() { // Needed to make global global $CFG, $content; // --- Create SQL Query // Create Where for USERID if ( isset($content['SESSION_LOGGEDIN']) && $content['SESSION_LOGGEDIN'] ) $szWhereUser = " OR `" . DB_VIEWS . "`.userid = " . $content['SESSION_USERID'] . " "; else $szWhereUser = ""; if ( isset($content['SESSION_GROUPIDS']) ) $szGroupWhere = " OR `" . DB_VIEWS . "`.groupid IN (" . $content['SESSION_GROUPIDS'] . ")"; else $szGroupWhere = ""; $sqlquery = " SELECT " . DB_VIEWS . ".ID, " . DB_VIEWS . ".DisplayName, " . DB_VIEWS . ".Columns, " . DB_VIEWS . ".userid, " . DB_VIEWS . ".groupid, " . DB_USERS . ".username, " . DB_GROUPS . ".groupname " . " FROM `" . DB_VIEWS . "`" . " LEFT OUTER JOIN (`" . DB_USERS . "`) ON (`" . DB_VIEWS . "`.userid=`" . DB_USERS . "`.ID ) " . " LEFT OUTER JOIN (`" . DB_GROUPS . "`) ON (`" . DB_VIEWS . "`.groupid=`" . DB_GROUPS . "`.ID ) " . " WHERE (`" . DB_VIEWS . "`.userid IS NULL AND `" . DB_VIEWS . "`.groupid IS NULL) " . $szWhereUser . $szGroupWhere . " ORDER BY `" . DB_VIEWS . "`.userid, `" . DB_VIEWS . "`.groupid, `" . DB_VIEWS . "`.DisplayName"; // --- // Get Views from DB now! $result = DB_Query($sqlquery); $myrows = DB_GetAllRows($result, true); if ( isset($myrows) && count($myrows) > 0 ) { // Overwrite existing Views array unset($CFG['Views']); // ReINIT Views Array InitViewConfigs(); // Unpack the Columns and append to Views Array foreach ($myrows as &$myView ) { // Split into array $myView['Columns'] = explode( ",", $myView['Columns'] ); // remove spaces foreach ($myView['Columns'] as &$myCol ) $myCol = trim($myCol); // Append to Views Array $CFG['Views'][ $myView['ID'] ] = $myView; } // Merge into existing Views Array! // $CFG['Views'] = array_merge ( $CFG['Views'], $myrows ); $content['Views'] = $CFG['Views']; } } function LoadSourcesFromDatabase() { // Needed to make global global $CFG, $content; // --- Create SQL Query // Create Where for USERID if ( isset($content['SESSION_LOGGEDIN']) && $content['SESSION_LOGGEDIN'] ) $szWhereUser = " OR `" . DB_SOURCES . "`.userid = " . $content['SESSION_USERID'] . " "; else $szWhereUser = ""; if ( isset($content['SESSION_GROUPIDS']) ) $szGroupWhere = " OR `" . DB_SOURCES . "`.groupid IN (" . $content['SESSION_GROUPIDS'] . ")"; else $szGroupWhere = ""; $sqlquery = " SELECT " . DB_SOURCES . ".*, " . DB_USERS . ".username, " . DB_GROUPS . ".groupname " . " FROM `" . DB_SOURCES . "`" . " LEFT OUTER JOIN (`" . DB_USERS . "`) ON (`" . DB_SOURCES . "`.userid=`" . DB_USERS . "`.ID ) " . " LEFT OUTER JOIN (`" . DB_GROUPS . "`) ON (`" . DB_SOURCES . "`.groupid=`" . DB_GROUPS . "`.ID ) " . " WHERE (`" . DB_SOURCES . "`.userid IS NULL AND `" . DB_SOURCES . "`.groupid IS NULL) " . $szWhereUser . $szGroupWhere . " ORDER BY `" . DB_SOURCES . "`.userid, `" . DB_SOURCES . "`.groupid, `" . DB_SOURCES . "`.Name"; // --- // Get Sources from DB now! $result = DB_Query($sqlquery); $myrows = DB_GetAllRows($result, true); if ( isset($myrows) && count($myrows) > 0 ) { // Overwrite existing Sources array unset($CFG['Sources']); // Append to Source Array foreach ($myrows as &$mySource ) { // Append to Source Array $CFG['Sources'][ $mySource['ID'] ] = $mySource; //['ID']; } // Copy to content array! $content['Sources'] = $CFG['Sources']; } } ?>loganalyzer-3.6.5/src/include/db_update_v9.txt0000644000175000017500000000131712225176641020656 0ustar danieldaniel-- New Database Structure Updates CREATE TABLE `logcon_savedreports` ( `ID` int(11) NOT NULL auto_increment, `reportid` varchar(255) NOT NULL, `sourceid` int(11) NOT NULL, `customTitle` varchar(255) NOT NULL, `customComment` text NOT NULL, `filterString` text NOT NULL, `customFilters` text NOT NULL, `outputFormat` varchar(64) NOT NULL, `outputTarget` varchar(64) NOT NULL, `outputTargetDetails` text NOT NULL, `scheduleSettings` text NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT = 'Table to store saved reports' AUTO_INCREMENT=1 ; ALTER TABLE `logcon_users` ADD `is_readonly` tinyint(1) NOT NULL DEFAULT '0' AFTER `is_admin` ; -- Insert data -- Updated Data loganalyzer-3.6.5/src/login.php0000644000175000017500000000650312225176641015750 0ustar danieldaniel File to login users in LogAnalyzer * * All directives are explained within this file * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // *** Default includes and procedures *** // define('IN_PHPLOGCON', true); $gl_root_path = './'; // Now include necessary include files! include($gl_root_path . 'include/functions_common.php'); include($gl_root_path . 'include/functions_frontendhelpers.php'); //include($gl_root_path . 'include/functions_filters.php'); // To avoid infinite redirects! define('IS_NOLOGINPAGE', true); $content['IS_NOLOGINPAGE'] = true; InitPhpLogCon(); // --- // // --- BEGIN Custom Code // Set Defaults $content['uname'] = ""; $content['pass'] = ""; // Set Referer if ( isset($_GET['referer']) ) $szRedir = $_GET['referer']; else if ( isset($_POST['referer']) ) $szRedir = $_POST['referer']; else $szRedir = "index.php"; // Default if ( isset($_POST['op']) && $_POST['op'] == "login" ) { // Perform login! if ( $_POST['op'] == "login" ) { if ( (isset($_POST['uname']) && strlen($_POST['uname']) > 0) && (isset($_POST['pass']) && strlen($_POST['pass']) > 0) ) { // Set Username and password $content['uname'] = DB_RemoveBadChars($_POST['uname']); $content['pass'] = $_POST['pass']; // RAW Copy of password string, otherwise passwords with special characters can be broken. if ( !CheckUserLogin( $content['uname'], $content['pass']) ) { $content['ISERROR'] = "true"; $content['ERROR_MSG'] = $content['LN_LOGIN_ERRWRONGPASSWORD']; } else RedirectPage( urldecode($szRedir) ); } else { $content['ISERROR'] = "true"; $content['ERROR_MSG'] = $content['LN_LOGIN_USERPASSMISSING']; } } } else if ( isset($_GET['op']) && $_GET['op'] == "logoff" ) { // logoff in this case DoLogOff(); } // --- END Custom Code // --- CONTENT Vars $content['REDIR_LOGIN'] = $szRedir; $content['TITLE'] = InitPageTitle(); // Append custom title part! $content['TITLE'] .= " :: " . $content['LN_LOGIN_TITLE']; // --- // --- Parsen and Output InitTemplateParser(); $page -> parser($content, "login.html"); $page -> output(); // --- ?>loganalyzer-3.6.5/src/lang/0000755000175000017500000000000012225176641015044 5ustar danieldanielloganalyzer-3.6.5/src/lang/de/0000755000175000017500000000000012225176641015434 5ustar danieldanielloganalyzer-3.6.5/src/lang/de/info.txt0000644000175000017500000000000712225176641017125 0ustar danieldanielDeutschloganalyzer-3.6.5/src/lang/de/admin.php0000644000175000017500000010537512225176641017250 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ global $content; // Global Stuff $content['LN_ADMINMENU_HOMEPAGE'] = "Zurück zu den Meldungen"; $content['LN_ADMINMENU_GENOPT'] = "Einstellungen"; $content['LN_ADMINMENU_SOURCEOPT'] = "Quellen"; $content['LN_ADMINMENU_VIEWSOPT'] = "Anzeigen"; $content['LN_ADMINMENU_SEARCHOPT'] = "Suchen"; $content['LN_ADMINMENU_USEROPT'] = "Benutzer"; $content['LN_ADMINMENU_GROUPOPT'] = "Gruppen"; $content['LN_ADMINMENU_CHARTOPT'] = "Charts"; $content['LN_ADMINMENU_FIELDOPT'] = "Felder"; $content['LN_ADMINMENU_DBMAPPINGOPT'] = "DBMappings"; $content['LN_ADMINMENU_MSGPARSERSOPT'] = "Meldungs Parser"; $content['LN_ADMINMENU_REEPORTSOPT'] = "Report Modules"; $content['LN_ADMIN_CENTER'] = "Administration"; $content['LN_ADMIN_UNKNOWNSTATE'] = "Unbekannter Status"; $content['LN_ADMIN_ERROR_NOTALLOWED'] = "Sie sind nicht berechtigt mit diesem Benutzer-Level diese Seite anzuzeigen."; $content['LN_DELETEYES'] = "Ja"; $content['LN_DELETENO'] = "Nein"; $content['LN_GEN_ACTIONS'] = "Mögliche Aktionen"; $content['LN_ADMIN_SEND'] = "Änderungen speichern"; $content['LN_GEN_USERONLY'] = "Nur Benutzer"; $content['LN_GEN_GROUPONLY'] = "Nur Gruppen"; $content['LN_GEN_GLOBAL'] = "Global"; $content['LN_GEN_USERONLY_LONG'] = "Eigene Einstellungen
(Nur für Ihren Benutzer)"; $content['LN_GEN_GROUPONLY_LONG'] = "Einstellungen für die Gruppe
(Nur für die ausgewählte Gruppe)"; $content['LN_GEN_GROUPONLYNAME'] = "Gruppe '%1'"; $content['LN_ADMIN_POPUPHELP'] = "Details für diese Funktion"; $content['LN_ADMIN_DBSTATS'] = "Anzeige der Datenbankinformationen."; $content['LN_ADMIN_CLEARDATA'] = "Wenn Sie alte Datenbankeinträge löschen wollen, benutzen Sie diese Funktion."; $content['LN_UPDATE_AVAILABLE'] = "Update available"; $content['LN_UPDATE_INSTALLEDVER'] = "Installed version: "; $content['LN_UPDATE_AVAILABLEVER'] = "Available version: "; $content['LN_UPDATE_LINK'] = "Click here to get the update"; // General Options $content['LN_ADMIN_GLOBFRONTEND'] = "Globale Anzeige Optionen"; $content['LN_ADMIN_USERFRONTEND'] = "Benutzer spezifische Anzeige Optionen"; $content['LN_ADMIN_MISC'] = "Verschiedene Optionen"; $content['LN_GEN_SHOWDEBUGMSG'] = "Anzeige von Debug Meldungen"; $content['LN_GEN_DEBUGGRIDCOUNTER'] = "Anzeige Debug Meldungssumme"; $content['LN_GEN_SHOWPAGERENDERSTATS'] = "Anzeige Status des Seiten-Renderers"; $content['LN_GEN_ENABLEGZIP'] = "Ermögliche GZIP komprimierte Ausgabe"; $content['LN_GEN_DEBUGUSERLOGIN'] = "Debug Benutzeranmeldung"; $content['LN_GEN_WEBSTYLE'] = "Standard Style"; $content['LN_GEN_SELLANGUAGE'] = "Standard Sprache"; $content['LN_GEN_PREPENDTITLE'] = "Diese Zeichenfolge im Titel mit anzeigen"; $content['LN_GEN_USETODAY'] = "Anzeige von 'Today' aund 'Yesterday' in den Zeitfeldern"; $content['LN_GEN_DETAILPOPUPS'] = "Benutze Popup-Fenster um alle Meldungsdatails anzuzeigen"; $content['LN_GEN_MSGCHARLIMIT'] = "Anzahl der Zeichen im Meldungsfenster in der Hauptanzeige"; $content['LN_GEN_STRCHARLIMIT'] = "Anzahl der Zeichen in Feldern"; $content['LN_GEN_ENTRIESPERPAGE'] = "Anzahl der Zeilen pro Seite"; $content['LN_GEN_AUTORELOADSECONDS'] = "Ermögliche automatisches neu laden der Seite nach Sekunden"; $content['LN_GEN_ADMINCHANGEWAITTIME'] = "Reloadtime in Adminpanel"; $content['LN_GEN_IPADRRESOLVE'] = "Ermitteln der IP-Adresse durch DNS-Abfragen"; $content['LN_GEN_CUSTBTNCAPT'] = "Benutzerdefinierte Such-Titel"; $content['LN_GEN_CUSTBTNSRCH'] = "Benutzerdefinierte Such-Zeichenfolge"; $content['LN_GEN_SUCCESSFULLYSAVED'] = "Die Einstellungen wurden erfolgreich gespeichert!"; $content['LN_GEN_INTERNAL'] = "Intern"; $content['LN_GEN_DISABLED'] = "Funktion deaktiviert"; $content['LN_GEN_CONFIGFILE'] = "Konfigurationsdatei"; $content['LN_GEN_ACCESSDENIED'] = "Der Zugriff auf diese Funktion wurde verweigert!"; $content['LN_GEN_DEFVIEWS'] = "Standard Anzeige"; $content['LN_GEN_DEFSOURCE'] = "Standard Quelle"; $content['LN_GEN_SUPPRESSDUPMSG'] = "Doppelte Meldungen nur einmal anzeigen"; $content['LN_GEN_TREATFILTERSTRUE'] = "Treat filters of not found fields as true"; $content['LN_GEN_INLINESEARCHICONS'] = "Show Onlinesearch icons within fields"; $content['LN_GEN_OPTIONNAME'] = "Option Name"; $content['LN_GEN_GLOBALVALUE'] = "Globale Werte"; $content['LN_GEN_PERSONALVALUE'] = "Persönliche (benutzerbezogene)Werte"; $content['LN_GEN_DISABLEUSEROPTIONS'] = "Hier klicken um persönche Optionen zu deaktivieren"; $content['LN_GEN_ENABLEUSEROPTIONS'] = "Hier klicken um persönliche Optionen zu aktivieren"; $content['LN_ADMIN_GLOBALONLY'] = "Nur Globale Optionen"; $content['LN_GEN_DEBUGTOSYSLOG'] = "Sende Debug zum lokalen Syslog Server"; $content['LN_GEN_POPUPMENUTIMEOUT'] = "Popupmenü Anzeige für Millisekunden"; $content['LN_ADMIN_SCRIPTTIMEOUT'] = "PHP Skript max. Lauzeit in Sekunden"; $content['LN_GEN_INJECTHTMLHEADER'] = "Voranstellen von HTML Code in <head> Bereich."; $content['LN_GEN_INJECTBODYHEADER'] = "Voranstellen von HTML Code am Anfang des <body> Bereichs."; $content['LN_GEN_INJECTBODYFOOTER'] = "Voranstellen von HTML Code Am Ende des <body> Bereichs."; $content['LN_ADMIN_PHPLOGCON_LOGOURL'] = "Optionale LogAnalyzer-Logo-URL. Bitte für das Standard-Logo leer lassen."; $content['LN_ADMIN_ERROR_READONLY'] = "This is a READONLY User, you are not allowed to perform any change operations."; $content['LN_ADMIN_ERROR_NOTALLOWEDTOEDIT'] = "You are not allowed to edit this configuration item."; $content['LN_ADMIN_USEPROXYSERVER'] = "Leave empty if you do not want to use a proxy server! If set to valid proxy server (for example '127.0.0.1:8080'), LogAnalyzer will use this server for remote queries like the update check feature."; $content['LN_ADMIN_DEFAULTENCODING'] = "Default character encoding"; $content['LN_GEN_CONTEXTLINKS'] = "Enable Contextlinks (Question marks)"; // User Center $content['LN_USER_CENTER'] = "Benutzer Optionen"; $content['LN_USER_ID'] = "ID"; $content['LN_USER_NAME'] = "Benutzername"; $content['LN_USER_ADD'] = "Benutzer hinzufügen"; $content['LN_USER_EDIT'] = "Benutzer bearbeiten"; $content['LN_USER_DELETE'] = "Benutzer löschen"; $content['LN_USER_PASSWORD1'] = "Passwort"; $content['LN_USER_PASSWORD2'] = "Passwort Bestätigung"; $content['LN_USER_ERROR_IDNOTFOUND'] = "Fehler, ein Benutzer mit der ID '%1', wurde nicht gefunden"; $content['LN_USER_ERROR_DONOTDELURSLF'] = "Fehler, Sie können sich NICHT SELBST LÖSCHEN!"; $content['LN_USER_ERROR_DELUSER'] = "Löschen des Benutzer mit der id '%1' fehlgeschlagen!"; $content['LN_USER_ERROR_INVALIDID'] = "Fehler, ungültige ID, Benutzer nicht gefunden"; $content['LN_USER_ERROR_HASBEENDEL'] = "Der Benutzer '%1' wurde erfolgreich gelöscht!"; $content['LN_USER_ERROR_USEREMPTY'] = "Fehler, Benutzername ist leer"; $content['LN_USER_ERROR_USERNAMETAKEN'] = "Fehler, dieser Benutzername existiert bereits!"; $content['LN_USER_ERROR_PASSSHORT'] = "Fehler, Passwort ist zu kurz, oder stimmt nicht überein."; $content['LN_USER_ERROR_HASBEENADDED'] = "Benutzer '%1' wurde erfolgreich hinzugefügt."; $content['LN_USER_ERROR_HASBEENEDIT'] = "Benutzer '%1' wurde erfolgreich geändert."; $content['LN_USER_ISADMIN'] = "Administrator?"; $content['LN_USER_ADDEDIT'] = "Hinzufügen/Bearbeiten von Benutzern"; $content['LN_USER_WARNREMOVEADMIN'] = "Sie sind im Begriff sich Ihre Administorenrechte zu nehmen. Sind Sie sicher?"; $content['LN_USER_WARNDELETEUSER'] = "Sind Sie sicher das Sie den Benutzer '%1' löschen wollen? Alle pers. Einstellungen werden ebenfalls gelöscht."; $content['LN_USER_ERROR_INVALIDSESSIONS'] = "Ungültige Benutzer Sitzung."; $content['LN_USER_'] = ""; // Group center $content['LN_GROUP_CENTER'] = "Gruppen Administration"; $content['LN_GROUP_ID'] = "ID"; $content['LN_GROUP_NAME'] = "Gruppenname"; $content['LN_GROUP_DESCRIPTION'] = "Gruppenbeschreibung"; $content['LN_GROUP_TYPE'] = "Gruppentyp"; $content['LN_GROUP_ADD'] = "Gruppe hinzufügen"; $content['LN_GROUP_EDIT'] = "Gruppe bearbeiten"; $content['LN_GROUP_DELETE'] = "Gruppe löschen"; $content['LN_GROUP_NOGROUPS'] = "Es wurde aktuell keine Gruppe angelegt."; $content['LN_GROUP_ADDEDIT'] = "Hinzufügen/Bearbeiten Gruppe"; $content['LN_GROUP_ERROR_GROUPEMPTY'] = "Der Gruppenname darf nicht leer sein.."; $content['LN_GROUP_ERROR_GROUPNAMETAKEN'] = "Der Gruppenname existiert bereits."; $content['LN_GROUP_HASBEENADDED'] = "Die Gruppe '%1' wurde erfolgreich hinzugefügt."; $content['LN_GROUP_ERROR_IDNOTFOUND'] = "Die Gruppe mit der ID '%1' konnte nicht gefunden werden."; $content['LN_GROUP_ERROR_HASBEENEDIT'] = "Die Gruppe '%1' wurde erfolgreich geändert."; $content['LN_GROUP_ERROR_INVALIDGROUP'] = "Fehler, ungültige ID, Gruppe nicht gefunden."; $content['LN_GROUP_WARNDELETEGROUP'] = "Sind Sie sicher, dass Sie diese Gruppe '%1'? löschen wollen. Alle Gruppeneinstellungen werden ebenfalls gelöscht."; $content['LN_GROUP_ERROR_DELGROUP'] = "Löschen der Gruppe mit der id '%1' fehlgeschlagen!"; $content['LN_GROUP_ERROR_HASBEENDEL'] = "Die Gruppe '%1' wurde erfolgreich gelöscht!"; $content['LN_GROUP_MEMBERS'] = "Gruppenmitglieder: "; $content['LN_GROUP_ADDUSER'] = "Benutzer der Gruppe hinzufügen"; $content['LN_GROUP_ERROR_USERIDMISSING'] = "Die Benutzer id fehlt."; $content['LN_GROUP_USERHASBEENADDEDGROUP'] = "Der Benutzer '%1' wurde erfolgreich zur Gruppe '%2' hinzugefügt"; $content['LN_GROUP_ERRORNOMOREUSERS'] = "Es sind keine Benutzer mehr verfügbar, welche zur Gruppe '%1' hinzugefügt werden können."; $content['LN_GROUP_USER_ADD'] = "Benutzer zur Gruppe hinzufügen"; $content['LN_GROUP_USERDELETE'] = "Benutzer von der Gruppe entfernen"; $content['LN_GROUP_ERRORNOUSERSINGROUP'] = "Es sind keine Benutzer mehr verfügbar, welche von der Gruppe '%1' entfernt werden können."; $content['LN_GROUP_ERROR_REMUSERFROMGROUP'] = "Der Benutzer '%1' kann nicht aus der Gruppe '%2' entfernt werden."; $content['LN_GROUP_USERHASBEENREMOVED'] = "Der Benutzer '%1' wurde erfolgreich aus der Gruppe '%2' entfernt"; $content['LN_GROUP_'] = ""; // Custom Searches center $content['LN_SEARCH_CENTER'] = "Benutzerdefinierte Suchen"; $content['LN_SEARCH_ADD'] = "Hinzufügen einer benutzerdefinierten Suche"; $content['LN_SEARCH_ID'] = "ID"; $content['LN_SEARCH_NAME'] = "Name der Suche "; $content['LN_SEARCH_QUERY'] = "Suchabfrage"; $content['LN_SEARCH_TYPE'] = "Zugewiesen zu"; $content['LN_SEARCH_EDIT'] = "Bearbeiten einer benutzerdefinierten Suche"; $content['LN_SEARCH_DELETE'] = "Löschen einer benutzerdefinierten Suche"; $content['LN_SEARCH_ADDEDIT'] = "Hinzufügen/Bearbeiten benutzerdefinerte Suche"; $content['LN_SEARCH_SELGROUPENABLE'] = ">> Gruppe auswählen <<"; $content['LN_SEARCH_ERROR_DISPLAYNAMEEMPTY'] = "Der Anzeigenname kann nicht leer sein."; $content['LN_SEARCH_ERROR_SEARCHQUERYEMPTY'] = "Die Suchabfrage kann nicht leer sein."; $content['LN_SEARCH_HASBEENADDED'] = "Die benutzerdefinerte Suche '%1' wurde erfolgreich hinzugefügt."; $content['LN_SEARCH_ERROR_IDNOTFOUND'] = "Es konnte keine Suche mit der ID '%1' gefunden werden."; $content['LN_SEARCH_ERROR_INVALIDID'] = "Ungültige ID der Suche."; $content['LN_SEARCH_HASBEENEDIT'] = "Die benutzerdefinierte Suche '%1' wurde erfolgreich geändert."; $content['LN_SEARCH_WARNDELETESEARCH'] = "Sind Sie sicher, dass Sie die Suche' %1' löschen wollen? Dies kann nicht rückgängig gemacht werden!"; $content['LN_SEARCH_ERROR_DELSEARCH'] = "Löschen der benutzerdefinerten Suche mit der id '%1' fehlgeschlagen!"; $content['LN_SEARCH_ERROR_HASBEENDEL'] = "Die benutzerdefinierte Suche '%1' wurde erfolgreich gelöscht!"; $content['LN_SEARCH_'] = ""; // Custom Views center $content['LN_VIEWS_CENTER'] = "Ansicht Optionen"; $content['LN_VIEWS_ID'] = "ID"; $content['LN_VIEWS_NAME'] = "Name der Ansicht"; $content['LN_VIEWS_COLUMNS'] = "Spalten"; $content['LN_VIEWS_TYPE'] = "Zugewiesen zu"; $content['LN_VIEWS_ADD'] = "Hinzufügen einer Ansicht"; $content['LN_VIEWS_EDIT'] = "Bearbeiten einer Ansicht"; $content['LN_VIEWS_ERROR_IDNOTFOUND'] = "Eine Ansicht mit der ID '%1' konnte nicht gefunden werden."; $content['LN_VIEWS_ERROR_INVALIDID'] = "Die Ansicht mit der ID '%1' ist keine gültige Ansicht."; $content['LN_VIEWS_WARNDELETEVIEW'] = "Sind Sie sicher, dass Sie die Ansicht '%1' löschen wollen? Dies kann nicht rückgängig gemacht werden!"; $content['LN_VIEWS_ERROR_DELSEARCH'] = "Löschen der Ansicht mit der id '%1' fehlgeschlagen!"; $content['LN_VIEWS_ERROR_HASBEENDEL'] = "Die Ansicht '%1' wurder erfolgreich gelöscht!"; $content['LN_VIEWS_ADDEDIT'] = "Hinzufügen/Bearbeiten einer Ansicht"; $content['LN_VIEWS_COLUMNLIST'] = "Konfigurierte Spalten"; $content['LN_VIEWS_ADDCOLUMN'] = "Eine Spalte hinzufuegen"; $content['LN_VIEWS_ERROR_DISPLAYNAMEEMPTY'] = "Der Name der Ansicht kann nicht leer sein."; $content['LN_VIEWS_COLUMN'] = "Spalte"; $content['LN_VIEWS_COLUMN_REMOVE'] = "Spalte löschen"; $content['LN_VIEWS_HASBEENADDED'] = "Die Ansicht '%1' wurder erfolgreich hinzugefügt."; $content['LN_VIEWS_ERROR_NOCOLUMNS'] = "Sie müssen mind. eine Spalte anegben, um eine neue Ansicht zu erstellen."; $content['LN_VIEWS_HASBEENEDIT'] = "Die Ansicht '%1' wurde erfolgreich geändert."; $content['LN_VIEWS_'] = ""; // Custom DBMappings center $content['LN_DBMP_CENTER'] = "Database Field Mappings Options"; $content['LN_DBMP_ID'] = "ID"; $content['LN_DBMP_NAME'] = "Database Mappingname"; $content['LN_DBMP_DBMAPPINGS'] = "Database Mappings"; $content['LN_DBMP_ADD'] = "Add new Database Mapping"; $content['LN_DBMP_EDIT'] = "Edit Database Mapping"; $content['LN_DBMP_ERROR_IDNOTFOUND'] = "A Database Mapping with ID '%1' could not be found."; $content['LN_DBMP_ERROR_INVALIDID'] = "The Database Mapping with ID '%1' is not a valid Database Mapping."; $content['LN_DBMP_WARNDELETEMAPPING'] = "Are you sure that you want to delete the Database Mapping '%1'? This cannot be undone!"; $content['LN_DBMP_ERROR_DELSEARCH'] = "Deleting of the Database Mapping with id '%1' failed!"; $content['LN_DBMP_ERROR_HASBEENDEL'] = "The Database Mapping '%1' has been successfully deleted!"; $content['LN_DBMP_ADDEDIT'] = "Add / Edit Database Mapping"; $content['LN_DBMP_DBMAPPINGSLIST'] = "Configured Mappings"; $content['LN_DBMP_ADDMAPPING'] = "Add Field Mapping into list"; $content['LN_DBMP_ERROR_DISPLAYNAMEEMPTY'] = "The DisplayName cannot be empty."; $content['LN_DBMP_MAPPING'] = "Mapping"; $content['LN_DBMP_MAPPING_REMOVE'] = "Remove Mapping"; $content['LN_DBMP_MAPPING_EDIT'] = "Edit Mapping"; $content['LN_DBMP_HASBEENADDED'] = "The Custom Database Mapping '%1' has been successfully added."; $content['LN_DBMP_ERROR_NOCOLUMNS'] = "You need to add at least one column in order to add a new Custom Database Mapping."; $content['LN_DBMP_HASBEENEDIT'] = "The Custom Database Mapping '%1' has been successfully edited."; $content['LN_DBMP_HASBEENEDIT'] = "The Custom Database Mapping '%1' has been successfully edited."; $content['LN_DBMP_ERROR_MISSINGFIELDNAME'] = "Missing mapping for the '%1' field."; // Custom Sources center $content['LN_SOURCES_CENTER'] = "Quellen Optionen"; $content['LN_SOURCES_EDIT'] = "Quelle bearbeiten"; $content['LN_SOURCES_DELETE'] = "Quelle löschen"; $content['LN_SOURCES_ID'] = "ID"; $content['LN_SOURCES_NAME'] = "Name der Quelle"; $content['LN_SOURCES_TYPE'] = "Typ der Quelle"; $content['LN_SOURCES_ASSIGNTO'] = "Zugewiesen zu"; $content['LN_SOURCES_DISK'] = "Festplatten Datei"; $content['LN_SOURCES_DB'] = "MySQL Datenbank"; $content['LN_SOURCES_PDO'] = "PDO Datenquelle"; $content['LN_SOURCES_ADD'] = "Hinzufügen einer Quelle"; $content['LN_SOURCES_ADDEDIT'] = "Hinzufügen/Bearbeiten einer Quelle"; $content['LN_SOURCES_TYPE'] = "Typ der Quelle"; $content['LN_SOURCES_DISKTYPEOPTIONS'] = "Festplatten Datei, zugewiesene Optionen"; $content['LN_SOURCES_ERROR_MISSINGPARAM'] = "Der Parameter '%1' fehlt."; $content['LN_SOURCES_ERROR_NOTAVALIDFILE'] = "Fehler beim öffnen der Syslog Detei '%1'! Bitte überprüfen Sie die Existenz der Datei und die Rechte für LogAnalyzer."; $content['LN_SOURCES_ERROR_UNKNOWNSOURCE'] = "Unbekannte Quelle '%1' gefunden"; $content['LN_SOURCE_HASBEENADDED'] = "Die neue Quelle '%1' wurde erfolgreich hinzugefügt."; $content['LN_SOURCES_EDIT'] = "Quelle bearbeiten"; $content['LN_SOURCES_ERROR_INVALIDORNOTFOUNDID'] = "Die Quellen-ID ist ungültig oder konnte nicht gefunden werden."; $content['LN_SOURCES_ERROR_IDNOTFOUND'] = "Die Quellen-ID konnte in der Datenbank nicht gefunden werden."; $content['LN_SOURCES_HASBEENEDIT'] = "Die Quelle '%1' wurde erfolgreich geändert."; $content['LN_SOURCES_WARNDELETESEARCH'] = "Sind Sie sicher, dass Sie die Quelle '%1' löschen wollen? Dies kann nicht rückgängig gemacht werden!"; $content['LN_SOURCES_ERROR_DELSOURCE'] = "Löschen der Quelle mit der id '%1' fehlgeschlagen!"; $content['LN_SOURCES_ERROR_HASBEENDEL'] = "Die Quelle '%1' wurde erfolgreich gelöscht!"; $content['LN_SOURCES_DESCRIPTION'] = "Beschreibung der Quelle (Optional)"; $content['LN_SOURCES_ERROR_INVALIDVALUE'] = "Ungültiger Wert für den Parameter '%1'."; $content['LN_SOURCES_STATSNAME'] = "Name"; $content['LN_SOURCES_STATSVALUE'] = "Wert"; $content['LN_SOURCES_DETAILS'] = "Details für diese Log-Datenstrom-Quelle"; $content['LN_SOURCES_STATSDETAILS'] = "Statistische Details für diese Log-Datenstrom-Quelle"; $content['LN_SOURCES_ERROR_NOSTATSDATA'] = "Es konnten keine statistsichen Daten für diese Log-Datenstrom-Quelle gefunden werden."; $content['LN_SOURCES_ERROR_NOCLEARSUPPORT'] = "Diese Log-Datenstrom-Quelle unterstützt nicht das löschen von Daten."; $content['LN_SOURCES_ROWCOUNT'] = "Summe der Zeilen"; $content['LN_SOURCES_CLEAR_HELPTEXT'] = "Achtung! Vorsicht beim Löschen von Daten, eine hier durchgeführte Aktion kann nicht mehr rückgängig gemacht werden!"; $content['LN_SOURCES_CLEARSINCE'] = "Lösche alle Daten seit ... "; $content['LN_SOURCES_CLEARDATE'] = "Lösche alle Daten a¨lter als ... "; $content['LN_SOURCES_CLEARDATA_SEND'] = "Lösche alle ausgewählten Daten"; $content['LN_SOURCES_ERROR_INVALIDCLEANUP'] = "Ungültiger Lösch-Typ"; $content['LN_SOURCES_WARNDELETEDATA'] = "Sind Sie sicher, dass Sie alle Daten löschen wollen welche in der '%1' Quelle enthalten sind? Dies kann nicht mehr rückgängig gemacht werden!"; $content['LN_SOURCES_ERROR_DELDATA'] = "Es konnten keine Daten in der Quelle '%1' gelöscht werden"; $content['LN_SOURCES_HASBEENDELDATA'] = "Die Daten in der Quelle '%1'wurden erfolgreich gelöscht, '%2' Zeilen wurden entfern. "; $content['LN_SOURCES_FILTERSTRING'] = "Custom Searchfilter"; $content['LN_SOURCES_FILTERSTRING_HELP'] = "Use the same syntax as in the search field. For example if you want to show only messages from 'server1', use this searchfilter: source:=server1"; // Database Upgrade $content['LN_DBUPGRADE_TITLE'] = "LogAnalyzer Datenbank Update"; $content['LN_DBUPGRADE_DBFILENOTFOUND'] = "Die Datenbank Upgrade Datei '%1' konnte im 'include'-Ordner nicht gefunden werden! Bitte überprüfen Sie, ob Sie LogAnalyzer komplett heruntergeladen haben."; $content['LN_DBUPGRADE_DBDEFFILESHORT'] = "Die Datenbank Upgrade Datei ist leer oder enthält kein SQL-Kommando! Bitte überprüfen Sie, ob Sie LogAnalyzer komplett heruntergeladen haben."; $content['LN_DBUPGRADE_WELCOME'] = "Willkommen zum Datenbank Upgrade"; $content['LN_DBUPGRADE_BEFORESTART'] = "Bevor Sie mit dem Upgrade der Datenbank beginnen, sollten Sie eine KOMPLETTE SICHERUNG IHRER DATENBANK durchführen. Alle weiteren Schritte werden automatisch duch das Upgrade-Skript durchgeführt."; $content['LN_DBUPGRADE_CURRENTINSTALLED'] = "Aktuell installierte Datenbank Version"; $content['LN_DBUPGRADE_TOBEINSTALLED'] = "Zu installierende Datenbank Version"; $content['LN_DBUPGRADE_HASBEENDONE'] = "Das Datenbank Upgrade wurde durchgeführt, das Ergebnis der Operation sehen Sie untenstehend"; $content['LN_DBUPGRADE_SUCCESSEXEC'] = "Erfolgreich ausgeführte Anweisungen"; $content['LN_DBUPGRADE_FAILEDEXEC'] = "Nicht erfolgreich ausgeführte Anweisungen"; $content['LN_DBUPGRADE_ONESTATEMENTFAILED'] = "Es wurde mind. eine Anweisung nicht korekt ausgeführt, dies muss manuell durch Sie korrigiert werden. Bitte beachten Sie die untenstehenden Details"; $content['LN_DBUPGRADE_ERRMSG'] = "Fehler Meldung"; $content['LN_DBUPGRADE_ULTRASTATSDBVERSION'] = "LogAnalyzer Datenbank Version"; // Charts Options $content['LN_CHARTS_CENTER'] = "Charts Optionen"; $content['LN_CHARTS_EDIT'] = "Chart bearbeiten"; $content['LN_CHARTS_DELETE'] = "Chart löschen"; $content['LN_CHARTS_ADD'] = "Neuen Chart hinzufuegen"; $content['LN_CHARTS_ADDEDIT'] = "Hinzufügen/Bearbeiten eines Charts"; $content['LN_CHARTS_NAME'] = "Name des Charts"; $content['LN_CHARTS_ENABLED'] = "Chart aktiviert"; $content['LN_CHARTS_ERROR_INVALIDORNOTFOUNDID'] = "Die Chart-ID is ungültig oder konnte nicht gefunden werden."; $content['LN_CHARTS_ERROR_IDNOTFOUND'] = "Die Chart-ID konnte in der Datenbank nicht gefunden werden."; $content['LN_CHARTS_WARNDELETESEARCH'] = "Sind Sie sicher, dass Sie den Chart '%1' löschen wollen? Dies kann nicht mehr rückgängig gemacht werden!"; $content['LN_CHARTS_ERROR_DELCHART'] = "Löschen des Chart mit der id '%1' fehlgeschlagen!"; $content['LN_CHARTS_ERROR_HASBEENDEL'] = "Der Chart '%1' wurde erfolgreich gelöscht!"; $content['LN_CHARTS_FILTERSTRING'] = "Custom Filter"; $content['LN_CHARTS_FILTERSTRING_HELP'] = "Use the same syntax as in the search field. For example if you want to generate a chart for 'server1', use this filter: source:=server1"; $content['LN_CHARTS_ERROR_CHARTIDNOTFOUND'] = "Error, ChartID with ID '%1' , was not found"; $content['LN_CHARTS_ERROR_SETTINGFLAG'] = "Error setting flag, invalid ChartID or operation."; // Fields Options $content['LN_FIELDS_CENTER'] = "Feld Options"; $content['LN_FIELDS_EDIT'] = "Feld Bearbeiten"; $content['LN_FIELDS_DELETE'] = "Feld löschen"; $content['LN_FIELDS_ADD'] = "Ein neues Feld hinzufügen"; $content['LN_FIELDS_ID'] = "Feld-ID"; $content['LN_FIELDS_NAME'] = "Anzeigename des Feldes"; $content['LN_FIELDS_DEFINE'] = "Interne Feld-ID"; $content['LN_FIELDS_DELETE_FROMDB'] = "Lösche des Feld aus der Datenbank"; $content['LN_FIELDS_ADDEDIT'] = "Hinzufügen/Bearbeiten des Feldes"; $content['LN_FIELDS_TYPE'] = "Feld-Typ"; $content['LN_FIELDS_ALIGN'] = "Ausrichtung der Liste"; $content['LN_FIELDS_SEARCHONLINE'] = "Aktiviere Online Suche"; $content['LN_FIELDS_DEFAULTWIDTH'] = "Zeilenhöhe in der Listenansicht"; $content['LN_FIELDS_ERROR_IDNOTFOUND'] = "Die Feld-ID konnte in der Datenbank oder in den Standardeinstellungen nicht gefunden werden."; $content['LN_FIELDS_ERROR_INVALIDID'] = "Das Feld mit der ID '%1' ist kein gültiges Feld."; $content['LN_FIELDS_SEARCHFIELD'] = "Name des Suchfilters"; $content['LN_FIELDS_WARNDELETESEARCH'] = "Sind Sie sicher, dass Sie das Feld '%1' löschen wollen? Dies kann nicht mehr rückgängig gemacht werden!"; $content['LN_FIELDS_ERROR_DELSEARCH'] = "Die Feld-ID konnte in der Datenbank nicht gefunden werden."; $content['LN_FIELDS_ERROR_HASBEENDEL'] = "Das Feld '%1' wurde erfolgreich gelöscht!"; $content['LN_FIELDS_ERROR_FIELDCAPTIONEMPTY'] = "Die Inhalt des Feldes war leer. "; $content['LN_FIELDS_ERROR_FIELDIDEMPTY'] = "Die ID des Feldes war leer. "; $content['LN_FIELDS_ERROR_SEARCHFIELDEMPTY'] = "Der Suchfilter war leer. "; $content['LN_FIELDS_ERROR_FIELDDEFINEEMPTY'] = "Die interne Feld-ID war leer. "; $content['LN_FIELDS_HASBEENEDIT'] = "Die Konfiguration des Feldes %1' wurde erfolgreich geändert."; $content['LN_FIELDS_HASBEENADDED'] = "Die Konfiguration des Feldes '%1' wurde erfolgreich hinzugefügt."; $content['LN_FIELDS_'] = ""; $content['LN_ALIGN_CENTER'] = "zentriert"; $content['LN_ALIGN_LEFT'] = "links"; $content['LN_ALIGN_RIGHT'] = "rechts"; $content['LN_FILTER_TYPE_STRING'] = "Zeichenkette"; $content['LN_FILTER_TYPE_NUMBER'] = "Zahl"; $content['LN_FILTER_TYPE_DATE'] = "Datum"; // Parser Options $content['LN_PARSERS_EDIT'] = "Bearbeiten eines Meldungs Parsers"; $content['LN_PARSERS_DELETE'] = "Löschen eines Meldungs Parsers"; $content['LN_PARSERS_ID'] = "Meldungs Parser ID"; $content['LN_PARSERS_NAME'] = "Melungs Parser Name"; $content['LN_PARSERS_DESCRIPTION'] = "Meldungs Parser Beschreibung"; $content['LN_PARSERS_ERROR_NOPARSERS'] = "Es konnte kein gültiger Meldungs Parser in Ihrer Installation gefunden werden. "; $content['LN_PARSERS_HELP'] = "Hilfe"; $content['LN_PARSERS_HELP_CLICK'] = "Klicken Sie hier, um weitere Hilfe und Beschreibung zu erhalten"; $content['LN_PARSERS_INFO'] = "Details für diesen Meldungs Parser anzeigen."; $content['LN_PARSERS_INIT'] = "Einstellungen für diesen Meldungs Parser."; $content['LN_PARSERS_REMOVE'] = "Einstellungen für diesen Meldungs Parser entfernen."; $content['LN_PARSERS_ERROR_IDNOTFOUND'] = "Es konnte kein Meldungs Parser mit der ID '%1' gefunden werden."; $content['LN_PARSERS_ERROR_INVALIDID'] = "Ungültige Meldungs Parser id."; $content['LN_PARSERS_DETAILS'] = "Details für diesen Meldungs Parser"; $content['LN_PARSERS_CUSTOMFIELDS'] = "Die folgenden benutzerdefinierten Felder werden von diesen Meldungs Parser benötigt."; $content['LN_PARSERS_WARNREMOVE'] = "Sie sind dabei die benötigten Felder des Meldungs Parser '%1' zu löschen. Sie können jederzeit die Felder wieder hinzufügen, falls Sie Ihre Meinung ändern sollten."; $content['LN_PARSERS_ERROR_HASBEENREMOVED'] = "Alle Einstellungen ('%2' benutzerdefinierte Felder) für den Meldungs Parser '%1' wurden entfernt. "; $content['LN_PARSERS_ERROR_HASBEENADDED'] = "Alle erforderlichen Einstellungen ('%2' benutzerdefinierte Felder) für den Meldungs Parser '%1' wurden hinzugefügt. "; $content['LN_PARSERS_ERROR_NOFIELDS'] = "Der Meldungs Parser '%1' benötigt keine benutzerdefinierten Felder."; $content['LN_PARSERSMENU_LIST'] = "List installed Message Parsers"; $content['LN_PARSERS_ONLINELIST'] = "All Available Parsers"; $content['LN_PARSERS_'] = ""; // Command Line stuff $content['LN_CMD_NOOP'] = "Ein benötigter Parameter ist nicht vorhanden"; $content['LN_CMD_NOLOGSTREAM'] = "Der Logstrom-Quellen Parameter ist nicht vorhanden"; $content['LN_CMD_LOGSTREAMNOTFOUND'] = "Logstrom-Quelle mit der ID '%1' konnte in der Datenbank nicht gefunden werden!"; $content['LN_CMD_COULDNOTGETROWCOUNT'] = "Es konnte keine Zeileanzahl von der Logstrom-Quelle '%1' ermittelt werden."; $content['LN_CMD_SUBPARAM1MISSING'] = "Unterparameter 1 ist nicht vorhanden, die Einstellung sollte 'all', 'since' or 'date' sein. Für mehr Details, sehen Sie bitte in der Dokumentation nach."; $content['LN_CMD_WRONGSUBOPORMISSING'] = "Entweder eine Unterfunktion ist fehlerhaft, oder ein anderer Parameter fehlt"; $content['LN_CMD_FAILEDTOCLEANDATA'] = "Das löschen der Daten aus dem Logstrom '%1'. war nicht erfolgreich!"; $content['LN_CMD_CLEANINGDATAFOR'] = "Lösche Daten aus der Logstrom-Quelle '%1'."; $content['LN_CMD_ROWSFOUND'] = "Erfolgreich Verbunden und '%1' Zeilen in der Logstom-Quelle gefunden."; $content['LN_CMD_DELETINGOLDERTHEN'] = "Durchführen der Löschung aller Einträge, älter als '%1'."; $content['LN_CMD_DELETEDROWS'] = "'%1' erfolgreich gelöschte Zeilen aus der Logstrom-Quelle.'"; $content['LN_CMD_'] = ""; // Report Options $content['LN_REPORTS_EDIT'] = "Edit Report"; $content['LN_REPORTS_DELETE'] = "Remove Report"; $content['LN_REPORTS_REQUIREDFIELDS'] = "Required Fields"; $content['LN_REPORTS_ERROR_NOREPORTS'] = "There were no valid reports found in your installation."; $content['LN_REPORTS_INFO'] = "Show more Information"; $content['LN_REPORTS_INIT'] = "Initialize settings"; $content['LN_REPORTS_REMOVE'] = "Remove settings"; $content['LN_REPORTS_ERROR_IDNOTFOUND'] = "There was no report with ID '%1' found."; $content['LN_REPORTS_ERROR_INVALIDID'] = "Invalid report id."; $content['LN_REPORTS_DETAILS'] = "Details for this report"; $content['LN_REPORTS_WARNREMOVE'] = "You are about to remove the custom settings needed by the '%1' report. However you can add these settings again if you change your mind."; $content['LN_REPORTS_ERROR_HASBEENREMOVED'] = "All settings for the report '%1' have been removed."; $content['LN_REPORTS_ERROR_HASBEENADDED'] = "All required settings for the report '%1' have been added."; $content['LN_REPORTS_ERROR_NOFIELDS'] = "The report '%1' does not have any custom settings which can be added."; $content['LN_REPORTS_ERROR_REPORTDOESNTNEEDTOBEREMOVED'] = "The report '%1' does not need to be removed or initialized."; $content['LN_REPORTS_REMOVESAVEDREPORT'] = "Remove Savedreport"; $content['LN_REPORTS_CUSTOMTITLE'] = "Report Title"; $content['LN_REPORTS_CUSTOMCOMMENT'] = "Comment / Description"; $content['LN_REPORTS_FILTERSTRING'] = "Filterstring"; $content['LN_REPORTS_OUTPUTFORMAT'] = "Outputformat"; $content['LN_REPORTS_OUTPUTTARGET'] = "Outputtarget"; $content['LN_REPORTS_HASBEENADDED'] = "The Savedreport '%1' has been successfully added."; $content['LN_REPORTS_HASBEENEDIT'] = "The Savedreport '%1' has been successfully edited."; $content['LN_REPORTS_SOURCEID'] = "Logstream source"; $content['LN_REPORTS_ERROR_SAVEDREPORTIDNOTFOUND'] = "There was no savedreport with ID '%1' found."; $content['LN_REPORTS_ERROR_INVALIDSAVEDREPORTID'] = "Invalid savedreport id."; $content['LN_REPORTS_RUNNOW'] = "Run saved report now!"; $content['LN_REPORTS_WARNDELETESAVEDREPORT'] = "Are you sure that you want to delete the savedreport '%1'?"; $content['LN_REPORTS_ERROR_DELSAVEDREPORT'] = "Deleting of the savedreport with id '%1' failed!"; $content['LN_REPORTS_ERROR_HASBEENDEL'] = "The savedreport '%1' has been successfully deleted!"; $content['LN_REPORTS_ERROR_ERRORCHECKINGSOURCE'] = "Error while checking Savedreport Source: %1"; $content['LN_REPORTS_FILTERLIST'] = "Filterlist"; $content['LN_REPORTS_FILTER'] = "Filter"; $content['LN_REPORTS_ADDFILTER'] = "Add filter"; $content['LN_REPORTS_FILTER_EDIT'] = "Edit filter"; $content['LN_REPORTS_FILTER_MOVEUP'] = "Move filter up"; $content['LN_REPORTS_FILTER_MOVEDOWN'] = "Move filter down"; $content['LN_REPORTS_FILTER_REMOVE'] = "Remove filter"; $content['LN_REPORTS_FILTEREDITOR'] = "Filtereditor"; $content['LN_REPORTS_FILTERSTRING_ONLYEDITIF'] = "Only edit raw filterstring if you know what you are doing! Note if you change the filterstring, any changes made in the Filtereditor will be lost!"; $content['LN_REPORTS_ADVANCEDFILTERS'] = "Advanced filters"; $content['LN_REPORTS_ADVANCEDFILTERLIST'] = "List of advanced report filters"; $content['LN_REPORTS_OUTPUTTARGET_DETAILS'] = "Outputtarget Options"; $content['LN_REPORTS_OUTPUTTARGET_FILE'] = "Output Path and Filename"; $content['LN_REPORTS_CRONCMD'] = "Local Report command"; $content['LN_REPORTS_LINKS'] = "Related Links"; $content['LN_REPORTS_INSTALLED'] = "Installed"; $content['LN_REPORTS_NOTINSTALLED'] = "Not installed"; $content['LN_REPORTS_DOWNLOAD'] = "Download Link"; $content['LN_REPORTS_SAMPLELINK'] = "Report Sample"; $content['LN_REPORTS_DETAILSFOR'] = "Details for '%1' report"; $content['LN_REPORTS_PERFORMANCE_WARNING'] = "Logstream Performance Warning"; $content['LN_REPORTS_OPTIMIZE_LOGSTREAMSOURCE'] = "Yes, optimize logstream source!"; $content['LN_REPORTS_OPTIMIZE_INDEXES'] = "The datasource '%1' is not optimized for this report. There is at least one INDEX missing. Creating INDEXES will speedup the report generation.

Do you want LogAnalyzer to create the necessary INDEXES now? This may take more then a few minutes, so please be patient!"; $content['LN_REPORTS_ERROR_FAILED_CREATE_INDEXES'] = "Failed to create INDEXES for datasource '%1' with error code '%2'"; $content['LN_REPORTS_INDEX_CREATED'] = "Logstream INDEXES created"; $content['LN_REPORTS_INDEX_CREATED_SUCCESS'] = "Successfully created all INDEXES for datasource '%1'."; $content['LN_REPORTS_OPTIMIZE_TRIGGER'] = "The datasource '%1' does not have a TRIGGER installed to automatically generate the message checksum on INSERT. Creating the TRIGGER will speedup the report generation.

Do you want LogAnalyzer to create the TRIGGER now? "; $content['LN_REPORTS_TRIGGER_CREATED'] = "Logstream TRIGGER created"; $content['LN_REPORTS_TRIGGER_CREATED_SUCCESS'] = "Successfully created TRIGGER for datasource '%1'."; $content['LN_REPORTS_ERROR_FAILED_CREATE_TRIGGER'] = "Failed to create TRIGGER for datasource '%1' with error code '%2'"; $content['LN_REPORTS_CHANGE_CHECKSUM'] = "The Checksum field for datasource '%1' is not set to UNSIGNED INT. To get the report work properly, changing the CHECKSUM field to UNSIGNED INT is necessary!

Do you want LogAnalyzer to change the CHECKSUM field now? This may take more then a few minutes, so please be patient!"; $content['LN_REPORTS_ERROR_FAILED_CHANGE_CHECKSUM'] = "Failed to change the CHECKSUM field for datasource '%1' with error code '%2'"; $content['LN_REPORTS_CHECKSUM_CHANGED'] = "Checksum field changed"; $content['LN_REPORTS_CHECKSUM_CHANGED_SUCCESS'] = "Successfully changed the Checksum field for datasource '%1'."; $content['LN_REPORTS_LOGSTREAM_WARNING'] = "Logstream Warning"; $content['LN_REPORTS_ADD_MISSINGFIELDS'] = "The datasource '%1' does not contain all necessary datafields There is at least one FIELD missing.

Do you want LogAnalyzer to create the missing datafields now?"; $content['LN_REPORTS_ERROR_FAILED_ADDING_FIELDS'] = "Failed adding missing datafields in datasource '%1' with error code '%2'"; $content['LN_REPORTS_FIELDS_CREATED'] = "Added missing datafields"; $content['LN_REPORTS_FIELDS_CREATED_SUCCESS'] = "Successfully added missing datafields for datasource '%1'."; $content['LN_REPORTS_RECHECKLOGSTREAMSOURCE'] = "Do you want to check the current logstream source again?"; $content['LN_REPORTS_ADDSAVEDREPORT'] = "Add Savedreport and save changes"; $content['LN_REPORTS_EDITSAVEDREPORT'] = "Save changes"; $content['LN_REPORTS_ADDSAVEDREPORTANDRETURN'] = "Add Savedreport and return to reportlist"; $content['LN_REPORTS_EDITSAVEDREPORTANDRETURN'] = "Save changes and return to reportlist"; $content['LN_REPORTS_'] = ""; ?>loganalyzer-3.6.5/src/lang/de/main.php0000644000175000017500000006456412225176641017110 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ global $content; // Global Stuff $content['LN_MAINTITLE'] = "Hauptseite LogAnalyzer"; $content['LN_MAIN_SELECTSTYLE'] = "Style auswählen"; $content['LN_GEN_LANGUAGE'] = "Sprache auswählen"; $content['LN_GEN_SELECTSOURCE'] = "Quelle auswälen"; $content['LN_GEN_MOREPAGES'] = "Mehr als eine Seite verfügbar"; $content['LN_GEN_FIRSTPAGE'] = "Erste Seite"; $content['LN_GEN_LASTPAGE'] = "Letzte Seite"; $content['LN_GEN_NEXTPAGE'] = "Nächste Seite"; $content['LN_GEN_PREVIOUSPAGE'] = "Vorherige Seite"; $content['LN_GEN_RECORDCOUNT'] = "Alle gefundenen Einträge"; $content['LN_GEN_PAGERSIZE'] = "Einträge pro Seite"; $content['LN_GEN_PAGE'] = "Seite"; $content['LN_GEN_PREDEFINEDSEARCHES'] = "Vordefinierte Suchkriterien"; $content['LN_GEN_SOURCE_DISK'] = "Datei"; $content['LN_GEN_SOURCE_DB'] = "Datenbank"; $content['LN_GEN_RECORDSPERPAGE'] = "Zeilen pro Seite"; $content['LN_GEN_PRECONFIGURED'] = "Vorkonfiguriert"; $content['LN_GEN_AVAILABLESEARCHES'] = "Verfügbare Suchabfragen"; $content['LN_GEN_DB_MYSQL'] = "MySQL Server"; $content['LN_GEN_DB_MSSQL'] = "Microsoft SQL Server"; $content['LN_GEN_DB_ODBC'] = "ODBC Datenbank Quelle"; $content['LN_GEN_DB_PGSQL'] = "PostgreSQL"; $content['LN_GEN_DB_OCI'] = "Oracle Call Interface"; $content['LN_GEN_DB_DB2'] = " IBM DB2"; $content['LN_GEN_DB_FIREBIRD'] = "Firebird/Interbase 6"; $content['LN_GEN_DB_INFORMIX'] = "IBM Informix Dynamic Server"; $content['LN_GEN_DB_SQLITE'] = "SQLite 2"; $content['LN_GEN_SELECTVIEW'] = "Anzeige auswählen"; $content['LN_GEN_CRITERROR_UNKNOWNTYPE'] = "Der Quell-Typ '%1' wird aktuell von LogAnalyzer nicht unterst&uum;tzt. Dies ist ein kritischer Fehler, bitte passen Sie Ihre Konfiguration an."; $content['LN_GEN_ERRORRETURNPREV'] = "Bitte klicken Sie hier, um auf die vorhergehende Seite zurückzukehren."; $content['LN_GEN_ERRORDETAILS'] = "Fehler Details:"; $content['LN_SOURCES_ERROR_WITHINSOURCE'] = "Die Überprüfung der Quelle '%1' endete mit dem Fehler: '%2'"; $content['LN_SOURCES_ERROR_EXTRAMSG'] = "Extra Fehler Details:
%1"; $content['LN_ERROR_NORECORDS'] = "Es wurden keine syslog-Einträge gefunden."; $content['LN_ERROR_FILE_NOT_FOUND'] = "Die Syslog Datei konnte nicht gefunden werden"; $content['LN_ERROR_FILE_NOT_READABLE'] = "Die Syslog Datei ist nicht lesbar, lesender Zugriff ist evtl. nicht gestattet"; $content['LN_ERROR_UNKNOWN'] = "Ein unbekannter oder unerwarteter Fehler ist aufgetreten. (Fehler Code '%1')"; $content['LN_ERROR_FILE_EOF'] = "Ende der Datei erreicht"; $content['LN_ERROR_FILE_BOF'] = "Anfang der Datei erreicht"; $content['LN_ERROR_FILE_CANT_CLOSE'] = "Das Schliessen der Datei ist nicht möglich"; $content['LN_ERROR_UNDEFINED'] = "Unerwarteter Fehler"; $content['LN_ERROR_EOS'] = "Ende des Datenstroms erreicht"; $content['LN_ERROR_FILTER_NOT_MATCH'] = "Der Filter ergab keine Übereinstimmung im Ergbenis"; $content['LN_ERROR_DB_CONNECTFAILED'] = "Die Verbindung zum Datenbank Server ist fehlgeschlagen"; $content['LN_ERROR_DB_CANNOTSELECTDB'] = "Die in der Konfiguration angegeben Datenbank konnte nicht gefunden werden"; $content['LN_ERROR_DB_QUERYFAILED'] = "Die Datenbank-Abfrage konnte nicht ausgeführt werden"; $content['LN_ERROR_DB_NOPROPERTIES'] = "Keine Einstellungen zur Datenbank gefunden"; $content['LN_ERROR_DB_INVALIDDBMAPPING'] = "Ungültige Datenfeld Zuordnung"; $content['LN_ERROR_DB_INVALIDDBDRIVER'] = "Ungültiger Datenbank Treiber ausgewählt"; $content['LN_ERROR_DB_TABLENOTFOUND'] = "Die angegebene Tabelle konnte nicht gefunden werden, evtl. ist der Eintrag falsch geschrieben oder Gross- und Kleinschreibung wurden nicht beachtet."; $content['LN_ERROR_DB_DBFIELDNOTFOUND'] = "Die Datenbankfeldzuordnung ist fehlerhaft, es konnte mindestens ein Feld nicht gefunden werden."; $content['LN_GEN_SELECTEXPORT'] = "> Exportformat auswählen <"; $content['LN_GEN_EXPORT_CVS'] = "CSV (Komma unterteilt)"; $content['LN_GEN_EXPORT_XML'] = "XML"; $content['LN_GEN_EXPORT_PDF'] = "PDF"; $content['LN_GEN_ERROR_EXPORING'] = "Fehler beim exportieren der Daten"; $content['LN_GEN_ERROR_INVALIDEXPORTTYPE'] = "Ungültiges Export Format ausgewähtl, oder andere Parameter sind ungültig."; $content['LN_GEN_ERROR_SOURCENOTFOUND'] = "Die Quelle mit der ID '%1' konnte nicht gefunden werden."; $content['LN_GEN_MOREINFORMATION'] = "Mehr Informationen"; $content['LN_FOOTER_PAGERENDERED'] = "Siete gerenderet in"; $content['LN_FOOTER_DBQUERIES'] = "DB Abfragen"; $content['LN_FOOTER_GZIPENABLED'] = "GZIP ermöglichen"; $content['LN_FOOTER_SCRIPTTIMEOUT'] = "Max. Skript Laufzeit"; $content['LN_FOOTER_SECONDS'] = "Sekunden"; $content['LN_WARNING_LOGSTREAMTITLE'] = "Log-Datenstrom Warnung"; $content['LN_WARNING_LOGSTREAMDISK_TIMEOUT'] = "Beim lesen des Log-Datenstroms, hat das PHP-Skript die max. Laufzeit erreicht und wurde abgebrochen.

Falls Sie dennoch die Ausführung ermöglichen wollen, bitte erhöhen Sie die max. LogAnalyzer Skript Laufzeit in Ihrer config.php. Falls das Benutzersystem installiert ist, können Sie dies im Bereich Administration einstellen."; $content['LN_WARNING_DBUPGRADE'] = "Datenbank Upgrade erforderlich"; $content['LN_WARNING_DBUPGRADE_TEXT'] = "Die aktuell installierte Datenbankversion ist '%1'.
Ein Update auf Version '%2' ist verfügbar."; $content['LN_ERROR_REDIRECTABORTED'] = 'Automatiche Rückkehr zur Seite page wurde abgebrochen, da ein interner Fehler aufgetrete ist. Bitte beachten Sie die weiteren Informationen zu diesem Fehler über dieser Meldung und/oder nehmen Sie Kontakt zum Support-Forum auf, falls Sie Hilfe benötigen.'; $content['LN_DEBUGLEVEL'] = "Debug Level"; $content['LN_DEBUGMESSAGE'] = "Debug Meldung"; $content['LN_GEN_REPORT_OUTPUT_HTML'] = "HTML Format"; $content['LN_GEN_REPORT_OUTPUT_PDF'] = "PDF Format"; $content['LN_GEN_UNKNOWN'] = "Unbekannt"; // Topmenu Entries $content['LN_MENU_SEARCH'] = "Suchen"; $content['LN_MENU_SHOWEVENTS'] = "Meldungen"; $content['LN_MENU_HELP'] = "Hilfe"; $content['LN_MENU_DOC'] = "Dokumentation"; $content['LN_MENU_FORUM'] = "Support Forum"; $content['LN_MENU_WIKI'] = "LogAnalyzer Wiki"; $content['LN_MENU_PROSERVICES'] = "Professionelle Unterstützung"; $content['LN_MENU_SEARCHINKB'] = "Suche in der Wissensdatenbank"; $content['LN_MENU_LOGIN'] = "Anmeldung"; $content['LN_MENU_ADMINCENTER'] = "Administration"; $content['LN_MENU_LOGOFF'] = "Abmeldung"; $content['LN_MENU_LOGGEDINAS'] = "Angemeldet als "; $content['LN_MENU_MAXVIEW'] = "Anzeige maximieren"; $content['LN_MENU_NORMALVIEW'] = "Standard Anzeige"; $content['LN_MENU_STATISTICS'] = "Statistiken"; $content['LN_MENU_CLICKTOEXPANDMENU'] = "Klicken Sie das Icon um das Menü anzuzeigen"; // Index Site $content['LN_ERROR_INSTALLFILEREMINDER'] = "Warnung! Sie haben das Installationsskript 'install.php' noch nicht aus dem LogAnalyzer Hauptordner entfernt!"; $content['LN_TOP_NUM'] = "No."; $content['LN_TOP_UID'] = "uID"; $content['LN_GRID_POPUPDETAILS'] = "Details f&uulm;r die Syslog-Meldung mit der ID '%1'"; $content['LN_SEARCH_USETHISBLA'] = "Bitte berücksichtigen Sie bei Ihrer Suche folgende Kriterien"; $content['LN_SEARCH_FILTER'] = "Suche (Filter):"; $content['LN_SEARCH_ADVANCED'] = "Erweiterte Suche"; $content['LN_SEARCH'] = "Suche"; $content['LN_SEARCH_RESET'] = "Suche zurücksetzen"; $content['LN_SEARCH_PERFORMADVANCED'] = "Erweiterte Suche starten"; $content['LN_VIEW_MESSAGECENTERED'] = "Zurück zur ungefilterten Ansicht, mit dieser Meldung als erster"; $content['LN_VIEW_RELATEDMSG'] = "Anzeige vorheriger Syslog Meldungen "; $content['LN_VIEW_FILTERFOR'] = "Filtere Meldungen nach "; $content['LN_VIEW_SEARCHFOR'] = "Suche online nach "; $content['LN_VIEW_SEARCHFORGOOGLE'] = "Durchsuche Google nach "; $content['LN_GEN_MESSAGEDETAILS'] = "Meldungsdetails"; $content['LN_VIEW_ADDTOFILTER'] = "Fü '%1' zur Filterliste hinzu"; $content['LN_VIEW_EXCLUDEFILTER'] = "Entferne '%1' von der Filterliste"; $content['LN_VIEW_FILTERFORONLY'] = "Filtere nur nach '%1'"; $content['LN_VIEW_SHOWALLBUT'] = "Anzeige aller Meldungen, ausgenommen '%1'"; $content['LN_VIEW_VISITLINK'] = "Öffne Link '%1' in neuem Fenster"; $content['LN_HIGHLIGHT'] = "Hervorhebung >>"; $content['LN_HIGHLIGHT_OFF'] = "Hervorhebung <<"; $content['LN_HIGHLIGHT_WORDS'] = "Hervorgehobene Wörter durch ein Komma voneinander trennen"; $content['LN_AUTORELOAD'] = "Auto. neu laden"; $content['LN_AUTORELOAD_DISABLED'] = "Auto. neu laden deaktiviert"; $content['LN_AUTORELOAD_PRECONFIGURED'] = "Konfiguriere auto. neu laden "; $content['LN_AUTORELOAD_SECONDS'] = "Sekunden"; $content['LN_AUTORELOAD_MINUTES'] = "Minuten"; // Filter Options $content['LN_FILTER_DATE'] = "Zeitliche Abgrenzung"; $content['LN_FILTER_DATEMODE'] = "Zeitraum auswählen"; $content['LN_DATEMODE_ALL'] = "Kompletter Zeitraum"; $content['LN_DATEMODE_RANGE'] = "Zeitspanne"; $content['LN_DATEMODE_LASTX'] = "Seit heute, x Uhr"; $content['LN_FILTER_DATEFROM'] = "Zeitraum seit x"; $content['LN_FILTER_DATETO'] = "Zeitraum bis x"; $content['LN_FILTER_TIMEFROM'] = "Time range from"; $content['LN_FILTER_TIMETO'] = "Time range to"; $content['LN_FILTER_DATELASTX'] = "Zeit seit"; $content['LN_FILTER_ADD2SEARCH'] = "Zur Suche hinzufügen"; $content['LN_DATE_LASTX_HOUR'] = "in der letzten Stunde"; $content['LN_DATE_LASTX_12HOURS'] = "in den letzten 12 Stunden"; $content['LN_DATE_LASTX_24HOURS'] = "in den letzten 24 Stunden"; $content['LN_DATE_LASTX_7DAYS'] = "in den letzten 7 Tagen"; $content['LN_DATE_LASTX_31DAYS'] = "in den letzten 31 Tagen"; $content['LN_FILTER_FACILITY'] = "Syslog Kategorie/Facility"; $content['LN_FILTER_SEVERITY'] = "Syslog Dringlichkeit/Severity"; $content['LN_FILTER_OTHERS'] = "Andere Filter"; $content['LN_FILTER_MESSAGE'] = "Syslog Meldungen"; $content['LN_FILTER_SYSLOGTAG'] = "Syslogtag"; $content['LN_FILTER_SOURCE'] = "Quelle (Hostname)"; $content['LN_FILTER_MESSAGETYPE'] = "Meldungs Typ"; // Install Page $content['LN_CFG_DBSERVER'] = "Datenbank Host"; $content['LN_CFG_DBPORT'] = "Datenbank Port"; $content['LN_CFG_DBNAME'] = "Datenbank Name"; $content['LN_CFG_DBPREF'] = "Tabellen Präfix"; $content['LN_CFG_DBUSER'] = "Datenbank Benutzer"; $content['LN_CFG_DBPASSWORD'] = "Datenbank Passwort"; $content['LN_CFG_PARAMMISSING'] = "Die folgenden Parameter können nicht gefunden werden: "; $content['LN_CFG_SOURCETYPE'] = "Quell-Typ"; $content['LN_CFG_DISKTYPEOPTIONS'] = "Disk-Typ Optionen"; $content['LN_CFG_LOGLINETYPE'] = "Logzeilentyp"; $content['LN_CFG_SYSLOGFILE'] = "Syslog Datei"; $content['LN_CFG_DATABASETYPEOPTIONS'] = "Datenbank Typ Optionen"; $content['LN_CFG_DBTABLETYPE'] = "Tabellen Typ"; $content['LN_CFG_DBSTORAGEENGINE'] = "Datenbank Typ"; $content['LN_CFG_DBTABLENAME'] = "Datenbank Tabellenname"; $content['LN_CFG_NAMEOFTHESOURCE'] = "Name der Quelle"; $content['LN_CFG_FIRSTSYSLOGSOURCE'] = "Erste Syslog Quelle"; $content['LN_CFG_VIEW'] = "Anzeige auswählen"; $content['LN_CFG_DBUSERLOGINREQUIRED'] = "Erfordert eine Benutzer-Anmeldung"; $content['LN_CFG_MSGPARSERS'] = "Meldungs Parser (Komma getrent)"; $content['LN_CFG_NORMALIZEMSG'] = "Standard Meldunganzeige mit Parser"; $content['LN_CFG_SKIPUNPARSEABLE'] = "Überspringe nicht lesbare Meldungen (Nur möglich, wenn ein Parsen konfiguriert wurde!)"; $content['LN_CFG_DBRECORDSPERQUERY'] = "Anzahl der Datenbankabfragen"; // Details page $content['LN_DETAILS_FORSYSLOGMSG'] = "Details für Syslog-Nachrichten mit der ID"; $content['LN_DETAILS_DETAILSFORMSG'] = "Details für Nachrichten-ID"; $content['LN_DETAIL_BACKTOLIST'] = "Zurück zur Listenansicht"; // Login Site $content['LN_LOGIN_DESCRIPTION'] = "Bitte geben Sie Ihren Benutzernamen und Ihr dazugehöriges Passwort ein, um sich bei LogAnalyzer anzumelden. "; $content['LN_LOGIN_TITLE'] = "Anmeldung"; $content['LN_LOGIN_USERNAME'] = "Benutzername"; $content['LN_LOGIN_PASSWORD'] = "Passwort"; $content['LN_LOGIN_SAVEASCOOKIE'] = "Angemeldet bleiben"; $content['LN_LOGIN_ERRWRONGPASSWORD'] = "Falscher Benutzername oder falsches Passwort!"; $content['LN_LOGIN_USERPASSMISSING'] = "Benutzername und/oder Passwort wurden nicht eingegeben!"; // Install Site $content['LN_INSTALL_TITLETOP'] = "Installing LogAnalyzer Version %1 - Step %2"; $content['LN_INSTALL_TITLE'] = "Installer Step %1"; $content['LN_INSTALL_ERRORINSTALLED'] = 'LogAnalyzer is already configured!

If you want to reconfigure LogAnalyzer, either delete the current config.php or replace it with an empty file.

Click here to return to pgpLogCon start page.'; $content['LN_INSTALL_FILEORDIRNOTWRITEABLE'] = "At least one file or directory (or more) is not writeable, please check the file permissions (chmod 666)!"; $content['LN_INSTALL_SAMPLECONFIGMISSING'] = "The sample configuration file '%1' is missing. You have not fully uploaded LogAnalyzer."; $content['LN_INSTALL_ERRORCONNECTFAILED'] = "Database connect to '%1' failed! Please check Servername, Port, User and Password!"; $content['LN_INSTALL_ERRORACCESSDENIED'] = "Cannot use the database '%1'! If the database does not exists, create it or check user access permissions!"; $content['LN_INSTALL_ERRORINVALIDDBFILE'] = "Error, invalid Database definition file (to short!), the file name is '%1'! Please check if the file was correctly uploaded."; $content['LN_INSTALL_ERRORINSQLCOMMANDS'] = "Error, invalid Database definition file (no sql statements found!), the file name is '%1'!
Please check if the file was not correctly uploaded, or contact the LogAnalyzer forums for assistance!"; $content['LN_INSTALL_MISSINGUSERNAME'] = "Username needs to be specified"; $content['LN_INSTALL_PASSWORDNOTMATCH'] = "Either the password does not match or is to short!"; $content['LN_INSTALL_FAILEDTOOPENSYSLOGFILE'] = "Failed to open the syslog file '%1'! Check if the file exists and LogAnalyzer has sufficient rights to it
"; $content['LN_INSTALL_FAILEDCREATECFGFILE'] = "Coult not create the configuration file in '%1'! Please verify the file permissions!"; $content['LN_INSTALL_FAILEDREADINGFILE'] = "Error reading the file '%1'! Please verify if the file exists!"; $content['LN_INSTALL_ERRORREADINGDBFILE'] = "Error reading the default database definition file in '%1'! Please verify if the file exists!"; $content['LN_INSTALL_STEP1'] = "Step 1 - Prerequisites"; $content['LN_INSTALL_STEP2'] = "Step 2 - Verify File Permissions"; $content['LN_INSTALL_STEP3'] = "Step 3 - Basic Configuration"; $content['LN_INSTALL_STEP4'] = "Step 4 - Create Tables"; $content['LN_INSTALL_STEP5'] = "Step 5 - Check SQL Results"; $content['LN_INSTALL_STEP6'] = "Step 6 - Creating the Main Useraccount"; $content['LN_INSTALL_STEP7'] = "Step 7 - Create the first source for syslog messages"; $content['LN_INSTALL_STEP8'] = "Step 8 - Done"; $content['LN_INSTALL_STEP1_TEXT'] = 'Before you start installing LogAnalyzer, the Installer setup has to check a few things first.
You may have to correct some file permissions first.

Click on to start the Test!'; $content['LN_INSTALL_STEP2_TEXT'] = "The following file permissions have been checked. Verify the results below!
You may use the configure.sh script from the contrib folder to set the permissions for you."; $content['LN_INSTALL_STEP3_TEXT'] = "In this step, you configure the basic configurations for LogAnalyzer."; $content['LN_INSTALL_STEP4_TEXT'] = 'If you reached this step, the database connection has been successfully verified!

The next step will be to create the necessary database tables used by the LogAnalyzer User System. This might take a while!
WARNING, if you have an existing LogAnalyzer installation in this database with the same tableprefix, all your data will be OVERWRITTEN! Make sure you are using a fresh database, or you want to overwrite your old LogAnalyzer database.

Click on to start the creation of the tables'; $content['LN_INSTALL_STEP5_TEXT'] = "Tables have been created. Check the List below for possible Error's"; $content['LN_INSTALL_STEP6_TEXT'] = "You are now about to create the initial LogAnalyzer User Account.
This will be the first administrative user, which will be needed to login into LogAnalyzer and access the Admin Center!"; $content['LN_INSTALL_STEP8_TEXT'] = 'Congratulations! You have successfully installed LogAnalyzer :)!

Click here to go to your installation.'; $content['LN_INSTALL_PROGRESS'] = "Install Progress: "; $content['LN_INSTALL_FRONTEND'] = "Frontend Options"; $content['LN_INSTALL_NUMOFSYSLOGS'] = "Number of syslog messages per page"; $content['LN_INSTALL_MSGCHARLIMIT'] = "Message character limit for the main view"; $content['LN_INSTALL_STRCHARLIMIT'] = "Character display limit for all string type fields"; $content['LN_INSTALL_SHOWDETAILPOP'] = "Show message details popup"; $content['LN_INSTALL_AUTORESOLVIP'] = "Automatically resolved IP Addresses (inline)"; $content['LN_INSTALL_USERDBOPTIONS'] = "User Database Options"; $content['LN_INSTALL_ENABLEUSERDB'] = "Enable User Database"; $content['LN_INSTALL_SUCCESSSTATEMENTS'] = "Successfully executed statements:"; $content['LN_INSTALL_FAILEDSTATEMENTS'] = "Failed statements:"; $content['LN_INSTALL_STEP5_TEXT_NEXT'] = "You can now proceed to the next step adding the first LogAnalyzer Admin User!"; $content['LN_INSTALL_STEP5_TEXT_FAILED'] = "At least one statement failed,see error reasons below"; $content['LN_INSTALL_ERRORMSG'] = "Error Message"; $content['LN_INSTALL_SQLSTATEMENT'] = "SQL Statement"; $content['LN_INSTALL_CREATEUSER'] = "Create User Account"; $content['LN_INSTALL_PASSWORD'] = "Password"; $content['LN_INSTALL_PASSWORDREPEAT'] = "Repeat Password"; $content['LN_INSTALL_SUCCESSCREATED'] = "Successfully created User"; $content['LN_INSTALL_RECHECK'] = "ReCheck"; $content['LN_INSTALL_FINISH'] = "Finish!"; $content['LN_INSTALL_'] = ""; // Converter Site $content['LN_CONVERT_TITLE'] = "Configuration Converter Step %1"; $content['LN_CONVERT_NOTALLOWED'] = "Login"; $content['LN_CONVERT_ERRORINSTALLED'] = 'LogAnalyzer is not allowed to convert your settings into the user database.

If you want to convert your convert your settings, add the variable following into your config.php:
$CFG[\'UserDBConvertAllowed\'] = true;

Click here to return to pgpLogCon start page.'; $content['LN_CONVERT_STEP1'] = "Step 1 - Informations"; $content['LN_CONVERT_STEP2'] = "Step 2 - Create Tables"; $content['LN_CONVERT_STEP3'] = "Step 3 - Check SQL Results"; $content['LN_CONVERT_STEP4'] = "Step 4 - Creating the Main Useraccount"; $content['LN_CONVERT_STEP5'] = "Step 5 - Import Settings into UserDB"; $content['LN_CONVERT_TITLETOP'] = "Converting LogAnalyzer configuration settings - Step "; $content['LN_CONVERT_STEP1_TEXT'] = 'This script allows you to import your existing configuration from the config.php file. This includes frontend settings, data sources, custom views and custom searches. Do only perform this conversion if you did install LogAnalyzer without the UserDB System, and decided to enable it now.

ANY EXISTING INSTANCE OF A USERDB WILL BE OVERWRITTEN!

to start the first conversion step!'; $content['LN_CONVERT_STEP2_TEXT'] = 'The database connection has been successfully verified!

The next step will be to create the necessary database tables for the LogAnalyzer User System. This might take a while!
WARNING, if you have an existing LogAnalyzer installation in this database with the same tableprefix, all your data will be OVERWRITTEN!
Make sure you are using a fresh database, or you want to overwrite your old LogAnalyzer database.

Click on to start the creation of the tables'; $content['LN_CONVERT_STEP5_TEXT'] = ' to start the last step of the conversion. In this step, your existing configuration from the config.php will be imported into the database.'; $content['LN_CONVERT_STEP6'] = "Step 8 - Done"; $content['LN_CONVERT_STEP6_TEXT'] = 'Congratulations! You have successfully converted your existing LogAnalyzer installation :)!

Important! Don\'t forget to REMOVE THE VARIABLES $CFG[\'UserDBConvertAllowed\'] = true; from your config.php file!

You can click here to get to your LogAnalyzer installation.'; $content['LN_CONVERT_PROCESS'] = "Conversion Progress:"; $content['LN_CONVERT_ERROR_SOURCEIMPORT'] = "Critical Error while importing the sources into the database, the SourceType '%1' is not supported by this LogAnalyzer Version."; // Stats Site $content['LN_STATS_CHARTTITLE'] = "Top %1 '%2' sortiert nach Meldungsanzahl"; $content['LN_STATS_COUNTBY'] = "Meldungsanzahl '%1'"; $content['LN_STATS_GRAPH'] = "Grafik"; $content['LN_STATS_TOPRECORDS'] = "Max. Anzahl: %1"; $content['LN_STATS_GENERATEDAT'] = "Erstellumgsdatum: %1"; $content['LN_GEN_ERROR_INVALIDFIELD'] = "Ungütiger Feldname"; $content['LN_GEN_ERROR_MISSINGCHARTFIELD'] = "Fehlender Feldname"; $content['LN_GEN_ERROR_INVALIDTYPE'] = "Ungültiger oder unbekannter Chart Typ"; $content['LN_ERROR_CHARTS_NOTCONFIGURED'] = "Es wurden kein Chart konfiguriert."; $content['LN_CHART_TYPE'] = "Chart Typ"; $content['LN_CHART_WIDTH'] = "Chart Breite"; $content['LN_CHART_FIELD'] = "Chart Felder"; $content['LN_CHART_MAXRECORDS'] = "Top Anzahl Summe"; $content['LN_CHART_SHOWPERCENT'] = "Prozentuale Anzeige"; $content['LN_CHART_TYPE_CAKE'] = "Kuchen (Pie)"; $content['LN_CHART_TYPE_BARS_VERTICAL'] = "Balken vertikal"; $content['LN_CHART_TYPE_BARS_HORIZONTAL'] = "Balken horizontal"; $content['LN_STATS_WARNINGDISPLAY'] = "Das Erstellen von Grafiken über eine grosse Anzahl von Datensätzen kann sehr Prozessortlastig sein.
Dies wird in nachfolgenden Versionen noch weiter optimiert werden.
Falls die Erstellung der Grafiken zu viel Prozessortzeit in Anspruch nehmen sollte, bitte brechen Sie die Erstellung einfach ab."; // asktheoracle site $content['LN_ORACLE_TITLE'] = "Fragen Sie das Orakel nach '%1'"; $content['LN_ORACLE_HELP_FOR'] = "Das sind die Links welche das Orakel für Sie ermittelt hat"; $content['LN_ORACLE_HELP_TEXT'] = "

Sie haben das Orakel nach mehr Informationen über '%1' - '%2' gefragt.

Diese Seite ermöglicht es Ihnen eine Suche über verschiedene Log-Quellen zu starten. %3
Die Idee ist es, einfach nach Informationen über spezifizierte Angaben allerorts zu suchen, egal wo diese vorkommen.

"; $content['LN_ORACLE_HELP_TEXT_EXTERNAL'] = "Es wird eine Suche über externe Datenquellen ermöglichti."; $content['LN_ORACLE_HELP_DETAIL'] = "Link Übersicht für '%1' - '%2'"; $content['LN_ORACLE_SEARCH'] = "Suche"; // in '%1' Field"; $content['LN_ORACLE_SOURCENAME'] = "Quellen Name"; $content['LN_ORACLE_FIELD'] = "Feld"; $content['LN_ORACLE_ONLINESEARCH'] = "Online Suche"; $content['LN_ORACLE_WHOIS'] = "WHOIS Abfrage für '%1' - '%2'"; $content['LN_GEN_ERROR_INVALIDOP'] = "Invalid or missing operation type"; $content['LN_GEN_ERROR_INVALIDREPORTID'] = "Invalid or missing report id"; $content['LN_GEN_ERROR_MISSINGSAVEDREPORTID'] = "Invalid or missing savedreport id"; $content['LN_GEN_ERROR_REPORTGENFAILED'] = "Failed generating report '%1' with the following error reason: %2"; $content['LN_GEN_ERROR_WHILEREPORTGEN'] = "Error occured while generating report"; $content['LN_GEN_ERROR_REPORT_NODATA'] = "No data found for report generation"; $content['LN_GEN_ALL_OTHER_EVENTS'] = "All other events"; $content['LN_REPORT_FOOTER_ENDERED'] = "Report rendered in"; $content['LN_REPORT_FILTERS'] = "List of used filters"; $content['LN_REPORT_FILTERTYPE_DATE'] = "Date"; $content['LN_REPORT_FILTERTYPE_NUMBER'] = "Number"; $content['LN_REPORT_FILTERTYPE_STRING'] = "String"; $content['LN_GEN_SUCCESS_WHILEREPORTGEN'] = "Report was successfully generated"; $content['LN_GEN_ERROR_REPORTFAILEDTOGENERATE'] = "Failed to generate report, error details: %1"; $content['LN_GEN_SUCCESS_REPORTWASGENERATED_DETAILS'] = "Successfully generated report: %1"; $content['LN_CMD_RUNREPORT'] = "Generating saved report '%1'"; $content['LN_CMD_REPORTIDNOTFOUND'] = "Invalid Report ID '%1'"; $content['LN_CMD_SAVEDREPORTIDNOTFOUND'] = "Invalid SavedReport ID '%1'"; $content['LN_CMD_NOREPORTID'] = "Missing Report ID"; $content['LN_CMD_NOSAVEDREPORTID'] = "Missing SavedReport ID"; $content['LN_CMD_NOCMDPROMPT'] = "Error, this script can only be run from the command prompt."; $content['LN_REPORT_GENERATEDTIME'] = "Report generated at: "; $content['LN_REPORT_ACTIONS'] = "Run Report Actions"; $content['LN_REPORTS_CAT'] = "Report Category"; $content['LN_REPORTS_ID'] = "Report ID"; $content['LN_REPORTS_NAME'] = "Report Name"; $content['LN_REPORTS_DESCRIPTION'] = "Report Description"; $content['LN_REPORTS_HELP'] = "Help"; $content['LN_REPORTS_HELP_CLICK'] = "Click here for a detailed report description"; $content['LN_REPORTS_INFO'] = "Show more Information"; $content['LN_REPORTS_SAVEDREPORTS'] = "Saved reports"; $content['LN_REPORTS_ADMIN'] = "Administrate Reports"; $content['LN_REPORTMENU_LIST'] = "List installed Reports"; $content['LN_REPORTMENU_ONLINELIST'] = "All Available Reports"; $content['LN_REPORTS_INFORMATION'] = "This page shows a list of installed and available reports including saved report configurations.
To run a report, click on the buttons right to the Saved Reports.
Attention! Generating reports can be very time consuming depending on the size of your database. "; $content['LN_REPORTS_CHECKLOGSTREAMSOURCE'] = "Verify Logstream optimization"; ?>loganalyzer-3.6.5/src/lang/en/0000755000175000017500000000000012225176641015446 5ustar danieldanielloganalyzer-3.6.5/src/lang/en/info.txt0000644000175000017500000000000712225176641017137 0ustar danieldanielEnglishloganalyzer-3.6.5/src/lang/en/admin.php0000644000175000017500000010176612225176641017262 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ global $content; // Global Stuff $content['LN_ADMINMENU_HOMEPAGE'] = "Back to Show Events"; $content['LN_ADMINMENU_GENOPT'] = "Preferences"; $content['LN_ADMINMENU_SOURCEOPT'] = "Sources"; $content['LN_ADMINMENU_VIEWSOPT'] = "Views"; $content['LN_ADMINMENU_SEARCHOPT'] = "Searches"; $content['LN_ADMINMENU_USEROPT'] = "Users"; $content['LN_ADMINMENU_GROUPOPT'] = "Groups"; $content['LN_ADMINMENU_CHARTOPT'] = "Charts"; $content['LN_ADMINMENU_FIELDOPT'] = "Fields"; $content['LN_ADMINMENU_DBMAPPINGOPT'] = "DBMappings"; $content['LN_ADMINMENU_MSGPARSERSOPT'] = "Message Parsers"; $content['LN_ADMINMENU_REEPORTSOPT'] = "Report Modules"; $content['LN_ADMIN_CENTER'] = "Admin center"; $content['LN_ADMIN_UNKNOWNSTATE'] = "Unknown State"; $content['LN_ADMIN_ERROR_NOTALLOWED'] = "You are not allowed to access this page with your user level."; $content['LN_DELETEYES'] = "Yes"; $content['LN_DELETENO'] = "No"; $content['LN_GEN_ACTIONS'] = "Available Actions"; $content['LN_ADMIN_SEND'] = "Send changes"; $content['LN_GEN_USERONLY'] = "User only"; $content['LN_GEN_GROUPONLY'] = "Group only"; $content['LN_GEN_GLOBAL'] = "Global"; $content['LN_GEN_USERONLY_LONG'] = "For me only
(Only available to your user)"; $content['LN_GEN_GROUPONLY_LONG'] = "For this group
(Only available to the selected group)"; $content['LN_GEN_GROUPONLYNAME'] = "Group '%1'"; $content['LN_ADMIN_POPUPHELP'] = "Details on this function"; $content['LN_ADMIN_DBSTATS'] = "Show database statistics."; $content['LN_ADMIN_CLEARDATA'] = "If you need to remove old data records, use this function."; $content['LN_UPDATE_AVAILABLE'] = "Update available"; $content['LN_UPDATE_INSTALLEDVER'] = "Installed version: "; $content['LN_UPDATE_AVAILABLEVER'] = "Available version: "; $content['LN_UPDATE_LINK'] = "Click here to get the update"; // General Options $content['LN_ADMIN_GLOBFRONTEND'] = "Global frontend options"; $content['LN_ADMIN_USERFRONTEND'] = "User specific frontend options"; $content['LN_ADMIN_MISC'] = "Miscellaneous Options"; $content['LN_GEN_SHOWDEBUGMSG'] = "Show Debug messages"; $content['LN_GEN_DEBUGGRIDCOUNTER'] = "Show Debug Gridcounter"; $content['LN_GEN_SHOWPAGERENDERSTATS'] = "Show Pagerenderstats"; $content['LN_GEN_ENABLEGZIP'] = "Enable GZIP Compressed Output"; $content['LN_GEN_DEBUGUSERLOGIN'] = "Debug Userlogin"; $content['LN_GEN_WEBSTYLE'] = "Default selected style"; $content['LN_GEN_SELLANGUAGE'] = "Default selected language"; $content['LN_GEN_PREPENDTITLE'] = "Prepend this string in title"; $content['LN_GEN_USETODAY'] = "Use Today and Yesterday in timefields"; $content['LN_GEN_DETAILPOPUPS'] = "Use Popup to display the full messagedetails"; $content['LN_GEN_MSGCHARLIMIT'] = "Character limit of the message in main view"; $content['LN_GEN_STRCHARLIMIT'] = "Character display limit for all string type fields"; $content['LN_GEN_ENTRIESPERPAGE'] = "Number of entries per page"; $content['LN_GEN_AUTORELOADSECONDS'] = "Enable autoreload after seconds"; $content['LN_GEN_ADMINCHANGEWAITTIME'] = "Reloadtime in Adminpanel"; $content['LN_GEN_IPADRRESOLVE'] = "Resolve IP Addresses using DNS"; $content['LN_GEN_CUSTBTNCAPT'] = "Custom search caption"; $content['LN_GEN_CUSTBTNSRCH'] = "Custom search string"; $content['LN_GEN_SUCCESSFULLYSAVED'] = "The configuration Values have been successfully saved"; $content['LN_GEN_INTERNAL'] = "Internal"; $content['LN_GEN_DISABLED'] = "Function disabled"; $content['LN_GEN_CONFIGFILE'] = "Configuration File"; $content['LN_GEN_ACCESSDENIED'] = "Access denied to this function"; $content['LN_GEN_DEFVIEWS'] = "Default selected view"; $content['LN_GEN_DEFSOURCE'] = "Default selected source"; $content['LN_GEN_SUPPRESSDUPMSG'] = "Suppress duplicated messages"; $content['LN_GEN_TREATFILTERSTRUE'] = "Treat filters of not found fields as true"; $content['LN_GEN_INLINESEARCHICONS'] = "Show Onlinesearch icons within fields"; $content['LN_GEN_OPTIONNAME'] = "Option name"; $content['LN_GEN_GLOBALVALUE'] = "Global value"; $content['LN_GEN_PERSONALVALUE'] = "Personal (User)value"; $content['LN_GEN_DISABLEUSEROPTIONS'] = "Click here to disable personal options"; $content['LN_GEN_ENABLEUSEROPTIONS'] = "Click here to enable personal options"; $content['LN_ADMIN_GLOBALONLY'] = "Global Options Only"; $content['LN_GEN_DEBUGTOSYSLOG'] = "Send Debug to local syslog server"; $content['LN_GEN_POPUPMENUTIMEOUT'] = "Popupmenu Timeout in milli seconds"; $content['LN_ADMIN_SCRIPTTIMEOUT'] = "PHP Script Timeout in seconds"; $content['LN_GEN_INJECTHTMLHEADER'] = "Inject this html code into the <head> area."; $content['LN_GEN_INJECTBODYHEADER'] = "Inject this html code at the beginning of the <body> area."; $content['LN_GEN_INJECTBODYFOOTER'] = "Inject this html code at the end <body> area."; $content['LN_ADMIN_PHPLOGCON_LOGOURL'] = "Optional LogAnalyzer Logo URL. Leave empty to use the default one."; $content['LN_ADMIN_ERROR_READONLY'] = "This is a READONLY User, you are not allowed to perform any change operations."; $content['LN_ADMIN_ERROR_NOTALLOWEDTOEDIT'] = "You are not allowed to edit this configuration item."; $content['LN_ADMIN_USEPROXYSERVER'] = "Leave empty if you do not want to use a proxy server! If set to valid proxy server (for example '127.0.0.1:8080'), LogAnalyzer will use this server for remote queries like the update check feature."; $content['LN_ADMIN_DEFAULTENCODING'] = "Default character encoding"; $content['LN_GEN_CONTEXTLINKS'] = "Enable Contextlinks (Question marks)"; // User Center $content['LN_USER_CENTER'] = "User Options"; $content['LN_USER_ID'] = "ID"; $content['LN_USER_NAME'] = "Username"; $content['LN_USER_ADD'] = "Add User"; $content['LN_USER_EDIT'] = "Edit User"; $content['LN_USER_DELETE'] = "Delete User"; $content['LN_USER_PASSWORD1'] = "Password"; $content['LN_USER_PASSWORD2'] = "Confirm Password"; $content['LN_USER_ERROR_IDNOTFOUND'] = "Error, User with ID '%1' , was not found"; $content['LN_USER_ERROR_DONOTDELURSLF'] = "Error, you can not DELETE YOURSELF!"; $content['LN_USER_ERROR_DELUSER'] = "Deleting of the user with id '%1' failed!"; $content['LN_USER_ERROR_INVALIDID'] = "Error, invalid ID, User not found"; $content['LN_USER_ERROR_HASBEENDEL'] = "The User '%1' has been successfully deleted!"; $content['LN_USER_ERROR_USEREMPTY'] = "Error, Username was empty"; $content['LN_USER_ERROR_USERNAMETAKEN'] = "Error, this Username is already taken!"; $content['LN_USER_ERROR_PASSSHORT'] = "Error, Password was to short, or did not match"; $content['LN_USER_ERROR_HASBEENADDED'] = "User '%1' has been successfully added"; $content['LN_USER_ERROR_HASBEENEDIT'] = "User '%1' has been successfully edited"; $content['LN_USER_ISADMIN'] = "Is Admin?"; $content['LN_USER_ADDEDIT'] = "Add/Edit User"; $content['LN_USER_WARNREMOVEADMIN'] = "You are about to revoke your own administrative priviledges. Are you sure to remove your admin status?"; $content['LN_USER_WARNDELETEUSER'] = "Are you sure that you want to delete the User '%1'? All his personal settings will be deleted as well."; $content['LN_USER_ERROR_INVALIDSESSIONS'] = "Invalid User Session."; $content['LN_USER_ERROR_SETTINGFLAG'] = "Error setting flag, invalid ID or User not found"; $content['LN_USER_WARNRADYONLYADMIN'] = "You are about to set your account to readonly! This will prevent you from changing any settings! Are you sure that you want to proceed?"; $content['LN_USER_ISREADONLY'] = "Readonly User?"; $content['LN_USER_'] = ""; // Group center $content['LN_GROUP_CENTER'] = "Group Center"; $content['LN_GROUP_ID'] = "ID"; $content['LN_GROUP_NAME'] = "Groupname"; $content['LN_GROUP_DESCRIPTION'] = "Groupdescription"; $content['LN_GROUP_TYPE'] = "Grouptype"; $content['LN_GROUP_ADD'] = "Add Group"; $content['LN_GROUP_EDIT'] = "Edit Group"; $content['LN_GROUP_DELETE'] = "Delete Group"; $content['LN_GROUP_NOGROUPS'] = "No groups have been added yet"; $content['LN_GROUP_ADDEDIT'] = "Add/Edit Group"; $content['LN_GROUP_ERROR_GROUPEMPTY'] = "The groupname cannot be empty."; $content['LN_GROUP_ERROR_GROUPNAMETAKEN'] = "The groupname has already been taken."; $content['LN_GROUP_HASBEENADDED'] = "The group '%1' has been successfully added."; $content['LN_GROUP_ERROR_IDNOTFOUND'] = "The group with ID '%1' could not be found."; $content['LN_GROUP_ERROR_HASBEENEDIT'] = "The group '%1' has been successfully edited."; $content['LN_GROUP_ERROR_INVALIDGROUP'] = "Error, invalid ID, Group not found"; $content['LN_GROUP_WARNDELETEGROUP'] = "Are you sure that you want to delete the Group '%1'? All Groupsettings will be deleted as well."; $content['LN_GROUP_ERROR_DELGROUP'] = "Deleting of the group with id '%1' failed!"; $content['LN_GROUP_ERROR_HASBEENDEL'] = "The Group '%1' has been successfully deleted!"; $content['LN_GROUP_MEMBERS'] = "Groupmembers: "; $content['LN_GROUP_ADDUSER'] = "Add User to Group"; $content['LN_GROUP_ERROR_USERIDMISSING'] = "The userid is missing."; $content['LN_GROUP_USERHASBEENADDEDGROUP'] = "The User '%1' has been successfully added to group '%2'"; $content['LN_GROUP_ERRORNOMOREUSERS'] = "There are no more available users who can be added to the group '%1'"; $content['LN_GROUP_USER_ADD'] = "Add User to the group"; $content['LN_GROUP_USERDELETE'] = "Remove a User from the group"; $content['LN_GROUP_ERRORNOUSERSINGROUP'] = "There are no users to remove in this the group '%1'"; $content['LN_GROUP_ERROR_REMUSERFROMGROUP'] = "The user '%1' could not be removed from the group '%2'"; $content['LN_GROUP_USERHASBEENREMOVED'] = "The user '%1' has been successfully removed from the group '%2'"; $content['LN_GROUP_'] = ""; // Custom Searches center $content['LN_SEARCH_CENTER'] = "Custom Searches"; $content['LN_SEARCH_ADD'] = "Add new Custom Search"; $content['LN_SEARCH_ID'] = "ID"; $content['LN_SEARCH_NAME'] = "Search Name"; $content['LN_SEARCH_QUERY'] = "Search Query"; $content['LN_SEARCH_TYPE'] = "Assigned to"; $content['LN_SEARCH_EDIT'] = "Edit Custom Search"; $content['LN_SEARCH_DELETE'] = "Delete Custom Search"; $content['LN_SEARCH_ADDEDIT'] = "Add / Edit a Custom Search"; $content['LN_SEARCH_SELGROUPENABLE'] = ">> Select Group to enable <<"; $content['LN_SEARCH_ERROR_DISPLAYNAMEEMPTY'] = "The DisplayName cannot be empty."; $content['LN_SEARCH_ERROR_SEARCHQUERYEMPTY'] = "The SearchQuery cannot be empty."; $content['LN_SEARCH_HASBEENADDED'] = "The Custom Search '%1' has been successfully added."; $content['LN_SEARCH_ERROR_IDNOTFOUND'] = "Could not find a search with ID '%1'."; $content['LN_SEARCH_ERROR_INVALIDID'] = "Invalid search ID."; $content['LN_SEARCH_HASBEENEDIT'] = "The Custom Search '%1' has been successfully edited."; $content['LN_SEARCH_WARNDELETESEARCH'] = "Are you sure that you want to delete the Custom Search '%1'? This cannot be undone!"; $content['LN_SEARCH_ERROR_DELSEARCH'] = "Deleting of the Custom Search with id '%1' failed!"; $content['LN_SEARCH_ERROR_HASBEENDEL'] = "The Custom Search '%1' has been successfully deleted!"; $content['LN_SEARCH_'] = ""; // Custom Views center $content['LN_VIEWS_CENTER'] = "Views Options"; $content['LN_VIEWS_ID'] = "ID"; $content['LN_VIEWS_NAME'] = "View Name"; $content['LN_VIEWS_COLUMNS'] = "View Columns"; $content['LN_VIEWS_TYPE'] = "Assigned to"; $content['LN_VIEWS_ADD'] = "Add new View"; $content['LN_VIEWS_EDIT'] = "Edit View"; $content['LN_VIEWS_ERROR_IDNOTFOUND'] = "A View with ID '%1' could not be found."; $content['LN_VIEWS_ERROR_INVALIDID'] = "The View with ID '%1' is not a valid View."; $content['LN_VIEWS_WARNDELETEVIEW'] = "Are you sure that you want to delete the View '%1'? This cannot be undone!"; $content['LN_VIEWS_ERROR_DELSEARCH'] = "Deleting of the View with id '%1' failed!"; $content['LN_VIEWS_ERROR_HASBEENDEL'] = "The View '%1' has been successfully deleted!"; $content['LN_VIEWS_ADDEDIT'] = "Add / Edit a View"; $content['LN_VIEWS_COLUMNLIST'] = "Configured Columns"; $content['LN_VIEWS_ADDCOLUMN'] = "Add Column into list"; $content['LN_VIEWS_ERROR_DISPLAYNAMEEMPTY'] = "The DisplayName cannot be empty."; $content['LN_VIEWS_COLUMN'] = "Column"; $content['LN_VIEWS_COLUMN_REMOVE'] = "Remove Column"; $content['LN_VIEWS_HASBEENADDED'] = "The Custom View '%1' has been successfully added."; $content['LN_VIEWS_ERROR_NOCOLUMNS'] = "You need to add at least one column in order to add a new Custom View."; $content['LN_VIEWS_HASBEENEDIT'] = "The Custom View '%1' has been successfully edited."; $content['LN_VIEWS_'] = ""; // Custom DBMappings center $content['LN_DBMP_CENTER'] = "Database Field Mappings Options"; $content['LN_DBMP_ID'] = "ID"; $content['LN_DBMP_NAME'] = "Database Mappingname"; $content['LN_DBMP_DBMAPPINGS'] = "Database Mappings"; $content['LN_DBMP_ADD'] = "Add new Database Mapping"; $content['LN_DBMP_EDIT'] = "Edit Database Mapping"; $content['LN_DBMP_ERROR_IDNOTFOUND'] = "A Database Mapping with ID '%1' could not be found."; $content['LN_DBMP_ERROR_INVALIDID'] = "The Database Mapping with ID '%1' is not a valid Database Mapping."; $content['LN_DBMP_WARNDELETEMAPPING'] = "Are you sure that you want to delete the Database Mapping '%1'? This cannot be undone!"; $content['LN_DBMP_ERROR_DELSEARCH'] = "Deleting of the Database Mapping with id '%1' failed!"; $content['LN_DBMP_ERROR_HASBEENDEL'] = "The Database Mapping '%1' has been successfully deleted!"; $content['LN_DBMP_ADDEDIT'] = "Add / Edit Database Mapping"; $content['LN_DBMP_DBMAPPINGSLIST'] = "Configured Mappings"; $content['LN_DBMP_ADDMAPPING'] = "Add Field Mapping into list"; $content['LN_DBMP_ERROR_DISPLAYNAMEEMPTY'] = "The DisplayName cannot be empty."; $content['LN_DBMP_MAPPING'] = "Mapping"; $content['LN_DBMP_MAPPING_REMOVE'] = "Remove Mapping"; $content['LN_DBMP_MAPPING_EDIT'] = "Edit Mapping"; $content['LN_DBMP_HASBEENADDED'] = "The Custom Database Mapping '%1' has been successfully added."; $content['LN_DBMP_ERROR_NOCOLUMNS'] = "You need to add at least one column in order to add a new Custom Database Mapping."; $content['LN_DBMP_HASBEENEDIT'] = "The Custom Database Mapping '%1' has been successfully edited."; $content['LN_DBMP_ERROR_MISSINGFIELDNAME'] = "Missing mapping for the '%1' field."; $content['LN_SOURCES_FILTERSTRING'] = "Custom Searchfilter"; $content['LN_SOURCES_FILTERSTRING_HELP'] = "Use the same syntax as in the search field. For example if you want to show only messages from 'server1', use this searchfilter: source:=server1"; // Custom Sources center $content['LN_SOURCES_CENTER'] = "Sources Options"; $content['LN_SOURCES_EDIT'] = "Edit Source"; $content['LN_SOURCES_DELETE'] = "Delete Source"; $content['LN_SOURCES_ID'] = "ID"; $content['LN_SOURCES_NAME'] = "Source Name"; $content['LN_SOURCES_TYPE'] = "Source Type"; $content['LN_SOURCES_ASSIGNTO'] = "Assigned To"; $content['LN_SOURCES_DISK'] = "Diskfile"; $content['LN_SOURCES_DB'] = "MySQL Database"; $content['LN_SOURCES_PDO'] = "PDO Datasource"; $content['LN_SOURCES_MONGODB'] = "MongoDB Datasource"; $content['LN_SOURCES_ADD'] = "Add new Source"; $content['LN_SOURCES_ADDEDIT'] = "Add / Edit a Source"; $content['LN_SOURCES_TYPE'] = "Source Type"; $content['LN_SOURCES_DISKTYPEOPTIONS'] = "Diskfile related Options"; $content['LN_SOURCES_ERROR_MISSINGPARAM'] = "The paramater '%1' is missing."; $content['LN_SOURCES_ERROR_NOTAVALIDFILE'] = "Failed to open the syslog file '%1'! Check if the file exists and LogAnalyzer has sufficient rights to it"; $content['LN_SOURCES_ERROR_UNKNOWNSOURCE'] = "Unknown Source '%1' detected"; $content['LN_SOURCE_HASBEENADDED'] = "The new Source '%1' has been successfully added."; $content['LN_SOURCES_EDIT'] = "Edit Source"; $content['LN_SOURCES_ERROR_INVALIDORNOTFOUNDID'] = "The Source-ID is invalid or could not be found."; $content['LN_SOURCES_ERROR_IDNOTFOUND'] = "The Source-ID could not be found in the database."; $content['LN_SOURCES_HASBEENEDIT'] = "The Source '%1' has been successfully edited."; $content['LN_SOURCES_WARNDELETESEARCH'] = "Are you sure that you want to delete the Source '%1'? This cannot be undone!"; $content['LN_SOURCES_ERROR_DELSOURCE'] = "Deleting of the Source with id '%1' failed!"; $content['LN_SOURCES_ERROR_HASBEENDEL'] = "The Source '%1' has been successfully deleted!"; $content['LN_SOURCES_DESCRIPTION'] = "Source Description (Optional)"; $content['LN_SOURCES_ERROR_INVALIDVALUE'] = "Invalid value for the paramater '%1'."; $content['LN_SOURCES_STATSNAME'] = "Name"; $content['LN_SOURCES_STATSVALUE'] = "Value"; $content['LN_SOURCES_DETAILS'] = "Details for this logstream source"; $content['LN_SOURCES_STATSDETAILS'] = "Statistic details for this logstream source"; $content['LN_SOURCES_ERROR_NOSTATSDATA'] = "Could not find or obtain any stats related information for this logstream source."; $content['LN_SOURCES_ERROR_NOCLEARSUPPORT'] = "This logstream source does not support deleting data."; $content['LN_SOURCES_ROWCOUNT'] = "Total Rowcount"; $content['LN_SOURCES_CLEARDATA'] = "The following database maintenance Options are available"; $content['LN_SOURCES_CLEAROPTIONS'] = "Select how you want to clear data."; $content['LN_SOURCES_CLEARALL'] = "Clear (Delete) all data."; $content['LN_SOURCES_CLEAR_HELPTEXT'] = "Attention! Be carefull with deleting data, any action performed here can not be undone!"; $content['LN_SOURCES_CLEARSINCE'] = "Clear all data older than ... "; $content['LN_SOURCES_CLEARDATE'] = "Clear all data which is older than ... "; $content['LN_SOURCES_CLEARDATA_SEND'] = "Clear selected data range"; $content['LN_SOURCES_ERROR_INVALIDCLEANUP'] = "Invalid Data Cleanup type"; $content['LN_SOURCES_WARNDELETEDATA'] = "Are you sure that you want to clear logdata in the '%1' source? This cannot be undone!"; $content['LN_SOURCES_ERROR_DELDATA'] = "Could not delete data in the '%1' source"; $content['LN_SOURCES_HASBEENDELDATA'] = "Successfully deleted data from the '%1' source, '%2' rows were affected. "; // Database Upgrade $content['LN_DBUPGRADE_TITLE'] = "LogAnalyzer Database Update"; $content['LN_DBUPGRADE_DBFILENOTFOUND'] = "The database upgrade file '%1' could not be found in the include folder! Please check if all files were successfully uploaded."; $content['LN_DBUPGRADE_DBDEFFILESHORT'] = "The database upgrade files where empty or did not contain any SQL Command! Please check if all files were successfully uploaded."; $content['LN_DBUPGRADE_WELCOME'] = "Welcome to the database upgrade"; $content['LN_DBUPGRADE_BEFORESTART'] = "Before you start upgrading your database, you should create a FULL BACKUP OF YOUR DATABASE. Anything else will be done automatically by the upgrade Script."; $content['LN_DBUPGRADE_CURRENTINSTALLED'] = "Current Installed Database Version"; $content['LN_DBUPGRADE_TOBEINSTALLED'] = "Do be Installed Database Version"; $content['LN_DBUPGRADE_HASBEENDONE'] = "Database Update has been performed, see the results below"; $content['LN_DBUPGRADE_SUCCESSEXEC'] = "Successfully executed statements"; $content['LN_DBUPGRADE_FAILEDEXEC'] = "Failed statements"; $content['LN_DBUPGRADE_ONESTATEMENTFAILED'] = "At least one statement failed, you may need to correct and fix this issue manually. See error details below"; $content['LN_DBUPGRADE_ERRMSG'] = "Error Message"; $content['LN_DBUPGRADE_ULTRASTATSDBVERSION'] = "LogAnalyzer Database Version"; // Charts Options $content['LN_CHARTS_CENTER'] = "Charts Options"; $content['LN_CHARTS_EDIT'] = "Edit Chart"; $content['LN_CHARTS_DELETE'] = "Delete Chart"; $content['LN_CHARTS_ADD'] = "Add new Chart"; $content['LN_CHARTS_ADDEDIT'] = "Add / Edit a Chart"; $content['LN_CHARTS_NAME'] = "Chart Name"; $content['LN_CHARTS_ENABLED'] = "Chart enabled"; $content['LN_CHARTS_ENABLEDONLY'] = "Enabled"; $content['LN_CHARTS_ERROR_INVALIDORNOTFOUNDID'] = "The Chart-ID is invalid or could not be found."; $content['LN_CHARTS_WARNDELETESEARCH'] = "Are you sure that you want to delete the Chart '%1'? This cannot be undone!"; $content['LN_CHARTS_ERROR_DELCHART'] = "Deleting of the Chart with id '%1' failed!"; $content['LN_CHARTS_ERROR_HASBEENDEL'] = "The Chart '%1' has been successfully deleted!"; $content['LN_CHARTS_ERROR_MISSINGPARAM'] = "The paramater '%1' is missing."; $content['LN_CHARTS_HASBEENADDED'] = "The new Chart '%1' has been successfully added."; $content['LN_CHARTS_ERROR_IDNOTFOUND'] = "The Chart-ID could not be found in the database."; $content['LN_CHARTS_HASBEENEDIT'] = "The Chart '%1' has been successfully edited."; $content['LN_CHARTS_ID'] = "ID"; $content['LN_CHARTS_ASSIGNTO'] = "Assigned To"; $content['LN_CHARTS_PREVIEW'] = "Preview Chart in a new Window"; $content['LN_CHARTS_FILTERSTRING'] = "Custom Filter"; $content['LN_CHARTS_FILTERSTRING_HELP'] = "Use the same syntax as in the search field. For example if you want to generate a chart for 'server1', use this filter: source:=server1"; $content['LN_CHARTS_ERROR_CHARTIDNOTFOUND'] = "Error, ChartID with ID '%1' , was not found"; $content['LN_CHARTS_ERROR_SETTINGFLAG'] = "Error setting flag, invalid ChartID or operation."; // Fields Options $content['LN_FIELDS_CENTER'] = "Fields Options"; $content['LN_FIELDS_EDIT'] = "Edit Field"; $content['LN_FIELDS_DELETE'] = "Delete Field"; $content['LN_FIELDS_ADD'] = "Add new Field"; $content['LN_FIELDS_ID'] = "FieldID"; $content['LN_FIELDS_NAME'] = "Display Name"; $content['LN_FIELDS_DEFINE'] = "Internal FieldID"; $content['LN_FIELDS_DELETE_FROMDB'] = "Delete Field from DB"; $content['LN_FIELDS_ADDEDIT'] = "Add / Edit a Field"; $content['LN_FIELDS_TYPE'] = "Field Type"; $content['LN_FIELDS_ALIGN'] = "Listview Alignment"; $content['LN_FIELDS_SEARCHONLINE'] = "Enable online search"; $content['LN_FIELDS_DEFAULTWIDTH'] = "Row width in Listview"; $content['LN_FIELDS_ERROR_IDNOTFOUND'] = "The Field-ID could not be found in the database, or in the default constants."; $content['LN_FIELDS_ERROR_INVALIDID'] = "The Field with ID '%1' is not a valid Field."; $content['LN_FIELDS_SEARCHFIELD'] = "Name of Searchfilter"; $content['LN_FIELDS_WARNDELETESEARCH'] = "Are you sure that you want to delete the Field '%1'? This cannot be undone!"; $content['LN_FIELDS_ERROR_DELSEARCH'] = "The Field-ID could not be found in the database."; $content['LN_FIELDS_ERROR_HASBEENDEL'] = "The Field '%1' has been successfully deleted!"; $content['LN_FIELDS_ERROR_FIELDCAPTIONEMPTY'] = "The field caption was empty. "; $content['LN_FIELDS_ERROR_FIELDIDEMPTY'] = "The field id was empty. "; $content['LN_FIELDS_ERROR_SEARCHFIELDEMPTY'] = "The searchfilter was empty. "; $content['LN_FIELDS_ERROR_FIELDDEFINEEMPTY'] = "The internal FieldID was empty. "; $content['LN_FIELDS_HASBEENEDIT'] = "The configuration for the field '%1' has been successfully edited."; $content['LN_FIELDS_HASBEENADDED'] = "The configuration for the field '%1' has been successfully added."; $content['LN_FIELDS_'] = ""; $content['LN_ALIGN_CENTER'] = "center"; $content['LN_ALIGN_LEFT'] = "left"; $content['LN_ALIGN_RIGHT'] = "right"; $content['LN_FILTER_TYPE_STRING'] = "String"; $content['LN_FILTER_TYPE_NUMBER'] = "Number"; $content['LN_FILTER_TYPE_DATE'] = "Date"; // Parser Options $content['LN_PARSERS_EDIT'] = "Edit Message Parser"; $content['LN_PARSERS_DELETE'] = "Delete Message Parser"; $content['LN_PARSERS_ID'] = "Message Parser ID"; $content['LN_PARSERS_NAME'] = "Message Parser Name"; $content['LN_PARSERS_DESCRIPTION'] = "Message Parser Description"; $content['LN_PARSERS_ERROR_NOPARSERS'] = "There were no valid message parsers found in your installation. "; $content['LN_PARSERS_HELP'] = "Help"; $content['LN_PARSERS_HELP_CLICK'] = "Click here for a detailed description"; $content['LN_PARSERS_INFO'] = "Show more Information for this message parser."; $content['LN_PARSERS_INIT'] = "Initialize settings for this message parser."; $content['LN_PARSERS_REMOVE'] = "Remove settings for this message parser."; $content['LN_PARSERS_ERROR_IDNOTFOUND'] = "There was no message parser with ID '%1' found."; $content['LN_PARSERS_ERROR_INVALIDID'] = "Invalid message parser id."; $content['LN_PARSERS_DETAILS'] = "Details for this Parser"; $content['LN_PARSERS_CUSTOMFIELDS'] = "The following Custom fields are needed by this Message Parser."; $content['LN_PARSERS_WARNREMOVE'] = "You are about to remove the custom fields needed by the '%1' Message Parser. However you can add these fields again if you change your mind."; $content['LN_PARSERS_ERROR_HASBEENREMOVED'] = "All settings ('%2' custom fields) for the Message Parser '%1' have been removed. "; $content['LN_PARSERS_ERROR_HASBEENADDED'] = "All required settings ('%2' custom fields) for the Message Parser '%1' have been added. "; $content['LN_PARSERS_ERROR_NOFIELDS'] = "The Message Parser '%1' does not have any custom fields to add."; $content['LN_PARSERSMENU_LIST'] = "List installed Message Parsers"; $content['LN_PARSERS_ONLINELIST'] = "All Available Parsers"; $content['LN_PARSERS_'] = ""; // Command Line stuff $content['LN_CMD_NOOP'] = "Operation parameter is missing"; $content['LN_CMD_NOLOGSTREAM'] = "The logstream source parameter is missing"; $content['LN_CMD_LOGSTREAMNOTFOUND'] = "Logstream Source with ID '%1' could not be found in the Database!"; $content['LN_CMD_COULDNOTGETROWCOUNT'] = "Could not obtain rowcount from logstream source '%1'"; $content['LN_CMD_SUBPARAM1MISSING'] = "Subparameter 1 is missing, it should be set to 'all', 'since' or 'date'. For more details see the documentation."; $content['LN_CMD_WRONGSUBOPORMISSING'] = "Either the sub-operation is wrong, or another parameter is missing"; $content['LN_CMD_FAILEDTOCLEANDATA'] = "Failed to cleandata for the logstream '%1'."; $content['LN_CMD_CLEANINGDATAFOR'] = "Cleaning data for logstream source '%1'."; $content['LN_CMD_ROWSFOUND'] = "Successfully connected and found '%1' rows in the logstream source."; $content['LN_CMD_DELETINGOLDERTHEN'] = "Performing deletion of data entries older then '%1'."; $content['LN_CMD_DELETEDROWS'] = "Successfully Deleted '%1' rows in the logstream source.'"; $content['LN_CMD_'] = ""; // Report Options $content['LN_REPORTS_EDIT'] = "Edit Report"; $content['LN_REPORTS_DELETE'] = "Remove Report"; $content['LN_REPORTS_REQUIREDFIELDS'] = "Required Fields"; $content['LN_REPORTS_ERROR_NOREPORTS'] = "There were no valid reports found in your installation."; $content['LN_REPORTS_INIT'] = "Initialize settings"; $content['LN_REPORTS_REMOVE'] = "Remove settings"; $content['LN_REPORTS_ERROR_IDNOTFOUND'] = "There was no report with ID '%1' found."; $content['LN_REPORTS_ERROR_INVALIDID'] = "Invalid report id."; $content['LN_REPORTS_DETAILS'] = "Details for this report"; $content['LN_REPORTS_WARNREMOVE'] = "You are about to remove the custom settings needed by the '%1' report. However you can add these settings again if you change your mind."; $content['LN_REPORTS_ERROR_HASBEENREMOVED'] = "All settings for the report '%1' have been removed."; $content['LN_REPORTS_ERROR_HASBEENADDED'] = "All required settings for the report '%1' have been added."; $content['LN_REPORTS_ERROR_NOFIELDS'] = "The report '%1' does not have any custom settings which can be added."; $content['LN_REPORTS_ERROR_REPORTDOESNTNEEDTOBEREMOVED'] = "The report '%1' does not need to be removed or initialized."; $content['LN_REPORTS_REMOVESAVEDREPORT'] = "Remove Savedreport"; $content['LN_REPORTS_CUSTOMTITLE'] = "Report Title"; $content['LN_REPORTS_CUSTOMCOMMENT'] = "Comment / Description"; $content['LN_REPORTS_FILTERSTRING'] = "Filterstring"; $content['LN_REPORTS_OUTPUTFORMAT'] = "Outputformat"; $content['LN_REPORTS_OUTPUTTARGET'] = "Outputtarget"; $content['LN_REPORTS_HASBEENADDED'] = "The Savedreport '%1' has been successfully added."; $content['LN_REPORTS_HASBEENEDIT'] = "The Savedreport '%1' has been successfully edited."; $content['LN_REPORTS_SOURCEID'] = "Logstream source"; $content['LN_REPORTS_ERROR_SAVEDREPORTIDNOTFOUND'] = "There was no savedreport with ID '%1' found."; $content['LN_REPORTS_ERROR_INVALIDSAVEDREPORTID'] = "Invalid savedreport id."; $content['LN_REPORTS_RUNNOW'] = "Run saved report now!"; $content['LN_REPORTS_WARNDELETESAVEDREPORT'] = "Are you sure that you want to delete the savedreport '%1'?"; $content['LN_REPORTS_ERROR_DELSAVEDREPORT'] = "Deleting of the savedreport with id '%1' failed!"; $content['LN_REPORTS_ERROR_HASBEENDEL'] = "The savedreport '%1' has been successfully deleted!"; $content['LN_REPORTS_ERROR_ERRORCHECKINGSOURCE'] = "Error while checking Savedreport Source: %1"; $content['LN_REPORTS_FILTERLIST'] = "Filterlist"; $content['LN_REPORTS_FILTER'] = "Filter"; $content['LN_REPORTS_ADDFILTER'] = "Add filter"; $content['LN_REPORTS_FILTER_EDIT'] = "Edit filter"; $content['LN_REPORTS_FILTER_MOVEUP'] = "Move filter up"; $content['LN_REPORTS_FILTER_MOVEDOWN'] = "Move filter down"; $content['LN_REPORTS_FILTER_REMOVE'] = "Remove filter"; $content['LN_REPORTS_FILTEREDITOR'] = "Filtereditor"; $content['LN_REPORTS_FILTERSTRING_ONLYEDITIF'] = "Only edit raw filterstring if you know what you are doing! Note if you change the filterstring, any changes made in the Filtereditor will be lost!"; $content['LN_REPORTS_ADVANCEDFILTERS'] = "Advanced filters"; $content['LN_REPORTS_ADVANCEDFILTERLIST'] = "List of advanced report filters"; $content['LN_REPORTS_OUTPUTTARGET_DETAILS'] = "Outputtarget Options"; $content['LN_REPORTS_OUTPUTTARGET_FILE'] = "Output Path and Filename"; $content['LN_REPORTS_CRONCMD'] = "Local Report command"; $content['LN_REPORTS_LINKS'] = "Related Links"; $content['LN_REPORTS_INSTALLED'] = "Installed"; $content['LN_REPORTS_NOTINSTALLED'] = "Not installed"; $content['LN_REPORTS_DOWNLOAD'] = "Download Link"; $content['LN_REPORTS_SAMPLELINK'] = "Report Sample"; $content['LN_REPORTS_DETAILSFOR'] = "Details for '%1' report"; $content['LN_REPORTS_PERFORMANCE_WARNING'] = "Logstream Performance Warning"; $content['LN_REPORTS_OPTIMIZE_LOGSTREAMSOURCE'] = "Yes, optimize logstream source!"; $content['LN_REPORTS_OPTIMIZE_INDEXES'] = "The datasource '%1' is not optimized for this report. There is at least one INDEX missing. Creating INDEXES will speedup the report generation.

Do you want LogAnalyzer to create the necessary INDEXES now? This may take more then a few minutes, so please be patient!"; $content['LN_REPORTS_ERROR_FAILED_CREATE_INDEXES'] = "Failed to create INDEXES for datasource '%1' with error code '%2'"; $content['LN_REPORTS_INDEX_CREATED'] = "Logstream INDEXES created"; $content['LN_REPORTS_INDEX_CREATED_SUCCESS'] = "Successfully created all INDEXES for datasource '%1'."; $content['LN_REPORTS_OPTIMIZE_TRIGGER'] = "The datasource '%1' does not have a TRIGGER installed to automatically generate the message checksum on INSERT. Creating the TRIGGER will speedup the report generation.

Do you want LogAnalyzer to create the TRIGGER now? "; $content['LN_REPORTS_TRIGGER_CREATED'] = "Logstream TRIGGER created"; $content['LN_REPORTS_TRIGGER_CREATED_SUCCESS'] = "Successfully created TRIGGER for datasource '%1'."; $content['LN_REPORTS_ERROR_FAILED_CREATE_TRIGGER'] = "Failed to create TRIGGER for datasource '%1' with error code '%2'"; $content['LN_REPORTS_CHANGE_CHECKSUM'] = "The Checksum field for datasource '%1' is not set to UNSIGNED INT. To get the report work properly, changing the CHECKSUM field to UNSIGNED INT is necessary!

Do you want LogAnalyzer to change the CHECKSUM field now? This may take more then a few minutes, so please be patient!"; $content['LN_REPORTS_ERROR_FAILED_CHANGE_CHECKSUM'] = "Failed to change the CHECKSUM field for datasource '%1' with error code '%2'"; $content['LN_REPORTS_CHECKSUM_CHANGED'] = "Checksum field changed"; $content['LN_REPORTS_CHECKSUM_CHANGED_SUCCESS'] = "Successfully changed the Checksum field for datasource '%1'."; $content['LN_REPORTS_LOGSTREAM_WARNING'] = "Logstream Warning"; $content['LN_REPORTS_ADD_MISSINGFIELDS'] = "The datasource '%1' does not contain all necessary datafields There is at least one FIELD missing.

Do you want LogAnalyzer to create the missing datafields now?"; $content['LN_REPORTS_ERROR_FAILED_ADDING_FIELDS'] = "Failed adding missing datafields in datasource '%1' with error code '%2'"; $content['LN_REPORTS_FIELDS_CREATED'] = "Added missing datafields"; $content['LN_REPORTS_FIELDS_CREATED_SUCCESS'] = "Successfully added missing datafields for datasource '%1'."; $content['LN_REPORTS_RECHECKLOGSTREAMSOURCE'] = "Do you want to check the current logstream source again?"; $content['LN_REPORTS_ADDSAVEDREPORT'] = "Add Savedreport and save changes"; $content['LN_REPORTS_EDITSAVEDREPORT'] = "Save changes"; $content['LN_REPORTS_ADDSAVEDREPORTANDRETURN'] = "Add Savedreport and return to reportlist"; $content['LN_REPORTS_EDITSAVEDREPORTANDRETURN'] = "Save changes and return to reportlist"; $content['LN_REPORTS_SOURCE_WARNING'] = "Logstream Source Warning"; $content['LN_REPORTS_ERROR_FAILED_SOURCE_CHECK'] = "Failed to check the datasource '%1' with error '%2'"; $content['LN_REPORTS_'] = ""; ?>loganalyzer-3.6.5/src/lang/en/main.php0000644000175000017500000006765112225176641017122 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ global $content; // Global Stuff $content['LN_MAINTITLE'] = "Main LogAnalyzer"; $content['LN_MAIN_SELECTSTYLE'] = "Select a Style"; $content['LN_GEN_LANGUAGE'] = "Select Language"; $content['LN_GEN_SELECTSOURCE'] = "Select Source"; $content['LN_GEN_MOREPAGES'] = "More than one Page available"; $content['LN_GEN_FIRSTPAGE'] = "First Page"; $content['LN_GEN_LASTPAGE'] = "Last Page"; $content['LN_GEN_NEXTPAGE'] = "Next Page"; $content['LN_GEN_PREVIOUSPAGE'] = "Previous Page"; $content['LN_GEN_RECORDCOUNT'] = "Total records found"; $content['LN_GEN_PAGERSIZE'] = "Records per page"; $content['LN_GEN_PAGE'] = "Page"; $content['LN_GEN_PREDEFINEDSEARCHES'] = "Predefined Searches"; $content['LN_GEN_SOURCE_DISK'] = "Diskfile"; $content['LN_GEN_SOURCE_DB'] = "MYSQL Native"; $content['LN_GEN_SOURCE_PDO'] = "Database (PDO)"; $content['LN_GEN_SOURCE_MONGODB'] = "MongoDB Native"; $content['LN_GEN_RECORDSPERPAGE'] = "records per page"; $content['LN_GEN_PRECONFIGURED'] = "Preconfigured"; $content['LN_GEN_AVAILABLESEARCHES'] = "Available searches"; $content['LN_GEN_DB_MYSQL'] = "Mysql Server"; $content['LN_GEN_DB_MSSQL'] = "Microsoft SQL Server"; $content['LN_GEN_DB_ODBC'] = "ODBC Database Source"; $content['LN_GEN_DB_PGSQL'] = "PostgreSQL"; $content['LN_GEN_DB_OCI'] = "Oracle Call Interface"; $content['LN_GEN_DB_DB2'] = " IBM DB2"; $content['LN_GEN_DB_FIREBIRD'] = "Firebird/Interbase 6"; $content['LN_GEN_DB_INFORMIX'] = "IBM Informix Dynamic Server"; $content['LN_GEN_DB_SQLITE'] = "SQLite 2"; $content['LN_GEN_SELECTVIEW'] = "Select View"; $content['LN_GEN_CRITERROR_UNKNOWNTYPE'] = "The source type '%1' is not supported by LogAnalyzer yet. This is a critical error, please fix your configuration."; $content['LN_GEN_ERRORRETURNPREV'] = "Click here to return to the previous page."; $content['LN_GEN_ERRORDETAILS'] = "Error Details:"; $content['LN_SOURCES_ERROR_WITHINSOURCE'] = "The source '%1' checking returned with an error:
%2"; $content['LN_SOURCES_ERROR_EXTRAMSG'] = "Extra Error Details:
%1"; $content['LN_ERROR_NORECORDS'] = "No syslog records found"; $content['LN_ERROR_FILE_NOT_FOUND'] = "Syslog file could not be found"; $content['LN_ERROR_FILE_NOT_READABLE'] = "Syslog file is not readable, read access may be denied"; $content['LN_ERROR_UNKNOWN'] = "Unknown or unhandled error occured (Error Code '%1')"; $content['LN_ERROR_FILE_EOF'] = "End of File reached"; $content['LN_ERROR_FILE_BOF'] = "Begin of File reeached"; $content['LN_ERROR_FILE_CANT_CLOSE'] = "Can't close File"; $content['LN_ERROR_UNDEFINED'] = "Undefined Error"; $content['LN_ERROR_EOS'] = "End of stream reached"; $content['LN_ERROR_FILTER_NOT_MATCH'] = "Filter does not match any results"; $content['LN_ERROR_DB_CONNECTFAILED'] = "Connection to the database server failed"; $content['LN_ERROR_DB_CANNOTSELECTDB'] = "Could not find the configured database"; $content['LN_ERROR_DB_QUERYFAILED'] = "Dataquery failed to execute"; $content['LN_ERROR_DB_NOPROPERTIES'] = "No database properties found"; $content['LN_ERROR_DB_INVALIDDBMAPPING'] = "Invalid datafield mappings"; $content['LN_ERROR_DB_INVALIDDBDRIVER'] = "Invalid database driver selected"; $content['LN_ERROR_DB_TABLENOTFOUND'] = "Could not find the configured table, maybe misspelled or the tablenames are case sensitive"; $content['LN_ERROR_DB_DBFIELDNOTFOUND'] = "Database Field mapping for at least one field could not be found."; $content['LN_GEN_SELECTEXPORT'] = "> Select Exportformat <"; $content['LN_GEN_EXPORT_CVS'] = "CSV (Comma separated)"; $content['LN_GEN_EXPORT_XML'] = "XML"; $content['LN_GEN_EXPORT_PDF'] = "PDF"; $content['LN_GEN_ERROR_EXPORING'] = "Error exporting data"; $content['LN_GEN_ERROR_INVALIDEXPORTTYPE'] = "Invalid Export format selected, or other parameters were wrong."; $content['LN_GEN_ERROR_SOURCENOTFOUND'] = "The Source with ID '%1' could not be found."; $content['LN_GEN_MOREINFORMATION'] = "More Information"; $content['LN_FOOTER_PAGERENDERED'] = "Page rendered in"; $content['LN_FOOTER_DBQUERIES'] = "DB queries"; $content['LN_FOOTER_GZIPENABLED'] = "GZIP enabled"; $content['LN_FOOTER_SCRIPTTIMEOUT'] = "Script Timeout"; $content['LN_FOOTER_SECONDS'] = "seconds"; $content['LN_WARNING_LOGSTREAMTITLE'] = "Logstream Warning"; $content['LN_WARNING_LOGSTREAMDISK_TIMEOUT'] = "While reading the logstream, the php script timeout forced me to abort at this point.

If you want to avoid this, please increase the LogAnalyzer script timeout in your config.php. If the user system is installed, you can do that in Admin center."; $content['LN_ERROR_FILE_NOMORETIME'] = "No more time for processing left"; $content['LN_WARNING_DBUPGRADE'] = "Database Upgrade required"; $content['LN_WARNING_DBUPGRADE_TEXT'] = "The current installed database version is '%1'.
An update to version '%2' is available."; $content['LN_ERROR_REDIRECTABORTED'] = 'Automatic redirect to the page was aborted, as an internal error occured. Please see the error details above and contact our support forums if you need assistance.'; $content['LN_DEBUGLEVEL'] = "Debug Level"; $content['LN_DEBUGMESSAGE'] = "Debug Message"; $content['LN_GEN_REPORT_OUTPUT_HTML'] = "HTML Format"; $content['LN_GEN_REPORT_OUTPUT_PDF'] = "PDF Format"; $content['LN_GEN_REPORT_TARGET_STDOUT'] = "Direct Output"; $content['LN_GEN_REPORT_TARGET_FILE'] = "Save into File"; $content['LN_GEN_REPORT_TARGET_EMAIL'] = "Send as Email"; $content['LN_GEN_UNKNOWN'] = "Unknown"; $content['LN_GEN_AUTH_INTERNAL'] = "Internal authentication"; $content['LN_GEN_AUTH_LDAP'] = "LDAP Authentication"; // Topmenu Entries $content['LN_MENU_SEARCH'] = "Search"; $content['LN_MENU_SHOWEVENTS'] = "Show Events"; $content['LN_MENU_HELP'] = "Help"; $content['LN_MENU_DOC'] = "Documentation"; $content['LN_MENU_FORUM'] = "Support Forum"; $content['LN_MENU_WIKI'] = "LogAnalyzer Wiki"; $content['LN_MENU_PROSERVICES'] = "Professional Services"; $content['LN_MENU_SEARCHINKB'] = "Search in Knowledge Base"; $content['LN_MENU_LOGIN'] = "Login"; $content['LN_MENU_ADMINCENTER'] = "Admin Center"; $content['LN_MENU_LOGOFF'] = "Logoff"; $content['LN_MENU_LOGGEDINAS'] = "Logged in as"; $content['LN_MENU_MAXVIEW'] = "Maximize View"; $content['LN_MENU_NORMALVIEW'] = "Normalize View"; $content['LN_MENU_STATISTICS'] = "Statistics"; $content['LN_MENU_CLICKTOEXPANDMENU'] = "Click the icon to show the menu"; $content['LN_MENU_REPORTS'] = "Reports"; // Main Index Site $content['LN_ERROR_INSTALLFILEREMINDER'] = "Warning! You still have NOT removed the 'install.php' from your LogAnalyzer main directory!"; $content['LN_TOP_NUM'] = "No."; $content['LN_TOP_UID'] = "uID"; $content['LN_GRID_POPUPDETAILS'] = "Details for Syslogmessage with ID '%1'"; $content['LN_SEARCH_USETHISBLA'] = "Use the form below and your advanced search will appear here"; $content['LN_SEARCH_FILTER'] = "Search (filter):"; $content['LN_SEARCH_ADVANCED'] = "Advanced Search"; $content['LN_SEARCH'] = "Search"; $content['LN_SEARCH_RESET'] = "Reset search"; $content['LN_SEARCH_PERFORMADVANCED'] = "Perform Advanced Search"; $content['LN_VIEW_MESSAGECENTERED'] = "Back to unfiltered view with this message at top"; $content['LN_VIEW_RELATEDMSG'] = "View related syslog messages"; $content['LN_VIEW_FILTERFOR'] = "Filter message for "; $content['LN_VIEW_SEARCHFOR'] = "Search online for "; $content['LN_VIEW_SEARCHFORGOOGLE'] = "Search Google for "; $content['LN_GEN_MESSAGEDETAILS'] = "Message Details"; $content['LN_VIEW_ADDTOFILTER'] = "Add '%1' to filterset"; $content['LN_VIEW_EXCLUDEFILTER'] = "Exclude '%1' from filterset"; $content['LN_VIEW_FILTERFORONLY'] = "Filter for '%1' only"; $content['LN_VIEW_SHOWALLBUT'] = "Show all except '%1'"; $content['LN_VIEW_VISITLINK'] = "Open Link '%1' in new window"; $content['LN_HIGHLIGHT'] = "Highlight >>"; $content['LN_HIGHLIGHT_OFF'] = "Highlight <<"; $content['LN_HIGHLIGHT_WORDS'] = "Highlight words comma separated"; $content['LN_AUTORELOAD'] = "Set auto reload"; $content['LN_AUTORELOAD_DISABLED'] = "Auto reload disabled"; $content['LN_AUTORELOAD_PRECONFIGURED'] = "Preconfigured auto reload "; $content['LN_AUTORELOAD_SECONDS'] = "seconds"; $content['LN_AUTORELOAD_MINUTES'] = "minutes"; // Filter Options $content['LN_FILTER_DATE'] = "Datetime Range"; $content['LN_FILTER_DATEMODE'] = "Select mode"; $content['LN_DATEMODE_ALL'] = "All time"; $content['LN_DATEMODE_RANGE'] = "Time range"; $content['LN_DATEMODE_LASTX'] = "Time x since today"; $content['LN_FILTER_DATEFROM'] = "Date range from"; $content['LN_FILTER_DATETO'] = "Date range to"; $content['LN_FILTER_TIMEFROM'] = "Time range from"; $content['LN_FILTER_TIMETO'] = "Time range to"; $content['LN_FILTER_DATELASTX'] = "Time since"; $content['LN_FILTER_ADD2SEARCH'] = "Add to search"; $content['LN_DATE_LASTX_HOUR'] = "Last hour"; $content['LN_DATE_LASTX_12HOURS'] = "Last 12 hours"; $content['LN_DATE_LASTX_24HOURS'] = "Last 24 hours"; $content['LN_DATE_LASTX_7DAYS'] = "Last 7 days"; $content['LN_DATE_LASTX_31DAYS'] = "Last 31 days"; $content['LN_FILTER_FACILITY'] = "Syslog Facility"; $content['LN_FILTER_SEVERITY'] = "Syslog Severity"; $content['LN_FILTER_OTHERS'] = "Other Filters"; $content['LN_FILTER_MESSAGE'] = "Syslog Message"; $content['LN_FILTER_SYSLOGTAG'] = "Syslogtag"; $content['LN_FILTER_SOURCE'] = "Source (Hostname)"; $content['LN_FILTER_MESSAGETYPE'] = "Message Type"; // Install Page $content['LN_CFG_DBSERVER'] = "Database Host"; $content['LN_CFG_DBPORT'] = "Database Port"; $content['LN_CFG_DBNAME'] = "Database Name"; $content['LN_CFG_DBPREF'] = "Table prefix"; $content['LN_CFG_DBUSER'] = "Database User"; $content['LN_CFG_DBPASSWORD'] = "Database Password"; $content['LN_CFG_PARAMMISSING'] = "The following parameter were missing: "; $content['LN_CFG_SOURCETYPE'] = "Source Type"; $content['LN_CFG_DISKTYPEOPTIONS'] = "Disk Type Options"; $content['LN_CFG_LOGLINETYPE'] = "Logline type"; $content['LN_CFG_SYSLOGFILE'] = "Syslog file"; $content['LN_CFG_DATABASETYPEOPTIONS'] = "Database Type Options"; $content['LN_CFG_DBTABLETYPE'] = "Table type"; $content['LN_CFG_DBSTORAGEENGINE'] = "Database Storage Engine"; $content['LN_CFG_DBTABLENAME'] = "Database Tablename"; $content['LN_CFG_NAMEOFTHESOURCE'] = "Name of the Source"; $content['LN_CFG_FIRSTSYSLOGSOURCE'] = "First Syslog Source"; $content['LN_CFG_DBROWCOUNTING'] = "Enable Row Counting"; $content['LN_CFG_VIEW'] = "Select View"; $content['LN_CFG_DBUSERLOGINREQUIRED'] = "Require user to be logged in"; $content['LN_CFG_MSGPARSERS'] = "Message Parsers (comma seperated)"; $content['LN_CFG_NORMALIZEMSG'] = "Normalize Message within Parsers"; $content['LN_CFG_SKIPUNPARSEABLE'] = "Skip unparseable messages (Only works if msgparsers are configured!)"; $content['LN_CFG_DBRECORDSPERQUERY'] = "Recordcount for database queries"; $content['LN_CFG_LDAPServer'] = "LDAP Server Hostname/IP"; $content['LN_CFG_LDAPPort'] = "LDAP Port, default 389 (636 for SSL)"; $content['LN_CFG_LDAPBaseDN'] = "Base DN for LDAP Search"; $content['LN_CFG_LDAPSearchFilter'] = "Basic Search filter"; $content['LN_CFG_LDAPUidAttribute'] = "LDAP Username attribute"; $content['LN_CFG_LDAPBindDN'] = "Privilegied user used to LDAP queries"; $content['LN_CFG_LDAPBindPassword'] = "Password of the privilegied user"; $content['LN_CFG_LDAPDefaultAdminUser'] = "Default administrative LDAP Username"; $content['LN_CFG_AUTHTYPE'] = "Authentication method"; $content['LN_GEN_AUTH_LDAP_OPTIONS'] = "LDAP Authentication Options"; // Details page $content['LN_DETAILS_FORSYSLOGMSG'] = "Details for the syslog messages with id"; $content['LN_DETAILS_DETAILSFORMSG'] = "Details for message id"; $content['LN_DETAIL_BACKTOLIST'] = "Back to Listview"; $content['LN_DETAIL_DYNAMIC_FIELDS'] = "Dynamic fields"; // Login Site $content['LN_LOGIN_DESCRIPTION'] = "Use this form to login into LogAnalyzer. "; $content['LN_LOGIN_TITLE'] = "Login"; $content['LN_LOGIN_USERNAME'] = "Username"; $content['LN_LOGIN_PASSWORD'] = "Password"; $content['LN_LOGIN_SAVEASCOOKIE'] = "Stay logged on"; $content['LN_LOGIN_ERRWRONGPASSWORD'] = "Wrong username or password!"; $content['LN_LOGIN_USERPASSMISSING'] = "Username or password not given"; $content['LN_LOGIN_LDAP_USERNOTFOUND'] = "User '%1' could not be found"; $content['LN_LOGIN_LDAP_USERCOULDNOTLOGIN'] = "Could not login user '%1', LDAP error: %2"; $content['LN_LOGIN_LDAP_PASSWORDFAIL'] = "User '%1' could not login with the given password"; $content['LN_LOGIN_LDAP_SERVERFAILED'] = "Failed to connect to LDAP Server '%1'"; $content['LN_LOGIN_LDAP_USERBINDFAILED'] = "Could not bind with the Search user DN '%1'"; // Install Site $content['LN_INSTALL_TITLETOP'] = "Installing LogAnalyzer Version %1 - Step %2"; $content['LN_INSTALL_TITLE'] = "Installer Step %1"; $content['LN_INSTALL_ERRORINSTALLED'] = 'LogAnalyzer is already configured!

If you want to reconfigure LogAnalyzer, either delete the current config.php or replace it with an empty file.

Click here to return to pgpLogCon start page.'; $content['LN_INSTALL_FILEORDIRNOTWRITEABLE'] = "At least one file or directory (or more) is not writeable, please check the file permissions (chmod 666)!"; $content['LN_INSTALL_SAMPLECONFIGMISSING'] = "The sample configuration file '%1' is missing. You have not fully uploaded LogAnalyzer."; $content['LN_INSTALL_ERRORCONNECTFAILED'] = "Database connect to '%1' failed! Please check Servername, Port, User and Password!"; $content['LN_INSTALL_ERRORACCESSDENIED'] = "Cannot use the database '%1'! If the database does not exists, create it or check user access permissions!"; $content['LN_INSTALL_ERRORINVALIDDBFILE'] = "Error, invalid Database definition file (to short!), the file name is '%1'! Please check if the file was correctly uploaded."; $content['LN_INSTALL_ERRORINSQLCOMMANDS'] = "Error, invalid Database definition file (no sql statements found!), the file name is '%1'!
Please check if the file was not correctly uploaded, or contact the LogAnalyzer forums for assistance!"; $content['LN_INSTALL_MISSINGUSERNAME'] = "Username needs to be specified"; $content['LN_INSTALL_PASSWORDNOTMATCH'] = "Either the password does not match or is to short!"; $content['LN_INSTALL_FAILEDTOOPENSYSLOGFILE'] = "Failed to open the syslog file '%1'! Check if the file exists and LogAnalyzer has sufficient rights to it
"; $content['LN_INSTALL_FAILEDCREATECFGFILE'] = "Coult not create the configuration file in '%1'! Please verify the file permissions!"; $content['LN_INSTALL_FAILEDREADINGFILE'] = "Error reading the file '%1'! Please verify if the file exists!"; $content['LN_INSTALL_ERRORREADINGDBFILE'] = "Error reading the default database definition file in '%1'! Please verify if the file exists!"; $content['LN_INSTALL_STEP1'] = "Step 1 - Prerequisites"; $content['LN_INSTALL_STEP2'] = "Step 2 - Verify File Permissions"; $content['LN_INSTALL_STEP3'] = "Step 3 - Basic Configuration"; $content['LN_INSTALL_STEP4'] = "Step 4 - Create Tables"; $content['LN_INSTALL_STEP5'] = "Step 5 - Check SQL Results"; $content['LN_INSTALL_STEP6'] = "Step 6 - Creating the Main Useraccount"; $content['LN_INSTALL_STEP7'] = "Step 7 - Create the first source for syslog messages"; $content['LN_INSTALL_STEP8'] = "Step 8 - Done"; $content['LN_INSTALL_STEP1_TEXT'] = 'Before you start installing LogAnalyzer, the Installer setup has to check a few things first.
You may have to correct some file permissions first.

Click on to start the Test!'; $content['LN_INSTALL_STEP2_TEXT'] = "The following file permissions have been checked. Verify the results below!
You may use the configure.sh script from the contrib folder to set the permissions for you."; $content['LN_INSTALL_STEP3_TEXT'] = "In this step, you configure the basic configurations for LogAnalyzer."; $content['LN_INSTALL_STEP4_TEXT'] = 'If you reached this step, the database connection has been successfully verified!

The next step will be to create the necessary database tables used by the LogAnalyzer User System. This might take a while!
WARNING, if you have an existing LogAnalyzer installation in this database with the same tableprefix, all your data will be OVERWRITTEN! Make sure you are using a fresh database, or you want to overwrite your old LogAnalyzer database.

Click on to start the creation of the tables'; $content['LN_INSTALL_STEP5_TEXT'] = "Tables have been created. Check the List below for possible Error's"; $content['LN_INSTALL_STEP6_TEXT'] = "You are now about to create the initial LogAnalyzer User Account.
This will be the first administrative user, which will be needed to login into LogAnalyzer and access the Admin Center!"; $content['LN_INSTALL_STEP8_TEXT'] = 'Congratulations! You have successfully installed LogAnalyzer :)!

Click here to go to your installation.'; $content['LN_INSTALL_PROGRESS'] = "Install Progress: "; $content['LN_INSTALL_FRONTEND'] = "Frontend Options"; $content['LN_INSTALL_NUMOFSYSLOGS'] = "Number of syslog messages per page"; $content['LN_INSTALL_MSGCHARLIMIT'] = "Message character limit for the main view"; $content['LN_INSTALL_STRCHARLIMIT'] = "Character display limit for all string type fields"; $content['LN_INSTALL_SHOWDETAILPOP'] = "Show message details popup"; $content['LN_INSTALL_AUTORESOLVIP'] = "Automatically resolved IP Addresses (inline)"; $content['LN_INSTALL_USERDBOPTIONS'] = "User Database Options"; $content['LN_INSTALL_ENABLEUSERDB'] = "Enable User Database"; $content['LN_INSTALL_SUCCESSSTATEMENTS'] = "Successfully executed statements:"; $content['LN_INSTALL_FAILEDSTATEMENTS'] = "Failed statements:"; $content['LN_INSTALL_STEP5_TEXT_NEXT'] = "You can now proceed to the next step adding the first LogAnalyzer Admin User!"; $content['LN_INSTALL_STEP5_TEXT_FAILED'] = "At least one statement failed,see error reasons below"; $content['LN_INSTALL_ERRORMSG'] = "Error Message"; $content['LN_INSTALL_SQLSTATEMENT'] = "SQL Statement"; $content['LN_INSTALL_CREATEUSER'] = "Create User Account"; $content['LN_INSTALL_PASSWORD'] = "Password"; $content['LN_INSTALL_PASSWORDREPEAT'] = "Repeat Password"; $content['LN_INSTALL_SUCCESSCREATED'] = "Successfully created User"; $content['LN_INSTALL_RECHECK'] = "ReCheck"; $content['LN_INSTALL_FINISH'] = "Finish!"; $content['LN_INSTALL_LDAPCONNECTFAILED'] = "Failed to connect to your LDAP Server '%1'."; $content['LN_INSTALL_WARNINGMYSQL'] = "A MYSQL database Server is required for this feature. Other database engines are not supported for the User Database System. However for logsources, there is support for other database systems."; $content['LN_INSTALL_'] = ""; // Converter Site $content['LN_CONVERT_TITLE'] = "Configuration Converter Step %1"; $content['LN_CONVERT_NOTALLOWED'] = "Login"; $content['LN_CONVERT_ERRORINSTALLED'] = 'LogAnalyzer is not allowed to convert your settings into the user database.

If you want to convert your convert your settings, add the variable following into your config.php:
$CFG[\'UserDBConvertAllowed\'] = true;

Click here to return to pgpLogCon start page.'; $content['LN_CONVERT_STEP1'] = "Step 1 - Informations"; $content['LN_CONVERT_STEP2'] = "Step 2 - Create Tables"; $content['LN_CONVERT_STEP3'] = "Step 3 - Check SQL Results"; $content['LN_CONVERT_STEP4'] = "Step 4 - Creating the Main Useraccount"; $content['LN_CONVERT_STEP5'] = "Step 5 - Import Settings into UserDB"; $content['LN_CONVERT_TITLETOP'] = "Converting LogAnalyzer configuration settings - Step "; $content['LN_CONVERT_STEP1_TEXT'] = 'This script allows you to import your existing configuration from the config.php file. This includes frontend settings, data sources, custom views and custom searches. Do only perform this conversion if you did install LogAnalyzer without the UserDB System, and decided to enable it now.

ANY EXISTING INSTANCE OF A USERDB WILL BE OVERWRITTEN!

to start the first conversion step!'; $content['LN_CONVERT_STEP2_TEXT'] = 'The database connection has been successfully verified!

The next step will be to create the necessary database tables for the LogAnalyzer User System. This might take a while!
WARNING, if you have an existing LogAnalyzer installation in this database with the same tableprefix, all your data will be OVERWRITTEN!
Make sure you are using a fresh database, or you want to overwrite your old LogAnalyzer database.

Click on to start the creation of the tables'; $content['LN_CONVERT_STEP5_TEXT'] = ' to start the last step of the conversion. In this step, your existing configuration from the config.php will be imported into the database.'; $content['LN_CONVERT_STEP6'] = "Step 8 - Done"; $content['LN_CONVERT_STEP6_TEXT'] = 'Congratulations! You have successfully converted your existing LogAnalyzer installation :)!

Important! Don\'t forget to REMOVE THE VARIABLES $CFG[\'UserDBConvertAllowed\'] = true; from your config.php file!

You can click here to get to your LogAnalyzerinstallation.'; $content['LN_CONVERT_PROCESS'] = "Conversion Progress:"; $content['LN_CONVERT_ERROR_SOURCEIMPORT'] = "Critical Error while importing the sources into the database, the SourceType '%1' is not supported by this LogAnalyzer Version."; // Stats Site $content['LN_STATS_CHARTTITLE'] = "Top %1 '%2' sorted by messagecount"; $content['LN_STATS_COUNTBY'] = "Messagecount by '%1'"; $content['LN_STATS_OTHERS'] = "All Others"; $content['LN_STATS_TOPRECORDS'] = "Maxrecords: %1"; $content['LN_STATS_GENERATEDAT'] = "Generated at: %1"; // $content['LN_STATS_COUNTBYSYSLOGTAG'] = "Messagecount by SyslogTag"; $content['LN_STATS_GRAPH'] = "Graph"; $content['LN_GEN_ERROR_INVALIDFIELD'] = "Invalid fieldname"; $content['LN_GEN_ERROR_MISSINGCHARTFIELD'] = "Missing fieldname"; $content['LN_GEN_ERROR_INVALIDTYPE'] = "Invalid or unknown chart type."; $content['LN_ERROR_CHARTS_NOTCONFIGURED'] = "There are no charts configured at all."; $content['LN_CHART_TYPE'] = "Chart type"; $content['LN_CHART_WIDTH'] = "Chart width"; $content['LN_CHART_FIELD'] = "Chart field"; $content['LN_CHART_MAXRECORDS'] = "Top records count"; $content['LN_CHART_SHOWPERCENT'] = "Show percentage data"; $content['LN_CHART_TYPE_CAKE'] = "Cake (Pie)"; $content['LN_CHART_TYPE_BARS_VERTICAL'] = "Bars vertical"; $content['LN_CHART_TYPE_BARS_HORIZONTAL'] = "Bars horizontal"; $content['LN_STATS_WARNINGDISPLAY'] = "Generating graphics on large data sources currently is very time consuming. This will be addressed in later versions. If processing takes too long, please simply cancel the request."; // asktheoracle site $content['LN_ORACLE_TITLE'] = "Asking the oracle for '%1'"; $content['LN_ORACLE_HELP_FOR'] = "These are the links the oracle got for you"; $content['LN_ORACLE_HELP_TEXT'] = "

You asked the oracle to find more information about the '%1' value '%2'.

This pages enables you do a a search over multiple log sources. %3
The overall idea is to make it easy to find information about a specific subject in all places where it may exist.

A useful use case may be a hack attempt you see in a web log. Click on the attacker's IP, which brings up this search page here. Now you can both lookup information about the IP range as well as check your other logs (e.g. firewall or mail) if they contain information about the attacker. We hope that this facilitates your analysis process.

"; $content['LN_ORACLE_HELP_TEXT_EXTERNAL'] = "It also enables you to perform canned searches over some external databases"; $content['LN_ORACLE_HELP_DETAIL'] = "Link matrix for the '%1' value '%2'"; $content['LN_ORACLE_SEARCH'] = "Search"; // in '%1' Field"; $content['LN_ORACLE_SOURCENAME'] = "Source name"; $content['LN_ORACLE_FIELD'] = "Field"; $content['LN_ORACLE_ONLINESEARCH'] = "Online Search"; $content['LN_ORACLE_WHOIS'] = "WHOIS Lookup for '%1' value '%2'"; // Report Strings $content['LN_GEN_ERROR_INVALIDOP'] = "Invalid or missing operation type"; $content['LN_GEN_ERROR_INVALIDREPORTID'] = "Invalid or missing report id"; $content['LN_GEN_ERROR_MISSINGSAVEDREPORTID'] = "Invalid or missing savedreport id"; $content['LN_GEN_ERROR_REPORTGENFAILED'] = "Failed generating report '%1' with the following error reason: %2"; $content['LN_GEN_ERROR_WHILEREPORTGEN'] = "Error occured while generating report"; $content['LN_GEN_ERROR_REPORT_NODATA'] = "No data found for report generation"; $content['LN_GEN_ALL_OTHER_EVENTS'] = "All other events"; $content['LN_REPORT_FOOTER_ENDERED'] = "Report rendered in"; $content['LN_REPORT_FILTERS'] = "List of used filters"; $content['LN_REPORT_FILTERTYPE_DATE'] = "Date"; $content['LN_REPORT_FILTERTYPE_NUMBER'] = "Number"; $content['LN_REPORT_FILTERTYPE_STRING'] = "String"; $content['LN_GEN_SUCCESS_WHILEREPORTGEN'] = "Report was successfully generated"; $content['LN_GEN_ERROR_REPORTFAILEDTOGENERATE'] = "Failed to generate report, error details: %1"; $content['LN_GEN_SUCCESS_REPORTWASGENERATED_DETAILS'] = "Successfully generated report: %1"; $content['LN_ERROR_PATH_NOT_ALLOWED'] = "The file is not located in the allowed directories list (By default /var/log is allowed only)."; $content['LN_ERROR_PATH_NOT_ALLOWED_EXTRA'] = "The file '%1' is not located in one of these directories: '%2'"; $content['LN_CMD_RUNREPORT'] = "Generating saved report '%1'"; $content['LN_CMD_REPORTIDNOTFOUND'] = "Invalid Report ID '%1'"; $content['LN_CMD_SAVEDREPORTIDNOTFOUND'] = "Invalid SavedReport ID '%1'"; $content['LN_CMD_NOREPORTID'] = "Missing Report ID"; $content['LN_CMD_NOSAVEDREPORTID'] = "Missing SavedReport ID"; $content['LN_CMD_NOCMDPROMPT'] = "Error, this script can only be run from the command prompt."; $content['LN_REPORT_GENERATEDTIME'] = "Report generated at: "; $content['LN_REPORT_ACTIONS'] = "Run Report Actions"; $content['LN_REPORTS_CAT'] = "Report Category"; $content['LN_REPORTS_ID'] = "Report ID"; $content['LN_REPORTS_NAME'] = "Report Name"; $content['LN_REPORTS_DESCRIPTION'] = "Report Description"; $content['LN_REPORTS_HELP'] = "Help"; $content['LN_REPORTS_HELP_CLICK'] = "Click here for a detailed report description"; $content['LN_REPORTS_INFO'] = "Show more Information"; $content['LN_REPORTS_SAVEDREPORTS'] = "Saved reports"; $content['LN_REPORTS_ADMIN'] = "Administrate Reports"; $content['LN_REPORTMENU_LIST'] = "List installed Reports"; $content['LN_REPORTMENU_ONLINELIST'] = "All Available Reports"; $content['LN_REPORTS_INFORMATION'] = "This page shows a list of installed and available reports including saved report configurations.
To run a report, click on the buttons right to the Saved Reports.
Attention! Generating reports can be very time consuming depending on the size of your database. "; $content['LN_REPORTS_CHECKLOGSTREAMSOURCE'] = "Verify Logstream optimization"; ?>loganalyzer-3.6.5/src/templates/0000755000175000017500000000000012225176641016121 5ustar danieldanielloganalyzer-3.6.5/src/templates/include_menu.html0000644000175000017500000001056712225176641021467 0ustar danieldaniel
{LN_MENU_SEARCH} {LN_MENU_SHOWEVENTS} {LN_MENU_STATISTICS} {LN_MENU_REPORTS} {LN_MENU_SEARCHINKB} {LN_MENU_LOGIN}   {LN_MENU_ADMINCENTER} {LN_MENU_LOGOFF} {LN_MENU_LOGGEDINAS} "{SESSION_USERNAME}"   {MAXLANGTEXT}
loganalyzer-3.6.5/src/templates/statistics.html0000644000175000017500000000466512225176641021214 0ustar danieldaniel

{LN_GEN_ERRORDETAILS}

{ERROR_MSG}

{LN_GEN_MOREINFORMATION}





{rowbegin}

{LN_MENU_STATISTICS}

{LN_STATS_WARNINGDISPLAY}

{DisplayName}
{LN_CHART_TYPE}  {CHART_TYPE_DISPLAYNAME}
{LN_CHART_FIELD}  {CHART_FIELD_DISPLAYNAME}
{LN_CHART_WIDTH}  {chart_width}
{LN_CHART_MAXRECORDS}  {maxrecords}
{LN_CHART_SHOWPERCENT}  {showpercent_display}


{rowend} loganalyzer-3.6.5/src/templates/include_footer.html0000644000175000017500000000427012225176641022013 0ustar danieldaniel
Made by Adiscon GmbH (2008-2012)  Adiscon LogAnalyzer Version {BUILDNUMBER}  Partners:  Rsyslog |  WinSyslog {LN_FOOTER_PAGERENDERED}: {PAGERENDERTIME} {LN_FOOTER_SECONDS}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}  | {LN_FOOTER_GZIPENABLED}: {GzipCompressionEnmabled}  | {LN_FOOTER_SCRIPTTIMEOUT}: {MaxExecutionTime} {LN_FOOTER_SECONDS}
{LN_DEBUGLEVEL} {LN_DEBUGMESSAGE}
{DBGLEVELTXT}
{DBGMSG}
{EXTRA_FOOTER} loganalyzer-3.6.5/src/templates/search.html0000644000175000017500000002115612225176641020261 0ustar danieldaniel
{LN_SEARCH_USETHISBLA}

{LN_FILTER_DATE}
{LN_FILTER_DATEMODE}
{LN_FILTER_DATEFROM} - -
{LN_FILTER_DATETO} - -
{LN_FILTER_TIMEFROM} - -
{LN_FILTER_TIMETO} - -
{LN_FILTER_DATELASTX}
 
{LN_FILTER_OTHERS}
{LN_FILTER_FACILITY} {LN_FILTER_SEVERITY}
{LN_FILTER_MESSAGETYPE}
{LN_FILTER_MESSAGE}
 
{LN_FILTER_SYSLOGTAG}
{LN_FILTER_SOURCE}


loganalyzer-3.6.5/src/templates/include_header.html0000644000175000017500000002063112225176641021744 0ustar danieldaniel {TITLE} {EXTRA_METATAGS} {EXTRA_STYLESHEET} {EXTRA_JAVASCRIPT} {EXTRA_HTMLHEAD} {EXTRA_HEADER}
Satisfied with Adiscon LogAnalyzer?
Donate and help keep the project alive!
 {LN_GEN_LANGUAGE} 
 
 {LN_MAIN_SELECTSTYLE} 
 {LN_GEN_SELECTSOURCE} 
 {LN_GEN_SELECTVIEW} 
 
 

{LN_WARNING_DBUPGRADE}

{WARNING_DBUPGRADE_TEXT}


loganalyzer-3.6.5/src/templates/include_index_globals.html0000644000175000017500000000205412225176641023325 0ustar danieldaniel
{LN_GLOBAL_STATS}

{LN_GLOBAL_LASTUPDATE}
{global_lastupdate_TimeFormat}
{DisplayName}
{VALUE_INT}

loganalyzer-3.6.5/src/templates/asktheoracle.html0000644000175000017500000000613512225176641021461 0ustar danieldaniel

{LN_GEN_ERRORDETAILS}

{ERROR_MSG}

{LN_GEN_MOREINFORMATION}





{LN_ORACLE_HELP_FOR}
{LN_DETAIL_BACKTOLIST} {LN_DETAIL_BACKTOLIST}
{ORACLE_HELP_TEXT}



{LN_ORACLE_ONLINESEARCH}
  {ORACLE_WHOIS}


{ORACLE_HELP_DETAIL}
{LN_ORACLE_SOURCENAME} {LN_ORACLE_FIELD} '{LN_FIELDS_MESSAGE}' {LN_ORACLE_FIELD} '{LN_FIELDS_HOST}'  
{SourceName}   {LN_ORACLE_SEARCH}   {LN_ORACLE_SEARCH}  


loganalyzer-3.6.5/src/templates/install.html0000644000175000017500000005424312225176641020465 0ustar danieldaniel {TITLE}
 


{INSTALL_TITLETOP}


ERROR: {errormsg}


{LN_INSTALL_STEP1}

{LN_INSTALL_STEP1_TEXT}

 

 

{LN_INSTALL_STEP2}

{LN_INSTALL_STEP2_TEXT}

 

{FILE_TYPE} '{FILE_NAME}'   {ISSUCCESS}

 

 

{LN_INSTALL_STEP3}

{LN_INSTALL_STEP3_TEXT}

 

{LN_INSTALL_FRONTEND}
{LN_INSTALL_NUMOFSYSLOGS}
{LN_INSTALL_MSGCHARLIMIT}
{LN_INSTALL_STRCHARLIMIT}
{LN_INSTALL_SHOWDETAILPOP} Yes No
{LN_INSTALL_AUTORESOLVIP} Yes No
 
{LN_INSTALL_USERDBOPTIONS}
{LN_INSTALL_ENABLEUSERDB} Yes No
{LN_INSTALL_WARNINGMYSQL}
{LN_CFG_DBSERVER}
{LN_CFG_DBPORT}
{LN_CFG_DBNAME}
{LN_CFG_DBPREF}
{LN_CFG_DBUSER}
{LN_CFG_DBPASSWORD}
{LN_CFG_DBUSERLOGINREQUIRED} Yes No
{LN_CFG_AUTHTYPE}
{LN_GEN_AUTH_LDAP_OPTIONS}
{LN_CFG_LDAPServer}
{LN_CFG_LDAPPort}
{LN_CFG_LDAPBaseDN}
{LN_CFG_LDAPSearchFilter}
{LN_CFG_LDAPUidAttribute}
{LN_CFG_LDAPBindDN}
{LN_CFG_LDAPBindPassword}
{LN_CFG_LDAPDefaultAdminUser}

 

 

{LN_INSTALL_STEP4}

{LN_INSTALL_STEP4_TEXT}

 

 

{LN_INSTALL_STEP5}

{LN_INSTALL_STEP5_TEXT}

  • {LN_INSTALL_SUCCESSSTATEMENTS} {sql_sucess}
  • {LN_INSTALL_FAILEDSTATEMENTS} {sql_failed}
{LN_INSTALL_STEP5_TEXT_NEXT}

 

{LN_INSTALL_STEP5_TEXT_FAILED}
{LN_INSTALL_ERRORMSG} {LN_INSTALL_SQLSTATEMENT}
{myerrmsg} {mystatement}

 

 

{LN_INSTALL_STEP6}

{LN_INSTALL_STEP6_TEXT}

{LN_INSTALL_CREATEUSER}
{LN_LOGIN_USERNAME}
{LN_INSTALL_PASSWORD}
{LN_INSTALL_PASSWORDREPEAT}

 

 


{LN_INSTALL_SUCCESSCREATED} '{MAIN_Username}'.


{LN_INSTALL_STEP7}

 

{LN_CFG_FIRSTSYSLOGSOURCE}
{LN_CFG_NAMEOFTHESOURCE}
{LN_CFG_SOURCETYPE}
{LN_CFG_VIEW}
{LN_CFG_DISKTYPEOPTIONS}
{LN_CFG_LOGLINETYPE}
{LN_CFG_SYSLOGFILE}
{LN_CFG_DATABASETYPEOPTIONS}
{LN_CFG_DBSTORAGEENGINE}
{LN_CFG_DBTABLETYPE}
{LN_CFG_DBSERVER}
{LN_CFG_DBNAME}
{LN_CFG_DBTABLENAME}
{LN_CFG_DBUSER}
{LN_CFG_DBPASSWORD}
{LN_CFG_DBROWCOUNTING} Yes No

 

 

{LN_INSTALL_STEP8}

{LN_INSTALL_STEP8_TEXT}

 

 

{LN_INSTALL_PROGRESS}
{LN_INSTALL_RECHECK} {LN_INSTALL_FINISH}
loganalyzer-3.6.5/src/templates/convert.html0000644000175000017500000001623112225176641020472 0ustar danieldaniel {TITLE}
 


{LN_CONVERT_TITLETOP}


ERROR: {errormsg}


{LN_CONVERT_STEP1}

{LN_CONVERT_STEP1_TEXT}

 

 

{LN_CONVERT_STEP2}

{LN_CONVERT_STEP2_TEXT}

 

 

{LN_CONVERT_STEP3}

{LN_INSTALL_STEP5_TEXT}

  • {LN_INSTALL_SUCCESSSTATEMENTS} {sql_sucess}
  • {LN_INSTALL_FAILEDSTATEMENTS} {sql_failed}
{LN_INSTALL_STEP5_TEXT_NEXT}

 

{LN_INSTALL_STEP5_TEXT_FAILED}
{LN_INSTALL_ERRORMSG} {LN_INSTALL_SQLSTATEMENT}
{myerrmsg} {mystatement}

 

 

{LN_CONVERT_STEP4}

{LN_INSTALL_STEP6_TEXT}



{LN_INSTALL_CREATEUSER}
{LN_LOGIN_USERNAME}
{LN_INSTALL_PASSWORD}
{LN_INSTALL_PASSWORDREPEAT}

 

 


{LN_INSTALL_SUCCESSCREATED} '{MAIN_Username}'.


{LN_CONVERT_STEP5}

{LN_CONVERT_STEP5_TEXT}

 

 

{LN_CONVERT_STEP6}

{LN_CONVERT_STEP6_TEXT}

 

 

{LN_CONVERT_PROCESS}
{LN_INSTALL_RECHECK} {LN_INSTALL_FINISH}
loganalyzer-3.6.5/src/templates/export.html0000644000175000017500000000071412225176641020332 0ustar danieldaniel

{LN_GEN_ERROR_EXPORING} - {LN_GEN_ERRORDETAILS}

{error_details}



{LN_GEN_ERRORRETURNPREV}


loganalyzer-3.6.5/src/templates/reports.html0000644000175000017500000002402412225176641020507 0ustar danieldaniel

{LN_GEN_ERRORDETAILS}

{ERROR_MSG}

{LN_GEN_MOREINFORMATION}





{LN_MENU_REPORTS}

{LN_REPORTS_INFORMATION}

{LN_REPORTS_ADMIN} {LN_REPORTMENU_ONLINELIST} {REPORTS_DETAILSFOR}  


{rowbegin}
{LN_REPORTS_NAME} {DisplayName}
{LN_REPORTS_HELP}    {LN_REPORTS_HELP}    {LN_REPORTS_INFO}
{LN_REPORTS_DESCRIPTION} {Description}
{LN_REPORTS_SAVEDREPORTS}
{customTitle}  


{rowend}
{LN_REPORTS_INSTALLED} {LN_REPORTS_ID} {LN_REPORTS_NAME} {LN_REPORTS_DESCRIPTION} {LN_REPORTS_LINKS}
{reportid} {reportname} {reportname} {reportdescription}         
{LN_REPORTS_DETAILS}
{LN_REPORTS_CAT} {Category}
{LN_REPORTS_ID} {ReportID}
{LN_REPORTS_NAME} {DisplayName}
{LN_REPORTS_DESCRIPTION} {Description}
{LN_REPORTS_REQUIREDFIELDS}
{FieldCaption} ({FieldDefine})

{LN_REPORTS_HELP} {LN_REPORTS_HELP_CLICK}
{LN_REPORTS_INIT} {LN_REPORTS_REMOVE}
{LN_REPORTS_SAVEDREPORTS}
{customTitle}      


{LN_GEN_ERRORRETURNPREV}

loganalyzer-3.6.5/src/templates/index.html0000644000175000017500000004200212225176641020114 0ustar danieldaniel
 {LN_SEARCH_FILTER}

{LN_SEARCH_ADVANCED}
(sample: facility:local0 severity:warning)
{LN_HIGHLIGHT_WORDS}
{highlight_html}
Recent syslog messages
{LN_GEN_PAGE} {main_currentpagenumber} {LN_AUTORELOAD}:
{LN_GEN_RECORDCOUNT}: {main_recordcount} {LN_GEN_PAGERSIZE}:
Pager:   {mypagenumber} 
{SourceDescription}
Debug {FieldCaption}
{ZAEHLER}
{fieldvalue} {fieldvalue} {fieldvalue}
{fieldvalue}
{popupcaption}
{detailfieldtitle} {detailfieldvalue}
  Pager:   {mypagenumber} 


{LN_ERROR_NORECORDS} - {LN_GEN_ERRORDETAILS}

{detailederror}

{LN_GEN_MOREINFORMATION}







{LN_WARNING_LOGSTREAMTITLE}

{logstream_warning_details}

{LN_GEN_MOREINFORMATION}





loganalyzer-3.6.5/src/templates/login.html0000644000175000017500000000327612225176641020127 0ustar danieldaniel

{ERROR_MSG}



{LN_LOGIN_DESCRIPTION}

{LN_LOGIN_TITLE}
{LN_LOGIN_USERNAME}
{LN_LOGIN_PASSWORD}


loganalyzer-3.6.5/src/templates/reportgenerator.html0000644000175000017500000000232212225176641022230 0ustar danieldaniel {TITLE}

{LN_GEN_ERROR_WHILEREPORTGEN}

{LN_GEN_ERRORDETAILS}
{error_details}

{LN_GEN_SUCCESS_WHILEREPORTGEN}

{LN_GEN_MESSAGEDETAILS}
{error_details}

loganalyzer-3.6.5/src/templates/details.html0000644000175000017500000001163712225176641020444 0ustar danieldaniel
{LN_DETAILS_FORSYSLOGMSG} '{uid_current}'
{LN_DETAIL_BACKTOLIST} {LN_DETAIL_BACKTOLIST} {LN_GEN_PAGE} {main_currentpagenumber} {LN_GEN_RECORDCOUNT}: {main_recordcount} Pager:   {LN_GEN_FIRSTPAGE} {LN_GEN_PREVIOUSPAGE} {mypagenumber}  {LN_GEN_NEXTPAGE} {LN_GEN_LASTPAGE}
{FieldCaption} {fieldvalue}
{LN_DETAIL_DYNAMIC_FIELDS}
{dynfieldkey} {dynfieldvalue}


{LN_ERROR_NORECORDS} (code {error_code} ) - {LN_GEN_ERRORDETAILS}

{detailederror}

loganalyzer-3.6.5/src/templates/admin/0000755000175000017500000000000012225176641017211 5ustar danieldanielloganalyzer-3.6.5/src/templates/admin/admin_securecheck.html0000644000175000017500000000171312225176641023535 0ustar danieldaniel

{warningtext}




{nomsg}

loganalyzer-3.6.5/src/templates/admin/admin_fields.html0000644000175000017500000001233712225176641022523 0ustar danieldaniel

{LN_GEN_ERRORDETAILS}

{ERROR_MSG}



{LN_GEN_ERRORRETURNPREV}


{LN_FIELDS_CENTER}


{LN_FIELDS_NAME} {LN_FIELDS_ID} {LN_FIELDS_DEFINE} {LN_GEN_ACTIONS}
{FieldCaption} {FieldID} {FieldDefine}      
 {LN_FIELDS_ADD}
{LN_FIELDS_ADDEDIT}
{LN_FIELDS_ID}
{LN_FIELDS_DEFINE}
{LN_FIELDS_NAME}
{LN_FIELDS_SEARCHFIELD}
{LN_FIELDS_SEARCHONLINE}
{LN_FIELDS_TYPE}
{LN_FIELDS_ALIGN}
{LN_FIELDS_DEFAULTWIDTH}


loganalyzer-3.6.5/src/templates/admin/result.html0000644000175000017500000000104512225176641021415 0ustar danieldaniel

{LN_ADMIN_CENTER}


{SZMSG}

You will be redirected to the this page on {REDIRSECONDS} seconds.



loganalyzer-3.6.5/src/templates/admin/admin_charts.html0000644000175000017500000001570212225176641022540 0ustar danieldaniel

{LN_GEN_ERRORDETAILS}

{ERROR_MSG}



{LN_GEN_ERRORRETURNPREV}


{LN_CHARTS_CENTER}


{LN_CHARTS_ID} {LN_CHARTS_NAME} {LN_CHARTS_ENABLEDONLY} {LN_CHART_TYPE} {LN_CHARTS_ASSIGNTO} {LN_GEN_ACTIONS}
{ID} {DisplayName} {DisplayName} {ChartTypeText} {ChartAssignedToText}          
 {LN_CHARTS_ADD}
{LN_CHARTS_ADDEDIT}
{LN_CHARTS_NAME}
{LN_CHARTS_ENABLED}
{LN_CHART_TYPE}
{LN_CHART_FIELD}
{LN_CHART_WIDTH}
{LN_CHART_MAXRECORDS}
{LN_CHART_SHOWPERCENT}
{LN_CHARTS_FILTERSTRING} {LN_CHARTS_FILTERSTRING_HELP}
{LN_GEN_USERONLY}
{LN_GEN_GROUPONLY}



loganalyzer-3.6.5/src/templates/admin/admin_groups.html0000644000175000017500000001432412225176641022572 0ustar danieldaniel

{LN_GEN_ERRORDETAILS}

{ERROR_MSG}



{LN_GEN_ERRORRETURNPREV}


{LN_GROUP_CENTER}


{LN_GROUP_ID} {LN_GROUP_NAME} {LN_GROUP_DESCRIPTION} {LN_GEN_ACTIONS}
{LN_GROUP_NOGROUPS}
{ID} {groupname} {groupdescription}        
{LN_GROUP_MEMBERS} {username}{seperator}
 {LN_GROUP_ADD}
{LN_GROUP_ADDEDIT}
{LN_GROUP_NAME}
{LN_GROUP_DESCRIPTION}
{LN_GROUP_ADDUSER}: '{GROUPNAME}'
{LN_USER_NAME}
{LN_GROUP_USERDELETE}: '{GROUPNAME}'
{LN_USER_NAME}


loganalyzer-3.6.5/src/templates/admin/admin_menu.html0000644000175000017500000000734512225176641022224 0ustar danieldaniel
{LN_ADMINMENU_GENOPT} {LN_ADMINMENU_SOURCEOPT} {LN_ADMINMENU_FIELDOPT} {LN_ADMINMENU_VIEWSOPT} {LN_ADMINMENU_SEARCHOPT} {LN_ADMINMENU_CHARTOPT} {LN_ADMINMENU_MSGPARSERSOPT} {LN_ADMINMENU_REEPORTSOPT} {LN_ADMINMENU_DBMAPPINGOPT} {LN_ADMINMENU_USEROPT} {LN_ADMINMENU_GROUPOPT}    
loganalyzer-3.6.5/src/templates/admin/admin_reports.html0000644000175000017500000006205712225176641022757 0ustar danieldaniel

{LN_GEN_ERRORDETAILS}

{ERROR_MSG}



{LN_GEN_ERRORRETURNPREV}


{LN_ADMINMENU_REEPORTSOPT}{OPTIONAL_TITLE}


{LN_REPORTMENU_LIST} {LN_REPORTMENU_ONLINELIST} {REPORTS_DETAILSFOR}  
{LN_REPORTS_ID} {LN_REPORTS_NAME} {LN_REPORTS_DESCRIPTION} {LN_GEN_ACTIONS}
{ID} {DisplayName} {Description}  
{LN_REPORTS_SAVEDREPORTS}  {LN_REPORTS_ADDSAVEDREPORT}    {LN_REPORTS_HELP}    {LN_REPORTS_INFO}    {LN_REPORTS_INIT}    {LN_REPORTS_REMOVE}
{customTitle}      
{LN_REPORTS_INSTALLED} {LN_REPORTS_ID} {LN_REPORTS_NAME} {LN_REPORTS_DESCRIPTION} {LN_REPORTS_LINKS}
{reportid} {reportname} {reportname} {reportdescription}         
{LN_REPORTS_DETAILS}
{LN_REPORTS_CAT} {Category}
{LN_REPORTS_ID} {ReportID}
{LN_REPORTS_NAME} {DisplayName}
{LN_REPORTS_DESCRIPTION} {Description}
{LN_REPORTS_REQUIREDFIELDS}
{FieldCaption} ({FieldDefine})

{LN_REPORTS_HELP} {LN_REPORTS_HELP_CLICK}
{LN_REPORTS_INIT} {LN_REPORTS_REMOVE}
{LN_REPORTS_SAVEDREPORTS}
{customTitle}      


{LN_GEN_ERRORRETURNPREV}
{MSG_WARNING_TITLE}

{MSG_WARNING_DETAILS}

{LN_REPORTS_RECHECKLOGSTREAMSOURCE}



{LN_REPORTS_ADDSAVEDREPORT}: '{DisplayName}'
{LN_REPORTS_CUSTOMTITLE}
{LN_REPORTS_CUSTOMCOMMENT}
{LN_REPORTS_FILTERSTRING} {LN_REPORTS_FILTERSTRING_ONLYEDITIF}
{LN_REPORTS_FILTEREDITOR}
{LN_REPORTS_FILTERLIST}
{FilterFieldName} ({FilterFieldID})
- -
- -
{LN_REPORTS_ADVANCEDFILTERS}
{LN_REPORTS_ADVANCEDFILTERLIST}
{fieldcaption}
({fielddescription})
{fieldcaption}   ({fielddescription})
{LN_REPORTS_SOURCEID} {LN_REPORTS_CHECKLOGSTREAMSOURCE}
{LN_REPORTS_OUTPUTFORMAT}
{LN_REPORTS_OUTPUTTARGET}
{LN_REPORTS_OUTPUTTARGET_FILE}
{LN_REPORTS_CRONCMD}
{LN_GEN_ERRORRETURNPREV}



loganalyzer-3.6.5/src/templates/admin/admin_upgrade.html0000644000175000017500000000655612225176641022712 0ustar danieldaniel

{LN_GEN_ERRORDETAILS}

{ERROR_MSG}



{LN_GEN_ERRORRETURNPREV}


{LN_DBUPGRADE_TITLE}


{LN_DBUPGRADE_WELCOME}

{LN_DBUPGRADE_BEFORESTART}

{LN_DBUPGRADE_CURRENTINSTALLED}: {database_installedversion}
{LN_DBUPGRADE_TOBEINSTALLED}: {database_internalversion}



Click on Upgrade to start!

 



{LN_DBUPGRADE_HASBEENDONE}:

  • {LN_DBUPGRADE_SUCCESSEXEC}: {sql_sucess}
  • {LN_DBUPGRADE_FAILEDEXEC}: {sql_failed}
    {LN_DBUPGRADE_ONESTATEMENTFAILED}
    {LN_DBUPGRADE_ERRMSG} SQL Statement
    {myerrmsg} {mystatement}

     

    {LN_DBUPGRADE_CURRENTINSTALLED}: {database_installedversion}
    {LN_DBUPGRADE_TOBEINSTALLED}: {database_internalversion}


    Click on here to return to the Admin Center

     

  • Welcome to the Database Upgrade

    Your database is fully updated!

    {LN_DBUPGRADE_CURRENTINSTALLED}: {database_installedversion}
    {LN_DBUPGRADE_ULTRASTATSDBVERSION}: {database_internalversion}



    Click on here to return to the Admin Center

     



    loganalyzer-3.6.5/src/templates/admin/admin_sources.html0000644000175000017500000004233712225176641022743 0ustar danieldaniel

    {LN_GEN_ERRORDETAILS}

    {ERROR_MSG}



    {LN_GEN_ERRORRETURNPREV}


    {LN_SOURCES_CENTER}


    {LN_SOURCES_ID} {LN_SOURCES_NAME} {LN_SOURCES_TYPE} {LN_SOURCES_ASSIGNTO} {LN_GEN_ACTIONS}
    {ID} {Name} {Name} {SourcesTypeText} {SourcesAssignedToText}            
     {LN_SOURCES_ADD}
    {LN_SOURCES_DETAILS}
    {LN_SOURCES_ID} {SOURCEID}
    {LN_SOURCES_NAME} {DisplayName}
    {LN_SOURCES_TYPE} {SourceTypeName}
    {LN_SOURCES_ROWCOUNT} {ROWCOUNT}

    {LN_SOURCES_CLEARDATA}
    {LN_SOURCES_CLEAR_HELPTEXT}
    {LN_SOURCES_CLEAROPTIONS}
      {LN_SOURCES_CLEARALL}
      {LN_SOURCES_CLEARSINCE}
      {LN_SOURCES_CLEARDATE} - -



    {LN_GEN_ERRORRETURNPREV}
    {LN_SOURCES_DETAILS}
    {LN_SOURCES_ID} {SOURCEID}
    {LN_SOURCES_NAME} {DisplayName}
    {LN_SOURCES_TYPE} {SourceTypeName}
    {LN_SOURCES_DESCRIPTION} {Description}

    {LN_SOURCES_STATSDETAILS}
    {LN_SOURCES_STATSNAME} {LN_SOURCES_STATSVALUE}
    {StatsDisplayName}
    {StatsValue}


    {LN_GEN_ERRORRETURNPREV}
    {LN_SOURCES_ADDEDIT}
    {LN_SOURCES_NAME}
    {LN_SOURCES_DESCRIPTION}
    {LN_SOURCES_TYPE}
    {LN_CFG_VIEW}
    {LN_CFG_MSGPARSERS}
    {LN_CFG_NORMALIZEMSG}
    {LN_CFG_SKIPUNPARSEABLE}
    {LN_SOURCES_FILTERSTRING} {LN_SOURCES_FILTERSTRING_HELP}
    {LN_GEN_USERONLY}
    {LN_GEN_GROUPONLY}

    {LN_SOURCES_DISKTYPEOPTIONS}
    {LN_CFG_LOGLINETYPE}
    {LN_CFG_SYSLOGFILE}
    {LN_CFG_DATABASETYPEOPTIONS}
    {LN_CFG_DBSTORAGEENGINE}
    {LN_CFG_DBTABLETYPE}
    {LN_CFG_DBSERVER}
    {LN_CFG_DBNAME}
    {LN_CFG_DBTABLENAME}
    {LN_CFG_DBUSER}
    {LN_CFG_DBPASSWORD}
    {LN_CFG_DBROWCOUNTING} Yes No
    {LN_CFG_DBRECORDSPERQUERY}


    loganalyzer-3.6.5/src/templates/admin/admin_index.html0000644000175000017500000004263412225176641022367 0ustar danieldaniel
    {LN_ADMINMENU_GENOPT}


    {LN_UPDATE_AVAILABLE}

    {LN_UPDATE_INSTALLEDVER} {BUILDNUMBER}
    {LN_UPDATE_AVAILABLEVER} {UPDATEVERSION}
    {LN_UPDATE_LINK}


      {LN_GEN_DISABLEUSEROPTIONS}
    {LN_GEN_ENABLEUSEROPTIONS}
    {LN_GEN_PERSONALVALUE}
    {LN_GEN_OPTIONNAME} {LN_GEN_GLOBALVALUE}
    {LN_ADMIN_GLOBFRONTEND}
    {LN_GEN_WEBSTYLE}
    {LN_GEN_SELLANGUAGE}
    {LN_GEN_DEFVIEWS}
    {LN_GEN_DEFSOURCE}
    {LN_GEN_PREPENDTITLE}
    {LN_GEN_MSGCHARLIMIT}
    {LN_GEN_STRCHARLIMIT}
    {LN_GEN_ENTRIESPERPAGE}
    {LN_GEN_AUTORELOADSECONDS}
    {LN_GEN_ADMINCHANGEWAITTIME}
    {LN_GEN_POPUPMENUTIMEOUT}
    {LN_GEN_CUSTBTNCAPT}
    {LN_GEN_CUSTBTNSRCH}
    {LN_GEN_USETODAY}
    {LN_GEN_DETAILPOPUPS}
    {LN_GEN_CONTEXTLINKS}
    {LN_GEN_IPADRRESOLVE}
    {LN_GEN_SUPPRESSDUPMSG}
    {LN_GEN_TREATFILTERSTRUE}
    {LN_GEN_INLINESEARCHICONS}
    {LN_ADMIN_MISC}
    {LN_GEN_SHOWDEBUGMSG}
    {LN_GEN_DEBUGGRIDCOUNTER}
    {LN_GEN_SHOWPAGERENDERSTATS}
    {LN_GEN_ENABLEGZIP}
    {LN_ADMIN_GLOBALONLY}
    {LN_ADMIN_SCRIPTTIMEOUT}
    {LN_ADMIN_PHPLOGCON_LOGOURL}
    {LN_ADMIN_USEPROXYSERVER}
    {LN_ADMIN_DEFAULTENCODING}
    {LN_GEN_DEBUGUSERLOGIN}
    {LN_GEN_DEBUGTOSYSLOG}
    {LN_GEN_INJECTHTMLHEADER}
    {LN_GEN_INJECTBODYHEADER}
    {LN_GEN_INJECTBODYFOOTER}


    loganalyzer-3.6.5/src/templates/admin/admin_users.html0000644000175000017500000001016212225176641022410 0ustar danieldaniel

    {LN_GEN_ERRORDETAILS}

    {ERROR_MSG}



    {LN_GEN_ERRORRETURNPREV}


    {LN_USER_CENTER}


    {LN_USER_ID} {LN_USER_NAME} {LN_USER_ISADMIN} {LN_USER_ISREADONLY} {LN_GEN_ACTIONS}
    {ID} {username}    
     {LN_USER_ADD}
    {LN_USER_ADDEDIT}
    {LN_USER_NAME}
    {LN_USER_PASSWORD1}
    {LN_USER_PASSWORD2}
    {LN_USER_ISADMIN}
    {LN_USER_ISREADONLY}


    loganalyzer-3.6.5/src/templates/admin/admin_dbmappings.html0000644000175000017500000001326112225176641023376 0ustar danieldaniel

    {LN_GEN_ERRORDETAILS}

    {ERROR_MSG}



    {LN_GEN_ERRORRETURNPREV}


    {LN_DBMP_CENTER}


    {LN_DBMP_ID} {LN_DBMP_NAME} {LN_DBMP_DBMAPPINGS} {LN_GEN_ACTIONS}
    {ID} {DisplayName} {DisplayName} {CaptionSeperator}{FieldCaption} => {FieldMapping}        
     {LN_DBMP_ADD}
    {LN_DBMP_ADDEDIT}
    {LN_DBMP_NAME}

    {LN_DBMP_DBMAPPINGSLIST}
    {LN_DBMP_MAPPING} {ZAEHLER}: {MappingCaption} ({MappingInternalID})






    loganalyzer-3.6.5/src/templates/admin/admin_views.html0000644000175000017500000001502612225176641022410 0ustar danieldaniel

    {LN_GEN_ERRORDETAILS}

    {ERROR_MSG}



    {LN_GEN_ERRORRETURNPREV}


    {LN_VIEWS_CENTER}


    {LN_VIEWS_ID} {LN_VIEWS_NAME} {LN_VIEWS_COLUMNS} {LN_VIEWS_TYPE} {LN_GEN_ACTIONS}
    {ID} {DisplayName} {DisplayName} {FieldCaptionSeperator}{FieldCaption} {ViewTypeText}        
     {LN_VIEWS_ADD}
    {LN_VIEWS_ADDEDIT}
    {LN_VIEWS_NAME}
    {LN_GEN_USERONLY_LONG}
    {LN_GEN_GROUPONLY_LONG}

    {LN_VIEWS_COLUMNLIST}
    {LN_VIEWS_COLUMN} {ZAEHLER}: {ColCaption} {ColInternalID}






    loganalyzer-3.6.5/src/templates/admin/admin_searches.html0000644000175000017500000001101312225176641023040 0ustar danieldaniel

    {LN_GEN_ERRORDETAILS}

    {ERROR_MSG}



    {LN_GEN_ERRORRETURNPREV}


    {LN_SEARCH_CENTER}


    {LN_SEARCH_ID} {LN_SEARCH_NAME} {LN_SEARCH_QUERY} {LN_SEARCH_TYPE} {LN_GEN_ACTIONS}
    {ID} {DisplayName} {DisplayName} {SearchQuery_Display} {SearchTypeText}        
     {LN_SEARCH_ADD}
    {LN_SEARCH_ADDEDIT}
    {LN_SEARCH_NAME}
    {LN_SEARCH_QUERY}
    {LN_GEN_USERONLY}
    {LN_GEN_GROUPONLY}


    loganalyzer-3.6.5/src/templates/admin/admin_parsers.html0000644000175000017500000001274112225176641022733 0ustar danieldaniel

    {LN_GEN_ERRORDETAILS}

    {ERROR_MSG}



    {LN_GEN_ERRORRETURNPREV}


    {LN_ADMINMENU_MSGPARSERSOPT}


    {LN_PARSERSMENU_LIST} {LN_PARSERS_ONLINELIST}  
    {LN_PARSERS_ID} {LN_PARSERS_NAME} {LN_PARSERS_DESCRIPTION} {LN_GEN_ACTIONS}
    {ID} {DisplayName} {Description}    
    {LN_PARSERS_DETAILS}
    {LN_PARSERS_ID} {ParserID}
    {LN_PARSERS_NAME} {DisplayName}
    {LN_PARSERS_DESCRIPTION} {Description}
    {LN_PARSERS_CUSTOMFIELDS}
    {FieldCaption} ({FieldDefine})

    {LN_PARSERS_HELP} {LN_PARSERS_HELP_CLICK}
    {LN_PARSERS_INIT} {LN_PARSERS_REMOVE}


    {LN_GEN_ERRORRETURNPREV}

    loganalyzer-3.6.5/src/js/0000755000175000017500000000000012225176641014537 5ustar danieldanielloganalyzer-3.6.5/src/js/common.js0000644000175000017500000002233212225176641016367 0ustar danieldaniel/* Detect Browser Version */ var szBrowserApp = "MOZILLA"; // Default! if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { if (!/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)) { // Set browser to Internet Explorer szBrowserApp = "IEXPLORER"; } } /* Helper Javascript functions */ function CheckAlphaPNGImage(ImageName, ImageTrans) { var agt=navigator.userAgent.toLowerCase(); var is_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)); if (is_ie) document.images[ImageName].src = ImageTrans; } function NewWindow(Location, WindowName,X_width,Y_height,Option) { var windowReference; var Addressbar = "location=NO"; //Default var OptAddressBar = "AddressBar"; //Default für Adressbar if (Option == OptAddressBar) { //Falls AdressBar gewünscht wird Addressbar = "location=YES"; } windowReference = window.open(Location,WindowName, 'toolbar=no,' + Addressbar + ',directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,copyhistory=no,width=' + X_width + ',height=' + Y_height); if (!windowReference.opener) windowReference.opener = self; } /* * Helper function for form scripting */ function toggleformelement(ElementNameToggle, isEnabled) { var myFormElement = document.getElementById(ElementNameToggle); if ( isEnabled ) { myFormElement.disabled = false; } else { myFormElement.disabled = true; } } // helper array to keep track of the timeouts! var runningTimeouts = new Array(); /* * Helper function to show and hide a div area */ function togglevisibility(ElementNameToggle, ElementNameButton) { var toggle = document.getElementById(ElementNameToggle); // Button is optional if (ElementNameButton != null) { var button = document.getElementById(ElementNameButton); } else var button = null; if (toggle.style.visibility == "visible") { if (button != null) { button.className = "topmenu2 ExpansionPlus"; } toggle.style.visibility = "hidden"; toggle.style.display = "none"; } else { if (button != null) { button.className = "topmenu2 ExpansionMinus"; } toggle.style.visibility = "visible"; toggle.style.display = "inline"; } } /* * Helper function to hide a div area */ function showvisibility(ElementNameToggle, ElementNameButton) { var toggle = document.getElementById(ElementNameToggle); // Button is optional if (ElementNameButton != null) { var button = document.getElementById(ElementNameButton); } else var button = null; if (button != null) { button.className = "topmenu2 ExpansionMinus"; } toggle.style.visibility = "visible"; toggle.style.display = "inline"; } /* * Helper function to hide a div area */ function hidevisibility(ElementNameToggle, ElementNameButton) { var toggle = document.getElementById(ElementNameToggle); // Button is optional if (ElementNameButton != null) { var button = document.getElementById(ElementNameButton); } else var button = null; if (button != null) { button.className = "topmenu2 ExpansionPlus"; } toggle.style.visibility = "hidden"; toggle.style.display = "none"; } function ResetFormValues(formName) { var myform = document.getElementById(formName); var i = 0; var iCount = myform.elements.length; // Loop through text fields for(i = 0; i < iCount; i++) { if (myform.elements[i].type == "text" ) { // Reset textfield myform.elements[i].value = ""; } } } function SubmitForm(formName) { var myform = document.getElementById(formName); if (myform != null) { myform.submit(); } } /* * Helper function to show and hide areas of the filterview */ function toggleFormareaVisibility(FormFieldName, FirstHiddenArea, SecondHiddenArea ) { var myfield = document.getElementById(FormFieldName); if (myfield.value == 1) { togglevisibility(FirstHiddenArea); hidevisibility(SecondHiddenArea); } else if (myfield.value == 2) { hidevisibility(FirstHiddenArea); togglevisibility(SecondHiddenArea); } } /* * Toggle display type from NONE to BLOCK */ function ToggleDisplayTypeById(ObjID) { var obj = document.getElementById(ObjID); if (obj != null) { if (obj.style.display == '' || obj.style.display == 'none') { obj.style.display='block'; // Set Timeout to make sure the menu disappears ToggleDisplaySetTimeout(ObjID); } else { obj.style.display='none'; // Abort Timeout if set! ToggleDisplayClearTimeout(ObjID); } } } function ToggleDisplaySetTimeout(ObjID) { // Set Timeout var szTimeOut = "ToggleDisplayOffTypeById('" + ObjID + "')"; runningTimeouts[ObjID] = window.setTimeout(szTimeOut, defaultMenuTimeout); } function ToggleDisplayClearTimeout(ObjID) { // Abort Timeout if set! if ( runningTimeouts[ObjID] != null ) { window.clearTimeout(runningTimeouts[ObjID]); } } function ToggleDisplayEnhanceTimeOut(ObjID) { // Only perform if timeout exists! if (runningTimeouts[ObjID] != null) { // First clear timeout ToggleDisplayClearTimeout(ObjID); // Set new timeout ToggleDisplaySetTimeout(ObjID); } } /* * Make Style sheet display OFF in any case */ function ToggleDisplayOffTypeById(ObjID) { var obj = document.getElementById(ObjID); if (obj != null) { obj.style.display='none'; } } /* * Debug Helper function to read possible properties of an object */ function DebugShowElementsById(ObjName) { var obj = document.getElementById(ObjName); for (var key in obj) { document.write(obj[key]); } } /* * Detail popup handling functions */ var myPopupHovering = false; function HoveringPopup(event, parentObj) { // This will allow the detail window to be relocated myPopupHovering = true; } function FinishHoveringPopup(event, parentObj) { // This will avoid moving the detail window when it is open myPopupHovering = false; } function initPopupWindow(parentObj) { // Change CSS Class parentObj.className='syslogdetails_popup'; } function FinishPopupWindow(parentObj) { // Change CSS Class parentObj.className='syslogdetails'; } function disableEventPropagation(myEvent) { /* This workaround is specially for our beloved Internet Explorer */ if ( window.event) { window.event.cancelBubble = true; } } function movePopupWindow(myEvent, ObjName, PopupContentWidth, parentObj) { var obj = document.getElementById(ObjName); var middle = PopupContentWidth / 2; // alert ( parentObj.className ) ; if (myPopupHovering == false) { obj.style.left = (myEvent.clientX - middle) + 'px'; } } function GoToPopupTarget(myTarget, parentObj) { if (!myPopupHovering) { // Change document location document.location=myTarget; } else /* Close Popup */ { FinishPopupWindow(parentObj); } } function FinishPopupWindowMenu() { // Change CSS Class var obj = document.getElementById('popupdetails'); if (obj != null) { obj.className='popupdetails with_border'; } } function movePopupWindowMenu(myEvent, ObjName, parentObj) { var obj = document.getElementById(ObjName); // var PopupContentWidth = 0; // var middle = PopupContentWidth / 2; var middle = -10; if (myPopupHovering == false && obj != null && parentObj != null) { // Different mouse position capturing in IE! if (szBrowserApp == "IEXPLORER") { obj.style.top = (event.y+document.body.scrollTop + 10) + 'px'; } else { obj.style.top = (myEvent.pageY + 20) + 'px'; } obj.style.left = (myEvent.clientX - middle) + 'px'; } } function HoverPopup( myObjRef, myPopupTitle, HoverContent, OptionalImage ) { // Change CSS Class var obj = document.getElementById('popupdetails'); obj.className='popupdetails_popup with_border'; if ( myObjRef != null) { myObjRef.src = OptionalImage; // "{BASEPATH}images/player/" + myTeam + "/hover/" + ImageBaseName + ".png"; } // Set title var obj = document.getElementById("popuptitle"); obj.innerHTML = myPopupTitle; // Set Content var obj = document.getElementById("popupcontent"); obj.innerHTML = HoverContent; } function HoverPopupHelp( myEvent, parentObj, myPopupTitle, HoverContent ) { // Change CSS Class var objPopup = document.getElementById('popupdetails'); objPopup.className='popupdetails_popup with_border'; // Set title var obj = document.getElementById("popuptitle"); obj.innerHTML = myPopupTitle; // Set Content obj = document.getElementById("popupcontent"); obj.innerHTML = HoverContent; // var PopupContentWidth = 0; /// var middle = PopupContentWidth / 2; var middle = -5; if (myPopupHovering == false && parentObj != null) { // Different mouse position capturing in IE! objPopup.style.top = (event.y+document.body.scrollTop + 24) + 'px'; objPopup.style.left = (myEvent.clientX - middle) + 'px'; } } function HoverPopupMenuHelp( myEvent, parentObj, myPopupTitle, HoverContent ) { if (szBrowserApp !== "IEXPLORER" ) { // Don't need helper here! return; } // Change CSS Class var objPopup = document.getElementById('popupdetails'); objPopup.className='popupdetails_popup with_border'; // Set title var obj = document.getElementById("popuptitle"); obj.innerHTML = myPopupTitle; // Set Content obj = document.getElementById("popupcontent"); obj.innerHTML = HoverContent; // var PopupContentWidth = 0; // var middle = PopupContentWidth / 2; var middle = -5; if (myPopupHovering == false && parentObj != null) { // Different mouse position capturing in IE! objPopup.style.top = (event.y+document.body.scrollTop - 50) + 'px'; objPopup.style.left = (myEvent.clientX - middle) + 'px'; } } loganalyzer-3.6.5/src/js/searchhelpers.js0000644000175000017500000001404512225176641017731 0ustar danieldaniel/* Helper Javascript Constants */ const DATEMODE_ALL = 1, DATEMODE_RANGE = 2, DATEMODE_LASTX = 3; const DATE_LASTX_HOUR = 1, DATE_LASTX_12HOURS = 2, DATE_LASTX_24HOURS = 3, DATE_LASTX_7DAYS = 4,DATE_LASTX_31DAYS = 5; /* Helper Javascript functions */ /* * Helper function to show and hide areas of the filterview */ function toggleDatefiltervisibility(FormName) { var myform = document.getElementById(FormName); if (myform.elements['filter_datemode'].value == DATEMODE_ALL) { hidevisibility('HiddenDateFromOptions'); hidevisibility('HiddenDateLastXOptions'); toggleformelement('filter_daterange_from_year', false); toggleformelement('filter_daterange_from_month', false); toggleformelement('filter_daterange_from_day', false); toggleformelement('filter_daterange_to_year', false); toggleformelement('filter_daterange_to_month', false); toggleformelement('filter_daterange_to_day', false); toggleformelement('filter_daterange_from_hour', false); toggleformelement('filter_daterange_from_minute', false); toggleformelement('filter_daterange_from_second', false); toggleformelement('filter_daterange_to_hour', false); toggleformelement('filter_daterange_to_minute', false); toggleformelement('filter_daterange_to_second', false); toggleformelement('filter_daterange_last_x', false); } else if (myform.elements['filter_datemode'].value == DATEMODE_RANGE) { togglevisibility('HiddenDateFromOptions'); hidevisibility('HiddenDateLastXOptions'); toggleformelement('filter_daterange_from_year', true); toggleformelement('filter_daterange_from_month', true); toggleformelement('filter_daterange_from_day', true); toggleformelement('filter_daterange_to_year', true); toggleformelement('filter_daterange_to_month', true); toggleformelement('filter_daterange_to_day', true); toggleformelement('filter_daterange_from_hour', true); toggleformelement('filter_daterange_from_minute', true); toggleformelement('filter_daterange_from_second', true); toggleformelement('filter_daterange_to_hour', true); toggleformelement('filter_daterange_to_minute', true); toggleformelement('filter_daterange_to_second', true); toggleformelement('filter_daterange_last_x', false); } else if (myform.elements['filter_datemode'].value == DATEMODE_LASTX) { togglevisibility('HiddenDateLastXOptions'); hidevisibility('HiddenDateFromOptions'); toggleformelement('filter_daterange_from_year', false); toggleformelement('filter_daterange_from_month', false); toggleformelement('filter_daterange_from_day', false); toggleformelement('filter_daterange_to_year', false); toggleformelement('filter_daterange_to_month', false); toggleformelement('filter_daterange_to_day', false); toggleformelement('filter_daterange_from_hour', false); toggleformelement('filter_daterange_from_minute', false); toggleformelement('filter_daterange_from_second', false); toggleformelement('filter_daterange_to_hour', false); toggleformelement('filter_daterange_to_minute', false); toggleformelement('filter_daterange_to_second', false); toggleformelement('filter_daterange_last_x', true); } } /* * Helper function to add a date filter into the search field */ function CalculateSearchPreview(szSearchFormName, szPreviewArea) { var mySearchform = document.getElementById(szSearchFormName); var myPreviewArea = document.getElementById(szPreviewArea); var szOutString = "", szTmpString = "", nCount = 0; if (mySearchform.elements['filter_datemode'].value == DATEMODE_RANGE) { szOutString += "datefrom:" + mySearchform.elements['filter_daterange_from_year'].value + "-" + mySearchform.elements['filter_daterange_from_month'].value + "-" + mySearchform.elements['filter_daterange_from_day'].value + "T" + mySearchform.elements['filter_daterange_from_hour'].value + ":" + mySearchform.elements['filter_daterange_from_minute'].value + ":" + mySearchform.elements['filter_daterange_from_second'].value + " "; szOutString += "dateto:" + mySearchform.elements['filter_daterange_to_year'].value + "-" + mySearchform.elements['filter_daterange_to_month'].value + "-" + mySearchform.elements['filter_daterange_to_day'].value + "T" + mySearchform.elements['filter_daterange_to_hour'].value + ":" + mySearchform.elements['filter_daterange_to_minute'].value + ":" + mySearchform.elements['filter_daterange_to_second'].value + " "; } else if (mySearchform.elements['filter_datemode'].value == DATEMODE_LASTX) { szOutString += "datelastx:" + mySearchform.elements['filter_daterange_last_x'].value + " "; } // --- Syslog Facility szTmpString = ""; nCount = 0; for (var i = 0; i < mySearchform.elements['filter_facility[]'].length; i++) { if (mySearchform.elements['filter_facility[]'].options[i].selected == true) { if ( szTmpString.length > 0) { szTmpString += ","; } szTmpString += mySearchform.elements['filter_facility[]'].options[i].value; nCount++; } } if ( nCount < 18 ) { // Only if not all selected! szOutString += "facility:" + szTmpString + " "; } // --- // --- Syslog Severity szTmpString = ""; nCount = 0; for (var i = 0; i < mySearchform.elements['filter_severity[]'].length; i++) { if (mySearchform.elements['filter_severity[]'].options[i].selected == true) { if ( szTmpString.length > 0) { szTmpString += ","; } szTmpString += mySearchform.elements['filter_severity[]'].options[i].value; nCount++; } } if ( nCount < 8 ) { // Only if not all selected! szOutString += "severity:" + szTmpString + " "; } // --- // --- SyslogTag if (mySearchform.elements['filter_syslogtag'].value.length > 0 ) { szOutString += "syslogtag:" + mySearchform.elements['filter_syslogtag'].value + " "; } // --- // --- Source if (mySearchform.elements['filter_source'].value.length > 0 ) { szOutString += "source:" + mySearchform.elements['filter_source'].value + " "; } // --- // --- Message | Just append as it is szOutString += mySearchform.elements['filter_message'].value; // --- // Set preview area myPreviewArea.innerHTML = szOutString; }loganalyzer-3.6.5/src/BitstreamVeraFonts/0000755000175000017500000000000012225176641017705 5ustar danieldanielloganalyzer-3.6.5/src/BitstreamVeraFonts/VeraMono.ttf0000644000175000017500000014011012225176641022147 0ustar danieldanielOS/2´_õ*ª,VPCLT!?ͪ„6cmap¤Ãè ¨Xcvt é— 0fpgmÆp((TŒgaspÀ glyf­‚ñÅ(àtÈhdmxÇ32`ª¼HheadÙ…¥'À6hhea ?ôª$hmtx ε`¡4loca­™§ÌmaxpŠñ©è nameä£Á` úpostnî]¥4–prep:ÇÀ!8::h:: mR0¶u  Œ y t ¤ 0   t 0  0   ~ 6 H `  Ž 0¼ & –Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans MonoBitstreamVeraSansMono-RomanRelease 1.10Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans MonoBitstreamVeraSansMono-RomanRelease 1.10Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com¸Ë¸Ëª‘¸f¸‡¸ÃË˸¸Ë‰ºË¦ü˃ò Ç7ƒ¾X!Ëœçu¼ÓÉÛuç9ºËÓ!߸‰¾‰Ã¾{¾Xm¤®{¸o{¸RÍÑ͇‡“¤oÍ˸ƒ‘Ý´‹ô˜éZ´ºÅ!þÕöª=f‹ÅššƒÕs þáÕ+¤´œbœÕ˜‡ÕÕð¤¸#Ӹ˦¼1NÓ {T\qÛ…#wé`jÏÕ#fy```{{w`ªébø{!Åœ{´RNNÑfœœfœfœÍúƒ‘þHF?{L˜¢'oo5jo{ªª-–{öª3=œf‹öÍoD7fî…´}sÕ¹€²”]A–€þþþþšþ ²ëGA% } % 2 – þþ%þ%þ@Yþþþý}üþûþú2ù»ø}÷öŒ÷þ÷ÀöõYöŒö€õô&õYõ@ô&óò/óúò/ñþðþï2îí–ìëGìþì¸ÿÑ@ÿëGêédê–édèþçæçþæåþäkãþâ»áàáúàß–ÞþÝþÜÛÜþÛÚ–ÙØÙþØ Ø×}Ö:Õ Õ:ÔþÓÒ ÓþÒ ÑþÐþÏŠÏÎÍþÌ–Ë‹%ËþÊþÉ}ÈþÇþÆþÅš ÄþÃþÂþÁþÀ À¿ ¾½»¾þ½¼]½»½€¼»%¼]¼@»%ºþ¹–¸A·þ¶A¶úµš ´þ³d²d±°¯þ®þ@ý­þ¬þ«ªþ©¨©2¨§¦§(¦¥¤-¥}¤-£þ¢þ¡þ Ÿ dŸžŸž œþ›š ›þš ™˜.™þ˜.—A—––•»–þ•”]•»•€”%”]”@“þ’þ‘%‘»%‹%AŽ Ž Œ‹%Œd‹Š‹%Љþˆþ‡þ†…†þ…„þƒþ‚B‚Sþ€x~}þ~}}|þ{zþwþvþut uu¸@Út tÀss@rþqþpþonSo–nm(nSm(lþk2jþi2húg»fþeþdþcbcþbbaþ`þ_þ^Z ^]d\È[Z [Z YþXWþVþUU2TþSþRþQ}PþONþM-MþL»K(JIJ7ICIHEHþGCGdFEF»EDCD7CBCC¸@@ BABB¸@ A@AA¸À@ @? @@¸€@ ? ? ?¸@@d>þ=-=ú<þ;(:þ9B9d818K7þ6-6þ5K404K303þ2B2þ1-10/-/. .»-,--¸€@ ,,,¸@@–+*%+þ* *%):)þ(þ'þ&%B%E$#þ""þ! -!} -KBþþþþþþBF-B-Bþ-B¸@  ¸À@   ¸€@    ¸@´  ¸@7 þ  þ þ-þ:ú-:-¸d…++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX ¸EDY!-,°%E`D-,KSX°%°%EDY!!-,ED-hþ–h¤¼¶ƒ/ÄÔì1ÔìÔì0!%!!hüsüåþ–øòr)ÏÕ @‡†ˆ Ô<ì2991/äüì03#3#Ë¡ËËÕýqþ›eý¸þRªÕ@‰ˆÔìÜì1ô<ì20###®Ñ®ÕýÕ+ýÕ+;J@0Œ Œ    ÔÌ91/<Ô<<ü<<Ô<<Ä2ì220333!3!###!5!!5!#3¬hõi iôþçTúþßh iöiŸhþþ)Tþö/hõTö¾þaŸþašþ²™þbžþbž™NšŸýÇþ²¾þÓZ /d@9($)%/%‹$Ž(‹Ž!$, ( 0Ô<ì2ü<ìüäî1/Æ2ÄîöîîÆöî999906654&'#&&'5&&546753&&'´n|pÞhumÔdfÉbdËcÈÊÓ¿dO¢TU¡PÎØé¼DþNtd]gÑp^VdûÀ-.)´>Bʶ–»ëë­+/þQššÎ !°˜ *9V@/7(" ’"’7“(’.‘“’+  % 4  + :ÄÔìüìîþî99991/îîöîþîî9999032654&#"4632#"&'%32654&#"4632#"&¸iNMklLNi‡¸†@s..2º‡ˆ¶þH#)üiOMllMMk‡¸‡@u--1º†‡¸?NjkMMljO‡¹0./t?…º·`¢`åOikMMkjN‡¹0--uA†¹¸9ÿãÅð*7³@b  -,.+2345617B7 1 +"1—"!%—–™ (! 7+!(!(! .8ÜìÄüÄÆîî99999991/ÆäöîÖÎî9990KSXí9í9íí9Y"6654''3#'#"5467&&54632&&#"3267667# '&¤JKªÕNSºjØþ抋20Ç­AƒF;}Eap:6\[È›*\,#‹ýÑ1–h F'¡óXåmFD ̉êdHŠG–®·'%[M;ÏI£\—Ç ª¾Õ·ˆÔì1ôÄ0#¾®ÕýÕ+ªþòu @œ›  Ôì2ì991üì0#&547u…ƒƒ… —””—äþ;æåþ:æîÃàßÄì\þò' @œ›  Ôüì2991üì03#654\ —””— …ƒƒìþ<ßáþ<ìèÆã䯦J+ðN@,   –    Ô<ì2Ü<ì2991ôÔ<ì2Äì2990%#'%%73%+þšf9þ°sþ°9fþš9PsPßÂÃbËþ‡yËbÃÂcËyþ‡ËXqy“ '@¡  ¡   Ô<ìü<ì1Ô<ìü<ì0!!#!5!¼½þC¨þD¼“þDªþD¼ª¼“þáò/@ £¢ÔìÔÌ1üì03#öüÅšc/Ïþdßmƒ¶ ÔÄ1Ôì0!!d ý÷ƒ¤éå1¶¢Ôì1/ì03#éüü1þÏfÿB7Õ@ ˆÔìÔì1ôÄ03#y¾üî¿Õùm…ÿãLð # @¥ — —–™$!"!$üììÔìî1äôìîÔî0@Ö////////// / / ?????????? ? ? OOOO O ____ _ ŸŸŸŸŸŸŸŸŸŸ Ÿ Ÿ ¯¯¯¯¯¯¯¯¯¯ ¯ ¯ ¿¿¿¿¿¿¿¿¿¿ ¿ ¿ F////////// / / __________ _ _ ¿¿¿¿¿¿¿¿¿¿ ¿ ¿ $]]4632#"&"32'2#"ãM68PO98K…‹‹Ž‹‹Žïõõïïôôî7PP78NLœþÐþÉþÊþÐ0670 þxþþ‚þxˆ~ˆöFÕ &@——ˆ— ## ÔìÄüì1/ì2ôìÔì0%!5%3!!:þ®PÊ6üȪuL¸JúÕª˜#ðQ@)%%B§ —–—  "$üÄüìÀÀ91/ì2ôìôÌ0KSXí9í2Y"%!!5676654&#"56632u®üu»5dF“€[ÈpgÇaÛ Yd8ÕªªªÅ.>z—O}ŽBCÌ12é½`ÀtAæ‰ÿã7ð(G@)— ‹ ¦ —‹ ¦—#–™©)&" )üÄÄüìÔì91ìäôìôìîöîî90#"&'532654&##532654&#"56632“œþëõgÖgfÆb¦²²˜šš‹œ‘†Y¾hy½IÚ‰'Ç•Îë&$É54–‚™¦zms{((º Ûµ{¤foÕ B@   B —ˆ   $üüÔ<ì291/äÔ<ì290KSXÉÉY"!33##!5ßþ)×!êÇÇÉý‡üëÍü3¤þœd¿ÿã-Õ=@"—‹Ž— —ˆ ™ª "üÄüÄìî1ääôìîöîþÄ90!!6632#"&'532654&#"ÏôýÄ+W,èþã÷wÅN\ºa§µ»§QšFÕªþ‘þîêìþð Í21°¢ ²%%…ÿãLð$=@#— — «‹Ž—–™%"& "%üììüäì1äôìôìåîî90&&#"6632# !2"32654&ß?ŽMÀÆ0ªnØíôÝþüò#J”þÝ””†ˆˆ´º%'þßþçdkþ÷óòþöu‘zýlº¤¤º±­®°‹7Õ5@%%B—ˆ"üìÄ991/ôì0KSXííY"!#!‹¬ýêÓý5ÕVú+ƒÿãNð #/C@% —'—-—–™'©0 $*$ "!0üÄìüÄìîî991ìäôìîî990"32654&%&&54632#"$54632654&#"h‡“•…ˆ“•þÊ‘òÐÑò‘–ŸþþääþÿŸM€yz€{y€Å—ŠŠ™—Œ‰˜T!´²ÑѲ´!!ÈŸÊäãÉ Ébx~~xz€ÿãFð $;@"—« ‹ Ž—"—–"™%"  &%üäìüìì1äôìîöîõî902654&#"532#"543 !"&T““†ˆ‡á?ŽMÀÅ/ªnØíóÞòþÝþëI”–º¤¤º±­®°ý‰º%'!dk ôñ þŠþoþ‡þséå'@ ¢¬¢Ô<ì21/ìôì03#3#éüüüü'þÑþ9þÏ“þáò' %@¢£¢¬  ÔüÔüÔÌ1äüìî03#3#öüÅšc üü/ÏþÇþÑXyw!@®­('üì291ôì90 5yü®Rûß!ÁþÀþ÷¢¦¢X`y¢@   Ô<Ä21ÔìÔì0!!!!X!ûß!ûß ¬BªXyw!@®­('ü<ì91ôì9055X!ûßRÁ¶þ^¦þ^·=ôð"{@B  %%B‹ —–†!    ) #ÔìÄÔÔìî99991/îöþôîÍ9990KSXí9í9Y"#546776654&#"566323#¬¾=TZ>/ƒmN²b^¿hºÝC^XE&ÅËË‘šb‰RY;X1YnED¼98À¡Lƒ\VBT=/þòþþÁšs 4p@1(+$ 4¯ ¯ '$¯+¯1+5' ( + . !+ -.5ÜìüÄþ<Äî991ÄÔüÄþÄÕÄîî999990@ €€€€€€]4&#"326#5#"&5463254&#"!267# !2€kkkk€Œ%ƒR¡ÓÓ¡P†$°‘öþÝJ6l90?{:þ›þ]x<Ñú!››‚››þèo?Dò¼¼òF=?œ¾þþ¹þ·þz‡ÒŒ†Îþöà%¬Õ ˜@A%%%% % % %  % B—°ˆ   / Üì91/<äüì90KSXííííííííY"²]@    †‰]]!3#!#hÕªþ±õÉÑnýõlÑ#ý®ú+…þ{¦qÕ =@#— —ˆ— ± 21 0!üì2üìÔì9991/ììôìî9032654&#32654&#%!2!!qï°–ž¨ïë’ƒ”þJºåøƒƒ“§þöþùþFÉýÝ{’‰fþ>p}qd¦Æµ‰žÏ ËÏ‹ÿã1ð.@³²— ³ ²— –™2 10üì2ì1äôìôìîöî0%# !2&&#"32671M¢[þáþÃ?[¢MJªVÅÄÄÅX©I5))–pn™))Ï=@þÐþÍþÎþÐ@=‰RÕ(@— ˆ— 2 10üìüì99991/ìôì0%26&!# !!´ÿÊÉÿ`dVDþ¼þªþѦûHKûûw/þ”þ€þ‚þ•ÕÅNÕ )@——ˆ—±  13 üì2üÄÄ1/ììôìî0!!!!!!ÅvýTŽýr¿üwÕªþFªýãªéXÕ $@——ˆ±14 üì2üÄ1/ìôìî0!!!!#éoý\eý›ËÕªþHªý7fÿãPð<@!—— ³ ²— –™ 625üìüÄüÄ1äôìôìþÔî990%# !2&&#"3267#5!PQËvþäþÄ@^¬PQª_ÅÅ¿ÆCe)Ùš{KM—on™56ÏMIþÏþÎþÉþÕ!‘¦‰HÕ &@—±ˆ 1 0 üì2üì21/<ä2üì03!3#!#‰Ë)ËËý×ËÕýœdú+Çý9ÉÕ %@ —ˆ—77 Ôì2üì21/ì2ôì20!!!!5!!É=þÇ9üÃ9þÇÕªûªªmÿã¼Õ,@ ²—— ˆ™  5üÔüÄ1äôìîöÎ990753265!5!#"&m[ÂhqþƒGÓ÷`¾=ìQQ•ËDªüþæê,‰ÉÕ —@!% %B´  0 üì2À91/<ì290KSXííY"²]@L&&6FUWX dzy{ ',+&:IGG[WXXWkzx]]33 ##‰Ëwíý»VôþšËÕýh˜ýžüì¤ý¸×sÕ@ —ˆ14üìì1/äì03!!×ËÑüdÕúÕªVyÕ …@,  B ´   / 0 üìüì91/<ì2Ä90KSXÉÉÉÉY"² ]@$  &)&) 6968  ]]! !###V»þö™þõºÕýøú+'üíúÙ‹FÕ m@B´10 üìüì991/<ì2990KSXÉÉY"²]@&)&8Wdjuz &)FIWgh]]!3!#‹øÃÿþÃÕû3Íú+Íû3uÿã\ð #@ ——–™2 625üìüì1äôìî0#"32#"32‰‡š™‡‡™š‡Ó÷ýýö÷üý÷éIþæþ·þ¸þæIþzþ€~ˆ‡€þ€ÅuÕ+@—— ˆ 2 8 3üì2üì91/ôìÔì032654&#%!2###ꌜþL´úþÿûêÊ/ýÏ”……“¦ãÛÝâý¨uþò\ð=@ —— –™ 2 625üìüì99991Ääôìî9990"#"32#"32ú÷÷üý÷‰‹È—‡š™‡‡™š‡€†‡€þ€þyþÚþ™H¾d÷Iþæþ·þ¸þæÑÕj@8  %%B— — ˆ    21  0üì2üÄì99991/<ôìÔì9990KSXíí9Y"#&&###!232654&#øNnRËÙ²M{cÁË ö¡ýÐÝ‘Ž—Áo¦þhy¡]ý‰ÕÞÒ”»Yý‰‹ÿãJð'„@=  %  %B ³§—³§—%–™( &919"0(üìÄüìä99991äôìôìîöî90KSXí9í9Y"²]@ ]].#"#"&'532654&/.54$32ô\¹^¦m•jÒÀþøüiÔksÍh™ªu‘lм ßV¾¢Í;<…qch#1ÒµÕà--×ID‰{pv /¾ Èñ'/¢Õ@—ˆ::Ôìüì1/ôì20!!#!/sþ-Ëþ+ÕªúÕ+“ÿã=Õ,@ —™ˆ10üìüì1ä2ôì99903326766553#"&'&&“Ë  yVWx! Ê9FBªjiªCE:=˜ü m];<<;\l^˜ühåÁ?;::;>Å9˜ÕL@)%%%%B´/0üì91/ì290KSXííííY"%3#3h_ÑþKõþKѪ+ú+ÕÑÕ á@D    %%% % B ´   /Ì91/<ü<Ä90KSXííííÉÉÉÉY"² ]@^ //+ ??8 ZZ  &*%*(+ % & 5:5:;: 4 6 TTZXWV[[RW X ] gh yvy v #]]333# #ŪӬÅß¿ËÊ¿ÕûD"üܾú+wü‰¾Õ Æ@K % % % %%%% % B ´  ;/; 0 üäüä91/<ì290KSXííííííííY"²7]@8  '()& X xyw !%+% 5UYX es]]3 3 # #VÙHNÙþAßÙþ’þuÚôÕýÍ3ýBüéƒý}%¬ÕY@.%%%%B´<< Ôìüì9991/ì290KSXííííY"33#%×lkÙþ!ËÕým“üÉýbžœ‘Õ E@%%B—ˆ—/0 üÄüÄ991/ìôì0KSXííY"²]²]!!!5!²Éüô"ü ÷ýÕšûoªš‘Ïþòw@¶·¶µ=ÔüÄ21üìôì0!#3!ϨððþXùüfÿB7Õ@ ˆÔìÔì1ôÄ0#%¾üíÕùm“Zþò@¶·¶µ=ÔÄ2ì1üìôì0!53#5þXððøÞH¨‰Õ@ ˆÔÌ91ôÌ290##ÁȲþ‘þ’²ÈÕýÓ‹þu-þþmµ¸/Ì1Ôì0!5üþmPPîöf1@ º¹<Ôì1ôì0K° TK°T[X½ÿÀ@878Y #Ýšþ»fþˆx…ÿã#{ )n@*  ¶Œ!‹ ¿Œ$¾™   D >*ôìÄüì22991/Ääôüôìîî99990@00 0!0"       ¢    ]#"326757#5#"&546;5.#"5>32¾=¡£zl˜®¹¹;³€«Ìûó÷†“^À[f»X‹Å=& 3qpepÓº)Lý¦d_Á¢»Â†y64¸''RR2“ÁÿãX 0@ Œ Œ™¾›G Fôì22üì1/ìäôìî9904&#"3266632#"&'#3–ˆ…†ŠŠ†…ˆýã,›fÊèéËd™.¸¸/ÖÚÛÕÔÜÚxRXþÉþïþëþÅWSÃÿã%{/@ ‹ À‹ÀŒŒ ¾™ FôÄ2ì1äôìþôîõî0%# !2&&#"3267%JRþüþÛ%QšNI“]­º»¬`˜A9++88*,ÁA:àÐÏá;>{ÿã0@ŒŒ™¾›G Hôìüì221/ìäôìî9903#5#"3232654&#"Z¸¸.™dËéêÊešþˆ……‹‹……ˆÑCùìSW;7Wþ ÖÚÜÔÕÛÚ{ÿãX{E@& ‹ ¶Œ ÁŒ¾ ™ IHôìüìÄ991äôìäîîôî990!3267# 32&&#"Xüã¿®XÀmiÃ[þûþÚ ðÖ÷¸‘ˆ…¬^Z·È89·++9 @þÞÅ¢©°œÃ'4@ ¶Œ›    Ô<Äü<Ä2991/ä2üìî2990#"!!#!5!5463'ÑcMþ¸þÕ+©³™Qgcü/ÑN¸®{þH{ )H@' ' ‹ ŒŒŒ$¾Ã(Â*' G!H*ôÄìüì221ääÄôìîîÕî999904&#"326#"&'5326=#"3253Z‡‡Žˆ‡¸îçL¦Sb C•ˆ,˜mÄêêÄl–/¸9Ï××ÏÏÙÚþÝüþü¶.,¢°}^\::VZ‘Ã,@ Œ¾ › J  Fôì2üì1/<ìôì990#4&#"#36632¹jq‹¸¸1¨s«©¶ýJ¶—Ž·«ý‡ý¤`cá²D .@¶ Ä ›Â¶L LK Ô<äìü<ì1/ì2äüìî0!!!5!!3#×münmþḸ`ü/BCéºþV 8@ Œ¶Ä›Âà  Ô<ì2ÄÄ991ääüìîî990!5!##53263#XþÃõ³¥þêZZ¸¸åûŒÃÓœ}¥éì² Å@:  B›  DE ôìì291/<ìä90KSXííííííY"²]@R546Ffuv ('(;;797JIYYkiiiyxyy]]33 ##ì¾ãàþGþáþb‰¾ü{ÑþZýFBþ?   &@  ¶ Ŷ L ÔìüÌ991/ìüì99033#"&5!5![Y×饵þÙß–|~œÔÂùmo{"Ì@'  Œ ¾ÂMNMNME#ôü<üìüì91/<<äô<ì299990@G000000 0 0 ?????????€€€€€€€ € € #]K° TK°T[K°T[X½#@##ÿÀ878YK°TX½#ÿÀ##@878Y>32#4&#"#4&#"#3>32¤"iJ‡o¨5FP;¨9JI9§§!c?LeîHEÑþßýwís{åýðp{åý``ôìüì1äôìî0"32654&'2#"hŒŒé÷öêéöößÚÖÕÛÛÕÖÚœþÒþâþáþÓ-.¾þVT{3@ŒŒ¾™Ã GFôì22üì1äääôìî990%#36632#"&4&#"326w¹¹.™dËçèÊf™ð‡…†ŠŠ†…‡ýÉ SWþÆþêþïþÉWõÖÚÛÕÔÜÚ‰þRw 3@ Œ Œ¾™Ã G>ôìüì221äääôìî99032654&#"#"3253#L‡……‰‰……‡-™eÉéèÊd™.¹¹+ÖÚÛÕÕÛÚýŠSY7:WSùöjƒ{O@ —¾  ÔÄì21/äôìÔÌ990@%  0030@@C@PPPP].#"#3>32ƒ;zI¬¶¹¹.¿ƒDv6y.*ØÌýÓ`Ûw"$Õÿã{'u@@    B ‹À‹ÀŒŒ%¾™( OI"E(ôÄìüìä99991äôìþõîõî990KSXí9í9Y"&&#"#"&'532654/&&54632ÍO S}{\·J‰ìÒS¶jg¼Tz†õEŸ’ÚÊZ¦9´..QSKJ#œ}¦»##¾55cY€1“¡¯!ƒž1@¶Â¶  Ô<Äü<Ä2991/ìô<Äì2990!!33#"&5!5!f¢þ^^uÏáϪþÕ+žþÂý |b“¦Ë`>Ãÿã^,@ Œ™   JFôìüì21/ä2ôì990332653#5#"&økp‚й¹1©q¬¨¨¶ýJ—Ž·«yû¢¨adádm`e@)BÂIEôì91/ä290KSXííííY"²']@%]]3 3#d¿EF¿þrí`üT¬û Ñ` @E      B    /Ì91/<ô<Ä90KSXííííÉÉÉÉY"² ]@Œ      &&)&))#, 96993< EI F J VX W Y fifij e vzx| r -   ++>>< H Y jih {yz|  ]]333# #¶Ã ¢Ã¶þú°³²°`üwBý¾‰û fýšL…` ©@H      B  IE ôÄüÄ91/<ä290KSXííííííííY"² ]@ fivy  :4 ZV ]] # # 3 ^þo¸Õþ¸þ¹Õ¸þoÌ)'`ýèý¸Áþ?Hþk•hþV` @E       B  ŒÃ IEôìÄ91ä2ôì9990KSXííííí9íY"²8]@v  &&8IIY ]]+532673 3Z.Gc".Š\”mQ\GþOÃLGÃhu¿þø:NNš^ÄNü”lËb X@B¶Â¶IE ôÄì2991/ìôì0KSXííY"²8]@68EJWXejuz ]!!!5!ã-ý}ƒü»ƒý•b¨üÜ–ª%Ýþ²ô$f@5 %   ! ¶ ¶Æ Ƕµ% $  = %Ô<Äü<Ä299999991üìäôìî99999990#"&554&##5326554633#"3ô@ù©kŒ>>j©ù@FŒU[noZUŒ¾”Ýï—tr–ðÝ“WŽøŽŽœøVþ¾·µÔì1üÌ0#¾¬øÝþ²ô$j@7%   ¶¶#ÆÇ¶µ%#= %Ô<Ä2ü<Ä99999991üìäôìî9999999032655467&&554&##53233#"##ÝDVZon[VD>ù¨k@@k¨ù>¾XøœŽŽøX“Ýð–rt—ïÝ”Xìy &@    'üÄ1Ôü<Ôì2990#"'&'&&#"56632326yKOZq Mg3OIN’S5dJ t]F‰ ®;73 !;?®<6 7=ÿÿ%¬N'$u%¬m !Á@W % %%% %!%! %!! % !B  — È É  !  PPK/K!"Üäüäî2î299999991/<ææÖîî9990KSXííííííííY"²€]@… ŠŠ… € €€]]4&#"326!.54632#!#Y?@WX??Y˜Õªþ”:A rr¡@;¬ÑnýõlÑZ?YWA?XXüýP!yIr¡¡rIv$ú‰…þ{ÿÿ‹þu1ð'&ÝdÿÿÅNk'(uÿÿ‹F^'1ÿîuÿÿuÿã\N'2uÿÿ“ÿã=N'8uÿÿ…ÿã#f'Dÿÿ…ÿã#f'DCÿÿ…ÿã#f'D×ÿÿ…ÿã#'DŽÿÿ…ÿã#7'DØÿÿ…ÿã#'DÜÿÿÃþu%{'FÝhÿÿ{ÿãXf'Hÿÿ{ÿãXf'HCÿÿ{ÿãXf'H×ÿÿ{ÿãX'HŽÿÿ²Df'Öÿÿ²Df'ÖCÿÿ²Df'Ö×ÿÿ²D'ÖŽÿÿÃ7'QØÿÿ‰ÿãHf'Rÿÿ‰ÿãHf'RCÿÿ‰ÿãHf'R×ÿÿ‰ÿãH'RŽÿÿ‰ÿãH7'RØÿÿÃÿãf'XÿÿÃÿãf'XCÿÿÃÿãf'X×ÿÿÃÿã'XŽ¢ÿ;/Õ '@Ë ˆÊ RQ R Ô<ìü<ì1äôÔ<ì203!!#!5!±nþ’±þ’nÕþ\™û£]™+u¦ð @Ì ÍÌ–STS Ôìüì1ôìüì02#"&546"32654&hAu,-/º†‡´¸…OomOPqpð1.-rB„·´‡†ºoPPlnNOpÕþÇ%˜!N@*‹ ‹Ë ˾ ™ " E"ôìÔ<Ô<<ì221Ää2ô<Äìþôîõî990&&'667#&5473%C‚??ƒBI‚9gáþüÞg9‚þÞ„  5¬(,üš-(¬"þâ9ûú=þá"ü+` 츸ë‹Xð>@  ¶ ‹§—– — Ô<ÄÄü<ÄÔÄ1/ì2ôìôìÔ<î2990&&#"!!!!53#5354632D>C†sþü3ìÇÇÛßA‰¶¸,,³ÀÙþ/ªªÑîþúÇÿ= ð2>j@<#$93 $*ÎÏÎÏ0–?#=÷><¶¤''PGZswšeZŒ54m@ލ¤''TLf{x™f[1,pE‚ŸýÕ-Z/L‡…-Z/Lˆ?Ñ‘! · Ð V Ôì1Ôä04632#"&?¬}|­®}|«ú|«¬{|­«jÿ;Õ #@ˆWW1 ÜüüÔì91Ä2ôÄÌ0!###&&54$FÀ¿×ìÕùfùáNݸ¾è¼ÿã}/V@1-'!  *‹Œ*Œ›™.  !' $'$-DF0ôìüÌÆîÔîî99991/äþîþÕî9904632#"&'532654&''&&5467&&#"#¼ÒØÌÒ›¨7C:—oàÄE‡BL…;l€AxC\[¢œyqyr»qÕÎÝØ|d1M*%]¤tš²¤aQG_J'8…O€«#krƒ‹û“}ÑN4L…@I  ] ] B  ×× ÖAÔ)Õ5Ô)ÓÑM  \\ [G#X;#Y//æþåþõÄîî299991ôìüäþí2îÖî9990KSXíí9Y"2#'&&####32654&2#"&'&&546766"32676654&'&&X“XP:&rk1=-7‚èffZJJDÚZZ\[[[Ú~}Ú[[[\ZZÚ~jµKKMMKLµijµLLKLKKµLbeG]C;º®P*þضTè6?>5VZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZgJKK¸jh·KLLLLLµij¸KKJ}ÑN1ID@' Ú ÚÜ&Ô>ÚÚÙÔ>Ó2ÑJ\ ^,8 8YD/æþÅþå2î1ôìüôìÔìþýîÖî0&&#"3267#"&54632'"32676654&'&&'2#"&'&&546766`:o:u‡Œ‚8g24r=´Ïг=rÄjµKKMMKLµijµLLKLKKµkÚZZ\[[[Ú~}Ú[[[\ZZÚ/l•€„ŽhȬ­Ê¡JKK¸jh·KLLLLLµij¸KKJgZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZ“fÕh@6    B  × ˆ  ` `_`_/üþìÕîÖî91ô<<ì2Ô<<Ä90KSXÉÉÉÉY"###5!3###¶¢r¢´‰}¬rœ7¦qÕ^þä^ÿý¾âþÓ-þBÛîºf1@ º¹<Ôì1ôì0K°TK° T[X½ÿÀ@878Y3#ôÆþ»šfþˆ?F‘\@ÞÝaaÔüÔì1ô<ì20K° TK° T[K°T[X½@ÿÀ878YK° TK°T[X½ÿÀ@878Y3#%3#?ËˈÊÊÊÊÊX%yÝ<@       Ô<Ä291Ô<Ä2ü<Äþ<Ä990!3!!!'7#5!7!X‡ö}¤Ëþ²¸ýyø}¤ÉJ¸ýþ¢;fÕªì¬þÅhÓ¬ìœÕg@7 % %%%B— ——ˆ—°±   c /Ô<î2ÖÄÄ91/<îîîôî2îî0KSXííííY"!!!!!!#!‰þ®3þÍeýáþ e¸šxÊ5ÕªþFªýãªþÕªüüÿº° +k@:+)&  *&——&–™, #* #)+262#5,üìüìÀ999999991/äôìîÀÀ9999990324&'&&#"#"&''7&5327sƒTš‡ ýÝøsVƒ»)+÷ýy´=g² %÷üs­9‹d/NZInˆ-ýËÏQUþÜþ†PeæQþþ£þzþ€QQËFüIž‡€RPÉJ)ú¨ð /7@$ á'!â á-ß0 $dd*0ÔìÔì99991ü<ì2ü<ì299032654&#"&&#"32676632#"&'#"&54632¶9[=G[TFBiË8\=G[SDCj~/“[w¬£~S€NA„U}¦„^ˆsˆd†lk€ut†c…jmvÿuÛ §Ôdƒ|kÖ¥­ÎsXy“.@ ã  ã    Ô<ì2ü<ì21/ìÔ<ìü<ì07!!!!#!5!X!ûßd½þC¨þD¼ªª“þ·ªþ´LªIVw? (@åä ( ' ü<ì2291/ìôì905!5wûß!üß!ûß¶¶L¨K¸çþ ªªXy? (@åä  (' ü<<ì291/ìôì90%%5!!X#üÝ!ûß!ûß¶êç¸þµ¨þ´Vª%¬Õ@D% % %%B ç çˆ< e e<Ô<ìì2ü<ì2ì99991/ä2Ô<ì2Ô<ì290KSXííííY"333!!!#!5!5'!53%×lkÙþ¶üþÅV‘þoËþqZþËóÕým“ýÏo—#oýô o#—oÃþTž` L@* Œ‹™Ã Â!   JF!ôìüìÄ9991ä2äô<ìüÄ9903326533267#"&'#"&'øxo¹ ! &D">K .…Y\,þT ýHŽ—ª¦ü ;8 ”OOPNLPýÕ¾ÿç-):@'! '!¸ @ * $$*ÔÌÜÌ9991äÌÜÌÎÎ9906654&#"#"&54632#"&54324&#"32JIH7$$0e´ÖþßÕ˜ËÝ¢e‚ WOmVPmmW£Kƒt,>bþÊþùþ±þFØ£Æ[àt}þþÏt{þL=î 7´  ¿ @  Ô<Ä91äôìî990!!55!!LñüR%ýÛšý# þÕ‰\—P_ŒüݘþL9î¹@ €€ÔìÔì1Ä2Ôì0!#!˜¡›ý•þL¢ø^øâPÿÙžL?@!  êêèì hggfôìÔìäÄ91/äôì22î99990!#3267#"&5!##P117,#J%q\þT´L”ý@H?… ƒ°¬üH¸þL%1¹ ² ½@ & ‚&Ôìüì1üìÜäÞä026732#"&'&&#"#"&54632‰j ¾ÊPd@7*9  k½ÄOeD=!0 þú°l9¼TA6?&#Hý•Ánþ!þbSA8?TÕÁð %)d@6  (ó&í&ñí  ïîíð#–*& (' j kji*üìÄüì22ÀÀ9991ôäüôìÄîíÖîî99990"326557#5#"&5463354&#"56632!!¬|WHiƒ1ƒR–»¬¶wu3}CD‡?¸¬ýkœýdPDN@Ms=þ@pABˆtŒZ\#!¬ý {ôÕÝð 3@óñíðí –  jkjiüìüì991ôìôìüì0"32654&'2#"&546!!hfssfeusgªËÊ«ªÊË«¤ý\{œ‹‹šˆ‹œu༻ßß»¼àü`{J‡´>@#ø÷ùqqro prol ôìäôìäää991/<î2öî0353&5323!5654#"Jõ{n ðò!o{øþ1x†´šš³†x¬† ¼7oþ’þȼþß…¬¬LIÞæ þ÷æÞþ·L¬)ÿã°{ C@I=70 6 %C ‹Œ"7‹6¿. ¶Á3Œ@:¾("™D%=/.M/u MCM6+sDôÄìüìÄüÄì29991ä2ô<ì2ô<ì2ôîþ<ôî999990@ 05060708]5#"32654&#"!3267#"&'#"&546;54&#"5>32>321©xYS\JíMWWLëþepO27„Gn• '…aœ£È¿uc^8„>M„<[|%!„Y®‘ºHZqYa…4—…ˆ+#"¡33¬)+RNPP¬¤«³Xx€+'¨#!?@=BíþÎ/ÿ –¼ +s@>+,&  )&  *&Œ& Œ¾&™,+,* # )#D>,ôìüìÀ999999991äôìîÀÀ9999999032654&'&&#"&&5327#"&''mþ1$eA H#cC‹•‹')öédž<“]¤*,öêg9 \ ýÑ//ÛÕ4o¯0.ÖÊ0tG GÃq.78°MÃBÁzþáþÓ;<ºLÁÿåÝÕ!%‚@G  %%B!‹ "†$ —™$ˆ&# # )"#&ÔüÄÔìÖî99991äôìþÍôî9990KSXí9í9Y"33267#"&546776654565#53%¾=TZ>/ƒmN²b^¿hºÝC^XC&ÄÊÊDšb‰RY;X1YnED¼98À¡Lƒ\V@T?þÏÕ @†ˆ Ô<ì2991/ôüÌ0533ËË¡×þþû)eþ›ýqXsy^@  'üÔì1ÔÄì0!#!X!¨ü‡^þ?;ÿÙ   /@     ÔÄ991ÔÄÀÀ90'%3##d)#ÛÓ”/þöÝ}bý%¿ƒù¼9þV°#ˆ@N   B   ¶ú¶ú¶!›$  /Ì91Ä2Äüìôìîöîî299990KSXíí9í9íY"&&#"!!#"&'53267#5!6632°$R,fs-/þ¸d+Ǻ9f.1d0`yuü1Æ”1cð¤|‚þÉý…þöæ¤!–—¯J±ÉX1yÃ7K@&' 10+5    *  5' .810*8Ô<Ä2991Ô<ìÔì2Ü<üÔ<ì99990#"'&'&&#"56632326#"'&'&&#"566323326yKOZq Mg3OIN’S5dK t]F‰JKOZq Sc1NJO’R`‚ t]DŠï;73 ";@®<7  6<þа;83 $77 7=ÿúÙO@*iiiiBùûÔÌ91/äì90KSXííííY"#3 !ÑýþáúqÃûéw# /@  ü¬  v vÔü<Ôì2991ô<ì299055LþÓ-þ+›þÓ-þ+#¿þôþô¿¢R¢¿þôþô¿¢RÁ\# /@  ü¬ vv Ô<üÔ<ì991ô<ì29905%5‡Õþ+-þÓþ:Õþ+-þÓ#þ^Rþ^¿  ¿þ^Rþ^¿  P1 #@¢   ÔüÔìÔì1/<<ì2203#3#3#Püü3üüþfüü1þÏ1þÏ1þÏÿÿ%¬k'$uÿÿ%¬^'$uÿÿuÿã\^'2uHÁÕ;@—  —ˆ— ±  -ÜìüÄÄÔì299991/ìì2ôì2î0%! !!!!!"33Áý£þÙõô(RþšHþ¸þþ±‹‹±=ªªMœ¡KªþFªýãæþ¤þ¦åÿãº{ 8i@92/ & 8 ‹ ¶ Œ#ÁŒ5/¾)#™92& MuMCM,s9ôìüìÄüì29991ä2ô<ì2äî2îôî9999904654&#"265&#"!3267#"&'#"326632PVWMþ¦fRPhgPP¬þcpPƒ/;}Jb“04€T½ªª½Y€/%‚W¯‘ & ‘‡‰ž+ýê¨ï#®§þóþó§‡T£53¬+)CBDA88>A>AíþÎìÑy¶¶ý/Æ1üì0!!Ñû/yìÑyµ¶/Ä1Ôì0!!Ñû/yÓÇþ %@£ µ  ÔÌÔìÔüÔÌ1ü<ì20#53#53œüÄšbþ5þÇ™bÇÏ~þ‚ÏÏ~þ‚ÓÇü '@ £µ  ÔìÔìÔÌÔÎ1ü<ì203#%3#üÅ™bþ5üÄšbÎþÎÎþÏÇ-@ £µÔüÔÌ1üì0#53ËüÄšbÇÏ~þ‚ÏÇ-@ £µÔìÔÌ1üì03#1üÅ™bÎþX–yo '@þþ  w Ô<Äü<Ä1ÔÄüÔìî03#3#!!îõõõõþj!ûß‹õÙö¢ªuþ#\u"@ÔÌ91ÔÌ990 hþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿhþV'\Žÿÿ%¬N'<ufÿB7Õ@ ˆÔìÔì1ôÄ03#y¾üî¿ÕùmÍÃLB /@ (-  * -'! ÿ¸@'ÿ) -0)$ !'$* xyx( $0ÔÄ2ìüÄ2ì9999999991ÔÄ2ìüÄ2ì99999999904&#"3267'#"&''7&&5467'76632d|[Z}}Z[|¦Z¦¨^¦.[20`0¤\¦¨^¦.[3.^ƒZ{{Z\}~t¦]¦1]02[-¦^§£Z¦3].2]-¦_¨Z/#@ ü¬vÔì291ôì905/þÓ-þ+#¿þôþô¿¢R¤y#@ ü¬vÔ<ì91ôì905¤Õþ+-þÓ#þ^Rþ^¿  #7N@* ¶ ŒÄ››      JEEô<äì2ü<Äî2991/<æìþîîî299903#'#"!#!##535463¸¸w´cM“¸þ%¸ÉÉ©³éë™Qgeû¢Ñü/ÑN¸®#7B@# ¶Œ›   JE Eô<äìü<Äî991/<æþîî29990#!"!!##5354637¸þÕcM%þÛ¸ÉÉ©³ùì{Qgeü/ÑN¸®¢ÿ;/Õ<@ËË Ê ˆR Q R Ô<<ì2ü<<ì21äôÄ2Ô<î2î20%!#!5!!5!3!!!/þ’±þ’nþ’n±nþ’nßþ\¤š™¤þ\™ýáé/å`¹µÔì1Ôì03#éüü`þÏ“þáò/²£¸¶ÔìÔÌ1üì03#öüÅšc/ÏþÓþáü/ *´ £¸@  ÔìÔìÔÌÔÎ1ü<ì203#%3#üÅ™bþ5üÄšb/ÏþÏÏþј'3?Kt@%1= ÈÈ1¸µ%È+‘C¸@&7ÈIF:4(:PFz4P@ PzP"P.zP@(/ÄìÄôìîöîîöî99991/<î2î2öîþîî299990'32654&#"4632#"&32654&#"4632#"&32654&#"4632#"&H%'üH_EDbcCE_y¥xx¦§wy¤LaEEacCEay¦yx¦¦xy¦ aEF`bDEay¦yx§§xy¦7aŸ`ýJGacECcaEy¥¦xy¨¦ÓEaaECcaEx§§xy¨§ý"GaaGCcaEx¦¦xy¨§ÿÿ%¬m'$uÿÿÅNm'(uÿÿ%¬k'$uÿÿÅNN'(uÿÿÅNk'(uÿÿÉk',uÿÿÉm',uÿÿÉN',uÿÿÉk',uÿÿuÿã\k'2uÿÿuÿã\m'2uÿÿuÿã\k'2uÿÿ“ÿã=k'8uÿÿ“ÿã=m'8uÿÿ“ÿã=k'8u²D` "@¶Â¶LLK Ôäìüì1/ì2ôì0!!!5!!×münmþá`ü/B)î¨f7@ º¹ Ôì91ôì290K° TK°T[X½ÿÀ@878Y3#'#“ö‹µ´‹fþˆõõ²7»@!  ÌÌ PPÔìÔì99991Ô<üÔ<ì99990K° TK° T[X½ÿÀ@878YK°TX½@ÿÀ878Y@?       ]'.#"#>3232673#"&d9!&$|f['@%9! '$}f['@Z7JQ†”!7JQ†”=b“ö¶¶ÔÌ1Ôì0!!=Výªö”/)¢H 8¹ @ ¹PPÔìÜì1ô<Ôì0K° TX½ÿÀ@878Y332673#"&/w `WU`w ž‘žHLJJLDÏ6@ ÞÝaÔì1ôì0K° TK° T[K°T[X½@ÿÀ878Y3#ÍÍÌVá{ W²È ¸@ È P{PÔìôì1Ôìôì0K° TK° T[X½ÿÀ@878YK° TX½@ÿÀ878Y#"&546324&#"326{ŸtsŸŸstŸ{X@@WW@@Xôs  ssŸŸs?XW@AWX‹þu)'³  º@ |ÔìÔÌÄ1/öþÅ90!#"&'532654&'¼85xv-W,"K/:=,,>i0Y[ ƒ0.W=XîfZ@º¹ÔÜÔÌ991ô<ì20K° TK°T[X½ÿÀ@878YK° TX½@ÿÀ878Y3#3#ªà‰ ³ø‡fþˆxþˆ¤þu"³  ¸@  |ÔìÄÔÌ1/ÔüÄ90!33267#"&546w-+76 >&Dzs5=X..… W]0i)î¨f7@ º¹ Ôì91ô<ì90K° TK°T[X½ÿÀ@878Y373ö‹´µ‹öîxõõþˆÿösÕ 7@ —ˆ  1 4ü<ìì2.9991/äì903%!!'7×Ë;NþwÑüd‘PáÕý˜Ûoþîýãª;jnžL >@!  ¶Å¶  Ô<Ìü<Ì2999991/ìüì999033#"&5'!5!%[Y×饵þÕP{þÙß;Pþu–|~œÔÂ$Ño/ý¾Ûnþíÿÿ‹ÿãJm'6uÿÿÕÿãf'Vàÿÿœ‘m'=uÿÿËf']àþ¢¾˜!¼·Ô<ì21ÔìÔì0##¾¬¬¬˜ý öüý öNÕ ;@!¶ —ˆ —  21 0 0ü<ì2ìüìÄ91/Æ2îöîî20 !!#5326&!#!!´VDþ»þ«þÑ}}/ÿÊÉÿ`þøÕþ”þ€þ‚þ•Å•{úÑûHKûþ+•ýá‰ÿãH)‹@O BŒ $Œ™ ›*'! !'D! >*ôìüì9999991ìÌôìî99990KSXííí9íY"#"32&&''7'3%&&#"32654&ÍŶûåäûûà"#!H&þéí¶Û!!®#R-’™”ˆ‰”:/Ôþ„ÈþôþØ(  (-Y,\bPÈ‘^bþ ÒÇÄÔÔÄnËÿÿ%¬k'<uÿÿhþVf'\ÉÕ4µ—— ¸@ ˆ 28  3üì22üì99991/ôüìÔì032654&#33 !##“êžžþLÊþøøþüþÊ!ý󄃃ƒ´þòÒÚÛÑþ‘¾þVT3@ŒŒ™¾ÃÅ GFôì22üì1ìääôìî990%#36632#"&4&#"326w¹¹.™dËçèÊf™ð‡…†ŠŠ†…‡ýÉÉý²SWþÆþêþïþÉWõÖÚÛÕÔÜÚX-y×¶ ÔÄ1Ôì0!!X!ûßת–®;T .@     Ô<Ì91Ô<Ì2907–^þ¢t^_tþ¢\tþ£þ¤%\^uþ¢^uþ¢þ¤w^þ¢Xœ“ß 9A      @ – aW}a Ôììüì1ôìäÔìî2035733!jÍßåŠÌý× c)t'ý+nBœ}ða@WWBA     @–ÔÄÔÄì9991ôìäÔìî990KSXí9íY"!!576654&#"56632ãšýÅçeQdR1q?Ay;ެJwrnâaz3=L$$}…k9wuFœð(\A          @#–) & )ÔÄÄÔìÔì991ôìäôìîÆöîî90#"&'532654&##532654&#"56632Û^c¾±:r;Eq-evnmBJ]b`W,p;Eu2‘¨X`lP|†yQDJLl?<8?yvcG]ÿÿþòZ{'ðþþœ'  ¸üVÿÿþòZ{'ðþþœ' ñÉüVÿÿþòZŒ'òÿœ'  ¸üVÿÿfÿãPm'* uÿÿ{þHH'JÚÿÿÉP', uÿÿ‹þuJð'6ÝÿÿÕþu{'VÝÿÿ‹ÿã1k'&ZuÿÿÃÿã%f'FZÿÿ‹ÿã1m'&ZuÿÿÃÿã%f'FàZ{ÿãÑ$H@ "ç ¸ @"ŒŒ™¾›   GH%ôìü<Äü<Ä1/ìäôìîý<î2990!5!533##5#"3232654&#"ZþÏ1¸¿¿¸.™dËéêÊešþˆ……‹‹……ˆÑ5y••yúúSW;7Wþ ÖÚÜÔÕÛÚdßmƒ¶ ÔÄ1Ôì0!!d ý÷ƒ¤é/å`¹µÔì1Ôì03#éüü`þÏ%ÿã%ð3p@< ç1&ç³ ²—(#³² —–#™43('1)-&- 2'-4ÔÄÄ2ìÄ2Ä99999999991äôìôìÆ2îöîî2Õ<î2032&&#"!!!!3267#"#73&'&54767#7Ó0ßT“JBŸN’®á1þFi1þÓ®“OCH”Uâþí,®1u¦1´!(*Ï=DÐÌl-.&nËÑC>Ï*( n -/ l?‘ÙQ@ ÞaaÔüÔì1Ô<ì20K°TX½@ÿÀ878YK°TK° T[X½ÿÀ@878Y3#%3#?ËˈÊÊÙËËËÛîZökµÔÄ1ÔÄ0K° TX½ÿÀ@878YK°TX½@ÿÀ878Y@&  //// //]]3# ºåšöþø²éÑ@ Ì Ì ÔÄÔÄ99991Ô<üÔ<ì990K°TK°T[X½@ÿÀ878Y@t        !      ]]'.#"#4632326=3#"&d9 #(}gU$=19#(}fT"<9! 2-ev 3)dwyîööiµÔÄ1ÔÄ0K° TX½ÿÀ@878YK°TX½@ÿÀ878YK°TX½@ÿÀ878Y@ //]#1Åšãöþø7îšø]@ ÔÄ91Ô<Ä90K° TX½ÿÀ@878YK°TX½@ÿÀ878Y@ //, ]3#'# ½ÓŒ¦¥Œøþö²²7îšøi@ ÔÄ91ÔÄ290K°TX½@ÿÀ878YK° TX½ÿÀ@878Y@ //*//]373 ÓŒ¥¦ŒÓî ²²þöøZj@ ÔÄ991ÔÜÔÌ0'3$øll œß 5³ ¸ ²º @  W ÔÔ<Äì291ôôÔ<ì29033##5!5!w¢ttŠþ}ƒþîßýæoººy“þc/¢ø ²¸@ PPÔìÔì1ÔüÄ20332673#"&/w dRSaw Ÿžø6978w{zÏÛ·ÞaÔì1Ôì03#ÍÍÛÍ  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•ÑhÑÑÑÑRÑѾÑ!Ñ9ÑѪÑ\ѦÑXÑ“ÑdÑéÑfÑ…ÑöјщÑfÑÑ…Ñ‹уÑÑéÑ“ÑXÑXÑXÑôÑÑ%ѦÑ‹щÑÅÑéÑfщÑÉÑmщÑ×ÑVÑ‹ÑuÑÅÑuÑÑ‹Ñ/Ñ“Ñ9ÑÑÑ%ÑœÑÏÑfÑZÑHÑÑÑ…ÑÁÑÃÑ{Ñ{ÑÃÑ{ÑÃѲѺÑìÑ ÑmÑÃщѾщÑjÑÕуÑÃÑdÑÑLÑhÑËÑÝÑÑÝÑXÑ%Ñ%Ñ‹ÑÅÑ‹ÑuѓххххххÑÃÑ{Ñ{Ñ{Ñ{ѲѲѲѲÑÃщщщщщÑÃÑÃÑÃÑÃÑ¢Ñ+ÑÕÑ‹ÑÇÑ?ÑjѼÑÑÑÑÛÑ?ÑXÑÑÑ)ÑXÑVÑXÑ%ÑÃѾÑјÑPÑÑÑôÑJÑ)Ñ/ÑÁÑÑXÑ;ÑÑXÑÿúÑwÑÁÑPÑÑ%Ñ%ÑuÑHÑÑÑÑÓÑÓÑÏÑÏÑXÑuÑhÑ%ÑfÑÍÑZѤÑ#Ñ#Ñ¢ÑéÑ“ÑÓÑÑ%ÑÅÑ%ÑÅÑÅÑÉÑÉÑÉÑÉÑuÑuÑuѓѓѓѲÑ)ÑÑ=Ñ/ÑÑVÑ‹ÑXѤÑ)ÑÿöÑLÑ‹ÑÕÑœÑËÑÑщÑ%ÑhÑÉѾÑXÑ–ÑXÑBÑFÑÑÑÑfÑ{ÑÉÑ‹ÑÕÑ‹ÑÃÑ‹ÑÃÑ{ÑdÑéÑ%Ñ?ÑÛÑÑyÑ7Ñ7ÑÑ Ñ/Ñÿ+   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ      sfthyphenperiodcenteredEuroc6459c6460c6461c6468c6470c6472c6477c6478c6475c6476%%%%KmËJÍz‘½é6b•ªÄ‡² i§õP~çAbŒ²Ó÷jô \ ° õ . [ ‚ Ó þ ) ^ Å á A Î  [ Á?`§ámï2l©Êì)žæ*rÆdœÐ ‰µO†Â T›JÇláV™þ|¼Écp}Š—¤±¾ËØåòÿ &3@MZgtŽ›¨µÂÏÜéP²ûŒ¬ÙJþ ‹ å! !M!!ê"l"Î##3#a#Ë$#$€$·$Ú% %u%æ&-&€'('©(#(J(f(—))Ž)Ë**A*m*m*z*‡*”*à+k+€+”+Á+ï, ,),V,€,,š,´-?-`-ƒ-Ò..W.o..½/e/r//Œ/™/¦/³/À/Í/Ú/ç/ô0000(0O0|111S1{1Í22C2t2¢2Û3"3/3<3I3V3{3É4S4`4m4­4ö5 5E5x5Ñ696J6[6l6y6†6“6 6­6º6Ç6Ô6á7>7T7l7ô8/8r99K9‹9Ò9í:$:N:d MF@WmþÑÿöÿøÙ ÑGÌþBGÌSf  €¯ JBits@ ûþšmãB¹Ñ`#cÕVeraSansMonoÿÿÿÿ6ÿÿþ628R00@             ÿÿ䥉ë_<õºÀÂlÿöþÙmloganalyzer-3.6.5/src/BitstreamVeraFonts/Vera.ttf0000644000175000017500000020061412225176641021324 0ustar danieldanielOS/2´_ôcëpVPCLTÑŠ^—ëÈ6cmap¤Ãè ±lXcvt ÿÓ9üüfpgmç´ñÄ&`‹gaspH glyf tAÏ&ìŠ~hdmx4ð!ìHheadÝ„¢ÐT6hheaEoëL$hmtx ÆŽ²´Ä0kernÜRÕ™½ -ŠlocaóËÒ=»„maxpG:ë, nameټȵßpost´Z/»¸ôŽprep;ñ øh::_:: dM0­l  ƒ p t › &   Y &  &   c . 5 ` õ s 0¡ & {Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera SansBitstreamVeraSans-RomanRelease 1.10Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera SansBitstreamVeraSans-RomanRelease 1.10Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com5¸ËËÁªœ¦¸fqË ²…u¸Ãˉ-˦ðÓª‡ËªJ3ËÙôT´œ99N´R¸çÍ7sÍ`s3¢V¦V9Åɸßsºé3¼Dßͪåªˤ{¸o{RÇÍššoËÍžÓðºƒÕ˜HžÕÁËöƒT3fÓǤ͚sÕ þ+¤´œbœ-ÕÕÕð{T¤¸#Ӹ˦Ãì“ Ó\qÛ…#¨H99`Õš#fy```{œw`ªé`b{Å{´RÍf¼fwÍ;…‰{ÍJ/œœ}oo5jo{®²-–{öƒT7öœáföÍD)fîs¸€@ÿûþúù%ø2÷–öõþôþó%òñ–ð%ïŠAïþî–í–ìúëúêþé:èBçþæ2åäSå–äŠAäSãâ/ãúâ/áþàþß2ÞÝ–ÜþÛÚ}Ù»ØþÖŠAÖ}ÕÔGÕ}ÔGÓÒÓþÒÑþÐþÏþÎþÍ–ÌËÌþËÊ2ÉþÆ…ÆÅÄþÃþÂþÁþÀþ¿þ¾þ½þ¼þ»þº¹†%¹þ¸·»¸þ·¶]·»·€¶µ%¶]@ÿ¶@µ%´þ³–²þ±þ°þ¯þ®d­¬«%¬d«ª«%ª©ŠA©ú¨þ§þ¦þ¥¤þ£¢£2¢¡d ŠA –Ÿþž žþ œ›œd›š›š™ ˜þ—– —þ– •ŠA•–”“”(“’ú‘»‘þ]»€Ž%]@Ž%þŒ‹.Œþ‹.І%ŠA‰ˆ ‰ˆ ‡†%‡d†…†%…„þƒ‚ƒþ‚þ€þþ@ÿ~}}~þ}}|d{T{%zþyþxw v uþtúsúrúqúpþoþnþl!kþjBjSiþh}gBfþeþdþcþbþa:`ú^ ]þ[þZþYX YúX WW2VþUTUBTSSRQJQþP OþNMNþMLþKJKþJIJI IH GþF–E–DþC-CúB»AK@þ?þ>=>=<=<; <@ÿ; :þ9þ878ú76765 65 43 21 2þ1 0/ 0 / .- .- ,2+*%+d*)*%)('%(A'%&% &% $þ#þ"!! dú d BþúBBþdþþþþBþ-B}dþ  þ   þ  þ-þdþ@-þ-þ¸d…++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX °ýEDY!-,°%E`D-,KSX°%°%EDY!!-,ED-fþ–f¤@ ûû/ÄÔì1ÔìÔì0!%!!füsüåþ–øòr)5Õ @@ƒ ü<ì2991/äüÌ0K° TX½ @ ÿÀ878Y¶ P ]%3#3#5ËËË¢þþÕýqþ›eŪéÕM@„üüÜì1ô<ì20K°TK°T[X½@ÿÀ878Y@0 @ P ` p   ¿ ]#!#oª$ªÕýÕ+ýÕ+ž¾`@1 ‡  ‡   üÌ91/<Ô<<ü<<Ô<<Ä2ì220@   ]!! !3!!!!#!#!5!!5!þÝT%Dh$i g8þ¡R>þ›h gþÛg¡hþÅ`Tþ¾if…þ²‡þaŸþašþ²™þbžþbž™NšŸªþÓm!(/Õ@U" '&( /)/))/B" ) *!††#Љ*Љ- ) " & 0ü<ìô<ü<ôäì1/äìÄÔäì2Äîî99990KSXíí9í9íY"K° TX½0@00ÿÀ878YK° TK°T[K°T[X½0ÿÀ00@878Y#.'5.546753.'>54&´diÒjfÑoÝÉÚÌd]®SS¯\ãÖãÖdtzqá{þÓ---´@AÈ$¬–£¼ëè¯*.þU#´œ©Ãš jXV`ÕþOnZXhqÿã)ð #'3•@6$%&%&'$'B’ ’.’$’ &Œ($‘4'!%   ! + 1 4üÄìôìîöî991ä2ô<äìîöîî0KSXííY"K° TK° T[K° T[K°T[K°T[K° T[X½4@44ÿÀ878Y"32654&'2#"&546"32654&%3#2#"&546ÑWccWUccUžº» º»ü—VcbWWcd1 üZ ž¼»ŸŸ¹º‘”„‚••‚ƒ•Ü»»ÛÛ»¼Ûa•‚„””„–ùó Û»½ÚÛ¼ºÜÿãþð 0Í@–  † †  † †††  !         B  (('•+•'”$‘Œ .  .'.'!!1üìÄÔÔìÆî99999991/ÆäöæîîÆ9990KSXíí9í9í9í9í9íí9í9ííí9Y"²2]@² " ) **&:4D ^YZ UZZY0g{›š™—• “••"™-  ' (   2'') #**(/2; 49?2J LKFO2VZ Y UY\_2j i`2uy z““—•œœŸš › š 2 2°29]]3267 >73#'#"5467.54632.#"ò[UÔ _¦Iþ{ü;Bº h]ühäƒñþΆ†02Þ¸S¥UWžDiƒ;#Q¡X’Â?@ýøYËr„þþ~þã“YW×€ác?}<¢Å$$¶/1oX3gŪoÕB@ „üì1ôì0K°TK°T[X½@ÿÀ878Y@ @P`p ]#oªÕýÕ+°þò{ O@˜—  Üä2ì991üì0K°TX½@ÿÀ878YK°TX½ÿÀ@878Y#&547{†‚ƒ… –•”—æþ>ççþ;åëÆàßÄì¤þòo @˜— Ü<ôì991üì03#654¤ –••– …ƒƒìþ<ßàþ:ëåÅççÂ=JÃðN@,  ™ ™ ‘    Ô<ä2Ü<ä2991ôÔ<ì2Äì2990%#'%%73%Ãþ™g:þ°rþ°:gþ™:PrPßÂÃbËþ‡yËbÃÂcËyþ‡ËÙÛ #@ œ  Üü<ü<ì1/Ô<ü<Ä0!!#!5!®-ýÓ¨ýÓ-ýÓªýÓ-ª-žÿÃþ@ žƒüìÔÌ1üì073#ðÓ¤Rþ¬þÀ@d߃¶œÜÌ1Ôì0!!dý僤ۮþ·ƒüì1/ì073#ÛÓÓþþÿB²Õ-@BŸ/Ä991ôì0KSXííY"3#ªýøªÕùm‡ÿãð #@   ‘Œ üìôì1äôìî0"32'2#"‹œœû þ÷ûûþ÷ PþÍþÌþÍþÍ3343 þsþ†þ‡þsyzáZÕ K@B     ÔìÄüì1/ì2ôìÔì0KSXY"K°TX½ ÿÀ @878Y´]7!5%3!!þJþ™eÊJü¤ªsH¸HúÕª–Jð¥@'B¡”  ‘   üÄÔìÀÀ91/ì2ôìôì0KSXíí9Y"K°TK°T[K°T[X½@ÿÀ878Y@2UVVzzv‡tvust‚†‚‚‚¨¨]]%!!567>54&#"5>32‰ÁüLs3aM§†_ÓxzÔXèE[þôªªªw‘:m—Iw–BCÌ12èÂ\¥pþëœÿãsð({@. † †     “  “#‘Œ£)&  )üÄÄÔìôì991ìäôäìæîîîî90K°TK°T[X½)@))ÿÀ878Y@ daa d!]!"&'532654&+532654&#"5>32?‘£þÐþè^ÇjTÈm¾Ç¹¥®¶•ž£˜S¾rsÉYæ Ž%ÄÝò%%Ã12–„•¦wps{$&´ Ѳ|«d¤Õ Œ@   B     ÜÔ<Äì291/äÔ<ì290KSXÉÉY"K° TK° T[X½@ÿÀ878Y@* *HYiwŠ+&+6NO O Vfuz… ]] !33##!5þþ5þÕÕÉý^%üãÍü3¨þ `ÞÿãdÕu@#†  ‰   Œ¤  üÄÔìÄî1ääôìæîþÄî90K°TK°T[X½@ÿÀ878YK°TX½ÿÀ@878Y!!>32!"&'532654&#"Ýý ,X,ú$þÔþï^ÃhZÀk­ÊÊ­Q¡TÕªþ’þîêñþõ Ë10¶œœ¶$&ÿã–ð $X@$ †   ¥  ‰"‘Œ% " !%üììôìä1äôäüäîîî90@ËËÍÍÍËˤ²]]"32654&.#">32# !2¤ˆŸŸˆˆŸŸ L›LÈÓ;²káþðâþýþîPL›;º¢¡»»¡¢ºy¸$&þòþïW]þïëæþêyb¥¨hÕc@B üÌÄ991/ôì0KSXííY"K°TX½@ÿÀ878Y@X9Hg°°]]!#!¨ÀýâÓþý3ÕVú+‹ÿã‹ð #/C@%  ' - ‘Œ'£0 $*$ !0üÄìôÄìîî991ìäôìîî990"32654&%&&54632#"$54632654&#"‹¥¥¦¥þ¥‚‘ÿÞßþ‘’£þ÷÷÷þ÷¤H‘ƒ‚““‚ƒ‘Åš‡‡š›†‡šV ²€³Ðг€² "ÆÙèèÙÆat‚‚tt‚‚ÿã‡ð$X@#†  ¥ ‰ ‘Œ%!"" %üìäôìì1äôìæþõîî90@ÄÂÀÀÀÂμé]]7532#"543 !"&2654&#"áLœKÈÓ:²làþûâþ±þåLœ>ˆŸŸˆˆŸŸ¸$& V\ëæþsþ†þŸþ[—º¢¡»»¡¢ºðÃ#@ƒ¦ƒü<ì21/ìôì073#3#ðÓÓÓÓþþ#þžÿÃ# %@ƒžƒ¦  ü<ì2ÔÌ1äüìî03#3#ðÓÓÓ¤R#þýÙ¬þÀ@Ù^Û¦M@*œœœœB¨§$#üì291ôì90KSXííííY" 5Ûûøúþðþ‘þ“¶ѦÑÙ`Û¢@ œœ#ü<Ä21ÔìÔì0!!!!Ùúþúþ¢¨ðªÙ^Û¦O@+œœœœB¨§$#ü<ì91ôì90KSXííííY"55Ùúþð¶þ/¦þ/¶m“°ð$p@+$  †ˆ•‘ƒ   &%ÜÄüìÔìî99991/îöþôîÍ9990K° TX½%@%%ÿÀ878Y¶y z z ]%3##546?>54&#"5>32‡ËËÅ¿8ZZ93ƒlO³a^Ág¸ßHZX/'þþ‘še‚VY5^1YnFC¼98ŸL‰VV/5<4‡þœq¢ L•@2  ©©L43¬0©7¬$©7CM34( (+(I+*(I,=MÜìüìþýþ<Æî991ÔÄüìþíÔÆÅî2Äî990K° TK° T[K°T[K°T[K°T[X½MÿÀMM@878Y@ NN/N?N]32654&#"#"&5463253>54&'&$#"3267#"$'&5476$32úŽ|{zy!<›g¬×Ø«gœ;’¥?@hþÕ°{â`±smiùhZ}þÙ˜¹þ¸€€†ˆ~R½Ôk{KOþÂþè£¤ŽŒ¥¤þHMIùÈÈúKLƒý ß±k¼Pƒ‹A@fþµÁŸþêjhmWQoagƒ}}I½¶J}‡® bæ{þùþÐhÕ º@A       B•    ÔÄ91/<äÔì90KSXííííííííY"² ]@:XvpŒ VXP ghxv|rwx‡ˆ€ ˜™–]] !3#!#¼þî%þ{å9Òˆý_ˆÕý®ú+þÉìÕ C@#• •• ­ . !üì2üìÔì9991/ììôìî90²"]!2654&#!2654&#%!2#!“D££þ¼+”‘‘”þ çú€|•¥þðûýèÉý݇‹Œ…fþ>orqp¦À±‰¢ ˘ÈÚsÿã'ð6@ ¡® •¡®•‘Œ 0üì2ì1äôìôìîöî0´].# !267# !2'fç‚ÿþð‚çfjí„þ­þz†S†íbÕ_^þÇþØþÙþÇ^_ÓHHŸghŸGɰÕ.@• •  2 üìôì99991/ìôì0²`]3 !%! )“ô5þáþËþBŸ²–þhþPþa/ûw.,¦þ—þ€þ~þ–É‹Õ .@•••­   üì2ÔÄÄ1/ììôìî0² ]!!!!!!ɰýÇý9øü>ÕªþFªýãªÉ#Õ )@••­ üì2ÔÄ1/ìôìî0² ]!!!!#ÉZýpPý°ÊÕªþHªý7sÿã‹ð9@ ••¡®•‘Œ43 üìüäüÄ1äôìôìþÔî990%!5!# !2&&# !26Ãþ¶uþæ þ¢þu‹^’opü‹þîþík¨Õ‘¦ýSU™mn™HF×_`þÎþÑþÒþÎ%É;Õ ,@•­ 8  üì2üì21/<ä2üì0²P ]3!3#!#ÉÊÞÊÊý"ÊÕýœdú+Çý9É“Õ9·¯üì1/ì0K°TX½ÿÀ@878Y@ 0@P`Ÿ]3#ÉÊÊÕú+ÿ–þf“Õ M@ •° 9 üìä991äüì990K°TX½ ÿÀ @878Y@ 0 @ P ` Ÿ ]3+53265ÉÊÍãM?†nÕú“þòôª–ÂÉjÕ ï@(B¯  üì2ÔÄ91/<ì290KSXííííY"²]@’ ((764GFCUgvwƒˆ”›ç    (+*66650 A@E@@@ b`hgwp ‹‹Ž š¶µÅÅ×Öèéèê÷øù,]q]q3! !#ÉÊžýþöý3ÊÕý‰wýHüãÏý1ÉjÕ%@ •:üìì1/äì0@ 0P€€]3!!ÉÊ×ü_ÕúÕªÉÕ ¿@4  B ¯   >  üìüì91/<Äì290KSXííííY"²p]@V   && & 45 i|{y €‚‚  #,'( 4<VY ej vy •›]]! !###É-}-ÅþËþÄÕüøú+üúáÉ3Õ y@B¯6 üìüì991/<ì2990KSXííY"² ]@068HGif€ FIWXeiy…Š•šŸ ]]!3!#É–ÄþðýjÄÕûáú+áûsÿãÙð #@•• ‘Œ 3üìüì1äôìî0"32' ! 'ÜþýÜÜþÿÜ:xþˆþÆþÅþ‡yLþ¸þåþæþ¸HH¤þ[þžþŸþ[¤bb¥ÉÕ:@••   ? üì2üì91/ôìÔì0@ ?_¯]32654&#%!2+#“þššþ8ÈûþÿûþÊ/ýÏ’‡†’¦ãÛÝâý¨sþøÙð R@*  B ••‘Œ    3üìüì9991Ääôìî990KSXíí9Y""32#'# ! 'ÜþýÜÜþÿ? ôÝ!#þÅþ‡y;:xÑLþ¸þåþæþ¸HHúÏþÝï¥ab¥þ[þžþüþŽÉTÕ±@5  B• •   ?  üì2üÄì99991/<ôìÔì9990KSXíí9Y"²@]@Bz%%%&'&&& 66FFhuuwˆˆ˜˜]]#.+#! 32654&#A{>ÍÙ¿J‹xÜÊÈüƒý‰þ’••’¼~þh–bý‰ÕÖØºOýƒ…‡ÿã¢ð'~@<    B ¡”••”%‘Œ( "-"(ÜÄìüìä99991äôäìîöîÆ90KSXí9í9Y"²)]¶)/)O)].#"!"&'532654&/.54$32HsÌ_¥³w¦zâ×þÝþçjï€{ìr­¼‡š{âÊõiÚ¤Å76€vce+Ù¶Ùà0/ÐEFˆ~n|-À«Æä&ÿúéÕJ@•@@Ôäüä1/ôì20K° TX½@ÿÀ878Y@  @ p Ÿ ]!!#!ïýîËýîÕªúÕ+²ÿã)ÕK@ •Œ  8Aüìüì1ä2ôì99990K°TX½@ÿÀ878Y¶Ÿ]332653! ²Ë®Ã®ËþßþæþåþßÕüuðÓÓð‹ü\þÜþÖ*$hÕ·@'B¯ÔÄ91/ì290KSXííííY"²P]@b*GGZ}ƒ *&&))% 833<<7HEEIIGYVfiizvvyyu€˜—)]]!3 3JýÆÓÙÚÒýÇÕûéú+D¦Õ {@I      B ¯    ÔÌ91/<ì2290KSXííííííííY"²]@ò  ($ >>4 0 LMB @ Yjkg ` {|€ –•     !   # $ %  <:5306 9 ? 0FFJ@E@BBB@@ D M @@XVY Pfgab```d d d wv{xwtyywpx  †‡ˆ‰… Š —Ÿ¯[]]3 3 3# #DÌ:9ã:9Íþ‰þþÅþÂþÕûîûîú+úð=;Õ ]@F      B ¯   ÔÄÜÄ91/<ì290KSXííííííííY"K° TK° T[K°T[X½ ÿÀ @878Y@¸ '' 486 KX[fkww †€‡‹… ”—–     &()&(' ) 54<;:;4 4 8 ? H O X _ eejjhiil l xyyx}  x €€ƒˆ…„ƒ ”——•“ Ÿ ¯ @]]3 3 # #ÙsuÙþ Ùþ\þYÚÕýÕ+ý3üø{ý…ÿüçÕ”@(B¯@@ Ôäüä91/ì290KSXííííY"² ]@<5000F@@@QQQe„“ &)78@ ghxp Ÿ ]]3 3#Ùž›ÙýðËÕýšfüòý9Ç\Õ ›@B••B ÜÄÔä991/ìôì0KSXííY"K° TK° T[X½ @ ÿÀ878Y@@ )&8HGH    / 59? GJO UYfio wx Ÿ ]]!!!5!s•üPÇû=°ügÕšûoªš‘°þòXS@©²©±CÜüÌ21üìôì0K° TX½ÿÀ@878YK°TK°T[X½@ÿÀ878Y!#3!°¨ððþXùüÿB²Õ-@BŸ/Ä991ôì0KSXííY"#ªªýøÕùm“Çþòo<@©²©±Cü<Üì1üìôì0K°TK°T[X½ÿÀ@878Y!53#5oþXïïøÞÙ¨ÛÕ@ ÜÌ91ôÌ290##¼ÉþHþHÉÕýÓ‹þu-ÿìþþ¬µ©ÄÄ1Ôì0!5ûØþ¬ªð‰f1@ ´³DÜì1ôì0K° TK°T[X½ÿÀ@878Y #o™þºfþŠv{ÿã-{ %¼@'  ©¹ †º¹#¸Œ   E&üìÌÔì22991/ÄäôüôìÆîî9990@n0000 0!0"?'@@@@ @!@"PPPP P!P"P'p'…‡‡‡ ‡!…"' 'ð'000 0!@@@ @!PPP P!``` `!ppp p!€€€ €!]]"326=7#5#"&5463!54&#"5>32¾ß¬o™¹¸¸?¼ˆ¬Ëýû§—`¶Te¾Zóð3f{bsÙ´)LýªfaÁ¢½À‹..ª''üºÿ㤠8@¹  ¹Œ¸—G Füì22ôì1/ìäôÄìÆî0¶`€ ]4&#"326>32#"&'#3å§’’§§’’§ýŽ:±{ÌÿÿÌ{±:¹¹/ËççËËççRdaþ¼þøþøþ¼ad¨qÿãç{?@†ˆ† ˆ ¹¹¸Œ HEüä2ì1äôìþôîõî0@ € ].#"3267#"!2çNP³ÆÆ³PNM¥]ýþÖ-U¢5¬++ãÍÍã++ª$$>:#qÿãZ8@¹¹Œ¸—G Eüìôì221/ìäôÄìÄî0¶`€ ]3#5#"3232654&#"¢¸¸:±|ËÿÿË|±ýǧ’’¨¨’’§¶^ùì¨daDDaþËççËËççqÿã{p@$ †ˆ©¹ »¹¸ ŒKEüìôìÄ91äôìäîîôî90@)?p Ðð?????,// , ooooo ]q]!3267# 32.#"ü² Í·jÇbcÐkþôþÇ)ü⸥ˆš¹^Z¾Ç44®*,8 CþÝÄ—´®ž/øp@ ©‡—¼    Lü<Äü<ÄÄ991/ä2üìî2990K° TX½ÿÀ@878YK°TX½@ÿÀ878Y¶@P ]#"!!##535463ø°cM/þѹ°°®½™Phcü/ÑN»«qþVZ{ (J@#  †¹¹&#¸'¼ ¹½& G E)üÄìôì221/ÄäìäôÄìþÕî990¶`*€* *]4&#"326!"&'5326=#"3253¢¥•”¥¥”•¥¸þþúa¬QQžRµ´9²|ÎüüÎ|²9¸=ÈÜÜÈÇÜÜëþâþé³,*½¿[cb::bcªºd4@ ‡¸ — N  Füì2ôì1/<ìôÄì90²`]#4&#"#3>32d¸||•¬¹¹B³uÁƤý\žŸž¾¤ý‡ýžedïÁy+@¾±¼Fü<ì21/äüì0@  @ P ` p ]3#3#Á¸¸¸¸`û éÿÛþVy D@ ¾ ‡½¼ ±O  Fü<ì2ä991ìäôìî990@ @P`p]3+532653#Á¸£µF1iL¸¸`ûŒÖÀœa™(麜 ¼@)B¼— F üì2ÔÄ91/<ìä90KSXííííY"² ]@_ ')+Vfgsw‚‰Ž“–—£    ('(++@ h` ‰…‰š—ª§¶ÅÖ÷ð÷ð]q]33 ##º¹%ëý®kðýǹüiãýôý¬#ýÝÁy"·—Füì1/ì0@ @P`pð]3#Á¸¸ùìº{"Z@&  ‡ ¸¼PPF#üì2üüüì91/<<äô<Äì290@0$P$p$$ $ $¿$ß$ÿ$ ]>32#4&#"#4&#"#3>32)EÀ‚¯¾¹ru¦¹rw¦¹¹?°yz«‰|võâý\ž¡œ¾¤ý‡ž¢›¿£ý‡`®gb|ºd{6@ ‡¸ ¼ N  Füì2ôì1/<äôÄì90´`Ï]#4&#"#3>32d¸||•¬¹¹B³uÁƤý\žŸž¾¤ý‡`®edïqÿãu{ J@¹¹ ¸Œ QEüìôì1äôìî0@#?{{   {  { ð]"32654&'2#"s”¬«•“¬¬“ðþîðñþïßçÉÉçèÈÇéœþÈþìþíþÇ98ºþV¤{>@¹¹¸Œ½¼ GFüì22ôì1äääôÄìÄî0@ `€ à]%#3>32#"&4&#"326s¹¹:±{ÌÿÿÌ{±8§’’§§’’§¨ý® ªdaþ¼þøþøþ¼aëËççËËççqþVZ{ >@¹  ¹¸Œ½¼ GEüìôì221äääôÄìÆî0@ `€ à]32654&#"#"3253#/§’’¨¨’’§s:±|ËÿÿË|±:¸¸/ËççËËççý®daDDadªùöºJ{0@  ‡¸ ¼ FüÄì21/äôìÄÔÌ90´PŸ].#"#3>32JI,œ§¹¹:º….´˾ý²`®fcoÿãÇ{'ç@<  S  SB †‰†‰¹¹%¸Œ( R"E(üÄìÔìä99991äôìþõîõî90KSXí9í9Y"²']@m   . , , , ; ; ; ; $( ( *//*(() )!$'† † † †      '/)?)_))€)) )ð)]]q.#"#"&'532654&/.54632‹N¨Z‰‰b”?Ä¥÷ØZÃlfÆa‚Œe«@«˜àÎf´?®((TT@I!*™‰œ¶##¾55YQKP%$•‚ž¬7òž8@©¼‡  Fü<Äü<Ä2991/ìô<Äì2990²¯]!!;#"&5#53w{þ…Ks½½Õ¢‡‡žþÂý ‰NšŸÒ`>®ÿãX`6@ ‡Œ ¼  NFüìôì21/ä2ôÄì90´`Ï]332653#5#"&®¸||•­¸¸C±uÁȺ¦ýaŸŸ¾¤{û ¬fcð=`@'B¿ÔÄ91/ì290KSXííííY"K° TX½ÿÀ@878YK°TK°T[X½@ÿÀ878Y@ŽHj{†€‘¤  &&)) 55::0FFIIFH@VVYYPffiigh`ut{{uz……‰‰‰†––—š˜˜—¨§°Àßÿ>]]3 3#=Ã^^Ãþ\ú`üT¬û V5` @IU U U U   B ¿    ÔÌ91/<ì2290KSXííííííííY"K° TK°T[K°T[K°T[K° T[X½ ÿÀ @878YK° TK° T[K°T[X½ @ ÿÀ878Y@ÿ" 5 IIF @ [[U P nnf yy‡™˜” ¼¼ÎÇÏ         %%#'!%""%' $ ! # 9669 0FHF@B@@@D D D @@VVVPQRRPS T U cdejejjjn a g ouuy}x}zzxy  { v } ‡ˆ——”“œ›˜˜™@/– Ÿ¦¦¤¤««©©«¤ ¯µ±½»¸ ¿ÄÃÌÊy]]333# #V¸æåÙæå¸þÛÙñòÙ`ü–jü–jû –üj;y` Z@F      B ¿  ÔÄÔÄ91/<ì290KSXííííííííY"K° TK°T[K°T[K°T[X½ ÿÀ @878YK°TX½ @ ÿÀ878Y@˜   & =1 UWX f vzvt ‚ ™Ÿ—’ ¦©¯¥£       )&% * :9746 9 0 IFE J @ YVYYWVYVV Y P o x ›”«¤° Ï ß ÿ /]] # # 3 dþkªÙþºþºÙ³þrÙ))`ýßýÁ¸þHJþq=þV`¢@C        B  ‡½ ¼  ÔÄÄ91ä2ôì9990KSXíííííí2Y"K° TK°T[X½ÿÀ@878YK°TX½@ÿÀ878Y@ð     # 5 I O N Z Z j ‡ € “        '$$  )( % $ $ ' ** 755008 6 6 8 990A@@@@@@@@B E G II@TQQUPPVUVW W U U YYPffh ii`{xx‰Š … … ‰ ‰‰™ • • šš¤ ¤ ««°Ïßÿe]]+5326?3 3“N”|“lLT3!þ;Ã^^ÃhÈzšH†TNü”lXÛ` ´@B©¼© ÜÄ2Ä991/ìôì0KSXííY"K° TK° T[X½ @ ÿÀ878YK°TX½ ÿÀ @878Y@B&GI  + 690 @@E@@CWY_ ``f``b € ¯ ]]!!!5!qjýL´ü}´ýe`¨üÛ“¨%þ²$‚@4 %   ! © ©À ©±% $  C %Ô<Äü<Ä299999991üìÄôìî99999990K° TX½%ÿÀ%%@878Y²&]#"&=4&+5326=46;#"3>ù©lŽ==k©ù>DV[noZV¾”Ýï—ts•ðÝ“XøŽŽœøXþ®·±Ôì1üÌ0#®ªøþ²$ž@6%   ©©#À©±%#C %Ô<Ä2ü<Ä99999991üìÄôìî99999990K° TX½%@%%ÿÀ878YK°TX½%ÿÀ%%@878Y²&]326=467.=4&+532;#"+FŒUZooZUŒF?ù§lŽ>>Žl§ù?¾VøœŽŽøŽW“Ýð•st—ïÝ”ÙÓÛ1#@ œœ ÔÄ1ÔüÔìÀ990#"'&'&'&#"56632326Ûi³an’ ›^X¬bi³an“ ›^V©1²OD;>MS²OE<>LÿÿhN'$¼uhm !Ë@T   !!  ! !!!B  Á • Ž  !  VV!"ÔÄÔì2Ôî299999991/<æÖîÔî9990KSXííííííííY"² #]@  s › P#f iu {yyv v!€# ]]4&#"326!.54632#!#TY?@WX??Y˜þð!þX=>Ÿsr¡?<Òˆý_ˆÕZ?YWA?XXþóýN)sIs ¡rFv)ú‹þÿÿsþu'ð'&Ý-ÿÿÉ‹k'(žuÿÿÉ3^'1þuÿÿsÿãÙN'2'uÿÿ²ÿã)N'8îuÿÿ{ÿã-f'DRÿÿ{ÿã-f'DCRÿÿ{ÿã-f'D×Rÿÿ{ÿã-'DŽRÿÿ{ÿã-7'DØRÿÿ{ÿã-'DÜRÿÿqþuç{'FÝÿÿqÿãf'H‹ÿÿqÿãf'HC‹ÿÿqÿãf'H׋ÿÿqÿã'HŽ‹ÿÿof'ÖÿÿÿÿǦf'ÖCÿÿÿÿÞ\f'Ö×ÿÿÿÿôF'ÖŽÿÿÿºd7'Qؘÿÿqÿãuf'Rsÿÿqÿãuf'RCsÿÿqÿãuf'R×sÿÿqÿãu'RŽsÿÿqÿãu7'RØsÿÿ®ÿãXf'X{ÿÿ®ÿãXf'XC{ÿÿ®ÿãXf'X×{ÿÿ®ÿãX'XŽ{9ÿ;ÇÕ '@¹  YW Y Ô<ìü<ì1äôÔ<ì203!!#!5!¨°oþ‘°þ‘oÕþ\™û£]™Ãu=ð  @ÃÄà ‘ Z[ZÜìüì1ôìüì0"32654&'2#"&546PnnPPnoO@v+..¹†‡´¸ooPOmmOOp1.-rB„·´‡†º¬þÇ#˜!Q@+  †ˆ †ˆ ¹ ¹¸Œ"  "ÜìÔ<Ô<<ì221äô<ÄìÄþôîõî9990%&&'667#&73¦“¤¤JˆDF‰HA‰Mfñþ÷ ñfI‰ƒX⸹⡬)*ü *'ª#þä 32þá!bð`@!† ©  ”‘   Ü<ÌÌü<ÄÔÄ1/ì2ôäìÔ<î2î990K° TX½ÿÀ@878Y´66].#"!!!!53#535632NLˆ=”t‡þy-üìÇÇÖè=—´¶))›Ô×þ/ªªÑîó\ÿ=¢ð >‘@54&.#"#"&'532654/.5467.54632{?>‹ú?>ÌS8alÎÓƒ\]>9Ì­IšXW”:fqÝÖ€][;;ȦI™¨.Z.L…‡-[.Kˆ“¤''PGZswšeZŒ54m@ލ¤''TLf{x™f[1,pE‚Ÿ3Ñ…! · Ç \ Ôì1Ôì04632#"&3­~|«¬}}¬ú|««|}¬¬žÿ;9Õ %@Á]] ÔÔüÜì91Ä2ôì90!###&&54$yÀ¾Ž×ëÕùfùáNݸ¾èºÿã¬/š@0-'!  *†¹*¹—Œ.  !' $'$-F0üÄüÌÆîÔîî99991/äþîþÕî990@@'(Š Š     ! "&  : :!MM I!I"jj ¥¥¦ ]]4632#"&'532654&/.5467.#"#ºïÚÐÛ—¨:A9¦`áÓ@ˆIPŒAtx;e\`W§—ƒq‚ˆ»qÈÛèàs`/Q*%jŽd¬·¤_[?T>7;‡[¬gp‹ƒû“åÍ/8L`@6EBC?2ÉH0É9JCÊ 9ÊÉÈ É$HE301BKL?gwyVpMIßÑ`3þœDåÍ/IC@&=Ë>:ÌAÊ$1Ë04ÌGÊÉÈ$É 7aD=0^* D^ JÜÌüìþí2î1/îöþýîÖîýîÖî02#"$'&5476$"32676654&'&&&&#"3267#"&54632˜mmllmmþù˜˜þùmmllmm˜ƒâ^^``^^⃄ã^]]^\^ã§B‚B•§«›@zBC‰FØûûØIˆÍnmmþúš˜þûmmnnmm˜šmmng^^^å‚ã^^__^]⃅ã]^^õ! ¯Ÿ®"ôÐÑò'“FÕ >@!  É  b b cbcÔäüäÔìÔì91ô<<ì2Ô<<Ä903#######5J®¤ªqÃ7ËrqËrÉÕÿý¾äþÑ/þB^þä^sîRf1@ ´³DÔì1ôì0K° TK°T[X½ÿÀ@878Y3#‹Çþº™fþˆ×F)’@ÎÍddÜüÔì1ü<ì20K° TK° T[X½@ÿÀ878YK° TK° T[K°T[K°T[X½ÿÀ@878YK°TK°T[X½@ÿÀ878Y@````pppp]3#%3#^ËËþyËËÊÊÊÙ'ÛÝ>@" Ïœ Ï œ  Ü<Ä291Ô<Ì2ü<ìþ<ì990!!!!!'7!5!7!Ù}®/þHÃ{üúþþ}®þÕ¶Ãý‡¢;fÕ¨ðªþÇfÓªðHÕ‡@9  B• ••••­    ÔÔ<ì2ÔÄÄ91/<ììÄôììîî0KSXííííY"²€]@gww† …– ¿ ]!!!!!!#!5ýÇý9øü=ýð Íq‹þ¶ËÕªþFªýãªþÕžüðfÿºå +ž@< +,  )&  *&•& •‘&Œ,+,* # )#3,üìüìÀ999999991äôìîÀÀ99999990@*WZWU!je!{vu! FYVjddj(|svz( ]] 324&'.#"&5!27!"&''¶ý3>¡_Ü'y=¡_Üþý''†NOy;‚ÝW¢fªNPþˆþÆ€Ý[¢gXü²@CHp¸¸@Cþ¸þåp¼Džf b¥MK¿YÆgþöžþŸþ[KK¿XÝÝÏî /ÿ@- !$'!!0 $*0ÔÄÔÄ99991ÔÄÔÄÀ9990@¾     $$$   $$ $ ***///***55500055 5 :::???:::EEE@@@EE E JJJOOOJJJV´° °!°"°&°'°(´)]]32654&#".#"326#"&54632>32#"&“1†Te€vYR…Ä1…UfvYR†F^ˆº§†_™HDža†¼§†^•/XZ‡ie†‡7XX„je†ˆ‡ߦ¯Ø~ŠŠƒá§¯ÖwÙÛ .@МР œ   Ô<ì2ü<ì21/ìÔ<ìü<ì0!!#!5!!!®-ýÓ¨ýÓ-ýÓúþþ}ªþ}ƒªƒû¦ªÙÛ¨ T@.œœœœBѧœ $# ü<ì2291/ìôì90KSXííííY" 5!!Ûü@Àúþúþúþøþëþî²pªoüªÙÛ¨ V@/œœœœBѧœ$ # ü<<ì291/ìôì90KSXííííY"55!5ÙúþÁAúþø°þ‘ªþ²ýǪªRÃÕÆ@F  B Ó Ó   fe f eÔ<ì2ìüì2ì99991/ä2Ô<ì2Ô<ì290KSXííííY"K° TX½ÿÀ@878Y@(†¦ µ' ' ')((79‡ ˆ¦ ¥ª©]]!#!5!5'!5!3 3!!!þcÉþ` Tþ´þþ{y¿þÂþµTŸÇþ9Ç{3›{JýD¼ý¶{›3®þVå` M@% ‡Œ ¼½!   NF!üì2ôìÄ91ää2ô<ìÜÄ990¶"`"Ï"]3326533267#"&'#"&'®¸Š‡”•¸#% )I#ER2‘bf*þV ýH‘”¨¨ü¢<9 ”NPOONNý×hÿçÁ-)b@'! '!Õ* $$*ÔÌÜÌ9991äÌÜÌÎÎ990K° TK° T[K°T[K°T[K°T[X½*@**ÿÀ878Y>54&#"#"&54632#"&54324&#"32ôIH7$$0e´ÖþßÕ˜ËÝ¢e‚ WOmVPmmW£Kƒt,>bþÊþùþ±þFØ£Æ[àt}þþÏt{þw;Á ]@    ÔÄ91ÄÔÌÎ990@0QVPZ spvupz €€ Z pp{ t €€ ]]!! !!5 7êüA ýJïúÞÕýIÁÁý3ýÀ•!ãœþwqÁ@×Ö¯ggÔìÔì1üìì20!#!#œÕðý ïÁø¶}ùƒÿáÿðª/#Ë@1 ÚÙ"ØÕ $ #" #h#$ÔÔÔì9999991/<äôì22î9990K° TX½$ÿÀ$$@878Y@V             ##(]]#3267#"&5467!##"#>3!‡¶i/7.%7vy"PþºÂµÃ)6<  ¥y‘þJ\:1fd.¡xüo‘@E¦}/þú%&@ Û Ûܱ& iji&Üìüì1üìÜäÞä026732#"&'&&#"#"&546327j ¾ÊPd@7*8  k½ÄOeD=!0 þú°l9¼TA6?&#Hý•Ánþ!þbSA8?SsÕ;ð)_@3(%ãÝá%Ý ßÞÝ à‘* "(kl"k *ÜìÌüì22ÀÀ9991ôäüôìÄîíÖîî99990!!#5#"&5463354&#"56632"32655‹°ýP®•,]€˜¿¼¶uu>ˆDI‘E·³þì¡~bRh‚P{¸þ@p?D‡q‡Š[[""°ðCO@Mr`Õdð.@ãáÝ àÝ‘ klk Üìüì991ôìôìüì0!!2#"&546"32654&‹°ýPX³Îγ³Ðгi~hi}|P{Ý¿¿Ûܾ¿Ýs¡ˆ…  …‰ NÏç@@" å‘å  mm  ÔììÔììÀÀ9991/<ì2ôì0%!5654#"!5!&5! Ïý¨±ÆþøØØþ÷Dzý¨?ž‘1/Ž¡²²²aLÊð"þÝïÊþ´a²²‹*¸>ŠþwþËÂþØ{ÿão{3>@C'-%= 4©%†ˆ©:¹.†-º*¹»1 ¸Œ%?47&%7& =&-7"E?üìÌÔü<ÔìÄ999991Ää2ô<Ääü<ôìÄî2îôîî9990@0+0,0-0.0/00@+@,@-@.@/@0P+P,P-P.P/P0…+…0€@@ @°@À@Ð@à@à@ð@??? ??0,0-0.0/@,@-@.@/P,P-P.P/ooo oo`,`-`.`/p,p-p.p/€,€-€.€/]q].#">32!3267#"&'#"&5463!54&#"5>32"326=¶¥‰™¹DJÔ„âü² Ì·hÈddÐj§øMIؽÒýû§—`¶Te¾ZŽÕï߬o™¹”—´®ž0Z^þÝúZ¿È55®*,ywxx»¨½À‹..ª''`þf{bsÙ´)Hÿ¢œ¼ +ä@<+,&  )&  *&¹& ¹¸&Œ,+,* # #Q)E,üì2ôì2À9999991äôìîÀÀ99999990@p(?-YVUV jf!{    { z{ {!"#$%{&›•%¨ -ð-&YVUZ(ifej(ztvz(‰•š$¢­$]] 32654&'.#".5327#"&''‰þ)gA“¬\*g>—©}66ñ]ŸC‹_’56þîð`¡?‹`!ý°*(èÈOuš))ëÓHn.—MÅw834¨O³MÆxþíþÇ43¨Nÿã¬Õ $†@/ †ˆ !ƒ# •Œ#%" " "!& %ÜìÔüìÔì99991äôìþÍôî9990K°TK°T[K°T[X½%ÿÀ%%@878Y@ ttttv]33267#"&546?>7>5#53ô¾7ZZ:3ƒmN´`^Àg¸àIYX0&ÄÊÊDœe‚WX5^1YnFC¼98ŸL‰VV/5<6þ5Õ b@ƒ ü<ì2991/ôüÌ0K° TX½ @ ÿÀ878YK°TK°T[K°T[X½ ÿÀ @878Y¶ P ]#53#3ËËË¢×þú+eþ›ÙÛ^@ œÜÔì1ÔÄì0!#!Ù¨û¦^ýÁ•=ÿ×} *@    ÔÌ91ÔÌÄ903##'%\½sý®BþÁ}}`ùºs-Pbý;þV#Š@@   B   ©Šæ©Šæ©!—$  $ÔÌ91Ä2Äüìôìîöîî299990KSXí2í9Y"K° TX½$ÿÀ$$@878Y.#"!!#"&'53267#5!>32&P,`r<þÃ:¼º:d/4a/am"‰ø?$Æ—5dð¤z„þÉý…þãÓ¦!!‰¦­J·ÃÙÛô;?@.9*-" *œ19œ"œ œ<-<Ô<Ä21ÔìÔìÜüÔìÀ9999990#"'&'&'&#"56632326#"'&'&'&#"56632326Ûi³an’ ›^X¬bi³an“ ›^V©gi³an’ ›^X¬bi³an“ ›^V©o³NE;=LT³NE;=KÚ²OE;=LS²NE;=Kÿú`Á8@ÔÌ91/ÄÌ90@cmpxyvn]] !3!¬þ^DýïàCúšîûÄú?ž%# †@Ièèèè è è è  è B  ç¦ o o nüü<Ôì2991ô<ì2990KSXííííííííY"55%þÓ-þ+#þÓ-þ+#¿þôþô¿¢R¢¿þôþô¿¢RÁH# †@I è è è è èèèèB  ç¦ o opü<üÔ<ì991ô<ì2990KSXííííííííY"5%5ÁÕþ+-þÓ²Õþ+-þÓ#þ^Rþ^¿  ¿þ^Rþ^¿  ìþ #@ƒ   ÔüÔìÔì1/<<ì220%3#%3#%3#–ÔÔ©ÕÕú­ÕÕþþþþþþÿÿhk'$¼uÿÿh^'$¼uÿÿsÿãÙ^'2'us Õ;@•••­   üìÔÄÄÔì299991/ìì2ôì2î0!!!!! !# !3úýÇý9øû×þOþA¿±gþ¿þÀ@AÕªþFªýãª|pm|ªþáþàþßþßqÿãÃ{'3„@1†ˆ ©. ¹(¹»"%¸Œ4"1 K1 Q+E4üìôüôìÄ9991ä2ô<Ääì2Äî2îôî90@%?5_5p5Ÿ5Ï5Ð5ð5????? ooooo ]q].#"!3267#"&'#"32>32%"32654& ¤‰™¹Hü² Ì·jÈbdÐj òQGÑŒñþïñŒÓBNèâú°”¬«•“¬¬”˜³®ž5Z¾Ç44®*,nmnm98olkpþ݇çÉÉçèÈÇééy¶©é/Æ1üì0!!üyéyµ©/Ì1Ôì0!!øy®émÕ '@ž   ÜüÌÔÌþÔÎ1ô<ì20#53#53Ó¤RšÓ¤Ré­?þÁ­­?þÁ®émÕ '@ ž  ÜìÔÌÜîÔÎ1ô<ì203#%3#Ó¤RšÓ¤RÕ¬þÀ@¬¬þÀ@®éÓÕ@ žÜüÔÌ1ôì0#53Ó¤Ré­?þÁ²þ×Õ@ žqÜìÔÌ1ôì03#Ó¤RÕ˜þÁ?Ù–Ûo )@êêœ r ÜÔ<ü<Ä1ÔÄüÄîî03#3#!!ßööööýúúþoöþõAªþ#îu"@ÔÌ91ÔÌ990 úþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿ=þV'\Ž^ÿÿÿüçN'<suþ‰ÿãÍð+@BŒ‘ÔÌ1ää0KSXííY"3#- ü\ ðùó^R¼²#/ƒ@I -'! - -¹ëì'¹ë!0 *$0* $ $(st*(s0Üäìôäì9999999991ÔäìôäìÀ9999999907'#"&''7&&5467'766324&#"326{ÏrÎ%$&(ÑrÏ;t=:x=ÏqÏ%%&&ÏsÏ7t@?s9ÏqÏ(&%%ÏsÎ>v:@t8ÎsÏ'%$þ|pššprœžs#G@%èèèèBç¦onüì291ôì90KSXííííY"5sþÓ-þ+#¿þôþô¿¢RÁ–#I@&èèèèBç¦opü<ì91ôì90KSXííííY"5ÁÕþ+-þÓ#þ^Rþ^¿  /J›@( ©‡¾±— ¼ Lü<Ä2Äü<Äî2991/<æ2îþîîî2990K° TX½ÿÀ@878YK°TX½@ÿÀ878Y@0P€€€ Ðï]]#!##53546;#"3#J¹þ¹°°­³¹°cMù¹¹`û Ñü/ÑN·¯™Phc²é/J„@! © ‡— ¼   Lü<ÄÄü<Äî991/<æ2þîî2990K° TX½ÿÀ@878YK°TX½@ÿÀ878Y@0P€ € € Ðï]!#!"!!##53546J¹þ·cM/þѹ°°®ùì{Phcü/ÑN»«9ÿ;ÇÕ>@ ¹¹  ÂY W Y Ô<<ì2ü<<ì21äôÄ2Ä2î2î20%!#!5!!5!3!!!Çþ‘°þ‘oþ‘o°oþ‘oßþ\¤š™¤þ\™ýáÛH®F·ƒÔì1Ôì03#ÛÓÓFþ®ÿÓþ@ žƒÔìÔÌ1üì0%3#Ó¤Rþ¬þÀ@®ÿmþ '@ žƒ   ÜìÔÌÜîÔÎ1ü<ì20%3#%3#šÓ¤RþfÓ¤Rþ¬þÀ@¬¬þÀ@qÿã Lð #'3?K®@D$%&%&'$'B@’ .’(’F’4 :&Œ$‘L%IC'1+C =  1 =I 7+ ! LüäìÔÄìäîîöîî991ä2ô<<ä2ì2îöîî20KSXííY"K°TK° T[K° T[K° T[K° T[K°T[X½L@LLÿÀ878Y"32654&'2#"&5462#"&546!3#"32654&2#"&546"32654&ôWddWUccUžº» º»ùtž¼»ŸŸ¹º% üZ VcbWWcd²žº» º»ŸWccWUcc‘”„‚••‚ƒ•Ü»»ÛÛ»¼ÛàÛ»½ÚÛ¼ºÜùóŽ•‚„””„–ýŸÜ»»ÛÛ»¼Û”„‚••‚ƒ•ÿÿhm'$¼uÿÿÉ‹m'(žuÿÿhk'$¼uÿÿÉ‹N'(žuÿÿÉ‹k'(žuÿÿ¢k',ÿ/uÿÿÿþ`m',ÿ/uÿÿXN',ÿ/uÿÿ;ºk',ÿ/uÿÿsÿãÙk'2'uÿÿsÿãÙm'2'uÿÿsÿãÙk'2'uÿÿ²ÿã)k'8îuÿÿ²ÿã)m'8îuÿÿ²ÿã)k'8îuÁy` ·¿Füì1/ì0@ @P`p]3#Á¸¸`û Áî?f7@ ´³uÜì91ôì290K° TK°T[X½ÿÀ@878Y3#'#¶”õ‹´´‹fþˆõõ¶J7c@$  Ãà íVwVvôìüì99991ü<üÔ<ì99990K° TK° T[X½ÿÀ@878Y'.#"#>3232673#"&ü9! &$}f[&@%9! &$}f[&@Z7IR‡“!7IR‡“Õb+ö/·ïîÔÌ1üì0K° TK°T[X½ÿÀ@878Y!!ÕVýªö”Ç)9H W@ ð³VVÜìÔì1ô<Ôì0K° TX½ÿÀ@878YK°TK°T[K°T[X½@ÿÀ878Y332673#"&Çv aWV` v ž‘‘žHKKJLšDf,@ ÎÍdÔì1üì0K° TX½ÿÀ@878Y3#šÌÌÌîá _@Áò ÁñV xVÔìôì1ôìôì0K° TK° T[X½ÿÀ@878YK° TK° T[K° T[X½ÿÀ@878Y4&#"3267#"&54632˜X@AWWA@XzŸssŸŸssŸô?XW@AWX@s  ssŸŸ#þuÁ@  ó' ÜÔìÔÌ1/ÔüÄ90!#"&'532654&'T76xv.W+"J/;<+->i0Y[ ƒ0.W=ðî®fB@´³ÔÜÔÌ991ô<ì20K° TK°T[X½ÿÀ@878Y3#3#ü²ø‡ªß‰fþˆxþˆLþuÁ @  óô 'ÔìÄÔÌ1/üüÄ90!33267#"&546¸w-+76 >&Dzs5=X..… W]0iÁî?f7@ ´³uÜì91ô<ì90K° TK°T[X½ÿÀ@878Y373¶õ‹´´‹õîxõõþˆÿòuÕ ?@ •  : yô<ìÄü<Ä991/äì90´0P]3%!!'7ÓË9Pþw×ü^”MáÕý˜Ûoþîýãª;jnžH ^@ — z z Ô<äü<ä991/ì90K°TX½ @ ÿÀ878Y@ @ P ` sz p à ð ]37#'7Ǹ}Lɸ{JÅý¦ZjüãšXjÿÿ‡ÿã¢m'6‹uÿÿoÿãÇf'Vàÿÿ\m'=¾uÿÿXÛf']àþ¢®˜@ õõÜ<ì21ÔìÔì0##®ªªª˜ý öý ö ºÕ g@  © ••  2  yô<ì2ÄôìÄ91/Æ2îöîî20@( °Ÿ Ÿ Ÿ Ÿ ŸŸŸŸ¿ ¿ ¿ ¿ ¿¿¿¿]]! )#53!!3 !Ó ±–þiþPþ`ÉÉËPþ°ó5þáþËÕþ—þ€þ~þ–¼ãþýê.,qÿãu('@^%{&%#${##{#({'(#&'('%$%(('"#" ! B('&%"! ##¹ ¹Œ#±)&' ! (%#" QE)üìôì99999991ìÄôìî9990KSXÉÉÉÉííííY"²?*]@v%+("/#/$)%-&-'*(6%F%X X!` `!f"u u!u"%#%$&&&''(6$6%F$E%Z Z!b b!z{     {zzv v!x" *ð*']].#"32654&#"5432''%'3%F2X)§¹®’‘®6 ~rþäæçþåÝ4*ŸþÁ!µäM!þÙ“ØÃ¼ÞÞ¼z¼&þà­ÿþÉ7ÿú7´kc\Ì‘oabÿÿÿüçk'<suÿÿ=þVf'\^ÉÕ =@• •ö  ? üì22üì91/ôüìÔì0@ ?_]332+#32654&#ÉÊþûþÿûþÊÊþš™ŽÕþøáÜÜâþ®'ýÑ’††‘ºþV¤>@¹¹Œ¸½— GFüì22ôì1ìääôÄìÆî0@ `€ à]%#3>32#"&4&#"326s¹¹:±{ÌÿÿÌ{±8§’’§§’’§¨ý®¾ý¢daþ¼þøþøþ¼aëËççËËççÙ-Û×¶œÔÄ1Ôì0!!Ùúþת?œÅ …@M œ  œœœœœ œ œ B   Ô<Ì291Ô<Ì290KSXííííííííY" '7œþ7Éwþ5þ5vÈþ8vËËLþ5þ7yËþ5yÉËyþ5ˉœÅß ,@Ý ÝÝ ÷‘ |]|| Üôäüä1ôììÔìî2035733!œÌßæ‰Íý× c)t'ý+n^œ´ðJ@$}}BÝÝ÷ Ý‘~ÜÄÔÄì91ôÄìüìî90KSXí2íY"!!56754&#"56632 ¨ýª"?XhU4zHM…9‘®þµ8rn81^BQ##{„l‹þä0bÍð(H@' Ý Ý Ý Ý ø÷Ý ø#‘)~&~ )ÜÄÄÔìÔì9991ôäìüäìÔìîî90#"&'532654&##532654&#"56632 \e¾±9}F4wCmxolV^^ad_(fQI€7©Z`mR|†yOFJLl?<:=svcE`ÿÿ‰ÿãð'ð'¼5 ‹ýdÿÿ‰ÿã?ð'ð'¼5ñ‹ýdÿÿbÿãð'ò'¼5 ‹ýdÿÿsÿã‹m'* uÿÿqþVZH'JÚ‹ÿÿÉ•P', ÿ/uÿÿ‡þu¢ð'6Ý‹ÿÿoþuÇ{'VÝÿÿsÿã'k'&-uÿÿqÿãçf'F‰ÿÿsÿã'm'&-uÿÿqÿãçf'Fà‰qÿãô$J@$Ó ù"¹¹ Œ¸—   GE%üìô<Äü<Ä1/ìäôÄìÄîý<î20¶`&€& &]!5!533##5#"3232654&#"¢þºF¸šš¸:±|ËÿÿË|±ýǧ’’¨¨’’§¶N}““}úü¨daDDaþËççËËççd߃¶œÜÌ1Ôì0!!dý僤ÛH®F·ƒÔì1Ôì03#ÛÓÓFþÿãð1@: Ó"+Ó ¡®•¡®•/‘Œ) 2+"!)#&  , & &*!/<ÔÄ2üÄÄ99999999991Ä2äôìôìîöîî2Ý<î20K° TK° T[K° T[K°T[K°T[K°T[X½2ÿÀ22@878Y@z  1Ti lnooooiko o!o"o#n$l%i'i-ŸŸŸ Ÿ Ÿ Ÿ Ÿ ŸŸŸŸŸŸ–Ÿ Ÿ!Ÿ"Ÿ#Ÿ$Ÿ%Ÿ&Ÿ'Ÿ(Ÿ)Ÿ*Ÿ+Ÿ,-2   USjg ]].#"!!!!3267#"#734&5465#7332[©fÊ A7ýæ¾8þŠ Êf©[Y¹`íþË(Ó7‹Â7œ(6ìb¹bÕiZÈ»{.# .{»ÊZiÓHH"{/ #/{"G×)Ù¥@ ÎddÔüÜì1Ô<ì20K°TK°T[X½@ÿÀ878YK°TK° T[K°T[X½ÿÀ@878YK°TK°T[X½@ÿÀ878YK°TX½ÿÀ@878Y@````pppp]3#%3#^ËËþyËËÙËËËsîðö@BúÄÀ1ôÌ0KSXÉÉY"K° TX½ÿÀ@878YK°TX½@ÿÀ878Y@ %%6FVjg //]]3#7¹ä™öþø¶Jéu@!  ÃÃúVV ÔìÔì99991ô<ìÔì2990K° TX½ÿÀ@878YK°TX½@ÿÀ878Y´ ]'.#"#4632326=3#"&ü9 $(}gV$=09" (}gT";9! 2-ev 3)dw î‹ö‰@BúÄÀ1ôÌ0KSXÉÉY"K° TX½ÿÀ@878YK°TX½@ÿÀ878Y@*$$5CUUŸŸ¯¯//]]#ÇÄ™æöþøÏî1øw@ úÔÄ91ô<Ä90K° TX½ÿÀ@878YK°TX½@ÿÀ878YK°TX½ÿÀ@878Y@ //- ]3#'#¢¼Ó‹¦¦‹øþö²²Ïî1ø†@ úÔÄ91ôÄ290K° TK° T[K° T[K° T[X½ÿÀ@878YK°TX½@ÿÀ878YK°TX½ÿÀ@878Y@ "  ]373¢Ó‹¦¦‹Óî ²²þö?œôß Ô@ Ý ÷‘ ] ÜÔ<Äì291ôüÔ<ì290K°TK°T[K°T[K°T[K° T[K° T[X½@ÿÀ878YK°TK°T[X½ÿÀ@878Y@T /9IFYi‹«»       "5GK S[ e„¥µ]] !33##5!5ÝþË5¦‡‡þbfþ]ýämººyÇ9ø j@à úVVÔìÔì1ôüÄ20K° TX½ÿÀ@878YK°TX½@ÿÀ878YK°TK°T[X½ÿÀ@878Y332673#"&Çv cSRav  Ÿø6978w{zšfÛ¶úÔÌ1ôÌ03#šÌÌÛÍ  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•Íf‹‹55®Å´žªšq=3ۤ=´Ù‹žãd‹Û²‡á–œdž¨‹²ð²ž´Ù´Ù´Ù?“‡y}É–s)ÉÉšÉ3sÉ\É\ÿ–?ÉuÉçÉüÉLsÓÉLsɇãÿúÛ²yéD{=ãÿü{\°²Ç´Ùÿìªç{ºfqqìqÑ/qº9Á9ÿÛ¢º9Á˺ºåqºqJº+o#7®¼=‹V¼;¼=3X²´Ùyy–sÉüÉLsÛ²ç{ç{ç{ç{ç{ç{fqìqìqìqìq99ÿÇ9ÿÞ9ÿôºåqåqåqåqåq®®®®9ì\¸3ž º's×´ÙËLfªÝ´Ù´Ù´ÙR®#hdœ¶ÿá+/ÅsÅ`NÛ{åH?55´Ù=´ÙZÿúåžåÁìyyLss/q%®%®‹®‹²´Ùô¼=ãÿüVþ‰^3ž3Á / /9‹Û‹®%® ¼qyÉyÉÉ\¢\ÿþ\\;LsLsLsÛ²Û²Û²9ÁÁ¶ÕÇšî#ðLÁÿòF‡+o{\3X²3 åqãÿü¼=×ɺ´Ù´5‰5^5bÁ‰Á‰Áb3sq\ɇ+o–sfq–sfqqãd‹Û×s¶ ÏÏ5?Çšÿ+   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ     sfthyphenperiodcenteredEuroc6459c6460c6461c6462c6463c6466c6467c6468c6469""""X“ÿ¶Oƒ²ö!n˜´ÊÞE‚~áL·üeÏî  R s ®  ß X ° û : i “ æ  = z /¬E…ëuñ)pཊëP‹±á@Ö"m¹#{ßC€øw³R¡Ø‡Äº‡wè [ r ó!5!B!â!ï!ü" ""#"0"="J"W"d"q"~"‹"˜"¥"²"¿"Ì"Ù"æ"ó## ##'#4#A#N#[#h#”#Ï$4$%3%S%&&º'K''·((X(Ã)_*%*\*£*é+z+Ó,D,,±-P- ..R.ª/‡0A0½11!1P1Ï2H2z2ß3F3p3p3}3Š3—3æ4z44£4Ñ4ÿ5595g5‘5ž5«5Ï6[6“6Í7C7©7ë888J999)969C9P9]9j9w9„9‘9ž9«9¸9Å9Ò9ï::{: :å;;^;Ž;Ä;ô<"<_<§<´<Á<Î<Û<þ=c>;>H>U>˜>ç>ý?a??Ü@:@K@\@m@z@‡@”@¡@®@»@È@Õ@âA@AVAkBEBªB÷C_C²CÿDUDÛE*E?-†” x$ÿÓ%ÿ·&')*K+-r./2934K57ÿD9ÿˆ:ÿ­;ÿš<ÿ =IQR&UYÿÉZ\ÿÜbÿÓdg9xy&z&{&|&}&‰­ÿÓ®ÿÓ¯9ºÿÜ»ÿ ÇÿÓÉÿÓÐ9Ñ9Ò9åéêÿ ëÿÜìöKûý$ÿÓ$ÿÜ$ÿÜ$$9$&ÿÜ$*ÿÜ$2ÿÜ$4ÿÜ$6$7ÿa$8$9ÿ}$:ÿ$;$<ÿa$FÿÜ$GÿÜ$HÿÜ$Iÿ·$RÿÜ$TÿÜ$WÿÜ$X$Yÿˆ$Zÿ­$\ÿu$b9$dÿÜ$gÿÜ$h$oÿÜ$pÿÜ$qÿÜ$rÿÜ$sÿÜ$yÿÜ$zÿÜ${ÿÜ$|ÿÜ$}ÿÜ$~$$€$$©ÿ·$ª$­9$®9$¯ÿÜ$´þø$µÿ$ºÿu$»ÿa$Å/$Ç9$É9$ÐÿÜ$ÑÿÜ$ÒÿÜ$Ó$Ô$Õ$ã$êÿa$ëÿu$öÿÜ$ù$ûÿÜ$üÿÜ$ýÿÜ$þÿÜ%%&ÿÜ%*ÿÜ%2ÿÜ%6ÿÜ%9ÿÁ%:ÿ·%<ÿ%dÿÜ%gÿÜ%©ÿÁ%ªÿÜ%¯ÿÜ%´ÿ%µÿ%»ÿ%Åÿ­%ÐÿÜ%ÑÿÜ%ÒÿÜ%ãÿÜ%êÿ%öÿÜ%ùÿÜ%ûÿÜ%ýÿÜ&&$&6&<ÿÜ&b&©ÿÜ&ªÿÜ&­&®&´&µ&&»ÿÜ&Å&Ç&É&ã&êÿÜ&ù''$ÿÜ'9ÿÜ':'<ÿ'bÿÜ'©ÿÜ'ªÿÜ'­ÿÜ'®ÿÜ'´ÿÓ'µÿÉ'»ÿ'ÅÿD'ÇÿÜ'ÉÿÜ'êÿ))þ·)ÿa)$ÿD)6ÿÜ)7ÿÜ)DÿD)Hÿ)Lÿk)Rÿ·)Uÿk)Xÿ)\ÿD)bÿD)iÿD)jÿD)kÿD)lÿD)mÿD)nÿD)pÿ)qÿ)rÿ)sÿ)yÿ·)zÿ·){ÿ·)|ÿ·)}ÿ·)~ÿ)ÿ)€ÿ)ÿ)©)ª)­ÿD)®ÿD)´ÿÓ)µ)ºÿD)Åþˆ)ÇÿD)ÉÿD)ãÿÜ)ëÿD)ùÿÜ**$*7ÿ·*:*<ÿš*b*©ÿÜ*ªÿÜ*­*®*´ÿÓ*µÿÓ*»ÿš*ÅÿÉ*Ç*É*êÿš++ÿÜ++©+ª+´ÿ·+µÿÁ+Åÿ·-ÿ·-$ÿÜ-bÿÜ-©ÿÜ-ªÿÜ-­ÿÜ-®ÿÜ-´ÿ·-µÿÁ-Åÿ-ÇÿÜ-ÉÿÜ.ÿ).$ÿÜ.&ÿ.2ÿ.7ÿa.8ÿÉ.:ÿ·.<ÿ·.DÿÜ.Hÿš.Rÿš.Xÿš.\ÿk.bÿÜ.dÿ.gÿ.hÿÉ.iÿÜ.jÿÜ.kÿÜ.lÿÜ.mÿÜ.nÿÜ.pÿš.qÿš.rÿš.sÿš.yÿš.zÿš.{ÿš.|ÿš.}ÿš.~ÿš.ÿš.€ÿš.ÿš.©ÿ}.ª.­ÿÜ.®ÿÜ.¯ÿ.´ÿÁ.µÿÁ.ºÿk.»ÿ·.Å.ÇÿÜ.ÉÿÜ.Ðÿ.Ñÿ.Òÿ.ÓÿÉ.ÔÿÉ.ÕÿÉ.êÿ·.ëÿk.ûÿ.ýÿ/ÿÜ/$//2ÿ·/7þæ/8ÿš/9ÿ/:ÿD/<þð/D/HÿÜ/RÿÜ/XÿÜ/\ÿD/b//gÿ·/hÿš/i/j/k/l/m/n/pÿÜ/qÿÜ/rÿÜ/sÿÜ/yÿÜ/zÿÜ/{ÿÜ/|ÿÜ/}ÿÜ/~ÿÜ/ÿÜ/€ÿÜ/ÿÜ/©/ª/­//®//¯ÿ·/´þa/µýæ/ºÿD/»þð/Å/Ç//É//Ðÿ·/Ñÿ·/Òÿ·/Óÿš/Ôÿš/Õÿš/êþð/ëÿD292ÿ­2ÿÜ2$ÿÜ29ÿÜ2;ÿ}2<ÿ2bÿÜ2©ÿÜ2ª2­ÿÜ2®ÿÜ2´ÿÓ2µÿÜ2»ÿ2ÅÿD2ÇÿÜ2ÉÿÜ2êÿ3ÿÓ3þÁ33$ÿ}383:3<ÿÓ3Dÿ¤3Hÿ·3LÿÓ3QÿÜ3Rÿ·3UÿÜ3VÿÜ3XÿÜ3\3bÿ}3h3iÿ¤3jÿ¤3kÿ¤3lÿ¤3mÿ¤3nÿ¤3pÿ·3qÿ·3rÿ·3sÿ·3xÿÜ3yÿ·3zÿ·3{ÿ·3|ÿ·3}ÿ·3~ÿÜ3ÿÜ3€ÿÜ3ÿÜ3©ÿÜ3ª3­ÿ}3®ÿ}3´&3µ&3º3»ÿÓ3Åþ·3Çÿ}3Éÿ}3Ó3Ô3Õ3äÿÜ3êÿÓ3ë3úÿÜ494©4ª4´ÿÓ4µÿÜ4Åÿ}5ÿ­5ÿ·5ÿÁ5$ÿ­5&ÿš57ÿk59ÿ5:ÿ­5<ÿ}5DÿÓ5Hÿ¤5Rÿ¤5Xÿ¤5\ÿ5bÿ­5dÿš5iÿÓ5jÿÓ5kÿÓ5lÿÓ5mÿÓ5nÿÓ5pÿ¤5qÿ¤5rÿ¤5sÿ¤5yÿ¤5zÿ¤5{ÿ¤5|ÿ¤5}ÿ¤5~ÿ¤5ÿ¤5€ÿ¤5ÿ¤5©ÿ5ªÿÜ5­ÿ­5®ÿ­5´ÿk5µÿ}5ºÿ5»ÿ}5ÅÿÜ5Çÿ­5Éÿ­5êÿ}5ëÿ5ûÿš5ýÿš6$&6&6*6264666b&6d6g6­&6®&6¯6Ç&6É&6Ð6Ñ6Ò6ã6ö6ù6û6ý7ÿD7ÿ 7ÿ7$ÿa7&ÿˆ77ÿÜ7Dþ­7Fþ¤7Hþ¤7LÿÁ7Rþ¤7UþÓ7Vþ­7XþÉ7Zþ­7\þÁ7bÿa7dÿˆ7iþ­7jþ­7kþ­7lþ­7mþ­7nþ­7oþ¤7pþ¤7qþ¤7rþ¤7sþ¤7yþ¤7zþ¤7{þ¤7|þ¤7}þ¤7~þÉ7þÉ7€þÉ7þÉ7©ÿD7ªÿ7­ÿa7®ÿa7´7µÿÓ7ºþÁ7Åþø7Çÿa7Éÿa7äþ­7ëþÁ7úþ­7ûÿˆ7üþ¤7ýÿˆ7þþ¤8$8-8=ÿÜ8b8­8®8Ç8É8åÿÜ9ÿˆ9þø9ÿY9$ÿ}92ÿÜ9Dÿa9Hÿa9LÿÓ9Rÿa9Xÿu9\ÿÉ9bÿ}9gÿÜ9iÿa9jÿa9kÿa9lÿa9mÿa9nÿa9pÿa9qÿa9rÿa9sÿa9yÿa9zÿa9{ÿa9|ÿa9}ÿa9~ÿu9ÿu9€ÿu9ÿu9©ÿN9ªÿ9­ÿ}9®ÿ}9¯ÿÜ9´9µ9ºÿÉ9Åþæ9Çÿ}9Éÿ}9ÐÿÜ9ÑÿÜ9ÒÿÜ9ëÿÉ:ÿ­:ÿ:ÿˆ:$ÿ:Dÿ}:Hÿˆ:LÿÓ:Rÿˆ:Uÿ¤:Xÿ·:\ÿÜ:bÿ:iÿ}:jÿ}:kÿ}:lÿ}:mÿ}:nÿ}:pÿˆ:qÿˆ:rÿˆ:sÿˆ:yÿˆ:zÿˆ:{ÿˆ:|ÿˆ:}ÿˆ:~ÿ·:ÿ·:€ÿ·:ÿ·:©ÿ:ªÿÜ:­ÿ:®ÿ:´ÿÜ:µ:ºÿÜ:Åþø:Çÿ:Éÿ:ëÿÜ;ÿš;$;&ÿk;2ÿ};7ÿÜ;Hÿ¤;b;dÿk;gÿ};pÿ¤;qÿ¤;rÿ¤;sÿ¤;©ÿ;ª;­;®;¯ÿ};´ÿa;µÿ­;ÅÿÓ;Ç;É;Ðÿ};Ñÿ};Òÿ};ûÿk;ýÿk<ÿ <þa<þð<$ÿa<&ÿ<2ÿ<Dþæ<Hþð<Lÿ·<Rþð<Xÿ<bÿa<dÿ<gÿ<iþæ<jþæ<kþæ<lþæ<mþæ<nþæ<pþð<qþð<rþð<sþð<yþð<zþð<{þð<|þð<}þð<~ÿ<ÿ<€ÿ<ÿ<©ÿ<ªÿk<­ÿa<®ÿa<¯ÿ<´ÿ<µÿÜ<Åþø<Çÿa<Éÿa<Ðÿ<Ñÿ<Òÿ<ûÿ<ýÿ=ÿÜ=©=ª=´ÿÜ=µÿÜ=ÅÿÜH[ÿÜIÿIÿkIÿ·IWÿÜIZÿÜI\ÿÜI©ÿ·IªÿÜI´AIµIºÿÜIÅÿIëÿÜNDÿÜNHÿ·NRÿ·NXÿÁN\ÿ·NiÿÜNjÿÜNkÿÜNlÿÜNmÿÜNnÿÜNpÿ·Nqÿ·Nrÿ·Nsÿ·Nyÿ·Nzÿ·N{ÿ·N|ÿ·N}ÿ·N~ÿÁNÿÁN€ÿÁNÿÁNºÿ·Nëÿ·QQQQ©QªQ´ÿkQµÿQÅÿ¤R&RÿÜRR[ÿÁR©RªR´ÿkRµÿ·RÅÿ}Uÿ}UÿDUÿÜUFÿÓUGÿÜUHÿÓUIUJÿÜUKÿÜUPÿÜUQÿÜURÿÓUTÿÜUUÿÜUXUYUZU[ÿÉU\U]UoÿÓUpÿÓUqÿÓUrÿÓUsÿÓUxÿÜUyÿÓUzÿÓU{ÿÓU|ÿÓU}ÿÓU~UU€UU©ÿ·UªU´UµVUºUÅþÉUæUëU÷ÿÜUüÿÓUþÿÓYÿÉYÿaYÿY©ÿÜYªÿÜY´YµÿÜYÅþðZZÿDZÿZ©ÿÜZªÿÜZ´ZµZÅÿ)[FÿÜ[HÿÁ[RÿÁ[oÿÜ[pÿÁ[qÿÁ[rÿÁ[sÿÁ[yÿÁ[zÿÁ[{ÿÁ[|ÿÁ[}ÿÁ[üÿÜ[þÿÜ\ÿÜ\þÜ\ÿk\©ÿÜ\ªÿÜ\´\µ\ÅþÓbÿÓbÿÜbÿÜb$9b&ÿÜb*ÿÜb2ÿÜb4ÿÜb6b7ÿab8b9ÿ}b:ÿb;b<ÿabFÿÜbGÿÜbHÿÜbIÿ·bRÿÜbTÿÜbWÿÜbXbYÿˆbZÿ­b\ÿubb9bdÿÜbgÿÜbhboÿÜbpÿÜbqÿÜbrÿÜbsÿÜbyÿÜbzÿÜb{ÿÜb|ÿÜb}ÿÜb~bb€bb©ÿ·bªb­9b®9b¯ÿÜb´þøbµÿbºÿub»ÿabÅ/bÇ9bÉ9bÐÿÜbÑÿÜbÒÿÜbÓbÔbÕbãbêÿabëÿuböÿÜbùbûÿÜbüÿÜbýÿÜbþÿÜdd$d6d<ÿÜdbd©ÿÜdªÿÜd­d®d´dµ&d»ÿÜdÅdÇdÉdãdêÿÜdùg9gÿ­gÿÜg$ÿÜg9ÿÜg;ÿ}g<ÿgbÿÜg©ÿÜgªg­ÿÜg®ÿÜg´ÿÓgµÿÜg»ÿgÅÿDgÇÿÜgÉÿÜgêÿh$h-h=ÿÜhbh­h®hÇhÉhåÿÜp[ÿÜq[ÿÜr[ÿÜs[ÿÜxxxx©xªx´ÿkxµÿxÅÿ¤y&yÿÜyy[ÿÁy©yªy´ÿkyµÿ·yÅÿ}z&zÿÜzz[ÿÁz©zªz´ÿkzµÿ·zÅÿ}{&{ÿÜ{{[ÿÁ{©{ª{´ÿk{µÿ·{Åÿ}|&|ÿÜ||[ÿÁ|©|ª|´ÿk|µÿ·|Åÿ}}&}ÿÜ}}[ÿÁ}©}ª}´ÿk}µÿ·}Åÿ}‰&‰©‰ª‰´ÿ‰µÿ‰Åÿ­©ª´ÿ­µÿ¤Åÿ©$©%ÿÜ©&ÿÜ©'ÿÜ©)©*ÿÜ©+©-ÿÜ©.©/©2©3©4©5©7ÿ©9ÿ©:ÿÜ©;©<ÿk©=©I©Q©R©U©YÿÜ©ZÿÜ©\ÿÜ©b©dÿÜ©g©x©y©z©{©|©}©‰©—©­©®©¯©ºÿÜ©»ÿk©Ç©É©Ð©Ñ©Ò©å©é©êÿk©ëÿÜ©ì©öÿÜ©ûÿÜ©ýÿܪ$ÿ·ª%ÿ·ª&ÿܪ'ÿܪ)ª*ª+ª-ÿܪ.ª/ª2ÿܪ3ª4ª5ª7ÿDª9ÿNª:ÿª;ÿª<ÿª=ªIªQªRªUªYÿܪZÿܪ\ÿܪbÿ·ªdÿܪgÿܪxªyªzª{ª|ª}ª‰ªª­ÿ·ª®ÿ·ª¯ÿܪºÿܪ»ÿªÇÿ·ªÉÿ·ªÐÿܪÑÿܪÒÿܪåªéªêÿªëÿܪìªöªûÿܪýÿÜ­ÿÓ­ÿÜ­ÿÜ­$9­&ÿÜ­*ÿÜ­2ÿÜ­4ÿÜ­6­7ÿa­8­9ÿ}­:ÿ­;­<ÿa­FÿÜ­GÿÜ­HÿÜ­Iÿ·­RÿÜ­TÿÜ­WÿÜ­X­Yÿˆ­Zÿ­­\ÿu­b9­dÿÜ­gÿÜ­h­oÿÜ­pÿÜ­qÿÜ­rÿÜ­sÿÜ­yÿÜ­zÿÜ­{ÿÜ­|ÿÜ­}ÿÜ­~­­€­­©ÿ·­ª­­9­®9­¯ÿÜ­´þø­µÿ­ºÿu­»ÿa­Å/­Ç9­É9­ÐÿÜ­ÑÿÜ­ÒÿÜ­Ó­Ô­Õ­ã­êÿa­ëÿu­öÿÜ­ù­ûÿÜ­üÿÜ­ýÿÜ­þÿÜ®ÿÓ®ÿÜ®ÿÜ®$9®&ÿÜ®*ÿÜ®2ÿÜ®4ÿÜ®6®7ÿa®8®9ÿ}®:ÿ®;®<ÿa®FÿÜ®GÿÜ®HÿÜ®Iÿ·®RÿÜ®TÿÜ®WÿÜ®X®Yÿˆ®Zÿ­®\ÿu®b9®dÿÜ®gÿÜ®h®oÿÜ®pÿÜ®qÿÜ®rÿÜ®sÿÜ®yÿÜ®zÿÜ®{ÿÜ®|ÿÜ®}ÿÜ®~®®€®®©ÿ·®ª®­9®®9®¯ÿÜ®´þø®µÿ®ºÿu®»ÿa®Å/®Ç9®É9®ÐÿÜ®ÑÿÜ®ÒÿܮӮԮծã®êÿa®ëÿu®öÿÜ®ù®ûÿÜ®üÿÜ®ýÿÜ®þÿܯ9¯ÿ­¯ÿܯ$ÿܯ9ÿܯ;ÿ}¯<ÿ¯bÿܯ©ÿܯª¯­ÿܯ®ÿܯ´ÿÓ¯µÿܯ»ÿ¯ÅÿD¯ÇÿܯÉÿܯêÿ´$þø´%ÿÁ´&ÿ·´'ÿÁ´)ÿÁ´*ÿ·´+ÿÁ´-ÿÁ´.ÿÁ´/ÿÁ´2ÿ·´3ÿÁ´4ÿ·´5ÿÁ´7´9´:´;ÿˆ´<´=ÿÜ´Iÿ·´Qÿ´Rÿk´Uÿ´Yÿ·´Zÿ·´\ÿ·´bþø´dÿ·´gÿ·´xÿ´yÿk´zÿk´{ÿk´|ÿk´}ÿk´‰ÿÁ´þ}´­þø´®þø´¯ÿ·´ºÿ·´»´Çþø´Éþø´Ðÿ·´Ñÿ·´Òÿ·´åÿÜ´éÿ·´ê´ëÿ·´ìÿÁ´öÿ·´ûÿ·´ýÿ·ºÿܺþܺÿkº©ÿܺªÿܺ´ºµºÅþÓ»ÿ »þa»þð»$ÿa»&ÿ»2ÿ»Dþæ»Hþð»Lÿ·»Rþð»Xÿ»bÿa»dÿ»gÿ»iþæ»jþæ»kþæ»lþæ»mþæ»nþæ»pþð»qþð»rþð»sþð»yþð»zþð»{þð»|þð»}þð»~ÿ»ÿ»€ÿ»ÿ»©ÿ»ªÿk»­ÿa»®ÿa»¯ÿ»´ÿ»µÿÜ»Åþø»Çÿa»Éÿa»Ðÿ»Ñÿ»Òÿ»ûÿ»ýÿÅ$&Å%ÿ·Å&ÿÅ'ÿ·Å)ÿ·Å*ÿ·Å+ÿ·Å-/Å.ÿ·Å/ÿ·Å2ÿÅ3ÿ·Å4ÿÅ5ÿ·Å7þæÅ9þˆÅ:ÿÅ;ÿ·Å<þˆÅ=ÅIÿÜÅQÿ·ÅRÿ·ÅUÿ·ÅYÿÅZÿ<Å\ÿÅb&ÅdÿÅgÿÅxÿ·Åyÿ·Åzÿ·Å{ÿ·Å|ÿ·Å}ÿ·Å‰ÿ·Å&Å­&Å®&ůÿźÿÅ»þˆÅÇ&ÅÉ&ÅÐÿÅÑÿÅÒÿÅåÅéÿ·ÅêþˆÅëÿÅìÿ·Åöÿ·ÅûÿÅýÿÇÿÓÇÿÜÇÿÜÇ$9Ç&ÿÜÇ*ÿÜÇ2ÿÜÇ4ÿÜÇ6Ç7ÿaÇ8Ç9ÿ}Ç:ÿÇ;Ç<ÿaÇFÿÜÇGÿÜÇHÿÜÇIÿ·ÇRÿÜÇTÿÜÇWÿÜÇXÇYÿˆÇZÿ­Ç\ÿuÇb9ÇdÿÜÇgÿÜÇhÇoÿÜÇpÿÜÇqÿÜÇrÿÜÇsÿÜÇyÿÜÇzÿÜÇ{ÿÜÇ|ÿÜÇ}ÿÜÇ~ÇÇ€ÇÇ©ÿ·ÇªÇ­9Ç®9ǯÿÜÇ´þøÇµÿǺÿuÇ»ÿaÇÅ/ÇÇ9ÇÉ9ÇÐÿÜÇÑÿÜÇÒÿÜÇÓÇÔÇÕÇãÇêÿaÇëÿuÇöÿÜÇùÇûÿÜÇüÿÜÇýÿÜÇþÿÜÉÿÓÉÿÜÉÿÜÉ$9É&ÿÜÉ*ÿÜÉ2ÿÜÉ4ÿÜÉ6É7ÿaÉ8É9ÿ}É:ÿÉ;É<ÿaÉFÿÜÉGÿÜÉHÿÜÉIÿ·ÉRÿÜÉTÿÜÉWÿÜÉXÉYÿˆÉZÿ­É\ÿuÉb9ÉdÿÜÉgÿÜÉhÉoÿÜÉpÿÜÉqÿÜÉrÿÜÉsÿÜÉyÿÜÉzÿÜÉ{ÿÜÉ|ÿÜÉ}ÿÜÉ~ÉÉ€ÉÉ©ÿ·ÉªÉ­9É®9ɯÿÜÉ´þøÉµÿɺÿuÉ»ÿaÉÅ/ÉÇ9ÉÉ9ÉÐÿÜÉÑÿÜÉÒÿÜÉÓÉÔÉÕÉãÉêÿaÉëÿuÉöÿÜÉùÉûÿÜÉüÿÜÉýÿÜÉþÿÜÐ9Ðÿ­ÐÿÜÐ$ÿÜÐ9ÿÜÐ;ÿ}Ð<ÿÐbÿÜЩÿÜЪЭÿÜЮÿÜдÿÓеÿÜлÿÐÅÿDÐÇÿÜÐÉÿÜÐêÿÑ9Ñÿ­ÑÿÜÑ$ÿÜÑ9ÿÜÑ;ÿ}Ñ<ÿÑbÿÜÑ©ÿÜѪѭÿÜÑ®ÿÜÑ´ÿÓѵÿÜÑ»ÿÑÅÿDÑÇÿÜÑÉÿÜÑêÿÒ9Òÿ­ÒÿÜÒ$ÿÜÒ9ÿÜÒ;ÿ}Ò<ÿÒbÿÜÒ©ÿÜÒªÒ­ÿÜÒ®ÿÜÒ´ÿÓÒµÿÜÒ»ÿÒÅÿDÒÇÿÜÒÉÿÜÒêÿÓ$Ó-Ó=ÿÜÓbÓ­Ó®ÓÇÓÉÓåÿÜÔ$Ô-Ô=ÿÜÔbÔ­Ô®ÔÇÔÉÔåÿÜÕ$Õ-Õ=ÿÜÕbÕ­Õ®ÕÇÕÉÕåÿÜã$&ã&ã*ã2ã4ã6ãb&ãdãgã­&ã®&ã¯ãÇ&ãÉ&ãÐãÑãÒãããöãùãûãýåÿÜå©åªå´ÿÜåµÿÜåÅÿÜéé©éªé´ÿ¤éµÿéÅÿ·êÿ êþaêþðê$ÿaê&ÿê2ÿêDþæêHþðêLÿ·êRþðêXÿêbÿaêdÿêgÿêiþæêjþæêkþæêlþæêmþæênþæêpþðêqþðêrþðêsþðêyþðêzþðê{þðê|þðê}þðê~ÿêÿê€ÿêÿê©ÿêªÿkê­ÿaê®ÿaê¯ÿê´ÿêµÿÜêÅþøêÇÿaêÉÿaêÐÿêÑÿêÒÿêûÿêýÿëÿÜëþÜëÿkë©ÿÜëªÿÜë´ëµëÅþÓììÿkìÿ·ì©ìªì´ÿÜìµìÅÿDöö$ö7ÿ·ö:ö<ÿšöbö©ÿÜöªÿÜö­ö®ö´ÿÓöµÿÓö»ÿšöÅÿÉöÇöÉöêÿšù$&ù&ù*ù2ù4ù6ùb&ùdùgù­&ù®&ù¯ùÇ&ùÉ&ùÐùÑùÒùãùöùùùûùýûû$û6û<ÿÜûbû©ÿÜûªÿÜû­û®û´ûµ&û»ÿÜûÅûÇûÉûãûêÿÜûùýý$ý6ý<ÿÜýbý©ÿÜýªÿÜý­ý®ý´ýµ&ý»ÿÜýÅýÇýÉýãýêÿÜýù MB@hmþ ¼þ‰þ‰ L GÌþBGÌSf €¯ JBits@ ûþšmãB±‹`#cÕVeraSansÿÿÿÿ6ÿÿþ628R00@                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        "                      "       #                       #     $               $    &              &    ÿÿ P ì_<õº¹ð¸ºÂg‘þ‰þ Lmloganalyzer-3.6.5/src/BitstreamVeraFonts/VeraSeBd.ttf0000644000175000017500000016256012225176641022071 0ustar danieldanielOS/2·„õ3ÏTVPCLTzÍZϬ6cmap¤Ãè ®Xcvt †ë¨¤fpgmçˆñÄ&4‹gaspå, glyf5“³&À‡Nhdmx”¹‰UÏäHhead|¸-Âå86hheaìÁÏ0$hmtx‰5gѱh0kernç4è·ºDÊloca“Œr–¸(maxp]^Ï nameRü ñpost´V0µ˜Žprep’V‘: ´::O:: S_0³r  ‰ v t ¡ (   ? 2  2   G . _ `  … 0³ & Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Serif BoldRelease 1.10BitstreamVeraSerif-BoldCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Serif BoldRelease 1.10BitstreamVeraSerif-BoldCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com{`öjyV\by‡b`{˜{N\=…ò‡¬¾¾¾¬VTq˜Ç\f{fb‹‹ݘ--){bb??)fD)¢öyš ÍVÅ%h¾N¾¤Õf s{Õjuy ÕÕÕðjdyÕö{Hy`åyqq 33øNy‰¾ªj``'''Dbj¦yyœb3'ªb=Û¶D)f‘RªRüÓ5fVVÁVJ!/TfDs¸€@äÏþÎKÍþÌ ÉÈ2ǻƻÅúÄ–ÂþÁþÀ¿GÀ}¿G¾0½}¼ »þºþ¹þ¸¶ µ´&³ ³@²±±°¯°¯®Ÿ ®7­Ÿ ­!¬7« ª©ª2©©€¨.§š§þ¦¥¦¥¤£+¤»£t£+¢t¢»¡ ¡þ Ÿ ž»žþœ]»€œ›%œ]œ@›š›%š™šš¸ÿÀ@ÿ™˜ ˜@—– •–” “’‘d’þ‘t‘d  @Ž Ž Œ‹ Œ2‹ Љˆ}‰þˆtˆ}† …„t„2ƒ‚ƒþ‚q‚€ €þ @~t~þ}|}þ|{z»{þzy]z»z€yx%y]y@x%w7vtvkutuútsþrqrþqq€po.pþo.nþmþlkKj hþg g@f!e}dþ@ckb»a}`þ^] ]þ[YXY-XW2V TST–SRQPQ%PPOONMN}MI MM@LL1KK2JI J}I HG H}G FE F2ED E E¸ÿÀ@ÿD CBC–BA@A}@6 @@€?=)?»>=)>]==)<;<;:;:9 :9 878}76 77€6 6@545–4+ 43 3–2) 2þ10 0/$)/7.! .-,-–,+ ,,@+ *&*) )@('(–'&''@&%$)%»$!$)#!#þ"! "–! ! !€  @!*@´-:!}22!þ)k!) !-} -þ€  ú  @   » »  @€@þ€¸d…+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX °ÑEDY!-,°%E`D-,KSX°%°%EDY!!-,ED-fþ–f¤@ ÏÏm/ÄÔì1ÔìÔì0!%!!füsüåþ–øòr)ÿãÕ )@r p s  Ôìôì991äôüÌ0%4632#"&!#5oNNppNNoww‹¢NppNOpp‚ü¶¾¾ÃªhÕ@ sÔÜÔÌ1ô<Ì20#!#°í¥íÕýÕ+ýÕ+‹)¾T@3        ÔÌÄ991/<Ä22Ô<Ä22Î22Î220!!!3!!!!#!#!5!!5!þøF+`aÝaþ¶Eþ°`Ý`þø`ß`þéHFþåR`hþîhþþÕþî×þþ×Õ¶þÕç$+2h@;+2ww,v %u "p3(  /,  (%!  3ôÄ2ìÔìþ<Ôîôî91ä2Ô<ÄÄì2Æî2Æää907333&&54673#&&'#&&6654&'ÃxùØõÜypÍay™| ÚýêynâPUcUcyehal;#†„•7¾£´Ï þó+'þðtþŒ;Ç´¹Íþò,‰ T=FVý WJJ`1ÿãhð '3W@,*(}}} .}"p {4+%1 4ÔÄìÄÔìÄîÖî1ä2ô<ÄìîÖîî0KSXÉÉY""32654&'2#"&546!3#2#"&546"32654&º@88@A88A¿ËË¿¾ËËN¬üZ¬;¿ÊÊ¿¾Ë˾A89@A88‹‹¦§ŒŒ§¦‹eÑÅÅÒÒÅÅÑùó-ÑÄÅÓÓÅÄÑd‹¦§ŒŒ§¦‹Rÿãð.8û@e,-,--,2130 ! 78/!! */,!60$ ($v&6~{-vp&03 !%$') 3/,$.)$)3 9ôÄìÔìîÖîÀÀ9999999991/ÆäîöÆþÄÎî2999990KSXí9í9íí9Y"²0]@0 / 07 8/0178 / 07 8/0178OOf0v/u0]])'# 5467.54$32#.#">7#5!#3%326þ!dòþÔþ­­¹33ùJÅ|tket³ Ì+*>þÂXÚ·´ÞÚþHþIÚuwwþpþ‰þ‰þqúÅð :@„„*v{  ÔÄÄüÄ1/äì2990KSXííY"!5!5%!!þÉw;y¸¸•âú‰y‰ÙðX@+   *  u{ …   ôìÄÔìÔì9991/ìôÄüÄÄ990KSXÉ9ÉY"#663 !53!57$54&#"xzïz?°øþ`Éû°Ý¼‰vŽdB%%éДë¡þï°þJô™Ã·­µÿãð*U@- vu)&u{p+ # ) #  +ôÄìÔìÔüÄî9991ÄäôÄüÄÆîîÄ90663 !"&'332654&##532654&#"#°„øv!¦ ÃÀþµþÆvû‰y œŠ˜¦­ŸB4“”‹‚vŠyª##Á´‡¨̱Ñß((HŽ•©›¢°xˆ‡‡{T=ðL@%„„* v v{ ôÔ<ÄÄü<Ä91/äü<Ô<ì290KSXííY"!!53!5!!!3üÊÞý‘qxÿÞý¨þCysôüþð‘Õý+¨ÿãöÕG@&uu …s p     ôäìÔìÄî91äôüÄÆîîÄ990!663 !"&'332654&#"#ƒüáB¢Z@þÀþàzñƒxГދLw3dÕþúþ¸34þéðôþð(*F“ÅÊÇÅ?Bãÿã#ð%6@ uu u{ p& # &ôììÔìôì1äôÄüÄîÖî906632! !2#&&#"2654&#"øA¡_åþÚþñþÎþÅ^XZÎvy‹n²ŸÞgXXggWWu44þôê÷þóqf—ŸþøfiôûÑ¯ØØ¯¯ØØ¯¢çÕ7@*…s ôÄì91/ôüÄ0KSXÉÉY"#!#!çý˜ËXý‰E×û)ºÊåjÿã#ð#/C@% 'u!-uu{p0$ *$* 0ôäìÔìôìî991äôìîÖî990! $5467&&54$! 4&#"3264&#"326¸²¹þÉþÛþÛþȺ±œæL\]KK]]K']rs\]rq^Ì¥ÎÜÜÎ¥Ì$©‚¾ÈȾ‚©'žwwžuuýÕ·ŠŠ·¹oÿãð %@@# #u#uu{p&   &ôäìÔììî1äôìÄÆîîÄ90"32654&#"54! !"&'3326ºgWWggXXxB¡^äþû$2<þ¢þ¨ZÎvy‹o° {¯ØØ¯¯ØØ¯üå55 ëø þŽþ›þiþafiõ¼ÿã7ì  @ rrp† Ô<ì21ìôìî04632#"&4632#"&¼oNNpoOOnoNNppNNo-OpqNNnnýÃNppNOpp5þ¶7ì .@ r ƒ†  ÔÄüÔì91ìüÜÄî904632#"&6655!¼oNNpoOOn‡ibº¿-OpqNNnnüeSÏŠXáþ¼mÙBÛÃ@ÔÌ291ÔÌ90 5Ûü-ÓúþÓþ®þ°ïÐâÏÙ-Û×@‡‡‡Ô<Ì21ôìüì0!!!!ÙúþúþãªãÙBÛÃ@Ô<Ì91ÔÌ9055ÙúþÓÓðþ1âþ0ïP…ÿãTð "9@r !‰ { p#! #ÔÄìÔÄìîî1äôÄüÄþÝÖÎ0%4632#"&6632#6654&#"#VpNOppONpÑ|àiüþûõ‹Œ‚zwnw y¢NppNOppY""ÝÍÊéÍ++¸š“„‚‡þœo  Nj@84O151 t ŠtMŒ1Š8Œ%Š8DO45M J+J>OÜÄÜÄÞÅîî229991ÔÄüìþý<îîîÄ9999054&#"326#"&54632536654&'&&#"3267#"$'&5476$32!#ø|ecyyce|,Z¿ÚÚ¿Z,Ûœnq\øŒ‚â^Ž™aYk£zäg9€þëÂþ¼~„„~€GͲ$s…„þÄþäøL¯””°›†HLðÓÓïLG}ý'ê°ê`NTFEjþ¸Å›þíewzDC^TT~~|KÀÀJ}~|aboþä®þìþÌÿðLÕŒ@Q     * v vs  ÔÌ91/<äì2Ôì90KSXíí2ííí2íííY"#5333!53!3!z2ï3ŽýE’{ýÏ}²Ïæy\ú¤yy1þÏy#;`RÕ$R@( v#Žvsv ## %(#"%ôì2ä2ÔìÔì99991/ì2ôì2üì90¶&P&p&]353#5! !32654&+32654&+`¿¿u½ºáðþ±þ›þƒ¬¦¡±ƒ¿¸º½yãy¸¹…œƤÞÒf}‚vû˜Ÿ žVÿãöð?@~ ~ {p % ôìÔÌÔì1äôÄüìþì0@ 0ou{{Ÿ]! !2#.#"3267ö;þÎþþþ†þI·z… ¡'ΩÚÔÔÜ•½+ªçà¡ef¡@Aþ‘¼»þ¿þ³þ³þÀ¦¨`šÕ8@ vs v % (# "ôìä2Ôì99991/ì2ôì20´¯¿]%32+53#5! ! ‹êÙØë‹ýÀ¿¿þ’ªþUþoy,GE+ú¤yãyþ€þ—þ•þ`°ÕW@. ” “ v”“ ’vŽs’v )( #"ôì2ä2ÔìÔìôì21/ììôììüìäîìä0´Po]353#5!#5!!53#5!!53`¿¿>ŠýŒ‡‰‰þy‡‰yãyþ ×þ!¾ýü¾ý¤×þ `“ÕO@) ” ’”“ ’vŽsv )* #("ôä2Äü<äîôî21/î2öîîþìäþä0´]353#5!#5!!53#5!3`¿¿3‰ý˜{‰‰þ…ëyãyþ ×þ!¾ýü¾ý”yVÿã3ðD@!  v ~~{p(  % ôìÔìÔìä1äôÄüìîÖÖî90´ P ].#"3267#5!# !2-Ò¿èÙÐÜT;´¨þ±¯þ€þI·€ 6ƱþÅþ­þ°þÃ&&šxýÃNLžhiž@Aþ‘`3Õ^@- ’Ž v sv - -( #(#"ôì2ä2Ôì2ä2ä2ä21/<î2ö<î2þî0@ P€Ÿ¯]353#5!#!#5!#3!53!3`¿¿ÀR¿ÀÀý¿ý®Àyãyyþ öyyûyydýœy``Õ 9@vs v (#(" ôä2üä21/ì2ôì20@ 0 @ P ` p € ]353#5!#3`¿¿ÀÀyãyyûyÿjþV{Õ@ –~ v s• (# *.ôäüäÔì1ìôì2Æþä990@ ///0@P]K°TK°T[K°T[K°T[X½ÿÀ@878Y@____Y_p]533265#5!#!"&–‚MLaMÙ¿õþõS¨þšë^X•Í+yyúÍóà"`3Õ@>   *  v sv (#("ôÄä2ü<ä291/<ì22ô<ì290KSXíííí2Y"² ]@š         , & & * *))'9H E @ E @ C CCHA@@@W S S S SSZy   ‡ ¯¯¯¯¼¼¼ËËË=  ! &5 6B GQ Vv ˆ ]]353#5!##5!# 3!3`¿¿Ày -ÇýèÙ“þýgÀyãyyýß!yyþ3üêyÕý¤y`sÕ =@ vs ’v(  (#"ôìä2Ôìä1/îîöî2Ä0@ 0 0 0 0 ]353#5!#!53`¿¿ÀL‡yãyyû-ìþ‹V{ÕÅ@D* vs v(( (# ("ôìä2Ôìä2ää991/<Äî2ö<î290KSXííííY"²]@> (Sp  &&&:VPf`uwvvp€Ÿ]]353#5! !#3!53#3V¾¾hª¬g¿¿ý¾þ1ýþ3¾yãyüB¾yûyysûïûyZþÕ~@-* v sv (( ( ("ôìä2Ôìäää1/<î2ö<î22990KSXííY"²]@@Php‡€Ÿ&77h]]353#5!#5!#!3Z¿¿Ó…¾ ¿þúüm¾yãyûߨyyú¤7üByVÿã ð /@~ ~{ p% % ôìÔì1äôìî0@ o¿Ï]%2#" ! {¿ºº¿¾»»¾þ‡þT­xy¬þS\BKLBþ»þ·þ¸þ»yœjjþdþ•þ–þd`ÑÕJ@"v vsv  / * # ("ôä2Äü<äî99991/î2öî2Öî0¶Pp€]353#5!2#!332654&+`¿¿Rù&þÙøþîññp‚›šƒpyãyíÇÈïþyã­‘«Vþ ð E@ ~~{p! % % !ôìÔì999991äÄôìÎî90@ o""¿"Ï"]$! ;#"&2#"uþ†þ[­xy¬þ·þÐ5˜y3¾þL¿ºº¿¾»»˜hjþdþ•þÂþt/92ö¤)BKLBþ»þ·þ¸þ»`²Õ$”@H  *v —#vs v  # ( $( #"%ôì2ä2ÔìäÀÀ999991/<î22öî2þî9990KSXíí9Y"²]´ ]3!.+3!53#5! %32654&+?Yz-Ú™þîEaV=Àý¿¿TÉý–ƒŒ——ŒƒÙ \Wþ`yÃŒMýÝyyãyÑÀœµ!˜–‡ÿãLð)@?#"$!   * !˜~'˜~{'p* !1$0*ôÄìÔäìîî99991äôÄüìÆþì90KSXí9í9Y"²+]@ˆ"( ( ( ( ((( (!("(#: : : : ::: :!:":#X X X X XXX X!X"X#k k k k kkk k!k"k#ª ª ª ª ªªª ª!ª"ª#½ ½ ½ ½ ½½½ ½!½"½#?0+P+ +°+]]7332654&/.54$!2#.#"!"$žØ¿›¢n¬àÛ²' ƒ˜ĵ”—hËàлþÈþÑ’þàHb¨¦vrZd+78ǸÞ÷,,þ¶šgf]a474ÜÁâë2ßÕo@  ’s v ( #(ÔÄäüäÔìî1/î2ôî2990K° TK°T[K°T[X½ÿÀ@878Y@@_`€€ € € ]!53!#!#5!3sÆþg‰ȇþdÇyÓìuþ‹ìû-yFÿãÍÕN@$   vsp(( ((#.ôìäÔäüää1äô<ì2Î99990@ ?Ÿ¯¿]#5!#326#5!#! ¾¿®Óέ¾¿þØþ£þ¥þÖ\yyýþéßáëyyýþªþÝ&UÿôRÕŠ@9        *  vs  ÔÌ91/ô<ì290KSXí2ííí2Y"² ]@     # # @P ]]###5!# #5R}ýÍîýͼ‘“–²Õyú¤\yyü#Ýyÿî Õê@\          *  v s ÔÌ91/<ô<<ì290KSXí2ííí2ííííY"² ]@D "CFSV   && '##EFFGH@TX WP]]) !#5!# ! #5!#Ñþþþ®þ®þþþV‘Ä BH#²Ι?ûÁ\yyükûá¦yy 3Õ)@f   * v sv  ÔÌ91/<ì2ô<ì290KSXí2ííí2í2ííí2Y"²]@4*%   &+++))+]]K° TK° T[K° T[K°T[X½ÿÀ@878Y@8= = ;;44?O]] 3!53 #5!# #5!# 3!53¶þɸýþ-‰æ¤!®¸þêý¦?þ:yy;¨yyþ\¤yyýèý5yyÿîÉÕü@A       *  v sv    #ÔÄÄüÄÄ999991/ì2ô<ì290KSXí2ííí2Y"K° TK° T[K°T[K°T[K°T[X½ÿÀ@878Y@P       JJ[[Y Y _nnh o o xxx z  z  ppp¨ ¨  ¿ ¿ &]]!53#5!# #5!#3`ÉþD̦PN•¬þbÉyñòyyýÇ9yyýBýÛyLÕ y@"  * ’s ’    ÔÄÔìÄî991/îöþÄÄ0KSXííY"K° TK° T[K° T[K° T[K° T[X½ÿÀ@878Y´O]35!#!!53L{ý5‰üò‰¿ßhûAÑþ¦þò7@vv€ÔüÄ21üìÔì0!#3!7ÕÕýÉxùÎxÿBìÕ@ s/ÄÀ91ôÌ0#ÝÞýòÕùm“‘þòÉ@vv€ÔÄ2ì1üìÔì0!53#5ÉýÈÕÕøÞx2xϨåÕ@ sÔÌ91ôÌ290##ÍÕþJþJÕÕýÓ;þÅ-þþÛ´/Ì1ÔÌ0!5üþÛ¾¾î¦f-µÔÌ1ÔÌ0K° TK°T[X½ÿÀ@878Y #¤¤þ‹fþˆxTÿãD(Œ@1&&¢&¡Ÿ‰ž¢p #35# 2)ôÄìÔì22äî991/ÆäîþÆþäîî99990@,*:?????9O** +//   !" ]]3!5#"&546;54&#"#5>3 5#"326h˜þF¬n£¯ûýºz€jsq_Ìq þž…cjMORdýìy‡TP¯£³²?{Wcå""ÔýÞÕleedl/ÿãF!G@$!¤¤¢€¢pž> <58"ôì22ä2ôì1/ìäìüìîî99990²?#]7#5!>32#"&'!532654&#"ǘú-˜pãþûãp˜-þú_jmYYmj_y#xýŒSQþÕþûþûþÔQS‡yfº¦°å實ºTÿãƒD2@‰ ‰ žp3 >2ôìÔÌÔì1äüÄüÄþÄ0²]# !2#.#"3267ƒ&ëÊþäþÈ4oâup~r”}zŠkL¶³& (**þÙ‡ƒÈ÷ñÏ€xTÿãh !L@% ¤ ¤¢ € ¢pž55 <>2"ôìôäü<<ä1/ìäìüìîî99990¶?##¯#]54&#"3263!5#"32#5!o`inYZmi`b—þ-™pâþýâp™-˜úßiº¦¯åå°¦¬y‡SQ,*QSüxTÿãºDe@" ¢Ÿ ‰¦‰žp>9 ?2ôì2ôìÔÌ1äüììþäî990@"`ŸÏ¿¿¿¿¿ ¿ ÏÏÏÏÏ Ï ]]4&#"!32673# ! 5N^[OÛý%|Šsަ+ÿæþìþÙ. XÒ©¦Ãwηztµª#(þÉ?ße@& ¢Ÿ‰€ ¢§3 + 5Aô<ÄÄäü<Ääî1/î2î2þÆþäî2990K° TX½@ÿÀ878Y´0 0 ]#.#"!!3!53#5354632ßpKEPH þõÍý:—žžâÛU¢N NLs‰yüËyy5y…±·Tþ9hD,t@., #)¤¢ ‰#¤ž§¨p- 35 <&>2-ôÄìôì22äî1äììüìÆþÄîî9999990@  ( ?.     $ ]]!"&'53326=#"325!4&#"3265ÑþÁþÝjÚsq‹¤‡-™pâþýâp™-ùþ`inYZmi`®ü`àõ!!þifÇySQ,*QS‡yþšº¦¯åå°¦º?¢x@, ¡ ¢€¢ žJH5 F5CAôäì2äôìäää1/<îî2üîî99990¶]K° TX½@ÿÀ878Y¶/°]353#5!>323!534&#"3F—ž@¤}³·˜ý…EUkd‚y#xý}_TÓÍýÕyy5‡i«þ#yF× ;@ª ¢§ ¢K 5 5Aôä2üäÔì1/ì2üìÜì0@ /`°]4632#"&3!53#5!¼pQOooOQpƒ˜ýo——ùTQooQOonûuyy5yÿhþ9= L@% «ª ‰ ¢§¨3K 5 AôäüÄÔìî1ìüìÌîîä9990´ / ]4632#"&#5!#"&'53265²oRNpoOQp)—ùçá<ˆIq;BI:TQopPOonþªyû\£§âPG^{F®¹@H„ „ LL* ¢ ¢€¢ §  H5AôÄä2ü<ä991/<ìì2üìî290KSXí9íííY"²]@0        /?]])53#5!#5!#3!533Åý——ù­åÅþîÀsýž}þÙc†y#xüyyöýÁyy{XþÝF× 1@¢€¢55A ôä2üä1/ì2üì0@  / ` ° ]%3!53#5!?˜ýo——ùyyy#xFHD0|@?  +'¢)¡.ž%! ¢)§#  H N5 N"H* ($5&A1ôä2ü<äÔìäÔìäää91/<<îî2þ<î2î990@ 2/2@2`2p22]>323!534&#"3!534&#"3!53#5!>32ÛJ¬s·µ˜ý‡=S^hý >R_hýˆ——ù> n‚¢yjaÏÑýÕyyöÇh‘†ýòyyöÇh‘†ýòyy5y–]VcF¢Dy@, ¢¡ ž¢§JH5 F5Aôì2ä2ôìäää1/<îî2þîî99990¶]K° TX½@ÿÀ878Y¶/°]353#5!>323!534&#"3F——ù@¤}³·˜ý…EUkd‚y5y–_TÓÍýÕyy5‡i«þ#yTÿãD -@‰ ‰ž p>; >2ôìôì1äüìî0¶@`]%26&#" ! ¬p[Zqq\\qþçþÁ?>þÁTÀ¿ÁþþÂq+)þ×þùþúþÕ/þVFD #q@+ ¤ ¢"¢ ¤ž§ •p$4>32#"&'3!53)_jmYYmj_þž˜ú-˜pãþûãp˜-¤ýb˜Hiº¦°å實¬y‡SQþÕþûþûþÔQSþHyyTþVhD#S@*# ¤ ¢¢¤ž§• p$45<> 2$ôìôä2ü<<ä1äììüìî2îî99990´o%%]3!53#"325!4&#"3265Ñ—ýc¤-™pâþýâp™-ùþ`inYZmi`®û!yy¸SQ,*QS‡yþšº¦¯åå°¦º;LDU@% ¢¡ž ¢§ 43C 5Aôäì2äÔìä1/îî2þîîÄ9990@ /?O_]#.#"3!53#5!>32LqPLt†ÁýF—¢4«|Y3þÃUS̵þ\yy5y½ok Xÿã-D)@C  Q!  Q ! * !­­‰¬'‰¬ž'p* ! 33O$O2*ôÄìÔÄìîî99991äüäìæîää90KSXí9í9Y"@ ]@€+Ÿ+¿+) ) ) , , )6#E#Y Y Y Y Y YYY Y!Y"Y#j j j j j jjj j!j"j#Š Š Š Š Š ŠŠ Š!Š"Š#™ ™ ™ ™ ™ ™™ ™!™"™#© © © © © ©© ©!©"©#<]]7332654&/.54632#.#"!"&`q–lsIi’¥”ðú^Õq ‰€lo@S‘Ñ þÿþñcÞ)w}KF@F%)™‚­©!þômnEB6>%5œ‹´«1ÿã¨q^@ ¢Ÿ ‰p§ 8ô<ì2ÌÔÄÌ1ì2ôüäÄî2990K° TK° T[X½@ÿÀ878Y¶O_]#53!!!32673#"&5Ëššb'þÙ,:@>• ÀÛœ®yJþ¶yýu‹DVZ ‰·/ÿã‹'i@# ¡ ¢§p¢H5F 5 8ôìäôäü<ä1/ìäü<ì2î99990²]K° TK° T[X½@ÿÀ878Y´°]3!5#"&5#5!3265#5ô—þ?¤}³·˜úBXkc'üRy–_TÓÍ+yý“Ækž¬ÛyÿÛÙ'}@: „  „ LL* ¢ §   ÔÌ91/ü<ì290KSXí9ííí2Y"²(]@ ,+KK[[]!#5!# #5!#Éþ‡ub  ‹{þ‡®yyý` yyüRÿî 'Þ@[ „ „  L  L„„L L *  ¢§  ÔÌ91/<ü<<ì290KSXí2ííí2ííííY"² ]@: + 7    &##**(7669 GGCCFJ WW Y ]]#5!## ##5!#PòÈ‹}þ¿ôáãòþ¾tZ}Äî'ý;LyyüRšýf®yyýÁ¸Ó'3@e„„ L  L„„LL*¢§ ¢   /Ì91/<ì2ü<ì290KSXí2ííí2í2ííí2Y"²]@€       %+ + + )"""99?9?9 85566LIILDDZ^^ZX Wxx8$*59]]#5!# 3!53 3!53 #5!#ϼƒžþñ<ý\‰ÈÉþJ˜þÏw‰¦yyþ…þFyyþèyy¨yyÿåþ9×'ñ@\„ „„„LL*  ‰¢§¨3ÔÄÔì9991ìü<ì2þÄ99990KSXí2ííí2í2íY"²]@B  %%55<<<<<<FFSSVV]]#"&'5326?#5!##5!#0ˆs1xGqCCAP(þ1seüðubÞMJGc%5yyý‹uyyHF' …@$ LL * ® ®¢§ ¢  33 ÔÄ2Ôìî991/îþþää0KSXííY"K° TK° T[K° T[K° T[K° T[X½ÿÀ@878Y@ ' `]]35!#!!53Hbþ5wÞýìwy9¶+wüÇÀþɬþ²m*\@/ + #&' ˆ ¢ˆ€+# *& +Ô<Äü<Ä299999991üìÔüÔì99999990#"&'&&554&##5326554676633#"3m”ì¤2k==k2¤ì”gpRcƒaRpÕy1>$npú—sys—úpm%=1x^ˆþòŸ‡"„Ÿþñ‡^þßµÔÌ1ÔÌ0#ß×øºþ²y*^@0"+  #¢)¢¢€+)" +Ô<Ä2ü<Ä99999991üìÔüÔì999999903265467&&54&##53233#"##ºeoSb„‚dSoe’ì¤2kŒ>>Œk2¤ì’Õ^‡†"ˆžˆ^x1=%mpú—sys—úpn$>1ÙÅÛ?-@ ‡ ‡ÔÌ991ÔìÔìÀ99990#"'&'&'&#"56632326Û]»e_˜ ¬aM§``¹d_—­eM§?ÎVR:BHIÎWQ9DHÿÿÿðLƒ'$uÿðLm &)¶@d)')(" !')()&%$#*)"v' 'x$  v #'%$*!")( *ÔÄÔÌÔÎ999991/<î2æÆÖÎî9990KSXíí2ííí2íííY"32654&#"53&&546323!53!3!‘N57MN65Ný_z:?§uv§=<ŽýE’{ýÏ}²ÏäP6MM66MMùzyï%yJu¨¨uJv(ûyy1þÏy#;ÿÿVþoöð'&Ýoÿÿ`°k'(/uÿÿZþo'1¨uÿÿVÿã ƒ'2}uÿÿFÿã̓'8°uÿÿTÿãf'DXÿÿTÿãf'DCXÿÿTÿãf'D×XÿÿTÿãN'DŽXÿÿTÿãV'DØXÿÿTÿã'DÜXÿÿTþoƒD'FÝ‹ÿÿTÿãºf'H‹ÿÿTÿãºf'HC‹ÿÿTÿãºf'H׋ÿÿTÿãºN'HŽ‹ÿÿFøf'Öÿ…ÿÿ×f'ÖCÿ…ÿÿ þf'Ö×ÿ…ÿÿøN'ÖŽÿ…ÿÿF¢V'QØ×ÿÿTÿãf'R¬ÿÿTÿãf'RC¬ÿÿTÿãf'R׬ÿÿTÿãN'RެÿÿTÿãV'Rجÿÿ/ÿã‹f'XÃÿÿ/ÿã‹f'XCÃÿÿ/ÿã‹f'X×Ãÿÿ/ÿã‹N'XŽÃ9ÿ;öÕ 8@ ° ² °s TRT  Ô<Ää2ü<ä2Ä1ÄôÔ<ä2ü<ä203%%#5¦ã)–þj)ã)þj–ÕþJ#Ø#û®R#Ø#²dLþ@  zUUÔìÔì1ôÌÔÌ02#"&546"32654&Bz0/11-0|D¿ÁHdcIHdeþ3/0xDCy-03¿Á¢dHHbcGHd þÕÑL"S@+ u už p#   ">#ôìÔÄÌÔ<<ì22î1äüÄÄìÄþÆÄ99990%%#$%3#&&'667ãcWVR ½˜yþëþÒ.y;¡vqnd[h ^kÉÓÓÈÓ³þì%#þó&%þÙ~ ü…zj“üðL@(  vu{v ’   ô<ì2Ä2ÔìÔì91/Ä2ììôÄìî2ÄÄ990#&&#"!!!53!53#534$!2ßxcTuf`þ ¤‰û—ÁÁÁ Aµx²al•¯þôyýÓäþ“y=yØÔ?ÿ=ðð5CÆ@l)(*'W<=<$%#&W==<  WC6C  W66C*C=<6'  &- ‰‰3{D=@#69&  @#-'9C<#Y#WYW0@WV09WV*DÔäìÄÔäìÄîîîî99999999991ôÄìÔÄüÄÄ990KSXí9í9í9í9Y"#&&#"#"&'5332654&''&&5467&&546326654&'whaQ[6Z‡½rrSMÚÈSµfvhjW]5[‡¼ŽssSOÚÄJ®þr,.[n¨-/]pÃðVVJC/B/Hb¨sh”+/Z‰˜ðZRJE/B/Hc¨rg’,.Yˆ™ý¬!N-=f:X#O*@"    ‡‡‡  Ô<Ì291ô<ì2ü<ì2.À990!3!!!'7#5!7!Ùú‘–òþV¸büæú’–òª¸ýž×5}¸ãäãþɸãäÿÁÛÕ#À@Y  *”v!““v”Ž’vs v’  $) "( #$Ô<ì2ÄäÔìÔìôì2991/<Äìì22ôì2ìüäìììîä0KSXíí2ííY"K°TK°T[K°T[X½$ÿÀ$$@878Y!#53!3!53#5!#5!!53#5!!53‘ÑKs¾ýö¤þTrPÉŠý¦o‡‡þ‘o‡!;ú¤y/þÑyyãyþ ×þ!¾ýü¾ý¤×þ Dÿ²²! +|@=, +&  ) *& ~~&{p,,#* # )#+%%# ,ôìÔìÀ999999991äôìîÀÀ99990@ o--¿-Ï-] .#"324&'!"$''7&5!27¥*£t¾» /-Ÿtø ZZþSþˆžþ÷jÌZÈ[[­x  hËZߦw{þ»þ·L„ËzxNfAe+hþõ¤þ–þdNNÍZÉf £jMMËZÍÇßþ /=@-$ '!º» º!¹0 $`*`0ÔìÔì99991üì2üì2À999032654&#"&&#"326#"&546326632#"&®-{N^ulQJ|ö.zN]vlQK~ŸEœ`‹Á«Š]™XD _‹Á¬‰]—1KLoYVqr$LJqXUqtE…}ë°¸âu„€ì°·âqÙÛ)@ ‡ ‡  Ô<Ä2Ü<Ä21/ìÔ<Äü<Ä07!!!!#!5!ÙúþôýòæýòããþšäþšfäfÙÛ¤ $@  ‡ Ô<Ì2291/üÔÌ90%!55Ûúþüy‡úþãããÓÓÓíPáPÙÛ¤ $@‡  Ô<<Ì291/üÔÌ9055%!!Ùúþ‡üyúþ¶îþ°áþ°íÓþã'RÕ$ü@\  *v ¼ v vs"v#  #!  %Ô<ÄÄÄ2ü<ÄÄÄ29999991/ì2ô<ì2Ô<î2ü<î290KSXí2ííí2Y"²]@HD, ,##3 553;??<LLEGX o o•• ]]!53!5!5'!5!#5!# #5!#!!!!3F¾þm“=þª߉¶ª—´‡Ý$þ¢5“þm¾yZu;‡uÝyyýÙ'yyþ#utNuþ¦y9þV–'€@1 ¡ ¢¢§p•¢ 5 H5F5 A ôì2ä2ôäü<ää1/îìäü<î2î2î99990²!]K° TK° T[X½ @ ÿÀ878Y²@!]3!5#"&'3!53#5!3265#5þ˜þ7mJ;!˜ýn˜˜úDXjcƒ'üRy}SGþÃyyßyý¬ÜnŸ«ÛyLÿçþF)=@'! '½¾!½À* $$*ÔÌÜÄÌ991äÌÜìîî9906654&#"#"&54632#"&54324&#"32ú4,,Ì:*:­|ÀêþÇð«Þè«fˆMHe…MIe„–c³Bds’<+@lþ½þñþ­þF屯Wít|þôÏuy þwßÁ9@$  ÄÃÂÁ ÔÄ91üìüì990!#'&&#!!26773!5Ó‹X\S~ýÓšý!v0" HX®úã6üÏÁþSú4+üñ)ýX&åýÅGôÍ/þw‡Á=@" Âà ÂÁa ba c baÔä2Äüää2þä1üì22ü<ì20!#3!53!3!53#/X¾¾ýF²ýº°ýF¿¿ÁTù^TT¢ù^TT¢F–'K@#¢§ ¢ HH 5F5Aôìä2ôìä2ää1/<î2þî220@ /@]353#5!#3!53!3F——P˜˜ýƒƒþ£‚y5yyüËyy5üËy1þ‹q)*@$ÆÇ ÆÅ*'! de!d*Üìüì91üÌìüÌì026732#"&'&'&'"#"&54632VfÖÝbwL>.> c ('8¹z`yNB2F üˆKüÀbPþØþ×f”›bN>J?(:=øÁð!,k@7"*# È#È*È ÉÈ {-$''"f'f-ÔÄìÔì22ÄÎ99991ôÄÄüäÄîÍÖîÎî99990!!3!5#"&5463354&#"#566325#"326qüâÝsþ…3U{…½ÀŒ^_LX `IšTÖÆþøeHS=9?K‡Äþ–^\96zr€~ZYA>¦”þ„KA>CJ=øÃð*@È È{ f fÔìÔì991ôìÔìÜÌ0!!2654&#""&54632qüâLCCLMBBMÔïïÔÔïï‡?Ž£¤ŽŒ¦¥ŒVз·ÑÑ··Ð\Ãð#K@(« ~{g g %!% $ôÄìÔÄìîîìì991/<Î2öîä2990%!53!56#"!3!&5! áN‰ý#œ ÈÀÀÇ¢šý"ˆOíôÁrrÂô¸}þËÁ 0 '5þËþ×þûþÍ Á5}\AÜ<ƒþ}þÄÜþ¿TÿãnD5@Å@E(.&>6.&¢7¢&Ÿ‰> .Ÿ+‰¦03 ž p&A8&;?'.3/6'?;/#2AôÄìÔÄìÄ2îÎî299991Ää2ü<Äìü<äîþäîî9999990@@:,?-?.?/?0?1PBÏB+-/.//$%&'789:¿¿¿¿¿¿ÏÏÏÏÏÏ]]4&#">3 !32673#"&'#"&546!354&#"#5>325#"326éN^[OÄM¹o ý%|‹rŒ¨+ÿæ†ÐNYÓ|ÎÖÿº{grq_Ìq‰Ä…mjOYV^XÒ©¦ÃPNNþÊþÓηyuµªMONN­¥´±?t†Waå""MýSÙnqq`p3ÿš#‰'|@>('%" &" ‰‰"žp((&%'?;?2(ôìôìÀ9999999991äüìîÀÀ99999990´@)`)] .#"326=!"&''7.5!27áƒZMn]\Mm\ BCþÁþçoºP¬T¤AB?t½H¨V ZX¿ëþÝYY¼ìH¿vþúþÕ12¬V£KÁu)21¨V\ÿã+ð "7@!r ‰ p {#! #ÔìÔìÔìÔì1äôÄìþÕÖÎÄ0#"&54632#"$54$75332673ZpNOnoNNpÑ|àiüþòõ‹‹ƒzxmw x1NnnNOpqú¨""ÝÍÊéÍþÕ+¹™‘’„‚ð &@r {  Ôìôì991/ôüÌ0#"&54632!53pNOnoNNpþ‰u‹1NnnNOpqúJ¾¾ÙÛ‡@ ‡ÔÔÌ1Ôì90!#!Ùåûã‡ý˜…Hÿ×Dž *@  ËÊ  ÔÄ91Äüì903##'%uÏgý°dþÉŒKìžùºZ3qtýkþP-ð%@ML!"!L""!L%%  L%*! "vu u{¨$&%#"!  &ÔìÔì9991Ä2ìôÄìÆîî2ÄÄ99990KSXí9ííí9Y"6632#4&#"!!#"&'533267#5!1èÈC™Yy49 ?/25ôìÔäìÔÌî2991ä2ü<ì2ìþ<äî99990@6¿ ¿¿¿¿¿Ï ÏÏÏÏÏ ]]%26&#"4&#">3 32673#"&'# !2¬p[Zqq\\O]ZNÇKºv ý%zŠsަ'üÑ„ÆHFÔ‡þòþÆ?ÇTÀ¿ÁþþÂÒ©¤ÅPPLþÆþØ϶zt®±MOMO.)M¨˜´/Î1ÔÌ0!!ü˜ð¨˜´/Ì1ÔÌ0!!ø˜ð¦#ð2@   { i iÔüÄÔüÄ991ô<Ä2Ì2990!67!67#`Yþò©­þ˜`Xþó¨¬hC½‹7ÏaˆC½‹7Ï`b‹øÕ4@   s ii ÔÄüÔÄì991ô<Ü<Ä29906655!%6655!3`V¨¬ýÆ`W¨¬C¼7Ñþèa‡C¼7Ñþèa¦Rð@ { i ÔüÄ91ôÄÌ90!67R`Xþó¨¬hC½‹7Ï`b‹'Õ@s i ÔÄì91ôÜÄ906655!b`W¨¬C¼7ÑþèaÙ{Û‰ '@ ‡  Ô<ÄÜ<Ä1ôÌüÌÎÎ04632#"&4632#"&!!ÅX=>XX>=XX=>XX>=Xþúþô=XX=>XXýZ>XX>=XX!äþ#îu"@ÔÌ91ÔÌ990 úþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿÿåþ9×N'\ŽTÿÿÿîɃ'<ÛuþƒÿãÓð)@*p{ÔÄ1ää0KSXÉÉY"3#)ªüZªðùóL=ÏÅ /u@> )0- *( -!'-0  )'!$* $ ( $ 0ÔÄ2ÌÔÄ2Ì9999991ÔÌÔÌÀÀ9999999902654&#"'7&&5467'766327'#"&[€\[€~|Ñ—ÑÑ™Ï0l=7m9͘ÑÑœÏ.j?:l¦\\\]~šÏšÑ.k@?l.ÍžÓÓšÍ8o6?i/ÓšÓžƒs-@ hÔì291ÔÌ905sððþ+-“þ¾þ¿”¨Áƒ–-@ hÔ<ì91ÔÌ905ÁÕþ+ïï-þ¨þ”AB?¢"l@4"¢‰€ ¢§ JH3 5 F5A#ô<Äì2äôìäÔìää1/<î2î2þîî2Ä9990@ $$/$$°$]#.#"!3!53!3!53#5354$!2ºp xi”‹˘ý…þ—‚ý…—žža×vôVZŽ™VüRyy5üËyy5yLÎÓ?ža@/ ¢ ¢€ ¢§ J H5 F5Aô<Äì2äôìäää9991/<î2î2þîî2990@ /°]4$)3!53#"3#3!53#53Ý$2Ó˜ý…X€òò‚ý…—žžsÕÌúeyy+Œ›VyüËyy5y9ÿ;öÕa@5°²° ° ²° s T R T Ô<Ä2ä22ü<ä22Ä21äÔÄ2Æ2æ2ü<ä2ä2ü<æ203%%%%#55¦ã)–þj))–þj)ã)þj–))þj–ÕþJ#Ø#þúþü#×#þI·#×##Ø#¦ #… µ   ÔÌ1ÔÌ04632#"&¦pNOppONpÇNppNNoo=þö?@  i ÔÄì91ÔÜÄ906655!=`W¨¬ƒC¼Œ7Ïþæ`=þöÓ?3@    ii ÔÄüÔÄì991Ô<Ü<Ä29906655!%6655! `Y¨¬ýÆ`W¨¬ƒC½‹7Ïþæ`‡C¼Œ7Ïþæ`1ÿã ãð #/3?Kk@723030121*@ }}*}$F}4:2p0${L C= I17!'73-LÔÄìÄÔìÄîÍÖîîÖî1ä2ô<<Ä2ì2îÖîî20KSXÉÉY"2#"&546"32654&"32654&'2#"&546!3#2#"&546"32654& Z¿Ê˾¾Ë˾@77@A88ø@88@A88A¿ËË¿¾ËËN¬üZ¬;¿ÊÊ¿¾Ë˾A89@A88ÑÄÅÓÓÅÄÑd‰¨©ŠŒ§¦‹ß‹¦§ŒŒ§¦‹eÑÅÅÒÒÅÅÑùó-ÑÄÅÓÓÅÄÑd‹¦§ŒŒ§¦‹ÿÿÿðLk'$uÿÿ`°k'(/uÿÿÿðLk'$uÿÿ`°ƒ'(/uÿÿ`°k'(/uÿÿ``k',ÿßuÿÿ``k',ÿßuÿÿ``ƒ',ÿßuÿÿ``k',ÿßuÿÿVÿã k'2}uÿÿVÿã k'2}uÿÿVÿã k'2}uÿÿFÿãÍk'8°uÿÿFÿãÍk'8°uÿÿFÿãÍk'8°uF×' 1@¢§¢55A ôä2üä1/ì2üì0@  / ` ° ]%3!53#5!?˜ýo——ùyyy5y‡îyf<@ ÔÌ91ÔÌ290K° TK°T[X½ÿÀ@878Y´XW]3#'#‡ò¤ÕÕ¤fþˆáášfVr@      ÔÌÔÌ99991ÔÜÔÌ99990@,               ]]5463232653#"&/&#"šjf%G.G,$)1njf%G.H-$)1’—/F=’—/F=ÅP; (µÔÌ1ÔÌ0K° TX½@ÿÀ878Y!!ÅvýŠ ¼ªþV5 6@  ÔÌÔÌ1ÔÌÄ20K° TK° T[X½ÿÀ@878Y332673#"&ª}pccp}µ¡£±5INNI’¥¢m)“N A¶  _ Ôì1ÔÌ0K° TX½ @ ÿÀ878YK° TX½ ÿÀ @878Y4632#"&mW<;y0f4-U$AJ)-œ \T4m‡îyf4@ ÔÌ91Ô<Ì90K° TK°T[X½ÿÀ@878Y 373‡ÿ¤ÕÕ¤ÿîxããþˆÕO@,  v s’v  ( ( #"ô<ì2ä2Ôìä99991/îîöî2Ä90353'%#5!#%!53mÀ×FÀ¿TFþfL‡y¬u¨™yyþNÉuôýìþ‹`@# ¢ €¢5  5 Aô<ä2ü<äÀ9991/ì2üì90@  /Z`°]]%3!53'7#5!7D—ýo—›>Ù—ú›@Ûyyy`i…xýÓai…ÿÿ‡ÿãLk'6ãuÿÿXÿã-f'VàBÿÿLk'=ìuÿÿHFf']àFþ¢ß˜@ Ô<Ì21ÄÔÌÎ0##ß××טý öüý öX¦Õ L@& ’ vsv  % (#"ô<ì2ä2Ôì99991/ì2ôì2ü<ì20²¿]%32+!!53#53#5! !®‹ê××ê‹Lþ´ý¿ÀÕÕÀ©þWþpy+HF*ýö‰ý7yP‰ yþþ–þ•þTÿã-j@7" "‰ (‰p €.+% +% +>;%> 2.ôìôì99999991ìÄôìîÀ99990´@/`/]! 5432.''%.'7%.#"32654&¼ÉþÂþæþíþ»?ô*V,A/þÁ24™dŒê[J/þ½/K o^^oo\9•þmäþíþÉ%ôæ. ?n4•dƒ&>nI7šgýÅ¿åê¾¼ìk¿ÿÿÿîÉk'<Ûuÿÿÿåþ9×f'\T`ÑÕW@)v vvsv / *# ("ôä2Äü<<äî999991/î2öî2ÕîÖî0¶Pp€]353#5!#!2#!332654&+`¿¿/ïù&þÙøþîññp‚›šƒpyãyyªíÇÇïÏyÁ¬‘«/þVF #q@+ ¤¤"¢ ¢€p •ž$4>32#"&'3!53)_jmYYmj_þž˜ú-˜pãþûãp˜-¤ýb˜Hiº¦°å實šxýŒSQþÕþûþûþÔQSþHyyÙÛô¶ÔÌ1ôÌ0!!Ùúþôæ/¬Õ /@    Ô<Ì291Ô<Ä290 '7¬þH¸šþHþHš¹þGš¸¸9þHþHš¸þHš¸¸œþH¸¬ôð ?@ÈÈ*ÈÎ{ k ÔÄÄüÄ1ôüì290KSXííY"535733¢¤·Þ㤬^eei}ý^V¬ð@@   «ÈÎ{ k ÔÄÔÌÎÔî9991ôÄìüäÞÄ990#56632!53!576654&#"¼^H—PµÈmôždýH»dSI?WÀrRZ‹`ú…T{Œ]T_SZœ/ð*N@) È«È)«&ÈÎ{+ # )#kk +ÔÄÌÔìÔüÄÎ9991ôÄÄìüäÆþäî906632#"&'5332654&##532654&#"oX•@´ºifx|ÌÉP P`VOX]b[)QWNHBP`ÉidH^o]z{ÈPOVRPWTD@?FI@ÿÿÿãð'ð'¼ ×ýdÿÿÿãåð'ð'¼ñ×ýdÿÿZÿãð'ò'¼ ×ýdÿÿVÿã3k'* juÿÿTþ9h5'JÚÍÿÿ``ƒ', ÿßuÿÿ‡þoLð'6ÝãÿÿXþo-D'VÝBÿÿVÿãök'&yuÿÿTÿãƒf'F˜ÿÿVÿãök'&yuÿÿTÿãƒf'Fà˜Tÿã} )a@1 & ¢(¤ ¤"¢$€ ¢pž#l!5'% <>2*ôìô<Ääü<ä91/ìäìüìîîÕ<î299990¶?++¯+]54&#"3263!5#"32!5!5#5!3#o`inYZmi`b—þ-™pâþýâp™-þ¼D˜ú¬¬ßiº¦¯åå°¦¬y‡SQ,*QS'x]xÕxožã¬µÜÌ1ÔÌ0!!otýŒ¬þò¦ #… µ   ÔÌ1ÔÌ04632#"&¦pNOppONpÇNppNNooÿøÿã1ð4u@?-v1uu"v+${p5-+%($,#5  "., #,(4( 5ÔÄ2ìÔÄÔìÄÄ9999999991ääÔ<Ì2ì2îÖîþìî20#"#734'&54765#7332#&&#"!!!!32671&þþÒþþ±4¾5y®5‰4Oþlæ‹v(‘t‚”×6þYR5þì•„p‘ªßè$ w58 w $>Cþ‘Ä·Úàw,16wÞÜ­¥és |@  _ _ÔüÔì1Ô<Ì20K° TK°T[X½@ÿÀ878YK° TK° T[K°T[X½ÿÀ@878YK°TK°T[K°T[X½ÿÀ@878Y4632#"&%4632#"&X<;VU<?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•ÍfÉɃ+ô‹‘¶š19RsÃÉÁÉh/-´ÙÉRoɦì‘`‘ú‘‰‘‘T‘¨‘‘¢‘j‘oô¼ô5´Ù´Ù´Ù°…‡5ÿðÃ`^Vð``®`ÕV`¾`Éÿjô` `ÛVPZøV`øV¦`LJôúF5ÿôüÿî5 ¶ÿî×LÉìÉ‘´Ï/T˜/ßT˜TTq?˜TÑ? Fåÿh‹F FwFÑFVT˜/˜T7;X²1Ñ/¦ÿÛãÿîŦÿå‹H%¬é%º´Ù5ÿð5ÿð^V`PZøVúF/T/T/T/T/T/TßTTTTT F   ÑFVTVTVTVTVTÑ/Ñ/Ñ/Ñ//9²‘ ‘“/?'“FîZ´ÙFÿÁøDªÍ´Ù´Ù´Ù‘'Û9FL¼/ÛF¢1å==\ÍTV3°\ƒ´ÙBH‘´Ù)žÁ¦‘5ÿð5ÿðøV qV9TššbÉÉb´Ùô¦ÿå¶ÿîVþƒL3ž3ÁÑ?Ñ?/9ɦÉ=š= 15ÿð`5ÿð``¾`¾`¾`¾`øVøVøVúFúFúF F‡šÅªmãá=‡®LJX×L‹HéþXVT¶ÿî¦ÿå`˜/´Ù´VZXXXZÕV˜T¾`LJX^VßT^VßT˜TRoɦ‘ÿøZšÙ‡‡1¬mÿ'ð   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ     sfthyphenperiodcenteredEuroc6459c6460c6461c6462c6463c6466c6467c6468c6469""""VwÝbÛ°Æõ#w¡ÆÜüVŠåN˜ðJ|èG}¸Üþ r  † ç 8 ~ Î  p È ù [  F Ò3|É)­qÄzß‚Ùú6Xl’o¶xÖU¼þTÜŠñ6§ \#xÕ1È‘9–  Æ Ó!r!!Œ!™!¦!³!À!Í!Ú!ç!ô""""("5"B"O"\"i"v"ƒ"""ª"·"Ä"Ñ"Þ"ë"ø#0#m#Õ$+$ð%!%U%Ý&©'>'º'ß(+(n))“)ø*,*Y*†+=+­, ,T,“,×-.-¦-è.K/ /Ž/à00/0^0à1e1¡1×22Y2Y2f2s2€2ò3‡3›3¯3ì4*4N4r4³4Ý4ê4÷55ž5½5Ý6G6£777B78"8/8<8I8V8c8p8}8Š8—8¤8±8¾8Ë8Ø8å99A9¦9Ç9û:2:‚:²:ä;;B;;ß;ì;ù<<<5<===,=„=ö> >E>z>Å?)?:?K?\?i?v?ƒ???ª?·?Ä?Ñ@A@W@uAAeAB5B`B—BÒCCUC§Æt ¸7þ­9ÿk:ÿ;ÿk<ÿ»ÿêÿ$7ÿ$9ÿk$:ÿš$<ÿš$IÿÜ$WÿÜ$Yÿ­$Zÿ­$\ÿ­$µÿ $·ÿ $ºÿ­$»ÿš$ÀÿÜ$ÁÿÜ$êÿš$ëÿ­%&%&&%*&%2&%<ÿÜ%d&%g&%‘&%¯&%°&%»ÿÜ%Ð&%Ñ&%Ò&%êÿÜ%ö&%û&%ý&&ÿÜ&ÿÜ'ÿ·'&'ÿ·'9ÿÜ(&)ÿ2)ÿ¤)ÿ2)ÿ·)ÿ·)$ÿˆ)Dÿ)Hÿ)Rÿ)UÿÜ)XÿÜ)bÿˆ)iÿ)jÿ)kÿ)lÿ)mÿ)nÿ)pÿ)qÿ)rÿ)sÿ)yÿ)zÿ){ÿ)|ÿ)}ÿ)~ÿÜ)ÿÜ)€ÿÜ)ÿÜ) ÿ)¡ÿ)­ÿˆ)®ÿˆ)±ÿ)Çÿˆ)Éÿˆ*ÿ·*&*ÿ·*<*»*ê-ÿ­-ÿa-ÿ­-ÿ­.ÿk.$ÿ­.&ÿÉ.2ÿÉ.8ÿ·.:ÿ·.<ÿÉ.HÿÓ.RÿÓ.XÿÓ.\ÿ¤.bÿ­.dÿÉ.gÿÉ.hÿ·.pÿÓ.qÿÓ.rÿÓ.sÿÓ.yÿÓ.zÿÓ.{ÿÓ.|ÿÓ.}ÿÓ.~ÿÓ.ÿÓ.€ÿÓ.ÿÓ.‘ÿÉ.¡ÿÜ.­ÿ­.®ÿ­.¯ÿÉ.°ÿÉ.±ÿÓ.ºÿ¤.»ÿÉ.Çÿ­.Éÿ­.ÐÿÉ.ÑÿÉ.ÒÿÉ.Óÿ·.Ôÿ·.Õÿ·.êÿÉ.ëÿ¤.ûÿÉ.ýÿÉ/7ÿY/8ÿ/9ÿ /:ÿu/<ÿ}/\ÿ·/hÿ/´þ/µþ/¶þ/·þ/ºÿ·/»ÿ}/Óÿ/Ôÿ/Õÿ/êÿ}/ëÿ·1ÿ}1ÿ}1ÿ·1ÿ·2ÿˆ2K2ÿˆ29ÿÜ2;ÿÜ3þø3ÿ3þ­3ÿ·3ÿ·3$ÿk383DÿÉ3HÿÉ3RÿÉ3V3bÿk3h3iÿÉ3jÿÉ3kÿÉ3lÿÉ3mÿÉ3nÿÉ3pÿÉ3qÿÉ3rÿÉ3sÿÉ3yÿÉ3zÿÉ3{ÿÉ3|ÿÉ3}ÿÉ3 ÿÉ3¡ÿÉ3­ÿk3®ÿk3±ÿÉ3Äþø3Åþø3Çÿk3Éÿk3Ó3Ô3Õ3ä3ú4ÿš4K4ÿš4µ4·57ÿÜ59ÿ·5:ÿÓ5<ÿÁ5D/5\ÿÜ5i/5j/5k/5l/5m/5n/5 /5¡&5µÿ·5·ÿ·5ºÿÜ5»ÿÁ5êÿÁ5ëÿÜ6ÿ·6K6ÿ·66ÿÓ6ãÿÓ6ùÿÓ7ÿ7þ­7þø7ÿ·7ÿ·7$ÿ77ÿ·7Dÿ<7Fÿ7Hÿ7Rÿ7Uÿk7VÿD7XÿD7Zÿ7\ÿ7bÿ7iÿ<7jÿ<7kÿ<7lÿ<7mÿ<7nÿ<7oÿ7pÿ7qÿ7rÿ7sÿ7yÿ7zÿ7{ÿ7|ÿ7}ÿ7~ÿD7ÿD7€ÿD7ÿD7 ÿa7¡ÿa7©ÿk7ªÿk7­ÿ7®ÿ7±ÿa7ºÿ7¾ÿk7¿ÿk7Äÿk7Åÿk7Çÿ7Éÿ7äÿD7ëÿ7úÿD7üÿ7þÿ8ÿD8ÿÜ8ÿD8ÿ·8ÿ·8$ÿÁ8-8bÿÁ8­ÿÁ8®ÿÁ8ÇÿÁ8ÉÿÁ9þš9ÿk9þš9ÿ29ÿ29$ÿa92ÿÜ9DÿD9HÿD9LÿÜ9RÿD9Xÿ}9\ÿ­9bÿa9gÿÜ9iÿD9jÿD9kÿD9lÿD9mÿD9nÿD9pÿD9qÿD9rÿD9sÿD9yÿD9zÿD9{ÿD9|ÿD9}ÿD9~ÿ}9ÿ}9€ÿ}9ÿ}9‘ÿÜ9 ÿD9¡ÿD9­ÿa9®ÿa9¯ÿÜ9°ÿÜ9±ÿD9µ&9·&9ºÿ­9Äþø9Åþø9Çÿa9Éÿa9ÐÿÜ9ÑÿÜ9ÒÿÜ9ëÿ­:þÁ:ÿ:þÁ:ÿu:ÿu:$ÿ}:DÿN:HÿY:LÿÜ:RÿY:Uÿ¤:Xÿ­:\ÿÓ:bÿ}:iÿN:jÿN:kÿN:lÿN:mÿN:nÿN:pÿY:qÿY:rÿY:sÿY:yÿY:zÿY:{ÿY:|ÿY:}ÿY:~ÿ­:ÿ­:€ÿ­:ÿ­: ÿu:¡ÿY:­ÿ}:®ÿ}:±ÿY:µ&:·&:ºÿÓ:Äÿ:Åÿ:Çÿ}:Éÿ}:ëÿÓ;ÿ·;$ÿ·;&ÿÜ;2ÿÜ;bÿ·;dÿÜ;gÿÜ;‘ÿÜ;­ÿ·;®ÿ·;¯ÿÜ;°ÿÜ;Çÿ·;Éÿ·;ÐÿÜ;ÑÿÜ;ÒÿÜ;ûÿÜ;ýÿÜ<þø<ÿ2<þø<ÿ<ÿ<$ÿ}<&ÿÜ<Dÿa<HÿN<LÿÜ<RÿN<XÿN<bÿ}<dÿÜ<iÿa<jÿa<kÿa<lÿa<mÿa<nÿa<pÿN<qÿN<rÿN<sÿN<yÿN<zÿN<{ÿN<|ÿN<}ÿN<~ÿN<ÿN<€ÿN<ÿN< ÿa<¡ÿN<­ÿ}<®ÿ}<±ÿN<Çÿ}<Éÿ}<ûÿÜ<ýÿÜ=ÿÜ=ÿÜIÿÓIÿ·Iÿ·I´AIµ—I·—Nÿ­RÿÜUÿkUÿDU´KUµKU¶KU·KYÿYYÿ2Y´KYµKY¶KY·KZÿYZÿ2Z´KZµKZ¶KZ·K[ÿÜ\ÿ<\ÿ\´K\µK\¶K\·Kb7ÿb9ÿkb:ÿšb<ÿšbIÿÜbWÿÜbYÿ­bZÿ­b\ÿ­bµÿ b·ÿ bºÿ­b»ÿšbÀÿÜbÁÿÜbêÿšbëÿ­dÿÜdÿÜe&fÿ}fÿ}fÿ·fÿ·gÿˆgKgÿˆg9ÿÜg;ÿÜhÿDhÿÜhÿDhÿ·hÿ·h$ÿÁh-hbÿÁh­ÿÁh®ÿÁhÇÿÁhÉÿÁyÿÜzÿÜ{ÿÜ|ÿÜ}ÿÜ&‘ÿˆ‘K‘ÿˆ‘9ÿÜ‘;ÿÜ¡ÿÜ©-ÿ·©7ÿkª-ÿ·ª7ÿk­7ÿ­9ÿk­:ÿš­<ÿš­IÿÜ­WÿÜ­Yÿ­­Zÿ­­\ÿ­­µÿ ­·ÿ ­ºÿ­­»ÿš­ÀÿÜ­ÁÿÜ­êÿš­ëÿ­®7ÿ®9ÿk®:ÿš®<ÿš®IÿÜ®WÿÜ®Yÿ­®Zÿ­®\ÿ­®µÿ ®·ÿ ®ºÿ­®»ÿš®ÀÿÜ®ÁÿÜ®êÿš®ëÿ­¯ÿˆ¯K¯ÿˆ¯9ÿܯ;ÿܰ&´$þæ´-´99´:9´;9´<9´bþæ´ÿ´­þæ´®þæ´»9´Çþæ´Éþæ´ê9¶$þæ¶-¶bþæ¶ÿ¶­þæ¶®þæ¶Çþæ¶Éþæºÿ<ºÿº´KºµKº¶Kº·K»þø»ÿ2»þø»ÿ»ÿ»$ÿ}»&ÿÜ»Dÿa»HÿN»LÿÜ»RÿN»XÿN»bÿ}»dÿÜ»iÿa»jÿa»kÿa»lÿa»mÿa»nÿa»pÿN»qÿN»rÿN»sÿN»yÿN»zÿN»{ÿN»|ÿN»}ÿN»~ÿN»ÿN»€ÿN»ÿN» ÿa»¡ÿN»­ÿ}»®ÿ}»±ÿN»Çÿ}»Éÿ}»ûÿÜ»ýÿܾ-ÿ·¾7ÿk¿-ÿ·¿7ÿkÅ7þøÅ9þÓÅ:ÿÅ;Å<ÿDÅYÿ·ÅZÿ·Å»ÿDÅêÿDÇ7ÿÇ9ÿkÇ:ÿšÇ<ÿšÇIÿÜÇWÿÜÇYÿ­ÇZÿ­Ç\ÿ­Çµÿ Ç·ÿ Ǻÿ­Ç»ÿšÇÀÿÜÇÁÿÜÇêÿšÇëÿ­È&É7ÿÉ9ÿkÉ:ÿšÉ<ÿšÉIÿÜÉWÿÜÉYÿ­ÉZÿ­É\ÿ­Éµÿ É·ÿ ɺÿ­É»ÿšÉÀÿÜÉÁÿÜÉêÿšÉëÿ­Ê&Ë&ÐÿˆÐKÐÿˆÐ9ÿÜÐ;ÿÜÑÿˆÑKÑÿˆÑ9ÿÜÑ;ÿÜÒÿˆÒKÒÿˆÒ9ÿÜÒ;ÿÜÓÿDÓÿÜÓÿDÓÿ·Óÿ·Ó$ÿÁÓ-ÓbÿÁÓ­ÿÁÓ®ÿÁÓÇÿÁÓÉÿÁÔÿDÔÿÜÔÿDÔÿ·Ôÿ·Ô$ÿÁÔ-ÔbÿÁÔ­ÿÁÔ®ÿÁÔÇÿÁÔÉÿÁÕÿDÕÿÜÕÿDÕÿ·Õÿ·Õ$ÿÁÕ-ÕbÿÁÕ­ÿÁÕ®ÿÁÕÇÿÁÕÉÿÁá7ÿYá8ÿá9ÿ á:ÿuá<ÿ}á\ÿ·áhÿáµþÓá·þÉáºÿ·á»ÿ}áÓÿáÔÿáÕÿáêÿ}áëÿ·ãÿ·ãKãÿ·ã6ÿÓããÿÓãùÿÓåÿÜåÿÜèÿ·èKèÿ·è$ÿÜè9ÿÜè<ÿÜèbÿÜè­ÿÜè®ÿÜè»ÿÜèÇÿÜèÉÿÜèêÿÜéÿÜêþøêÿ2êþøêÿêÿê$ÿ}ê&ÿÜêDÿaêHÿNêLÿÜêRÿNêXÿNêbÿ}êdÿÜêiÿaêjÿaêkÿaêlÿaêmÿaênÿaêpÿNêqÿNêrÿNêsÿNêyÿNêzÿNê{ÿNê|ÿNê}ÿNê~ÿNêÿNê€ÿNêÿNê ÿaê¡ÿNê­ÿ}ê®ÿ}ê±ÿNêÇÿ}êÉÿ}êûÿÜêýÿÜëÿ<ëÿë´KëµKë¶Kë·Kìþøì&ìþÓíÿÜíÿšöÿ·ö&öÿ·ö<ö»öêùÿ·ùKùÿ·ù6ÿÓùãÿÓùùÿÓûÿÜûÿÜýÿÜýÿÜ UG@+ƒþ þƒþƒ ã ‡¼GÌþBGÌSðf€¯ JBits ûþšƒãB·É'#sÕVeraSerifBdÿÿÿÿ6ÿÿþ628B00‚                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       !                         !        #                         #        $                      $        %                   %        '             !   '        ÿÿÿð_<õº¿5ߺÂ*^þƒþ ムloganalyzer-3.6.5/src/BitstreamVeraFonts/VeraMoBI.ttf0000644000175000017500000015337012225176641022041 0ustar danieldanielOS/2µ†ö}ÀÜVPCLTc¥kÁ46cmap¤Ãè ´HXcvt ¤>ˆ06fpgmçQñÄ#ø‹gaspÖ´ glyf’«`h$„ÂhdmxÇ33>ÁlHheadÙ—âÖÀ6hhea M[À¸$hmtxÍlL· 8locaõó¾xmaxpâgÀ˜ namešµL- $post*(¥ù»ØžprepÔ±Ÿ™ hŽ:: S%:%: _k0ă  š ‡ t ² 0 &  X J & J &  p 8 ˆ ` : ¸ 0æ & ÀCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans Mono Bold ObliqueRelease 1.10BitstreamVeraSansMono-BoldObCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans Mono Bold ObliqueRelease 1.10BitstreamVeraSansMono-BoldObCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com#3#¶îN#'#¸\ #Í#3#þ#/٨𢃮º¦˜¼°ô%¢Ã%1ž/;¶¢¤Å¤sÕÃáîÕ˜¢ÕÕðqÕîoúVú#Áéd\œH¾```{ÓšÃî\{šá`ª¸ߢƒšoÍ7ºLøÑ'5ª%ÓÕ={¢¤ðD=!Ï¢/îÑs¸€@t˜þ•»”»“ú‘úG»GŽ2–Œ2‹dŠ–‰ˆ‰kˆ†…þ„ƒ „úƒ ‚Œ‚þ‚À€YŒ€€&€Y€@&~2}þ|{zG{þ{¸ÿÑ@ÿzyAzGyAxw2xkw2vþuþtúsúrþqp%olþkj j ii€hghh€gg@fþeþd:d}cbcbaba`;`2_^_^];]d\ [Z»[þZY]Z»Z€YX%Y]Y@X%WþV;V}U:U2T;T'SRSdRQ–PdOSM;M2L:L2KJ;JdIþHþGF F F@ED.EþD@ÿ.CBA»BþA@]A»A€@=%@]@@?k>=%>»=%<;4K–7 7   @6ú 2 ú  2X}X–¸d…++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX °šEDY!-,°%E`D-,KSX°%°%EDY!!-,ED-hþ–h¤@ ˜˜7/ÄÔì1ÔìÔì0!%!!hüsüåþ–øòr)RÕ ]@.    49    ÔäôÄÀ99991/äÜÄ0KSXíííí9Y"!!!#‰ 7þö# fÇ!þåÕýqþ›eçªçÕ@ 9ÔÌÔÌ1ô<Ì20!!!çÿÿÿÕýÕ+ýÕ+ÿ×ô¾N@3      ÔÌ91/<Ä2Ô<<Ì22Ô<<Ì220#3333#3#####73#73ðËJË^Í^Ý^ð6ñHð6ñ^Þ_Í^Þ_ð5òHð5ò^qþÛrþŠvþŠ×þÛ×þ‹uþ‹u×%×v'þÓD /m@;)%%$(<2 ZD*9û’-.,=BZ(¤|±íííú',þÂ.¨‚¸ï!Ø '3V@-(  (?? ?>.?%1"+1""4ÔÄìÜìîÞî99991/îÎöîÞîî999904632#"&"32654&4632#"&"32654&!º……»»……º?9PP9:OPþ½)ûè˹†„¼¼„†¹=8ON9:QRX†º»……º¹O::OO:9PýP¢`þ^’†º»…„»¹P::OP99Qÿßÿã¾ð&0—@O$%$&%%$()'/.040'$ % -<;C<BE%%!&!0$ ' !* 1ÔÄìÔÌî99999991/äöîöîî99990KSXÉ9É9ÉÉ9Y"%#"&547&&54$32&&#"6673!3267ãV³WÀäź äF‡A16€BX^&(Ý*0ë xlsþÄþ®Z^^,Z.H23Õ°£i:d/·Ûÿ#&GB"tWþ :š]û[öÛ4•\c„çªçÕ¶9ÔÌ1ôÌ0!çÿÕýÕ+Rþò7 @ G   ÔüÄ9991üÌ0#&57éê89áRPþÈý¥þÛþͦ¬J¡"F!qþòV @G  ÔÄì9991üÌ04'3qéê89áQQþýþÿþò8[%3¦«þ¶¢þÞýºþßy9TðJ@(   B   Ô<Ä2Ü<Ä2991ôÔ<Ä2ÄÄ2990%#'%%73%Tþ¶JLþ´¬þµLLþ´LK¬LÁ­®¸þ¨X¸®­¶Xþ¨¶B\¨ #@ H   Ô<Äü<Ä1Ô<Äü<Ä0!!#!5!ß®þRíþP°¨þRîþP°î®Ñþáìo4@4IÔäÄÀ1üÌ0KSXíí9Y"!#²:6þò׬oþñþô¼ ß·ÔÌ991ÔÌ0!!+u8ýŒßþÝ\ðo/@4IÔäÀ91/ì0KSXííY"!!¢NFþ²oþ‘ÿB3Õ@ 49/Ì991ôÌ0KSXY"3#TßüªÝÕùmZÿãwð /ò@ J$J-B$E0 '0ÔÄìÔìÎ1äôìîÔÎ0@Â////////// / / ?????????? ? ? D@@@@@E UPPPPPU ookkkkk k o ‹‹‹‹‹ ‹ ————— — C////////// / / ¿¿¿¿¸¿¸¿¸¿¸¿¸¿¿ ¿ ¿ ]]4632#"&3267654&#"#"&547>32éI45JJ54IjDG@k$6ABGCj$6AøfUIñÁ×eSJòÁÙé5HI43IGüqljc˜\rkhe•þ¤õÕþIŸ‰˜ìÕÓºœ‰ší+üÕ O@(4JJ9J   ÔÔÄÀ991/ì2ôìÔì0KSXííY"!%!!!^J¼þ¿3Fï53übÉL Jû/þüÿãoðc@24LK JBJ ÔÔì9999991/ìôìôì9990KSXí9íY"!!7%6754&#"6632bi3üK13^’pcRÐv3mÖeÁòþ:(þüüø.Rb™HQ;: (*¾–ùþ{"ÿáÿã`ð(M@,M LK#M L K MBE) ) &  )ÔÔìÔì9991Ääôìôìîöîî90#32654&#"6632!"&'32654&ž4|›sjSÇn6hÁXÌö½§†„þ¹þçfåz6`Ïlš¢œoUFL*( ŸŒÁ$¤„æþð&$.0‰Rc`Õ o@<      4 J9    ÔÜä991/äÔ<ì290KSXííííÉÉY"!!3#!!þu•5²¤1¤>þæ?ý®:ý¾–üjýþ¾BÿãÕj@84JLKJ J9 E  ÔÔìÀ9991ÄäôìîöîþÄ90KSXíí9Y"!!6632!"&'32654&#"T+3ýÄ5!H)ÅéþœþÌ_¿_3F«_¬ÇŽzN¥OÕþüþë éÅþõþÇ  (*ž‡hy(&`ÿß‘î '8@M M L KM%BE(  (ÔìÔìÀÀ91äôìôìîÖî904&#"326&&#"6632#"&5476$32#[Mi“[Kl’n3<ŒHÔ/<˜Y§ÂþÌéãäymb¹C‹-XgÈ“XjÈþô,.ÙÑABßÁþýþ©ûûÙš—ˆ‡mÉÕ3@4J9ÔÌÄ991/ôì0KSXííY"!!!Ã)ý þÁßý‡ÕÑúüÑ?ÿãqð #/N@$ M' M-MBE'0 $*$  *  !0ÔÄìÔìÔìî991Ääôìîî990¶)*+]4&#"326.5432#"&54632654&#" k[pŽo[mþ¨hk'յᲖmzþ×ïÒçÆà[Ge\S\}ÝXg—vVh—·n·ÆŸ”Ì©{ÜþîÇ´©ï7I]x]OY|7ÿáhð'4@M LKM %MBE("  (ÔìÔì91äôìÄîöîî9073267#"&532#"&32654&#"73=ŒHœÔ0=˜X¦Á2éããylaþêºCŒ%YMh”[Kl ,.ÙÑABÞÂWüúÙþc–ˆ…¡XeÈ’XkÊ1L'O@)4INI ÔäôäÀ91/ìüì0KSXííííY"!!!!þNHþ²?NFþ²'þ“þµþ‘ªþáL' F@"4IIN   ÔÄäÔäÀ991ìüÌî0KSXíí9Y"!#!!wN6þòט¼NHþ²oþñþÇþ“Xmy˜@ üì291ÔÌ90 5yüåûß!žþãþåùŸì X'yÛ@HH ü<ì21ÔìÔì0!!!!X!ûß!ûßí´ëXmy˜@ ü<ì91ÔÌ9055X!ûßžúþ`ìþaù#uð!‡@K !4  !  ;<B!   "ÄÔÄæî9991/ÎöÆîÍî99990KSXííí9íY"!!!766?654&#"6632Z 7þöXþöX]k‘JEYÍt5fÖh¥Æbui~þ呚`N]~C9>IH 7:¥†_¦bViŒÿòþÁÍs ?a@4-0)? OO P,)O0P O09@? < ,- <&<3@ÔÄüÄîî999991ÔÄüìþÄýÄîî999902654&#"#7#"&54326654&#"3267# 476$32ÓhŽQGgP Å+r<‹ ÿ·Hh |i|âX[`ìÈO¢Q?k¿_þãþ±XTtP½Âì-·‰MX³‚S]¦R15°™Þ31/#B[kv{þØ›ïþé00®95~D¤<‰ºÍͨ@$ÿÕ n@:      4<Q9    ÔÌ91/<äüì90KSXÉÉÉÉÉÉÉÉY"!!!!!Íþø›hqþÛþp¢þÕÃý¡qú+qþÿìš×#@I###  # #4T T9T S"  "#$ÔôÔìÔì9991/äìôìî90KSXí9í9í9í9Y"²]´ ]32654&# 32654&#%!2#!VÅœ“joTDÅy{VZþKâÓ×¾¯‹šLEKæÃþ¦þF…VRFþ¥mjD@릤¡Æ žƒl»?C<ƒÿãÃðJ@UCVUCV BE  ÔÄì9991äôìôìîöî0K° TX½ @ ÿÀ878Y%#"476$32.#"3267²M¡Uïýya™RM@2‘XPš6EU~vQ¡^+$$槉nr$$þ¸DEaUkþÓ‡’›CIÿøÕ ]@+   4V 9V    ÔôÔì9991/ìôì0KSXí9í9Y"² ]´]3267654&#! #! º`pš+4A}þ½;%hH^þúÛþ¶Ëü?XXj%~„€ öøWÅq—ÒE\PáÕ U@/  4VV9 VS   ÔÄä91/äìôìî0KSXííííY"!!!!!!!¾ü_ ¤3ý…??1ýÁL{Õþüþ¾þüþy/ôÕ P@+4VV9S   ÔÄä91/äôìî0KSXííííY"!!!!!Áý…>B3ý¾þÙ#¢Ñþ¾þüýuÕfÿã¨ð&x@3#&& !"&4"##V%VUCV BE'%$#"&'ÔìÔÄ991äôìôìþÔî990KSXí9íY"K° TX½'@''ÿÀ878Y%#"476$32.#"3267#7!ßFÄsòþö‘xb˜QMB3ŠQG4)E "€t$?9Î1Ì^;@"פ‡os$$þ¸CF;9/~Mb·N#øÿøÙÕ ‡@?     4VS9   ÔäÔä91/<ä2ôì0KSXííííííííY"²P]@ PPPPP]!!!!!!'oqn'þÝþÙþþÙÕýÇ9ú+˜ýh¶Õ J@&  4V9 V    ÔÄÄÀ991/ì2ôì20KSXííY"!!!!! 3y3þ×¼)4üˆ3)¼Ñþüü3þüÍÿìÿãÕR@+  4 UCVV 9E  ÔÌ991äôìîöî990KSXí9íY"'3267!!#"&AN±gtq”þ—4Ç!RCC¶qoÖNX`_lŒòü ª¬7785ÿîXÕ w@B      49   ÔÄä91/<ä290KSXííííÉÉÉÉY"!!!!'l3\ý¢RþÑþ¬_þÚÕýÓ-ý¤ü‡žªþ P!Õ6@4V9ÔÄä91/äì0KSXííY"3!!P#'ðw3Õû/þüÿÇ Õ â@I     4 9   ÔäÔä991/<ä290KSXííííÉÉÉÉY"K° TK° T[X½ @ ÿÀ878Y@>  /////   '//)/;8]]!!## #ça1)hþßýíþÛÛ/çüÕýqú+®ýqûRÿççÕ ¤@:  49  ÔäÔä9991/<ä2990KSXííííÉÉY"²(]@*5(*'%300005QWPPWPWPW]]!!! ! /×ÓþàþÛáÓþùÕûÃ=ú+=ûÃ=ÿã“ð)P@V'VB'E*! *ÔìÔì1äôìî0@+0044553300000000 0!0"0#0$0%]4&#"3267>7>47>32#"&dPQ;d$+PQ;c%-üÙdUMúœ×ãbTNûœÙâüxxGE'\sÇKxvGE,ƒSsÇþ ÈššŒ—üîÊþc—˜ýºÕk@;    4TT 9   ÔäÔì9991/ôìÔì0KSXí9íí9í9Y"32654&#%!2##!)T’‘h}þ‘¤ì÷I:N蹤mþÙÝþJ‡‡[Mø·¯ràB[QýÑ=þç“ð-|@%VV BE." " ".ÔìÔì99991äôìÄî990@A000 0 0 00000000005553$3%3&0'0(0)0*0+0,0- ]#"&547>324&#"3267>7>ÚåcTNûœÓçaU#iI”Ó›PQ;d$+PQ;c%-úðÊ—˜÷àÕþ]›Bn/º†xxGE'\sÇKxvGE,ƒSsÇÕ @Q       4T T9    ÔäÔì999991/<ôìÔì9990KSXííí9í9ÉÉ9Y"²(]²(]!&'&+!!232654&#=D¤þÓj5iusþÙ#šèàÄþZP{‡‹\\Á HWýçx »ý²Õ¯µ»áþi€|NMÿã‡ð'·@;'''4 ' UC!V U C VBE('$ $(ÔìÔìÀÀ99991äôìôìîöî990KSXÉ9É9Y"¶   ]@    ( ]]@() ( ( 9 9 9 I I I Y Y Y h h h y y y ( ]].54!2.#"!"&'32654&'úÀ|CgÃ[9D¶ov”¸t’‡þ¾þînå|;aÔk…˜FE˜P–~Ü))þã>?qXTS3A·…æþî451QUud>[´Õ}@4V9ÔôÔÄ991/ôì20KSXííY"K° TK°T[K°T[K°T[K°T[K°T[X½@ÿÀ878Y@ ¯¯])!!!jþÚïþ1#3þ…Óþþ-ÿãøÕs@=   4  VE9 ÔìÀÀ9991ä2ôì99990KSXíí9í9íY"!3267!#"&546D¸'Ç\TlÇ'¹#P?LÐ}Ûì '®ü/RZz|øüR´¹?JNÆ·*dË-ÕF@#49ÔÌ91/ä290KSXÉÉÉÉY"%!!!ú-ý{þdA#òãú+Õ)ZÕ @A      4 9    ÔÌ91/<ä290KSXÉÉÉÉÉÉÉÉY"²]@**5888]33!!!þlî )þ3þò þÂþôÕû¸Åý;Hú+üðÿq?Õ u@?    4 9   ÔÌ91/<ä290KSXÉÉÉÉÉÉÉÉY"!!!!!/þÝÈþpþ½fþá#»hAýÃþÇþ1Ïý‘NÕ`@149 ÔÄÄÄ91/ä290KSXííÉÉÉÉY"!!!‘%»›Bý‡sþÛsÕýw‰üwý´Lÿß Õ 7@4V9V   ÔÌ91/ìôì0KSXÉÉY"!!!7!ñ1ü”¼3ûé/Zý}Õôü#þüôÝßþò?F@!4WWGÔÄÔÄÖÆ991üìÔì0KSXííY"!#3!Dû&òþçò%þ¾úZ¾TÿBåÕ.@49ÔÄÀ91ôÌ0KSXÉÉY"#ÆÊÇÕùm“jþòÉB@4WWGÔÄÔÔÔÄ991üìÔì0KSXííY"!73#7!dþ%òò%üþò¾¦¾9¨˜Õ@ 9ÔÌ91ôÌ290##ãµòþÂþÃòµÕýÓ-þÓ-þÑþÛµW/Ì1Ôì0!5Ñû/þÛ¾¾sî`f/¶ÔÌ91ÔÌ0K° TK°T[X½ÿÀ@878Y#ÑÆþÙfþˆx/ÿãu{ *@O      4!  ]]!<"\]%[E_ (  !"(+ÔìÔì99999991/ääôìôìîî9990KSXíí9í9í9Y"K° TK° T[K°T[K°T[K°T[K°T[K°T[X½+ÿÀ++@878Y@23 0!0"3#vv…†       x¦¦¦ ¦¦¦ ]]"3267%!7#"&54$!37>54&#"7>32²¬¦Q?v 7{þÝC­n—±7%ÁfaRÏv/qÉ[Ùàhm?Rº¬mý}MM¯•×ã1 9<98ú''˜“'j/ÿã ´@J    4 <<E[G    ÔäÔì999991/ìäôìî990KSXíí9í9íí9í9Y"K° TK°T[K°T[K°T[X½ ÿÀ @878Y%254&#"!!>32#"&XoŸSJr¥Z)þÛ/%w?¦_’«=7EÒuoÑÊepþëÆhwÏý¤`cÛ½ƒþýi}–ÿã…{W@ ` <K< K [E  ÔÄì9991äôäìæîîÆ0K° TK°T[K°T[X½ÿÀ@878Y%#"$5!2.#"3267¼M£Sâþÿo(bªL5=ˆNªÕz|FŸ[%!!ø×=Œ)+þô:8øÆ€~44Bÿãø ´@J    4 <<E[ G    ÔìÔä999991/ìäôìî990KSXí9ííí9í9í9Y"K° TK° T[K°T[K°T[X½ ÿÀ @878Y"3254&7!!7#"&547>32yo SIr§Z‘}%þÑþÝB¥_’«>8EÒup“þåÊepÆhw…ùì¦`cܾk’Lÿãƒ}&w@#`d<Kc#< [E'& 'ÔìÔì99991äôììæîîî0K° TK° T[X½'ÿÀ''@878Y@ÏÏÏÏÏÏÏÏÏÏ Ï& ]%#"$547>32!3267>54&#"á_ÎnøþþXPTè†Ñü ý †ƒlØ]¨fYdŽ(7**íäafmðÆ-vSce>;h Ubvvçô©@=    4 ddG e    ÔÄä99991/ä2üìî2990KSXí9íííY"K° TX½@ÿÀ878YK° TK°T[K°T[X½ÿÀ@878Y!!!!7!7>;#"XX+þ¨®þÛ®þï+*¸ïð+æA:¬LáüáNÓ“á7þX¦ +Ò@\+ + + + +* +'(&)+ +4)* `<<K<&[*ef,* )+ + ,ÔÄì99991Äääôìæîîî99990KSXí9íí9í9í9í9Y"K° TK° T[K°T[X½,ÿÀ,,@878Y²]%254&#"!"&'326?#"&547>327!s¨RHr¨P5þìþïb¶W6K¥W}6›`¹TIFÉjh‡#%ö »doþ÷¹fo¢þëç --u|…SUѲ‹lgtng¶;`Û@L   4  <[G   ÔäÔì99991/<ìôì99990KSXíí9í9ííí9Y"K° TK° T[K°T[K°T[K°T[K°T[X½ÿÀ@878Y@    7 ]!>54&#"!!>32NþÛ…:7StyþÛ/#t0¨e€Š Øý(ª5:=‡ý‹ý¤\g‹L7 “@5   4 i hded    ÔäÔÔÄ991/ì2ôìüì0KSXííííY"K° TK° T[K°T[K°T[K°T[K°T[X½ÿÀ@878Y!!!7!!!!5D®l+ü+mƒþá´%CþÛ`üáážþªÿÁþX¸@?   4 id dhef  ÔÄä.991äôììîî990KSXí9íííY"K° TX½@ÿÀ878YK° TK° T[K°T[K°T[X½ÿÀ@878Y´]%#!73267!7!7!!Ý!=/;¢þÍ-çdf¦þ×+N)þÛB%+§.;4ák‡TáËVR “@D      4eG   ÔÄä991/<ìä90KSXííííÉÉÉÉY"K° TX½ ÿÀ @878Y!! !!%˜”rþ9þÉÞtRþÛüòZþ^ýB `þTé Œ@/ 4dGd  ÔÄÀ999991/ìüì990KSXí9íY"K° TK°T[K°T[K°T[X½ÿÀ@878Y@ ‰‰‰‰]3!!"&5467!7!q>N-þ×ͪ ËþÎ+Vm!-%áp‚F,¸áÿß¶{+‰@k !    $!"!#""!4&$!  <)[$e" $,"%  &!"% # % " ,ÔÄìÔäî.999999999991/<<æö<î29990KSXíííí9íí9Y"K°TK° T[K°T[K°T[K°T[X½,ÿÀ,,@878Y@™? ? ? ?????7???????@@@@@@@ @ GOOOOOOOOOO O!O"O#O$O%O&O'O(PPPPPP P __________ _!_"_#_$_%_&_'_(…… …!‡"„$„%„&„'L]>32#>54&#"#>54&#"#3>32 €L\l Œï‹ #"09‹ð $"/7‹ðÙÕ)yEEWð@Kpa/aKý1Ï3=(*Zwý1Ï*B(*Wzý1`tDKK;`{Î@L   4  <[e   ÔäÔì9991/<äôì99990KSXíí9í9ííí9Y"K° TK° T[K°T[K°T[K°T[K°T[X½ÿÀ@878Y@ ]!>54&#"!!>32NþÛ…:7RuyþÛÙ% 0¨e€Š Øý(ª5:=†ý‹`¨\g‹LXÿãy} !@ <<[E ÔìÔì1äôìî04&#"32!2!"&R]U{¦aSy¦ýM ×òþ³þõ×ò¬mvþðÍjy6B‘ñÖþ½þpñÿÛþV‘{ª@M4<<[Efe    ÔäÔì999991äääôìî990KSXíí9í9íí9í9Y"K° TX½ @ ÿÀ878Y%!!>32#"&7254&#"{{þÛ-%!G¤]“ª>8EÒupËo¡SJr§ZÏý‡ ¨baÛ½þüj|rÉepþëÆhwDþV¢}¶@N4<<[Efe  ÔìÔä999991äääôìî990KSXí9ííí9í9í9Y"K° TK° T[K°T[X½ ÿÀ @878Y7!!#"&547>32"3254&V'%þÓþÝs?¦_’«>8FÐto‘Ëo TJr¥ZÑùöP_dܾk‚‘}sþåÊdqÆhwšË{}@5       4 <[ e   ÔäÌ91/äôìÔÄ990KSXíí9í9íY"K°TX½ÿÀ@878Y.#"!!>32–0vJ¦³(dþÙÛ%#>Æw>o,/+)°Ïýü`®`iZÿãF{'¼@<    4 ``<K<K%[E( " "(ÔìÔìÀÀ99991äôäìæîîî90KSXÉ9É9Y"K° TK° T[X½(ÿÀ((@878Y@(-/// / / ,/. / :::JJJYYY ]].#"#"&'32654&/.54$32F2K®]^nIJ€vþíõhÏc3V¾]n{=…Xzrâ]º=þ56F;-7%%Œr¶Ï##8;KC.4'$‹p¨Ï¤‘ž¦@>  4 de d  ÄÀ9991/ìô<Äì2990KSXíííí9Y"K° TX½@ÿÀ878YK° TK°T[K°T[X½ÿÀ@878Y!!;#"&5467!7!P>+þhjÿã`×@O   4  <E e  ÔììÔä9991/ä2ôì99990KSXíí9í9ííí9Y"K° TK° T[X½@ÿÀ878YK°TX½ÿÀ@878Y@      ]!3267!!7#"&546{#ƒ:6Sqz#ÙþÛ!,ªeЇÙýT4:?ŒŠwû ¦Zi„H¬Ï`¨@#4eÔÌ91/ä290KSXÉÉÉÉY"K° TK° T[X½@ÿÀ878YK°TK° T[K° T[K°T[K°T[K°T[X½ÿÀ@878Y@    ] !!ÏýÙþ‹P…`û `ü’nZ-` °@B      4 e    ÔÌ91/<ä290KSXÉÉÉÉÉÉÉÉY"²]@.&))::KL   **-<<<IM[\]]333! !`ð!ãæ#üþ^þèïþé`ü¦5ýËZû Ný²ÿ´Ë` Ú@@    4 e   ÔÌ91/<ä290KSXÉÉÉÉÉÉÉÉY"K° TX½ @ ÿÀ878YK°TK°T[K°T[K°T[K°T[K°T[K°T[K°T[X½ ÿÀ @878Y@ )8HYY]] !! !Ëþ#þÕªþÑþ´þþ-” `ý×ýÉdþœRþÃ=ÿ¦þXé`·@A     4  df e  ÔÌ991ä2ôì9990KSXÉÉÉÉÉ9ÉY"K° TX½@ÿÀ878YK° TK° T[K°T[K°T[X½ÿÀ@878Y+7326?!!'p£~ð-uWd<'Ù)5yÆiß%=€)+»•${hY& }‚_S) DP¿m}88×0=L=¿nœ×à¾Vѧ†WLE'Í.8;3öþÙ¶kÔÌ1üÌ0#Ùãøÿáþ²0µ@i+,+,,+ 4+1''%,%W'W/W'G1/, 1'&%(&01Ä.ÀÀÀ991üÄìÔìî999999990KSXí9í9í9í9Y"32677667&&546776654&##73233#"##{gX' ~^T) BQy%“ͤ)_t>%>ƒ)+Æø–UͤŠTOG*Ñ06<1¾`r#m× :UF¿t–×Þ“XÏy++@ ll  üì1ÔüÔìÀ9990#"'&'&&#"56632326yKOZq Mg3NJN’S5dJ t]FŠ+é<73 ":?å=6 7=ÿÿÿnk'$3uÿm !‘@J    !  !4 < = Q  " !  "ÔÄÔÌÔÎ99991/<îæÖÎî9990KSXÉÉÉÉÉÉÉÉY"32654&#"!!!&&54632!oM66MN56MEkþÙþu¢þÙ”$*§vt¨/þæþþP6MM66MMþûúqþ$j5u¨¨u;lâýÿÿƒþoÃð'&Ýyÿÿák'(Xuÿÿÿççm'13uÿÿ=ÿã“k'23uÿÿ-ÿãøk'89uÿÿ/ÿã×f'Dÿÿ/ÿãuf'DCÿÿ/ÿãuf'D×ÿÿ/ÿãu1'DŽÿÿ/ÿã‡9'DØÿÿ/ÿãu'DÜÿÿ–þo…{'FÝ‘ÿÿLÿã¸f'HÿÿLÿãƒf'HCÿÿLÿãƒf'H×ÿÿLÿãƒ1'HŽÿÿ‹f'ÖÿÓÿÿ7f'ÖCÿÓÿÿ7f'Ö×ÿÓÿÿ71'ÖŽÿÓÿÿ;h9'QØÿÿXÿã¸f'ÿÿXÿãyf'CÿÿXÿãyf'×ÿÿXÿãy1'ŽÿÿXÿãy9'Øÿÿjÿã¸f'Xÿÿjÿãf'XCÿÿjÿãf'X×ÿÿjÿã1'X޶ÿ;yÕ Z@/4; 9    ÔäÀ9991ÄôÔ<ì20KSXííííY"!!!!!7!yLL+þ´ÑÿÑþ´+LÕþ}ßûÈ8ßV´ð@m mBÔìÔì1ôìÔì02#"&546"32654&hCz//12.0zD¾ÀHdbHHdcð30/xDBz./3¾ŽÁ¢dHHbcGHdhþÇN˜$R@1` `J K JK[ E%  ""%ÔìÀÀÀ91ä2ô<äÄì2äÆì2îî0&&'667#&&5476673N5-n@‡@@3>A77ÂÐmfP×{7Ž75rþˆˆ»h5þø(/ýL.)þø"þà íÈ›jSYþá"üƒ´þû®j…ÿéÝð@F  4 dLK<B J  ÔÔÔÔÄÀ9991/Ä2ì2ôìôìî2990KSXííí9íY"&&#"!!!!3#737$32Ý5i!P+þ®?á3ü4ë@Ç-Ç%3ïJ°þö))†°áþ²þüNáÅ ì hÿ=#ðG‰@N7829 %8?/;.2;+;;EB+H785 (" 5%(9B 8?"B5("B#&N:)9>&"J-Dƒ?U^=micUor-+ïÃR±b.JžKV^˜dmPzr30ë¿G 7,X&':6&'X(#@Ïå"!D?)HECAzLT–C+e?˜¾å!"D?Ee DHsK]š2)b?ÂÑ`µ ÔÌ1ÔÌ04676632#"&'&&736€HIƒ256743„IH‚426úIƒ235624‚HIƒ447743ƒfÿ;¦Õ `@-  49  ÔÔäÔ<äÀ9991Ä2ôÌ90KSXÉÉÉÉ9Y"!###&&54 þ¸¾-¿þÕ¾¤«¸EÕùfùùN¬ŽÙ'ÿã…3@e )*+*&'%(++*4("!%3.+%`< %<.G E))*31! (+*1!  ! 1*4ÔÔÄÜÄîÎ99999999991/äþîîÖî99990KSXí9íÉ9É9Y"K°TK°T[K°T[K°T[K° T[X½4ÿÀ44@878Y@lllllllllll ]#"&'732654/.546754&#"!6$32yœ`L;:þÿÜB‚@1:k.ZhoE,*·©ZR]rÛþÛÛ)ÔÆÃ #dS9`L;}D¼Þú ODBoG-g;‡»%@GfeûžfÔÝ®±+d}ÑN 4L\@3-*+'0!o5n2+oAn M*',$0-!1"3+"$ G3 ;/ÆþåþõîÄî29991ÔÄüô<ÄþõÎÎ99902#"&'&&546766#32654&'2#'&&'##%"32676654&'&&hÚZZ\[[[Ú~}Ú[[[\ZZÚb@@998(…NG&7O¬?9)¤cªIGHHGH«cc¬GHHHHH©NZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZþb¤((+)oXZAU 81¦…:/ðq®GIG¬ebªJGHHGJªbe¬GIG}ÑN1ID@%  q po>qpo2n>n&JD  8 ,/ÆþåÄ2îÎ1ÔìÔüôüäõþäÎÎ0&&#"3267#"&546322#"&'&&546766"32676654&'&&P4[0akjb5`*7j2©ÊÊ©7iµÚZZ\[[[Ú~}Ú[[[\ZZÚ~cªIGHHGG¬cd¬FHHHHH©¨h__g¨»›œº$ZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZGIG¬ebªHHIIHHªbe¬GIG“fÕ A@$   9 # # ###/üþìÕîÖî91ô<<Ì2Ô<<Ä9073#######5ÙdYЙkKu˜TœÕããý¾µÿþKB…þC½…9î¸f-µÔÌ1ÔÌ0K°TK° T[X½ÿÀ@878Y!#wAþFÅfþˆ ;H1a@ÔÜÔÌ99991Ô<Ì20K° TK° T[X½@ÿÀ878Y@////????]]3#%3#Zî1ìþ¤í1ë1öööNÿöƒ >@"   H H   ü<ì291Ô<ì2Ô<ì2.À990!3!!!'7#5!7!N“ü–’¢þÅ®éýmü–’¢A°þÛ1}´ëÜíþϲíÜÿjÕ…@L    4V <V9VQS  ÔÌ91/<äììôì2îî0KSXÉÉÉÉííííY"!!!!!!!33þÝ<3þüN64ýÍHþå›þýŒ‡þðã}ÕþüþÉþüþnþüjþ–Õþüý…{ÿsÿÁL'.l@8+'/.(+%&"V"+VB"E/ .(% '& &/ÔîÖìÀÀ99999991äôìîÀÀ9999999032&&54766327#"&''&&#"wM8}›4üô bUNüi¦=š‹Í L5Nûœr­9 áK4y™6b<=2^ý®"J'Ö¢™Ž—BAªsã8a,>ŽO‹ìb˜JH´rN47þÛþ® ßÅ /7@$ s'!t s-r0 $$$*0ÔìÔì99991ü<ì2ü<ì299032654&#"&&#"3266632#"&'#"&54632Õ0P2;JC88bý6J0 b )'8¹yaxMB3F ü‰KûÀbPJ?(:Ó¬ð *.t@A! '~!~ -~+ +'~}~|B/! *$-,.+/  $ $ /ÔìÔì99999991ôäìüìÌÔÄîîî9990#7#"&5463376654&#"76632"3267!!XÏ.{OkßЇIF9“S!PA”¤þÈzu:,Upý˰#ýPþ@X65zh• #(*(&®i^ E…HK,:xþªÝ¬+ð 4@~~ }~B  ÔìÔì99991ôìüìÜì0432#"&4&#"326!!3ïÁ›­îÀœ®%D=WxE54&#"!3267#"&'#"&546;7>54&#"7>32>32ÏJbu:1CP% (,8Gšþ=UF8‰A/9ˆQ^† =“Y–óÌl DA4‹V/O‘ERt4‹T~ˆ‘NgU3IHþô7:¥†_¦bViŒñRÕ ]@. 49 ÔÄôäÀ99991/ôÜÄ0KSXí9íííY"!!!3Hþõ8 þÝþöfÇ#ºú+eþ›Xjyƒ@ H üüì1ÔÄì0!#!X!îü̓ýç,1ÿÙ–¾ ,@  —–   ÔÄ91Äüì90'%3##q@`ªƒØ4þ4»ÛžÆ{ý»$Ðùëø þV#„@I   4   d`K<`Ks7+P'_iPü'Ë 54&#"!3267#"&'#"&547>32>32267>7>54&#"þ (,7G™þ> VH9‡@/9ŠR^…2\›¤@68Ç„Sx%0ŠR‚‹ür4D 394D3²B'40UYFÓ54O]72î((QEKK¨žŒ<€‰=<;>‹ƒ1†XþZ@JvaZxHA@I*|HQz"IAÿżDz@ ÔÌ991ÔÌ0!! Ñ1û/²öÿżDz@ ÔÌ991ÔÌ0!! Ñ1û/²öÇå d@2     4 G    ÔäÄÔÄä991ü<Ì20KSXíí9íí9Y"!3!3üþÇ5׬ÓþÇ5׬‡~þ‚þñ~þ‚“‡¶ `@0     4 G   ÔäÄÔÄäÀ91ü<Ì20KSXíí9íí9Y"!#!#}95þò׬þ-95þñ׬þòþþòþ¤‡¾8@4GÔÄä91üÌ0KSXíí9Y"!3ÝþÇ5׬‡~þ‚¤‡¾4@4GÔäÄÀ1üÌ0KSXíí9Y"!#…95þò׬þòþBV® $@H  Ô<ÄÜ<Ä1ÔìÔÌÕÎ0!!!!!!Í5þË5þËþuKûµ®þËþþˤîuþ#\u"@ÔÌ91ÔÌ990 hþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿÿ¦þXé1'\Žÿÿ‘Nk'</uÿB3Õ@ 49/Ì991ôÌ0KSXY"3#TßüªÝÕùmº°^T /c@8  *( -'! ) -0)'!$ * ( $0ÔÄ2ÌÔÄ2Ì9991ÔÄ2ÌÔÄ2Ì99904&#"3267'#"&''7&&5467'76632;dJIeeIJd¬ª¬ƒª$P0'T-ªª¬ƒ¦)S.'QƒIccIJffqªª)S,/Q$ªƒ¬¨ª*S)/Q&ªƒ¬1m#@ /Ôì91ÔÌ907m2þÃå)þw#üãâÕŠƒ=w#@ /Ôì91ÔÌ907%'ð‡ýß-Bë#þwƒþvîÝÝB¨@]       4 ddGe       ÔäÔôÔÄ999991/<ä2ü<Ììî2990KSXí9íííííííY"!!!!!!#7376633#"Û%9þÝþÀZÙþÛ®þÉ®þÛ®¾-¾'ÆäP+CB:þÜ-cû üáNÉá1B‹@M    4 ddG e      ÔäÔä99991/<ä2üìî2990KSXí9íííííY"3#!#737663!!#"dº+¼®þÛ®¾-¾'ÆäôþÓþÛÂB:ÃcáüáNÉùì311ÿ;{Õ†@J   4;;  9      ÔäÀ99991äÔÄ2Ô<î2î20KSXííííííY"!!!!!!!7!!7!yLN-þ´ZL+þ²JÿJþ¶+LZþ´-JÕþ}ßþ+àþ}ƒàÕߘ-/@4IÔäÀ91Ôì0KSXííY"!!ßNHþ³þ“¬þáÇo4@4IÔÄäÀ1üÌ0KSXíí9Y"!#:6þò׬oþñþÿ²þáÓo `@0     4 I   ÔäÄÔÄäÀ91ü<Ì20KSXíí9íí9Y"!#!#š93þïÕ¬þ+:3þïÕ¬oþñþþñþј $0<HLp@?J%K+I"L 71= ‰+‰"‡%‰>4‡C‰: L(I1KJ11F17@11.11(1/ìÄÜìîÞîÝîÞî99991/<î2î2öîþîî29999904632#"&5%"32654&4632#"&%"32654&4632#"&%"32654&%–¥ww¨¨wu§2IH33JJü§xv¦¦vw¨4GH33JKþÞ¥xw§¨vw¦3HH33JKþ§'ûê!x¦§wx©¦wK24KK42IÝx§¨wx©¨öG45LM41Jü+x¦§wx©¨öH35LM41JúŸ^þ\ÿÿÿrk'$3uÿÿák'(Xuÿÿÿwk'$3uÿÿák'(Xuÿÿák'(Xuÿÿ¶k',/uÿÿ¶k',/uÿÿ¶k',/uÿÿ¶k',/uÿÿ=ÿã“k'23uÿÿ=ÿã“k'23uÿÿ=ÿã“k'23uÿÿ-ÿãøk'89uÿÿ-ÿãøk'89uÿÿ-ÿãøk'89u7` j@"4ded   ÔÔÄ991/ì2ôì0KSXííY"K°TK°T[K°T[K° T[X½ ÿÀ @878Y!!!7!!5D®l+ü+mƒþá`üáážPîFf6@ ÔÌ991ÔÌ290K° TK°T[X½ÿÀ@878Y3#'#œó·°˜ð¾fþˆááyh9¢@   ŠŠ  ÔÌÜÌ99991ÔüÔì999999990K° TK° T[X½ÿÀ@878YK° TX½@ÿÀ878Y@'           ]'&'&#"#>3232673#"&ã1*"4 ‹ˆ_"=.3$&4 ‹}e#AT%!E<‚š$'C>¦XB1·ÔÌ991ÔÌ0K° TK° T[X½@ÿÀ878Y!!Ëw%ý‰¼¾`Fd@Š  ÔÌÔÌ1Ô<Ôì990K° TX½@ÿÀ878YK° TX½ÿÀ@878Y@  ]332673#"&5¾XLQuƘ”“F =HMEŽ›ƒ…R;“18·ÔÌ991ÔÌ0K° TX½@ÿÀ878Y@ //??]!!ƒ/þî1öÏá :@ŠŠ 2 2ÔìÔì1ÔìÔì0K° TK° T[X½ÿÀ@878Y4632#"&732654&#"Ϧwv¦¦vw¦™M76MN57Mþv§§vv§§v7LM66MM–þo{%@  Š  2ÔìÔÌÄ91/ÖþÅ90!#"&'732654&'3$$™‚4f0+R#DI0\,cv œ62E7uîôfi@ ÔÜÔÌ1Ô<Ì20K° TK°T[X½ÿÀ@878Y@/,,,,&87663146LLJJBB]!#3#ðþ¦¬Šöþ¿¤fþˆxþˆþo®#@  Š 2 ÔÄìÔÌ91/ÔüÄ90!33267#"&546œK04*%P-1\+ctNPJ!)œ MB<žî‘f6@ ÔÌ991Ô<Ì90K° TK°T[X½ÿÀ@878Y#373Fò¶®™î¾îxããÿº!Õ d@8   4  V9   ÔäÌ.9991/äì90KSXííííY"3'%!7!P`ƒs+Ž'_úsþ^\w3öcšÓÕþ®šþÙþ#þü%¤ž@J 4dGd  ÔÄÀ99991/ìüì990KSXí9íííY"K°TK°T[K° T[X½ÿÀ@878Y3!!"&5467'!7!%=N-þ×Ω 5þìZ¢bþÏ+V^"gþEl -%áp‚F,Ã’Éáþ:ËŠþÓÿÿÿã¢k'6 /uÿÿZÿã‘f'Vàÿÿÿß k'= /uÿÿ1¤f']àöþ¢Ù˜@ Ô<Ì21ÔÌÔÌ0##Ùããã˜ý öý öÿðÕ"}@F!" 4<V9V #" #ÔäÔìÀ99991/Ä2ìôìî20KSXí9ííí9Y"! #!#733#3267654&#;%hH^þúÛþ¶‰/‡f?Ó-ÓN`pš+4A}ÕöøWÅq—ÒE\P˜íFþºíþrXXj%~„€Rÿã¶)‚@G!"! %&'&$#$''&4)('$#"!%< <E%G*() "#'%$! ) *ÔìÔìÀ9999991ìÄôìî99990KSXÉÉÉ9ÉY"&&#"32654&!"&532&&''%'!%F&R,ªdT~£8EÒupÑÉepþëÆhwý‡¾ý¤baÛ½þüj|B ú·H üÌ1Ôì0!!BKûµúîw“Xs 0@   ü<Ì291Ô<Ì290 '7Xþ¶J¨þ¶þ¹¨Jþ¶¨GJËþ¸þ¶¦Hþ¸¦JH¨þ¸H!œÏß S@+334Œ Œ Œ‹     ÔÄÀ991üììÔìî20KSXííY"37733!;ìjååŇãýo-+•)ýN‘œðL@&ŒŒ4ŒŒŽ Œ‹3ÔÔì9999991üììôìî90KSXííY"!!76754&#"76632¶ýh3[HC?•ML’I›þfD-‘%A[-1$#¢lcŒþá/ð(K@+Œ ŒŽ#Œ Œ Ž Œ‹)  &33)ÔÔìÔì9991üììôìîÆöîî90#732654&#"76632#"&'732654&omX^PF0ŠPIBžypScÛËK“E>’O`oW’73(.˜fYZo cJ†“šQF-5ÿÿþòw{'ðþþœ'  ‰üVÿÿþòž{'ðþþœ' ñšüVÿÿ/þòwŒ'òÿœ'  ‰üVÿÿfÿã¨k'* /uÿÿþX¦F'JÚÿÿ¶k', /uÿÿþo‡ð'6ÝÿÿZþoF{'VÝÿÿƒÿãk'&Áuÿÿ–ÿãf'FVÿÿƒÿã4k'& Áuÿÿ–ÿãçf'FàVBÿãs'À@h'&% #"$      4 "  <"<E[G %      (ÔìÔäÀ999991/ìäôìîÕ<Î2990KSXíííí9í9íí9í9Y"!7!7!3#!7#"&5476632"3254&VBþÐ%/%’%’óþÝB¥_’«>8EÒup“Îo SIr§ZT½tt½û¦`cܾk’qþåÊepÆhwô¼ ß·ÔÌ991ÔÌ0!!+u8ýŒßþݘ-/@4IÔäÀ91Ôì0KSXííY"!!ßNHþ³þ“ÿßÿãÓð,v@@#$u& uUCJ UC JB E*-,&+*'## %+#-ÔÄÄÄüÄÄ9999999991Ä2äôìôìîöîî2Ý<î290632&&#"!!!!3267#"55#73667#7]VçPœI@8‹Oi¬9’RþZRþê€hM’s?LUãþÉT°Tòø$$þ¸KM‡½g»|Œ>Zþ¸$$ î»+K!½“;ö\@ÔÜÔÌ99991Ô<Ì20K°TX½@ÿÀ878Y@////????]]3#%3#Pë/íþ¦ë1ìöööö5îDösµÔÄ1ÔÄ0K° TX½ÿÀ@878YK° TX½ÿÀ@878YK°TX½@ÿÀ878Y@++//]]!#+þÀÏöþøsî`ø¨@ Š ŠÔÌÔÌ99991Ô<üÔ<ì99990K° TX½@ÿÀ878YK° TX½ÿÀ@878YK°TX½@ÿÀ878Y@%         ]'.#"#>3232673#"&Û1!#5 ‰ƒ`%A#5%'4 ‰‚^%@!% @8€Š) =:€ŠXÿãy} !@ <<[E ÔìÔì1äôìî04&#"32!2!"&R]U{¦aSy¦ýM ×òþ³þõ×ò¬mvþðÍjy6B‘ñÖþ½þpñÁîXö¶ÔÄ91ÔÄ0#ɲåöþøXî?ö@ ÔÄ991Ô<Ä90!#'#L\—©¤æ´öþø¡¡šîsö@ ÔÄ991ÔÄ290!373þ¤‰ª•åµî¢¢/ôwo@ ÔÌ991ÔÌÔÌ0'T%#%ôvuœÕß _@3 3  3 334Œ  ‹    ÔÜÄ991üüÔ<ì290KSXííííY"333##7!7îþÆúRÍeml#¼$þ{)þ¶þ´´¢²îNö@  ÔÌÔÌ1ÔÜÄ290332673#"&5² ROGjš(Æ“ˆ“ö<7=6‡‡}H‰ö·ÔÌ991ÔÌ0!!w/þîöö  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•ÑhÑÑÑRÑçÑÿ×Ñ'Ñ!ÑÿßÑçÑRÑqÑyÑBÑÑÑôÑ\ÑÑZÑ+ÑÿãÑÿáÑÑÑ`ÑmÑ?Ñ7Ñ1ѪÑXÑXÑXÑ#ÑÿòÑÿÑÿìуÑÿøÑÑ/ÑfÑÿøÑÑÿìÑÿîÑPÑÿÇÑÿçÑ=ÑÑ=ÑÑÑ´Ñ-ÑËÑ)ÑÿqÑ‘ÑÿßÑßÑTÑjÑ9ÑÑsÑ/Ñ/Ñ–ÑBÑLÑçÑÑ;ÑÑÿÁÑRÑéÑÿßÑ;ÑXÑÿÛÑDÑšÑZѤÑjѬÑZÑÿ´Ñÿ¦Ñ1уÑöÑÿáÑXÑÿÑÿуÑÑÿçÑ=Ñ-Ñ/Ñ/Ñ/Ñ/Ñ/Ñ/Ñ–ÑLÑLÑLÑLÑÑÑÑÑ;ÑXÑXÑXÑXÑXÑjÑjÑjÑjѶÑÑhÑÿéÑhÑÑfÑÑÑÑÑ9Ñ ÑNÑÿjÑÿsÑ ÑXÑXÑXÑÿãÑÿÉÑ‘ÑјÑÑHÑÓÑÝÑZÑÿáÑÿ®ÑZÑRÑXÑ1Ñ ÑXÑÿúÑNÑRÑÿªÑÑÿÑÿÑ=ÑÑÿìÑÿÅÑÿÅÑÃѓѤѤÑBÑuÑÿ¦Ñ‘ÑѺÑ1Ñ=ÑBÑBÑ1јѬÑÿ²ÑÑÿÑÑÿÑÑÑÑÑÑÑ=Ñ=Ñ=Ñ-Ñ-Ñ-ÑÑPÑyѦѾÑRÑÏÑ–ÑuÑÑžÑÿºÑ%ÑÑZÑÿßÑ1ÑöÑÿðÑRÑ‘Ñÿ¦ÑÑÿÛÑBÑwÑ!ÑÑÑÑÑ/ÑfÑÑÑÑZуÑ–уÑ–ÑBÑôјÑÿßÑ“Ñ5ÑsÑXÑÁÑXÑšÑ/ÑѲÑHÿõÿ#ö  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ      sfthyphenperiodcenteredEuroc6459c6460c6461c6462c6469c6471c6473c6478c6479c6476c6477""""kìtðˆŸÍüGqž·Ýø¼ÿ_Å…áØTy›¾ ; Ë  ¡ û Z ¡ ã ^ ¿  Q « ØhÔ?#¨C–ÿ7žøAv­Ó*?f(·ž‘@ÜFÊ2œ¥9uÿñ ¥  …!!Ž!æ"†"œ#=#€#$$$+$8$E$R$_$l$y$†$“$ $­$º$Ç$Ô$á$î$û%%%"%/%<%I%V%c%p%}%Š%—%à&&‹&þ'¬'Ý(,(ü)œ***o*”*Ø++‹,,r,§,Õ--t-þ.Z.Š.­.÷/M/Ð00q1z1÷2t2½2Ú3 3…44A4{4·5555+585£6s66§6ø7G7v7£7Ò7ü8 8818­8Î8ð9t9â:N:t:¡:ð;š;§;´;Á;Î;Û;è;õ<<<<)<69>m>¸>ê??i?ì?ù@@@ @A@»ABAOA\AÌBKBaB›BÝC/C‘C¢C³CÄCÑCÞCëCøDDDD,D9DÙDòEE›EÝF%F¦FâFúGG8GSG GÉGáNH@®ŽmþÑÿjÿ^sѼGÌþBGÌSöf   €¯ JBits! ûþšmãB¼Ñ`#cÕVeraSansMonoBdObÿÿÿÿ6ÿÿþ628J00@             ÿÿ¬9Ã_<õºÁ=‘ºÂ–Êÿjþsmloganalyzer-3.6.5/src/BitstreamVeraFonts/VeraMoBd.ttf0000644000175000017500000013763412225176641022101 0ustar danieldanielOS/2µ‰ös©€VPCLTc£Ð©Ø6cmap¤Ãè œüXcvt ´I°D‚fpgmçwñÄ%‹gasp¿X glyfuÃ’&vÞhdmxÇ32`ªHheadÙj ¿d6hhea "ô©\$hmtx Ïœœ T4locaÛ•ùè§ maxpâÍ©< name×) postn…îÆ¤ˆ–prepLQŸ3 ˜ø::S:: Wc0ºy   } t ¨ 0   N :  :   V 4 n `  š 0È & ¢Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans Mono BoldRelease 1.10BitstreamVeraSansMono-BoldCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans Mono BoldRelease 1.10BitstreamVeraSansMono-BoldCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com3#®¶îN\{Û#'##\ #Í\\w¼#3‰b#þ#\b b– áb…¤ÍƒðÍ¢ƒ®º¦˜¼°ô%¢Ã%1ž/#ð/Õ 9bÍR¶¢¤Å¤sÕÃáÓîÕ˜¢ÕÕðq¸#îoúVúÁéd\œH¾fšÃ```{î\{šá`ªß¢ƒšoÍ7LøÑ'ª5%ÓÕ={¢¤ðD=!Ï¢/îÑs¸€@t¾þ»»º»¹ú·ú¶µG¶»µG´2³–²2±d°–¯®¯k®¬«þª© ªú© ¨§Œ¨þ¨À§¦Y§Œ§€¦¥&¦Y¦@¥&¤þ£2¢¡ G¡þ¡¸ÿÑ@ÿ ŸA GŸAž2žk2œþ›úšú™þ˜—%–“þ’þ‘þþe}ŽŽŒŒ‹f‹2Š ‰ˆ»‰þˆ‡]ˆ»ˆ€‡†%‡]‡@†%…„…„ƒ–‚þe2€€d~–}d|S{f{2zez2yxfxdwþvþts s rq.rþq.pfp}onm»nþml]m»m€li%l]l@kkji%j»i@ÿ%hfhdgfgdfefedþcþbþa}`þ^d\[\þ[Z2Y-YXWWþV2UþTS TS RQR–QPQPOþNMdN–MdLþKþJIJ–IHúGúF}EDE}DCA?2>=<=þ<; <; :9:–98 99€8 8@76776-6545K4343212d1-10/@0D/.-.-,--¸@@ ,+,,¸@ +*++¸À@ * **¸€@W)K('K&$&$%$%K$$#""2! 4!>  4þ2¸€@ ¸@@ ¸@WK–77ú22ú2X}X       ¸À@   ¸€@   ¸@´ ¸@–  ¸d…+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX °ÀEDY!-,°%E`D-,KSX°%°%EDY!!-,ED-hþ–h¤@ ¾¾b/ÄÔì1ÔìÔì0!%!!hüsüåþ–øòr)ãîÕ @ d Ô<ì2991/äÜÌ0!!!#ã þõ !Ç#þåÕýqþ›eçªçÕ@ dÔÌÔÌ1ô<Ì20!!!çÿÿÿÕýÕ+ýÕ+;J@0g g    ÔÌ91/<Ô<<ü<<Ô<<Ä2ì220333#3!####5!#5!#3Ã_Ë^àaÁöJÍþþ^Ý^Í^Ý^ÏJÛ^ÍJ;þŠvþŠ×þÛ×þ‹uþ‹u×%×vý³þÛ¤þÓD /P@+)%$(hh!/$, ( 0Ô<Ì2üÄÌüÎÄ1/<ÄÆ2î2ÖÆÆî2ÖÆ906654&#&&'&&546753&&'¶?FEÍ>??ËW¾ggÁUÅÀ̹G™P>˜[ÅÉÙ´þÒ O=>O-C:9Lû‘-.+=BI'¿§Æ ííÿ(0þÍϬ¤Ò !Ø '3V@-(  (kk kj.k%1"+1""4ÔÄìÜìîÞî99991/îÎöîÞîî999904632#"&"32654&4632#"&"32654&!º……»»……º?9PP9:OPþ½)ûè˹†„¼¼„†¹=8ON9:QRX†º»……º¹O::OO:9PýP¢`þ^’†º»…„»¹P::OP99Q%ÿãÓð*8©@Z)(*()(-,.+23456718%8+(%#1) #1p#popnr)($ +.#  .8 )$. 9ÜÄìüÄÄÌî999999991/äöîöîÆî99990KSXÉ9É9ÉÉ9Y"%#"5467&&54632&&#"6654&'3!32676767fK©Wàþê‹20ÚÎIŒD@ƒAPR=D9ëDI¢þÃþ"BCr;H23Ñ‘îXN…<¢®ÿ$%86$~fþ &b993‘ÙVöÛ+wIz§  çªçÕ¶dÔÌ1ôÌ0!çÿÕýÕ+þòœ @ut  ÔÄ2ì991üì0#&547œ„€€„䟚›žïþ@àÞþ=ðçÁéèÃä5þòR @ut  ÔüÄ2991üì03#6545äž›šŸä„€€äþ=èéþ?çðÃÞàÀy9TðJ@(   n   Ô<Ä2Ü<Ä2991ôÔ<Ä2ÄÄ2990%#'%%73%Tþ¶JLþ´¬þµLLþ´LK¬LÁ­®¸þ¨X¸®­¶Xþ¨¶B\¨ #@ v    Ô<Äü<Ä1Ô<Äü<Ä0!!#!5!ß®þRíþP°¨þRîþP°î®jþáo@ w ÔìÜÄ1üÌ0!#Í9ÄØcoþñþ-¼¤ßµÔÌ1ÔÌ0!!-wý‰ßþÝÁo¶w Ôì1/ì0!!ÁMþ³oþ‘qÿB`Õ@ dÔÄÔÄ1ôÌ03#ƒÝüîÝÕùm{ÿãVð #$@ x! xn!r$  $üììÔÌî1äôìîÔÎ0@ò////////// / / ?????????? ? ? OOKKKKK K O TTTPPPTT T ddd```dd d ŸŸŸŸŸŸŸ Ÿ Ÿ ¯¯««««« « ¯ ÀÀÀÿÿÿÿÿÿÿÿÿÿ ÿ ÿ T////////// / / ¿¿¿¿¿¿¿¿¿¿ ¿ ¿ ÀÀÀÀÀÀÀÀÀÀ À À $]]4632#"&"326&32#"ìH45HH54H|f^^fg^^ý¬ö÷øööø÷öé5HH54HGBúþíþîúúúýó„ƒþ~þ{þ|þ~ƒ¼oÕ $@xxdx  ÔÄÄüÄ1/ì2ôìÔì0!%!!!¼JþÍ5JüMÉL Jû/þüs'ð[@/% zy xnx    üÄüìÀÀ991/ìôìôì990KSXÉ9ÉY"!!5776654&#"6632²uüL =KByoOÅkkÍ^í;H5îþüüª/FV…Adm?<')Ý¿Xš^Dî}ÿãLð(G@)p zy#p z y pnr) &  )üÄÄüìÔì91Ääôìôìîöîî90#32654&#"6632!"&'32654&%žžnyynTÀggÈ\옠¨þêþ÷qÛd^ÚxxŒŒœWOS]*( !ε…©Ç¢Ùä&$/1o^s}fuÕ B@   % xd   üüÔ<ì291/äÔ<ì290KSXÉÉY"!!3#!!¶þ‡y5¤¤þåý°ý²–üjýþ¾BÿãFÕ<@!xzyx xd r  üÄüìÄî1ÄäôìîöîþÄ90!!6632!"&'32654&#"Á+ýÄ$R.ÞþÕþþ`ÄfS¯Xœ¢¡†OŸQÕþüþë þèàëþï  ))…u''ƒÿábî $5@{{ z y{"nr%   %üììüìÄ1äôìôìîÖî90"32654&&&#"6632# !2ƒ`ee``gg#O‘C §/’cÊÜ÷àþï÷..F•ì‹„ƒ‹‹ƒƒŒÆþô--×ÒAAÿêûþìn˜„ƒ‡7Õ5@%xd üìÄ991/ôì0KSXííY"!!!‡°þþÓæý‘ÕÑúüÑÿãPð #/D@% {'{-{nr'0 $*  ! 0üÄìüìÔìî991Ääôìîî990"32654&%&&54632#"&54632654&#"hczzcc{zþÁqvòÐÑòto|ŒþêéþŽeWXeeXVfš}gg~€eg}}'§yºØØºx§(&ĉ×êê׊ÄTXggXWefoÿÙNã$7@{ zy{ {nr% " %üìÄüìì1äôìÄîöîî9073267#"&543 !"&2654&#"ËO‘CŸ§/’dÉÜöá÷þÒþÒF•7_ee_`gg .,ÕÔAAÿêúþ“þiþ}þ}î‹„ƒ‹‹ƒƒŒÁ'@ ww Ô<ì21/ìÔì0!!!!ÁMþ³Mþ³'þ“þµþ‘sþá' "@ww   Ô<ì2ÜÄ1ÄüÌî0!#!!ÁMÄ×NMþ³oþñþÇþ“Xmy˜@üì291ÔÌ90 5yüåûß!žþãþåùŸì X'yÛ@vvü<ì21ÔìÔì0!!!!X!ûß!ûßí´ëXmy˜@ü<ì91ÔÌ9055X!ûßžúþ`ìþaùé)ð$q@8   %$  fhn !  %Ô<ì2ÔÔì999991/ÌôìÔìÅ9990KSXÉ9É9Y"!!!546776654&#"6632¸ þõ þõ>PZ?-\\T·`bÉeÊæD^XD&þ呚cŒNY=P+CDGF 89¼¥Lƒ\VBT= þÁ‡s 4]@1(+$ 4| | }'$|+}|+15'(   ! .5ÔÄüÄî2îî991ÔÄüìþÄýÄîî9999904&#"326#5#"&5463254&#"3267# !2ÍfYYeeYYfºÄ&gH¤ÉÈ¥Gl"•ŠÐþù0ýP–E\Q¿mþ¢þ`v4Úý!q€€qr€€þØR51ìÂÁë1/)ˆ”þ’þÛþÍþ•//°77ÒŒƒÑþùã!°Õ ¼@;      %h~d     ôì91/<äüì90KSXÉÉÉÉÉÉÉÉY"K° TK° T[X½ ÿÀ @878Y@,0000 5::5s|€´»]]!!!!!h‹þÀi“þÙ\þuZþÙÇýqú+qþ}‡× >@$h hdh €  !üì2üìÔì991/äìôìî9032654&#32654&#%!2!!šÄqvˆÄÄp_anþáùû”«­þüþÛþ¦þF`wyjFþ¥P\\Së½¼¢ İØÂ˜ÿã9ð.@op op nr! üì2ì1äôìôìîöî0%# !2&&#"32679FšUþÒþÂ>.UœDLL¢¥¥¢LL+$$ŽxyŽ$$þ¸FAþÿýüþÿAF‰uÕ(@p dp !  "üìüì99991/ìôì0326&#! !!°P®””®þ‰<nBþ¾þ’þÄËü?ÛÚ þ£þtþsþ¡¨JÕ *@ppd p€#  üì2ü<ä1/äìôìî0!!!!!!!Jü^¢ý…?ýÁ{Õþüþ¾þüþy¶XÕ %@ppd€# üì2üä1/äôìî0!!!!!Xý…Bý¾þÙ¢Ñþ¾þüýuÕuÿãjðS@!ppopnr%! üìüÄüÄ1äôìôìþÔî990@]]#5!# !2.#"326hÊÌUÍuþÞþÄ?-Z®L>¡`¨¦ ™.DøýTIK“syŽ30þ¹PQýþÿùþü‰HÕ &@p€d  " üì2üì21/<ä2ôì0!!!!!!‰'q'þÙþþÙÕýÇ9ú+˜ýh¬%Õ #@pd p ÔÄ2üÄ21/ì2ôì20!!!!!¬yþ×)ü‡)Ñþüü3þüÍmÿãðÕ.@ opp dr  üüüÄ1äôìîöî99073265!!!"&mVÃctlþ—åþù_ÏJVX\tòü þïë4uÉÕ a@3  %d   üì2À91/<ä290KSXÉÉÉÉÉÉY"!!!!u'ÎNþ)èþ¸þžƒþÙÕý²Ný´üw ¦þáÕ@ pdüìì1/äì03!!á'wÕû/þüV{Õ ³@,  % d   % % üìüì91/<ä2Ä90KSXÉÉÉÉY"² ]@R )=?? ‡€¯¯ ¿¿ & )/708?…€Š‡ € Ÿ”› ¤«¢¬ ±¿¶º ]]!!###V`²±bþžë þÕýqú+¬ýsûTwXÕ S@%d&& üìüì991/<ä2990KSXÉÉY"²‡]@  ‡‰]]!!!!w= þÅþ^þüÕûÃ=ú+=ûÃ\ÿãuð #@ppnr !! 'üìüì1äôìî0"326&! ! hqhhqrhhý‚  þ÷þüþýþ÷çñþóþôññ  ñþˆþxþþ‚þxˆ¢{Õ,@pp d !  üì2üì99991/ôìÔì032654&#%! !#!Éy‘uu‘þ`•5þñþËnþÙÝþJbyybøÜ÷÷ÜýÑ\þçuð<@ pp n ! !'üìüì991ÄôìîÅ9990# ! "326& þÿþ÷  ~xºÊþùqhhqrhhˆ~ˆþxþþùþL¶–ñþóþôññ  ñ…ÑÕf@6  %p pd   !  "üì2üìÄ9991/<ôìÔì9990KSXÉÉ9Y"!&'&##!! 32654&#',A/þ¼´ Ok^þÙª û–ýø‹yihzÁ A^ýçy©ý²ÕÌæš¶ þi_mm^ÿãVð'p@>'' '%' o!p o pnr('$ ($"(üÄìüìä99991äôìôìîöî90KSXÉ9É9Y"&&54$32&&#"!"&'32654&'þßžãgÎe_Ä`krS„´ªþõþòoßhvÝlmxPLU»žËè/.þàCFVP>Q10BÚ¦âß541TRcYCeZwÕ@ pdÔÄüÄ1/ôì20!!!!!üþÙþ…þ…ÓþþjÿãfÕ*@  pr d  üìüì1ä2ôì99990!3265!! j'reer'òþôþõó'®üppøüRþÐþì9˜Õs@%%dôì91/ä290KSXÉÉÉÉY"K° TX½ÿÀ@878Y@  ]]%!!!h)þþgþ)ößú+ÕÑÕ µ@@      % d   /Ì91/<ô<Ä90KSXÉÉÉÉÉÉÉÉY"²‡]@6fe   )&ghj f g wzsx‡ˆŠ††‰‡]]!3!! !kõ–T¬þíªŸþïÕû¸Åý;Hú+üð¶Õ ª@C    % d   ôÄüÄ91/<ä290KSXÉÉÉÉÉÉÉÉY"K° TX½ ÿÀ @878Y@  ]]) ! ! !¶þÏþãþäþ϶þV11þXîþößþ%Ûý!ÉÕS@(%d ÔÄüÄ9991/ä290KSXÉÉÉÉY"!!!>"#>þ3þÙÕý¨Xüwý´Ls‰Õ 8@%pdp üÄüÄ991/ìôì0KSXÉÉY"!!!5!‰òýLÂûêŸýwÕôü#þüôݦþò¢$@‚u‚tÔìÀÀÀÀ1üìüì0!#3!¦üòòþ¾úZ¾oÿB`Õ@ dÔÌ991ôÌ0#NßüîÕùm“/þò+ @‚u‚tÔì991üìüì0!53#5+þòòøÞ¾¦¾9¨˜Õ@ dÔÌ91ôÌ290##ãµòþÂþÃòµÕýÓ-þÓ-þÑþÛµ‚/Ì1Ôì0!5Ñû/þÛ¾¾Çîüf.¶ƒÔÌ1ôÌ0K° TK°T[X½ÿÀ@878Y #áÅþfþˆx^ÿãT{ %…@/   ggh Šg#‰r… #  .)&üìÌüì22991/ääôìôìîî99990@-400 4!urrˆˆˆ       ¦¦    ]"326=%!5#"&546!354&#"5>3 ¼¤‚ZMt€#þÝ5¦d¿Õþ ËgdiÅkaÈpÝTfLZ¯qý}JPʵĻ1GI5:ú(&Þ–ÿãw 6@  h hr‰t2 0üì22üì1/ìäôìî9904&#"3266632#"&'!!Rl__nn__lþh6ZÇ×ÔÀe–.þÜ$-¢¸¸¢¢¸¸6]]þÐþäþèþÌba¦¨ÿã%}.@‹yh ‹ yh ‰r 75üì2ì1äôìôìîöî0%# !2&&#"3267%JªbþýþÜ&Z§S@™RššU”B9++89*,þô7;¶¨¨´9:Zÿã;6@hhr‰t2 )üìüì221/ìäôìî990!!5#"3232654&#"$þÜ/•eÀÔ×ÇZþžl__nn__lÁSùì¦ab40]þ¢¸¸¢¢¸¸\ÿã}{L@#  ‹ hy Žh ‰r .)üììüÄì1äôììæîîî90@ Ï Ï ÏÏÏ]%# 32!3267.#"NfÔvþçþ×÷ùý š™eÄkøspex 7**->þÙþôw„‚:?itw{q®;4@ t  Ô<Äü<Ä2991/ä2üìî2990!!!!5!54633#"ãXþ¨þÛþð¨äñåB/ÂbáüáNÊœá0bþXH} (I@(  &' h‹yhh#‰'‘)& 2 ))üìÄüì221Äääôìîöîî999904&#"326!"&'32655#"325!#r]\qq\]r%óþï\´]S¬[|v+ŽfÀââ¾`–+%B–µ´—˜´µþ©þóï .,u|yPN, 8ZR¬/.@ h‰ t 7  5üì2üì1/<ìôì99990!4&#"!!6632/þÝENPZþÝ#–jŸ¢×ý)ªyh}ýý¤]fÓ B@  s  Ô<ÄÄü<Ä1/ìì2ôìÎ0K° TX½ÿÀ@878Y!!!5!!!!ÝDlümþá%þÛ`üáážþªþXR O@  ‘s  Ô<ì2ÄÄ991ìäôìîÎ990K° TX½ÿÀ@878Y%#!53265!5!5!!RµÒþÄêbRþ×NþÛ%+ü×án„TáËV®® @@! %t  .5 üìì291/<ìä90KSXÉÉY"!!!!®%`cþXÀþ¼þÍdþÛüÏ}þ^ýB `þTZF %@t  ÔÄüÄ991/ìüì990!5!33!"&ƒþ×NRbêþÄѶÓ`áû¿„náØRƒ{"Ÿ@'  h ‰:=:=:#ÔìüìþîÎ91/<<æö<î299990K° TK° T[X½#ÿÀ##@878Y@7      /////////?? ? ? ? ?????]>32#4&#"#4&#"#3>32²!fJ‘oð&22(í(22&ðÕnDDpðGDÈþÄý‰Ï}TV{ý1Ï{VT}ý1`tBMQ¬/{0@  h‰ 7  5üì2üì1/<äôì99990!4&#"!!6632/þÝENO[þÝ#–jŸ¢×ý)ªziŽ~ý`¨]fÓbÿão{ #@hh‰r . )üìüì1äôìî0"32654&32#"hixxijxxýíîþçîíþç¹¥¥¹¹¥¥¹þ¢=þÃþñþñþÃ=–þVw{9@hh‰r‘ 20üì22üì1äääôìî990%!!6632#"&4&#"326ºþÜ$.–eÀÔ×ÇZbl__nn__lžý¸ ¨abþÌþèþäþÐ]ñ¢¸¸¢¢¸¸ZþV;{ 5@ h h‰r‘ 2)üìüì221äääôìî99032654&#"#"325!!l__nn__l˜6ZÇ×ÔÀe•/$þÜ1¢¸¸¢¢¸¸ýË^]04ba¨ùö#{)@ h‰  ÔÄì21/äôìÔÄ990&&#"!!66320M]‹&þÛ%+²w&lnýü`®`i¬ÿã+{'¥@=    %  ‹yh‹yh%‰r( >7"5(üÄìüìä99991äôìôìîöî990KSXÉ9É9Y"²(!]@+ $)) ) ) ) ) ),//,))))) (!$'].#"#"&'32654&/.54632ßQ¯XbdÖ T •ãäeÔmaÉ^gjKQ¨šêÔ_½=ÿ4598P2&©­­##7:<98<"&¢ˆ¢´o1žN@  Ô<Äü<Ä2991/ìô<Äì2990K° TK° T[X½ÿÀ@878Y!!;#"&5!5!²þIUáöü²þâžþÂáýîKAá¡Úá> ÿã%`0@  hr   75üìüì21/ä2ôì99990!3265!!5#"& %DOOY%þÛ•i £‡ÙýTyhŒ~ƒû ¦]fÔP`i@%%1/üì91/ä290KSXÉÉÉÉY"²X]@U  ZUUY]] !!þœþ—þœ)ïð`û `ü–jÑ` ¿@@      %    /Ì91/<ô<Ä90KSXÉÉÉÉÉÉÉÉY"²h ]@@     )&') 96k c wxuy ‡ˆ†‰ ——˜˜–™ ]]333! !ô…yíw‡ôËþꈇþê`ü¦5ýËZû Fýº7š` —@B    %  1/ üÄüÄ91/<ä290KSXÉÉÉÉÉÉÉÉY"² ]@    96]] ! ! !yþ‡šþªÜÛþªžþƒVº»`ýèý¸yþ‡Hþ²N;þX˜`w@A     %  ‘  1 /üìÄ91ä2ôì9990KSXÉÉÉÉÉ9ÉY"##532677!!Ç;¥vòwZT+þV4õ4yž‘ß=o<Aý)×¢9` 8@%6/ üÄì2991/ìôì0KSXÉÉY"!!!5!ºý³MüiNýÊ`åý`Ûå °þ²$^@0 %   ! ‚ ‚‚ t% $  %Ô<Äü<Ä299999991üÄìÔìî99999990#"&554&##5326554633#"3–ù©kŒ>>Œk©ù–{hFb~~bFh¿”Ý×—s¿r˜×Ý“¾TÑ¥†ˆ¤ÍUöþÙ¶tÔÌ1üÌ0#Ùãø´þ²!$`@1%   ‚‚#‚t%# %Ô<Ä2ü<Ä99999991üÄìÔìî9999999032655467&&554&##53233#"##´yhHb}~aGiy–ø§m>>m§ø–Vͤˆ†¥ÑV¾“Ý×—s¿t–×Ý”XÏy++@ ’’ üì1ÔüÔìÀ9990#"'&'&&#"56632326yKOZq Mg3NJN’S5dJ t]FŠ+é<73 ":?å=6 7=ÿÿ!°k'$u!°m!ý@M ! !%h  i ~!   "üìÔÌÔÎ999991/<îæÖÎî9990KSXÉÉÉÉÉÉÉÉY"²]@\ !000 0!oŸ¯¯¼¸¸¼¼¿¿¿¼¿  !!' )!;44 ;!t |!‚ !°°¿¿¿°µ º!]] !!!.54632%32654&#"!/þÙ\þuZþÙ,*§uv§*þŠN57MN65Nƒ‹úsqþ%a=u¨¨u>_6MM66MMþAýÿÿ˜þo9ð'&Ýuÿÿ¨Jk'(uÿÿwXm'1uÿÿ\ÿãuk'2uÿÿjÿãfk'8uÿÿ^ÿãTf'Dÿÿ^ÿãTf'DCÿÿ^ÿãTf'D×ÿÿ^ÿãT1'DŽÿÿ^ÿãT9'DØÿÿ^ÿãT'DÜÿÿ¨þo%}'FÝHÿÿ\ÿã}f'H'ÿÿ\ÿã}f'HC'ÿÿ\ÿã}f'H×'ÿÿ\ÿã}1'HŽ'ÿÿf'Öÿÿf'ÖCÿÿf'Ö×ÿÿ1'ÖŽÿÿ¬/9'QØbÿão0@ hh‰r“ .)ìÔÄîþî1ìäôìîÎ0!#"32654&32#"ðþÅ“ixxijxxýíîþçîíþçþÕþŸ¹¥¥¹¹¥¥¹þ¢=þÃþñþñþÃ=bÿão0@ hh‰r“ .)ìÔÄîþî1ìäôìîÎ0#"32654&32#"áÅþ¡ixxijxxýíîþçîíþçþÕ+ýt¹¥¥¹¹¥¥¹þ¢=þÃþñþñþÃ=bÿão8@ hh‰r“ . )ìÔÄîþî91ìäôìîÎ2903#'#"32654&32#"ðñ²ÇƲxixxijxxýíîþçîíþçþÕ““þŸ¹¥¥¹¹¥¥¹þ¢=þÃþñþñþÃ=bÿão7@hh‰r . ) ìÔÌÔÌîþî1Ä2äôìîÎ203#%3#"32654&32#"-ìì‹ììPixxijxxýíîþçîíþçöööþj¹¥¥¹¹¥¥¹þ¢=þÃþñþñþÃ=bÿão".:h@:    )h8#h2 “2‰8r;&,5.&/ /);ìÔÄîþî99991ääüÄÌîîÎ999990'&'&#"#54632326553#"&"32654&32#"j7 +"'ŒlY$G*>%$'ŒkX#A4ixxijxxýíîþçîíþç3%@9!q‹+>: s‰þ|¹¥¥¹¹¥¥¹þ¢=þÃþñþñþÃ=ÿÿ ÿã%f'Xÿÿ ÿã%f'XCÿÿ ÿã%f'X×ÿÿ ÿã%1'XŽœÿ;3Õ $@f d ?  Ô<Äü<Ä1ÄôÔ<ì20!!!!!5!çLþ´ÿþµKÕþ}ßûÈ8ßV´ð@” ”n@@ÔìÔì1ôìÔì02#"&546"32654&hCz//12.0zD¾ÀHdbHHdcð30/xDBz./3¾ŽÁ¢dHHbcGHd“þÇ ˜!F@&‹ yh ‹yh‰ r" -/"üìü<Ô<<Ì221ä2ô<Äì2ôìÆî2ôî0&&'667#&5473 8x?@w84xCŽëþïëŽ=uþÀr{~5þô*1ýL0+þô"þà :úÿ9þá!ü„´³™›¹wbð>@  zyhn x Ô<ÄÄü<ÄÄÄ1/Ä2ì2ôìôìî2990&&#"!!!!3#535632N9‚EjcPþ°áüëÆÆáèS޶þî)+…°áþ²þüNáÅøªÿ=%ð >y@C/0*1 06 'f&*f# f f™^§Àú C:HX D0M~«JIebûžfÓÛíö}ÑN 4L\@3-*+'0!–5•2+–A• M*',$0-!1E3+E$CGB3C;B/ÆþåþõîÄî29991ÔÄüô<ÄþõÎÎ99902#"&'&&546766#32654&'2#'&&'##%"32676654&'&&hÚZZ\[[[Ú~}Ú[[[\ZZÚb@@998(…NG&7O¬?9)¤cªIGHHGH«cc¬GHHHHH©NZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZþb¤((+)oXZAU 81¦…:/ðq®GIG¬ebªJGHHGJªbe¬GIG}ÑN1ID@%  ˜ —–>˜—–2•>•&JDB C8B ,/ÆþåÄ2îÎ1ÔìÔüôüäõþäÎÎ0&&#"3267#"&546322#"&'&&546766"32676654&'&&P4[0akjb5`*7j2©ÊÊ©7iµÚZZ\[[[Ú~}Ú[[[\ZZÚ~cªIGHHGG¬cd¬FHHHHH©¨h__g¨»›œº$ZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZGIG¬ebªHHIIHHªbe¬GIG“fÕ A@$   d F F FFF/üþìÕîÖî91ô<<Ì2Ô<<Ä9073#######5ÙdYЙkKu˜TœÕããý¾µÿþKB…þC½…Õî f.¶ƒÔÌ1ôÌ0K°TK° T[X½ÿÀ@878Y!#ðþÅfþˆ-;¤1I@ ÔÜÔÌ1Ô<Ì20K° TX½@ÿÀ878YK° TX½ÿÀ@878Y3#%3#¸ììþuìì1öööNÿöƒ >@"   v v  ü<ì291Ô<ì2Ô<ì2.À990!3!!!'7#5!7!N“ü–’¢þÅ®éýmü–’¢A°þÛ1}´ëÜíþϲíÜœÕc@3  %p hpdp~€  % /ÔÄÄÔ<ì291/<äììôì2îî0KSXÉÉÉÉY"!!!!!!#3‰þÝþü6ýÌþæVøf³”ãÕþüþÉþüþnþüjþ–Õþüý…{ÿúÿÁÅ )s@> )*  '$ ($p$ pn$r*(! '!)!!!'*üìüì.À99999991äôìîÀÀ999999903264&'&&#"&&5!27!"&''ÃU8rh9N4pií## g¦=q¢ž''þ÷þüjª@x¢b9=ñ >5 33ðþýþ¬Xãˆ>=¢sß^ïþ‚þxCB§r ßÅ /7@$ š'!› š-™0 $GG*0ÔìÔì99991ü<ì2ü<ì299032654&#"&&#"3266632#"&'#"&54632Õ0P2;JC88bý6J0"#>þïàþ¾V˜þdþÙþd˜Vþ¾àÕý¨Xýð»—½þJ¶½—»®þT¤` G@'  hr‘ !    75!üì2üìÄ991ä2äô<ü<Ä990!3265!3267#"&'#"&'®RRQP!+J#H[%nF;SþT ýXrsrs¨üøG> ÙKSNP/0þ‘ÿçDF)8@'! '!¶* $$*ÔÌÜÌ9991äÌÜÌÎÎ9906654&#"#"&54632#"&54324&#"32?3-,Ë:*:¬}ÀêþÆï¬Þé«f‡MHe…LJd…–c³Bds’<+@lþ½þñþ­þF屯Wít|þôÏuy þLPî *@ · ¸·   Ô<Ä91Üìüì9905!!!!5mþÀýyÁþ=šü/9)ŒÕý üæÓ‡˜þL9î@¸·__ÔìÔì1Üìì20!!!9ÿþ_ÿîø^Óù-¢ÿÙ¾L<@  žœ ¡ LKJKJHôìäÔìää1/äôì22Î99990#3267#"&'&&55!!#5ž¢1F",c7Orþîþã¢LÑýï?¼ " VX#oü…{ÑHþ‹‡)*@$º» º¹*'! `a!`*Ôìüì91üÌìüÌì026732#"&'&'&#"#"&54632mfÖÜbwL=.> b )'8¹yaxMB3F ü‰KûÀbPJ?(:¬Õð %)d@4 $#(£&$£&£¢£¤ n*&(' #*ÔìÌÔì22ÀÀ9991ôäìôìÍîÔÖÎî999905#"326#"&5463354&#"56632#!!fmd=6Vn2yN‚—¹¼[[R@I”L½²Áþ°ýP4818g 96‰u†…11!"¼¬·þ@wª¬çð0@££ ¤£n  ÔìÔì991ôìôìÜì0!!4632#"&"32654&%°ýPŦ¦Äç¦ÅkIUUIIUUVª¨½ßÞ¾½Ýݨ~mm}}mm~Zw´F@$ª¨ «   OON N ÔìÔìääÀÀ9991/<î2þî99073&5323!6654&#"!Zîxlëílxîþ)QNpgfqPRþ'Óm¿8nþ’þÈ¿þñmÓ Oê§ÖèèÖ¦íMþôÿã¤{ Aµ@K. 4, ;5#A ‹ ggy 4‹5ŠŽ1g8g,…>8‰& rB#;-, 4T)-RBÔ<üÄÄÔìÌÎÅ99991ä2ä2ôìî2îöîæî2îî999990@'33040536G3G4G5G6YYYYW3W6Ï ÏÏÏÏA]5#"326554&#"!3267#"&'#"&546;54&#"5>32>32éIWY@=?=Ú2??2Ãþ=d_A=BîþÑÿ‹²Ó +s@>+,  )*&h&h‰&r,+,* # )#.),üìüìÀ999999991äôìîÀÀ9999999032654&&&#"&&5327#"&''?þ¤B&hxþJZ>'jyÏ--íU“C”‹ ./þçîS—C—‹£þc»£:Å›¹¥"4þîI²m=+-°y¼L¸kþñþÃ--²w°ÿåîÕ%x@<   %%  fhrd&# !  &Ô<ü<ÔÔì9999991äôÄìÞÅî9990KSXÉ9É9Y"!!!3267#"&546776654765þõ þõ >PZ=-\\SµabÉeÉåD^XB&ºþošcMY;Q,CDGFþô89¼¥Lƒ\V@T?ãîÕ @ d Ô<ì2991/ôÜÄ0!!!3îþõ þõ!Ç#ºú+eþ›Xjyƒ@ v üüì1ÔÄì0!#!X!îü̓ýç,1ÿÙ–¾ ,@  ½¼   ÔÄ91Äüì90'%3##q@`ªƒØ4þ4»ÛžÆ{ý»$Ðùëø þV#„@I   %   ‹yh‹yh!n$  $ÔÌ91Ä2Äôìôìîöîî299990KSXí9ííí9Y"&&#"!!#"&'53267#5!6632)R%^gþß^Ê >s7+P'_iPü'Ë @!p  pdp €%  üìüÄÄÔ<î99991/æî2öî2î0! !!!!!"33Áý¸þ¼ñòC=þ´.þÒþÏ{\[|4þü7²´8þüþÉþüþnͲþÊþÉ®Íÿãº{ )5o@1("!% !g‹y3g Ž-%g‰ r6*0T!*R(6Ô<üÄÔÄÌî991ä2ô<ì2ìî2öîî999990@ÏÏÏ Ï!Ï"Ï(Ï)]!3267#"&'#"32>32'54&#"4&#"326ºþ>c_>2ð:MN;;NM:ß—;:ô,*JJMG8;;B%$'Œg^$BT%>;ˆ”+?:ˆ”-X¤@µÔÌ1ÔÌ0K° TX½@ÿÀ878YK° TX½ÿÀ@878Y!!-wý‰¼¸F `@ ° ]]ÔìÔì1Ô<Ôì0K° TX½@ÿÀ878YK° TX½ÿÀ@878Y@]332673#"& dSSc ­œ­FEKJF™™ß;ò1MµÔÌ1ÔÌ0K° TX½ÿÀ@878YK° TK° T[X½@ÿÀ878Y´00]!!ßþí1öLá… R@°° ] ]ÔìÔì1ÔìÔì0K° TK° T[X½ÿÀ@878YK° TX½ÿÀ@878Y4632#"&732654&#"L¦vw¦¦wv¦™M67MN66Mþv§§vv§§v7LM66MMoþo3!@  ° ]ÔìÔÄÄ1/ÖþÅ90!#"&'532654&'Ã97{0e5-T$:A*.>j/_[ œ.(R<)î=fI@ƒÔÜÔÌ991ô<Ì20K° TK°T[X½ÿÀ@878Y´55]3#3#Vçþð®“Ùø¤fþˆxþˆ¾þoj@  °] ÔÄìÔÄ1/ÔüÄ90!33267#"&546-5%=2&M(6_)r|7GF'1œ \V5mðîáf5@ ƒÔÌ91ô<Ì90K° TK°T[X½ÿÀ@878Y 373ðÿ²ÆÇ²ÿîxããþˆÿÙÕ 7@  pd    ü<ìì2.9991/äì903'%!%!á—q'pþ}woš¼ÕýøÂ™þïþþü%\D@%  t  Ô<Äü<Ä99991/ìüì99905'!5!%33!"&šþïduþÙK'gþrSbéþÅѶӦâÓáþÑ þèþ‹„náØÿÿÿãVk'6uÿÿ¬ÿã+f'Vàÿÿs‰k'=uÿÿ¢9f']àöþ¢Ù˜@ Ô<Ì21ÔÌÔÌ0##Ùããã˜ý öý öuÕ 9@hp dp  ! "/þ<î2þî9991/Æ2îöîî203#326&#! !!#53°ÓÓP®””®þ‰<nBþ¾þ’þĉ‰ËþºíþrÛÚ þ£þtþsþ¡˜íbÿãf(‹@N (((#$%$"!"%%$%('%"! #&#h hr#t)'& !#(%" .))üìüì99991ìÄôìîÀ9990KSXÉÉÉ9ÉY"&&#"32654&#"432''%'!%+1b0izwhms udVþðòìþêÙ(? þÈ7ž%\)Bþëø‘}ž²µ­-bЉý—þìþÈ2ì ÛwumÊt{uÿÿÉk'<uÿÿ;þX˜f'\¢{Õ0@hh d !  üì22üì99991/ôÔìÔì032654&#!3 !#!Éy’tu‘þ`'n5þîþÎnþÙöþIbxydßîÛøïÙþ´–þVw9@hhr‰‘t 20üì22üì1ìääôìî990%!!6632#"&4&#"326ºþÜ$.–eÀÔ×ÇZbl__nn__lžý¸¾ý¤abþÌþèþäþÐ]ñ¢¸¸¢¢¸¸B ú·vüÌ1Ôì0!!BKûµúîw“Xs 0@   ü<Ì291Ô<Ì290 '7Xþ¶J¨þ¶þ¹¨Jþ¶¨GJËþ¸þ¶¦Hþ¸¦JH¨þ¸H9œÁß )@² ²² ³± ^ ÔÄÄüÄ1ôììÔìî2035733!9âÜÞÂâýx-+•)ýN‘œ¬ð2@²²´³ ²±^ÔÄÔìÀÀ91ôììôìî90!!56754&#"56632ô¸ýf3Z:WK8‡MKŽB©»þ6-‘+KO4<#"¤}o~þè*Ãð(D@&² ²´#² ² ´³ ²±)^&^ )ÔÄÄÔìÔì91ôììôìÆîöîî90#532654&#"56632#"&'532654&FooJUOFEŠDE‹C¢¸ibouÁ¸K–JC˜PU_b’2,-3˜teI^p\yš@8=Dÿÿ/þòw{'ðþþœ'  ¸üVÿÿ/þòw{'ðþþœ' ñÉüVÿÿ/þòwŒ'òÿœ'  ¸üVÿÿuÿãjk'* uÿÿbþXHF'JÚÿÿ¬%k', uÿÿþoVð'6Ýÿÿ¬þo+{'VÝÿÿ˜ÿãAk'&‰uÿÿ¨ÿãpf'Ffÿÿ˜ÿãjk'&‰uÿÿ¨ÿãGf'FàfZÿãÍ$F@&"   "hhr‰t   2)%üìü<Äü<Ä1/ìäôìîÕ<Î2990!5!5!3#!5#"3232654&#"þÎ2$’’þÜ/•eÀÔ×ÇZþžl__nn__lÁ"½tt½û¦ab40]þ¢¸¸¢¢¸¸-¼¤ßµÔÌ1ÔÌ0!!-wý‰ßþÝÁ·w Ôì1Ôì0!!ÁMþ³þ“ÿã5ð1@9&(  ox#o xn#r/21('/),&, 0',2ÔÄ2Ä2üÄÄ99999999991Ä2äôìôìîöîÎ2Ý<Î20@€†€]]632.#"!!!#3267#"'#73.5467#7Ñ,$ëS’DJŒMkŒºTþ‚?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•ÑhÑÑÑãÑçÑѤÑ!Ñ%ÑçÑÑ5ÑyÑBÑjÑ-ÑÁÑqÑ{ѼÑsÑ}ÑfÑучÑÑoÑÁÑsÑXÑXÑXÑéÑÑ!Ñ}јщѨѶÑuщѬÑmÑuÑáÑVÑwÑ\Ñ¢Ñ\Ñ…ÑÑZÑjÑ9ÑÑÑÑsѦÑoÑ/Ñ9ÑÑÇÑ^Ñ–ѨÑZÑ\Ñ®ÑbѬÑÑÑ®ÑZÑRѬÑbÑ–ÑZÑ#ѬÑoÑ ÑPÑÑ7Ñ;Ñ¢ѰÑöÑ´ÑXÑ!Ñ!јѨÑwÑ\ÑjÑ^Ñ^Ñ^Ñ^Ñ^Ñ^ѨÑ\Ñ\Ñ\Ñ\ÑÑÑÑѬÑbÑbÑbÑbÑbÑ Ñ Ñ Ñ ÑœÑÑ“ÑwѪÑÑFÑÑÑÑÑÕÑ-ÑNÑÑÿúÑ ÑXÑXÑXÑÑ®Ñ‘ÑјÑÑHÑÑÑZÑÑѰÑãÑXÑ1Ñ ÑXÑÿúÑwÑÁÑ9ÑÑ!Ñ!Ñ\ÑDÑÑÑјÑ–Ñ°Ñ°ÑBÑuÑ;ÑÑqѺÑZÑ¤Ñ Ñ ÑœÑÁÑjÑ–ÑÑ!ѨÑ!ѨѨѬѬѬѬÑ\Ñ\Ñ\ÑjÑjÑjÑÑðÑ Ñ-ÑÑßÑLÑoÑ)ѾÑðÑÿÙÑ%ÑѬÑsÑ¢ÑöÑÑbÑÑ;ѢіÑBÑwÑ9ÑÑÑ/Ñ/Ñ/ÑuÑbѬÑѬјѨјѨÑZÑ-ÑÁÑÑ-ÑÕÑ ÑÑðÑðÑ/ÑöÑÑßÿ#ö   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ      sfthyphenperiodcenteredEuroc6459c6460c6461c6468c6470c6472c6477c6478c6475c6476""""IkÈ>ºe|¨ÓHe{‘ªy¤e¤óJxà7Yƒ¨Êíaá \ ± ö 0 ^ ˆ å  = t Â Þ S • ×  h ÏEeœëcØNr¯Ñæ ‰Õe½ø]—Ö[ˆ G…ÒVä-g±-˜ó&‡ÿBO #0=JWdq~‹˜¥²¿ÌÙæó gµ ^ëøJˆç2Ëü ( Ÿ!?!Í""8"o"²# ##ï$$$R$€$å%<%˜%È%ë&5&‹&û'A'˜(P(Ô)M)t)‘)Á*<*¼*ø+.+f+–+–+£+°+½, ,”,¨,¼,ì--9-V-…-¯-¼-É-â.^.}.ž.í/0/q/ˆ/¥/Õ00Œ0™0¦0³0À0Í0Ú0ç0ô1111(151B1g1”2+2Y2£2×3&3W3‘3Á3ï4(4s4€44š4§4È55ž5«5¸5÷6D6Z6”6¿77_7p77’7Ÿ7¬7¹7Æ7Ó7à7í7ú88d8z8‘99I9t::::}:Ä:ô;1;Y;o ME@¯ømþÑÿÙÿøÙ ѼGÌþBGÌSöf  €¯ JBits ûþšmãB»Ñ`#cÕVeraSansMonoBdÿÿÿÿ6ÿÿþ628B00@             ÿÿXß-_<õºÁ#ĺ–UÿÙþÙmloganalyzer-3.6.5/src/BitstreamVeraFonts/VeraBI.ttf0000644000175000017500000017335012225176641021545 0ustar danieldanielOS/2µ†÷GàÌVPCLT-´ôá$6cmap¤Ãè ½Xcvt sã…4Âfpgmç—ñÄ&d‹gaspö¤ glyfWkG»&ð–hdmx':ïá\HheadÝ®ÄËö°6hheal’à¨$hmtxz€W–ÀX,kernöì É$dlocaÿ<%XÇ maxpJDàˆ name2i+èpostø–xúÄ„†prep|餖 øk:: N : : Zf0À  – ƒ t ® & "  J @ " @ "  b : z ` . ¬ 0Ú & ´Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans Bold ObliqueRelease 1.10BitstreamVeraSans-BoldObliqueCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans Bold ObliqueRelease 1.10BitstreamVeraSans-BoldObliqueCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com#/f3f¼é=ú;+ffTì}Íf¼ºå+–\9×//uüÍÙ“¸šì¸LfLššDDÍš;ËËÕÕP¬¬w /X²#öö/55ç3˜ÑXfåòsÕƒ+ÕÃá×åj-ÕÕð¨jìáÕ!føì¦ø#^Í`lj켺3B3\šáfy```{ìøÍÝÕj\{šÝ®º…®šXîššÑÍšPËË‹‹ðL`¨Á%Á!J–Jƒ7{ɨÁÁÁÁ–ì}3˜ÑXÍy9œbœ“¸¸s¸€@ÿÞþÝÜÛÚ:ÛþÚ:ÙdØ»×þÖÕÔþÓþÒþÑþÐþÏÎÏþÎËÊ}ËþÊ}ÉÈŒÉþÉÀÈÇYÈŒÈ€ÇÆ&ÇYÇ@Æ&ÅþÄúÃþÂúÁ Á€Àþ¿ú¾}½>¼þº¹,ºþ¹,¸þ·¶G·}¶Gµú´þ³þ²þ±»°þ¯®þ­¬ ­þ¬ ¬@«ª «2ª ©ú¨Y¨þ§ú¦ú¥Y¥þ¤þ£þ¢ú¡ ¡d ŸhŸdž@ÿ%žú%œYœú›š›š™š™˜— ˜ — –•%–ú•Y•%”“”&“’“’‘Y‘Ž»þŽ]޻ހŒ%]@Œ%‹þŠd‰X‰þˆ‡†:‡ú†t†:…„…2„ƒ„ƒ‚ƒ‚ ‚ €Y€þþ~}|þ{þzþyxwvtvúutuútYtsYs}rþq&pþoþnþm @ÿlþkjkþjj@ihiúhYhgYgúf\ feþdc»dþcb]c»c€bW%b]b@aþ`_.`þ_.^Y^]\ ] \ [Y[KZYZþYXYXW%VþUþTþSþRþQþPO%P–O%NMþLþKþJúIúH H@FE¦FþE¦DCDúCC@BdB@A}@þ?>,>,=ú<þ;þ:þ94 928þ7265 6@ÿþ5 5@43 4 3 2þ11}0/0d//.þ-ú,+,K++**K)()(' (' &%$%2$#"#"!%!ú   2@   @:–%dþdþ:–%:þþ%K  þ þ  –  @úd:@  @¸d…++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX °àEDY!-,°%E`D-,KSX°%°%EDY!!-,ED-fþ–f¤@ ÞÞQ/ÄÔì1ÔìÔì0!%!!füsüåþ–øòr)Õ Y@.   :UTS ÔäôÄÀ991/äüì0KSXíííí9Y"!!!!°iqƒþþlhEþ—ÕýÃþ^¢ýÌþœÃªhÕ@VSüüÜì1ô<ì20###híËíÕýÕ+ýÕ+…=¾P@6 Z Z W   ôÌ91/<ä2Ô<<ì22Ô<<ì220!!!3!!!!#!#!7!!7!þøF+`aÝa)5þ×E)6þÙ`Ý`þø`ß`þã5Fþå5`hþîhþþÕþî×þþ×Õ7þÓ !(/v@C# ")^] ^][* [!*)#"&- !&-& - & 0ÔìÔìÀÀ9999991/<Äì2ÔÄüôìõî9990#&&'&&54$773&&'6654&T¢;Ú]1`Ùx=Ò¿+ÿ,¡+e¼X1?¿w9ÕÍþÓþî3TdA§7ckIþÓ-+&7=7¡Çõ åã"þ%/þà$¢†Üú DQ=07þ³þãVK39qÿã“ð '3M@+e .e"a(ee a`d4+%   1  + %4ÔìÄüìîþî991ä2ô<ììîþîî0"32654&'2#"&54#3!2#"&54"32654&Vo=>Wn? ½þ÷Ö½ ü±õÓõûkœ¾þõÖ½ ·Vn==Wn?h¨…WW¨‡UW¨«Œàþê­ÞüÓ ¬ŒßþêªÞ¨©„XYªˆTX9ÿãð&0@[   0'0%&$''0:0' - -iYf!gd` '*$ * 0$* 1ôÄìÔìî999991/Æäöîöîî99990KSXí9í9í9íY"²]@`  * 9 K K'[ \'bm n'   &0' ' +'+0;';0III H H'J0ZZ\ \ \\#X'honki i l0$]] >7!!'#"$5467.54$32.#"3267m)>Z7+ŸxþJTvì{õþÖ¿É.ï[¿e5WžOVd<óPS˜r54&#"6$32ú‰7ûÄ8{hmpe_ê“@ˆ€ä þðþåßP¤MRZKN=21Ū’ðÌÿãð(i@,s ^ x s ^xsw#d`)   & /ÔìÔì9991äôäüôìþõîî90K° TK° T[X½)ÿÀ))@878Y!"&'32654&+732654&#">32Çq~þwþ¨‚ëh9YÒi©Å–—™1¢·yUÈl7våpýÿ±%žsøþá%%)49kYYøraLP,* ¨¦•ÇÿþÕ ¡@;         : uS    ÔÔäÀ991/äÔ<ì290KSXííííÉÉY"K° TK° T[K° T[K° T[X½ÿÀ@878Y·K]] !!3#!!Lýíšo¶¹Õ5Õ5þ“6ý`Aýš®üRþéþðJÿã'Õ’@9:^]]sys vS `  ÔÔìÀ9991äôìîöþäõî90KSXíí9Y"K° TK° T[K° T[K° T[X½ÿÀ@878Y!!>32!"&'32654&#"j½7ýv-,_0åþrþ«}ìt;oÑlž¾|TÃtÕþåç ѹþÚþ§12/HD¥†`q+-fÿáHî 'r@! ^ ]sss%d`(  (ÔìÔìÀÀ91äôìîÖîõî90K° TX½(ÿÀ((@878Y@```` ` ` `````` ]"32654&.#">32!"476$32år’ZPq“X6V¢QºæN¥]¸êþ—þäÿþè|pxGÌ^²á¼”Yc¹`fÍþì,,ȵ31Ú©þìþŸ!Ìs†  Õ3@:vSÔÌÄ991/ôì0KSXííY"!!!'f-üÁþý<ÕÛûº-ÿãFð #/t@$ *ssw$sd`0- ' -!0ÔÄìÔìÔìî991äôìäîî990K° TK° T[K° T[K°T[K°T[K°T[X½0ÿÀ00@878Y"32654&%.54$!2!"$546"32654&°ufXwœgþ²lkM&쵨ztþ™þÇ÷þíÓ3f{YIf{YœŸtSauSb-eËè° ŽÊ-/žyæþôŰŸïwbDTwbESTÿá7î'€@ ^]s s "sd`(%% (ÔìÔì91äôìÄîîõî90K° TX½(ÿÀ((@878YK°TX½(@((ÿÀ878Y@o o o ooo$o%o&o' ]73267#"&5!2#"&2654&#"T5W¢QºæM¤]·êiÿ|qxþ»Ì_´r’WQq•X!-+ȵ31Ú©aþßþøËþ‡ í¼“[bºŒ`fT–`N@(:TzTÔäÔäÀ91/ìôì0KSXííííY"!!!!-iJþ—ChLþ˜`þ}þ¦þ}ÿ¸þÝ–` Z@.   :TpTz   ÔäÄÔäÀ991äüìî0KSXíí9ííY"!#!! h;þÀÕ¬ÉiJþ—ƒþÏþ‹uþ}Ù=ÛÇ@|{ÔÄ291ôì90 5Ûü<ÄúþÍþ´þ¶úÏìÏÙ'ÛÛ@ o}oÔ<Ä21Ôìüì0!!!!ÙúþúþÛëÜíÙ=ÛÇ@|{Ô<Ä91ôì9055ÙúþÅÍúþ1ìþ1úJÕoð!€@I !:!  Y]iUTd  ! "ÄÔì999991/äüìþôî9990KSXí9íííY"!!!766776654&#"6632hFþ˜Ëþ—WƒJOHQLPÉs>ÒaÂÜj€LP9dþœø1P}f:=j69=CB:*(«•w¼f<>M+\þ j  L]@5IM-.* LF~*1~!=WM -.L C'7MÔììÜìî991ôììÔìü<<Äì2ÄîÄ9990"32654&#"&543273654!"!267#"&'&5476$32!"#"&' j˜QMj”P'-–Z¤ÅS}Ë…—Ëþ·þùÄþ¯v\`Kvçhm’þ⎇úbŒ‘xr’›í¦oirþgþ´!Ò‘TXÉ’V^ýÕKS½§ÝBTE…ýK¿Õ˜nþøŽþóþ«WSžbbRMl>ɰH‰°½]\Yï‚þÅþvÿ{‡Õ ž@A     : uS   ÔÌ91/<äÔì90KSXííííííííY"²]@  + / ? ¿ ¿   + ) †]]!!!!!îý¬”þuL¸þ’þ‘ZþðÕú+?+˜Õ h@::€…€S €   !ôäÔìÔì9991/ìôìôì90KSXííííY"2654&##2654&##!!! 3gtQL×>e„ŽbeãL¬bkþ™þ»ý#A ÿ–“h[;>þÄýs~vKHþy•nñþñÕœ£‰ÏJÿãËðJ@ uu d` ôìÀÀ991äôüÄþÄ990@  ))]]%# 476$32.#"3267ÙŠþrþÓþ˜roƒqÕtêy>`ÂoçþÈÀ©eãF12J³=ƒš¦78þËIDþœþõ¬ÄIN+JÕ@@!  :‡ S‡   ôäÔì9991/ìôì0KSXííY"3 4&#! !!˜³Š :ÍÊþ/•""`ab§—„þ£þ–þj²üq.®²#EQQç’Ëþ™zm\+\Õ T@/    :‡…‡S‡    ôäÀ91/ìôìôì0KSXííííY"!!!!!!N9ýs6g:ýšB¢7ûÛÕþÝþêþÝþªþÝ+\Õ O@+    :‡…‡S  ôäÀ91/ôìôì0KSXííííY"!!!!!N9ýs6g:ýš{þÕþÝþêþÝý‡Jÿã9ð h@6  : €uu d`!  !ôìÔÄ2991Ääôìîî99990KSXí9íY"%# 476$32&&# 3267#!s’þƳþÂþ”rqŠwñ†„;zévþþþ¼½¬8p99ë1VoGECµ=ƒ ž87þËGFþ¨þò³Æ"+‡Õ u@A     :‡…S    ôäôä91/<ô<ôì0KSXííííííííY"!!!!!!No8nþÝþ{ýÉ{þÕýÇ9ú+yý‡+ÏÕ6@:SôäÀ91/ä0KSXííY"²]!!NþÝþÕú+þ¬þfÏÕ g@%  : ‡S    ÔÌ9991äÔì990KSXí9íY"K° TK°T[X½ @ ÿÀ878Y!!#3267Nþú:þ­þ¾N9  :S  ôäôôÄ9991/<ä2990KSXííííÉÉY"²]² ]!!!!N®VÉlþÝþRþªÈþ“Õûö ú+ ûöJÿãƒð ;@ uud`! !ôìôì1äôìî0K°TX½!ÿÀ!!@878Y4&#"3267> # 476$쟗Èþñžs³?ø qÈRn{ojaé*kþÏþðåþ‘4Ÿ—Èþñžs³?=Qû·EŸ›þµþõþÆþ'lþºœ°¸þ™þò¬¾a_[ä+{Õ@H    : u u S      ôäÔÄì99991/<ôìÔì9990KSXíííííí9Y"²]´ ]2654&+ !!2!.#ðƒ‡]dŸL3oþ#9öþÈ«Nh'þp"a\?zvJEþþöýËÕ¸³µêƒþXsoSÿãRð'@;    : ˆuˆu%d`( " "(ÔìÔìÀÀ99991äôüôÄþõÆ90KSXí9í9Y"²]@Œ9 9 9 9 9 99999 9!I I I I I IIIII I!YZ Z Z Z Z ZZZZZ Z!m m m m m mkkmmmmm m!y y y y y yyyyyy y!< )```` ]].#"!"$'32654&/.54!2R>qÜi¡GožÆ¹þþÉ‘þá‰=…ûz„¥J}®ªe.yÿ¦þÄ87ZP39'2½–óþÚ65EMLlT7= '+º”é%büÕ`@:‡SÔôÄÔÄÆ991/öî20KSXííY"K° TK° T[K°T[X½@ÿÀ878Y!!!!œ`9þêþêþÕþÝûN²‹ÿãTÕg@:     : ‡` S  ÄÀ91ä2ôì90KSXíí9í9íY"!3267!! $5467N® ihŒ–$®®Aþ•þ®þ÷þì Õü‚0Jba»üþ¶þ×ãØ$Y;œ¸Õq@':SÔÌ91/ä290KSXííííY"²]@%5)76 ]]!!!œn·jüµþ5Õû¤\ú+Û %Õ @J        : S    ÔÌ91/<ä2290KSXííííííííY"K°TX½ @ ÿÀ878Y@j       / / ? ? O O YYY Œ      &%#' 637 0 BB UZVPP €€€€€† ‚ !]]!!!!!Ûd.Õn1Åý}þL2þþBÕûÃ=ûÃ=ú+oû‘ÿ˜Õ ¿@I   :  S   ÄÀ91/<ä290KSXííííííííY"² ]@4  -$ <2 LC    '$' * 79 : DHG ]] !! !!ønþyóþKþaŸþž‰æ™¢ôý ôþ þ×þ+ÕyÕx@5:S  ÄÀ991/ä290KSXííííííY"²]@  D]]!!!þ¼½ýyþyÕý×)üšý‘oÿËìÕ 9@:‡S‡   ÔÌ91/ìôì0KSXííY"!!!7!è0ü8%:úì-ËýÕîü<þÝîÄÿìþòºF@":‰l‰kÔäÔÄÖÆ991üìüì0KSXííY"!!!!Nl-þêþó-ý–áú á‘ÿB5Õ@ SÔÄÀ91ôÌ03XÇÞÆ¾“ùmÿÇþò–@@:‰l‰kÔÄÔôÔÄ991üìüì0KSXííY"!7!!7!3ý”+ þç+mþòá`áϨåÕ@ SÔÌ91ôÌ290##ÕñþfþgòÕýÓ-þÓ-ÿìþÿµÔÌ1ÔÌ0!ûØáþþ îøf2@ ‹ŠÔÌ91ôì0K° TK°T[X½ÿÀ@878Y#'ÑÅþÙfþˆx#ÿãã{ +ó@c        : "  –”g#‘"g&`  )#"),ÔÄìÄ9991/äôüôìîöî99990KSXíí9í9í9í9í9Y"²;"]@83!0"C!@"S!P"c!`"”!"¤! "´!°"5":#:$K#K$[#[$k#k$›#›$«#«$ ]]"326?%!7#"&54$!37>54&#">32¢†‰QGn”ƒ}þšXÄsŸ»K8Ó}{oÐa6pë~ùò øSQ=F…y)‡ý¦d_¥ŒÖã BC..«¯"Q?ÿãj Œ@K  : ii`k    !  ôäÔì9991/ìäôìî990KSXíí9í9íí9í9Y""32654&!!6632#"&?НcX‡°_þ.!þ™.huR´k½ÜMH[åƒs¡wÿÌ\iûÄfký+¢ý¨b]ðÏôd~‚]Lÿã¦{3@‘ ˜ i‘˜i`  ôÄì9991äôüôìþôî0&&#"3267# $5476$32¦9HŒC¯ÞŠ~T¢I7Y´[þøþãibm¸U¨=þÜ02ë·u21þÛíÚ‰gqnJÿãË Œ@K  : ii` k    ! ôìÔä9991/ìäôìî990KSXí9ííí9í9í9Y"%2654&#"!!7#"&54676632uŠ­aWˆ°_ÓtiþÑþ—!R´k½ÜMH[åƒs¡çþÍ]hûÄfkÕXùì¢b]ðÏôd~‚]Jÿã{'H@(œ ‘ ˜g›$g`( ' !  (ôìÔÄì99991äôìäþôîî90!3267# $54676$32%6654&#" üºƒƒqûŠ7ƒþý†þúþã[Wg¯ã þ¢`Ri“'9mlDCþê0/òÝ€ñdx|òÍ(Yo  P^spfR©@<      : igkz     ÔÄÀ991/ä2üìî2990KSXí9íííY"K° TK°T[K°T[K°T[K°T[K°T[X½@ÿÀ878Y@ ``pp]#"!!!#37>3R/ÅKE /1þѨþ˜¨±2°%êØë7COÿü `Nº¬)þFuy+¤@Y+* )'&(  :& &‘˜g i zž&i)#! ,ôÄì99991/ìääôìþõî99990KSXí9íí9í9í9í9Y"%#"&546766327!!"&'3267"32654&XV²i¾ÝMHXäƒv¡7i½:þ„þ®hÁ^5UªY²¿!T„¯^Zƒ°^¾b\õÔqãdy\c¦ü3þÓþà !65˜¦î´fkí±hm?;@L   :  Ÿk  %#  ôäôì9991/<ìôì99990KSXíí9í9ííí9Y"²0]!>54&#"!!>32)…þ™q GAoŸlþ™.hucÈm›¨ ªýVH9O@F­™ýÙý¨a^¢“ N?ÕX@(:¡zk  ôÄôäÀ91/ìôì0KSXííííY"² ]²o ]!!!!hÛþ™.h9þ—`û þÜþúþFÕ •@:     : ¡gžz k   ÔÔä...ÀÀ9991ìäôìí990KSXíí9ííY"K° TK° T[X½@ÿÀ878Y´o]!+73267!!h×.ûÕ²-?e]+h9þ—`û´ëãë[ˆþÜ?º ¾@A      :zk   ôäÔÄ91/<ìä90KSXííííÉÉííY"²]@<     )EQXcwpvz—§  *ESdpus§ ]]!! !!mh¤ã¦ýuÙþgþ•^þ™üµ—ýúý¦ãþ?Õ6@:k  ôäÀ91/ì0KSXííY"²]!!mhþÑþ™ùì?ß{+ÿ@x !    "#$# !$#(')&$#%$$#:!  &$ Ÿ)$z" %"!$  &$ %% $# ,ôÄÔüÔì99999991/<<äô<ì299990KSXíí9í9ííí9íí9Y"²]@#     /-]>32!7654&#"!>54&#"!!>32SÓr–­ …þ—q?6glþ—s >7c•lþ™Úh!T¾gt¦¦gn¥M1ýVH|#7@©ýÙHKM8?¯—ýÙ`¤_`w?;{“@N   :  Ÿz  %#& ôäôì9991/<äôì99990KSXíí9í9ííí9Y"²0]!>54&#"!!>32)…þ™q GAoŸlþ™Úh!cÈm›¨ ªýVH9O@F­™ýÙ`¤a^¢“ NJÿã5{ )@ii ` !)! ôìôì1äôìî0²p]"32654&2#"$54676$‹´a]‹´a@úZVfþê«÷þã\Vd{üÃjoýÄinþÛïcvxþÛ~ñdtxÿìþVj{–@M:ii`¢z !   ÜäÔì9991äääôìî990KSXíí9í9íí9í9Y"²0!]%!!>32#"&"32654&Çsþ˜-h!R´k½ÜMH[åƒs¡AНcX‡°_¢ý´ ¤b]ðÏôd~‚]7ÿÌ\iûÄfkJþVu{‘@N:ii`¢z  ! ôìÔä9991äääôìî990KSXí9ííí9í9í9Y"7!!#"&546766322654&#"îiþÓþ—sP´k½ÜMH[åƒs¡þ¿Š­aWˆ°_¼¤ùöLb]ðÏôd~‚]üÉþÍ]hûÄfk?\{’@6       : ‡ z   & ôäÌ91/äôüÄ9990KSXíí9í9íY"² ]@#    @@@@@@``````].#"!!>32%Z4‰µ fþ™Úh'GÕ‚0!/°¦ýü`Àjqÿã{{'¯@9    : ‘˜g‘˜g%`(  ,*"(ÔìÔìÀÀ99991äôüôìþõî90KSXí9í9Y"K° TK°T[K° T[X½(@((ÿÀ878Y@i j j jjj j!````o)vv]].#"!"&'32654&/.54$!2{5iÐ]js@^AÙ®þÎþísð}6aÝtqr@dAÀ¤sß=þê2473$ .‘ÃÛ$$9:64$( (œŠ»ÊXž¢@>  : iz i  ÄÀ9991/Äìô<ì2990KSXíííí9Y"K° TK° T[K°T[K°T[K°T[K° T[X½@ÿÀ878Y²)]!!;!"&5467#3á=n3þ’\=H¹3þÓ¢ª\°1²>žþÂÿþ& .(ÿˆ€@!Û>{ÿãs`Ü@M    :  Ÿ` z &%ÔìÔä9991/ä2ôì99990KSXíí9í9ííí9Y"K° TK° T[K° T[K° T[K° T[K°T[K°T[K°T[K°T[K°T[K°T[X½@ÿÀ878Y²0]!3267!!7#"&546‹ƒgq FAo lgÙþ—!\Êp™¨´¬ý¹9P?F¬™'û ¤a`¢”#Nm`¢@&:zÔÌ91/ä290KSXííííY"K° TK°T[K°T[K°T[K°T[K°T[K° T[K° T[K° T[X½@ÿÀ878Y@€€FVffj‰‰]]!!!J‘¦kýnþ…`üòû ²j` Ð@F     : z    ÔÌ91/<ä2290KSXííííÉÉÉÉY"K°TK°T[K°T[K° T[X½ @ ÿÀ878Y@(I   %% GHF W fh xty ]]!!!!!²J'R)P`þþ„%þªþ`üþýû üþÿ¬^` ÿ@I     : z    ÌÀ91/<ä290KSXííííííííY"K°TK°T[K°T[K° T[K° T[X½ @ ÿÀ878Y@N  (%)+ 1GJ €  ((')+* 65GEGFG G G kch i € ]] !! !!Åþ×t¦#…þ8þ‹°þ¾þ{=#þ´LýßýÁbþžþF`Ç@C :  gžz   /Ì91ä2ôì9990KSXííííí9íY"K° TK°T[K°T[K°T[K°T[K°T[K° T[K° T[X½@ÿÀ878Y@   H]]!!+7326?‡Ršý;wÊ Ù%qXa&!`üøû6Ïë;J<ÿî°` x@,,:izi   ÔÌ91/ìôì0KSXííY"K°TK°T[K°T[K°T[K°T[X½ @ ÿÀ878Y@)&/ ]]!!!7!ßÑ1ýFC1ü/¼ýÕ`úýšÿúfÙþ²Z0³@g0/.-,+* $%&'() "!# : 1 #)*‰‰‰k110-*)&#   1ÔÄÄ99999991üìÔìÔì99999990KSXí9í9í9í9Y"#"&546776654&##7326776633#"3+Ú³µ%[u@->ƒ'%éÛÙ+F‹g!vrPJ Qtmá{{<(Á7XHßt–ÍÁ¯áWަœZMC(¦.0C4þç¶Ôì1ÔÌ0#çãøZþ²Ù0¼@l+,+0,,+ :+1''%,'‰%‰/‰k1'&0  /0+",%(&01ÔÄÄÀÀÀ9999991üìÔìÔì99999990KSXí9í9í9í9Y"32677667&&546776654&##73233#"##…FŒg!wsPL !QtC+Û³³']t?-=ƒ%%êÛÙmY¦›ZND-¦*2D3áz{="Í6XHßu–ÀÁ°Ù²ÛR#@ o oÔÄ1ÔìÜìÀ990#"'&'&'&#"56632326Ûj³`k›^X¬bk²`k›^V©RôPE:=MSôPE:=Kÿÿÿ{‡k'$Duÿ{‡m !Ó@P!!    ! !:! u W " !  "ÔÔÔÄÔÄ99991/<ÄäÔÄî9990KSXííííííííY"²]@2!!!-!9!?!Y!‹!º!¿! ! !(* +!‰!¹! ]]32654&#"!!!.54632!M66MN56Mhþ’+ý¬”þu9§vu§ý‹‘ZP6MM66MMÖúPþð²%M,u¨¨u0MüL?ÿÿJþoËð'&Ý–ÿÿ+\k'(uÿÿ+‡m'1uuÿÿJÿãƒk'2¼uÿÿ‹ÿãTk'8muÿÿ#ÿãf'D´ÿÿ#ÿããf'DC´ÿÿ#ÿããf'D×´ÿÿ#ÿãã1'DŽ´ÿÿ#ÿãã9'DØ´ÿÿ#ÿãã'DÜ´ÿÿLþo¦{'FÝçÿÿJÿã3f'HãÿÿJÿãf'HCãÿÿJÿãf'H×ãÿÿJÿã1'HŽãÿÿ?Ãf'Öÿsÿÿ?f'ÖCÿsÿÿ?Pf'Ö×ÿsÿÿ?R1'ÖŽÿsÿÿ?;9'QØÙÿÿJÿã5f'RÁÿÿJÿã5f'RCÁÿÿJÿã5f'R×ÁÿÿJÿã51'RŽÁÿÿJÿã59'RØÁÿÿ{ÿãsf'XÙÿÿ{ÿãsf'XCÙÿÿ{ÿãsf'X×Ùÿÿ{ÿãs1'XŽÙNÿ;Õ [@0:¥£S ¤   ÔÄÀ9991ä2ôìî20KSXííííY"!!!!!7!çJJ!-þßÑþ·Ïþß-#ÕþƒîûÑ/î²dLþ @¦§¦  -.-Ôìüì1Ôìüì0"32654&'2#"&546HdcIHdeGBz0/11-0|D¿Á\dHHbcGHd¢3/0xDCy-03¿Á‰þÇá˜"a@8  ‘˜ ‘˜ i i #   #ÔìÀÀÀ991ÄôìÄÆüôîõî99990&&##667#&&5%3åf{94p9K‡@ €YŸG8HœU7¢7Éçl(7¢7D’X.Ñ€Jm5þÜ20ýh10þÛþâ"é¶#’"#þá‡ð}@E  :^] gsd s  ÔÄÀ99991/Ä2ì2ôìî2õî990KSXí9íííY"&&#"!!!!3#737$!2‡7;ŒG}Œ!u-þ‰@3û•4á?À-Â!4.\°ºþâ%({…ªïþºþö Fïªùÿ¼ÿ=ôð3?‚@F@1:4%  $+¨¨1d@$7! =%+.47! :=(!11.=070.(@ÔÄìÔìÄîîÀÀÀ99999991ÄôìþÅÅ99990&&#"#"&'732654&''&&5467&&54$326654&ô+Z=P^19Z¯€š“96þæìT´_0f =Ma0O‡wp“42ÝS¬þ!PUa£PXr¶ã(&=22)N—o{¾:$X6¢Çí++?0/%=6“f{¿;)\5œÉýƒY>=V@[8=]'‘ö`·© 2Ôì1Ôì04676632#"&'&&'535‚IIƒ245633ƒJI‚326úJ‚235624IJƒ336633ƒ˜ÿ;ÓÕ c@.  :S  ÔÔÄÔÄÀ99991Ä2ôÄÌ0KSXÉÉÉÉ9Y"!###&&54Ëþ¸¾+½þÓ¼¤¨¶9ÕùfùùN¸”×?ÿãT7ª@^&% %&%67734257:5,& % 2gg2gk`667&%)"/ 57) ,/), "/, 7 8ôÔÄìÔìî9999999991/äþîþÕî990KSXí9íí9í9Y"6$!2#"&'732654&''&&54676654&#"!*5âë—²f =TNþêäN—J18o4Rd.M=C<·­ROfu×þ™ZàÚ°ª0I]H7H+;‹[ÁïôL=(A7+/e?ŠÆ1CFkpû´åÍ 4Lb@8-*+'®0®!«¦5­ ¦2+«A'*,$0-+$!1837$4-;6-34GMÔììüìüìî299991/ì2îþîüîÖî9990"32676654&'&&#32654&'2#'&&###2#"$'&5476$yÐWWWWWVÑy{ÎWWWWWXϲ##NOM+°®i`)Goåk&: Õ1˜mmllmmþù˜˜þùmmllmm3WWWÏzyÏWVVUWWÏyzÏWXVþÙÏ5442ŠwyVpP:ÝÕNAþœD7nmmþúš˜þûmmnnmm˜šmmnåÍ1IH@(  ¯¯«¦2­&¦«>7,- 486 -9DJÔììüì2ìî1/ìîþîüþÅþÄ990&&#"3267#"&54632'"32676654&'&&'2#"$'&5476$+9o9q~r@s.Aƒ>ÓþþÓE€îyÐWWWWWVÑy{ÎWWWWWXÏy˜mmllmmþù˜˜þùmmllmmf×%#€rs~$#ÕêÂÃé·WWWÏzyÏWVVUWWÏyzÏWXVšnmmþúš˜þûmmnnmm˜šmmn'“RÕ v@>  :  ® S ;: : ;:ÔìäÔìÔìä91ô<<ì2Ô<<Ä9990KSXÉÉÉÉY"73#######5ww㪉L‰¬q®¬¬Õããý¾µÿþKBþM³ÑîPf\·‹ŠÔÌ1ôì0K° TK°T[X½ÿÀ@878YK° TK° T[X½@ÿÀ878Y@ ))<<LL]!#+%þJÉfþˆ7;ß1u@ÔÜÔÌ99991Ô<Ì20K° TK° T[X½@ÿÀ878Y@*    0000 ////????]]3#%3#fî1ì½ë1ë1öööÙÿöÛ =@!   o} o  Ô<Ä291Ô<ì2ü<ì2.À990!3!!!'7#5!7!Ùü•‘ëþ^®Püêü–’쨰ý¨Û1}´ëÜíþϲíÜÿ`“Õž@M  :‡ u‡ …S ‡ ÄÀ91/<Äìôäìîî90KSXííííííííY"²]@ %%] !!!!!!!!!Ùþ‰ywþ´9ýs5f9ý™A¡7ûÛDþÙþÕýžbþÝþêþÝþªþÝ^þ¢ÿ ÿ²++ (6@D(76) ,&# ,'#,u#ud#`72'76) 2 2&(2 7ôìÔì.À99999991äôìîÀÀ99999990@‘             ! . / 0 1 2 3 4 5 6@@@@@@@@@@@@@@ @!@.@/@0@1@2@3@4@5@6PPPPPPPPPPPPPP P!P.P/P0P1P2P3P4P5P6H].#".5476$32%#"&''3267>54'&'¬(zRÊþóþ¹**nkaé”éXfþþ--oj‚þœç“ì\üf{'zNs³?a_\åt5úé /B@#  $'!±-²±!°0 $<*<0ÔìÔì99991üìü<ìÀ999032654&#"&&#"326#"&546326632#"&¼+vIZqgLHwþñ+tKZqfMGz©DŸa‹Æ¯ŒZ™cGž_ŒÅ¯Œ[–1CDeOMeeCCdOMeia‚~ó³¼êq„~ò´½ënÙÛ .@³o³  o = = Ô<ì2ü<ì21/ìÔ<ìü<ì0!!#!5!!!Ñ ýöîýö ýöúþþžìþžbìbûêîÙÛ¨ '@  o ´ Ô<Ä2291/äüÌ90%!55ÛúþüúþîîîÆÑÑóPëNÙÛ¨ '@ o´  Ô<<Ä291/äüÄ907!!55%Ùúþúþîî´ôþ²ëþ°óÑ  Õ’@S  : µ µ  S    ÔÄÀ9991/ä2Ô<ü<Ô<ì290KSXííííííY"!!!7!7'!7!!!!!!þ:RþƒRþA'½þo%#×pÕþH%%þh;Æ þ` ÂLLÀþ ôýåÀLLÿÉþT\`&š@W   &#$"% : % Ÿ"`¢ z'&%  'ÜôÔÄ999991ä2äô<ì990KSXíí9í9íí9íY"!3267!3267#"&'#"&'7-hVRfxh‘'29b-Xc>—XJ]`þT ýu(INpu‹ý# úLROO/0þ;ÿçR)8@'! '!·* $$*ÔÌÜÌ9991äÌÜÌÎÎ9906654&#"#"&54632#"&54324&#"32þ;'#ÂS0@ºÒõþ»ÿ¶êï³e‹ID`IFa~¬qº9WzºC2Eqþ¾þèþ¨þGé·Ë Uór|þïÒtx)þw“Á 0@  ¹¹¸  ÔÄÜÄÄ91Äüìî990!!!!5Bü’lý’¥ú–ºý_Áþ÷ý{ýNþö¬²–þw²Á@»º¸??ÔìÔì1üìì20!!!!–þ¨ý”þ¨Áø¶)ù×ÿÝJD/@    ÔÌ991/<ÔÌ22990#!#!#"663J'°šþá˜î—þá˜7: Õ¼ÙDàüœdüœd>DÇœ3þ‹°,:@ *#¾½¿ ¾½¼- *(&  @A @-Üìüì991üììüìì9026732#"&54&#"#"&54632jcãìi‚RA@Ae '&>ÄkTF54&#"7>32/'üÑ\”p>5T‚VøB—e}‹÷óMLX®U#b¯KºÃ=ÈÄ9F,4qXTþ@}LFod› ,.##´€z3^u\ð b@à ÂÄÀÄd   DD ÔìÔì99991ôìüìüì0@,@@@OOOPPP___ JJJEEEXXX ]]2#"&54!!"32654&Ï·ÖþÙó¶Ú*þ©7&üÈXc‚FCc‚Gðµ™Ûþó·—ÙüMÈѹLP¸ŽKQ7îå>@  ËÉÅ  GFG F ÔììÔììÀÀ9991/<ì2üì990!!654&#"!!&5! Ë#ýŸ~„˲±Ë„~ýŸ#~zx89xzÿ#V¥Ëééˤþ÷UþÝy¤9yþ‡þǤþê#ÿã{ @JÔ@T7@5= ,&A Aœ–5&‘%˜"g5”) ‘@G=g›/)`KJAD76 ,:%&D5:@ 2:D2KÔìÔìÔÌ999999999991ä2ô<äü<ôìæþ<ôîîî999990@6; ; K K [ [ k k ­ ­ 2?0@B?@@R?P@b?`@’?@¤? @´?°@]]"326?>32>32!3267#"&'#"&54$!37>54&#">54&#"¢†‰QGn”ýÕußh•Ä9_Õ‚ß ü¼ƒƒpù‹5ƒþû‡­ìBu÷ŠªÀK<Í|xrÏ^¼aQi•%øSQ=F…y)JIMMIôÉ-\/9mlCDþê0/ghif¢Øã BC..‡  P^toÿÝÿššÇ$+{@@$,+%("(#(ii`,+#, %+ +" $+!! ,ôìÔì.À999999991äôìîÀÀ99999990&&#"&&54676$327#"&''3267‰E-Œ© þ×''[Wd¬h¬DÀa·))ZVeþç©m¯DÁ`E/«JïÖþø;‰L~ïduw..¨o¢;ŠOïctz12¬pøÙLÿåçÕ!‡@M !!!:UT Y] i` S"  !  "ôìÔÔä999991äôüôìþí9990KSXííí9íY"!3267#"&54677667%!!h VƒKPFPLPËr=Ó`ÃÝjLS8Žþ—FhÝ3P{f<=h69=DAþÆ*(«•w¼fK“Á@Ÿ/Î91/îî90!!!Éþºþ#-3úmVüªÁú?}‰Á' 4@     ÔÄÔÄ991Ô<Ì29077Á2þ¦+þZ%L1þ¦+þZ%'üåÞßqºsüåÞßqºu‡¶' 4@     ÄÔÄÆ991Ô<Ì29077%%77%%7u1Xÿ+¤#L1Xþþ-¤#‡þåÞßþºþþåÞßþº^ƒ y@=    :T     ÔäÔäÔäÀ999991/<<ì220KSXííííííY"!!!!!!%hKþ—ýÑhKþ—BhLþ˜ƒþ}ƒþ}ƒþ}ÿÿÿ{‡k'$Duÿÿÿ{‡m'$DuÿÿJÿãƒm'2¼uV ;Õ !€@8    :‡…‡ S ‡  !  "ôìÀÀÀ91/ì2ôì2ôì0KSXííííY"²]@ ## #0#`#p#€# ]#";!!!!!!# 476$3ôiŒÐLq‰ñÿkh9ýu8g9ý™A£9ûy7þ…þ`ìЀ;Ͳ/1Jú‡·­²þÝþêþÝþªþÝ.ò›zIFJÿão{ 3?j@:+( œ ‘˜g:i ›g4i.(`@ 1 +=1=17!" @ôìÔìÔÌ99999991ä2ô<ììäîþôîî99906654&#"!3267#"&'#"$54676$326632"32654&`Ri—%# üºƒƒpüŠ7ƒþüˆ›È:ZÖ‰ûþá[Ue¬ŒË@^ä‰ß ú‹´a]‹´aª  P^un¤9mlDCþê0/NRRNýÜñcuwQQQQôÉ(]BüÃjoýÄinÿðö²@ ÏqÔÌ991ôì0!! 3ü²þþÿðö²@ ÏqÔÌ991ôì0!! 3ø²þþçX7Õ f@4     :Ð S   H  ÔäÄôôÄ991ô<ì20KSXíí9íí9Y"!3!3Xþ¬7'Õ¨ý¬þ¬:'ÕªX`þ þã`þ –XåÕ b@2     : ÐS H  ÔäÄôÄäÀ91ô<ì20KSXíí9íí9Y"!#!#‘T7þÙÕ¨þT8þ×Ô©Õþãþ `þãþ `çXÕ9@:ÐSÔÄä91ôì0KSXíí9Y"!3;þ¬:'ÕªX`þ –XËÕ5@:ÐSÔÄäÀ1ôì0KSXíí9Y"!#wT8þ×Ô©Õþãþ `ÙVÛ® *@ÑÑ on IJI Ô<ìü<ì1ôÄüÔìî0!!!!!!Á3þÍ3þÍþúþ‹þËXþËìþ#îuv@A:ÔÄ91ÜÌ990KSXÉÉÉÉÉÉÉÉY" úþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿþF1'\Žœÿÿyk'<uýÇÿãð¶dÔÌ1äÄ0#3þ¼õÓõ J=ÏÅ#/@H ! ! $ÓÒ!Ô*Ó Ò00   'LKM-L K0Üìì2üìì29999991Ôìì2üìì2À999990'7&&5467'766327'#"&72654&#"²Ï™ÏÑ™Ï0l=6l9ϘÏÏšÏ.j?:l¦[€\[€~ ÏšÏ1k??l.ÍšÏÏšÏ7n6?i/ϙζ\\\]~}‰×'@ÔÌ91ÔÌ907×1þ¦+þZ%'üåÞßqºN‡¦'@ ÔÌ91ÔÌ99077%%7N1Xÿ+¤#‡þåÞßþºfbÜ@c  : i¡ gkz  &N&Ôäüäôä991/<ä22ü<ìíî2990KSXí9íííííííY"K° TK°T[K°T[K°T[X½@ÿÀ878Yµ?]]!!!!#"!!!#37>3úh9þ˜hÛþš…/ÅKE /1þѨþ˜¨±2°%êØþÜû ë7COÿü `Nº¬fb´@L   : i gk z    N&Ôäüä991/<ä2üìî2990KSXí9íííííY"K° TK°T[K°T[K°T[X½@ÿÀ878Y´?]!!!"!!!#37>?#þÑþšþþ“KE /1þѨþ˜¨±2°%êùì)7COÿü `Nº¬ÿÇÿ;Õ€@F       : X £¥¤S       ÔÄ.À9999991äô<ì2þÖ<î20KSXííííííY"!!!!!!!7!!7!çJJ!-þÝX#/þßJþµIþà/!Xþß-!Õþƒîþ<îþƒ}îÄî¬`‰/@:TÔäÀ91Ôì0KSXííY"!!øhLþ˜‰þ}ÿºÿðƒ5@:ÐTÔÄäÀ1üì0KSXíí9Y"!#œT8þ×Õªƒþãþ `ÿºÿ ƒ b@2     : ÐT H  ÔäÄôÄäÀ91ü<ì20KSXíí9íí9Y"!#!#¶T7þÙÕ¨þT8þ×Õªƒþãþ `þãþ `qÿã 5ð #/3?Kb@7 eFe:a@e2e$a0*`42dL1C=3'!    - ! 'I 7 'C =LÔìÄüìÅîþîîþî991ä2ô<<ì2ì2îþîî202#"&54"32654&!"32654&'2#"&54#3!2#"&54"32654& Ûœ¾þö×½ ·Vn=>Wm>ü$Vo=>Wn? ½þ÷Ö½ ü±õÓõûkœ¾þõÖ½ ·Vn==Wn?«Œßþé­Þ¨¨…WW¨‡UW¨…WW¨‡UW¨«Œàþê­ÞüÓ ¬ŒßþêªÞ¨©„XYªˆTXÿÿÿ{‡k'$Duÿÿ+\k'(uÿÿÿ{‡k'$Duÿÿ+\k'(uÿÿ+\k'(uÿÿ+•k',ÿ¶uÿÿ+…k',ÿ¶uÿÿ+‰k',ÿ¶uÿÿ+Ïk',ÿ¶uÿÿJÿãƒk'2¼uÿÿJÿãƒk'2¼uÿÿJÿãƒk'2¼uÿÿ‹ÿãTk'8muÿÿ‹ÿãTk'8muÿÿ‹ÿãTk'8mu?`0@:z& ôäÀ91/ä0KSXííY"!!hÛþ™`û ÙîÝf8@ ‹ŠÔÌ991ôì290K° TK°T[X½ÿÀ@878Y!#'#!¶²œñÅfþˆáá9Š@"  ÕÖÕ Š ÔÌ91ôìüì999999990K° TK°T[X½ÿÀ@878Y@(         (]]'&'&#"#>3232673#"&{1&"4 Œƒ^$C%5"&4 ‹‚^"<T%E<‰“+C>ˆ”=XÙ,·ÔÌ991ÔÌ0K° TX½@ÿÀ878Y!!bw%ý‰¼TøFo@  ÔÌÔÌ91Ô<ÔÌ90K° TX½@ÿÀ878YK° TX½ÿÀ@878Y@   ]332673#"&546WŽVPQh˜"ÍœŒF AFGIš|yé;-1K@ ÄÀ991ÔÌ0K° TK° T[X½@ÿÀ878Y@  00//??]]!!1þí1öyײ @@Ò×Ò  KKÔìÔì1Ôìüì0K° TK° T[K°T[X½ÿÀ@878Y#"&546324&#"326²¥wx¥¥xw¥‡TABTUAATôx¥¥xx¤¤xATTAAUT-þo#@   ÔÌÄÄ991/ÔÌÔÌ0!#"&'732654&'Ë%"—‰1a3(Q&BL4X*hs œ9/E7%îf…@ ŠÔÜÔÌ1ô<Ì20K° TK° T[X½ÿÀ@878YK° TK°T[X½ÿÀ@878Y@-   0000@@@@]3#3#úþÉ®búþ¨®fþˆxþˆ–þoF@@  ÔÄÀÀ991/ÔÌÔÌ0@IIIIYYYYiiii ]!33267#"&5463ŽG41-%R+9Z'joJJP"&˜ EBA~5î9fP@ ‹ŠÔÌ991ô<ì90K° TK°T[X½ÿÀ@878YK° TX½@ÿÀ878Y!373ðþü·°œôÄîxããÿÑÓÕ `@6    : ‡S    Ôä.À9991/äì90KSXííííY"!%!!'%šeTiþ N¢7ûÛb h=Õýü—ÒÜþiþÝöJׇÿò¦ ›@1: k   Ôä.À9991/ì90KSXííííY"K°TK°T[K°T[K°T[K°T[K°T[K° T[K° T[X½ @ ÿÀ878Y´ / ]!7!'%˜hf¨dþÀ•þ—u‹` ýüNË‘üþVDˇÿÿÿãRk'6uÿÿÿã›f'VàbÿÿÿËìk'=!uÿÿÿî°f']àTþ¢ç˜@ Ô<ì21ÄÔÄÆ0##çããã˜ý öüý öÿümÕ p@:    :€…‡ S‡      ôäÔì.9999991/ìôìô<ì20KSXííííY"²!]3#3 4&#! )#3¸9ö3öF‰;ÏËþ0•""`ad©—„þ£þ•þk}Í3ͲþÕþüþ /®²#EQQè‘Éþ˜{m\ƒJÿãm,¯@c*+,+)(),,+&'&#$#%$$#'(&%&(#$#(( !"(:,+*)&%$#'"'i i`'k-*+,) %$'&#" + !! -ôìÔìÀ9999991ìÄôìî9990KSXí9íííÉÉÉÉY"&&#"32654'4#"$5!2''%'!%¾4f4Œ£d^Œ´õ@A[Weþé«ñþßl%1W$—þ#T‰`R#þ¬ç¼žmsýÆ (j\Ôt‚ódtxúÍ] ×l^Ætj^ÿÿyk'<uÿÿþFf'\œ+Õj@: :u uS  ôäÔì9991/äÔìÔì0KSXííííííY"!32##!32654&#N+öë WSYù¸ö9þBP̈‘ebÕß׿uÑOVNþÙáþ\‚zRVÿìþVj‘@L:ii`¢k  !  ÜÄÔì999991ìääôìî990KSXíí9í9íí9í9Y"%!!6632#"&"32654&Çsþ˜huR´k½ÜMH[åƒs¡AНcX‡°_¢ý´¾ý¨b]ðÏôd~‚]7ÿÌ\iûÄfkÙ Ûø·onÔÄ1ôì0!!Ùúþøì)´Û /@   Ô<Ì291Ô<Ì290 '7´þN²¨þNþN¨²þN¨²²3þNþP¨°þP¨°²¨þN²‰œ)ß …@0 OO:Ø Ø Ùb     ÔÄÀ9991ôìÔìî290KSXíí2Y"²]@   ))99JMMJJ]3?33!¨ÍféôÛ…Ïý9 4 1ýZ\œsðc@! Ø ÛÙdPÔÔì9991ôìüÄî9990@ 55YY…•••¥¥¥ –¦¸·]]!!7>54&#"7>32¨y!ý\nPNA:D“G$S•E•ŸlxD¨™ :c*(..,ºmdO•TRjð(t@- # Û ÛÛÙÜ#d)   PP& )ÔÔìÔì9991ôììüÄþÅî9990@        (°°°°°°]#"&'732654&+732654&#"7>32šKNêØP‘>!:w54&#"7>32#33?33!Dv ý^nQMB9D–G%S”F• lwû=õÓõùmÍféôÛ…Ïý¨¨š :a))0/,»mdO”Tþ— ýI 4 1ýZZÿãÓð(+6:@r*6,6)+),,6)O*)-2-+O2-4O2-3O22-: #)* .*Ø0Û ÛÛÙÜ9#d40,Ù7`2*)43+5:.120/-8   /-PP& 25- ;ÄÔÄÄÖîÔîÀ9999991/äîÄ2ö<îîþÄþÅîî299990KSXííííÉÉY"² (]@:)+*,(.9+:,9.Y)Y+i)i+         '[)l)°°°°°°]]#"&'732654&+732654&#"7>32 333##7!7#3¢LOéÙQ’>#:w3232673#"&j1!$4 ‰ƒ_%A#5$'5 Šƒ]&@!% @8€Š) =:€Š`îøö:¶ÔÄ91ÔÄ0K° TX½ÿÀ@878Y@ //]#h²æöþøçîÏöG@ ÔÄ991Ô<Ä90K° TX½ÿÀ@878Y@/// ]!#'#Û\˜ª¤ç³öþø¡¡3î öM@ ÔÄ991ÔÄ290K° TX½ÿÀ@878Y@//// ]!373þ£‰¬”ç²î¢¢Nîéö3@  ÔÌÔÌ1ÔÜÄ290K° TX½ÿÀ@878Y332673#"&5N QOHj™'Æ”ˆ’ö<7=6‡‡}ß!ö>@ ÄÀ991ÔÄ0K° TX½ÿÀ@878Y@ 0000]]!!/þíöö  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•ÍfÉɦ+Ñ…‘7qú9s螨ÿÉ/)´Ù ÿºR3 ^ìÿ;‘J‘X‘‘‘ÿþ‘‘f‘ ‘-‘T3T3ÿ¸´Ù´Ù´Ù¤Õ\1ÿ{+ßJ¤+w+w+‘J²+ú+úþ¬3++ö+²+ÍJÝ+ÍJ)+Ãub‹1œÓÛ+ÿ˜ËÍÿ˨ÿì쑨ÿÇ´Ïÿì f#º?¾LºJmJ{fº)²?¾?¾þúR?¾?V?²?JºÿìºJò?ÃÓX²{7d²)ÿ¬7¨ÿî²Ùì²Z´Ù1ÿ{1ÿ{ßJw+²+ÍJ‹f#f#f#f#f#f#¾LmJmJmJmJ¾?¾?¾?¾?²?JJJJJ²{²{²{²{N²‘‰‘ÿ¼'˜Á?'Ñ7´Ù®ÿ`Íÿ ªÃ´Ù´Ù´Ù‘ ãÿÉZ;¾)L–'ÿÝá3ƒXƒ^'7b#ÿݤL¦´ÙVL‘ÿé´Ù“3}3u^‘1ÿ{1ÿ{ÍJ VVÁJÿÃÿÃ'ç'– ç –´Ùô7ËVýÇJL}LNLfLfÿÇ ¬ ÿº'ÿº ¢q1ÿ{w+1ÿ{w+w+ú+ú+ú+ú+ÍJÍJÍJ‹‹‹¾?Ù=Téy-%–5HÿÑÿòÃÃÍÿ˨ÿîìÃÿüJË7ð+ºÿì´Ù´‰\R…‰…‰…Z‘Jº)ú+ÃÃßJ¾LßJ¾LºJR3 ¬‘ÿ¬+Ñ`ç3Nßÿõÿ   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ    sfthyphenperiodcenteredEuroc6459c6460c6461c6462c6463c6466c6467c6468""""iŒò€øÏçEޏåÿ%J¡öbÕGÃ>lðq¯ö  < _ Ù  ì Y ° ÿ F ‡ õ M w Æm¤EŸøKÄ?H¨õ™n¤Üö+Mc‹Iĉígÿu¸$¡Ë‘NÎL·NÍhÎ W ÷!{!Ð"q"‡#,#n#{$ $-$:$G$T$a$n${$ˆ$•$¢$¯$¼$É$Ö$ã$ð$ý% %%$%1%>%K%X%e%r%%Œ%™%¦%ï&.&Ÿ''°'â(3(Ü)„**w*´++E+Á,¥- -D-s- ..§//8/[/•/õ0â1D1›2t2û3x3Á3Ý4+4¬5'5L5‰5Å6!6!6.6;6H6Å7Z7v7’7ä848c88Á99"9/9E9Î9ñ::µ;:;£;É;ö>u>™>ï?#?i?œ?õ@6@p@ÁA+A8AEARA_A‚AõB–B£B°CCC¥CÞD8D”E EÅF{G`GmGzG‡G”G¡G®G»GÈGÕHpHŠH°I5IqI¡J J6JlJ¥JÚK`ã R7þÓ9ÿk:ÿ¤;ÿ2<þ­»þ­êþ­$&$&$&$&$&ÿÁ$2ÿÁ$7ÿ<$8ÿ¤$9ÿu$:ÿ$<ÿ$FÿÁ$GÿÁ$Wÿ$Yÿ$Zÿ¤$\ÿk$dÿÁ$gÿÁ$hÿ¤$oÿÁ$‘ÿÁ$¯ÿÁ$°ÿÁ$µÿ$·ÿ$ºÿk$»ÿ$Äh$Åh$ÐÿÁ$ÑÿÁ$ÒÿÁ$Óÿ¤$Ôÿ¤$Õÿ¤$êÿ$ëÿk$ûÿÁ$üÿÁ$ýÿÁ$þÿÁ$ÿÿÁ%9ÿ­%:ÿ%<ÿ%»ÿ%êÿ&6ÿ·&ãÿ·&ùÿ·'&'<ÿa'»ÿa'ÄÿÜ'ÅÿÜ'êÿa)þD)ÿš)þ<)ÿ)ÿ)$þø)Dÿ)Hÿa)Rÿa)Uÿ)Xÿ<)\ÿD)bþø)iÿ)jÿ)kÿ)lÿ)mÿ)nÿ)pÿa)qÿa)rÿa)sÿa)yÿa)zÿa){ÿa)|ÿa)}ÿa)~ÿ<)ÿ<)€ÿ<)ÿ<) ÿ)¡ÿa)­þø)®þø)±ÿa)·ÿÜ)ºÿD)Äþ<)Åþ<)Çþø)Éþø)ëÿD*7ÿÜ*<ÿ­*»ÿ­*êÿ­.ÿ.&ÿ}.2ÿ}.8ÿ·.:ÿÉ.Hÿ.Rÿ.Xÿ.\ÿ2.dÿ}.gÿ}.hÿ·.pÿ.qÿ.rÿ.sÿ.yÿ.zÿ.{ÿ.|ÿ.}ÿ.~ÿ.ÿ.€ÿ.ÿ.‘ÿÉ.¡ÿ.¯ÿ}.°ÿN.±ÿ.ºÿ2.Ä&.Å&.Ðÿ}.Ñÿ}.Òÿ}.Óÿ·.Ôÿ·.Õÿ·.ëÿ2.ûÿ}.ýÿ}/2ÿ·/7þ­/8ÿ/9þæ/:ÿN/<þÁ/\ÿ/gÿ·/hÿ/‘ÿ·/¯ÿ·/°ÿ·/µýð/·þ/ºÿ/»þÁ/Ðÿ·/Ñÿ·/Òÿ·/Óÿ/Ôÿ/Õÿ/êþÁ/ëÿ2ÿÓ2&2ÿÓ29ÿ·2;ÿ·2<ÿk2»ÿk2êÿk3ýð3ÿÜ3ýð3$ÿD3Dÿ}3HÿÉ3UÿÁ3Vÿ·3Xÿ·3bÿD3iÿ}3jÿ}3kÿ}3lÿ}3mÿ}3nÿ}3pÿÉ3qÿÉ3rÿÉ3sÿÉ3~ÿ·3ÿ·3€ÿ·3ÿ·3 ÿ}3­ÿD3®ÿD3µ&3·93Äþa3Åþa3ÇÿD3ÉÿD3äÿ·3úÿ·4&5&5&57ÿ¤5<ÿD5Hÿš5Rÿš5Xÿ5\ÿ}5pÿš5qÿš5rÿš5sÿš5yÿš5zÿš5{ÿš5|ÿš5}ÿš5~ÿ5ÿ5€ÿ5ÿ5¡ÿš5±ÿš5ºÿ}5»ÿD5êÿD5ëÿ}66ÿ·6ãÿ·6ùÿ·7þ·7þÓ7þ¤7ÿ7ÿ7$ÿa77/7Dÿ 7Fþø7Hþø7Rþø7Uÿ7Vÿ 7Xþø7Zþæ7\þ­7bÿa7iÿ 7jÿ 7kÿ 7lÿ 7mÿ 7nÿ 7oþø7pþø7qþø7rþø7sþø7yþø7zþø7{þø7|þø7}þø7~þø7þø7€þø7þø7 ÿ 7¡þø7­ÿa7®ÿa7±þø7ºþ­7ÄþÓ7ÅþÓ7Çÿa7Éÿa7äÿ 7ëþ­7úÿ 7üþø7þþø8$ÿ¤8bÿ¤8­ÿ¤8®ÿ¤8Çÿ¤8Éÿ¤9þÁ9ÿk9þÁ9ÿ¤9ÿ¤9$ÿu92ÿÜ9Dÿa9Hÿk9LÿÜ9Rÿk9Xÿk9bÿu9gÿÜ9iÿa9jÿa9kÿa9lÿa9mÿa9nÿa9pÿk9qÿk9rÿk9sÿk9yÿk9zÿk9{ÿk9|ÿk9}ÿk9~ÿk9ÿk9€ÿk9ÿk9‘ÿÜ9 ÿa9¡ÿk9­ÿu9®ÿu9¯ÿÜ9°ÿÓ9±ÿk9Äþð9Åþð9Çÿu9Éÿu9ÐÿÜ9ÑÿÜ9ÒÿÜ:ÿN:ÿ¤:ÿN:ÿÁ:ÿÁ:$ÿ·:Dÿu:Hÿ}:Rÿ:Uÿˆ:bÿ·:iÿu:jÿu:kÿu:lÿu:mÿu:nÿu:pÿ}:qÿ}:rÿ}:sÿ}:yÿ:zÿ:{ÿ:|ÿ:}ÿ: ÿu:¡ÿ:­ÿ·:®ÿ·:±ÿ:Çÿ·:Éÿ·;ÿ ;&ÿ·;2ÿ·;Hÿ};dÿ·;gÿ·;pÿ};qÿ};rÿ};sÿ};‘ÿ·;¯ÿ·;°ÿ;Ðÿ·;Ñÿ·;Òÿ·;ûÿ·;ýÿ·<þ­<þÓ<þ­<ÿN<ÿN<$ÿ<<&ÿ·<2ÿ·<Dÿ <Hþø<Rþø<Xÿ<bÿ<<dÿ·<gÿ·<iÿ <jÿ <kÿ <lÿ <mÿ <nÿ <pþø<qþø<rþø<sþø<yþø<zþø<{þø<|þø<}þø<~ÿ<ÿ<€ÿ<ÿ<‘ÿ·< ÿ <¡þø<­ÿ<<®ÿ<<¯ÿ·<°ÿˆ<±þø<Äþˆ<Åþk<Çÿ<<Éÿ<<Ðÿ·<Ñÿ·<Òÿ·<ûÿ·<ýÿ·=ÿkD\ÿÁDºÿÁDëÿÁIÿIÿÜIÿIµVI·NHÿ·NRÿ·Npÿ·Nqÿ·Nrÿ·Nsÿ·Nyÿ·Nzÿ·N{ÿ·N|ÿ·N}ÿ·N¡ÿÓN±ÿ·UþÓUþÜUµ&U·VYÿYYÿYZÿ}Zÿ}\ÿa\ÿDb&b&b&b&b&ÿÁb2ÿÁb7ÿ<b8ÿ¤b9ÿub:ÿb<ÿbFÿÁbGÿÁbWÿbYÿbZÿ¤b\ÿkbdÿÁbgÿÁbhÿ¤boÿÁb‘ÿÁb¯ÿÁb°ÿÁbµÿb·ÿbºÿkb»ÿbÄhbÅhbÐÿÁbÑÿÁbÒÿÁbÓÿ¤bÔÿ¤bÕÿ¤bêÿbëÿkbûÿÁbüÿÁbýÿÁbþÿÁbÿÿÁd6ÿ·dãÿ·dùÿ·gÿÓg&gÿÓg9ÿ·g;ÿ·g<ÿkg»ÿkgêÿkh$ÿ¤hbÿ¤h­ÿ¤h®ÿ¤hÇÿ¤hÉÿ¤i\ÿÁiºÿÁiëÿÁj\ÿÁjºÿÁjëÿÁk\ÿÁkºÿÁkëÿÁl\ÿÁlºÿÁlëÿÁm\ÿÁmºÿÁmëÿÁn\ÿÁnºÿÁnëÿÁÿÜ‘ÿÓ‘&‘ÿÓ‘$ÿÜ‘9ÿÜ‘;ÿ·‘<ÿÜ‘bÿÜ‘­ÿÜ‘®ÿÜ‘»ÿÜ‘ÇÿÜ‘ÉÿÜ‘êÿÜ­&­&­&­&­&ÿÁ­2ÿÁ­7ÿ<­8ÿ¤­9ÿu­:ÿ­<ÿ­FÿÁ­GÿÁ­Wÿ­Yÿ­Zÿ¤­\ÿk­dÿÁ­gÿÁ­hÿ¤­oÿÁ­‘ÿÁ­¯ÿÁ­°ÿÁ­µÿ­·ÿ­ºÿk­»ÿ­Äh­Åh­ÐÿÁ­ÑÿÁ­ÒÿÁ­Óÿ¤­Ôÿ¤­Õÿ¤­êÿ­ëÿk­ûÿÁ­üÿÁ­ýÿÁ­þÿÁ­ÿÿÁ®&®&®&®&®&ÿÁ®2ÿÁ®7ÿ<®8ÿ¤®9ÿu®:ÿ®<ÿ®FÿÁ®GÿÁ®Wÿ®Yÿ®Zÿ¤®\ÿk®dÿÁ®gÿÁ®hÿ¤®oÿÁ®‘ÿÁ®¯ÿÁ®°ÿÁ®µÿ®·ÿ®ºÿk®»ÿ®Äh®Åh®ÐÿÁ®ÑÿÁ®ÒÿÁ®Óÿ¤®Ôÿ¤®Õÿ¤®êÿ®ëÿk®ûÿÁ®üÿÁ®ýÿÁ®þÿÁ®ÿÿÁ¯ÿÓ¯&¯ÿÓ¯9ÿ·¯;ÿ·¯<ÿk¯»ÿk¯êÿk´$þø´-ÿ¤´<&´bþø´þÓ´­þø´®þø´»&´Çþø´Éþø´ê&¶$þð¶-ÿ¤¶9&¶<K¶bþð¶þø¶­þð¶®þð¶»K¶Çþð¶Éþð¶êKºÿaºÿD»þ­»þÓ»þ­»ÿN»ÿN»$ÿ<»&ÿ·»2ÿ·»Dÿ »Hþø»Rþø»Xÿ»bÿ<»dÿ·»gÿ·»iÿ »jÿ »kÿ »lÿ »mÿ »nÿ »pþø»qþø»rþø»sþø»yþø»zþø»{þø»|þø»}þø»~ÿ»ÿ»€ÿ»ÿ»‘ÿ·» ÿ »¡þø»­ÿ<»®ÿ<»¯ÿ·»°ÿˆ»±þø»Äþˆ»Åþk»Çÿ<»Éÿ<»Ðÿ·»Ñÿ·»Òÿ·»ûÿ·»ýÿ·Ä7þ<Ä9þ­Ä:ÿÄ<þaÄ»þaÄêþaÅ7þ<Å9þ­Å:ÿÅ<þaÅ»þaÅêþaÇ&Ç&Ç&Ç&Ç&ÿÁÇ2ÿÁÇ7ÿ<Ç8ÿ¤Ç9ÿuÇ:ÿÇ<ÿÇFÿÁÇGÿÁÇWÿÇYÿÇZÿ¤Ç\ÿkÇdÿÁÇgÿÁÇhÿ¤ÇoÿÁÇ‘ÿÁǯÿÁǰÿÁǵÿÇ·ÿǺÿkÇ»ÿÇÄhÇÅhÇÐÿÁÇÑÿÁÇÒÿÁÇÓÿ¤ÇÔÿ¤ÇÕÿ¤ÇêÿÇëÿkÇûÿÁÇüÿÁÇýÿÁÇþÿÁÇÿÿÁÉ&É&É&É&É&ÿÁÉ2ÿÁÉ7ÿ<É8ÿ¤É9ÿuÉ:ÿÉ<ÿÉFÿÁÉGÿÁÉWÿÉYÿÉZÿ¤É\ÿkÉdÿÁÉgÿÁÉhÿ¤ÉoÿÁÉ‘ÿÁɯÿÁɰÿÁɵÿÉ·ÿɺÿkÉ»ÿÉÄhÉÅhÉÐÿÁÉÑÿÁÉÒÿÁÉÓÿ¤ÉÔÿ¤ÉÕÿ¤ÉêÿÉëÿkÉûÿÁÉüÿÁÉýÿÁÉþÿÁÉÿÿÁÐÿÓÐ&ÐÿÓÐ9ÿ·Ð;ÿ·Ð<ÿkлÿkÐêÿkÑÿÓÑ&ÑÿÓÑ9ÿ·Ñ;ÿ·Ñ<ÿkÑ»ÿkÑêÿkÒÿÓÒ&ÒÿÓÒ9ÿ·Ò;ÿ·Ò<ÿkÒ»ÿkÒêÿkÓ$ÿ¤Óbÿ¤Ó­ÿ¤Ó®ÿ¤ÓÇÿ¤ÓÉÿ¤Ô$ÿ¤Ôbÿ¤Ô­ÿ¤Ô®ÿ¤ÔÇÿ¤ÔÉÿ¤Õ$ÿ¤Õbÿ¤Õ­ÿ¤Õ®ÿ¤ÕÇÿ¤ÕÉÿ¤á2ÿ·á7þ­á8ÿ·á9þæá:ÿaá<þÁá\ÿágÿ·áhÿ·á‘ÿ·á¯ÿ·á°ÿ·áµþøá·þøáºÿá»þÁáÐÿ·áÑÿ·áÒÿ·áÓÿ·áÔÿ·áÕÿ·áêþÁáëÿã6ÿ·ããÿ·ãùÿ·åÿkè&è<ÿaè»ÿaèÄÿÜèÅÿÜèêÿaêþ­êþÓêþ­êÿNêÿNê$ÿ<ê&ÿ·ê2ÿ·êDÿ êHþøêRþøêXÿêbÿ<êdÿ·êgÿ·êiÿ êjÿ êkÿ êlÿ êmÿ ênÿ êpþøêqþøêrþøêsþøêyþøêzþøê{þøê|þøê}þøê~ÿêÿê€ÿêÿê‘ÿ·ê ÿ ê¡þøê­ÿ<ê®ÿ<ê¯ÿ·ê°ÿˆê±þøêÄþˆêÅþkêÇÿ<êÉÿ<êÐÿ·êÑÿ·êÒÿ·êûÿ·êýÿ·ëÿaëÿDö7ÿÜö<ÿ­ö»ÿ­öêÿ­ù6ÿ·ùãÿ·ùùÿ·û6ÿ·ûãÿ·ûùÿ·ý6ÿ·ýãÿ·ýùÿ· MI@kmþ ¢ýÇýÇ 5 •¼GÌþBGÌSf  €¯ JBits! ûþšmãB´É`#cÕVeraSansBdObÿÿÿÿ6ÿÿþ628J00@                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              !                        !        #                     #        $                       $        &                       &        '                   '       )             !   )       ÿÿ"Õ°_<õººëºÂiYýÇþ 5mloganalyzer-3.6.5/src/BitstreamVeraFonts/local.conf0000644000175000017500000000176412225176641021656 0ustar danieldaniel serif Bitstream Vera Serif sans-serif Bitstream Vera Sans monospace Bitstream Vera Sans Mono loganalyzer-3.6.5/src/BitstreamVeraFonts/VeraBd.ttf0000644000175000017500000016253412225176641021602 0ustar danieldanielOS/2µ‰÷=Ï@VPCLT,e‰Ï˜6cmap¤Ãè ­¸Xcvt >¹-âRfpgmÆp9)Œgaspå glyf4Þh¥)„&hdmxE¼úÏÐHheadóO«“å$6hhea. Ï$hmtxyò€®±,kernÔê¹ÜlocaXùz[·Ämaxp}Îü name·YÍ¿ëpostø¡xúµ<†prep|a¢ç!\§::N:: R^0±p  ‡ t t Ÿ &   ; 0  0   C , [ `   0­ & ‡Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans BoldRelease 1.10BitstreamVeraSans-BoldCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans BoldRelease 1.10BitstreamVeraSans-BoldCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comf3f¼é=¢úff¬Tì¼bf…Tfm¤fÍ3bq%¤¼ºåfHZfmöÃð99Xm=²²fuf°f9Ñœ{Ï{X3fLfL¬šJ#ššDDÍÁf?š;ËËÕÕP¬¬w Çò/X²#öö/55îç3˜ÑX š˜¼ÍååòsfÕ+ÕÃá×åj-ÕÕð¨jìáÕ!føìƒ¦ø#^Í`lj켺3B3\Õššáfy```{ìø;ÝÕj\{šÝ®º…®`bššXîššÑÍšPËË‹‹1öðL`¨Á%Á!J–Jƒ¨7{ÉÁÁÁÁ–'žì}3˜ÑXyÍ9bœœœ“¸“¸sA„€&þ%$!:$ú#"!:"þ!: ú»dþþþþþþþþþ}þ}  Œ þ À  Y Œ €  & Y @ & þþ €²—.Aúúþúú@ÿ}ÿ>þþüû,üþû,úþùøGù}øG÷úöþõþôþó»òþñþðþïîþíì íþì ì@ëê ë2ê éúè‘èþçúæúå‘åþäþãþâþáþàþßþÞúÝÜÝdÜÛ ÛdÚÙ%ÚúÙ%ØÑ%Øú×Ö×ÖÕÖÕÔÓ Ô Ó ÒÑ%ÒúÑ‘Ñ%Д Ð#ÏÎÏ&ÎÍÎÍÌ‘ÌËÊÉ»ÊþÉÈ]ɻɀÈ@ÿÇ%È]È@Ç%ÆþÅdÄÄþÃÂþÁþÀ¿:Àú¿­¿:¾½¾2½¼½¼»¼»º »º ¹‘¹þ¸þ·¶µþ´þ³þ²±°¯­¯ú®­®ú­‘­¬‘¬}«þª&©þ¨þ§þ¦þ¥ ¤þ£¢£þ¢¢@¡ ¡ú ‘ Ÿ‘Ÿúž” žþœ›»œþ›š]›»›€š%š]š@™þ˜—.˜þ—.–‘–@ÿ•” • ” “‘“K’‘’þ‘‘%ŽþþŒþ‹þŠþ‰þˆ‡%ˆþ‡%†þ…þ„2ƒ–‚þþ€ ~þ}þ|þ{úzúyþwv¦wþv¦utuútsúr}qþpo,o,númúlúkþjþiþhc h2gþf2ed eþd d@cb c b a`a–``_ ^þ]þ\\þ[Z[þZZYþXúWþV@ÿVþUþTSRQRúQQPOPúONONMLKLKJKJIJIHúGFGFEúDCDCBA%BúAA%@?@þ?>?>=< =< ;d:þ98þ7656%5455À4 44€32 33@2 10¦1þ00¦/ .-,:-ú,%,:+d*d)þ(''& %$#@+$#" "ú!!@  %¸@‘ K}Kþ%ú%dþþdÀ€  ú 2   €  @ þþþ þ @údþ  ¸d…++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX ¸(EDY!-,°%E`D-,KSX°%°%EDY!!-,ED-fþ–f¤¼&&¶‰/ÄÔì1ÔìÔì0!%!!füsüåþ–øòr)‡Õ @Œ‹ Ô<ì2991/äüì0!!!!h3þþ3hþ˜ÕýÃþ^¢ýÌþœÃªhÕ@ŽüüÜì1ô<ì20###híËíÕýÕ+ýÕ+‹)¾K@1’ ’    ÔÌ91/<ä2Ô<<ì22Ô<<ì220!3!!!!#!#!5!!5!!!`aÝaþ¶Eþ°`Ý`þø`ß`þéHFþåR`PþøF¾þþÕþî×þþ×Õýªþî þÓ#*1s@? %$ + ,#–•,–•“,“ (/($ +/ 2ÔÄüÔ<ü<ÔüÄ991/ÄìÔÄüôìõî99999990#&&''&&546773&&'6654&¢}êosëy!ïÉõã¢dÈedÈe þÍô÷¢GUNðWWPþÓ-.);?7*´©³É çã"þ*/þá(»·¸ÅBE5;Cþ±þêBBDCBÿãÃð '3c@5  % ."™( ™˜œ41+  1 +%4ÜÄìôìîöî991ä2ô<äìîöîî0KSXííY""32654&'2#"&546#3!2#"&546"32654&3GNMHHLMGºÖÖºº××ý%Ý¥ÞûºÕÕººÕÕºHNNHHMNh{rs{{sr{¨Ø½½ÛÛ½¼ÙüÓ Ù½½ÚÚ½½Ù¨|rs}}sr|{ÿã¤ð&06@Y     ,-./+0()'%0' - ‘-¡!Ÿžœ˜ '*$ 0$*$  *  1üìÄÔÔìÆî99999991/Æäöæîîî99990KSXí9í9íí9Y"²']@„   ' 0   0%/ / %&? ? @K K K/K0ZZUZ Z U(\.\0X2_2dig`i i d&€2, ' '* 9 5005@J I'I(WW\ ['ggl ]] >7!!'# 5467.54632.#"3267™577oc%þXbiè‚þùþ»¢*(þÓ[Åk^¨PMU1—ABªwCt2ßþ>F®n¶þäkþ¾mFDÛ’áj5j:£Äþê0.;6"WþÓ/wGs¢))ê°Õ@ Žüì1ôì0#°íÕýÕ+°þò @¤£ üüÄ2991üì0!&547!þ×™’“˜)€€þò÷½ÛÛÁõíþ;ÝÝþ:¤þòø @ ¤£  ÔÄ2ì991üì0654'!¤€€€€)˜“’™þòîÆÝÝÅíõþ?ÛÛþC÷)9ðF@(  ¥ œ   Ô<Ä2Ü<Ä2991ôÄ2ôÄ290%#'%%73%þ¶JLþ³ªþ²LNþ²LNªMÁ­®¸þ¨X¸®­¶Xþ¨¶ÙÛ "@§ ¦  Ô<Äü<Ä1/ô<ü<Ä0!!#!5!Ñ ýöîýö ýôìýô ì mþÝ9ƒ@ ©¨üìÔÌ1üì0!#Ñh÷ÕdƒþÏþ‹uo¼ãß·«ªÔÄ1ôì0!!otýŒßþÝÑ9ƒ·¨üì1/ì0!!Ñhþ˜ƒþ}ÿBìÕ·/Ä991ôÌ03#ÞýñÝÕùmbÿã/ð #@ ¬¬œ˜ üìüì1äôìî0&#"326! ! ®i||jj|{jþÀþÚþÙþÀ@'&@ìååþèþåèèþþm“st“þmçÕ (@®®®  ÔÄìÄüì1/ì2ôìÔì0!%!!!ðTþ£[nTûì ÅHHû5þö¢ßð–@)% ¬œ¯ÜÄüÔì9991/ì2ôìÔì990KSXí9íY"K° TX½@ÿÀ878Y@&**"""555BJFF]]!!>54&#">3 N‘ûÃ!IFuZÖz‚þz )~ÊþåáB~Di€MLH+-ìÓzÓ±‰ÿãîð(L@+¬ – ± ¬ –±¬°#œ˜)& )üäÄüìÔì9991äôäüôìþõîî90!"&'32654&##532654&#"663 º—þ¬þºsçqlÕg™£§£š¢‘ŽŠ~]¾^ràl#!Š%'Á•Þç%%)67jcfiø[]V^*) ¿Àƒ§\3Õ C@ !  ! % ®   üÔ<Äì291/äÔ<ì290KSXííY"!!3#!!òþZ¦@¬ÕÕþ”ýj˜ý®üRþéþðJžÿãÕ=@"•¬–•¬² ¯ ˜" ÜÄüìÄî1äôìæþõîþä90!!663 !"&'32654&#"Ù½ýv,Y00þµþÚù{zÛaŒ¡¡ŒS¼lÕþåç þïôòþî12/FF‰uvˆ+-ÿã#î $7@¬¬ – •¬"œ˜% %$%üìüäîÄ1äôüôìîÖî90"32654&&&#"6632! !2åeeeefeev_¨P¬ÀBš[åþÆþøþÝþÁuEgÂჃƒƒƒƒƒƒÍþì-+¿¼11þôÙðþ߉ir§ ‰îÕE@%¯ÜÌ91/ôì0KSXííY"²]@ &5F]!!!‰eýºþ‰'ý1ÕÙûº}ÿãð #/G@( '¬¬°-¬œ˜0 $*& '&!$0üäìüìôìî991äôìäîî990"32654&%&&54$! ! $54632654&#"Élttlkrrþ|ˆŠ‹ˆ˜›þÙþÞþÝþ×›òc\ZbbZ\cœvnnuunou)ª½ÆÅ¾ª)*½ÞããÞ½UY``YY_`jÿãî$7@¬ –•¬ ¬œ˜%%" $%üìÄüüä1äôìÄþõîî9073267#"54! !"&2654&#"Í\¨R¬ÀDšZåþç9$@þŠþºiÀeffeeff!++¿¼22 Úñ"þvþ˜þŽþY‚„„‚ƒƒåN`@¨³¨ü<ì21/ìôì0!!!!åiþ—iþ—`þ}þ¦þ}þÝN` %@¨©¨³  ü<ì2ÔÄ1äüìî0!#!!åiøÕdiþ—ƒþÏþ‹uþ}Ù=ÛÇ@µ´ÔÄ291ôì90 5Ûü<ÄúþÍþ´þ¶úÏìÏÙ'ÛÛ@ §¶§Ô<Ä21Ôìüì0!!!!ÙúþúþÛëÜíÙ=ÛÇ@µ´Ô<Ä91ôì9055ÙúþÅÍúþ1ìþ1úJð!H@'Œ‘• ¡‹   "Ô<ì2ÔÔì99991/ìôüôìí9990!546776654&#"6632!!Åþ—Bj@95`VQ¼fyÈ]ôN^@D*þ—iþ—ø1Rb:4\.FOCB:*(Ç¿b›Y9>K-Áþœ‡þœo  Ml@: 40LM3 ¸30 ¸0¸·7$¸·CN34L **)(I(*)4=NÔÄììÔììîþ<Æ991ôììÔììÄîÄî299999032654&#"#"&54632536654&'&$#"3267#"$'&5476$32!#?iZYjkZXiš…Y¬×Ø«Y…Ñ|Ž:;_þã¦tÔZ”¥ked“~üYk}þÙ˜¹þ¸€€†ˆ~~O´àn{KMþºþ×'{ŽzyþZGOùÈÈúPGƒýKÉd¯Iz„=;bþɵ•þûdbg^P¢agƒ}}I½¶J}|ˆ«¡bå~þñþÔ 'Õ @@     % ®   ÔÄ91/<äÔì90KSXííííííííY"K° TX½ ÿÀ @878Y@€ / V f  t Š Ÿ ¿ ¿ Ï Ï ß   %* IFGH XYVWhifg` t{zu{t ‰††‰ ™–•š ¶¹ ËÅÅËÂÍ ÙÖÖÙÕÚ /]]!!!!!Fý¦_þ})Ë)þ}ý¨™ÌþðÕú+%R¼‰Õ P@%¹¾¹ ¹   !üì2ÔìÔì99991/ìôìôì90@ ""/"P"]2654&+2654&+)! [^^[ÕâtutuâH|ˆþÜþÖýB7f“PNMQþÄýsbcaaþy$ÂØÔÕ¼Ïm™fÿã\ð;@   ®® œ˜- +üÄ2ì1äôìþÄÅ990´/_]%# !2.#"3267\jæ}þ‹þL´u}æjkÐsÎììÎsÐkR78¡ef¡87þËIDþøèçþøDI¼9Õ.@À À -. üìüì99991/ìôì0²P]32654&#! )=Šìùøíýõ–TMwiffixþ°þ°þj²üqêßÞè#ateþø§©þ÷eta¼áÕ 0@À¾ÀÀ   üì2ÔÄÄ1/ìôìôì0¶ P p ]!!!!!!¼ýrgý™¤ûÛÕþÝþêþÝþªþݼËÕ +@À¾À üì2ÔÄ1/ôìôì0¶ P p ]!!!!!¼ýrgý™þÕþÝþêþÝý‡fÿãúðK@%   ¹®® œ˜1 3/-+üìôäüÄ1ÄäôìîîÅ9990²_]%# !2.#"3267#!úþÊ¥þ‹þL¼‚•y}÷|æùðÝ@À¾   üì2Ôì21/<ô<ôì0@P ` p Ÿ ]!!!!!!¼8þýÈþÕýÇ9ú+yý‡¼=Õ7·Áüì1/ì0K°TK°T[X½ÿÀ@878Y¶@P]!!¼þÕú+ÿþf=Õ L@ À  üÄì991äüì990K°TK°T[X½ ÿÀ @878Y¶ @ P ]!!#3265¼þÑþÍN3IO@UZfi ]]!!!!¼®mþRýáþ“Õüú+üfÿãfð 2@®® œ˜ -7-+üìüì1äôìî0@ /?]"3254 ! f°Â°±Â±h˜þhþ˜þ™þg™Ùþüìëþüëìþdþ•þ–þdœjkœ¼‰Õ 1@ ® ®  - üì2Ôì99991/ôìÔì0²]! !#!32654&#¼1þÏþãþþÕpzzpÕýêëýýú¾þ_mddlfþÕfðb@ ®®œ˜  - 7-+üìüì9991Ääôìî90@,  '/V S f ` w w p  Y Y YXj i x ]]# ! !"3254þþf™gk•×Ê-þ‘þã°Â¾´±Â˜lkœþhþ‘üþ”\þ°þüìðÿëì¼Õ‡@2% ® ®     üì2ÔÄì9991/<ôìÔì9990KSXíí9Y"²]@66EEVVPee`]2654&+!! !.#ßyiiy¢þL'O}@Ñþf¶7q^?ZgfXþþöýËÕÆÖ”¾-þXspR“ÿã-ð'§@*% Ãî®%œ˜( "(ÜìÄÔìÄ99991äôìþåå9990@Tp)9999 JJJ X ]\^^ Z!joooh o n!t t t || |!– — ›šœ š!¦ ¦ ¦ ªªªª ª!(]].#"!"$'32654&/.54$!2Ë{êhŠ„Yu¤ùÒþÛþÓŽþâ |~†[ˆ•àÏ {¦þÄ78LP@À88Ôìüì1/ôì20K° TK°T[X½ÿÀ@878Y²@ ]!!!! `þþþÕþÝûN²¼ÿãÃÕ3@ À˜  9üìüì1ä2ôì90¶@pŸ]!3265!! ¼y‰ŠyþÂþºþ»þÂÕü¹ŸŸ¹üþÃþÊ6= 'Õ˜@'%ÁÔÄ91/ì290KSXííííY"K° TK°T[X½ÿÀ@878Y@, ° GGHHEJWX]]! !! ƒŒ‹ƒý×þ5Õû²Nú+=“Õ x@J 6  6 6 6   % Á    ÔÌ91/<ì2290KSXííííííííY"K° TK° T[K° T[K° T[X½ ÿÀ @878Y@Ì  % :?:?3 0 0 @ @ @ ^^a ¸± ° °         '('(%* /66220002 4 6 ?IFHE J ]]ZZUURRRZ U ] ooonhheh k n i o wwx v x ˆ…‰ ·º¶¸±¾ K]]! ! !! !=qsnþ þDþñþôþDÕûÃ=ûÃ=ú+oû‘'Õ û@E    %  Á   ÔÄÜÄ91/<ì290KSXííííííííY"K° TK°T[K°T[X½ ÿÀ @878Y@X  /& <3 _P € ¿°    ++%$%+ :55: P ejo ¹µµº ]] ! ! ! !üþoþ£þ¦þmþ’GF”úýþþúÛþáÿìßÕ @(%Á:: Ôìüì91/ì290KSXííííY"K° TK° T[K°T[X½ ÿÀ @878Y@, %%0@P`° %*5:0 O o ]]! !!¥TT¦ýÇþÕýìü ý‹u\qÕ w@%ÀÀ ÔÄÜÄ991/ìôì0KSXííY"K° TK° T[X½ ÿÀ @878Y@ %)69? FHO V_ o ]!!!5!sçüß8úë!üöÕéü7þÝéɰþò@ĤģüüÌ21üìüì0!!!!°mþçý“áú áÿBìÕ·/Ä991ôÌ03ýòݾ“ùm‹þòø@ĤÄ£ÔÌ2ì1üìüì0!5!!5!øý“þçmþòá`áϨåÕ@ ÔÌ91ôÌ290##ÕñþfþgòÕýÓ-þÓ-þþÛ´/Ä1ÔÌ0!5üþÛ¾¾^î“fN·ÆÅÔÌ1ôì0K° TK°T[X½ÿÀ@878YK° TX½ÿÀ@878Y´] #yÄþfþˆxXÿãÅ{ %@*  ÒÏŸÐ ÌËŸ#ʘ # = ;&üìÄôì229991/äôüôìæîöî9990@L/'= =!?'M M!] ]!n n!~ ~!p'Œ Œ! !­ ­!½ ½!20C@SPc`…€“¢ ²°]]"326=%!5#"&54$!354&#">3 ¢pq[QeŠiþ—H´®Ù"Ó†ŽsÆUsèt/ øLJDM‘m)‡ý¦f]ˢŸUO..ï¬ÿã^ 8@¡ С˜Ê£ÐB@ üì22ôì1/äìäôìæî0´O`]%2654&#">32#"&'!!syyss{{{J´uÏ þöÏu´Jþšf稠 ¨©ŸŸ©Õb]þ·þýþýþ·]b¢Xÿã5{7@ÌÔÌ Ô ¡¡Ê˜B ;üÄ2ì1äôìþôîõî0´_].#"3267# !25I“O–§§–T—@T­WþÑþªV/X«=þÜ20¯¯21þÛ77\ÿã8@¡Ð¡Ð˜Ê£ @B ;üìôì221/ìäôäìäî0´O`]!!5#"322654&#"¦hþ˜J²uÏþö Ït³¢syysryy¼Xùì¢c\II]üɨ  ¨¨  ¨Xÿã {C@!Ø ÌÔŸ ×ŸÊ ˜ D ;üìôìÄ91äôìäþôîî90´/?]!3267# ! 4&#" ü» œŒqí}þþÐþ¯K"=þw`h‚3f~~CDþì015:þ“f}un'`@ ¡Ÿ£³   E Ü<ìü<ÄÄ991/ä2üìî2990K° TK°T[X½ÿÀ@878Y@ €€]#"!!!#35463ÆL<2þÎþš²²ÌÖë7DNÿü `N·¯\þFy(K@&ÌÔŸ¡ Ð Ê ³#¡ÚÐ& @ B;)üìÄôì221/ääìäôäìþõî990´O*`*]%#"54325!!"&'3265"32654&¦J²uÍþô Íu²Jhþ«þ¼iÄc^´[°¤ìo|xsp||¾b\CúûA\c¦üþòþã !65š¤¤–šŸ¤•–¤¬5@  ÛÐÊ£ G üì2ôì1/<ìôäì9990´`€]!54&'.#"!!>32þ˜ H.p€þšfQ¶nÂɪýVo™“n#'­™ýÙý¨b]î¬)@ݳ£ ü<ì21/ìôì0@ P ` p € ]!!!!¬fþšfþš`û þÜÿ¼þF =@ ŸݳÚ £  ü<ì2Ä991ìäôìî990@ P`p€]!+53265!!¬fØÍ±>fLfþš`û´áíë\‡þܬy Œ@³£   üì2ÔÄ91/<ìä90@`;IIZ]X_ogvv{ˆ…‡‹Ÿ•–›¹:DGJV]g`ewpv|‡ˆ‹’—›]]!! !!¬fœ ýÝNþNþKþšü±›ýþý¢Óþ-¬·£ üì1/ì0@ P`p€]!!¬fþšù쪴{%t@)  Û Ð#ʳ  H H &üü<üìüì991/<<äô<äì29990K°TX½&ÿÀ&&@878Y@'0'P'p'€''¯']>32!>54&#"!4&#"!!>32ºD»pÁÊþ˜FNfoþ˜@Rgpþ˜hB«gt²¦hmîãýVH wk¨ŸýÚHºk©ýÙ`¤_`p¬{5@  ÛÐʳ G üì2ôì1/<äôäì9990´`€]!54&'.#"!!>32þ˜ H.p€þšfQ¶nÂɪýVo›‘n#'­™ýÙ`¤b]îXÿã'{ -@¡¡ ʘ BLB;üìüì1äôìî0¶7?G]"32654& ! Áw}}wu||u!Eþ»þßþÞþ¹G{«¡¡««¡¡«þÈþìþìþÈ88¬þV^{;@¡Ð¡Ðʘ޳B @ üì22ôì1äääôäìäî0´O`]%!!>32#"&"32654&þšfJ´uÏ þöÏu´¤s{{ssyy¢ý´ ¤b]þ·þýþýþ·]7©ŸŸ©¨  ¨\þVy ;@¡ СÐʳޘ @B;üìôì221äääôäìæî0´O`]"32654&#"325!!ºryyrsyyyJ²uÏþö Ïu²Jhþ˜w¨  ¨¨  ¨ý+c\IG\c¦ùö¬ì{C@ À ”Ê ³  üÄì21/äôäüÄ990K°TX½@ÿÀ878Y.#"!!>32ì/]/Š•þšfE³}*(/±¥ýü`¸nejÿãb{'Ü@@  6  6% ÌÔÌÔŸŸ%ʘ( SRP"M(üìÄÔìä99991äôìþõîõî90KSXí9í9Y"² ]@^ #  ,. . . . . ) 9; ; ; : : K J J J H w w ºº º º º º %  7 ?)_) ]].#"!"&'32654&/.54632sÖ_fcKa?¾þøþúoí}kátijIm?ïÀôücÚ=þð0035+. # «³´##44:90/ ¢¥²¬¤žx@¡³¡    Tü<Äü<ÄÄ991/Äìô<ì2990K°TK°T[K°T[K°T[X½ÿÀ@878Y@??PPP`` ]]!!;!"&5#33qþ>\¸þÍÔ±²²žþÂÿþ%N7ÿ±ÔÛ> ÿã`;@ ÛИ³ G üìôì291/ä2ôäì9990´`€]!3265!!5#"& hG.p€fþšQµmÂË´¬p[þí.‡w#&¬™)û ¢b]î`è@'%ßÔÄ91/ì290KSXííííY"K° TK°T[X½ÿÀ@878Y@| 0@Vf€ °°°°ÀÀÐÐàààðð  &$+)64990FFII`x‡ˆ‡ˆ––™™•š¨¶¹$]]! !!fgþGþw`üúû H` @J 4  4 4 4   % ß    ÔÌ91/<ì2290KSXííííííííY"K° TK° T[K° T[X½ ÿÀ @878Y@æ 550 G @ @ _ l  °°°°° ÀÀÑ Ð ààï    &$+)*+ $ % /554;::78 ?GIFHGH YVV[ T Y _f`b```d ` upspppt p ‡ˆ„‰ † ‹ ”› ¦©¦©¥© ¦ ª ¶¹¶¹ ÆÄÊÉÕÙ×Úåé æ ê []]!!!! !H\¼½+¼½\þÙþy½¼þy`üüýüû üþ ` „@F    % ß   ÔÄÔÄ91/<ì290KSXííííííííY"K° TK°T[K°T[K°T[X½ ÿÀ @878Y@Ú  / 3< CL R\ bl sz € ——œ Ÿ  ¯ °°°¿ ¿ ¿ ÀÀÏ Ï ÐÐß ß ààï ï ÷ð÷ÿ 2     $++$ 4;;4 0 DKKD o †€‰€ —•š™š– §°¿¿° ÀÏÏÀ ×ÐߨßÐ çàïèïà ùö:]] !! ! !Çþl{åè{þl¨þ…üùþ…=#þ´LýßýÁbþžþF`A@C %  ŸÚ³  ÔÄ91ä2ôì9990KSXííííí9íY"K° TK°T[K°T[X½ÿÀ@878Y@¤ @Pet†€” ´°°°ÀÀÔÐàà $$$5586699EEJJEEge†††ˆ ˆ—––™ ™¨ªª©©µ¼¸° ° ¿ ¹ ¹ÈË ËÉÖå9]]! !+5326?f-fþ)G½›Ïp[S `ýøû6»•ë:K\F` ž@%¡³¡ ÔÄÌ2991/ìôì0KSXííY"K° TK° T[X½ ÿÀ @878Y@DYVifyv„“ &)/ 9? J_ Žž±½ÀÏÐßãì]]!!!5!uÑý²NüNýË`úýšÿúfþ²²$^@1 %   ! Ä áÄàÄ£% $  %Ô<Ìü<Ä299999991üìôìôì99999990#"&554&##5326554633#"3²ÙÚÈlŽ==ŽlÈÚÙEUZnoYUmá°ÁÀ–ußt–ÍÁ¯áWަŽŽœ¦Wþç¶Ôì1ÔÌ0#çãøþ²²$`@2%   ÄáÄ#àÄ£%# %Ô<Ì2ü<Ì99999991üìôìôì9999999032655467&&554&##53233#"##FŒUZooZUŒFÙÚÈlŽ==ŽlÈÚÙmW¦œŽަŽWá¯ÁÍ–tßu–ÀÁ°Ù²ÛR#@ § §ÔÄ1ÔìÜìÀ990#"'&'&'&#"56632326Ûj³`k›^X¬bk²`k›^V©RôPE:=MSôPE:=Kÿÿ 'k'$u 'm!{@S!! ! !%!®â !  UU "ÔÄÔìÔî9999999991/<ÆæÖîî9990KSXííííííííY"K° TX½"ÿÀ""@878Y@À/!/!:!o! ¶ ¶º·°°°·ºº¿¿¿º¿!¿! # ///  /// "+ #EKUZ` ` ` ooo``ooo`fi `#tuyz{t …Š…Š •š° ° ° ° ¿¿¿¿°°¿¿¿·°³¼ D]] !!!.54632%32654&#"!þ}^ý¦_þ}§vt¨þwM66MN56MJ™Ì¸úHþð¸"K+u¨¨u/L{6MM66MMûŸRÿÿfþo\ð'&Ýsÿÿ¼ák'(´uÿÿ¼öm'15uÿÿfÿãfk'2Nuÿÿ¼ÿãÃk'8'uÿÿXÿãÅf'DºÿÿXÿãÅf'DCºÿÿXÿãÅf'D׺ÿÿXÿãÅ1'DŽºÿÿXÿãÅ9'DغÿÿXÿãÅ'DܺÿÿXþo5{'FݸÿÿXÿã f'HÙÿÿXÿã f'HCÙÿÿXÿã f'H×ÙÿÿXÿã 1'HŽÙÿÿ¬f'ÖÿwÿÿÿÕf'ÖCÿwÿÿÿþðf'Ö×ÿwÿÿ<²1'ÖŽÿwÿÿ¬9'QØòÿÿXÿã'f'R×ÿÿXÿã'f'RC×ÿÿXÿã'f'R××ÿÿXÿã'1'RŽ×ÿÿXÿã'9'RØ×ÿÿ ÿãf'Xòÿÿ ÿãf'XCòÿÿ ÿãf'X×òÿÿ ÿã1'XŽò5ÿ;ÃÕ *@åã ä WV W Ô<äü<ä1ä2ôìî20!!!!!5!VJ#þÝþ¶þß!ÕþƒîûÑ/î²dLþ @æçæ  XYXÔìüì1Ôìüì0"32654&'2#"&546HdcIHdeGBz0/11-0|D¿Á\dHHbcGHd¢3/0xDCy-03¿Á®þlj˜#W@. ÌÔ ÌÔ ¡ ¡!ʘ$   B$ÔüÔ<<Ä2ì22991Ääô<ìÄþôîõî9990&&##667###$4%3¾NMMNËJAY—9S’: ¢þúþö¢G“Z,“lm”*9þÜ02ýi2/þÛ þä (.ô##þá}çð@@!–• Ÿ¬œ ¬ Ô<ÄÄü<ÄÔÄ1/Ä2ì2ôìî2õî990&&#"!!!!3#5356!2ÛF”Mvquþ‹û–ãÂÂþ\µºþâ'&}ƒªïþºþö Fïªøÿ=øð3?k@8@1:4 %+èè1œ@ =!+%74:!=\.!\=[.7[(@ÜÄìÄÔÄìÔìî9999991ÄôìþÅÅ999990&&#"#"&'532654'&'&&5467&&546326654&ucž9KL¼ ÒŸquMKòÕUµfs¶9AN´$Ë oqKAåÉT´þšDC{¶AFжã''1/CO Y­}uŸ0)qI‘§í)+2(FJW³‚hš33oK¢ý…L2CbBO4Cj'‘ö`·é ]Ôì1Ôì04676632#"&'&&'535‚IIƒ245633ƒJI‚326úJ‚235624IJƒ336633ƒÿ;dÕ &@ ^^ÔìÔìÄ91Ä2ôÄÌ0!###&&54$\¾½¾ÌÞÕùfùùNÛ²¾è¬ÿãh0j@4.(" !+ŸŸ+Ÿ£˜/"!(%  a%.(a_ . 1üìÔìôìÝî99991/äþîþÕî990@ /2O2p2Ÿ2]4$! #"&'532654&/.5467.#"!¬ —1]EtkåçAŠJ8s6HX7bFXT‹‘`[efþšZÞÜàÚG NJ%94%@©u½¼ôH9/D7'1‡Ztž2UYnmû´åÍ 4Lb@8-*+'î0î!ëæ5í æ2+ëA'*,$0-+$!1g3f$cX;eX3cGMÔììüìüìî299991/ì2îþîüîÖî9990"32676654&'&&#32654&'2#'&&###2#"$'&5476$yÐWWWWWVÑy{ÎWWWWWXϲ##NOM+°®i`)Goåk&: Õ1˜mmllmmþù˜˜þùmmllmm3WWWÏzyÏWVVUWWÏyzÏWXVþÙÏ5442ŠwyVpP:ÝÕNAþœD7nmmþúš˜þûmmnnmm˜šmmnåÍ1IH@(  ïïëæ2í&æë>f,X c8e XhDJÔììüì2ìî1/ìîþîüþÅþÄ990&&#"3267#"&54632'"32676654&'&&'2#"$'&5476$+9o9q~r@s.Aƒ>ÓþþÓE€îyÐWWWWWVÑy{ÎWWWWWXÏy˜mmllmmþù˜˜þùmmllmmf×%#€rs~$#ÕêÂÃé·WWWÏzyÏWVVUWWÏyzÏWXVšnmmþúš˜þûmmnnmm˜šmmn'“RÕ v@>  %  î  ji i jiÔìäÔìÔìä91ô<<ì2Ô<<Ä9990KSXÉÉÉÉY"73#######5ww㪉L‰¬q®¬¬Õããý¾µÿþKBþM³mî¢f7·ÆÅÔÌ1ôì0K° TK°T[X½ÿÀ@878Y´]!#‡þÄfþˆÅ;;1\@ñðÔüÔì1ô<ì20K° TK° T[K°T[K°T[X½@ÿÀ878YK° TX½ÿÀ@878Y3#%3#Åëë‹ëë1öööÙÿöÛ =@!   §¶ §  Ô<Ä291Ô<ì2ü<ì2.À990!3!!!'7#5!7!Ùü•‘ëþ^®Püêü–’쨰ý¨Û1}´ëÜíþϲíÜÕ¡@7%À ®À ¾ À  /ÔÄÄÔ<ì291/<Äìôäìîî90KSXííííY"K° TK° T[X½ÿÀ@878Y@&W††³³µµ ] !!!!!!!!!{ÿyþ}‘ýsfýš¤ûÛþ“þÕýžbþÝþêþÝþªþÝ^þ¢-ÿ¶– +è@> +,   )*&®& ®œ&˜,+,* # )-#7-+,üìüìÀ999999991äôìîÀÀ99999990@p- -*'&!/-976!9)?-GYVT!Y(Y)jege!j%j($'))68)KFE I)Z^SVV T!V"[(j ejlaf c!k(x ™ ˜ ª ]]3254&/.#".5!27!"&''\4ƒS±ÂM3‚R°ÂþêJJ™gšøfÇqÉMLþhþ˜™ÿfÊqs>;ëDu1“:9þüì@q.þêdú—kœKMÇsÇcÿšþ–þdOOËqúé /B@#  $'!ó-ôó!ò0 $k*k0ÔìÔì99991üìü<ìÀ999032654&#"&&#"326#"&546326632#"&¼+vIZqgLHwþñ+tKZqfMGz©DŸa‹Æ¯ŒZ™cGž_ŒÅ¯Œ[–1CDeOMeeCCdOMeia‚~ó³¼êq„~ò´½ënÙÛ .@õ§õ  § l l Ô<ì2ü<ì21/ìÔ<ìü<ì0!!#!5!!!Ñ ýöîýö ýöúþþžìþžbìbûêîÙÛ¨ '@  § ö Ô<Ä2291/äüÌ90%!55ÛúþüúþîîîÆÑÑóPëNÙÛ¨ '@ §ö  Ô<<Ä291/äüÄ907!!55%Ùúþúþîî´ôþ²ëþ°óÑyÕ´@B  % ÷ ÷   nm n mÔ<ì2ìü<ì2ì999991/ä2Ô<ü<Ô<ì290KSXííííY"²]@, $+6:FI   0@€€°° ]]!!!5!5'!5!! !!!!Nþ9þƒþ:Æ1þk$þ±! þ°%þj1Ç þ` ÂBVÀþ3ÍýåÀVB®þT¢` :@! Û˜ ³Þ!   !üì2ÜÄì91ää2ô<ì990!3265!3267#"&'#"&'®idfgdh!'!5]-Yq#/‡YJhþT ýutqqt‹ýG8 úKSOO/0þ;ÿçR)8@'! '!ù* $$*ÔÌÜÌ9991äÌÜÌÎÎ9906654&#"#"&54632#"&54324&#"32þ;'#ÂS0@ºÒõþ»ÿ¶êï³e‹ID`IFa~¬qº9WzºC2Eqþ¾þèþ¨þGé·Ë Uór|þïÒtx)þw“Á O@  ûûú  ÔÄÜÄÄ91Äüìî990@ &#)  ) ( ) 8 ]]!! !!5 Bü’lý’¥ú–ºý_Áþ÷ý{ýNþö¬²–þw²Á@ýüúppÔìÔì1üìì20!!!!–þ¨ý”þ¨Áø¶)ù×ÿÝJD/@    ÔÌ991/<ÔÌ22990#!#!#"663J'°šþá˜î—þá˜7: Õ¼ÙDàüœdüœd>DÇœ3þ‹°,B²*#¸²ÿº @ÿþ- *(&  qr q-Üìüì991üììüìì9026732#"&54&#"#"&54632jcãìi‚RA@Ae '&>ÄkTF32°-üÓÓ…hB:Yr õ7Œ^‘¤Òâ‰YUW¦O\©KàØ=ÈÄ4>3:rWTþ@LH†t„8;##´¯uuð 9A  @œ  uu ÔìÔì991ôìôìüì02#"&546!!"32654&BÕ÷öÖÖ÷÷Æ7üÉœT[[TS[[ðÞ¾¾Üܾ¾ÞüMÈÑ~tt||tt~7îåF³ ½  @  xwx w ÔììÔììÀÀ9991/<ì2üì990!!654&#"!!&5! Ë#ýŸ~„˲±Ë„~ýŸ#~zx89xzÿ#V¥Ëééˤþ÷UþÝy¤9yþ‡þǤþêXÿã{>Ì@B8>6Ò6Ø'Ì&Ô# Ÿ6Ï-*Ì>Ë;Ÿ×Ê0*˜? - 6 & 7 3;?üÄìÔü<ÔìÄ999991ä2ô<Ääü<ôìÄæþ<ôîîî9990@N>>?@MMO@^^_@nno@@@­­½½2=0>B=@>R=P>b=`>ƒ=€>’=>¤= >²=°>]]4&#""326=>32>3 !3267#"$'#"&54$!354&#"w`g€ýápq[QeŠý^wßa–ÙGMÌz =üº›qí}ÿ~³þ÷Heß‹Ââ"Ó†ŽsÆUªf}un²LJDM‘m)JMOMOþÂþöf~~CDþì01kdkdŨŸUO..Nÿ¢)Á +¸@> )+ *& ¡&¡Ê&˜++, #* #)B#LB;,üìüìÀ999999991/äôìîÀÀ9999990@@:5 ;75!8)?-IF KGD!H)[VT!U(ikfe!e(5:)EJ)U^(i em( ]].#"32654&'.5!27!"&''XK/w}HO0u|ý;CDG"j³K“mFEþ»þßl¶M”pD«¡)A‹«¡+CýäNÈ{8,,že•PÊ~þìþÈ--›^ÿãÕ!M@*‘• Œ‹ ¡˜ "  "ÜìÔÔ<ì299991äôìþíôî9990!3267#"$54677665%!!çiAm@84`VQ½ewË\ôÿN^@D*iþ—iÛ1Q~d:3\/FPDBþÆ*(Ǿc›X:=L-Ãd‡Õ @Œ‹ Ü<ì2991/ôüì0!!!33þ˜h=¢þ^ýÃqdþœÙÛ@ §ÔÔì1ÔÄì0!#!Ùëûéý’Lÿ×Z² n@*      %  º@  ÔÄ91Äüì90KSXÉÉÉÉÉÉY"3##'%ƒ×`ý²wþÍ‘%hß²•ùºN7ý…þV7#w@I #"!   %  ¬”¬” ŸŸŸ!£Þ$Ä2äüìîî2õîõî99990KSXí9í2Y"&&#"!!#"&'53267#5!766327.T*Zd!þ´…)å¿A…D.U)Ycuò!3*ã¾B„ìþs¨îý_ÎÌþsMîüÎËÙáÛ#;C@!.9* 1§ §"§9*§1<-<Ô<Ä21ÄÔìÜìîÜîÀ9999990#"'&'&'&#"56632326#"'&'&'&#"56632326Ûj³`k›^X¬bi³an“ ›^V©gj³`k ›^X¬bk²`k›^V©#ôPE:=MSôNE;=Kþ³ôPE:=LTôPE:>K“Á ²¸ @ ú/Î91/îî90!!!Éþºþ#-3úmVüªÁú?ž‰j' 5³  »@  y yÔü<Ôì2991ô<ì299055‹þÛ%þÌþÜ$þ'òÝÝòqºsòÝÝòqºÁ‰' 5³  »@ yy Ô<üÔ<ì991ô<ì29905-5%% íþ%þÛþ!ëþ$þÜ'þºþòÝÝòþºþòÝÝ¢^ƒ #@¨   ÜüÔüÔì1/<<ì220!!!!!!öhþ˜ú¬hþ˜ªhþ˜ƒþ}ƒþ}ƒþ}ÿÿ 'k'$uÿÿ 'm'$uÿÿfÿãfm'2NufÿþÁ×P@" À¾ À À   -+ üìÔÄÄÔì299991/ì2ôì2ôìÀÀ0@ !!?!O!_!]# !3!!!!!!"# !2œiþßþâ iZhýsfýš¤û / þFþ&Úº 0²âäåä²þÝþêþÝþªþÝ…ihƒXÿã^{'3t@2" ØÌÔ Ÿ.¡(¡×Ÿ%ʘ4"1 1 +B;4üìÔüÔÄì9991ä2ô<ìäìîþôîî9990@/5?5O5O5_5o5o55F"]]4&#"!3267#"&'# !2>3 %"32654&îw`h‚Aü» œŒqí}~ÿ~¥ÖHRÕ‚þÞþ¹G"†ÎQRLJBúcw}}wu||ªf}unwf~~CDþì01QWTT88RVWQþÆ:«¡¡««¡¡«°²¹´ª/Æ1ôì0!!ü²þþ°²¹´ª/Ì1ôì0!!ø²þþÓX…Õ +º@    ÜüÌÔÌþÔÎ1ô<ì20!3!3!þ¬ãÕdþþ¬ãÕdXbþžþå`þ ¼XoÕ +º @  ÜìÔÌÜîÔÎ1ô<ì20!#!#!TäÕeúTäÕeÕþãþ `þáþ¢^ÓX‹Õ¹@ ÜüÔÌ1ôì0!3'þ¬ãÕdX`þ X9Õ¹@ ÜìÔÌ1ôì0!#åTãÕdÕþãþ `ÙVÛ® 0¼@ §¦ z{z Ô<ìü<ì1ôÄüÔìî0!!!!!!Á3þÍ3þÍþúþ‹þËXþËìþ#îuv@A%ÔÄ91ÜÌ990KSXÉÉÉÉÉÉÉÉY" úþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿþF1'\Žœÿÿÿìßk'<Íuþhÿãîð+@55%˜œÔÌ1ää0KSXííY"#3¸à¦à J=ÏÅ#/@ ! ! $A !* @&00   '}|~-} |0Üìì2üìì29999991Ôìì2üìì2À999990'7&&5467'766327'#"&72654&#"²Ï™ÏÑ™Ï0l=6l9ϘÏÏšÏ.j?:l¦[€\[€~ ÏšÏ1k??l.ÍšÏÏšÏ7n6?i/ϙζ\\\]~ž‰‹'¼¶yÔì291ôì905‹þÛ%þ'òÝÝòqºÁ‰®'¼¶yÔ<ì91ôì905%%Áíþ$þÜ'þºþòÝÝ+Bu@& ¡Ý Ÿ£ ³    ETü<ìì2ô<ü<Ì991/<ä2ü<ìíî2990K°TK°T[K°T[K°T[X½ÿÀ@878Y´@€]!!#"!!!!#35463Ùiþ—JÆK:þþ—þkþ—°°ÌÖþÜ$ë7DNû `ü `N·¯'Bl@! ¡ Ÿ£ ³     ETü<ìì2ôüÌ991/<ä2üìî2990K°TK°T[K°T[K°T[X½ÿÀ@878Y´@€]!!!"!!!#3546{Çþ—þîL<þçþš²²Ìùì)7DNÿü `N·¯3ÿ;ÃÕ?@!å å ãä W VW Ô<<äü<<ä291ä2ôüÔ<ì2î20!!!!!!!5!!5!VJ#þÝ#þÝþ¶þÝ#þß!Õþƒîþ<îþƒ}îÄîÑ9‰·üì1ÔÌ0!!Ñhþ˜‰þ}“ÿLƒ¹@ ¨ÜìÔÌ1üì0!#øTæÓeƒþãþ `“ÿFƒ +º @¨  ÜìÔÌÜîÔÎ1ü<ì20!#!#øTæÓeúTäÕeƒþãþ `þáþ¢^Bÿã Vð #/3?K|@C3 2211 003%@ *™$F4 ™:0˜2$œL3IC1!  C=!'= I7' -LÜäìÔÌìäîîîöî991ä2ô<<ä2ì2îöîî20KSXííY""32654&'2#"&546"32654&'2#"&546#32#"&546"32654& ÇHNNHGLLGºÕÖ¹ºØ×øÅHNNHHMNGºÕÕººÕՇݥ޺ÖÖºº×׺GNMHHLMh{rs{{sr{¨Ø½½ÛÛ½¼Ù8|rs}}sr|¨Ù½½ÚÚ½½Ùùó ý ؽ½ÛÛ½¼Ù¨{rs{{sr{ÿÿ 'k'$uÿÿ¼ák'(´uÿÿ 'k'$uÿÿ¼ák'(´uÿÿ¼ák'(´uÿÿ¼²k',ÿduÿÿÿëÝk',ÿduÿÿ)Ÿk',ÿduÿÿ=k',ÿduÿÿfÿãfk'2Nuÿÿfÿãfk'2Nuÿÿfÿãfk'2Nuÿÿ¼ÿãÃk'8'uÿÿ¼ÿãÃk'8'uÿÿ¼ÿãÃk'8'u¬`·ß üì1/ì0@ P`p€]!!¬fþš`û ‡îyf6@ ÆÅÔÌ91ôì290K° TK°T[X½ÿÀ@878Y3#'#‡ò²ÇDzfþˆáá¤\9É@  ¼@ Å€€ ÔìÔì99991ôìüì9999990K° TK°T[X½ÿÀ@878Y@T              ( ]]'&'&#"#4632326=3#"&7/$&‹g]$I)=%$(‹g]$CT%>;ˆ”+@9ˆ”ÅX;EµÔÄ1ÔÌ0K° TK°T[X½@ÿÀ878YK°TX½ÿÀ@878Y!!Åvýм°PF i@  ÔìÔì1Ô<ÔÌ0K° TK°T[K°T[X½@ÿÀ878YK° TX½ÿÀ@878Y@]332673#"&° cSSc ®œœ®FFJJF™™w;‰1*·ñ‚Ôì1Ôì0K° TX½@ÿÀ878Y!!wþî1öãá C½ @ ƒ:ƒ Ôìüì1Ôìüì0K° TK°T[X½ÿÀ@878Y32654&#"4632#"&}M67LM67Lš§vv§§vv§þ7LM66MM6v§§vv§§þoË5@   ÔÔÌ991/ÔÌÔÌ0K° TX½ÿÀ@878Y!#"&/32654&'Z:7{0f42S!:A+->j/_[ ˜.(R<ÁîÕfE@ÅÔÌÜÜÌÌ991ô<Ì20K° TK°T[X½ÿÀ@878Y3#3#ƒÙø£-çþð®fþˆxþˆVþo@   ÔÄÌ991/ÔÌÔÌ0!33267#"&546Å2&;1'M(7^)s{6CI'1œ \V5m‡îyf6@ ÆÅÔÌ91ô<ì90K° TK°T[X½ÿÀ@878Y 373‡ÿ²ÇDzÿîxããþˆÿ¤ìÕ `@2 % À   „ü<ü<Ä.9991/äì90KSXÉÉÉÉY"!7!!'%Çþþs¤ûÛ”#Õþ`¹ÁþðþþÝ j¾ÅÿÛ ~@-   % £   T ü<ì2.À991/ì90KSXÉÉÉÉY"² ]@utƒ@ P ` ` tp p €€ ]]!7!'7Çhoðþ˜}oìþ Xš¤üÇVš£ÿÿ“ÿã-k'6Éuÿÿjÿãbf'Vàbÿÿ\qk'=Ïuÿÿ\Ff']àTþ¢ç˜@ Ô<ì21ÄÔÄÆ0##çããã˜ý öüý ö!LÕ •@¹À À  -. „ ü<ì2ÄüìÄ91/îöîÖ<î20@X!P!`!////////OOOOOOOO________ŸŸŸŸŸŸŸŸ¿¿¿¿¿¿¿¿(]]3#32654&#! )#3Pëë‰ìùøíýö•ULxhgghyþ°þ°þk®®²þ¿þüþ¶êßÞè#ateþø§©þ÷etamXÿã'(õ@Y&'('%$%(('"#" ! "! 5((5(%('&%"! ##¡ ¡˜#£)'& !#(%" BB;)üìÔì99991ìÄôìî9990KSXí9í2ÉÉÉÉY"K°TK°T[X½)@))ÿÀ878Y@6f!/*76"?*O*oooooooooo]].#"32654&! 4!2''%'!%˜7l4u‚ru| £ujþ»þßþÞþ¹-.N$¾þ‹%3¼`ox#þÅç…y”¨«¡-\”ˆþÿ”þìþÈ8ç ÛwaÊtr`ÿÿÿìßk'<ÍuÿÿþFf'\œ¼‰Õ Œ@® ® - üì22Ôì99991/äÔìÔì0K° TK° T[K°T[K°T[K°T[X½ÿÀ@878Y@,0000PPPP    °°°°]]!!3 !32654&#=þþ1þÏþãþÕpzzpþþÕþüýëêýºþ]mcen¬þV^;@¡Ð¡Ð˜ÊÞ£B @ üì22ôì1ìääôäìæî0´O`]%!!>32#"&"32654&þšfJ´uÏ þöÏu´¤s{{ssyy¢ý´¾ý¨b]þ·þýþýþ·]7©ŸŸ©¨  ¨Ù Ûø·§¦ÔÄ1ôì0!!Ùúþøì)´Û /@   Ô<Ì291Ô<Ì290 '7´þN²¨þNþN¨²þN¨²²3þNþP¨°þP¨°²¨þN²{œß 7´¾  @ š …†… ÔäÄüä1ôìÔìî29035733!ÏáåâÌý9 4 1ýZmœð]@% ¸ ² º"@œˆÜÄÔÔì9991ôìüÄî9990KSXÉ9ÉY"!!56654&#"56632œrý_9=4I;>ŽTW£Kž´GeD¨™ 5P(2>-/ºoHyVZð(W@ #  ¸"²¼"#@#œ)ˆ&ˆ )ÜÄÄÔìÔì9991ôììüÄþÅÎ9990#"&'532654&##532654&#"56632P\fÆÉQ”DB€<_hkrJTbZNP4{FA—W§±Z`nQ®$%@;@=‰/3--¦piE`dÿã¨ð ›@     %¸²¾´œ ¸@˜œ    †…†…Ä2ÔÄäüäì2ÄÆ9991/æäîÄ2öîÖîî2î2990KSXÉÉííY"333##5!5#335733!9ïïø‰‰æþyþ+ߦßùôÍàæßÍýþ¼ýù›¢¢¨þ™ ýI 4 1ýZdÿãåð'¬@   %!   ¸$²$¾& !&²"œº@ ˜œ#ˆ%…#†… (ÄÔÄÔÄÄäþäî9991/æäîîöîÖîî2þÄ99990KSXÉ9ÉííY"%!!56654&#"56632#335733!qtý];>3J<>‹UX¡JŸ³Icûªß¦ßùôÍàæßÍý¨¨š 5N'2?-0»oH|Tþ• ýI 4 1ýZhÿã¨ð 6:Á@ : 9988 77: %.1* #! ¸´#!¸$²-*¼$!#µ91œ7˜¸@$$8'" :!'"4  †'ˆ4ˆ-";Ä2ÔÄÄÔìÔìî2ÄÆ9999991/Ä2îäö<îîþÄþÅÎî299990KSXÉÉííY"33##5!53#"&'532654&##532654&#"56632#3'ø‰‰æþy‡ïïü%]fÇÉQ”DB€<_hjsJTb[OO5zGA˜V§±Z-ߦßDýù›¢¢¨7þ¼#nQ®$%@;@=‰/3--¦piE`ûq ÿÿfÿãúk'* 1uÿÿ\þFF'JÚÝÿÿ¼=k', ÿduÿÿ“þo-ð'6ÝÝÿÿjþob{'VÝbÿÿfÿã\k'&fuÿÿXÿãuf'FÓÿÿfÿã\k'&fuÿÿXÿãLf'FàÓ\ÿã¨$Kº%@" ¡Ð¡ Иʣ    @"B;%üìô<Äü<Ä1/ìäôäìäîÝ<î20²O&]!5!5!3#!5#"322654&#"¦þºFhššþ˜J²uÏþö Ït³¢syysryy¼ÍrrÍû+¢c\II]üɨ  ¨¨  ¨o¼ãß·«ªÔÄ1ôì0!!otýŒßþÝÑ9‰·üì1ÔÌ0!!Ñhþ˜‰þ}ÿÙÿãð1r@;.*÷(÷1.®®œ˜!2*("%!) 2 +) )% 2ÔÄ2Ä2üÄÄ99999999991Ä2äôüÄþÄî2Ý<î2990%# '#73&&5467#736!2&&#"!!!!3267_Ïpþúþ™KÙXbºXMepÏ_Q¸c³-Vþ­YþÕ2¯~cµTR78õà Ãö87þËNO{vÃ$$ ÃzzOOÅ;ö@ ñÔüÔì1Ô<ì203#%3#Åëë‹ëëöööömîNö8µÔÄ1ÔÄ0K° TX½ÿÀ@878Y@ //]!#3þãÄöþø¤î\ø#Ã@  »@! $ €€ $ÔìÔìÀ999991Ô<ìÔì29990K° TX½$ÿÀ$$@878Y@\             ##+]]'&'&#"#465463232653#"&8- (‹kW%J';'%'‹kW&F#<2j‚'<9j²î“ö8µÔÄ1ÔÄ0K° TX½ÿÀ@878Y@ //]#ÍÆÄþãöþø‡îyöE@ ÔÄ91Ô<Ä90K° TX½ÿÀ@878Y@/// ]!#'#f4ß²ÇDzöþø¡¡‡îyöK@ ÔÄ91ÔÄ290K° TX½ÿÀ@878Y@//// ]373fß²ÇDzßþø°îPö S@  ÔìÔì1ÔÄ2Ì0K° TX½ÿÀ@878Y@///// / ]332673#"&°`LL`¬””¬ö=<<=‡‡w‰ö*·ñ‚Ôì1Ôì0K° TX½ÿÀ@878Y!!wþîöö  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•ÍfÉɦ+ô‹‘ Bú{sè°¨¤/)´Ù mRo Ñì‘b‘ç‘¢‘‰‘\‘ž‘‘‰‘}‘j3å3´Ù´Ù´Ù¤‡1 ¼ßf¤¼w¼w¼‘f²¼ú¼úÿ3¼¼ö¼²¼ÍfݼÍf)¼Óu ¼1 Ó=+'ËÿìÍ\¨°ì¨‹´Ï^fXº¬¾Xº\mX{'º\²¬¾¬¾ÿ¼R¬¾¬Vª²¬Xº¬º\ò¬ÃjÓ² 7dH)7¨\²ì²´Ù1 1 ßfw¼²¼Íf¼fXfXfXfXfXfX¾XmXmXmXmX¾¬¾ÿÕ¾ÿþ¾<²¬XXXXX² ² ² ² 5²‘®‘}'Á¬'mÅ´Ù®Í-ªÃ´Ù´Ù´Ù‘ã®Z;¾)L–'ÿÝá3ƒžƒu'7bXN¤¦´ÙVL‘´Ù“+ž+Á¢‘1 1 Íf VfÁXBÓB¼ Ó ´Ùô7ËÿìVþhJLžLÁî+î'3 Ñ “B“ …B1 w¼1 w¼w¼ú¼úÿëú)úÍfÍfÍf¼¼¼¾¬‡¤Å°wãÁV‡#ÿ¤øÿÛÓÃjÍ\¨\ì´!XËÿì7缺¬´Ù´{mZHdHdHh‘fº\ú¼ÓÃjßf¾Xßf¾Xº\Ro Ñ‘ÿÙÅm¤²‡‡°wÿ   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ    sfthyphenperiodcenteredEuroc6459c6460c6461c6462c6463c6466c6467c6468%%%%NqÓ]ÜÆÞ 6©ÇÞô N{òU•å?uã<_НÐóOû ¡ K Á í G € © è E a ç > ‡ Ä*Ÿ2e¡àç:\u—¹ÍÚ#pÅ|¿è$†£ZŸí<~*‰ÑZ@!âIªÀ"dqjw„‘ž«¸ÅÒßìù   - : G T a n { ˆ • ¢ ¯ ¼ É Ö ã ð!!]!È""¨"Ú##†$.$Á%!%K%‹%Î&H''n'¥'Ô((Š(Ú)6){)ž)Ø*<*Ê++p,5,Ú-8-a-}-Î.B.½.ä//\/Œ/Œ/™/¦/³00¢0¹0Ð1161U1t1¨1ü2 2292É2ì33v3Ò44-4L4~5*575D5Q5^5k5x5…5’5Ÿ5¬5¹5Æ5Ó5à5í6 676Ê6ú7H7k7³7ï8'8W8†8Ô9-9:9G9T9a9„::Ç:Ô:á;O;ž;´;í<ª>·>Ä>Ñ>Þ>ë>ø?????–?­@4@T@AA@AuA­AðB‚ 7þÓ9ÿk:ÿ¤;ÿY<þÓ»þÓêþÓ$&$&$&$&$7ÿa$8ÿÁ$9ÿu$:ÿ¤$<ÿ<$Yÿ·$\ÿ·$hÿÁ$µÿD$·ÿD$ºÿ·$»ÿ<$Är$År$ÓÿÁ$ÔÿÁ$ÕÿÁ$êÿ<$ëÿ·%9ÿ­%:ÿ%<ÿ%»ÿ%êÿ&/&6&&µK&·K&ã&&ù&'&'<ÿk'»ÿk'ÄÿÜ'ÅÿÜ'êÿk)þ·)ÿÁ)þÓ)ÿ)ÿ)$ÿ)Dÿˆ)Hÿ­)Rÿ­)Uÿ})Xÿš)\ÿ)bÿ)iÿˆ)jÿˆ)kÿˆ)lÿˆ)mÿˆ)nÿˆ)pÿ­)qÿ­)rÿ­)sÿ­)yÿ­)zÿ­){ÿ­)|ÿ­)}ÿ­)~ÿš)ÿš)€ÿš)ÿš) ÿˆ)¡ÿ­)­ÿ)®ÿ)±ÿ­)·&)ºÿ)Äþ­)Åþ­)Çÿ)Éÿ)ëÿ*7ÿÜ*<ÿÓ*»ÿÓ*êÿÓ.ÿN.&ÿ¤.2ÿ¤.8ÿÜ.HÿÜ.RÿÜ.XÿÜ.\ÿ}.dÿ¤.gÿ¤.hÿÜ.pÿÜ.qÿÜ.rÿÜ.sÿÜ.yÿÜ.zÿÜ.{ÿÜ.|ÿÜ.}ÿÜ.~ÿÜ.ÿÜ.€ÿÜ.ÿÜ.‘ÿÉ.¡ÿÜ.¯ÿ¤.°ÿš.±ÿÜ.ºÿ}.Ä&.Å&.Ðÿ¤.Ñÿ¤.Òÿ¤.ÓÿÜ.ÔÿÜ.ÕÿÜ.ëÿ}.ûÿ¤.ýÿ¤/2ÿ·/7þ­/8ÿ·/9þæ/:ÿa/<þÁ/\ÿu/gÿ·/hÿ·/‘ÿ·/¯ÿ·/°ÿ·/µþ/·þ)/ºÿu/»þÁ/Ðÿ·/Ñÿ·/Òÿ·/Óÿ·/Ôÿ·/Õÿ·/êþÁ/ëÿu2ÿÓ2&2ÿÓ2$ÿÉ29ÿÉ2;ÿ·2<ÿ·2bÿÉ2­ÿÉ2®ÿÉ2»ÿ·2ÇÿÉ2ÉÿÉ2êÿ·3þˆ3ÿÜ3þˆ3$ÿD3DÿÉ3VÿÜ3\&3bÿD3iÿÉ3jÿÉ3kÿÉ3lÿÉ3mÿÉ3nÿÉ3 ÿÉ3­ÿD3®ÿD3µ&3·93º&3Äþa3Åþa3ÇÿD3ÉÿD3äÿÜ3ë&3úÿÜ4&5&5&57ÿ¤5<ÿ5\ÿ¤5ºÿ¤5»ÿ5êÿ5ëÿ¤66ÿ¤6ãÿ¤6ùÿ¤7þÜ7þÓ7þÉ7ÿ7ÿ7$ÿa77/7Dþø7Fþð7Hþð7Rþð7Uÿ7Vþð7Xÿ7Zÿ7\ÿ 7bÿa7iþø7jþø7kþø7lþø7mþø7nþø7oþð7pþð7qþð7rþð7sþð7yþð7zþð7{þð7|þð7}þð7~ÿ7ÿ7€ÿ7ÿ7 ÿ<7¡ÿa7­ÿa7®ÿa7±ÿa7ºÿ 7Äþø7Åþø7Çÿa7Éÿa7äþð7ëÿ 7úþð7üþð7þþð8$ÿÁ8bÿÁ8­ÿÁ8®ÿÁ8ÇÿÁ8ÉÿÁ9þø9ÿk9þø9ÿ¤9ÿ¤9$ÿu92ÿÜ9Dÿ9Hÿ9LÿÜ9Rÿ9Xÿ·9bÿu9gÿÜ9iÿ9jÿ9kÿ9lÿ9mÿ9nÿ9pÿ9qÿ9rÿ9sÿ9yÿ9zÿ9{ÿ9|ÿ9}ÿ9~ÿ·9ÿ·9€ÿ·9ÿ·9‘ÿÜ9 ÿ9¡ÿ9­ÿu9®ÿu9¯ÿÜ9°ÿÜ9±ÿ9Äÿ9ÅÿD9Çÿu9Éÿu9ÐÿÜ9ÑÿÜ9ÒÿÜ:ÿY:ÿ¤:ÿY:ÿÁ:ÿÁ:$ÿ¤:Dÿ·:Hÿ·:Rÿ·:UÿÜ:bÿ¤:iÿ·:jÿ·:kÿ·:lÿ·:mÿ·:nÿ·:pÿ·:qÿ·:rÿ·:sÿ·:yÿ·:zÿ·:{ÿ·:|ÿ·:}ÿ·: ÿ·:¡ÿ·:­ÿ¤:®ÿ¤:±ÿ·:Çÿ¤:Éÿ¤;ÿY;&ÿ·;2ÿ·;HÿÉ;dÿ·;gÿ·;pÿÉ;qÿÉ;rÿÉ;sÿÉ;‘ÿ·;¯ÿ·;°ÿ·;Ä&;Å&;Ðÿ·;Ñÿ·;Òÿ·;ûÿ·;ýÿ·<þ­<þÓ<þ­<ÿN<ÿN<$ÿ<<&ÿ·<2ÿ·<DÿD<HÿD<RÿD<Xÿk<bÿ<<dÿ·<gÿ·<iÿD<jÿD<kÿD<lÿD<mÿD<nÿD<pÿD<qÿD<rÿD<sÿD<yÿD<zÿD<{ÿD<|ÿD<}ÿD<~ÿk<ÿk<€ÿk<ÿk<‘ÿÜ< ÿD<¡ÿD<­ÿ<<®ÿ<<¯ÿ·<°ÿ¤<±ÿD<Äþˆ<ÅþÓ<Çÿ<<Éÿ<<Ðÿ·<Ñÿ·<Òÿ·<ûÿ·<ýÿ·=ÿÜD\ÿÁDºÿÁDëÿÁIÿIÿÜIÿIµVI·NHÿÉNRÿÉNpÿÉNqÿÉNrÿÉNsÿÉNyÿÉNzÿÉN{ÿÉN|ÿÉN}ÿÉN¡ÿÓN±ÿÉUþÓUþÜUµ&U·VYÿYYÿYZÿ}Zÿ}\ÿa\ÿDb&b&b&b&b7ÿab8ÿÁb9ÿub:ÿ¤b<ÿ<bYÿ·b\ÿ·bhÿÁbµÿDb·ÿDbºÿ·b»ÿ<bÄrbÅrbÓÿÁbÔÿÁbÕÿÁbêÿ<bëÿ·d/d6&dµKd·Kdã&dù&gÿÓg&gÿÓg$ÿÉg9ÿÉg;ÿ·g<ÿ·gbÿÉg­ÿÉg®ÿÉg»ÿ·gÇÿÉgÉÿÉgêÿ·h$ÿÁhbÿÁh­ÿÁh®ÿÁhÇÿÁhÉÿÁi\ÿÁiºÿÁiëÿÁj\ÿÁjºÿÁjëÿÁk\ÿÁkºÿÁkëÿÁl\ÿÁlºÿÁlëÿÁm\ÿÁmºÿÁmëÿÁn\ÿÁnºÿÁnëÿÁÿÜ‘ÿÓ‘&‘ÿÓ‘$ÿÜ‘9ÿÜ‘;ÿ·‘<ÿÜ‘bÿÜ‘­ÿÜ‘®ÿÜ‘»ÿÜ‘ÇÿÜ‘ÉÿÜ‘êÿÜ­&­&­&­&­7ÿa­8ÿÁ­9ÿu­:ÿ¤­<ÿ<­Yÿ·­\ÿ·­hÿÁ­µÿD­·ÿD­ºÿ·­»ÿ<­Är­År­ÓÿÁ­ÔÿÁ­ÕÿÁ­êÿ<­ëÿ·®&®&®&®&®7ÿa®8ÿÁ®9ÿu®:ÿ¤®<ÿ<®Yÿ·®\ÿ·®hÿÁ®µÿD®·ÿD®ºÿ·®»ÿ<®Är®År®ÓÿÁ®ÔÿÁ®ÕÿÁ®êÿ<®ëÿ·¯ÿÓ¯&¯ÿÓ¯$ÿɯ9ÿɯ;ÿ·¯<ÿ·¯bÿɯ­ÿɯ®ÿɯ»ÿ·¯ÇÿɯÉÿɯêÿ·´$þø´-ÿ¤´<&´bþø´þÓ´­þø´®þø´»&´Çþø´Éþø´ê&¶$ÿ¶-ÿ¤¶9&¶<K¶bÿ¶þø¶­ÿ¶®ÿ¶»K¶Çÿ¶Éÿ¶êKºÿaºÿD»þ­»þÓ»þ­»ÿN»ÿN»$ÿ<»&ÿ·»2ÿ·»DÿD»HÿD»RÿD»Xÿk»bÿ<»dÿ·»gÿ·»iÿD»jÿD»kÿD»lÿD»mÿD»nÿD»pÿD»qÿD»rÿD»sÿD»yÿD»zÿD»{ÿD»|ÿD»}ÿD»~ÿk»ÿk»€ÿk»ÿk»‘ÿÜ» ÿD»¡ÿD»­ÿ<»®ÿ<»¯ÿ·»°ÿ¤»±ÿD»Äþˆ»ÅþÓ»Çÿ<»Éÿ<»Ðÿ·»Ñÿ·»Òÿ·»ûÿ·»ýÿ·Ä7þaÄ9þæÄ:ÿ)Ä<þšÄ»þšÄêþšÅ7þaÅ9þæÅ:ÿ)Å<þšÅ»þšÅêþšÇ&Ç&Ç&Ç&Ç7ÿaÇ8ÿÁÇ9ÿuÇ:ÿ¤Ç<ÿ<ÇYÿ·Ç\ÿ·ÇhÿÁǵÿDÇ·ÿDǺÿ·Ç»ÿ<ÇÄrÇÅrÇÓÿÁÇÔÿÁÇÕÿÁÇêÿ<Çëÿ·É&É&É&É&É7ÿaÉ8ÿÁÉ9ÿuÉ:ÿ¤É<ÿ<ÉYÿ·É\ÿ·ÉhÿÁɵÿDÉ·ÿDɺÿ·É»ÿ<ÉÄrÉÅrÉÓÿÁÉÔÿÁÉÕÿÁÉêÿ<Éëÿ·ÐÿÓÐ&ÐÿÓÐ$ÿÉÐ9ÿÉÐ;ÿ·Ð<ÿ·ÐbÿÉЭÿÉЮÿÉлÿ·ÐÇÿÉÐÉÿÉÐêÿ·ÑÿÓÑ&ÑÿÓÑ$ÿÉÑ9ÿÉÑ;ÿ·Ñ<ÿ·ÑbÿÉÑ­ÿÉÑ®ÿÉÑ»ÿ·ÑÇÿÉÑÉÿÉÑêÿ·ÒÿÓÒ&ÒÿÓÒ$ÿÉÒ9ÿÉÒ;ÿ·Ò<ÿ·ÒbÿÉÒ­ÿÉÒ®ÿÉÒ»ÿ·ÒÇÿÉÒÉÿÉÒêÿ·Ó$ÿÁÓbÿÁÓ­ÿÁÓ®ÿÁÓÇÿÁÓÉÿÁÔ$ÿÁÔbÿÁÔ­ÿÁÔ®ÿÁÔÇÿÁÔÉÿÁÕ$ÿÁÕbÿÁÕ­ÿÁÕ®ÿÁÕÇÿÁÕÉÿÁá2ÿ·á7þ­á8ÿ·á9þæá:ÿaá<þÁá\ÿuágÿ·áhÿ·á‘ÿ·á¯ÿ·á°ÿ·áµþˆá·þ­áºÿuá»þÁáÐÿ·áÑÿ·áÒÿ·áÓÿ·áÔÿ·áÕÿ·áêþÁáëÿuã6ÿ¤ããÿ¤ãùÿ¤åÿÜè&è<ÿkè»ÿkèÄÿÜèÅÿÜèêÿkêþ­êþÓêþ­êÿNêÿNê$ÿ<ê&ÿ·ê2ÿ·êDÿDêHÿDêRÿDêXÿkêbÿ<êdÿ·êgÿ·êiÿDêjÿDêkÿDêlÿDêmÿDênÿDêpÿDêqÿDêrÿDêsÿDêyÿDêzÿDê{ÿDê|ÿDê}ÿDê~ÿkêÿkê€ÿkêÿkê‘ÿÜê ÿDê¡ÿDê­ÿ<ê®ÿ<ê¯ÿ·ê°ÿ¤ê±ÿDêÄþˆêÅþÓêÇÿ<êÉÿ<êÐÿ·êÑÿ·êÒÿ·êûÿ·êýÿ·ëÿaëÿDö7ÿÜö<ÿÓö»ÿÓöêÿÓù6ÿ¤ùãÿ¤ùùÿ¤û/û6&ûµKû·Kûã&ûù&ý/ý6&ýµKý·Kýã&ýù& NE@í§mþ …þhþh V •¼GÌþBGÌSf €¯ JBits ûþšmãB³É`#cÕVeraSansBdÿÿÿÿ6ÿÿþ628B00@                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               !                        !        #                     #        $                       $        %                       %        '                   '       (             !   (       ÿÿÿð_<õº¹Ìº¼–²þhþ Vmloganalyzer-3.6.5/src/BitstreamVeraFonts/VeraMoIt.ttf0000644000175000017500000015235412225176641022124 0ustar danieldanielOS/2´Zôô¾ÐVPCLTp¢Í¿(6cmap¤Ãè ²LXcvt ÁÕç&$¼fpgmç”ñÄ%ЋgaspÔ¨ glyf·§ò4&\‹ðhdmxÇ32`¿`HheadÙ®ŸµÔ´6hhea fF¾¬$hmtx ö„鵤4locaÓ÷¼pmaxpë;Œ name@žZå postn‚î]¹Ø–prep8ÿ‰ àî::S : : Zf0À  – ƒ t ® 0 "  T @ " @ "  b : z ` . ¬ 0Ú & ´Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans Mono ObliqueRelease 1.10BitstreamVeraSansMono-ObliqueCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans Mono ObliqueRelease 1.10BitstreamVeraSansMono-ObliqueCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com##¸Ë¸ª¸¸‡¾‰ºË¦ü¸ÓǸX!œÓ¸¸#/Ù¨¸{{¸R¤fÍÑ͇‡“¤oƒÝ´‹˜Z´ºÅ!þ˸¸ô7öª={fššƒÕsÕ þá+¤´œbÕ˜‡ÕÕðb¤Õ#Ӹ˦¼3N{T…\q#wé!`jÏÕ#fy```{œ¸w`ªéø{Å{´RNNÑfœœfœfœÍúƒ‘þHF?{L˜¢'5oojo{ªª-–{öª{=“föoD7fî…´}s¸€@‘ÛþÚþÙØþ×þÖšÕþÔ´GÔ}Ó%Ò2Ñ–ÐþÏþÎÍþÌþËþÊþÇþÆ}ÅþÄþÃ2»Á}À¿ŒÀþÀÀ¿¾Y¿Œ¿€¾½&¾Y¾@½&¼»/¼ú»/ºþ¹2¸·–¶þµ´Gµþµ¸ÿÑ@ÿ´G³²d³–²d±þ°¯°þ¯®þ­k¬þ«»ª©ªú©¨–§¦þ¥¤¥þ¤£–¢¡¢þ¡Y ¡ }Ÿ:žY ž:þœ› œþ› šþ™þ˜V˜—–þ•–”þ“–’Š ‘þþf þŽþþŒþ‹Š ‹þŠ ‰XA‰úˆ ‡W%‡d†…»†þ…„]…»…€„ƒ%„]„@ƒ%‚þ–€XAþ~XA~þ}þ|d{dzy@ÿ}xþwþvþuþtst2srqpq(poþnþmþlkldkjkji hþgf f f@ed.eþd.cXAc–bY ba`»aþ`_]`»`€_[%_]_@^þ]þ\[%\»[%ZY ZY XW%XAWVW%VUþTþSRSþRQþPþOþNBNSMþLxKJ}KþJ}IH–GþDþCþB2A@BAF@?-@B?>@ÿ?->=þ<þ;þ:9S:–98(9S8(7þ6þ5ú4»3þ2þ1þ0þ/+ /.d-È,+ ,+ *þ)(þ'-'–&þ%%2$þ#þ"þ!-!1 d 2 @:–%þ%þþ:þBþ-B–þ þ þ : – þ  þ@$-þ-:-  ¸d…++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX °ÝEDY!-,°%E`D-,KSX°%°%EDY!!-,ED-hþ–h¤@ ÛÛO/ÄÔì1ÔìÔì0!%!!hüsüåþ–øòr)s`Õ Y@.   :TSQ ÔäôÄÀ991/äüì0KSXíííí9Y"3#3#–ÊX¢2sË2ÊÕýqþ›eý¸þRªÕ@UQÔìÜì1ô<ì20###®Ñ®ÕýÕ+ýÕ+ÿúѾP@5 X X    ÔÌ91/<Ä2Ô<<ì22Ô<<ì220#333!!!!###!7!!7! öSõiöiŸh'ÿT'þþh hõi iÿ'Tþþ'h…þ²‡þaŸþašþ²™þbžþbž™NšŸþÓ; 0l@@()%/0%W$ZXWZX!0 !()/ %$, 1ÔìÔìÀÀ9991/Ä2ÄìôìîÆöî9999902654&'#&&'7&&54$773&&'##uVŸ^®Pw—Te;_À_#Q½hZ°Ÿ Ñ0d/UœH AšYQ®²þîØ LþE‘tNUÍš‰cEJû¶-.+´J ¨zk{Ç;_ÈhÃëǼöÏA|9#*zLq‰,_‡‹¬A’G‹ýÓBÍ‹¨þófÝqGGÖ¯¨!g4l7®Ó·&&s^/ƒ¸IÅuw 96ª¾Õ·QÔì1ôÄ0#¾®ÕýÕ+uþò @hg   ÔüÄ9991üì0#&5ìï;< OJüþÓýþÒ’þÒ¢½:Ž/W–þò3 @hg  ÔÄì9991üì04'3–ìï;< NKþþüþò,c/’.¢¼þÅŽþÑý©þë¦J+ðN@,  i i a    Ô<ì2Ü<ì2991ôÔ<ì2Äì2990%#'%%73%+þšf9þ°sþ°9fþš9PsPßÂÃbËþ‡yËbÃÂcËyþ‡ËXqy“ '@m lm    Ô<ìü<ì1Ô<ìü<ì0!!#!5!¼½þC¨þD¼“þDªþD¼ª¼Ëþáœ/5@:onÔÄäÀ1üì0KSXíí9Y"3# ü)þñ™¬/Ïþ/ßZƒ·ÔÄ991ÔÌ0!!P !ýöƒ¤bš//@:nÔäÀ91/ì0KSXííY"3#žü<ü/þÑÿB#Õ@ :QÔÄìÀ1ôÄ0KSXY"3T¿üª¾“ùmbÿãoð /Â@ c'cae0$ -0ÔìÄÔìÆ1äôìîÔÆ0@’////////// / / OOOOOOOOOO O O  ŸŸŸŸŸŸŸŸŸŸ Ÿ Ÿ 0////////// / / ÀÀÀÀÀÀÀÀÀÀ À À ]]4632#"&#"&47>32267654&#"áP77ON87PŽsTTߔürUUݓþý‹P‰/E]bkPŠ0F\gî7PP78NOE¿þEŠˆöÀ·†öûg`Œ°š‹f_‹þ_½Š{ÓÕ T@* :ccQc   ÔÔÄÀ99991/ì2ôìÔì0KSXíí2Y"7!7%3!!œ9Ýþ #`Ëþþ5!üɪuL¸JúÕªfð^@1: q cacÔÔì99991/ì2ôìôÄ9990KSXí9íY"%!!7754&#"76632 ¬ ün!7'€r\Ô~)pÑa¹äGR!¬´ªªª#×Ë]jCDÌ12›`­g*ž›ÿîÿãNð(J@+c W q cW qc#ae) )  & )ÔÔìÔì991Ääôìôìîöîî90!"&'732654&##732654&#"76632úr€þ±þèlÍ^&[¾b¶àŠ™ šžº{RÂq%{ÂT¼Ø³¤~êþä%%É45»•uy¦–|d_((º!°˜™Ï?Õ s@>      : cQ     ÔÜÄÀ991/äÔ<ì290KSXííííííY"!33##!7JýÙœé¾ÆÇFÆEý†$ýÍü3¤þœd¿ÿãTÕ j@8  : cWbccQe!   !ÔÔìÀ9991ÄäôìîöîþÄ90KSXíí9Y"!!6632#"&'732654&#"`ô!ýÅH/Y,¼æi`Xãl»H)T°^ºô¡ŽO¥KÕªþ‘ã¹|êVPP!Í32ꮀ’(&\ÿãhð *;@ ccr W bc(ae+ "+ÔìÔìÀÀ91äôìôìõÆîî04&#"32&&#"6632#"&5476$32\tk’Æzk $:ˆKÁû7D»q²ÁPDNÇzËÝNDb1ÏKŽRqzü¾y‰ 'º%'þáþåfiǸwîSa`êצf’××®¼Õ5@:cQÔÄÌ91/ôì0KSXííY"!#!¨üÛÙ ý<Õ^ú‰+)ÿãfð #/?@" c* c$cae*t0 '-!0ÔÄìÔìÔìî991ìäôìîî9904&#"326&&5432#"&546"32654&5„vŽ·†p”µþykl(ֲߠ~€þÐíÏíÑɤuf{¨xÍt„Åši~¸â&‘i¶¶ã)¦…Ñþï̳¦ì`¡|cr®}[l?ÿãLð *3@cr c( ca(e+"+ÔìÔì91äôìîÖÆõÆî032654&#"732#"&54676632#"&Jtk’ÆxkÄþõ#:ˆKÁû7D»q²ÁPCNÈzËßNDbþÎÐKŒqzü¾zˆþôûÙº%'fiȹvíS`aëÖ¦þš’ÖØX#%O@):nunÔäôäÀ91/ìôì0KSXííííY"3#3#'ü<ûYü;ü%þÑþ9þÑËþá#' Z@.   :nonu   ÔÄäÔäÀ991äüìî0KSXíí9ííY"3#3#“ü)þþ™Ÿ½ü<û/ÏþÇþÑXyw!@wvüì291ôì90 5yü®Rûß!ÁþÀþ÷¢¦¢X`y¢@ llÔ<Ä21ÔìÔì0!!!!X!ûß!ûß ¬BªXyw!@wvü<ì91ôì9055X!ûßRÁ¶þ^¦þ^·=F`ð!@H !!!:c caS  ! !"ÄÔäÖî9991/îöþÔîÅ9990KSXííí9íY"#766776654&#"766323#`¾MqkUGpcOÅi$mÊe™Áa‚iT<öË1Í‘š[‚^[Ho8JRGB¼98£~^¡lVFfVþòþÿãþþu @o@5.1*@ xx -*x1!x1:A@= -. ='=4AÔÄüÄîî9991ÔÄüÄþÄÕÄîî999990@ ””––]2654&#"#7#"&54327>54&#"3267# 476$32Å}®eX{¬c´3ŽQƒ¦¶T’‚Žþù_TXá9xC-BŽSþàþ¥|n&Ÿ½à Ó˜`nÑ—ap}o?D¸‘Ü9H=+#4~Œœ}þÕþÿþÚƒ{=É‘ƒŽÑ°M/ÿ–Õ v@B      :cyQ    ÔÄ91/<äôì90KSXííííííííY"!3#!#ßþ”®¢ö¦É#ýø¸Ù-üú®ú+…þ{Õ u@@       :c cQc z   !ÔäÔìÔì9991/ììôìî90KSXí9í9ííY"32654&#32654&#%!2!!mkø¸Ãˆ{Xô—­o}þb»Ëиœ}…þÁþÝþ<ÉýÝ®¤kffþ>‘^T¦ŸššÏž|êþüsÿã¼ð2@|{c|{c ae  ÔÄì9991äôìôìîöî0%#"5476$32&&#"3267°T«[æýŒrk¥PžK)@ŽP_¢Ghœ“UµX5)) ðܰ‰‚|*(Ï?>QS{þ€Á­¸@=ÿøjÕ P@(   : c Qc   ÔäÔì99991/ìôì0KSXí9í9Y"%267654&## !!D¹àD6E¤ÁrâgTGhþÉþ÷þÑ#¦}s?…°˜ûw/øü¢þ¨…¿£Õ5ÍÕ X@0    :ccQcz   ÔäÄ991/ììôìî0KSXííííY"!!!!!!Xu!ýTV ýrh¾!üwÕªþFªýãª\îÕ S@,    :ccQz  ÔäÄ991/ìôìî0KSXííííY"!!!!#o!ý\Vd ý›‹ËÕªþHªý7Nÿã˜ð)a@3&))#$"%):%&"&c("c|{cae*('&%)*ÔìÔÄ9991äôìôìþÔî990KSXí9íY"%#"54676676$32&&#"3267#7!ÉWÎuèù! #^8k¦PŸM)AQb¬D,N"#ž‘Dl%LÙš`>? ùZËou½C‚|*(Ï?>SQ4œarÈQ«º%#‰¦ÿøÙÕ {@B     :czQ   ÔäÔä9991/<ä2üì0KSXííííííííY"3!3#!#Êv)vËþÝÊ‹ýÕ‰ËÕýœdú+Çý99˜Õ ?@"  : cQc   ÔÄ91/ì2ôì20KSXííY"!!!!7!!Z>!þÆß:!üÂ!9àþÆÕªûªªÿçÿãNÕU@.  : {cc Qe  ÔÌ991äôìîöÆ990KSXí9íY"'73267!7!#"&-H¸gŽ(¤þƒ!HÅ8ðîaÈ=ìOS’ÎDªüþßã.ÿøJÕ j@;      :}   ÔäÌ991/<ì290KSXííííííY"33##ÊæþýA¬Ûþ˜ÁpËÕýy‡ý•ü–å¨ýÃN Õ8@:cQÔäÄ9991/äì0KSXííY"3!!qÊþþÑ!üeÕúÕªÿÅ Õ ´@D     : }   ÔäÜä99991/<ì2Ä90KSXííííÉÉÉÉY"²]@&  ]]!!# ##å nžþݺþNsÿºÕý ôú+/üåúÑÿú×Õ …@<  :}  ÔäÔä9991/<ì2990KSXííííííY"²]@  )]!3!#ïÃþÝÿþøðÂÕû3Íú+Íû3Rÿãð)!@c c'ae**ÔìÔì1äôìî0%267654&#"#"&4676676632öU/J\inUŽ/L\i÷-+C'XÚ‘ÉÂ++C'XÚ‘ÊÇf_‘œ¾Ž‡f_“þh¾ˆunþþˆ\’;yöoÿˆ\’;yõ3´Õh@6    :cc Q   ÔäÔì99991/ôìÔì0KSXí9í9í9íY"32654&#%!2!##mê¥Å|‚þm¸ÎØþÀþèéuË/ýÏ¿Ÿlg¦¸®ùþâý¨Rþòð-3@c%c ae.+"+.ÔìÔì991Ääôìî990#"&4676676632267654&#"ø ×Å++C'XÚ‘ÊÃ@%6ŒOšš¼U/J\inUŽ/L\iîoÿˆ\’;yõÿSÅot¬C_ˆ!¼\•f_‘œ¾Ž‡f_“þh¾ˆ Õ™@R       :c c Q      ÔäÔì9999991/<ôìÔì9990KSXí9í9íííí9Y"#&&###!232654&#þHW6yÉj,mnÀ{Ë! ÏãÏþ)fÛ£Ã~ˆÁj±þhyœbý‰Õ³£·ðWýpiÿã{ð'³@:    : |qc|qc%ae(  "(ÔìÔìÀÀ99991äôìôìîöî90KSXí9í9Y"²8]@<'''))))777  (((%%%%88VVVV]].#"!"&'732654&/.54!2{'Q®]¥Ðby£—þ´þáhÉd)bÉp¥ÎX…e¸“J Pµ¢Í;<¤GX('2§ëþí--ÑEB°‡RZ)!:“yÝ( 5Õ@@:cQÔôÔÄ99991/ôì20KSXííY"!!#!Át!þ+ÿÌþ+ÕªúÕ+PÿãÏÕ~@K   : ceQÔìÀÀ991ä2ôì90KSXíí9í9íY"332676673#"&546s²Ë³mnY|--²Ë²*_NG¶jÀÏ=˜üh š;\\9>—‰˜ühÛÍ?8;´¦%~Ç+ÕJ@':}ÔÄ91/ì290KSXííííY"%3!3þV×ý1þþ“ƾú+ÕR`Õ ç@J        : }    ÔÄ91/<ü<Ä90KSXííííííííY"² ]@\  ;u Ÿ Ÿ      )%& 86736 FFCE ZVTU kfch e zvvy u „‰ ƒ “™ ” %]]333##‘¿ZIÓyÆþÂþ¼ÕûF üÞ¼ú+füšÿ9Õ ~@H      : }    ÔÌ91/<ì290KSXííííííííY"33##òÈà¸çý¬DÉþþç‘Õýìý1üúdýœÃDÕf@5:} ÔÄÄÄ9991/ì290KSXííííííY"33#ÃÊìñÚý…σÕýu‹üÉýbžÿúúÕ 9@:cQc   ÔÄ91/ìôì0KSXííY"!!!7!1Éü-"ü Ðý)Õšûoªš‘þòG@":~~gÔÄÔÔÄÆ991üìôì0KSXííY"!#3!m§ðþÕðþVùüdÿBÕÕ0@:QÔÄÀ91ôÄ0KSXííY"#3ժǪ¾““þò C@ :~~gÔÄÔÔÔÄ991üìôì0KSXííY"!73#7 þ›þXð+ðøÞH¨‰Õ@ QÔÌ91ôÌ290##ÁȲþ‘þ’²ÈÕýÓ‹þu-þþmµ€/Ì1Ôì0!5üþmPPÅîPf2@ ‚ÔÌ91ôì0K° TK°T[X½ÿÀ@878Y#‹ÅüfþˆxHÿã?{ .ð@a! "   : % ‰ ‡&W%ˆ"‡)†e,% &,/ÔìÔì99991/Ääôüôìîî99990KSXíí9í9í9í9í9Y"² ']@65$0%0&5'         ¥   ¦¦¦¦¦¦ ¦ ¨¦¦¯' ]]"326?#7#"&54$!37>54&#"7>32´wt+DRgX”×&Ç}¸ HÄn™·5ö ~uVÇo#lÂYºÏ 3{IScÔ¹)Lý¦^e§ŠÄë= U[33´''¤‘ h;ÿãT%Ž@L$#  $#"$# !#$#$#%$$#:! ‡‡e†$‹""#%!#$ $#&ÔäÔì999991/ìäôìî990KSXíí9í9íí9í9Y"%2676654&#"6632#"&'#3Tˆ.19eeS‰30:k>¤f¤¶RHLÛ|b…"¹/¹ZV^èl€€\XVéo{…RTVϺ‘þàlsVTœÿãq{4@WZWZ‡‡ †e   ÔÄì9991äôìþôîõî0%#"&5476632&&#"3267¬I§Zàæk[]ß…Y¦O%BŒUnª<8?‰ˆ`±S3')áÜ•bcb++¶:6YYRÓh‘>?wÿãå%Ž@L  $%#: ‡# ‡e#†‹ &ÔìÔä999991/ìäôìî990KSXí9ííí9í9í9Y""32676654&3#7#"&5476632®X†.16feU‰018mªs¸þѸA¥d£µPEKË|a’ßWWZås€€ZXWçrx†CùìTVÒ¼!lvxWbÿãf} &\@"‰ W&Y#‡ Œ‡† e'  &  'ÔìÔì99991äôìäþôîî0@h hooooo ooooo ]]>54&#"#"&547>32!3267ª‚t{Ë,uiÈgßèxjSÉmºß üÙš“XÑr“#x†´˜ý¦++ßÖœ,mVZå¿"eN 4‹’98Ýj@9     : ‰‡‹      ÔÄä999991/ä2üìî2990KSXííííY"#"!!#!7!7663ÝÐ_`þ¿¸¾þÕ)&Á»™Secü/ÑNÁ¥;þHy{.¦@[ ... ..-.)*+(,..: , W‡ ‡ ‡)† Ž-/-,. .#/ÔÄì9991ääÄôìîîÕî99990KSXí9íí9í9í9í9Y"%2676654&#"#"&'732677#"&547663273O….17pdšÓr5þõ÷RŸK%IP•¤%:®nš¶PHJÐoe˜"¸‘ZTZàjw…þ¯ÿw‡Iþññ¶,. ºuW[׸‹jp|aU—TH’@R    :  ‡†‹ ÔäÔì99991/<ìôì990KSXíí9í9ííí9Y"#67654&#"#366323‡¸‡]W²!{¸/¸tK¯b‹š ¶ýJ· G'QWº¨ý‡ý¤ab‘‚ ^=ì h@7   : ‰‰     ÔäÔÔÄ99991/ìì2ôìî0KSXííííY"!!!7!!3#f×¾münm¡þâ¸-¸`ü/BCéþVÛ r@@  :  ‡‰Ž   ÔÄä91ìäôìîî990KSXí9íííY"!7!##73263#òÀþÃöÝ)ʵþé_nJ¸-¸åûŒÕÁœw«éZ´ {@:!!     :‹   ÔäÌ991/<ìä90KSXííííííY"²w]·v}p]]33 ##‰¿ª%ñýøuÕþͨX¿ü–¶þZýFF…þ?7Ñ]@/:‰‰    ÔÄÀÀÀ99999991/ìüì990KSXíí9Y"33#"&5467!7!XY[ÓÏ­© ÓþÄô˜#6IHœƒP.óÿòš{+Ô@e    $%"%#""%:!  &$ ‡)†$" $"%  &!"% # %" ,ÔÄìÔäî.999999999991/<<æö<î299990KSXíííí9íí9Y"K° TX½,ÿÀ,,@878Y>32#>54&#"#>54&#"#3>32ì'}MVg¨}.3KT+}¨}/1JQ-}¨Ù¨,o@K\îDIm\6ˆkýw\u?8ßýaq=:wéý``žþÂý 3B5“ovD/`>}ÿåm`‘@Q     :  ‡e   ÔìÔä99991/ä2ôì990KSXíí9íí9í9íY"332673#7#"&546…¹‡]U°!{¹Ú¸!I²iƒ˜ ª¶ýJ%DOU¹©yû ¨ba“~']¶¾`J@'!!!!:ÔÌ91/ä290KSXííííY"33#¶²šöÆýšî`üD¼û \#` ñ@J      !!! ! :     ÔÌ91/<ô<Ä90KSXííííííííY"² ]@f   * J ‡ ’Ÿ Ÿ ¦¯ ¯    *$ :4 GCD ZZ T kfh c yxy u ƒ‰ € ™—“¨£¨   !]]333##\° ¢1j¿þ¥<þצ`üwBý¾‰û oý‘ÿº¸` ~@H!! ! !  !  !!!:    ÔÌ91/<ä290KSXííííííííY" ##3¸þ>Åôþ_â4þÛÄÙq`ýÝýüþDT þu‹ÿÙþVÉ`~@F!  !!!!!:  ‡Ž   ÔÌ991ä2ôì9990KSXííííí9íY"##73267733>g›6:•`”lQu<+Ù·¬ãÍhkµþíILJš]qTNü¢^Nm` 7@!!:‰‰  ÔÌ91/ìôì0KSXííY"!!!7!?.!üïuü»!ý¤`¨üÛ“¨%¸þ²˜4°@f -.-..-    : 5'- )'.)~‘)~'‘~g5)(54.  $-5ÄÀÀÀÀ9991üìüüüì99999990KSXí9í9í9í9Y"#"33#"&5467767654&##732677667663˜Nˆ^3!xoIP/VaNH»£- bq>=‘~2H6/Š…O–ü ‘gK@&ô!3?9m{D%ì 2-UK“n–ô{'"þ¾·’Ôì1üÌ0#¾¬øÿòþ²Ñ4­@e -.-..-    :-5)  )'.)~‘'~)‘~g54.  5)('*(5Ä.ÀÀÀ991üìüüüì99999990KSXí9í9í9í9Y"732677667&&546776654&##73233#"#Nˆ^3!xpJP/UbMJ¼¢- bp>= /H6/Š„þ²O–ü ‘fLA&ó"3@9l{ D%ì 1-VJ“n–ô|Ž'"Xìy &@ ll üÄ1Ôü<Ôì2990#"'&'&&#"56632326yKOZq Mg3OIN’S5dJ t]F‰ ®;73 !;?®<6 7=ÿÿÿ–LN'$3uÿ–m !”@Q   !! !!  !:  c “ [ y   " ""!"ÔÄÔìÔî99991/<ææÖîî9990KSXííííííííY"4&#"326!&&54632#!#œY?@WW@?Y½þ”®É33Ÿsr¡PFšÉ#ýø¸ÙZ?YWA?XXîüú`#kEr¡¡rQ ú–…þ{ÿÿsþu¼ð'&Ýhÿÿ5Ík'(`uÿÿÿú×^'1/uÿÿRÿãN'2+uÿÿPÿãÏN'87uÿÿHÿãjf'DÿÿHÿã?f'DCÿÿHÿã?f'D×ÿÿHÿã?'DŽÿÿHÿãZ7'DØÿÿHÿã?N'DÜÿÿœþuq{'FÝwÿÿbÿãff'Hÿÿbÿãff'HCÿÿbÿãff'H×ÿÿbÿãf'HŽÿÿ=If'Öÿãÿÿ=ìf'ÖCÿãÿÿ=ìf'Ö×ÿãÿÿ='ÖŽÿãÿÿTV7'QØÿÿuÿãff'RÿÿuÿãZf'RCÿÿuÿãZf'R×ÿÿuÿãZ'RŽÿÿuÿãZ7'RØÿÿ}ÿåmf'Xÿüÿÿ}ÿåmf'XCÿüÿÿ}ÿåmf'X×ÿüÿÿ}ÿåm'XŽÿüÃÿ;oÕ \@0:‡ Q”   ÔäÀ99991äôÔ<ì20KSXííííY"3!!#!7!¢°Roþ‘Ù®ÙþoÕþ\™û£]™+u¦ð @• –•a#$# Ôìüì1ôìüì02#"&546"32654&hAu,-/º†‡´¸…OomOPqpð1.-rB„·´‡†ºoPPlnNOp{þÇ?˜$V@3WY WY‡ ‡† e %  "" %ÔìÀÀÀ91Ää2ô<Äìþôîõî990&&'667#&&5476673? 1{HªA‹K!K‰?7f7·Ì¢F›V8f7<}þ¨¥åu5¬&,üš-(¬!þâòúD`16þá"ü+`þ·á‚™ÿøÍð@F  : ‰ Wq‡a c  ÔÔÔÔÄÀ9991/ì2ôìôìÔ<î2990KSXííí9íY"&&#"!!!!73#737$32Í%6y?‹š&+rþZ ü3!íZÆÇ/3ä<‚¶¸+-ªÉÙþ/ªªÑîôdÿ7-ç4Bv@E$%B<;5& %, X—˜X—˜2aC$%5 "<%&,/B;"%/"%8%/?%)CÔìÄÔìÔìîÀÀ999991Äôìôìîöî9990&&#"#"&'732654/&&5467&&546326654&''-!G‰:g„†V|U„r))óÇF™S!J=p…· J}P€v)%ðºG“þÄTXk“PRVU~®¤&(bHOZ ;VuEe´5#Z7Ä¡$'^Nb| 3UoI`¬?%P5•ÃûÆ3o75p^34p73`S?Ñ‘! · ™ & Ôì1Ôä04632#"&?¬}|­®}|«ú|«¬{|­«}ÿ;uÕ g@0  :Q  ÔÔÄÔÄÀ99991Ä2ôÌ90KSXÉÉÉÉ9Y"!###&&54ß–þ¸‹/¿þѤ±ÌZÕùfùáN¾¡Ñ7ÿãf5©@[#$# $$#45512035:3*$ #0W‡0‡‹e445$'# 35'*-  '' '-56ÔÔÄüÄîî999999991/äþîþÕî990KSXí9íí9í9Y"6632#"&'732654&''&&54676654&#"#*ï˰¾ ®É)<3sQþýÞG†A;…Gƒ—6U=Z8˲h\yŽÛ»qÔÏ •!F$‡`&=,'U…W·×¤ !}l4R?/D\?ƒÀ$OY‡‰û“}ÑN4L…@I  . . :     ŸA)ž5)œšM  -- ,G(#);(#*//æþåþõÄîî299991ôìüäþí2îÖî9990KSXíí9Y"2#'&&####32654&2#"&'&&546766"32676654&'&&X“XP:&rk1=-7‚èffZJJDÚZZ\[[[Ú~}Ú[[[\ZZÚ~jµKKMMKLµijµLLKLKKµLbeG]C;º®P*þضTè6?>5VZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZgJKK¸jh·KLLLLLµij¸KKJ}ÑN1ID@' £ £¥&>££¢>œ2šJ- /,(8 (8*D/æþÅþå2î1ôìüôìÔìþýîÖî0&&#"3267#"&54632'"32676654&'&&'2#"&'&&546766`:o:u‡Œ‚8g24r=´Ïг=rÄjµKKMMKLµijµLLKLKKµkÚZZ\[[[Ú~}Ú[[[\ZZÚ/l•€„ŽhȬ­Ê¡JKK¸jh·KLLLLLµij¸KKJgZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZ“fÕh@6    :    Q  1 1010/üþìÕîÖî91ô<<ì2Ô<<Ä90KSXÉÉÉÉY"###5!3###¶¢r¢´‰}¬rœ7¦qÕ^þä^ÿý¾âþÓ-þB?îff/·‚ÔÌ1ôì0K° TK°T[X½ÿÀ@878Y3#‹Ûþuœfþˆ´F-n@¦ÔÜÔÌ99991Ô<ì20@@@@@PPPP]K° TX½@ÿÀ878YK° TX½@ÿÀ878Y3#%3#ÛË'Ë®Ë'ËÊÊÊX%yÝ<@ l  l  Ô<Ä291Ô<Ä2ü<Äþ<Ä990!3!!!'7#5!7!X‡ö}¤Ëþ²¸ýyø}¤ÉJ¸ýþ¢;fÕªì¬þÅhÓ¬ìÿoÕ‰@P   :c ccQc§z  ÔÌ91/<ìììôì2îî0KSXííííííííY"!!!!!!#!!þ®V3!þÍjd!ýâKþ °¸¼\þœ5–ÕªþFªýãªþÕªüüÿº° 8o@;)9$863 '$*73(c$c3a$e9)9(*-7  '-6 8 -9ÔìÔìÀ999999991äôìîÀÀ99999990%3267654&'&&#"#"&''7&&54766327B^Bp¡=26ýyf[8q¡<2:$iSXðžQ‡6^cwhTXïŸMƒ6Tdå,2¤®‘'{#ý)u'+¤®”þÏl ¨<[ÄþZ”š—..…@ª:VÆ¥•™–++}@)ú¨ð /7@$ ª'!« ª-¨0 $22*0ÔìÔì99991ü<ì2ü<ì299032654&#"&&#"32676632#"&'#"&54632¶9[=G[TFBiË8\=G[SDCj~/“[w¬£~S€NA„U}¦„^ˆsˆd†lk€ut†c…jmvÿuÛ §Ôdƒ|kÖ¥­ÎsXy“.@ ¬ l¬ l   Ô<ì2ü<ì21/ìÔ<ìü<ì07!!!!#!5!X!ûßd½þC¨þD¼ªª“þ·ªþ´LªIVw? (@®­l  ü<ì2291/ìôì905!5wûß!üß!ûß¶¶L¨K¸çþ ªªXy? (@®­l  ü<<ì291/ìôì90%%5!!X#üÝ!ûß!ûß¶êç¸þµ¨þ´Vª/øÕ¢@]  : ° °  Q    ÔÄÀ9991/ä2Ô<ì2Ô<ì290KSXííííííííY"!#!7!7'!73333!! þwbÇbþs7þËöÍÏßËÓþlüþÈn ‰ ýô o#—o1ýh˜ýÏo—#ÿÙþV‡`&§@\   &#$"% :%   ‡c"e Ž'&'  %'ÔäÀÀ9991ää2ô<ìì99999990KSXíí9í9íí9íY"3326733267#"&5#"&''-»ˆmf‰¤!º¨ (J!CO5‹b\| mþV ýH6[a¦ªü¢  ”UIRLSSý;ÿç-)6@'! '!Ô* $$*ÔÌÜÌ9991äÌÜÌÎÎ9906654&#"#"&54632#"&54324&#"32JIH7$$0e´ÖþßÕ˜ËÝ¢e‚ WOmVPmmW£Kƒt,>bþÊþùþ±þFØ£Æ[àt}þþÏt{þL=î -@  Ö ÖÕ×  Ô<Ä91äôìî990!!55!!LñüR%ýÛšý# þÕ‰\—P_ŒüݘþL9î@ ÖLLÔìÔì1Ä2Ôì0!#!˜¡›ý•þL¢ø^øâPÿÙžL?@!  ³³±µ 5443ôìÔìäÄ91/äôì22î99990!#3267#"&5!##P117,#J%q\þT´L”ý@H?… ƒ°¬üH¸þL%&@ Ù ÙÚØ& MNM&Ôìüì1üìÜäÞä026732#"&'&&#"#"&54632‰j ¾ÊPd@7*9  k½ÄOeD=!0 þú°l9¼TA6?&#Hý•Ánþ!þbSA8?TßÕ ð +/o@?  .¼,·#¹"¸·,º ¶·&a0 .- )/,0 #"6)60ÔìÔì9999991ôìôÄÄììôîîî9990"326?#7#"&5463347654&#"76632!!Ù”‹I@#ÁÀÂ<<=: ;=:7 ôìäôìäää991/<î2öî0353&5323!5654#"Jõ{n ðò!o{øþ1x†´šš³†x¬† ¼7oþ’þȼþß…¬¬LIÞæ þ÷æÞþ·L¬ÿÑÿã¾{ OP@…'O'OO'  ';:987<6'5':+ $!F@6?$O4‰%W$ˆ!‡(@W?ˆ<‡ŒIC†.(ePOL?965F$%+4@L'1PÔìÔÄÔÄ99999991ä2ô<ä2ü<ôìþôîì29999990KSXíí9í9í9íí9Y"@`>#>$>%0?0@Z#Z$Z%Z&ooollloooooj#j$j%j2o3o4o5oNoO{#{${%{&‹#‹$‹%‹&%9#9$9%2?2@I#I$I%I&j3 ]]7#"3267>54&#"!3267#"&'#"&546;7>54&#"7>32>32ç1}i##N;Ze=D;SjÕþaUF5";„Hj‹/]€˜ñàuUM1…L#OŠ8Rv2ŒPyºH'!b3Cšƒ'\/ÿ –¼ '1m@:'2"1( +%&"‡"+‡†"e2'2& 1(.%.  . 2ÔìÔìÀ999999991äôìîÀÀ99999990324&&&54766327#"&''&&#"ýêN4£ÜýPKQß“Nx.p]{ RJOâ“J{3w\%I4¤Û9ýW.ý`0€PŽnwu$$‰M’2€TŠþïmvv%%L¾þ¨þô'ÿåªÕ!@J !!!:S WY ce Q"  ! ! "ÔìÔÔä9991äôüôìþÅ9990KSXííí9íY"33267#"&54677667#73¿PojUGodOÄj%lËe˜Âb‚hT=öË1ËDš]ƒ]YHo8JRGB¼98£~^¡lVFfVþ…sÕ ^@/ :SQ ÔÄôäÀ99991/ôüÄ0KSXí9íííY"#73#3BË1ËþÝËX¢1×þú+eþ›Xsy^@ lüÔì1ÔÄì0!#!X!¨ü‡^þ?;ÿÙ   /@     ÔÄ991ÔÄÀÀ90'%3##d)#ÛÓ”/þöÝ}bý%¿ƒù¼9þV°#ˆ@NAA  A A:   ‰XÉXÉ!‹$  /Ì91Ä2Äüìôìîöîî299990KSXíí9í9íY"&&#"!!#"&'53267#5!6632°$R,fs-/þ¸d+Ǻ9f.1d0`yuü1Æ”1cð¤|‚þÉý…þöæ¤!–—¯J±ÉX1yÃ7K@&' 10+5  ll* l5'l.810*8Ô<Ä2991Ô<ìÔì2Ü<üÔ<ì99990#"'&'&&#"56632326#"'&'&&#"566323326yKOZq Mg3OIN’S5dK t]F‰JKOZq Sc1NJO’R`‚ t]DŠï;73 ";@®<7  6<þа;83 $77 7=ÿúÙO@*BBBB:ÂÄÔÌ91/äì90KSXííííY"#3 !ÑýþáúqÃûéJR# 3@  Åu  CC ÔüÔì991ô<ì299077R+þ¢ú#þ}R+þ¢ú#þ}#Óþøþõ°¢R¢Óþøþõ°¢RRZ# 3@ Å u   CCÔüÔì991ô<ì299077777R+^ú#ƒT+^ú#ƒÓ °þ^Rþ^Ó °þ^Rÿ¾)/ w@<    :n    ÄÔäÔäæÀ999991/<<î220KSXííííííY"3#3#3#ü<üoü;üþ¡ü;ü/þÑ/þÑ/þÑÿÿÿ–k'$3uÿÿÿ–…^'$3uÿÿRÿã^'2+u#HÕ"b@7!"!"!"!""!:c c Q c"!    #ÔìÀÀÀ91/Äì2ôì2î0KSXííííY"%!"&5476$3!!!!"33P!ý¤ÚÖB5VñR!þšWH!þ¹k!v¦/1}{>᪪ÍÑ’lçêþFªýãlm7´~j¦=xzÿúÿãø{,8PÃ@\-'@?6758'@@?  '@? '?@?:8/-59 - E5-‰ Wˆ‡ Œ5‡*†eQB8/.- N N2'N'!QÔìÔì999991ä2ô<ìäþôîî99999990KSXíí9í9íY"²o.]@oo o o jjo-i/o8 ]>32!3267#"&'#"&5467>7>32!7>54&#"267>7>54&#"ß:‡PzŽþ aUF6#;„G_ˆ":Q™;'8´uP|4IB=Skþ7<`(HCA_(Jü?@˜…+ƒTZ[nNX:2¬)+E@AD¦œ6†Ny»GfkDþVL8GN€€ýœGB,•jl‡ MTEF5”`V’$QWÿÍìºy@ ‰ÆÔÄ991üì0!!Ñû/yÿÍìºy@ ‰ÔÄ991Ôì0!!Ñû/yöÇ‘ e@3     :o g     ÔäÄÔÄä991ü<ì20KSXíí9íí9Y"#73#73¼û&™¬þ ü'š®ÇÏ~þ‚ÏÏ~þ‚ÝÇy _@0     : og     ÔäÄÔÄäÀ91ü<ì20KSXíí9íí9Y"3#%3#²ü)þòš¬ôü)þòš¬ÎþÎÎþÏÇ 9@:ogÔÄä91üì0KSXíí9Y"#73Ëü)š¬ÇÏ~þ‚ÏÇ 5@:ogÔÄäÀ1üì0KSXíí9Y"3#¤ü)þñ™¬ÎþX–yo '@ÇÇl D Ô<Äü<Ä1ÔÄüÔìî03#3#!!îõõõõþj!ûß‹õÙö¢ªuþ#\u"@ÔÌ91ÔÌ990 hþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿÿÙþVÉ'\ŽÿÿÃDN'<9uÿB#Õ@ :QÔÄìÀ1ôÄ0KSXY"3T¿üª¾“ùmÍÃLB /}@B (-  * -'! ÈÉÈ) -0)$ !'$* EFE( $0ÔÄ2ìüÄ2ì9999999991ÔÄ2ìüÄ2ì99999999904&#"3267'#"&''7&&5467'76632d|[Z}}Z[|¦Z¦¨^¦.[20`0¤\¦¨^¦.[3.^ƒZ{{Z\}~t¦]¦1]02[-¦^§£Z¦3].2]-¦_¨5m#@ÅuCÔì91ôì907m+þ¡ø!þ{#Óþøþõ°¢R=s#@ÅuCÔì91ôì90%77=+_ú#ƒÓ °þ^Rbç±@`   : ‰ ‡‹      ÄÔÄÔÄ2ÆÀ999991/<æ2þ<îîî2990KSXííí9íííííY"3#'#"!#!##737663/¸-¸Jµ__•Û¸¾þ%¾¸¾ÉÇ&Á»éé™Secû Ñü/ÑNÁ¥bç‰@K   : ‰ ‡‹    ÔÄÜÄ99991/<ä2üìî2990KSXííí9íííY"!#!"!!##73766øïþѸþÓ__)þÙ¾¸¾ÉÇ&Áùì{Secü/ÑNÁ¥;ÿ;oÕ‰@L       :‡ ‡ ” Q   ÔÄÀ9991äôÄ2Ä2î2î20KSXííííííY"%!#!7!!7!3!!!Éþ‘R®Pþ‘ojþoR°Roþ‘hnßþ\¤š™¤þ\™ýáÇ/þ`/@:nÔäÀ91Ôì0KSXííY"3#þ;ü`þÏËþáœ/5@:onÔÄäÀ1üì0KSXíí9Y"3# ü)þñ™¬/Ïþÿðþá‹/ _@0     : on     ÔäÄÔÄäÀ91ü<ì20KSXíí9íí9Y"3#%3#Åü'þóü'þðš¬/ÏþÏÏþј'3?Km@<%1= ÊÊ1Ë%Ê+\CË7ÊIF:4(:"FG4"@ "G""".G"@(/ÄìÄôìîöîîöî99991/<î2î2öîþîî299990'32654&#"4632#"&32654&#"4632#"&32654&#"4632#"&H%'üH_EDbcCE_y¥xx¦§wy¤LaEEacCEay¦yx¦¦xy¦ aEF`bDEay¦yx§§xy¦7aŸ`ýJGacECcaEy¥¦xy¨¦ÓEaaECcaEx§§xy¨§ý"GaaGCcaEx¦¦xy¨§ÿÿÿ–3m'$3uÿÿ5Ím'(`uÿÿÿ–Ek'$3uÿÿ5ÍN'(`uÿÿ5Ík'(`uÿÿ9˜k',9uÿÿ9˜m',9uÿÿ9˜N',9uÿÿ9˜k',9uÿÿRÿãk'2+uÿÿRÿãm'2+uÿÿRÿãk'2+uÿÿPÿãÏk'87uÿÿPÿãÏm'87uÿÿPÿãÏk'87u=ì` C@":‰‰   ÔÔÄ991/ì2ôì0KSXííY"!!!7!!f×¾münm¡þâ`ü/BîfR@‚ÔÌ91ôì290K° TK°T[X½ÿÀ@878YK° TX½@ÿÀ878Y3#'#Í“¤…uáœfþˆññ‘V7Ñ@!  ““ ÔÌ91Ô<üÔì99990K° TK° T[X½ÿÀ@878Y@=     ]K° TK° T[X½@ÿÀ878Y@           ]'.#"#>3232673#"&å/#*/}rY+D&/ )1}qY,B`1KNˆ’&/NM‰“¸b+ö@ ÌÔÄ991Ôì0!!ÕVýªö”Õ)JHn@Ì H HÔìÜì91Ô<Ôì90K° TX½ÿÀ@878Y@   ]K° TX½@ÿÀ878Y332673#"&546ØxWUPjw ³‹†‘HADJL’€vwDm;@ ¦ÍÔÌ991ôì0K° TX½@ÿÀ878Y@ @@PP]3# Í)ÍÌø)N h@“Î “" I"Ôìüì1Ôìüì0K° TK° T[K° T[X½@ÿÀ878YK°TK°T[K°T[K°T[X½@ÿÀ878Y4&#"3267#"&54632¢X@@WW@@X{ ssŸŸss ;@XWA@WX?sŸŸstŸŸ¶þus&@  “  ÔÔÜÄ991/ÔüÄ90!#"&'732654&'+%#w,^/(I CK@]$]m<6N6¸îÉfe@ ‚ÔÜÔÌ1ô<ì20K°TK° T[X½ÿÀ@878Y@)////2222BBBBVSUU]3#3#°½þÒ‡LÅþ¼‡fþˆxþˆçþuX"@  “  ÔÄÌ9991/ÔüÄ90!33267#"&546w=@/-!B "G"alK:e&%&… PG7x×îNf:@‚ÔÌ91ô<ì90K° TK°T[X½ÿÀ@878Y#373“¤ƒwáœîxóóÿãÓ e@8    : Qc     ÔäÄ.99991/ìä90KSXííííY"3%!!'%sÊr)IþqqÑ üdq–JÓý°ÑdþéýϨ3hd´XZ€@K:‰‰   ÔÄÀÀÀ99991/ìüì990KSXíííí9Y"33#"&5467'!7!%XY[ÓÏ­© ;þÇJ¨sþÄôs;JþX˜%6IHœƒ#O(Ûc$)ý×ÙbþÛÿÿÿã{m'69uÿÿsÿãNf'Vàÿÿÿúúm'=9uÿÿNmf']àþ¢¾˜@ ÏÏÔ<ì21ÔìÔì0##¾¬¬¬˜ý öüý öÿøjÕk@;  : ‰ cQc    ÔäÔì99991/Ä2ìôìî20KSXííííY"%267654&##!! !!#73D¹àD6E¤Ár[ þökgTGhþÉþ÷þщ{¦}s?…°˜þ+•ýá/øü¢þ¨…¿£Å•{wÿãj!0…@L:! %%‡+‡ e‹1( .(!. ( 1ÔìÔìÀ99991ìÄôìî99990KSXííí9íY"#"&54676632&&''%'3%&&#"324&f{qKFMãÁÌLGLç†0 5)þ×Õhÿ%P,³Ýsh§Ô/«þÖ—‹þÿhtx×Ë~ôio{&V:^\VÈ‘X\þ þÈýx„A@eÿÿÃDk'<9uÿÿÿÙþVÉf'\3‡Õ ‹@I   :c cQ   ÔäÔì999991/ôÔìÔìÀ0KSXíí9í9íí9í9Y"#32!32654&#FHË#Ë3ñÏÙþ¾þè`iê¤Æ|‚mþ“Õþî°§ìþï¶ý縘gbÿþþVh%Ž@M%$#" ! :‡‡e†Ž&& &ÄÔì.9991ìääôìî990KSXíí9í9íí9í9Y"%#36632#"&72676654&#"%o¸ƒ¸r=¬d¢²OFKÌzdèQ†-18gfU‰018pýÉÉý²RXлþànvzTHYU\çqZXXär{…X-y×¶lÔÄ1Ôì0!!X!ûßת–®;T .@     Ô<Ì91Ô<Ì2907–^þ¢t^_tþ¢\tþ£þ¤%\^uþ¢^uþ¢þ¤w^þ¢\œšß X@. JJ:Ð Ð ÑÐ`     ÔÄÀ991ôìäÔìî20KSXíí2Y"37733!qÎuçî‰Íý× c)t'ý+n3œßðj@5ÐÐ: ÐÐ ÐÑaKÔÔì9999991ôäìÔìî99990KSXí9í9Y"!!?$54&#"76632ì‹ýÓª!9J?3zST}5vˆþËrnŒýi3=%)o^‹ó×ð(H@*Ð Ð Ò ÐÐ ÒÐÑ#a)   KK& )ÔÔìÔì991ôäìôìÆîöîî90#"&'732654&##732654&#"76632HNЯB;Ch2p‚UYHHavVV*e<Gz7yƒr\ [Gƒžy\NC@jP@33sd[Otÿÿ/þòm{'ðþþœ'  ‰üVÿÿ/þòy{'ðþþœ' ñšüVÿÿ/þòmŒ'òÿœ'  ‰üVÿÿNÿã˜m'* 9uÿÿ;þHyH'JÚÿÿ9˜P', 9uÿÿþu{ð'6Ýÿÿsþu5{'VÝÿÿsÿãÀk'&®uÿÿœÿãÀf'FZÿÿsÿããm'&®uÿÿœÿã¨f'FàZwÿã‡-Ó@|  "! #+,-+,-*: °Ó‡+ ‡"e+†‹ %.ÔìÔäÀ999991/ìäôìîý<î2990KSXííí9íí9í9í9í9Y""32676654&!7!733##7#"&5476632®X†.16feU‰018mª>þ´I¸ÀÁú¸A¥d£µPEKË|a’ßWWZås€€ZXWçrx†5y••yúúTVÒ¼!lvxW/ßZƒ·ÔÄ991ÔÌ0!!P !ýöƒ¤Ç/þ`/@:nÔäÀ91Ôì0KSXííY"3#þ;ü`þÏÿöÿã¨ð-|@C$%°|{c!|{ c °'+a!e.'.-,+($$ &,$.ÔÄÄÄüÄÄ9999999991ääÔ<Ì2ì2îöîîöîî299032&&#"!!!!3267#"5#73667#7î]LèJ—H'FƒGŠßGÙ2þ8 ›/þˆ‘‡L«U'P VÝå¬1… ž1´!*(ÏA<ÓÅl+\4n6«·@=Ï*( -n;Y'l ÙŒ@¦ÔÜÔÌ99991Ô<ì20@OOOO____]K°TK°T[X½@ÿÀ878YK° TX½@ÿÀ878YK° TK°T[X½ÿÀ@878Y3#%3#NË'Ëþ Ì)ÊÙËËË?îö[µÔÄ1ÔÄ0@))**//]]K° TX½ÿÀ@878YK°TX½@ÿÀ878Y3#BÐþÍ öþø‡RéÐ@ “ “ÔÄ91Ô<üÔ<ì9990@z                       ]]K°TK°T[X½@ÿÀ878Y/&#"#>3232673#"&ã"*&"6}#|U">##$(8 } ~\79 32mn 6.mnôî=öY¶ÔÄ91ÔÄ0@//]]K°TX½@ÿÀ878YK° TX½ÿÀ@878Y#ª“‹¾öþø‡îø]@ ÔÄ91Ô<Ä90@/// ]K° TX½ÿÀ@878YK°TX½@ÿÀ878Y3#'#Õž…‹Ñ˜øþö²²ºî5øc@ ÔÄ91ÔÄ290@//// ]K° TX½ÿÀ@878YK°TX½@ÿÀ878Y#373-Õžˆ‹Ñ—î ²²/ømf@ ÔÌ991ÔÜÔÌ0'F#øllœªß t@> JJ J  J: ÐÑ`   ÔÜÄÀ991ôôÔ<ì290KSXííííÉÉY"33##7!7!ü¢iuw!‹#þ~Íþª ßýäo¸¸y}þyÃ5ø 3@  HHÔìÔì1ÔÜÄ20K°TX½@ÿÀ878Y332673#"&ÃrOKWky!¹€xø=68;qym`Û:@ ¦ÔÌ991Ôì0@ OO__]K°TX½@ÿÀ878Y3#–Ê'ÌÛÍ  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•ÑhÑÑÑsÑRÑÿúÑÑ!ÑÿìÑÑuÑ–ѦÑXÑËÑ/ÑbÑÑbÑ{ÑÑÿîÑÑÑ\Ñ®Ñ)Ñ?ÑXÑËÑXÑXÑXÑFÑÿãÑÿ–ÑÑsÑÿøÑ5Ñ\ÑNÑÿøÑ9ÑÿçÑÿøÑNÑÿÅÑÿúÑRÑ3ÑRÑ ÑÑ ÑPÑÇÑRÑÿÑÃÑÿúÑÑdÑ“ÑHÑÑÅÑHÑ;ÑœÑwÑbÑÑ;ÑTÑ=ÑÑZÑ7ÑÿòÑTÑuÑÿþÑbÑÙÑsÑÃÑ}ѶÑ\ÑÿºÑÿÙÑNѸÑÑÿòÑXÑÿ–Ñÿ–ÑsÑ5ÑÿúÑRÑPÑHÑHÑHÑHÑHÑHÑœÑbÑbÑbÑbÑ=Ñ=Ñ=Ñ=ÑTÑuÑuÑuÑuÑuÑ}Ñ}Ñ}Ñ}ÑÃÑ+Ñ{ÑÿøÑdÑ?Ñ}Ñ7ÑÑÑÑ?Ñ´ÑXÑÿoÑÑ)ÑXÑVÑXÑ/ÑÿÙѾÑјÑPÑÑßÑßÑJÑÿÑÑ/ÑÑ…ÑXÑ;ÑÑXÑÿúÑJÑRÑÿ¾ÑÑÿ–Ñÿ–ÑRÑ#ÑÿúÑÿÍÑÿÍÑöÑÝÑÏÑÏÑXÑuÑÿÙÑÃÑÑÍÑ5Ñ=ÑbÑbÑ;ÑÇÑËÑÿðÑÑÿ–Ñ5Ñÿ–Ñ5Ñ5Ñ9Ñ9Ñ9Ñ9ÑRÑRÑRÑPÑPÑPÑ=ÑёѸÑÕÑwÑøѶѸÑçÑ×ÑÿãÑXÑÑsÑÿúÑNÑÑÿøÑwÑÃÑÿÙÑ3ÑÿþÑXÑ–Ñ\Ñ3ÑÑ/Ñ/Ñ/ÑNÑ;Ñ9ÑÑsÑsÑœÑsÑœÑwÑ/ÑÇÑÿöÑ Ñ?чÑôчѺÑ/ÑÑÃÑmÿõÿ+   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ      sfthyphenperiodcenteredEuroc6459c6460c6461c6468c6470c6472c6477c6478c6475c6476""""g‰ít÷œ³á]‰µÍò½`„å}Ú\‚£Ç > Ø .   í C Š Ë = – Ñ  o tÈ!ƒ›ÐB{ j´ê"G~ µÝœkïZ´PÇvÑ"ÐF‰ ƒØ„é]•,Šï$Ëâ † Æ Ó!V!c!p!}!Š!—!¤!±!¾!Ë!Ø!å!ò!ÿ" ""&"3"@"M"Z"g"t""Ž"›"¨"µ"Â"Ï"Ü#%#`#Î$?$Ü$ü%O%ó&§'4'Ž'´'ÿ(A(±)E)§)Ý* *:*º+K+¦+Ø+ù,?,--b-µ.Ñ/[/Ó0070h0æ1_1œ1Ù22m2m2z2‡2”33Ú3õ44_4«4Ù5525\5i5v5”66@6c6é7W7Ã7è88`9999,999F9S9`9m9z9‡9”9¡9®9»9È::=:Ó:ì;A;l;Æ;ú0>Â>Ï>Ü?K?Ï?å@@b@ÁA!A2ACATAaAnA{AˆA•A¢A¯A¼AÉBzB’B·C=C—CÓDhD£DãE&EAEšEÎEø QK@¸îmþÑÿoÿJ‡ ÑGÌþBGÌSf   €¯ JBits ûþšmãBºÑ`#cÕVeraSansMonoObÿÿÿÿ6ÿÿþ628I00@             ÿÿª[_<õºÀòŽºÂb ÿoþ‡mloganalyzer-3.6.5/src/BitstreamVeraFonts/README.TXT0000644000175000017500000000050012225176641021236 0ustar danieldanielContained herin is the Bitstream Vera font family. The Copyright information is found in the COPYRIGHT.TXT file (along with being incoporated into the fonts themselves). The releases notes are found in the file "RELEASENOTES.TXT". We hope you enjoy Vera! Bitstream, Inc. The Gnome Project loganalyzer-3.6.5/src/BitstreamVeraFonts/VeraSe.ttf0000644000175000017500000016557012225176641021627 0ustar danieldanielOS/2¶XòeÕ\VPCLTyŽbhÕ´6cmap¤Ãè µˆXcvt 3«ô”fpgmç€ñÄ%ø‹gaspë4 glyf' ;è&„hdmx»Ã/CÕìHheadµ'šë@6hheaEoÕ8$hmtx1Åwó¸à0kernÏUÎ Á¼\locaã$Àà¿ maxp=;Õ nameÔµè€åpost´Z/±½Žprepuyö ˜^::a:: fN0¯n  … r t  (   _ (  (   i 0 9 ` û y 0§ & Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera SerifBitstreamVeraSerif-RomanRelease 1.10Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera SerifBitstreamVeraSerif-RomanRelease 1.10Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com s¸ËËÓLjq‡ å{ËËÁÙ¸Ó¸)j/¾s3¸åËf búÍÍÍšÍwPšP ¸;ÍÍfË=ºªfÍ–R××BsJ¼Ùƒ¤Õ}s ÕjjbÕÕÕð\jjjÕ j ¼Ë¤jj)R`fX{ªHj…j``'''Djb{sjÍ\)'ª\jjÍ ª=Íf×H×fé  ÁJJ }T{3š`}TjNN×s¸€@àÇþÆÅÄ$ÅdÅ@Ä$à ÂÁ'ÂdÁ'À]¿}¼ » º¹º2¹¸2·þ¶þµþ³þ²þ±°G±ú°G¯þ®}­þ¬«ª «ª ©2¨d§¤2£¢d£þ¢d¡–¡% x  %ŸKž.œˆœþ›š›š™˜™%˜x ˜˜@—–——€––@•%”„0”þ“’“%’‘ ’’¸@@ ‘ ‘ ‘¸@I Ào}»Ž ŽŽ@ :Œ‹»Œþ‹Š]‹»‹€Љ%Š]Š@‰ˆ‰%ˆ‡ˆˆ¸ÿÀ@ÿ‡…„0…d„0ƒ‚– €dd€þl~}~2}|{|{z–yx wv wúvuv utltsþrþqp qþp p@o}nm>nkm>lk ll€k k@jddjúih»iþhg]h»h€gf%g]g@f%eddeúddcbþaþ`_.`þ_.^þ]þ\K[}ZþYDXþWþV»UþSdRQ2POP}ONA@BL JdI"I–H2GGFE EDCDkCBCBA BA@ A @ @¸ÿÀ@S?–>->M=<=K<; <<@; :9:]98987 6þ545þ43432 321 2 2¸ÿÀ@ÿ1 0/0D/.//À. ..€- d-–,+,K+"++@* *d)(0)A(-(0'-'þ&:% %]$#$S#"##@"! !]   À € @#$0S-0þ þk@-»þB d–-þ    @ þ   @8k d } d2}-2- Sþ¸d…+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX °ÉEDY!-,°%E`D-,KSX°%°%EDY!!-,ED-fþ–f¤@ ÇÇ]/ÄÔì1ÔìÔì0!%!!füsüåþ–øòr)ÿã!Õ $@a ` b  ÄÔÄüÄî1äôüÄ0%4632#"&!#5L97NN79LD{h8NN87NM¥üËüüɪåÕ@ bÔÜÔÌ1ô<Ì20#!#hŸŸÕýÕ+ýÕ+ž¾W@6 cc       ôÌÄ991/<Ä22Ô<Ä22î22î220!!!3!!!!#!#!5!!5!þæT32!53!5>54&#"pkÙhéþÎ þ‡ouü=Å–€Šœq 9<âÂÛþÏ þ‡¸þ¤mÄ–ûŠ—ªŽœÿãð*M@+ etee)te&ei`+  #) #  +ôÄìÔìÔìî99991äôìüìÆîþîî906632!"&'332654&##532654&#"#Çu×^Ûöªœ¸Ëþçþøußnp ®ž™±¶°_2¯¯‡‡• p–,.½¨‡µ ׫Ñß23"”±š°µf‘’ƒ‹€~?°ðŸ@%d d M ss i  ôÔ<ÄÄü<Ä91/äü<Ô<ì290KSXííY"²/ ]¶ ]K° TK° T[K° T[K°T[X½ÿÀ@878Y@ 8I( 68 GH ]] !53!53!!3Ëþ¶ýXðýtŽÆþãðúüæþj%môü kþÛ®ÿãyÕ­@%xetee wb `     ôìÄÔìÄî91äôìÆîþîþä90K° TK° T[K°T[X½ ÿÀ @878YK°TK°T[X½ @ ÿÀ878Y@& //]]!>32!"&'332654&#"#ýT4‹VòþåÿgØqq £“žª©ŸZ‰5VÕ¤þT$$þôèíþ÷23"Ž–ÐÃÂÏ@Cî‰ÿã–ð %c@" eely#ei`&    &ôììôìôì1äôìüìîÖî90@%   ) ) NN N!]%2654&#">32#"!2#.#"ž˜˜–˜¹D¬lßþééýþðB%O®[q ‚n¾FÏÂÂÏȽÇÖðKJþôèãþïy^ˆ®öejþÚ¬ƒÕr@Mwb  ôÄì91/ôì90KSXííY"K° TX½ ÿÀ @878YK°TX½ @ ÿÀ878Y´] #!#!ƒý¸•-ýNu×oú‘1¸\‰ÿãð />@"$e ee*i`0$ ' -'! 0ôÄìôìÔìî991äôìîÖî9904&#"3264&#"326#"$5467&&54632ºŸŸŸŸ)Š|{‹‹{|Šlª¾þöø÷þõ¾«—¡øÙÙø¡˜ ±± ¡±±vˆ˜˜ˆ‰˜˜ÉÍŸÒããҟͯˆ´ÏÏ´ˆ¯ÿãð%]@$ elyee i`& #  &ôäìôììî1äôìÄîþîî90@ !"AAA ]#"5432!"&'5332"32654&¾C®mÞþÿéýþ¾þÜO®[p ‚m¾þ¾Ž——ŽŽ—˜KJ èãþ‡þ¢þxþRøel%"ÏÂÂÐɽÇÖÕÿãßy @a a ` Ô<ì21äÔìî074632#"&4632#"&ÕM88ML99LM89LL98Mh8NN88MMÄ8ML99LMJþéãy"@a  ÔüÔì1ÄÔìÎ990665534632#"&J^XÅ‘’?M88MM88MÇE»…%«õZ 8MN78MMÙ^Û¦@ôì291ÔÌ90 5Ûûòúþüþ…þ‡ªѦÑÙfÛž@rrô<ì21ÔìÔì0!!!!Ùúþúþž ø Ù^Û¦@ô<ì91ÔÌ9055Ùúþüªþ/¦þ/ªy‹ÿãçð "<@ a ! ei `#! #ôìÄÔÄìîî1äôÄìÔÄÎþÅ0%4632#"&6632#6654&#"#hM97NN79MÝj¿TÞÝß{±³’~r‘ah8NN87NMc/.Ö¶ºì3þH+Êœ‰žƒ{‡þœo¢@Mm@;BAKE'N$ KE($ Ez Kzz@|$z+ |z+7N'(HA ==1NôÄüìþýî22î991ÔÄüìþý<îîîÄ9999990%#"&54632536654&'&$#"3267#"$'&5476$3254&#"326;“]¯ÚÚ¯]“;œª¼DCjþϳZ°VÊàd_m+­à`5lþþ³}…†€YÂÖawLNþºþæsy‡ˆzrŽøRPúÉÉùPRŽüü%ú¼oÆT…&']þ‡÷§þçgw}LLF]]…{G½¸F~ˆ¦œbæ|þôþÉi}›¯žŸ¯ÿôÛÕ¢@Qdddd  Mo ob    ÔÌ91/<äì2Ôì90KSXí2ííííí2ííY"²(]@ ((( (,+]! 5333!53!3š$þîýHƒ¨“ýá¦}ýŒ}¤Æûjkú•jjHþ¸jqdÕ$E@'o obo ~ $ !$ !%ôì2ä2ÔìÔì9991/ìì2ôì2î90%!2654&#!532654&##53#5!2!ú+´¦¥µþÕþ¤——¤þþw¾¾áâ埙¾Åþèþ×jœª©›j~ˆ‰}ú–jk¹¸…žäÞÒsÿã¤ð8@ndn i`&' %ôìÔìôì1äôìüìÆî0´o]#"&'&5!2#.#"3267¤BþÉî’úapm’IzŸq%ßÉïööï§Ø0‹Ñ×dap´\«@Aþ¨¼²þ­þ·þ¸þ­ŸžqôÕ=@ ob o  $ !ôìä2Ôì99991/ì2ôì20@ 0O€Ÿ]%3 !#53#5! !úº#7þÊþܺþw¾¾R‚¯þPþjL66Hú–jkþvþ¡þ þtq3ÕR@*€  €obo€ ~ $ !ôì2ä2ÔìÔìÔì21/ìììôìüÄäþäÄ0´0O]353#5!#5!!53#5!!53q¾¾²{ýRé{{þ¾{jkþ´Ñþ »þ»ýÑþ´q7ÕF@'€  €obo ~  $ !ôì2ä2ÔÄìÄî21/îî2öîþÄäþä0353#5!#5!!53#5!3q¾¾Æ{ý>þ{{þïjkþ´Ñþ »þ»ý~jsÿãÃðG@"  o ndni` &%ôìÔäüÄî1äôìüìîÖî990¶ 0 O ].# 3267!5!# !2#ÞÆþþþþqÎ]þçä…þͯþ®þi˜Y€š»³þ´þ°þ·þ®88kýÓMM§_b¥;<þžq‰Õ^@.€  o bo ~ $ $$ $!ôì2ä2Ôì2ä2ä2ä21/<îî2ö<î2î0@ p€¿]353#5!#!#5!#3!53!3q¾¾G¾¾G¾¾ý¹¾üú¾jkkýükkûjj‚ý~jq¸Õ 7@ obo $$! ôä2üä21/ì2ôì20@ 0 P ` p € Ÿ ]%3!53#5!#ú¾ý¹¾¾G¾jjjkkÿTþV×Õm@ dn o b‚ $ ÔÄüäÔì1ìôì2îþÆ990K° TX½@ÿÀ878Y²0]K°TK°T[X½ÿÀ@878Y533265#5!##"&¬rXXw^èq¾ÆÜG“þšëca–Ú9kkú¿÷Ü"qÕ(@Dd  dM  o bo $$!ôä2ü<ä2Ä991/<ì22ô<ì290KSXííí2íY"²p]@¢  $ '6 F HW YYhzz    * % % & &'(: 6 6F F @ F @ F @ F@B@@@@@S X X U UPXXi i e efb```y  y  v vvyyC]]353#5!##5!# 3!3q¾¾G¾ƒ¢ð¨ýͪþ¥ý<¾jkkýË5kkýÍý3jÅý¥jqÕ 0@ ob €o$  $!ôìä2Ôìä1/îîöî2Ä0353#5!#!53q¾¾G¾ª{jkkûúþ‹fÉÕ@GddM ob o$$ $ $ $$!ôäìäÔääìää9991/<î2ô<î290KSXííííY"²]@ˆ (/))8?99IHOJJXX_ZZihoiiw&$&&6355FEDFUTUTdddctuts€Ÿ¯¿$]]353#5! !#3!53#3q¾É³  ˜Ç¿ý¸¾þþ¾jkûÙ'kûjj‚ûïû~jdÿã¦Õp@-M o bo $$ $ $!ôìä2Ôìäää1/Æî2ö<î22990KSXííY"² ]@0Op€Ÿ]]353#5!#5!##3dÉÉÈ ÉyüDÉjkûf/kkúyêûjsÿãð ,@n ni `! %!ôìÔì1äôìî0¶_"o" "]%2#""&'&547>3 Hõúúõöúúö˜ÿapmmpbüšEnpbüNQJKQþ¯þµþ¶þ¯kdapµµpbcþVþ£³þáobcqÕC@!oƒ ob o # $ !ôì2ä2Ôìæ99991/î2öî2þî0²_]!2654&#!53#5!2#!3ú•œœ•þøþw¾¾ÂàþúàþÇçø¡˜™ ú–jkãÁÀäýÝjsþ¸ð"@@nn i`#  %#ôìÔì999991äÄôìÎî90¶_$o$ $] 47>3 ;.'2#"`þ©þjmpbüšEþÔþø6›m©ñdõúúõöúú¥aµpbcþVþ£þØþm:C@¹•ùQJKQþ¯þµþ¶þ¯q7Õ$ˆ@H  Mo ƒ#ob o#   $ $ !%ôì2ä2ÔìäÀÀ9999991/<î22öî2þî9990KSXíí9Y"3!&&##3!53#5!2%!2654&#!ÕFe(Ù¶þ éCpbßÓý¤¾¾õÚí­ýz'——þÙå[RþEjÛŠQý´jjkпš±&––ެÿãåð)'@B#"$!   M !dn'dni'`* !)$)*ôÄìÔäìîî99991äôìüìîþî90KSXí9í9Y"²+]@ +0+P+p+€+]K°TK°T[K°T[X½*@**ÿÀ878Y@t( ) ) ) )) )!)"8 9 : : : 99:: :!9"8#I I J I HI I!I"Y Y Y Y Y Y!Y"j l l l k kl l!l"i#{ { { { y{{ {!{"y#7 +°+]]732654&/.54$32#.#"!"&¾s»¿²»q¶ÅÖ¯ôhøŒq±µž¥|ɹ˭þêþí{ÿHTª£‡lt7;A©¾Ò-+þž{kz<7=½ŸÙÜ2BÕ{@  ob o $ $ÔÄäüÄäîî1/î2ôþ<Ä20K° TX½@ÿÀ878Y²]K° TK° T[X½ÿÀ@878Y@ /` ¿]!53!#!#5!3‡¿þI{.{þI¿jôé`þ éû j`ÿãbÕn@%  … ob`$$ $$!ôìäÔäüää1äô<ì2î99990´`]K°TK°T[X½@ÿÀ878Y´ ]#5!#326#5!#! ¿H¿»å廿ø¾þúþÆþÆþõjkküüþâââkküèþ«þæSÿìåÕ’@9dd  M o b   ÔÌ91/ô<ì290KSXí2ííí2Y"²]@"   (* * ']] #5!###5!f¹¸¨¶‘ýë¬ýî• jû†zkkú–jkk 3Õ–@[d d    dd     M  o b ÔÌ91/<ô<<ì290KSXí2ííí2ííííY"²]K°TX½ÿÀ@878Y@Ú   %) $?< 5L FX\ Tm d~ t        &&&&)$ &546 4 7 IIEBFE G D H[[XW[X Y [_______feeehgff g g f d ehjjhusvuu v u w t y||yV]]!# ##5!# 3 #5!#¤þªþª¤þy”!º7T¢Z9¬®“¾ûBjkkû±ºû9\kk ¨Õó@gdddd   M o bo  ÔÜÄ91/<ì2ô<ì290KSXí2ííí2í2ííí2Y"²]²]K° TK° T[K°T[X½ÿÀ@878Y@ÿ )(%&65EFVUjicdyz        &&'& ()%%$$/6777 8997FCGGEE KIFIIUSSSSWSV V S [[WYYedeedede e d kllke``eee`xzzzz{yx x y {~||@{{}yuxxur]] 3!53 #5!# #5!# 3!53¦þ“Áþ¬®þL P°@IÀé¨þu× ý°²ýëjjskkþákkýÁý?jjÿéZÕ/@E  d d    M  o bo    $$ÔäÄüäÄ999991/ì2ô<ì290KSXí2ííí2Y"²]²]K° TX½@ÿÀ878YK° TK° T[K°T[X½ÿÀ@878Y@d 6 E [Zf xw       **/::7 8 ? 9 ? 9 ? ???F I V Y [ [ i h o h o `vvx x x )]]!53#5!# #5!#3ƒ¿þ3Œ+®uu¨²þ?¿jçkký¤\kký,ýÔj\?Õ m@#  M €b €     ÔÄÔìîÄ991/îöþÄÄ0KSXííY"²]@  O ]]35!#!!53\¢üü{œü^LzHßZHúîÑþ´°þò$@ssqôìÀÀÀÀ1üìÔì0!!!!°Ñþîþ/jù²jÿB²Õ*@Mb/Ì991ôÌ0KSXÉÉY"#  ýîÕùm“žþòo@ssqÔì991üìÔì0!5!!5oþ/þîøÞjNjÙ¨ÛÕ@ bÔÌ91ôÌ290##¼™þþšÕýÓ}þƒ-þþmµ†/Ì1Ôì0!5üþmPPªìsdvµÔÌ1ÔÌ0K° TK°T[X½ÿÀ@878YK°TK° T[K° T[K°T[K°T[K°T[X½ÿÀ@878YK°TX½@ÿÀ878Y #ouþ¬dþˆxfÿã‹D (~@/!  z“!Ž#&Œ` z!-" ,' "*)ôÄìÔì22äî991/îäþîöæîöî99990@$*o*x(À*z(ÀÀÀÄÄÄÄÄÄÀÀÀ ]]5#"3263!5#"&5463!54&#"#5>32/퉆ˆts¸¤þ¤= k±ÐîÙ“…n‚_`µVÝçNávzo‚޼ýÒjsJF¼ ¥¶Iy…db×))Û;ÿã¸!G@%!””zqz`Œ 5,'0"ôì22ä2ôì1/ìäìüìîî990²#]7#5!>32#"&'!532654&#"ì±i6§{ÄøøÄ{§6þ—i“Œ‘‘Œ“j@jýmd_þÊúúþÉ_d¦juÀÉâÜÝàÊ¿fÿãD5@™ — • Œ`- *ôìÔÌÔì1äüìüìþä0²o]#"5432#.#"3267'Þ°èþæèeÈekƒ•˜—–wŽ?ª²3þÿ1/0þðŒ€çææè|}fÿãã!O@&” ”zqz` Œ,',5 *"ôìôäü<<ä1/ìäìüìîî990@ ###°#]%3!5#"5432#5!54&#"3263°þ˜6§{ÄùøÅ{§6®f¸“ŒŽ‘‘ŽŒ“jj¦d_7úú6_d)jûËi¿ÊàÝÜâÉfÿãVDN@z™ ›Œ ` *ôì2ÔìÔÌ1äüììþäî90@ @ÏÏÏÏÏ]]!32673#"5432.#"Vü碞y›”,íÁéþåâñÔ‘ˆ’×Û}¯°3þü4þ×±º½¾¹Jqq@& zq zœ - '6,0ô<ä2äü<Äî91/î2î2þîÖÆî2990²]K°TX½ÿÀ@878Y·``?]]#.#"!!3!53#5354632qaSOgT)þ×ìý¬°°°¹³C†BKNq‘‰kü®jjRk…²¶fþ9ãD,f@3, )z)”ž #”Œ`œ- -, '5&7*-ôäìôì22äî1ììäüìîÞæîî99990@ ...°.]#"&'53326=#"54325!4&#"32653üéiÀX`†}¢—6§{ÄùøÅ{§6hþ˜“ŒŽ‘‘ŽŒ“¼ü[åù&&ßh`·Äd_7úú6_d¦kþŒ¿ÊàÝÜâÉÀJîo@, … zqz Œ=,,' :,',0ôäì2äôìäää1/<îî2üîî99990¶/°]K°TX½ÿÀ@878Y353#5!>323!534&#"3T¦°h3£l°¦¤þŸ_z€† j@jýVlnÊÖýÆjjú²þjJ`ã I@ zœ z , ',0ôä2üäÔì1/ì2üìÔÌ0²]K°TX½ÿÀ@878Y4632#"&3!53#5!ÇC/.CB//Cë®ýê°°hq.DD./BBû(jjRkÿ;þ9²ã i@"   zœ-6' , 0ôäüäÔìî1ìüìÄîÖÆÎ990¶/ ` p ]K°TX½ÿÀ@878Y´ss]4632#"&#5!#"&'533265ÍC/.CA0/C-®fëHƒ>_UR[Wq.DD./BBþzkûq¤»!!Û`Z{;ç@XŸ Ÿ Ÿ Ÿ >>M z zqz œ  ,',0ôäü<äÀÀ9991/<ìì2üìî290KSXíí9ííííY"²]@Ú  &))899HVWggghwˆ–¶           ( ( ( &)-**+,)/6 6 6959?F D D DEY X X WVVVh f f gegaabef`x x x zxxvz‹‹‰‰––¹ º º ¸T]])53#5!#5!# 3!533Jýü¦±iÀ™á¶þÄ”™ýô˜þ‘¦j@jü kkþÜýÒjjµ‡þÒ;R @@zqz,',0 ôä2üä1/ì2üì0² ]K°TX½ ÿÀ @878Y%3!53#5!¤®ýé±±ijjj@jJ^D0©@A  +…'z)œ%! z.Œ#  = ", , '?=',?(,* '$,&01ôäì2äôäüäôìäää91/<<î2î2þîî2990@ ?2_2o22°2]K°TX½1ÿÀ11@878Y@/ / //Ï Ï ÏÏÀ2 ]>323!534&#"3!534&#"3!53#5!>32%5¥n§¤¦þ `o{ þ `o{ þ¦°h3žd|¦XuwÏÑýÆjj%£Šº²þjj,Ÿ‡º²þjjTi½jp{JîDp@. … zœz Œ=,,' :,',0ôäì2äôìäää1/<îî2üîî90¶/°]K°TX½ÿÀ@878Y353#5!>323!534&#"3T¦°h3£l°¦¤þŸ`y€† jRk½lnÊÖýÆjjÑ»³þjfÿãjD +@ Œ `D *ôìôì1äüìî0´ o]%2654&#""5432h”——””—˜“èþæééþçFêääééääêc3þþ2þÎþþþÍ;þV¸D #U@, ” z"z ”Œ` ‚œ$,5!,' 0$ôì22ä2ôìä1ììäüìî2îî990´%°%]32654&#"'#5!>32#"&'3!53¤“Œ‘‘Œ“¸±i6§{ÄøøÄ{§6®ýé±HiÀÉâÜÝàʵk¦d_þÊúúþÉ_dþkkfþVãD#S@+# ” zz”Œ `‚œ$,',5 *$ôìôä2ü<<ä1ììäüìî2îî990´%°%]3!53#"54325!4&#"32653°ýê®6§{ÄùøÅ{§6hþ˜“ŒŽ‘‘ŽŒ“¼ûkkåd_7úú6_d¦kþŒ¿ÊàÝÜâÉÀJÓD•@" zŒ zœ -,' ,0ôäì2äÔìÄ1/îî2þÆÆîÆ990@8/@@@@@@D@@@  ]]K°TX½ÿÀ@878Y#.#"3!53#5!>32ÓjNKˆ‘Õýͦ°h6ªz-c)þöON¼°þjjTi½oksÿã²D)Ù@A#"$!>  > M !¡ '¡ Œ'`* !->'F$-E*ôÄìÔäìîî99991äüìôìîöî90KSXí9í9Y"² +]@X'' '!'"'#Z Z Z Z ZZ Z!Z"X#†† †!†"†#–– –!–"–#¦¦ ¦!¦"¦#@++¯¯¯¯¯¯¿¿¿¿¿¿]]75332654&/.54632#.#"#"&sjŠ|‚_™…‰{Ö½TºcjˆutwZ‡’—…çËgÄ;øwv]YFV1-,„f’¦,*ègtRRCQ*-/o—­,;ÿã'qh@  zœ`, '/ô<ì2äÔÌ91äü<ì2ÄþÄ990K° TX½@ÿÀ878Y@&&/Ÿ ]#533!!32673#"&5Ý¢¢¹Zþ¦4FHB‹Ž‘Ÿ„¼kJþ¶ký]‡LU_‘†©7ÿãÛ'u@" …  zœ `,',:,' /ôìäôäü<ä1/äü<ì2î299990K° TX½@ÿÀ878Y´°]K°TX½ÿÀ@878Y!3!5#"&5#5!3265#ÕX®þš3¢k±§¦__z€† 'üCj¼joÉ×9ký•¼³ãÿú'¸@9 Ÿ  Ÿ >>M z œ   ÔÌ91/ü<ì290KSXí2ííí2Y"² ]@H' Scv   %*** * *80HG GWXghvvwxx x x ]]!#5!# #5!#úþyyéª++Ÿwþy¼kký%ÛkküD!¾'Ä@[ Ÿ Ÿ  >  >ŸŸ> > M  zœ  ÔÌ91/<ü<<ì290KSXí2ííí2ííííY"²`]@ÿ $, (3= 9DJ IW ^di itz zŠ          &() & # **%&:;??????:; 9 ; 8 8:9FEEE F F I H HHHHFQPPPPPPPPP R T XVSPb``dd````` b d fb`uxy}}yyyz@y v q u v vvwwwtwŠ ‰ Àx]] #5!## ##5!#×ðšvþÄ™þúþù“þÅwá¬î'üÂÓkküDüå¼kký->j'°@gŸŸ >  >ŸŸ>>Mzœ z    ÔÄÜÄ91/<ì2ü<ì290KSXí2ííí2í2ííí2Y"K° TK°T[X½ÿÀ@878Y@à %*GIWWYXffhhyy…‹       (),,% % ( '&&&))'9?9?HIGFGZYYYWY WUVVVVjjjgh h h gefx||||y wttttxvuuu†‰Œ Œ ‰ ‰‡‡††††[]]#5!# 3!53 3!53 #5!#Tß™þãL‹þ‡çèŠþl%þ½ƒÛ‰3kkþwþ7jj>þÂjj”¾kkÿúþ9'@YŸŸ  ŸŸ> >M z œ  - ÔÄÔì9991ìü<ì2îÖÆ9990KSXí2ííí2í9íY"²]@ZYix))* * ''&XSUPUPSV V hd``dvwx~~tty x x yuuvvvv(]]7#5!# #5!##"&'53326ºFþsyéª++Ÿwþ2zo/c2^9<7CñÎkký%ÛkkûT|[ËD;=Rì' j@" >> M zœ z  - - ÔÄÔÄìî991/îþþÄÄ0KSXííY"K° TK° T[X½ÿÀ@878Y´if ]35!#!!53RšýñjfýfBkVf¸#Vü™ÁþÕþ²$^@0 !   ! s ssq! %$ '%Ô<ì2ÀÀÀÀÀÀ9991/üìÔìÔì999999990#"&54&##532654633#"3>ù©lŽ==Žl©ù>DVd‚„bVåi”Ý–tit–Ý“hXþឈ"†þáXþª¶GÔì1ÔÌ0#ª¢øþ²$[@/   ss#sq%' %Ô<ì2ÀÀÀ9991/üìÔìÔì9999999903265467&&54&##53233#"##FŒUbƒ‚cUŒF?ù§lŽ>>Žl§ù?åWކ"ˆžŽWh“Ýþþ–tit–þþÝ”ÙÝÛ'>@   £ £ôì91ÔìÔìÀ9999990#"''&'&#"56632326Ûd´]`® “_\­Yd³^`® ‘a\°'”XTB 9IM˜WQB:JÿÿÿôÛ\'$ãuÿôÛm )÷@a dd )('d&d  %"#$M %o  f'#o!$ ('& *%"   *ÔÄÔÌÔÎ99999991/<î2æÆÖÎî9990KSXí2ííííí2ííY"²]@://   / & ) "!   ///..)(%'&+/]]4&#"326! 53.546323!53!3wY?@WW@?Yþ#"þðýHƒéHK rr¡NHì“ýá¦}ýŒ}¤Z?YWA?XXüÆûjþ%zSr¡¡rP#ûjjHþ¸jÿÿsþu¤ð'&ÝLÿÿq3k'(ìuÿÿdÿã¦^'1uÿÿsÿã\'2Huÿÿ`ÿãb\'8‡uÿÿfÿã‹f'D9ÿÿfÿã‹d'DC9ÿÿfÿã‹f'D×9ÿÿfÿã‹!'DŽ9ÿÿfÿã‹7'DØ9ÿÿfÿã‹'DÜ9ÿÿfþuD'FÝdÿÿfÿãVf'H^ÿÿfÿãVd'HC^ÿÿfÿãVf'H×^ÿÿfÿãV!'HŽ^ÿÿJšf'ÖÿHÿÿÿò`d'ÖCÿHÿÿ ‡f'Ö×ÿHÿÿ!'ÖŽÿHÿÿJî7'QØ“ÿÿfÿãjf'Rhÿÿfÿãjd'RChÿÿfÿãjf'R×hÿÿfÿãj!'RŽhÿÿfÿãj7'RØhÿÿ7ÿãÛf'XHÿÿ7ÿãÛd'XCHÿÿ7ÿãÛf'X×Hÿÿ7ÿãÛ!'XŽH9ÿ;ÇÕ 6@ ¤  ¤b HH  Ô<Ää2Ü<ä2Ä1ÄôÔ<ä2Ü<ä203%%#5¦´#þp#´#þpÕþF¦ûs¦Ãu=ð @  i ÔÌÔÌ1ôÌÔÌ0"32654&'2#"&546LhgMLhjJ@v+..¹†‡´¸fiMLfgKKkŠ1.-rB„·´‡†ºšþ×PL"I@'™ —•Œ `# -" #ÔìÄ22ÔÌÔìì221ä2ü<Äì2üìÆþ<æ0%#&5473#&&'667uÛ#¼˜dÜÿÿÜd\¨PjsdZtßæÖ׿÷š­þò,ðò+ þö.'þð{ƒ üi l‰dðL@(  seis €  I Ô<ì2ä2ÔìÔì91/Ä2ììôìÔÄî2Ä990#&&#"!!!53!53#534632Ni q`yœþdÞtü%ÁÁÁåÝU¢KÉ_e›¤þÙký½ãþ¤jRk'ÍÕ\ÿ=¤ð Ak@;39 (',o$ o?i$B3/9)'J1'*'"', 04ôÄÄäüÄîîÔîî999991/îäþÆîîÖÆî99990@D --./5``o55/0123-/0123]].#"!534632#"#"&'5332654&/.546¬‹w„zþ—±åÑÕß ‘§6IY›wç¹U¨OmofoPuVhY©ºw‹ûZj8°ÂÐÓl]4M/7cªr›Ä%#éeiyhTuI6ARz¤åÍ$<T™@TN N M ¨ ¨§1¨§%¦=¥1¦I 7" " PNPN"L7KCL+KCMOUÔìüìþýîä2þ<æ99999991/îþþýÆî2ý<î22î9990KSXíí9Y"32654&##3#'&&##3!53#5!2"32676654&'&&'2#"$'&5476$}SSTR}ö*;tL¾ƒ#>1\TþÃSSŸ€‚`׃â^]__]^⃄ã^]]^\^ㄘmmllmmþù˜˜þùmmllmmLKJLþ®3(åDþF/þÑDD CpmS[j^^]僂â^^__^]⃅ã]^^gnmmþúš˜þûmmnnmm˜šmmnåÍ2JM@+  «¨ «¨ ©? ©3¦¥?¦' REK!Q9K!M-KÔìüìþýÎÔÎÎ1/îþþííþäþä90#"&54632#&&#"32672#"$'&5476$"32676654&'&&`µŽ»ßá¹P›WTriwyxvaqé˜mmllmmþù˜˜þùmmllmm˜ƒâ^]__]^⃄ã^]]^\^ã=ƒðÈÉò%'Õmf·¶µµ_cnmmþúš˜þûmmnnmm˜šmmng^^]僂â^^__^]⃅ã]^^ò“œÕ(z@D  # '¬%!b) &S"7$S P PP TPS$T 7)ÔäÄìÔìä2Ôìä2ääîäÔî91ô<<Ä22Ü<ä2Î2999903#3!53#3#53#5!!#5#3!53##^®µÛVVþãVÑ+ÇTñVVý}-D™VþáVœAÕþòBþBBBªþÉ7þVBB¾BªhþBBB¾h‰îRfOµÔÌ1ÔÌ0K° TK°T[X½ÿÀ@878YK° TK° T[K°T[X½ÿÀ@878Y3#‹Çþ¬ufþˆÉ77! z@   ÔÜÔÌ1Ô<Ì20K° TK° T[K°T[K°T[X½@ÿÀ878YK° TK° T[K°T[X½ÿÀ@878YK° TX½ÿ€€878Y2#"&546!2#"&546=0EB32BEµ/EB23BE!E03BB30EE03BB30EÙ'ÛÝ<@!  r r  ô<ì291Ô<ì2Ô<ì2À9990!!!!!'7!5!7!Ù}®/þHÃ{üúþþ}®þÕ¶Ãý‡ž?fÙ ø þÁfÙ øÿݘÕ#Á@Udd  ddM€o!€ob o€~  $ "$ $Ô<ì2ÄäÔìÔìÔì2991/<ììì22Äôì2üÄÄîäþä0KSXíí2ííY"²]@ !"#0%O%o%%]!#53!3!53#5!#5!!53#5!!53ªédZ¾ý昤þXƒN×°{ýPì{{þÁ{Mú–jHþ¸jjkþ´Ñþ »þ»ýÑþ´dÿÇ' +s@:, +&  ) *& nn&i`,,#* # )+#%,ôìÔìÀ999999991äôìîÀÀ99990¶_-o- -].#"324&'7!"&''7&5!27¾A¹|öú "5@¼}õú!"{WWþoþ¼îe¶N»WU’Cð`²P×XVþ¯þµwÁQ`YYQJuÅR‡lþù þ§þSVVÈEÏi Z­USÆGÝÝÏî /D@$ !- $'!®¯®!­0 $U*U0ÔìÔì99991üìüìÀ9999032654&#"&&#"326#"&546326632#"&“2…Te€vYQƒÇ1…Ue€vYQƒ”G›_‡»§†_–KDža…½§†_“/YY‡ie†…9XX…ie†„ˆ~९Ø{Šƒâ¦®×uÙÛ *@r  r   Ô<Ä2ü<Ä21/ìÔ<Äü<Ä0!!#!5!!!ª1ýÏ ýÏ1ýÏúþþy¢þy‡¢‡ûœ ÙÛ¨ &@r  ô<ì2291/ìÔÌ90 5!!Ûûáúþúþúþþáþâ¦pªoûôœÙÛ¨ &@ r  ô<<ì291/ìÔÌ90%!555Ûúþúþœœœf¦þ‘ªþ¦ÿðÕ$K@]dd  M s s sb"s# % #I! I%Ô<äÄü<äÄ9999991/Ä2ì2ô<ì2î2Õ<î290KSXí2ííí2Y"²]@˜6iih     89969::9F K M MKKJ@@BBFIXVYYYYge g g gffgjhohojjhu y||yz€€€€F]]!53!5!5'!5!#5!# #5!#!!!!3h¿þl”Rþ¾þá‹)¯WS§°Žþäþ´G“þm¾joiAiñkký¤\kkþizTiþ‘j;þVé'@3 …  zzœz‚ ` , ,',:, '0 ôì2äôäü<ää91/äìîþ<î2î2î99990²!]K° TX½ @ ÿÀ878Y²!]!3!5#"&'3!53#5!3265#ãX®þš4“Z9^'®ý鱦^`y€† 'üAh¼jo$$þ–kkûký•¼³ãhÿçÁ-)6@'! '!±* $$*ÔÌÜÌ9991äÌÜÌÎÎ9906654&#"#"&54632#"&54324&#"32ôIH7$$0e´ÖþßÕ˜ËÝ¢e‚ WOmVPmmW£Kƒt,>bþÊþùþ±þFØ£Æ[àt}þþÏt{þwœÁJ@#  ´³²  Ô<Ä91üìüÌ990@  *]]!#'.#!!>?3!5 ŠnNI =DýN)üÇu?$ HN”û˜ühÁþ“ã"üÀ%ý!%æþ)/¼5þw'Á=@" ³´ ³²V WV V WVÔä2Äüää2þä1üì22ü<ì20!#3!53!3!53#5ò¿¿ý¬Àý6Àý¬¿¿ÁJùJJJ¶ùJJJ¶Jø'J@%zœ z =,' ,,:,',0ôäìäôääìää1/<î2üî220¶/@]353#5!#3!53!3T¦°®®¤þŸþ! jRkkü®jjRü®j/þú%#@ ¶· ¶µ& XX&ÜìÜì1üÌìüÌì026732#"&'&&#"#"&546327j ¾ÊPd@7*8  k½ÄOeD=!0 þú°l9¼TA6?&#Hý•Ánþ!þbSA8?S}–ð(,q@<&¸+)¸¼)&¸º¸¸»i-) #*#Y#Y -ôÄìÔì22ÄÎ99991ôììüäÄîÍþîÎî999903#5#"&5463354&#"#566325#"326!!FPä0}W¤¾ªÍtiWfLMB±¸”¼ilea\oýôºýFÃþ…TP30‚pr€-T^FEšþ”PNQUaþéh^dð ,@¸ »¸i Y YôìÔì991ôìüìÜÌ02654&#""&54632!!ájklihmli¯ÔÔ¯¯ÔÓýø°ýP-Ÿœœ ¢š› L×°±××±±Öbh}'ð)M@( n!iw   '%*ôÄìÔÄìîÄÄî991/<î2öîÄ2990%!53!565#"!3!&5476$32`Puý°´¹þîÞÞþý²uNÑôsnc‘‘þcotõ¤‰þÓ¶F7èSþ­þééþÊF¶-‰W`Ö—g[`_\gþù–ÕþŸfÿãD 8?¯@G,2*$ 29z*z2™/“Ž*›<'!Œ6`@ $+-?+239**@ôÄìÔìÄ2ÔÌî2î99991ä2ü<ì2ìôäæîþäîî999990@(AoAÀÀÀÄÄÄÄÄÄÀÀÀÏ*Ï+Ï,Ï9Ï?]]5#"326#"&5463!54&#"#5>32>32!32673#"&.#"/퉆ˆtsmSÊ}Å×ïØ€t„_`µVÁ7JÀuñü衟y›“+îÀzÏ\‘ˆ“Návzo‚ŽF[X¶¦¥¶Ix†cc×))WZXYþÖþæ×Û}¯°[,º½¾¹Lÿ¢}… +@?+*&  ) *& &Œ`,,#* # )#+D#*,ôìôìÀ999999991äüìîÀÀ99990@ -o-wx]].#"32654&'7#"&''7.54327H&pJ“˜-(oJ“˜w>@þçé^ CL•=>é^ @‹Lo99êãHv1g=;ëãLy3ŽJÆvþþÍ56¬?²MÁsþ232¦?‹ÿåçò "8@a ! e` i#! #ôìÔìÔìÔì1äôìÄÔÄþÅÎ0#"&54632#"$54675332673 M87NN79LÝj¾UÝþþÞß{±´“~q’`m8NN87NMú/.Ö¶ºì3þþ¸+Êœ‰žƒ{!ò !@ ai   ÄÔÄüÄî1/öþÅ04632#"&53L97NN79LC{Dm8MN78NNúË5üüüËÙÛ^@ r ôÔì1ÔüÄ0!#!Ù ûž^ýÁ=ÿ×} *@  ¾½  ÔÄ91Äüì903##'%\½sý®BþÁ}}`ùºs-Pbý;#þPÝð%‘@N%%  %!"!""!M!"se ei$&%#"!  &ÔìÔì9991Ä2ìôìÔÄîÖÆî299990KSXí2í2í9í2Y"6632#&&#"!!#"&'533267#5!hɦ3vFbKIPW#1þÁ\˦2tGbJHPW\ü oºÇÞVR‹ªþÝjýºÇÝVRŒ©äjÙÛé8l@9216/$#(!6/,(+! /£(£/6 £6£!921$#+9ô<ì291ÔìÔüÄÔîîÀ9999999999990#"'&'&'&#"56632326#"''&'&#"56632326Ûcµ]\¦ “_\­Ye³]`® ‘a\°Xbµ^`® “_\­Ye³]`® ‘a\°d“ZT?9IL“ZRB 9IÑ“YSB9IL“ZRA 9I3VÕM@)ddMwbÔÌ91/äì90KSXííííY"%33þ^þ]»<¬;¤Aû¿¤Õú+ž%# :@     Z Z ôÄü<ÔÄì21Ô<Ä2Ä2Ä2Ô<Ä2Æ2055%þ×)þ+#þ×)þ+#sþ¨þ¨s¢R¢sþ¨þ¨s¢RÁH# :@     Z Z ô<üÄÔ<üÄ1Ô<Ä2Ä2Ä2Ô<Ä2Æ205%5sÕþ+)þ×þNÕþ+(þØ#þ^Rþ^sXXsþ^Rþ^sXXÑÿã/î #&@a! `$ $ÔüÔìÔì1ô<<ì220%4632#"&%4632#"&%4632#"&%M87NN79LýVM87NN79LýVM87NN79Lh8NN87NM88NN87NM88NN87NMÿÿÿôÛk'$ãuÿÿÿôÛ^'$ãuÿÿsÿã^'2HuwuÕ!^@0 €€obo€~    %"ôìÔÄìÔìÔì2î299991/îîîöîþÄäþäÄ0´ #0#]%# !! )#5!!53#5!!53q»þÜþÊ7#¿û3þþP¯‚¼{ýRìyyþ¿{jþ¸þÌþÉþ³jŒb_ˆþ´Ñþ »þ»ýÑfÿãƒD ,3k@/ '--z ™ ›0*$Œ`4'3 - !*4ôìÔÄìÔÌî2991ä2ü<ì2ìþ<äî9990@P5Ï Ï ÏÏ-Ï3]]%2654&#"!32673#"&'#"5432>32.#"h”——””—˜®ü碞y›”,íÀ‚ÏIEÏ‚èþæé„ÎFIÈzòÔ‘ˆ’Fêääééääêº×Û}¯°ba`c3þþ2c``cþ×±º½¾¹Ýb´/Î1ÔÌ0!!üb…Ýb´/Ì1ÔÌ0!!øb…Ñö°ð/@  i  ÔüÄÔüÄ991ô<Ì290#667#667°LEÃ|ˆþÃMEÂ}ˆ @ª?¯ð[P@ª?®ñ[‘ÛrÕ3@  b  ÔÄüÔÄì991ô<Ì29066553%66553‘NFÂ~‰@LEÂ}‡+?¬‚=­ò[P?«?¯ð[Ñö%ð@ i  ÔüÄ91ôÌ990#667%MEÂ}ˆ @ª?®ñ[‘ÛçÕ@ b  ÔÄì91ôÌ99066553‘NFÂ~‰+?¬‚=­ò[Ù‹Ûy '@a ar  Ô<Äü<Ä1ÔÄüÔìî04632#"&4632#"&!!ÕM87NN79LM87NN79Lþúþô8MN78MLýU8NN87NMû¢þ#îu"@ÔÌ91ÔÌ990 úþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿÿúþ9!'\ŽDÿÿÿéZ\'<¤uþ‰ÿãÍð+@M`iÔÌ1ää0KSXííY"3#7–üR–ðùóh\´¨#/o@= -'! 0 -!-'!0 *$0* $ $*0ÔÌÔÌÀ99999991ÔÌÔÌÀ999999907'#"&''7&&5467'766324&#"326…Ñ^Ñ+))-Ï`Ï8wE@}=Ì_Í))*,Ï_Ï8xEBzQ›rpœ›qqœÙÏ^Ñz@Fw9Ï^Ï,*(þ€pššprœžs##@ZôÄì21ÔÄÄÄÔÄÆ05sþ×)þ+#sþ¨þ¨s¢RÁ–##@Zô<üÄ1ÔÄÄÄÔÄÆ05ÁÕþ+(þØ#þ^Rþ^sXXJ'"}@1z"q zœ - =,' , ,'0#ô<ì2ä2ÔÄäìääî1/<î2î2þîÖÆî2990@ $/$o$ $]K°TX½#ÿÀ##@878Y'.#"!3!53!3!53#5354632/^z{™ŽÇ®ýé±ýñ®ýê°°°êåW¶YVUŽ™düCjjRü®jjRk`ÅÈJu@. z zqz œ =',, ',0ô<ä2Äü<Äääþä991/<î2î2þîî2990¶/ ]K°TX½ÿÀ@878Y!3!53#"!!3!53#53546ݯýé°×£†'þÙ®ýê°°°ïúVjj@‚dkü®jjRk`ÉÄ9ÿ;ÇÕ\@1¤¤ ¤ ¤ b  H  H Ô<Ä2ä22Ü<ä22Ä21ÄôÄ2Ö<æ2Ü<ä2ä2Ü<æ203%%%%#55¦´#þp##þp#´#þp##þpÕþF¦þÙþÛ¦þE»¦%'¦¾BÉL · a  Ôì1Ôì04632#"&¾M97NN79MÇ8MN78MLZþéÕã@   ÔÄì91ÔÌ99066553Z_WÅ‘’ÇE»…%«õZZþé`ã2@     ÔÄüÔÄì991Ô<Ì29066553%66553Z_WÅ‘’;_XÄ‘“ÇE»…%«õZPE»…%«õZqÿã Lð #0<@L|@B?@=@=>?>M G$jjGj=*j1?7`A=iM$>0-'@!' :  - :4! D4 J MôìÄÔìÆîÕîÖîî991ä2ô<<Ä2ì2îÖîî90KSXííY"2#"&546"32654&"32654&"32654&#'2#"&5463#2#"&546ôžº» º»ŸWddWVbcø‚XcdWVbc±XbdVVbaUžº» º»"˜üZ˜ž¼»ŸŸ¹ºÜ»»ÛÛ»¼ÛZ¨•“§§“”©ݦ•’§¦“”§ý!¦•“§§““¨\Ü»»ÛÛ»¼Ûàùó Û»½ÚÛ¼ºÜÿÿÿôÛk'$ãuÿÿq3k'(ìuÿÿÿôÛk'$ãuÿÿq3\'(ìuÿÿq3k'(ìuÿÿq¸k',ÿ–uÿÿWÕk',ÿ–uÿÿ_Í\',ÿ–uÿÿq¸k',ÿ–uÿÿsÿãk'2Huÿÿsÿãk'2Huÿÿsÿãk'2Huÿÿ`ÿãbk'8‡uÿÿ`ÿãbk'8‡uÿÿ`ÿãbk'8‡uJ`' @@zœz,',0 ôä2üä1/ì2üì0² ]K°TX½ ÿÀ @878Y%3!53#5!²®ýê°°hjjjRkÁî?f[@ ÔÌ91ÔÌ290K° TK°T[X½ÿÀ@878YK° TK° T[K°T[K°T[X½ÿÀ@878Y3# #¬¨ëtËËtfþˆþü¶J7È@  ¿¿[[ÔìÔì99991Ô<ìÔì299990@A            ]K° TK°T[K°T[X½ÿÀ@878YK°TK°T[K°T[X½@ÿÀ878Y'.#"#>3232673#"&ü9!*0`f[&@%9"+0`f[&@Z7OL‡“!7PK‡“Õb+ö(µÔÌ1ÔÌ0K° TX½ÿÀ@878Y!!ÕVýªö”Ç)9H n@  ¿[[ÔìÔì1ÔìÄ20K°TX½ÿÀ@878YK° TX½ÿÀ@878YK°TK°T[K°T[X½@ÿÀ878Y332673#"&Ç` hddh ` ž‘‘žHOGGO‹7u! -µ  ÔÌ1ÔÌ0K° TK° T[X½ @ ÿÀ878Y2#"&5460EB33BE!E03BB30Eîá \@¿ ¿ [[ÔìÔì1ÔìÔì0K° TK° T[K° T[X½ÿÀ@878YK° TK° T[X½ÿÀ@878Y#"&546324&#"326ŸssŸŸssŸzX@AWWA@Xôs  ssŸŸs?XW@AWX#þuÁ"@  ¿  ÔÌÄ991/ÔüÄ90!#"&'532654&'B@?~p*X.)O#9B,,@p1QY ƒ5-X<ôî¬f:@ ÔÜÔÌ91Ô<Ì20K° TK°T[X½ÿÀ@878Y3#3#°ªôr²þátfþˆxþˆLþwÁ&@  ¿ ÔÜÄ9991/Ôì9990!33267#"&546Í^WC8:$C q|<{/.8  YQ1iÁî?fL@ ÔÌ91Ô<Ì90K° TK°T[X½ÿÀ@878YK°TX½ÿÀ@878Y33¬ëtËËtëîxþüþˆV)ÕQ@-  o b€o  $ $ !ô<ì2ä2Ôìä99991/îîöî2Ä90353'7#5!#%!53{¾Fã¾F¿3Fþ‡¬{jàq\¢“kkýüâ\þíý¢úþ‹-{a@% z qz, ' , 0ô<ä2ü<äÀ9991/ì2üì90²P]K°TX½ÿÀ@878Y%3!53'7#5!7¬°ýꮊ=Ç®f“<Ïjjj>`Vjý˜bVÿÿ¬ÿãåk'6¾uÿÿsÿã²f'Vàÿÿ\?k'=ÉuÿÿRìf']àþ¢ª˜@ GÔ<ì21ÄÔÌÎ0##ª¢¢¢˜ý öý öqþÕ M@% € obo   $!ô<ì2ä2Ôì99991/ì2ôì2Ô<ì20´0€]%3 !#!!53#53#5! !¼#8þÉþܼPþ°þy¾ÈȾR‚¯þPþjL66Hýâ}ý1je}kþvþ¡þ þtfÿãj-a@3-,+'$#"!( `ˆ(q.-, #"! '($+ D*.ôìôì999999991ììôìî99990´ /o/].#"32654&#"5432.''%.'7%5-Q(­¥Ž›/l·»þçéåþãä#K4I2þ¾%%=_wÑ\B%  ÖàÒäåÕpÓاþyÙþþÍ/ôì"5k7•N‡:QV^D–NÿÿÿéZk'<¤uÿÿÿúþ9f'\DqÕM@&oo ob o # $ !ôì22ä2Ôìä299991/Äî2öî2îÖî0²_]!2654&#!53#5!#!2#!3ú•œœ•þøþw¾¾pç9àþùßþÇ粡™˜¡ûÛjkkÛãÀÂäÜj;þV¸ #S@+ ””"z zq` ‚Œ$,5!,' 0$ôì22ä2ôìä1ììäüìî2îî99990²°%]32654&#"#5!>32#"&'3!53¤“Œ‘‘Œ“¸±i6§{ÄøøÄ{§6®ýé±HiÀÉâÜÝàÊ£jýmd_þÊúúþÉ_dþkkÙ1ÛÓ@ rôì1Ôì0!!ÙúþÓ¢DšÁ /@   Ô<Ì291Ô<Ì290 '7šþ1Ïsþ3þ3rÌþ4rÍÍPþ1þ3pÌþ4pÍÏqþ3Í“œ–ß ?@MÂÀh \ ÔÄÄüÄ1ôÄôì2990KSXÉÉY"535733°¬Éðf­œTzj^ýTZœ´ðk@6 Á  ÁM  à ÅÃÂÀh  \ ôÌÔÔÌÔì99991ôäüäþÆä99990KSXí9íY"#56632!53!5%6654&#"ªFBŒEŠ«ÂîJý¦VJaTN^ž "„hz®×lÄKþMzBUcLdÍð*R@,& ÂÃÂ)Ã&ÂÀÆh+  #)#\\ +ôÄÌÔìÔìÎ99991ôääüäþäî99906632#"&'532654&##532654&#"#}I†;Š•j_wy¯£H‹DFb\^ffe5acQLRWF¼lcHdwdrzªJMXR]_JJJCH@Aÿÿ“ÿãð'ð'¼5 ‹ýdÿÿ“ÿã?ð'ð'¼5ñ‹ýdÿÿdÿãð'ò'¼5 ‹ýdÿÿsÿãÃm'* 3uÿÿfþ9ãH'JÚÿÿq¸^', ÿ–uÿÿ¬þuåð'6ݾÿÿsþu²D'VÝÿÿsÿã¤k'&5uÿÿfÿãf'F^ÿÿsÿã¤k'&5uÿÿfÿãf'Fà^fÿãã)d@2!z!” '”zqz` Œ$,',5$ **ôìô<ä2ü<ä91/ìäìüìîîÕ<î2990@ +++°+]%3!5#"5432!5!5#5!3#54&#"3263°þ˜6§{ÄùøÅ{§6þºF®f°°¸“ŒŽ‘‘ŽŒ“jj¦d_7úú6_dJjujßjýi¿ÊàÝÜâÉZ×ZsµÔÌ1ÔÌ0!!Zþsœ¾BÉL · a  Ôì1Ôì04632#"&¾M97NN79MÇ8MN78MLÿøÿãqð4p@;-s+!s1edei`#5-+$(#,"5 .!, ",(4( 5ÔÄ2ìÔÄÔÄÄÄ99999999991Ä2äôìüìÆîî2Ý<î20#"#73&'&5467#7332#&&#"!!!!3267q+ç­½þð/¾-‡´-‘/¾cÇ|j™zˆ¥ø/þ1w/þÀ¤‡t—‹ÍÛ0h1"0h.>Eþª´Âîåh3 Dhæï§žÉþ7ç k@   ÔÜÔÌ1Ô<Ì20K° TK°T[X½@ÿÀ878YK° TK° T[X½ÿÀ@878YK°TX½@ÿÀ878Y2#"&546!2#"&546=0EC21CEµ/EC12CEçF.2CC2.FF.2CC2.F‰îöPµÔÄ1ÔÄ0@ //]K° TX½ÿÀ@878YK° TX½ÿÀ@878Y3#?Åþúuöþø¶Jé@! ¿¿ [[ÔìÔì999991Ô<üÔ<ì99990@2         ]]K° TK° T[K°T[X½@ÿÀ878Y@)   ]K° TK° T[K° T[X½ÿÀ@878YK°TK°T[X½@ÿÀ878Y'.#"'>3232653#"'ó0)'4`fU$>71,)/ag^CH> 9.dv 7/ir-öîqöPµÔÄ1ÔÄ0@ //]K° TX½ÿÀ@878YK°TX½@ÿÀ878Y#º·uþúöþøÁî?öu@ ÔÄ91ÔÄ290K° TX½ÿÀ@878Y@/// ]K°TX½ÿÀ@878YK°TX½@ÿÀ878Y3#'#¨°çtËËtöþø¡¡Áî?öc@ ÔÄ91Ô<Ä90K° TX½ÿÀ@878Y@//// ]K°TX½ÿÀ@878Y373¨çtËËtçþø5œößP@'Á Á M ÂÂÀ h  \Ô<ÄÄü<ÄÄ91ôôü<Ô<ì290KSXííY"!535!533#3ÃþÌTþN’þr¤¤‘Ë—þiþÑT‰TýìR‰É7ø N@ ¿[[ÔìÔì1Ô<Ôì0K° TK° T[K° T[X½ÿÀ@878Y@  ]332673#"&É^k\\k^ ƒ„Ÿø7667u}|‹ué -µ  ÔÌ1ÔÌ0K° TK° T[X½ ÿÀ @878Y2#"&546/FC22CFéF.2CC2.F  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•Íf‹‹7®É´ž®šq“3É¢‘!´Ù‹J´Z‹Á²‡ú‹œ?®‰¬‰²Õ²J´Ù´Ù´ÙJ‹‡Çÿôáqsjq×qqdsúq)q5ÿTúqPq1fdsbqsq{¬V¾`Çÿì9 ² Hÿé\°²ž´ÙªÅf;{ff¼föJf'JJ{ÿ;Ù;;–J'JÑf;fÓJs7;'7…ÿúÙ!ƒ…ÿú7R²´ÙÇÿôÇÿôs×qds¾`ÅfÅfÅfÅfÅfÅf{f¼f¼f¼f¼fJÿò 'JÑfÑfÑfÑfÑf'7'7'7'79Ú‰\¸3žX;ò‰É´ÙÿÝdªÝ´Ù´Ù´Ùÿð3;#h¶^5BJ+/Í}Ã^¢}…fÑLJ‹7´Ù=#´Ù–3åžåÁÑÇÿôÇÿôs wéfÑ‘‹Ñ‹‘´Ùô…ÿúHÿéVþ‰h3ž3ÁVJVJ9‹¾‹Z%Z ¼qÇÿô×qÇÿô×q×q)q)W)_)qsss¾`¾`¾`JÁ¶ÕÇ‹î#ôLÁZV˜-{¬s\7R²uqÑfHÿé…ÿúhq;´Ù´5“5Z5dÁ“Á“Áddsf)q{¬ss{fs{ff´Z‹¾ÿøÉ‰¶öÁÁ55É‹ÿ+…   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ     sfthyphenperiodcenteredEuroc6459c6460c6461c6462c6463c6466c6467c6468c6469""""TuÜ_Þ”ª×Ox™®Îñ2…ÝAµ?®ýcÐ9^€£ö ¢  t Ä  \ ¡ ý U † Þ › Ë~×(uÔR%~áH;f"s˜¼ßaÜ4{Ö-‘i±4Ì/nÎ/¡J¤ !•"G"—"ú##r#¾#Ë$‹$˜$¥$²$¿$Ì$Ù$æ$ó%% %%'%4%A%N%[%h%u%‚%%œ%©%¶%Ã%Ð%Ý%ê%÷&&&H&€&à'5'Ê'é((Â)*%*ž*Ô+7+{,,™--6-f-“.r.â/=//Î00`0Û11‰2>2Å33H3d3“44¢4ß55`5©5©5¶5Ã5Ð6;6À6Ô6è7!7\7~7 7á8 88%8I8Ë8ñ99Š9ñ:M:l::Ç;t;;Ž;›;¨;µ;Â;Ï;Ü;é;ö<<<<*<7/>a>”>È??P? ?­?º?Ç?Ô?÷@S@Ï@Ü@éA?AŸA¶AïB$B„BêBûC CC*C7CDCQC^CkCxC…C’DDD5D¿EEQFF9F…FÉGGTGX7 J7ÿ·9ÿk:ÿ;ÿ·<ÿ»ÿêÿ$7ÿ$9ÿš$:ÿ­$<ÿ­$IÿÜ$WÿÜ$Yÿ­$Zÿ¤$\ÿ­$µþÓ$·þÓ$ºÿ­$»ÿ­$ÀÿÜ$ÁÿÜ$êÿ­$ëÿ­%&%&&%*&%2&%<ÿÜ%d&%g&%‘&%¯&%°&%»ÿÜ%Ð&%Ñ&%Ò&%êÿÜ%ö&%û&%ý&&ÿ·&ÿ·'ÿ·'&'ÿ·'9ÿÜ(&)þÁ)ÿ¤)þÁ)ÿ·)ÿ·)$ÿN)Dÿu)Hÿ)Rÿ)bÿN)iÿu)jÿu)kÿu)lÿu)mÿu)nÿu)pÿ)qÿ)rÿ)sÿ)yÿ)zÿ){ÿ)|ÿ)}ÿ) ÿu)¡ÿ)­ÿN)®ÿN)±ÿ)ÇÿN)ÉÿN*ÿ·*&*ÿ·*<ÿÜ*»ÿÜ*êÿÜ-ÿˆ-ÿa-ÿ­-ÿ­.ÿk.$ÿ­.&ÿÉ.2ÿÉ.8ÿ·.:ÿ·.<ÿÉ.HÿÉ.RÿÉ.XÿÓ.\ÿ}.bÿ­.dÿÉ.gÿÉ.hÿ·.pÿÉ.qÿÉ.rÿÉ.sÿÉ.yÿÉ.zÿÉ.{ÿÉ.|ÿÉ.}ÿÉ.~ÿÓ.ÿÓ.€ÿÓ.ÿÓ.‘ÿÉ.¡ÿÜ.­ÿ­.®ÿ­.¯ÿÉ.°ÿÉ.±ÿÉ.ºÿ}.»ÿÉ.Çÿ­.Éÿ­.ÐÿÉ.ÑÿÉ.ÒÿÉ.Óÿ·.Ôÿ·.Õÿ·.êÿÉ.ëÿ}.ûÿÉ.ýÿÉ/7ÿY/8ÿ/9ÿ /:ÿN/<ÿ}/\ÿÜ/hÿ/µþ/·þ/ºÿÜ/»ÿ}/Óÿ/Ôÿ/Õÿ/êÿ}/ëÿÜ1ÿ}1ÿ}1ÿ·1ÿ·2ÿˆ2K2ÿˆ29ÿÜ2;ÿÜ3þa3ÿ3þa3ÿ·3ÿ·3$ÿD38ÿÜ3Dÿ¤3Hÿ¤3Rÿ­3VÿÉ3bÿD3hÿÜ3iÿ¤3jÿ¤3kÿ¤3lÿ¤3mÿ¤3nÿ¤3pÿ¤3qÿ¤3rÿ¤3sÿ¤3yÿ­3zÿ­3{ÿ­3|ÿ­3}ÿ­3 ÿ¤3¡ÿ­3­ÿD3®ÿD3±ÿ­3ÇÿD3ÉÿD3ÓÿÜ3ÔÿÜ3ÕÿÜ3äÿÉ3úÿÉ4ÿš4K4ÿš4µ&4·&57ÿÜ59ÿ·5:ÿÓ5<ÿÁ5D/5\ÿÜ5i/5j/5k/5l/5m/5n/5 /5¡&5µÿ5·ÿ5ºÿÜ5»ÿÁ5êÿÁ5ëÿÜ6ÿ·6K6ÿ·66ÿÜ6ãÿÜ6ùÿÜ7þÓ7þø7þÓ7ÿ·7ÿ·7$ÿ77&7Dÿa7Fÿa7Hÿa7Rÿa7Vÿk7Zÿ·7bÿ7iÿa7jÿa7kÿa7lÿa7mÿa7nÿa7oÿa7pÿa7qÿa7rÿa7sÿa7yÿa7zÿa7{ÿa7|ÿa7}ÿa7 ÿa7¡ÿa7­ÿ7®ÿ7±ÿa7Çÿ7Éÿ7äÿk7úÿk7üÿa7þÿa8ÿD8ÿÜ8ÿD8ÿ·8ÿ·8$ÿÁ8-ÿÉ8bÿÁ8­ÿÁ8®ÿÁ8ÇÿÁ8ÉÿÁ9þš9ÿD9þš9ÿ29ÿ29$ÿu92ÿÜ9DÿD9HÿD9LÿÜ9RÿD9Xÿ}9\ÿ­9bÿu9gÿÜ9iÿD9jÿD9kÿD9lÿD9mÿD9nÿD9pÿD9qÿD9rÿD9sÿD9yÿD9zÿD9{ÿD9|ÿD9}ÿD9~ÿ}9ÿ}9€ÿ}9ÿ}9‘ÿÜ9 ÿD9¡ÿD9­ÿu9®ÿu9¯ÿÜ9°ÿÜ9±ÿD9µK9·K9ºÿ­9Çÿu9Éÿu9ÐÿÜ9ÑÿÜ9ÒÿÜ9ëÿ­:þš:ÿk:þš:ÿN:ÿN:$ÿš:DÿN:HÿY:LÿÜ:Rÿu:Uÿ¤:Xÿ­:\ÿÓ:bÿš:iÿN:jÿN:kÿN:lÿN:mÿN:nÿN:pÿY:qÿY:rÿY:sÿY:yÿu:zÿu:{ÿu:|ÿu:}ÿu:~ÿ­:ÿ­:€ÿ­:ÿ­: ÿu:¡ÿu:­ÿš:®ÿš:±ÿu:µ&:·&:ºÿÓ:Çÿš:Éÿš:ëÿÓ;ÿ·;$ÿ·;&ÿÜ;2ÿÜ;bÿ·;dÿÜ;gÿÜ;‘ÿÜ;­ÿ·;®ÿ·;¯ÿÜ;°ÿÜ;Çÿ·;Éÿ·;ÐÿÜ;ÑÿÜ;ÒÿÜ;ûÿÜ;ýÿÜ<þø<ÿ<þø<ÿ<ÿ<$ÿa<&ÿÜ<Dÿa<HÿN<LÿÜ<RÿN<XÿN<bÿa<dÿÜ<iÿa<jÿa<kÿa<lÿa<mÿa<nÿa<pÿN<qÿN<rÿN<sÿN<yÿN<zÿN<{ÿN<|ÿN<}ÿN<~ÿN<ÿN<€ÿN<ÿN< ÿ<<¡ÿN<­ÿa<®ÿa<±ÿ)<Çÿa<Éÿa<ûÿÜ<ýÿÜ=ÿÜ=ÿÜIÿ·Iÿ·Iÿ·I´&Iµ—I·—NÿÜRÿÜUÿUÿYÿ Yÿ Zÿ Zÿ [ÿÜ\þð\þðb7ÿb9ÿšb:ÿ­b<ÿ­bIÿÜbWÿÜbYÿ­bZÿ¤b\ÿ­bµþÓb·þÓbºÿ­b»ÿ­bÀÿÜbÁÿÜbêÿ­bëÿ­dÿ·dÿ·e&fÿ}fÿ}fÿ·fÿ·gÿˆgKgÿˆg9ÿÜg;ÿÜhÿDhÿÜhÿDhÿ·hÿ·h$ÿÁh-ÿÉhbÿÁh­ÿÁh®ÿÁhÇÿÁhÉÿÁyÿÜzÿÜ{ÿÜ|ÿÜ}ÿÜ&‘ÿˆ‘K‘ÿˆ‘9ÿÜ‘;ÿÜ¡ÿÜ­7ÿ­9ÿš­:ÿ­­<ÿ­­IÿÜ­WÿÜ­Yÿ­­Zÿ¤­\ÿ­­µþÓ­·þÓ­ºÿ­­»ÿ­­ÀÿÜ­ÁÿÜ­êÿ­­ëÿ­®7ÿ®9ÿš®:ÿ­®<ÿ­®IÿÜ®WÿÜ®Yÿ­®Zÿ¤®\ÿ­®µþÓ®·þÓ®ºÿ­®»ÿ­®ÀÿÜ®ÁÿÜ®êÿ­®ëÿ­¯ÿˆ¯K¯ÿˆ¯9ÿܯ;ÿܰ&´$þø´-/´99´:9´;9´<9´bþø´þÓ´­þø´®þø´»9´Çþø´Éþø´ê9¶$þø¶-/¶bþø¶ÿ¶­þø¶®þø¶Çþø¶Éþøºþðºþð»þø»ÿ»þø»ÿ»ÿ»$ÿa»&ÿÜ»Dÿa»HÿN»LÿÜ»RÿN»XÿN»bÿa»dÿÜ»iÿa»jÿa»kÿa»lÿa»mÿa»nÿa»pÿN»qÿN»rÿN»sÿN»yÿN»zÿN»{ÿN»|ÿN»}ÿN»~ÿN»ÿN»€ÿN»ÿN» ÿ<»¡ÿN»­ÿa»®ÿa»±ÿ)»Çÿa»Éÿa»ûÿÜ»ýÿÜÅ7ÿ·Å9ÿÅ:ÿ·Å;9Å<ÿ·ÅYÿÜÅZÿÜÅ»ÿ·Åêÿ·Ç7ÿÇ9ÿšÇ:ÿ­Ç<ÿ­ÇIÿÜÇWÿÜÇYÿ­ÇZÿ¤Ç\ÿ­ÇµþÓÇ·þÓǺÿ­Ç»ÿ­ÇÀÿÜÇÁÿÜÇêÿ­Çëÿ­È&É7ÿÉ9ÿšÉ:ÿ­É<ÿ­ÉIÿÜÉWÿÜÉYÿ­ÉZÿ¤É\ÿ­ÉµþÓÉ·þÓɺÿ­É»ÿ­ÉÀÿÜÉÁÿÜÉêÿ­Éëÿ­Ê&Ë&ÐÿˆÐKÐÿˆÐ9ÿÜÐ;ÿÜÑÿˆÑKÑÿˆÑ9ÿÜÑ;ÿÜÒÿˆÒKÒÿˆÒ9ÿÜÒ;ÿÜÓÿDÓÿÜÓÿDÓÿ·Óÿ·Ó$ÿÁÓ-ÿÉÓbÿÁÓ­ÿÁÓ®ÿÁÓÇÿÁÓÉÿÁÔÿDÔÿÜÔÿDÔÿ·Ôÿ·Ô$ÿÁÔ-ÿÉÔbÿÁÔ­ÿÁÔ®ÿÁÔÇÿÁÔÉÿÁÕÿDÕÿÜÕÿDÕÿ·Õÿ·Õ$ÿÁÕ-ÿÉÕbÿÁÕ­ÿÁÕ®ÿÁÕÇÿÁÕÉÿÁá7ÿYá8ÿÜá9ÿ á:ÿNá<ÿ2á\ÿÜáhÿÜáµþá·þáºÿÜá»ÿ2áÓÿÜáÔÿÜáÕÿÜáêÿ2áëÿÜãÿ·ãKãÿ·ã6ÿÜããÿÜãùÿÜåÿÜåÿÜèÿ·èKèÿ·è$ÿÜè9ÿÜè<ÿÜèbÿÜè­ÿÜè®ÿÜè»ÿÜèÇÿÜèÉÿÜèêÿÜéÿÜêþøêÿêþøêÿêÿê$ÿaê&ÿÜêDÿaêHÿNêLÿÜêRÿNêXÿNêbÿaêdÿÜêiÿaêjÿaêkÿaêlÿaêmÿaênÿaêpÿNêqÿNêrÿNêsÿNêyÿNêzÿNê{ÿNê|ÿNê}ÿNê~ÿNêÿNê€ÿNêÿNê ÿ<ê¡ÿNê­ÿaê®ÿaê±ÿ)êÇÿaêÉÿaêûÿÜêýÿÜëþðëþðìþ­ì&ìþ­íÿÜíÿšöÿ·ö&öÿ·ö<ÿÜö»ÿÜöêÿÜùÿ·ùKùÿ·ù6ÿÜùãÿÜùùÿÜûÿ·ûÿ·ýÿ·ýÿ· UE@ ^mþ ¼þ‰þ‰ L GÌþBGÌS…f€¯ JBits@ ûþšmãBµ‹'#sÕVeraSerifÿÿÿÿ6ÿÿþ628R00‚                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     "                      "        #                       #         $                   $        &                   &        ÿÿÿð_<õº²KºÀ²þ‰þ Lmloganalyzer-3.6.5/src/BitstreamVeraFonts/RELEASENOTES.TXT0000644000175000017500000001766012225176641022211 0ustar danieldanielBitstream Vera Fonts - April 16, 2003 ===================================== The version number of these fonts is 1.10 to distinguish them from the beta test fonts. Note that the Vera copyright is incorporated in the fonts themselves. The License field in the fonts contains the copyright license as it appears below. The TrueType copyright field is not large enough to contain the full license, so the license is incorporated (as you might think if you thought about it) into the license field, which unfortunately can be obscure to find. (In pfaedit, see: Element->Font Info->TTFNames->License). Our apologies for it taking longer to complete the fonts than planned. Beta testers requested a tighter line spacing (less leading) and Jim Lyles redesigned Vera's accents to bring its line spacing to more typical of other fonts. This took additional time and effort. Our thanks to Jim for this effort above and beyond the call of duty. There are four monospace and sans faces (normal, oblique, bold, bold oblique) and two serif faces (normal and bold). Fontconfig/Xft2 (see www.fontconfig.org) can artificially oblique the serif faces for you: this loses hinting and distorts the faces slightly, but is visibly different than normal and bold, and reasonably pleasing. On systems with fontconfig 2.0 or 2.1 installed, making your sans, serif and monospace fonts default to these fonts is very easy. Just drop the file local.conf into your /etc/fonts directory. This will make the Bitstream fonts your default fonts for all applications using fontconfig (if sans, serif, or monospace names are used, as they often are as default values in many desktops). The XML in local.conf may need modification to enable subpixel decimation, if appropriate, however, the commented out phrase does so for XFree86 4.3, in the case that the server does not have sufficient information to identify the use of a flat panel. Fontconfig 2.2 adds Vera to the list of font families and will, by default use it as the default sans, serif and monospace fonts. During the testing of the final Vera fonts, we learned that screen fonts in general are only typically hinted to work correctly at integer pixel sizes. Vera is coded internally for integer sizes only. We need to investigate further to see if there are commonly used fonts that are hinted to be rounded but are not rounded to integer sizes due to oversights in their coding. Most fonts work best at 8 pixels and below if anti-aliased only, as the amount of work required to hint well at smaller and smaller sizes becomes astronomical. GASP tables are typically used to control whether hinting is used or not, but Freetype/Xft does not currently support GASP tables (which are present in Vera). To mitigate this problem, both for Vera and other fonts, there will be (very shortly) a new fontconfig 2.2 release that will, by default not apply hints if the size is below 8 pixels. if you should have a font that in fact has been hinted more agressively, you can use fontconfig to note this exception. We believe this should improve many hinted fonts in addition to Vera, though implemeting GASP support is likely the right long term solution. Font rendering in Gnome or KDE is the combination of algorithms in Xft2 and Freetype, along with hinting in the fonts themselves. It is vital to have sufficient information to disentangle problems that you may observe. Note that having your font rendering system set up correctly is vital to proper judgement of problems of the fonts: * Freetype may or may not be configured to in ways that may implement execution of possibly patented (in some parts of the world) TrueType hinting algorithms, particularly at small sizes. Best results are obtained while using these algorithms. * The freetype autohinter (used when the possibly patented algorithms are not used) continues to improve with each release. If you are using the autohinter, please ensure you are using an up to date version of freetype before reporting problems. * Please identify what version of freetype you are using in any bug reports, and how your freetype is configured. * Make sure you are not using the freetype version included in XFree86 4.3, as it has bugs that significantly degrade most fonts, including Vera. if you build XFree86 4.3 from source yourself, you may have installed this broken version without intending it (as I did). Vera was verified with the recently released Freetype 2.1.4. On many systems, 'ldd" can be used to see which freetype shared library is actually being used. * Xft/X Render does not (yet) implement gamma correction. This causes significant problems rendering white text on a black background (causing partial pixels to be insufficiently shaded) if the gamma of your monitor has not been compensated for, and minor problems with black text on a while background. The program "xgamma" can be used to set a gamma correction value in the X server's color pallette. Most monitors have a gamma near 2. * Note that the Vera family uses minimal delta hinting. Your results on other systems when not used anti-aliased may not be entirely satisfying. We are primarily interested in reports of problems on open source systems implementing Xft2/fontconfig/freetype (which implements antialiasing and hinting adjustements, and sophisticated subpixel decimation on flatpanels). Also, the algorithms used by Xft2 adjust the hints to integer widths and the results are crisper on open source systems than on Windows or MacIntosh. * Your fontconfig may (probably does) predate the release of fontconfig 2.2, and you may see artifacts not present when the font is used at very small sizes with hinting enabled. "vc-list -V" can be used to see what version you have installed. We believe and hope that these fonts will resolve the problems reported during beta test. The largest change is the reduction of leading (interline spacing), which had annoyed a number of people, and reduced Vera's utility for some applcations. The Vera monospace font should also now make '0' and 'O' and '1' and 'l' more clearly distinguishable. The version of these fonts is version 1.10. Fontconfig should be choosing the new version of the fonts if both the released fonts and beta test fonts are installed (though please discard them: they have names of form tt20[1-12]gn.ttf). Note that older versions of fontconfig sometimes did not rebuild their cache correctly when new fonts are installed: please upgrade to fontconfig 2.2. "fc-cache -f" can be used to force rebuilding fontconfig's cache files. If you note problems, please send them to fonts at gnome dot org, with exactly which face and size and unicode point you observe the problem at. The xfd utility from XFree86 CVS may be useful for this (e.g. "xfd -fa sans"). A possibly more useful program to examine fonts at a variety of sizes is the "waterfall" program found in Keith Packard's CVS. $ cvs -d :pserver:anoncvs@keithp.com:/local/src/CVS login Logging in to :pserver:anoncvs@keithp.com:2401/local/src/CVS CVS password: $ cvs -d :pserver:anoncvs@keithp.com:/local/src/CVS co waterfall $ cd waterfall $ xmkmf -a $ make # make install # make install.man Again, please make sure you are running an up-to-date freetype, and that you are only examining integer sizes. Reporting Problems ================== Please send problem reports to fonts at gnome org, with the following information: 1. Version of Freetype, Xft2 and fontconfig 2. Whether TT hinting is being used, or the autohinter 3. Application being used 4. Character/Unicode code point that has problems (if applicable) 5. Version of which operating system 6. Please include a screenshot, when possible. Please check the fonts list archives before reporting problems to cut down on duplication. loganalyzer-3.6.5/src/BitstreamVeraFonts/COPYRIGHT.TXT0000644000175000017500000001350212225176641021657 0ustar danieldanielBitstream Vera Fonts Copyright The fonts have a generous copyright, allowing derivative works (as long as "Bitstream" or "Vera" are not in the names), and full redistribution (so long as they are not *sold* by themselves). They can be be bundled, redistributed and sold with any software. The fonts are distributed under the following copyright: Copyright ========= Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org. Copyright FAQ ============= 1. I don't understand the resale restriction... What gives? Bitstream is giving away these fonts, but wishes to ensure its competitors can't just drop the fonts as is into a font sale system and sell them as is. It seems fair that if Bitstream can't make money from the Bitstream Vera fonts, their competitors should not be able to do so either. You can sell the fonts as part of any software package, however. 2. I want to package these fonts separately for distribution and sale as part of a larger software package or system. Can I do so? Yes. A RPM or Debian package is a "larger software package" to begin with, and you aren't selling them independently by themselves. See 1. above. 3. Are derivative works allowed? Yes! 4. Can I change or add to the font(s)? Yes, but you must change the name(s) of the font(s). 5. Under what terms are derivative works allowed? You must change the name(s) of the fonts. This is to ensure the quality of the fonts, both to protect Bitstream and Gnome. We want to ensure that if an application has opened a font specifically of these names, it gets what it expects (though of course, using fontconfig, substitutions could still could have occurred during font opening). You must include the Bitstream copyright. Additional copyrights can be added, as per copyright law. Happy Font Hacking! 6. If I have improvements for Bitstream Vera, is it possible they might get adopted in future versions? Yes. The contract between the Gnome Foundation and Bitstream has provisions for working with Bitstream to ensure quality additions to the Bitstream Vera font family. Please contact us if you have such additions. Note, that in general, we will want such additions for the entire family, not just a single font, and that you'll have to keep both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add glyphs to the font, they must be stylistically in keeping with Vera's design. Vera cannot become a "ransom note" font. Jim Lyles will be providing a document describing the design elements used in Vera, as a guide and aid for people interested in contributing to Vera. 7. I want to sell a software package that uses these fonts: Can I do so? Sure. Bundle the fonts with your software and sell your software with the fonts. That is the intent of the copyright. 8. If applications have built the names "Bitstream Vera" into them, can I override this somehow to use fonts of my choosing? This depends on exact details of the software. Most open source systems and software (e.g., Gnome, KDE, etc.) are now converting to use fontconfig (see www.fontconfig.org) to handle font configuration, selection and substitution; it has provisions for overriding font names and subsituting alternatives. An example is provided by the supplied local.conf file, which chooses the family Bitstream Vera for "sans", "serif" and "monospace". Other software (e.g., the XFree86 core server) has other mechanisms for font substitution. loganalyzer-3.6.5/src/BitstreamVeraFonts/VeraIt.ttf0000644000175000017500000017430412225176641021627 0ustar danieldanielOS/2´Zô-â¨VPCLT í^ã6cmap¤Ãè ÇXXcvt °hfpgmçjñÄ$‹gaspø€ glyf¨ë¼Æ%¢:hdmxhH6ã8HheadhŽ…tøŒ6hheaiàâ„$hmtx vl³Ê°0kern¥^§™ÓŒÖloca=c‘Ñpmaxp@äâd nameöJRýpost´O/»ÎàŽprep’‘" „ ::N:: Ua0·v   z t ¥ &   A 6  6   O 2 g `  ‘ 0¿ & ™Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans ObliqueRelease 1.10BitstreamVeraSans-ObliqueCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans ObliqueRelease 1.10BitstreamVeraSans-ObliqueCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces. The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera". This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names. The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com#/¸Ë¸ÁªÇÇ 77R¾‰-˦‡Ù´œ997Óy…¨Ë\¸H/ٓ˸¸{PfÇÍššo˸ðºƒÕ˜ËHöƒTšsÕ þ+¤´œœb-ÕÕÕð{T¤¸Ӹ˦Ãìé Ó\qbœ¨…#¨H99`ƒš```{wœ`ªÅ{PÍf¼fwÍ;…‰{ÕÍJ/œœ}5oo®²-–{öƒTfœföqÍD)fs¸€@ÿ±þ°%¯2®–­¬s¬2«þª%©¨%§–¦ú¥ú¤þ£:¢þ¡2 ŸS –ŸMAŸSž2œ–› šþ™˜}—»–þ”MA”}“þ’‘G’}‘GþŽþþŒþ‹þЉŠþ‰ˆ2‡þ„ƒþ‚þþ€þþ~þ}K%}d|þ{zy»zþyx]y»y€xw%x]x@w%vþu–tdsrq%rdqpq%poMAoún@ÿþmþlþkji:jdiK%i:hN hgfg2feddMAd–cþba bþa `_`d_^_^] \[ \þ[ ZMAZ–YXY(XWúVU»VþUT]U»U€TS%T]T@S%RþQP.QþP.ON ON MK%MALK%LþKJK%JIþHGHþGFþEþDþCB}CþB}Aþ@ú?ú>ú<6B<þ;È:6B:S9þ@p8}76B6-6B5þ4þ3:2ú0 /þ-þ,þ+-+1*))#('&'d&% %2$ $}#:#þ" "»!!    ¸ÿÀ@š  @:––%d%%A%þþúþþþ:–  }    þ:–þ-:-  @¸d…++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P° y ¸ÿÿPXY°°%°%#á °P° y ¸ÿÿPXY°°%á-,KPX °³EDY!-,°%E`D-,KSX°%°%EDY!!-,ED-fþ–f¤@ ±±D/ÄÔì1ÔìÔì0!%!!füsüåþ–øòr)¢Õ @-   :HF ÔäôÄÀ991/äüÌ0KSXíííí9Y"K° TK° T[K°T[K°T[X½ @ ÿÀ878Y3 #3#ÅÊZ¢2qË1ÍÕýqþ›eý¸þŪéÕ@IFüüÜì1ô<ì20#!#oª$ªÕýÕ+ýÕ+/¾N@4L L    ÔÌ91/<Ô<<ü<<Ô<<Ä2ì220!3!!!!#!#!7!!7!!!h$i gP'þ°RT$þ©h gþÛg¡hþ¶%JTþ°'Pf8þÝT%¾þaŸþašþ²™þbžþbž™NšŸýÇþ²DþÓ /`@9 $ KOM+* K#M-*',+ -#$*  '0ÔìÔìÀÀ9991/<ÄÄÄ2üÄîÆî2öî90%6654&'&&'#&&'7&&54$773X‹¢fs„–_l""V§OT¸Áþâí;d;tÌS"\ÈjX½¬á/d,Z«‘gT\Z€dFOìµ.2þU¬‡¯å þÓ-/*¸>DÈ$•~¦æééºÿãßð #/3O@,W*WRW!W*R1$Q0V40-2 '  ' - 4ÔììÔììîî991ä2ô<äìîöîî0"&54324&#"3264&#"326"&5432#ሟ躈ŸèHNMp~QKk‚\LMoQKk€ÿˆžçºˆç›û. Óñ˜Ø ³™ÖþõÛij­\d¾ý¾kjí]d¾þò˜Ø °™×þó ùó `ÿããð 3û@T// ///:0 /& Z&%Y)Z"VQ 0/&, % 3,3  4ôìÄÔìî999991/ÄäöîöÎî9990KSXíí9í9í9Y"²]@X *: ItˆŽ–• œ     % & %&+)*%*&6 9%9&6/KIkxu/‰ŠŠžšš]] 326#'#"$547.5467>32.#">7ÇþVy}«Ž^·n-“gÑüjjô…Ýþù¹¶.+EÐxNžQ#K•F|›&E—KjXÆgšA[Ÿþølþò‹SUÚ´št._6Dz2RZ$$¶/1d,VXýøOÍzŪoÕ@ IFüì1ôì0#oªÕýÕ+žþòj @ \   ÔüÄ9991üÌ0#&5jþ÷þûLL \Zþµý­þìžþÉ™¬Eœ)G#ÿþòN !@\ ÔÄì9991üÌ04'3 KL \ZþëþìþòKSž7™­þ¾œþÖýµþà=JÃðN@,  ] ] V    Ô<ä2Ü<ä2991ôÔ<ì2Äì2990%#'%%73%Ãþ™g:þ°rþ°:gþ™:PrPßÂÃbËþ‡yËbÃÂcËyþ‡ËÙÛ #@ `  Üü<ü<ì1/Ô<ü<Ä0!!#!5!®-ýÓ¨ýÓ-ýÓªýÓ-ª-ÿ‹þ†@:bHÔäÄÀ1üì0KSXíí9Y"K° TK° T[X½@ÿÀ878Y@%%55FFVV ]K°TX½€ÿ€878Y73#¸Ó!ãþ¬þÀ@\ߘƒ?@ cÔÌ991Ôì0K°TX½@ÿÀ878Y@ __oo]!!}ýヤw{þQ@:HÔäÀ91/ì0KSXííY"K° TK° T[K°T[X½@ÿÀ878Y73#¨Ó1ÓþþÿjÿBjÕ.@:FÔÄÀ91ôÌ0KSXÉÉY"3#¸²ü±±Õùmfÿã°ð#D@d dV Q$! $ôìÔì1äôìî0K° TK° T[K° T[X½$@$$ÿÀ878Y2#"547>"3267654&Ë×e[]û˜ÄÖg\\÷†L‰7\murPˆ7[kuðþòýÀþ…––›û¾}•–œ QO„þuÐ¥©QOƒ‹Ñ¥©dáÕ T@* :ddFd   ÔÔÄÀ99991/ì2ôìÔì0KSXíí2Y"7!7%3!!…Jßþ‹#sËþþI ü£ª}H®HúÕª˜ð›@,:eY dVd ÔÔì999991/ìôìôì990KSXí9íY"K° TX½@ÿÀ878Y@( ,,eyuxy '4Ucv]] !!7>54&#"7>32°ý{É#ü7!¢‡qˆn_è„%|â`ÄïrÑýרªBu±]azDAÈ12ЩrÏÿã“ð+–@+ d!KXd+KX(dVQ!g,!  "+ %,ÔÔìÔì991ìäôìôìîöîî90K° TX½,@,,ÿÀ878YK° TK°T[K°T[X½,ÿÀ,,@878Y@aff*a++]]>32#"&'732654&+732654&#"DnÏdÆè·¡~vslRä•^Àc%^¿dÅõœ‘®¸¦¿Œ`Él° °”‘Ð&$˜}xÒL:9%%¿43Ë¢hq¤˜‚^g))%…Õ È@;   : d F   ÔÔäÀ991/äÔ<ì290KSXííííÉÉY"K° TK° T[K°T[K°T[K°T[K°T[X½ÿÀ@878Y@$:  +*) :89 6 f yu ˆ… š– ]]33##!7 !qþ¿Õ!ÕCÉDý^'7ýfþÕü3¨þ `Ãüã)ÿã¦Õ ‰@6  :dKOddFQ!   !ÔÔìÀ9991ÄäôìîöîþÄ90KSXíí2Y"K° TK°T[K°T[X½!ÿÀ!!@878Y!>32#"&'732654&#"¦ý–H._1Ïð{qPç‰Z¼g%\¹^Ãÿ§–O«Z‘Õ¨þÞ¾…ô\@E ¼--ê°‚%%îÿã¼ð *½@# d dk K hj(VQ+ "+ôìÔìÀÀ91äôìôìåîî90K° TX½+@++ÿÀ878Y@`z{J J JJ*Z Z ZZ*j j jj*z z zyz*Š Š ŠŠ*™ ™ ™™*© © ©©*¹ ¹ ¹¹*É É ÉÉ*Ù Ù ÙÙ*é é éé*-]]4&#"326.#">32#"5476$32¬‚p›ÓrœÑ":–UÏû>IÁp·ÙkfFºiÎîmbg%±N˜)“ï°„•õ:¸&(þüþëUWÓ²’û_AFäÔ‰˜ž¾Õ@:dFÔÌÄ991/ôì0KSXííY"K° TX½@ÿÀ878YK° TK°T[K°T[X½ÿÀ@878Y@ ')Zhxy]!#!þüªÞ'ýÕVú+Dÿã¾ð /c@#$d dd*VQg0$' -'!0ÔÄìÔìÄîî991ìäôìîî990K° TK° T[K°T[X½0ÿÀ00@878Y4&#"3264&#"326#"&5467.54$32ž€œË›„ÉgŒt‰±‹sв‰qxþÀý×þÚ¯in-çÁóµÅq»r†¶D_tštdzŸñ+®{ÏþôÓ° ù"$—lµóŘ„ÏZÿã˜ð*œ@("K"d kjh(dVQ+% +ÜìÔì91äôìæþõîî90K° TX½+@++ÿÀ878YK° TK°T[K°T[K°T[K°T[K°T[X½+ÿÀ++@878Y@FFFdddd•••• ]?32#"&5467>32#"&32654&#"Z%:”UÏý>JÃp¶×jgF¸hÏðobhþܲM™Ç„p›Ò‚r›Ò!¸&(UYÓ²’û^BFþùãÓþv˜žª••ój #k@(:HlHÔäÔäÀ91/ìôì0KSXííííY"K° TK°T[X½@ÿÀ878Y3#3#9Ó1ÓlÓ2Ó#þýÙþÿ## ¡@.   :HbHl   ÔäÄÔäÀ991äüìî0KSXíí9ííY"²]´]K° TK° T[K°T[X½ @ ÿÀ878Y@%%55FFVV ]73#3#´Ó#á¿Ó1Óþ¬þÀ@ÑþÙ^Û¦M@*````:nmüì291ôì90KSXííííY" 5Ûûøúþðþ‘þ“¶ѦÑÙ`Û¢@ ``ü<Ä21ÔìÔì0!!!!Ùúþúþ¢¨ðªÙ^Û¦O@+````:nmü<ì91ôì90KSXííííY"55Ùúþð¶þ/¦þ/¶müð! @F  : K!NZHV  !"ÔÔÔì9991/äüÌþôî9990KSXííí9íY"K° TX½"@""ÿÀ878Y@ t t ttt]%#7>32#7>?>54&#"þ1Ë1fËj¡ºkyhT8¾NojTDm`PÅhþþþ98–g´bTB^\{š^ƒ\YFj9LVGBwþžš 4@Z@3 5"!4;or!o%5o ro%.A>  !"4811(AÔÄüìîî991ÔÄüüÄìþÄýî2ÅÆ990%#"&543273654!"!267# 476$3 "32654&åE¡W“Á)Ç\‘'±äþ¶þú²þ´‘¢]ú‰R‡þÇ¥þ¾þUѼ‹h½A¥þiþÄÅreŽÀsîJLƘÜIPGƒý0Ñé'}r†þ ¸þûþ«W]rfi¬Gᥙr~þ†þäþÙþwúßœp~ä¦fyÿ“ìÕ £@@    :Z F   ÔÌ91/<äÔì90KSXííííííííY"²]@$‰ *HIHGWhgwˆ]]3#!# !òåÓ>ý`ÓÕ¨þ]$Õú+þý7Õ l@<:ZZFZs    !ôäÔìÔì9991/ììôìî90KSXííííY"!2!!!2654&#!2654&#ZÒг‘||þ³þßýñTjE·Æƒ‘ÍX-¡µz†ÕœÑž„áþúÉýݨ™vlfþ>Œ|aYVÿãðS@ ZetZVQ   ôÄì9991äôìôìîÖÆ0K° TK°T[X½ ÿÀ @878Y²o!].#"32$7# 476$32)`×}«þý^32.#"326^Nþ´…þÆŸþçþÃÁªkþ›Œu)Zò‰Ÿò_Q]ÖÔjÆß‡¦ýoIO8ç¡‹WUGG×^cylþÛ˜ÑÓ-7ÍÕ }@D     :ZsF    ôäôä9991/<ä2üì0KSXííííííííY"3!3#!#ZËwÝwËþÝË‹ý#‹ËÕýœdú+Çý97%Õ2@:FôäÀ91/ä0KSXííY"3#ZËþÝËÕú+þ°þf!Õ K@&  : ZvF    ÔÌ9991äüì990KSXí9íY"3##73267VËþñ5ûâP!?‡Œ%Õú“þñ󪚾7ÇÕ ó@G     :F    ôäÌ991/<ä290KSXííííííííY"²]@j$%#675HXkixxš  &&%'787=<IGFYX\[hfbbzxx~~…‡‰”$]]3! ##ZË{ ü‰‰öý¬ËÕý‹uý7üô×ý)7úÕ9@:ZFôäÌ9991/äì0KSXííY"3!!XËÿ×!ü^ÕúÓ¨7°Õ @Q     : F    ôäôä9991/<Ää290KSXííííííííY"²]@‚  )70 JC x‹‡‡ ˜Ÿ”• ­¯&)(') 2547 5 DGJCI F XYWhfw‹‡‡ˆ‡ ‡ –™”™¦ª£*]]!!## #Z/®B7þÝÄþý¶Å¾þÅÕüîú+üúß7ÅÕ Ó@@  :F   ôäôôÄ999991/<ä2990KSXííííííY"²]@P' ?6H[jŠ„ ")&5:=7IWY_ hkwŠˆ†‡­©¯ ]]!3!#ZœúÅþÝþïþeúÅÕûú+úøRÿãúð#P@ ZZVQ$  $ôìôì1äôìî0²0%]K°TK° T[K°T[K°T[X½$ÿÀ$$@878Y"32$7>54& 476$3 ¦¦þ^54&ã þèþÄyl}9½<þ¶þöËâ¦þ^>OO]]``¯¯]!!#!yï ýëÿËýðÕªúÕ+wÿã´Õ³@<     : ZQ F   ÔìÀÀ9991ä2ôì99990KSXíí9í9íY"@!     4 4 4 4 4 444]K° TX½@ÿÀ878Y²]332673!"$5467=˰ š•Á×.°Ë´;þ¶þáàþû Õüu=OŠÔï‹ü\þÒþàáÁ#W2 ðÕ„@&:FÔÌ91/ä290KSXííííY"²]@0*(8GGXWgieyywˆª©¨h†©]]!33¦þúÆÙÕÜü¡Õúüú+Å)Õ  @I      : F    ÔÌ91/<ä2290KSXííííííííY"² ]@‚ ()& ;;3 KF Š € Ÿ™Ÿ   ')$)+*(- & * 6756 6 8 KGCH G VV gihg g yx„‡ˆ†… „ —™›ª¨§1]]333##ÅÄH3áJ-ÍýhþEýÑþÕû öû öú+Ýû#ÿ¨ Õ M@I    : F    ÄÀ91/<ä290KSXííííííííY"²]@ )+) :8; IJI YZhhh y€Œ–—¨   ''()())& ( 8::665 5 8 FFGGD F H YYXT T X ffehfggfe e f zzzyu u ‡†‹‰‡‚ •——™˜Ÿ Ÿ ¤¨«¯ ¯ I]]3 3 # #ÌÏìý™sËþÓýßëºÕýåý7üôuý‹#hÕ¯@7:F ÔÄÄÀ9991/ä290KSXííííííY"²]@:(9IIZY{yŒ™——¨©$5Vjƒ“’§¦¨ ]]3 3#Ùãý[ŠÊ‰Õýšfüòý9ÇÿÓ Õ P@:ZFZ   ÔÌ91/ìôì0KSXííY"²x]@ „‰§¨w]]!!!7! ”û{¸ û=…üwÕšûoªš‘Rþò\Q@!:oo\ÔÄÔÄÖÆ991üìÔì0KSXííY"²ˆ]²Œ]!#3!´¨ïþÕïþXùü®ÿBÕ0@:FÔÄÀ91ôÌ0KSXÉÉY"#XÁ¨ÃÕùm“ÿ²þò¼D@ :oo\ÔÄÔÄÖÆ991üìÔì0KSXííY"!73#7¼þžþXï+íøÞÙ¨ÛÕ@ FÜÌ91ôÌ290##¼ÉþHþHÉÕýÓ‹þu-ÿìþþ¬¶oÔÌ1Ôì0!5ûØþ¬…ðfk¶ÔÌ91ÔÌ0K° TK°T[X½ÿÀ@878YK° TK° T[K°T[K°T[K°T[X½@ÿÀ878Y@ DDUgv†]#JÑšüfþŠvTÿã`{ +@d  #"$!)*(+:+(!!o (LK{LzQ +"! % %#% ",ôìÔì99991/Ääôüôìîî99990KSXíí9í9í9í9í9Y"²0]@.<<O[[jjzz‹‰ 2C@TPd`tpƒ€ ]]K°TX½,ÿÀ,,@878Y@¥        ! " #¥$ + ]#7#"&54$)7>54&#"7>32#"3267L}¸"QÏ·9 ‘ƒZ½d hÇ]ÆÏ ѸâÙob–à$ýªdc¯‰Ää1Yc..ª''¬¤!Y~yXd×´Jÿã²%²@M  $#$#"$# !#$#$#%$$#:! L LQz$\""#% !#$$%#$&ôäÔì999991/ìäôìî990KSXíí9í9íí9í9Y"²`']K°TX½&ÿÀ&&@878Y²Ÿ']4&#"3267>>32#"&'#3ö…uU•7:CƒsW”89FýÄDÍp¬ËwnH¼gm 2!¸/¸¬‘¤SOSÛmŠQORÚm\ièÆ¢þÐvNTdcª^ÿãJ{K@KN LKNLzQ  " ôÄì9991äôüôìþôî0K°TX½ ÿÀ @878Y.#"3267#"&547>32J%B•PXŸ6V^—šL«]#P©Yßð}{Tâ†Nš5¶00>9Wê}—”..¶!!ßÏ®%uPR#^ÿã%«@L   : L LQ z\%"&ôìÔä999991/ìäôìî990KSXí9ííí9í9í9Y"²`']K°TX½&ÿÀ&&@878Y%#"&547>323#3267>54&#"XJÊ{¨ÃvpJºfl¥-x¹þѹýèƒtV“8;DƒsW–5:E¨adåǦ-wOShabùì°‘¢SQTÜk‹œRMSÜ^ÿã‘{ &@$o KNL |L!zQ' $ #$#"'ôìÔì99991äôìäþôîî0²p(]K°TX½'ÿÀ''@878Y@,oooolo o o o$o%o&ŠŠ™™šš]]>54&#"!3267#"&547>32Ù{‰Ò65ü¨«œxÖ\#cÓméû}yN×y¾á ”"zŽ­Ÿ&,‹˜64¶((ßͯ-vJPäÀ.i‹Ó§@<      : o}\~      ÔÄÌ991/ä2üìî2990KSXí9íííY"K° TK° T[K° T[K° T[K°T[K°T[K°T[K°T[X½@ÿÀ878Y#"!!##737>3Ó°d[/þѾ¹¿°°&¿Í™Oicü/ÑNÆ BþVÅ{.Á@X"#!-.,   :#,K L#Lz,L~ )"/ôÄì99991/ääìôìþÕî99990KSXí9íí9í9í9í9Y"²`0]K°TX½/ÿÀ//@878Y!"&'7326?#"&547>3274&#"32Å¿7þÉþùa¦H"D˜V¯á$MÌvªÃvkG½gq¨) \€vI„/LUy¯ê`ü+þãþè³,*¿³TX\áÅ›)sLRi`®þeˆ”:4Vé|Š”=H‡µ@M   :  Lz\   '%$ôäÔì99991/<ìôì99990KSXíí9í9ííí9Y"²0]²`]K°TX½ÿÀ@878Y²Ÿ]#>54&#"#3>32uƒ¹ƒ j_”Ù y¸/¸wFÚx”£ ¤ý\/HT^Ȧý“ýœ^m ‘$RH/q@*:c\~(%$ôÄôäÀ9991/äüì0KSXííííY"²@ ]K°TX½ÿÀ@878Y3#3#w¸-¸'¸Û¸éËû ÿþV7µ@A : c }~\   (ÔÔä...À9991ìäôìî9990KSXíí9ííY"K° TK° T[X½@ÿÀ878Y@////PPPP```` ]3+732673#)¸Ý%0-­vE/l[3¸-¸`ûŒ¿GCHœZ (éHå á@H))     :~\   % $ ôäÌ9991/<ìä90KSXííííííííY"²]@>6STThi€“ ::@ XXWWiljyyy…Ž‰Šš]]K°TX½ ÿÀ @878Y33 ##w¸°wïý@ßþ"j¸üu×ýèý¸#ýÝH/U@:\%$ôäÀ91/ì0KSXííY"²@]²`]K°TX½ÿÀ@878Y3#w¸þѸùìH?{+ô@s    : # L& z~  #) # '#')$,ôÄÔììÔì99999991/<<äô<ì2990KSXíí9í9ííí9íí9Y"²0-]¶@-`-p-]K°TX½,ÿÀ,,@878Y#>54&#"#>54&#"#3>32>32/ƒ¸dZ†Ò{¸ƒdXˆÒ{¸Û¸#KÉszTÝ{¤ý\ž+>ZdÉ¡ýž%?[eÉ¡ý`®bg€rv|¦˜!OH‡{µ@M   :  Lz~   '*$ôäÔì99991/<äôì99990KSXíí9í9ííí9Y"²0]²`]K°TX½ÿÀ@878Y²Ÿ]#>54&#"#3>32uƒ¹ƒ j_”Ö!{¸Ù¸%MØw”£ ¤ý\/HT^Å©ý“`°aj ‘$R^ÿã‡{ ?@LL zQ! "!ôìÔì1äôìî0K°TX½!ÿÀ!!@878Y²p"]"&5467>323254&#"ÅåO?côš¿ëN?bôþy¹ó‚~h¢@/3óÒzýV†€îÀ…þøW†€˘—Cø‘”acJ¾ÿúþV¶{%È@O  $#$$#"$# !#$#$#%$$#:! LLzQ"$~&"&% !#$$%#&ÔäÔì999991äääôìî990KSXíí9í9íí9í9Y"K° TK° T[K°T[K°T[K°T[X½&@&&ÿÀ878Y¶`'p'Ÿ']4&#"3267>>32#"&'#3ø€xR•:9D€vW•59FýÆJÉ{¬¾voJºgw¢(s¸-¸²“œTPOànŒ—RNRÞiadá˦þÓwOScbý® ^þZÇ{"²@L  :LL zQ~#%"#ôìÔä999991äääôìî990KSXí9ííí9í9í9Y"²`$]²€$]K°TX½#ÿÀ##@878Y%#"&547>3273#3254&#"VJÉzªÁwoH»g| $ ¹þÕ¹þ:|u®öwW”7:C¨adåÉ¢.xNTbc¨ùüR”›Mî™QNRÜH´{©@4       : Lz ~   $ôÄÌ991/äôìÔÌ990KSXíí9í9íY"²O]@ T ][__]]K°TX½@ÿÀ878Y@@@@@@@@@P ].#"#3>32‘H)“Ü$q¸Û¸#IËs:¶ß»ýÅ`®ahÿã{(Â@?      :  KOLKOL&zQ)  #)ÔìÔìÀÀ9991äôüôìþõî990KSXí9í9Y"K° TK°T[K°T[X½)@))ÿÀ878Y@( //)X X X X XX ))99JJYY]].#"#"&'732654/.54$32#I¢V‘§Â;¸{þååYÄv$eÄZ‡©Þ?Œ‚ ç[­?®((cUc53pa²à"$¾46tY`;%y^³Òƒbž¦@>  : o~ }  ÄÀ991/ìô<Äì2990KSXíííí9Y"²]@ gyy]K° TK° T[K°T[K° T[X½@ÿÀ878Y!;#"&5467#733bþ‘wMUº°¤¡wœ™>¸=`ý ". @:š€‚7!`>þÂuÿã¶`Ã@L    :  LQ ~  'ÔìÔÄ99991/ä2ôì99990KSXíí9í9ííí9Y"K° TK° T[K° T[K°T[K°T[K°T[X½@ÿÀ878Y²`]332673#7#"&546‰ƒ¹ƒ h_”Ø!{¸Ù¸%N×y“¤ ¼¤ýc1FU]È©lû °bk¡Z“Õ`¹@'++++:~ÔÌ91/ä290KSXííííY"²]@,x…€%75IIgftsu‡‰‹]]K° TK° T[K° T[K°T[K°T[K°T[X½@ÿÀ878Y´0]33#“äÃýƒø`üH¸û ®` x@J++     + + : ~    ÔÌ91/<ä2290KSXííííííííY"² ]@˜5 ED ST gdvt ‚‡ € “    ,&( ) $ 6=768 3 6 LHJJII H F [XZYZX feeddf` f v{zyv v ‰Œ‰‡ † Š ˆ ›˜››• š =]]K°TK° T[K°T[X½ @ ÿÀ878Y@.«¥¡   ¸¿²² ° ° §¦¨§¤ © ¶·¶² · ]]333##®¶/¢Õ>¸þ×7þTÙ`ü{…ü{…û  ü`ÿËÍ` ‰@H++ + +  +  +++: ~   ÔÌ91/<ä290KSXííííííííY"²]@Ô*)&'%&)) ) + :865579 ; JIGEEGI J VVUVXW ffffefg f f vuvuuw v ‰‡„‡† ‡ Š •–˜—’–— ¥¥ ··J   &+)& 6886 FIIF Xihh wx Œ‰… š™– ¸È]]K° TK°T[K°T[K°T[X½ @ ÿÀ878Y² ] ## 3Íýþ;Óíþdß'þÛÓ×w`ýÛýżþDNþk•ÿÍþVÓ`2@F +  ++ +  + + :  } ~ ÔÌ991ä2ôì9990KSXííííí9íY"²]@f& 7 F v w v † “ &$$)9 9 98I I H Hwwwx x v v yyŠ‹ ‰ „ „ ‰ ˆ–––– ” ” – *]]K° TK° T[K°T[K°T[K°T[X½@ÿÀ878YK°TX½ÿÀ@878Y+7326?33ü€¡}‘jMlC9øÃºÁh×kšTzk7ü¦ZÿúX` @++:o~o   ÔÌ91/ìôì0KSXííY"²x]@…‡Š‘™xw‹ƒ]]K° TK°T[K°T[K°T[X½ @ ÿÀ878Y!!!7!îj!üµ¸üs!Kýk`¨üÛ“¨%øþ²×4@f -.-..-    : 5'- )'.)o'oo'\5)(54.  $-5ÄÀÀÀ9991üÄìÔìî99999990KSXí9í9í9í9Y"²]@K      % % % %%5 5 5 55H H H HHK K!K"K#K$K%Z Z!Z"Z#Z$Z%%]#";#"&546?47654&+7326?>7>3×Mˆ^3 yoIQ/UaNG¼¢- bq=> /G7.Š…O–ü ‘gKB&ô5?9m{ D%ë 2-UK“m—ô{'"þ®·€Ôì1üÌ0#®ªøþ²î4®@f -.-..-    :-5)  )'.'o)o)o\54.  5)('*(5ÄÀÀÀ991üìÄÔìî99999990KSXí9í9í9í9Y"732677667&&546776654&##73233#"#Nˆ^3!xoIP/UaNJ»£- bq>>~5F5/Š…þ²O–ü ‘fL@&ó"2@9l{D'ë 1-VJ“n–ô~&"ÙÓÛ1#@ `` ÔÄ1ÔüÔìÀ990#"'&'&'&#"56632326Ûi³an’ ›^X¬bi³an“ ›^V©1²OD;>MS²OE<>Lÿÿÿ“ìN'$Ùuÿ“ìm !Ú@P !  !   : Z S " !"ÔÔÔÄÔÄ999991/<ÄäÔìÆ9990KSXííííííííY"² ]@8 & 9MW‰  ( 98HGHW[YXX!gww Š ˆ‰]]4&#"326.54632#!# !üY?@WW@?YþÅ69 rr¡IEÓ>ý`ÓÕ¨þ]$Z?YWA?XXœ%qEr¡¡rOz$ú“þýÿÿVþuð'&Ýÿÿ7 k'( uÿÿ7Å^'1þuÿÿRÿãúN'2Tuÿÿwÿã´N'8úuÿÿTÿã‘f'DdÿÿTÿã`f'DCdÿÿTÿã`f'D×dÿÿTÿã`'DŽdÿÿTÿã7'DØdÿÿTÿã`'DÜdÿÿ^þuJ{'FÝwÿÿ^ÿãœf'Hoÿÿ^ÿã‘f'HCoÿÿ^ÿã‘f'H×oÿÿ^ÿã‘'HŽoÿÿH+f'ÖþþÿÿHf'ÖCþþÿÿHÏf'Ö×þþÿÿHð'ÖŽþþÿÿH¤7'Q؉ÿÿ^ÿã f'Rsÿÿ^ÿã‡f'RCsÿÿ^ÿã‡f'R×sÿÿ^ÿã‡'RŽsÿÿ^ÿãŽ7'RØsÿÿuÿã¶f'Xjÿÿuÿã¶f'XCjÿÿuÿã¶f'X×jÿÿuÿã¶'XŽjVÿ;Õ Y@.:L F   ÔÄÀ99991äôÔ<ì20KSXííííY"3!!#!7!5®Poþ’Ù°Ùþ‘pÕþ\™û£]™Ãu=ð  @‚ƒ‚ V ,-,Üìüì1ôìüì0"32654&'2#"&546PnnPPnoO@v+..¹†‡´¸ooPOmmOOp1.-rB„·´‡†º˜þÇ–!¤@[     ! : K NKNLL LLzQ"!    "ÔìÀÀÀ91ä2ô<ììÄÆîþôîõî0KSXÉ9ÉÉÉ9É9É9Y"&&'667#&&5%3ö²ðz€+I>#/|Y¨B”S#A’M54&#"#=& Ů٢È*01wRþêÚLŒ?A‹G|š/N3aCÔ­qd… Û¹qÅÞº“=%‡a(H%'^ƒP¬à¤r[-NC+RoC~Ê%NZˆ†û“åÍ/8L`@6EBC?2‡H0‡9JCˆ 9ˆ‡† ‡$HE301BKL?gwyVpMIßÑ`3þœDåÍ/IC@&=‰>:ŠAˆ$1‰04ŠGˆ‡†$‡ 73D=00*/D0/JÜÌüìþí2î1/îöþýîÖîýîÖî02#"$'&5476$"32676654&'&&&&#"3267#"&54632˜mmllmmþù˜˜þùmmllmm˜ƒâ^^``^^⃄ã^]]^\^ã§B‚B•§«›@zBC‰FØûûØIˆÍnmmþúš˜þûmmnnmm˜šmmng^^^å‚ã^^__^]⃅ã]^^õ! ¯Ÿ®"ôÐÑò'“FÕ >@!  ‡ F 4 4 545ÔäüäÔìÔì91ô<<ì2Ô<<Ä903#######5J®¤ªqÃ7ËrqËrÉÕÿý¾äþÑ/þB^þä^î-f…µÔÌ1ÔÌ0K° TK°T[X½ÿÀ@878YK° TK°T[K° T[K°T[K°T[X½@ÿÀ878YK° TX½€ÿ€878Y@VV……••¥¥]3#fÇþqšfþˆyFòš@‹ÔÜÔÌ99991Ô<ì20K° TK° T[K°T[K°T[K°T[X½@ÿÀ878YK° TK° T[X½@ÿÀ878Y@"@@@@QQQQOOOOPPPP]]3#%3# Í)Ë®Ë'ËÊÊÊÙ'ÛÝ>@" Œ` Œ `  Ü<Ä291Ô<Ì2ü<ìþ<ì990!!!!!'7!5!7!Ù}®/þHÃ{üúþþ}®þÕ¶Ãý‡¢;fÕ¨ðªþÇfÓªðÿ¤ôÕ»@L  : ZZZZF Zs  ÔÄ91/<ìÄìôììîî0KSXííííííííY"²]@-   GIIIGWXgfwuwwy†††] !%!!!!!!#¤þÊšÏ!ýXÈ!ý8iø!ü>IýòëÍ“7üðžªþFªýãªþÕÿºÿ¾y 7@B78(&# )562'#Z2Z#V2Q8',(68),  &,5 (,7,  8ôìôì.À99999991äôìîÀÀ999990@$7754709 &5&5' )765]]K° TK°T[K°T[K°T[X½8ÿÀ88@878Y@>IJ J7YZ d j gu { w…‰)˜– —D6C7WS6S7`6`7w q6q7…6…7”6”7]].#" 32$7>54&.5476$327#"&''Ç-’b¥ÿ\>A Éüu3“c¤[>? ûŠ''zm}9½‚ÒTËZÑ((vp€þ˽‹ÙLÜZÓ<=¢¢mîr-W,Ñü²DC£¡pëz8]üÁP¤U¦P‡ššMMÁcÆI©b±þµ‡œ˜TRËcÝÝÏî /<@- !$'!!0 $*0ÔÄÔÄ99991ÔÄÔÄÀ999032654&#"&&#"326#"&546326632#"&“1†Te€vYR…Ä1…UfvYR†F^ˆº§†_™HDža†¼§†^•/XZ‡ie†‡7XX„je†ˆ‡ߦ¯Ø~ŠŠƒá§¯ÖwÙÛ .@`  `   Ô<ì2ü<ì21/ìÔ<ìü<ì0!!#!5!!!®-ýÓ¨ýÓ-ýÓúþþ}ªþ}ƒªƒû¦ªÙÛ¨ T@.````:Žm`  ü<ì2291/ìôì90KSXííííY" 5!!Ûü@Àúþúþúþøþëþî²pªoüªÙÛ¨ V@/````:Žm`  ü<<ì291/ìôì90KSXííííY"55!5ÙúþÁAúþø°þ‘ªþ²ýǪª\bÕå@]  :    F    ÔÄÀ9991/ä2Ô<ì2Ô<ì290KSXííííííííY"²]@85ESww€  &&&::GFWUT``v vuuŠ]]!#!7!7'!7!33!!!bþeXËXþ`¡ 6þ³ ̾ðÂþRþ¸q šÇþ9Ç{3›{JýD¼ý¶{›3ÿåþV¼`&š@X   &#$"% : % L"Q ~'&'  %%'ÔäÀÀ9991ä2äô<ì990KSXíí9í9íí9íY"3326733267#"&5#"&'-¹ˆum”¶ ¸§ # ,P&BK8›i]‹lþV ýG4]d¨¨ü£  ”TJPNVFý×hÿçÁ-)6@'! '!’* $$*ÔÌÜÌ9991äÌÜÌÎÎ9906654&#"#"&54632#"&54324&#"32ôIH7$$0e´ÖþßÕ˜ËÝ¢e‚ WOmVPmmW£Kƒt,>bþÊþùþ±þFØ£Æ[àt}þþÏt{þw;Á [@    ÔÄ91ÄÔÌÎ990@.UPQVPb`g`e`tppupx V pp]]!! !!5 7êüA ýJïúÞÕýIÁÁý3ýÀ•!ãœþwqÁ@•”“77ÔìÔì1üìì20!#!#œÕðý ïÁø¶}ùƒÿáÿðª/#i@1 ˜—"–’ $ #" #8#$ÔÔÔì9999991/<äôì22î9990@ ]]#3267#"&5467!##"#>3!‡¶i/7.%7vy"PþºÂµÃ)6<  ¥y‘þJ\:1fd.¡xüo‘@E¦}/þú%&@ ™ ™š€& 9:9&Üìüì1üìÜäÞä026732#"&'&&#"#"&546327j ¾ÊPd@7*8  k½ÄOeD=!0 þú°l9¼TA6?&#Hý•Ánþ!þbSA8?SRÕ‘ð +/r@@ " œ.œ,#ž" œ,›œ&V0 .- )/,0 #";);0ÔìÔì9999991ôìüÄÌìÄôîîî99990"326?#7#"&5463356654&#"76632!!RŽLAs¢X•:™`kƒçж]dF‘IO˜D–™üܱýPPKS;F‡{=þ@pABzdŒŸFA""|x7ý¦{RÕ²ð 4@œ œ›œ V;;ÔìÔì99991ôìüìÜì04&#"3262#"&546766!!cat©c\z¨§”±þöË–¯&%>Ðþw±ýPœnsÖ—mvÓð¬Üþâ´šD…?jvü`{NÏç@@"  V   =<= < ÔììÔììÀÀ9991/<ì2ôì0%!5654#"!5!&5! Ïý¨±ÆþøØØþ÷Dzý¨?ž‘1/Ž¡²²²aLÊð"þÝïÊþ´a²²‹*¸>ŠþwþËÂþØTÿãœ{ >I@T5>3*# I?>?o3o$K#NF L' K>{;L| z-'Q3JI@C54?  >3 C8*? #$ ?C0"JôìÔìÔì9999999991Ää2ô<äü<ôìþ<ôîîî99990@2; ; K K \ \ k k { { ‹ ‹ 3=0>D=@>T=P>c=`>t=p>ƒ=€> ]]K°TX½JÿÀJJ@878Y@,oooolo ooooo¥1 2 3 4 ? @ A¥B–"™#]]>54&#">32>32!3267#"&'#"&54$)7>54&#"#"3267ãŽ|‰Ò6üñhÇ]º-Và„¾â ü¨«œx×["dÓm¨ã8fÜ„®Á9 ‘ƒZ½df¸âÙob–à$”"zŽ­Ÿš''Z\Z\äÀ.i<&,‹˜64¶((sqvn¤”Ää1Yc..þ°yXd×´ÿãÿ¢ú¸ '1é@B'2")( ,%" ,&",L"Lz"Q2/&2 )( / /% /' "2ôÄìÔìÀ99999991äôìîÀÀ99999990@DJ H EGV%U&X)kkg%b&f's&w'p3†I I FFU VWWY(fh%uvx%y&y'y)]]K°TX½2ÿÀ22@878Y·• ™(˜)]].#".5467>327#"&'' 324&…%]:ºðO?bóœW”:¢V¬O>aóžW“9¬VÞýŸ'[;½ïš#"þ¿ú/)1~KzÿV†€43¤V¬7}D|þýV†€54ªT3ýž%#G'&LÿåfÕ!½@I  : !HK!NZQF" ! $"ôìÔÔÄ9991äôüôìþÌ9990KSXííí9íY"K°TX½"ÿÀ""@878Y@#dddddddz y zzzz]73#"&546?>?33267d2Ê1gÊk¡¹kxgU9¾NnkTCm_QÄh×þþû98–g´bTD^Z{š^ƒ\YFj9LVGB®œÕ k@/ :HF   ÔÄôäÀ99991/ôüÌ0KSXí9íííY"²]´]!#3#73yËZ¢1pÊ1Íeþ›HþÙÛ^@ `ÜÔì1ÔÄì0!#!Ù¨û¦^ýÁ•=ÿ×} *@    ÔÌ91ÔÌÄ903##'%\½sý®BþÁ}}`ùºs-Pbý;ÿÑþVò#Ž@P !    :  M¡ ooM¡o!\$  $ $ÔÌ991Ä2äüìôìîî2õî99990KSXí9ííí9Y"&&#"!!#"&'73267!7!6632ò&P,`r<>þÃ9º­J{74a/am"‰þê?%Ê©.cå™z„þÉý…þéÙž!!‰¦­J¿»ÙÛô;?@.9*-" *`19`"` `<-<Ô<Ä21ÔìÔìÜüÔìÀ9999990#"'&'&'&#"56632326#"'&'&'&#"56632326Ûi³an’ ›^X¬bi³an“ ›^V©gi³an’ ›^X¬bi³an“ ›^V©o³NE;=LT³NE;=KÚ²OE;=LS²NE;=Kÿú`Á@ÔÌ91/ÄÌ90!3!¬þ^DýïàCúšîûÄú?q# 1@  ¢l   ÔÔÔÌ991ô<ì299077´'þžü%þ}â'þü%þ}#Éþòþöµ¢R¢Éþòþöµ¢Ro# 1@ ¢ l   ÔÜÔÌ991ô<ì2990%77779'cü'ü'`ú%É ´þ^Rþ^É ´þ^R…ßþ v@:    :H     ÔÄÔÄÔÄÀ999991/<<ì220KSXííííííY"73#%3#%3#¶Ó1Ó‡Ó1Óý…Ó1Óþþþþþþÿÿÿ“ìk'$Ùuÿÿÿ“ð^'$ÙuÿÿRÿãú^'2Tu^‰Õ #‹@9    :ZZ F Zs  #  $ôìÀÀÀ91/ìì2ôì2î0KSXííííY"K°TK° T[K°T[K°T[X½$ÿÀ$$@878Y#";!!!!!"&'&5476$3ºx¦þýW…Šý÷1°!ýXÇ!ý9hø!û¾¢±N¹¬{^á+LInþÓµËÑ+ªþFªýãª#F¼Ñt‡ba^ÿãß{(2A¸@9 /) )o K N6L|32>32'>54&#"3254&#"Çü¨ªœxÙ[%cÒm¡æ/e燿ëLBcôš‚Ç6còŽ¿á ¬{ŠÑ7üŒ¹óh¢@/32‹˜64¶')ncihîÀ‰X†€ulpqäÀ.iT"zŽ­Ÿå˜—@ù“”acJ¾ÿòéy@ o£ÔÌ991üì0!!üyÿòéy@ oÔÌ991Ôì0!!øy é+Õ —@1     :b F   ÔÄÄÔÄÄ991ô<ì20KSXíí9íí9Y"@1     *** * ::: : III I YYY Y ]#73#73ßÓ#áwÓ#áé­?þÁ­­?þÁé3Õ —@.     : bF    ÔÄÄÔÄÄÀ91ô<ì20KSXíí9íí9Y"² ]@1    %%% % 666 6 FFF F UUU U ]3#%3#ÇÓ#ႼÓ#áÕ¬þÀ@¬¬þÀ@ é‘ÕT@:bFÔÄÄ91ôì0KSXíí9Y"@  **99IIYY ]#73ßÓ#áé­?þÁéšÕV@:bFÔÄÄÀ1ôì0KSXíí9Y"²]@%%66FFVV ]3#ÇÓ!ã‚Õ¬þÀ@Ù–Ûo )@¤¤` > ÜÔ<ü<Ä1ÔÄüÄîî03#3#!!ßööööýúúþoöþõAªþ#îu"@ÔÌ91ÔÌ990 úþþôþ þ üÏüÇ9%ûÛûÓ-ÿÿÿÍþVÓ'\Ž^ÿÿhN'<uýçÿãmð_@:QVÔÄÀ1ää0KSXÉÉY"²]@) %86EYViexuuˆ…„™›˜]3#º³û/µðùó^R¼²#/ƒ@I -'! - -L¥¦'L¥!0 *$0* $ $?@*?0Üäìôäì9999999991ÔäìôäìÀ9999999907'#"&''7&&5467'766324&#"326{ÏrÎ%$&(ÑrÏ;t=:x=ÏqÏ%%&&ÏsÏ7t@?s9ÏqÏ(&%%ÏsÎ>v:@t8ÎsÏ'%$þ|pššprœ´#@ ¢lÔÌ91ôì907´%þœü%þ}#Éþòþöµ¢R´#@ ¢lÔÌ91ôì90777'dü#ƒÉ ´þ^R‹!ç@b  : o }c\~  (%ÔÄÔÔôä9991/<ä22ü<ììî2990KSXí9íííííííY"K° TK° T[K° T[K°T[K°T[K°T[X½@ÿÀ878Y¶__€]3#3#'#"!!##737>3»Û¹/¹-¹h°d[/þѾ¹¿°°&¿Í`û éé™Oicü/ÑNÆ ‹!Ô@J   : o }\ ~    %ÔÄÜä9991/<ä2üìî2990KSXí9íííííY"K° TK° T[K° T[K°T[K°T[K°T[X½@ÿÀ878Y@ ````` ` € ]!#!"!!##737>%üþѹþ¶d[/þѾ¹¿°°&¾ùì{Oicü/ÑNÇŸÿÝÿ;Õ†@I       :LL  F   ÔÄ.À999991äôÄ2Ô<î2î20KSXííííííY"%!#!7!!7!3!!!jþ’R°Rþ‘nkþ‘oR°Rpþ‘jnßþ\¤š™¤þ\™ýáéHîF/@:HÔäÀ91Ôì0KSXííY"3#Ó2ÓFþÿ‹þ4@:bHÔÄÄÀ1üì0KSXíí9Y"73#¸Ó#áþ¬þÀ@ÿ%þ ]@.     : bH    ÔÄÄÔÄÄÀ91ü<ì20KSXíí9íí9Y"73#%3#¸Ó#á¼Ó#áþ¬þÀ@¬¬þÀ@ºÿã ð #/;GKd@83W-WR'W9WBRI<QHVLHE0J*6 ?  $ !0 ? E* ! LÔììÔììÄîîþîî991ä2ô<<ä2ì2îöîî20"&54324&#"326"&54324&#"3264&#"326"&5432#s‰žç»‡çHMMo~PKkønˆŸèºˆŸèHNMp~QKk‚\LMoQKk€ÿˆžçºˆç›û. Ó²˜Ø °™×þóÛkjí]d¾£±˜Ø ³™ÖþõÛij­\d¾ý¾kjí]d¾þò˜Ø °™×þó ùó ÿÿÿ“ìm'$Ùuÿÿ7 m'( uÿÿÿ“ìk'$Ùuÿÿ7 N'( uÿÿ7 k'( uÿÿ7k',ÿ;uÿÿ7m',ÿ;uÿÿ7"N',ÿ;uÿÿ7Vk',ÿ;uÿÿRÿãúk'2TuÿÿRÿãúm'2TuÿÿRÿãúk'2Tuÿÿwÿã´k'8úuÿÿwÿã´m'8úuÿÿwÿã´k'8úuHÛ`O@:~$ôÄÀ91/ä0KSXííY"²@]K°TX½ÿÀ@878Y3##¸Û¸`û RîÑfd@ ÔÌ91ÔÌ290K° TK°T[X½ÿÀ@878YK° TK° T[K° T[K°T[K°T[X½@ÿÀ878Y3#'#‘”¬‹ê‹fþˆííP7ö@  ‚‚ ÔÌ91Ô<üÔ<ì99990K° TK° T[X½ÿÀ@878Y@  ]]K° TK° T[K° T[K°T[X½@ÿÀ878Y@!    ]K° TX½€ÿ€878YK°TK°T[X½@ÿÀ878Y'.'"#>322673#"&¢- '3}[%@/ &1}\&BZ7IR‰‘7GT‰‘}bðöd@ oÔÌ991Ôì0K° TK° T[K° T[K° T[K°T[K°T[X½@ÿÀ878YK°TK°T[X½@ÿÀ878Y!!šVýªö”š)H•@ ¨§ ÔÌÔÌ91ô<Ôì90K° TX½ÿÀ@878YK° TK° T[K° T[K° T[K°T[K°T[X½@ÿÀ878YK°TK°T[K°T[K°T[X½@ÿÀ878Y332673#"&546œrTVUnt ¾’€„HDCIM‹”};D/‡@:ÄÀ991ÔÌ0KSXÉÉY"K° TK° T[K° T[K° T[K°T[K°T[X½@ÿÀ878Y@OOPPUU]]K° TX½@ÿÀ878Y3#dË'Í̬áÑ Õ@  © ÔÌÔÌ1ÔÌôÌ0K° TK° T[X½ÿÀ@878Y@   ]K° TK° T[K°T[K°T[K°T[X½@ÿÀ878Y@I44400044 4 444000444OOKKKKK K O O O KKKKKKO$]K° TX½€ÿ€878Y#"&546324&#"326ÑŸtsŸŸstŸ{WABUUBCUôs  stžžt@WUBBVVdþu#&@  ª  ÔÄÜÄ991/ÔüÄ90!#"&'732654&'Ý$"“€+V+'O*32''%'3%.#"3254&øDEOKTõÆìRLXò‹:(|þ¡ G‹Ù`P#þÇ+W,Êþƒ¶ôufÝvˆýdt|ëÃxìet|´k^aÌ‘m_bþdþÓïŠCôDlÿÿhk'<uÿÿÿÍþVÓf'\^7žÕ q@= :Z Z­F  ôäÔì999991/ôüìÔì0KSXííííííY"!#3!232654&#DÿBË#Ë3 ÌÖþÄþqmþ¬¹|rRþ®Õþø¾·öþðÕýѯ¥hsÿúþV¶%Ä@L  $#$#"$# !#$#$#%$$#:! L LQz"$\&"&% !#$$#&ÔÄÔì999991ìÄäôìî990KSXíí9í9íí9í9Y"K° TK° T[K°T[K°T[K°T[X½&@&&ÿÀ878Y¶`'p'Ÿ']4&#"3267>>32#"&'#3ø€xR•:9D€vW•59FýÆJÉ{¬¾voJºgw¢(s¸}¸²“œTPOànŒ—RNRÞiadá˦þÓwOScbý®¾Ù-Û×¶`ÔÄ1Ôì0!!Ùúþת?œÅ …@M `  ````` ` ` :   Ô<Ì291Ô<Ì290KSXííííííííY" '7œþ7Éwþ5þ5vÈþ8vËËLþ5þ7yËþ5yÉËyþ5ˇœÇß ‚@/ AA:œ œ ®œV     ÔÄÀ9991ôììÔìî20KSXíí2Y"²]@  //??OO__]3?33!œÌwåæ‘Íý× c)t'ý+nJœðÕ@/AA:œœ œ®V CÔÔì9991ôììÔìî990KSXí9íY"²]@ )),,]K° TK° T[K°T[K°T[K°T[K°T[K°T[K°T[X½@ÿÀ878Y@#699FOOLLLLFYYjjzz] !!7>54&#"7>32“þ¹ý–¦;:TF7„SLˆ@{™@BþÌrnT.V(6C"${rY>q!òð(k@* œœ¯œ(œ¯%œ®V) (C "C)ÔÔìÔì991ôììôìîÆöîî90@(     ]]>32#"&'732654&+732654&#"×S~7}–raKP߸@‚@5p?{‹abV\fsRR8|=ÍiVMr^Hžy\R>?lH@55ÿÿ‡ÿãªð'ð'¼5 ‹ýdÿÿ‡ÿãŸð'ð'¼5ñ‹ýdÿÿ!ÿãªð'ò'¼5 ‹ýdÿÿ\ÿãÍm'* 'uÿÿBþVÅH'JÚ‹ÿÿ7`P', ÿ;uÿÿ þuÓð'6Ýdÿÿþu{'VÝÿÿVÿãk'&-uÿÿ^ÿã¤f'FwÿÿVÿãm'&-uÿÿ^ÿãf'Fàw^ÿãœ-Ú@i'&(% !"#$  :(°(L LQ z\%%".ôìÔäÀ999991/ìäôìîý<î2990KSXíí9í9íííí9í9Y"²`/]K°TX½.ÿÀ..@878Y%#"&547>32!7!733##3267>54&#"XJÊ{¨ÃvpJºfl¥-CþºF¹ššù¹ýèƒtV“8;DƒsW–5:E¨adåǦ-wOShaR{••{úü°‘¢SQTÜk‹œRMSÜ\ߘƒ@ cÔÌ991Ôì0!!}ýヤéHîF/@:HÔäÀ91Ôì0KSXííY"3#Ó2ÓFþÿÙÿãÛð+Œ@> ZetZ)% # )VQ,,%$#   &$,ÔÄÄÄüÄÄ9999999991ääÔ<Ì2ì2îöîîÖÆî20@o o ooooooo o! ].#"!!!!3267#"#73>7#7332Û!S§`ØG5þ ¼7þw Ÿ—mÀf'^Æaßþù Æ7‘ ­8—a@äg¹bÕe^ÃÀ{2f7{ÃÂV`ï34${7g1{GoçÙ²@‹ÔÜÔÌ99991Ô<ì20@"@@@@PPPPOOOO____]]K°TK°T[K°T[K° T[X½@ÿÀ878YK°TK°T[X½@ÿÀ878YK°TK°T[X½ÿÀ@878Y3#%3#–Ì)Ê®Ê&ËÙËËËîÕöµÔÄ1ÔÄ0@   ]K° TK° T[K° T[K°T[X½@ÿÀ878Y@ ]K° TX½ÿÀ@878Y@(**)66GGWW //]]K°TX½@ÿÀ878Y@ffŠŠœœ¯¯]3#ÏþÍžöþøLén@ W WÔÄ91Ô<üÔ<ì9990K°TK°T[X½@ÿÀ878YK°TK° T[X½@ÿÀ878Y/&#"#>3232673#"&¨#+&"6}#{U#=$ &'9 }!}\79 32mn 6.mnÑîöˆ¶ÔÄ91ÔÄ0K° TX½ÿÀ@878Y@ //]]K°TX½@ÿÀ878YK° TK°T[X½@ÿÀ878Y@ tt†ˆŠ‡]#‡”Œ¾öþøRîÍø@ ÔÄ91Ô<Ä90K° TK° T[K° T[K° T[X½ÿÀ@878Y@     ]K°TX½@ÿÀ878YK°TK°T[X½@ÿÀ878Y3#'#Xמ‡ŒÑ—øþö²²‘î øc@ ÔÄ91ÔÄ290@//// ]K° TX½ÿÀ@878YK°TX½@ÿÀ878Y#373Õž†‹Ñ—î ²²Tœß Ò@*A  A  A :œ  ®V     ÔÔÄÀ99991ôüÔ<ì290KSXíííY"K° TK° T[K° T[K° T[K°T[K°T[K°T[X½@ÿÀ878Y@)+/--/ / 6Fy¬]K°TK°T[K°T[K°T[X½€ÿ€878Y !33##7!7Zþw7R¦j‰‰%%þ`bþaýämººƒ…øø O@ ¨ ÔÌÔÌ1ÔüÄ20K°TK°T[X½@ÿÀ878YK°TX½ÿÀ@878Y332673#"&…w NLVlw"¸€yŒø=67?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ   0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•Íf‹‹5¢®Å´Dšº=`3Åžÿ=´Ù‹ã\‹w²ÿjfd%)¾DZ²j²´Ù´Ù´Ù?üwyÿ“}7–V)77š73\7\7\þ°?7u7ç7ü7LRÓ7LT7 ãXÛwy éÅ{ÿ¨ã{ÿÓR²®ÿ²´Ùÿì…çTJf^^ì^Ñ‹BH9H9ÿ¢H9HËHHå^ÿú^JH+#ƒu¼“‹®¼ÿ˼ÿÍ3ÿúø²´Ùyÿ“yÿ“–V7ü7LRÛwçTçTçTçTçTçTf^ì^ì^ì^ì^9H9H9H9HHå^å^å^å^å^uuuuVØ1¸3  `'y´ÙËÿ¤LÿºªÝ´Ù´Ù´Ù\ÿå#hdœ¶ÿá+/ÅRÅRNöTåÿã?L5®´Ù=ÿÑ´ÙZÿúðð…yÿ“yÿ“LR^9^ÿòÿò% %‹ ‹´Ùô¼ÿÍãVýç^33+‹+‹ÿÝ‹é‹% ͺyÿ“7yÿ“77\7\7\7\7LRLRLRÛwÛwÛw9HRP}š;¬dÉšÿ×L# +{ÿÓ3ÿú²3å\ã¼ÿÍÝ7ÿú´Ù´5‡5J5!Á‡Á‡Á!3\B\7 +–Vf^–Vf^^ã\‹éÿÙoLÑR‘5T…1ÿõÿ+   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ     sfthyphenperiodcenteredEuroc6459c6460c6461c6462c6463c6466c6467c6468c6469""""zƒýÎæF“½=r—ô8±<À9Û0© 9 ‚ é % F  Ÿ | Ü * r ´1‹²ñ‡µcçO¤-§0ZþÄ3t±Ø1G‹ZðHÛ_׃ VÔ`™WÝ2Ô f Ü!{!ú"‡"÷#Ñ$µ%m%Å&”&«'O'‘'ž(E(R(_(l(y(†(“( (­(º(Ç(Ô(á(î(û)))")/)<)I)V)c)p)})Š)—)¤)±)¾)Ë**M*Þ+O+ò,,f-8-Þ.o.´//f/«0411v1­1ô2:2Ý3h3Ã4 4/44í5o5½67 7Ó8i8¶8Ò99…9þ:$:a::ñ:ñ:þ; ;;›)>6>C>? ?0?R?÷@‹@öAAEAŽB4BABNB[BhBuB‚BBœB©B¶BÃBÐBÝBêB÷C,CpDDYDÂEE¤EØF.FoF³GGSG`GmGzG‡GªHHÄHÑHÞI@IàIöJZJ³KIKºKËKÜKíKúLLL!L.L;LHLULbMM0MUMâNON¾O"OuOÎPP˜PÚQÒv Ä7ÿk9ÿ­:ÿÜ;ÿ·<ÿk»ÿkêÿk$&$&$&$&$7ÿk$9ÿš$:ÿÜ$µþð$·þð%ÿÜ%<ÿÜ%»ÿÜ%êÿÜ&6&&µÿÓ&·ÿÓ&ã&&ù&)þø)ÿ)þø)ÿ·)ÿ·)$ÿˆ)Xÿ­)bÿˆ)~ÿ­)ÿ­)€ÿ­)ÿ­)­ÿˆ)®ÿˆ)Çÿˆ)Éÿˆ.ÿ2.&ÿÉ.2ÿÉ.8ÿÜ.Dÿ·.Hÿ·.Rÿ·.XÿÉ.\ÿÉ.dÿÉ.gÿÉ.hÿÜ.iÿ·.jÿ·.kÿ·.lÿ·.mÿ·.nÿ·.pÿ·.qÿ·.rÿ·.sÿ·.yÿ·.zÿ·.{ÿ·.|ÿ·.}ÿ·.~ÿÉ.ÿÉ.€ÿÉ.ÿÉ.‘ÿÉ. ÿÜ.¡ÿ¤.¯ÿÉ.°ÿÉ.±ÿ¤.ºÿÉ.ÐÿÉ.ÑÿÉ.ÒÿÉ.ÓÿÜ.ÔÿÜ.ÕÿÜ.ëÿÉ.ûÿÉ.ýÿÉ/ÿa/2ÿÁ/7ÿu/9ÿk/:ÿ­/<ÿ</\ÿ·/gÿÁ/‘ÿÁ/¯ÿÁ/°ÿÁ/´ÿD/µþ/¶ÿD/·þ/ºÿ·/»ÿ</ÐÿÁ/ÑÿÁ/ÒÿÁ/êÿ</ëÿ·2ÿ­2ÿ­2&2&2;ÿÉ3þæ3ÿ3þæ3ÿÜ3ÿÜ3$ÿš3bÿš3­ÿš3®ÿš3Çÿš3Éÿš4&66ÿ·6ãÿ·6ùÿ·7ÿ 7þÜ7ÿ 7ÿD7ÿD7$ÿD7Dÿ)7Fÿ7Hÿ7Rÿ7Uÿa7Vÿ 7Xÿ27ZÿY7\ÿN7bÿD7iÿ)7jÿ)7kÿ)7lÿ)7mÿ)7nÿ)7oÿ7pÿ7qÿ7rÿ7sÿ7yÿ7zÿ7{ÿ7|ÿ7}ÿ7~ÿ27ÿ27€ÿ27ÿ27 ÿ7¡ÿ7­ÿD7®ÿD7±ÿ7ºÿN7ÇÿD7ÉÿD7äÿ 7ëÿN7úÿ 7üÿ7þÿ9ÿ9ÿN9ÿ9ÿÉ9ÿÉ9$ÿu9Dÿ}9Hÿˆ9Rÿˆ9XÿÜ9bÿu9iÿ}9jÿ}9kÿ}9lÿ}9mÿ}9nÿ}9pÿˆ9qÿˆ9rÿˆ9sÿˆ9yÿˆ9zÿˆ9{ÿˆ9|ÿˆ9}ÿˆ9~ÿÜ9ÿÜ9€ÿÜ9ÿÜ9 ÿk9¡ÿˆ9­ÿu9®ÿu9±ÿˆ9Çÿu9Éÿu:ÿY:ÿa:ÿY:$ÿš:Dÿ:UÿÜ:bÿš:iÿ:jÿ:kÿ:lÿ:mÿ:nÿ: ÿ:­ÿš:®ÿš:µÿÜ:·ÿÜ:Çÿš:Éÿš;ÿD;&ÿÜ;2ÿ·;dÿÜ;gÿ·;‘ÿÜ;¯ÿ·;°ÿÉ;Ðÿ·;Ñÿ·;Òÿ·;ûÿÜ;ýÿÜ<þø<þæ<þø<ÿN<ÿN<$ÿa<&ÿÜ<2ÿÜ<DÿD<Hÿ<LÿÜ<Rÿ<XÿD<bÿa<dÿÜ<gÿÜ<iÿD<jÿD<kÿD<lÿD<mÿD<nÿD<pÿ<qÿ<rÿ<sÿ<yÿ<zÿ<{ÿ<|ÿ<}ÿ<~ÿD<ÿD<€ÿD<ÿD<‘ÿÜ< ÿD<¡ÿ<­ÿa<®ÿa<¯ÿÜ<°ÿÜ<±ÿ<´ÿÓ<¶ÿÓ<Çÿa<Éÿa<ÐÿÜ<ÑÿÜ<ÒÿÜ<ûÿÜ<ýÿÜ=ÿšIÿÜIÿÜIÿÜI´Iµ^I¶I·^UÿDUÿUÿDYÿYYÿYZÿ}Zÿ}\ÿa\ÿ·\ÿab&b&b&b&b7ÿkb9ÿšb:ÿÜbµþðb·þðd6&dµÿÓd·ÿÓdã&dù&gÿ­gÿ­g&g&g;ÿÉÿÜ‘ÿ­‘&‘ÿ­‘&‘&‘;ÿÜ­&­&­&­&­7ÿk­9ÿš­:ÿÜ­µþð­·þð®&®&®&®&®7ÿk®9ÿš®:ÿÜ®µþð®·þð¯ÿ­¯ÿ­¯&¯&¯;ÿÉ´$ÿ ´9K´</´bÿ ´þÓ´­ÿ ´®ÿ ´»/´Çÿ ´Éÿ ´ê/¶$ÿ ¶9K¶</¶bÿ ¶þÓ¶­ÿ ¶®ÿ ¶»/¶Çÿ ¶Éÿ ¶ê/ºÿaºÿ·ºÿa»þø»þæ»þø»ÿN»ÿN»$ÿa»&ÿÜ»2ÿÜ»DÿD»Hÿ»LÿÜ»Rÿ»XÿD»bÿa»dÿÜ»gÿÜ»iÿD»jÿD»kÿD»lÿD»mÿD»nÿD»pÿ»qÿ»rÿ»sÿ»yÿ»zÿ»{ÿ»|ÿ»}ÿ»~ÿD»ÿD»€ÿD»ÿD»‘ÿÜ» ÿD»¡ÿ»­ÿa»®ÿa»¯ÿÜ»°ÿÜ»±ÿ»´ÿÓ»¶ÿÓ»Çÿa»Éÿa»ÐÿÜ»ÑÿÜ»ÒÿÜ»ûÿÜ»ýÿÜÄ&ÿ·Ä2ÿ·Ä4ÿ·Ä7ÿÄ9þøÄ:ÿkÄ<þ­ÄIÿ·ÄYÿÄZÿ·Ä\ÿ¤Ädÿ·Ägÿ·Ä‘ÿÉįÿ·Ä°ÿ·Äºÿ¤Ä»þ­ÄÀÿ·ÄÁÿ·ÄÐÿ·ÄÑÿ·ÄÒÿ·Äêþ­Äëÿ¤Äûÿ·Äýÿ·Å&ÿ·Å2ÿ·Å4ÿ·Å7ÿÅ9þøÅ:ÿkÅ<þ­ÅIÿ·ÅYÿkÅZÿ·Å\ÿÅdÿ·Ågÿ·Å‘ÿÉůÿ·Å°ÿ·ÅºÿÅ»þ­ÅÀÿ·ÅÁÿ·ÅÐÿ·ÅÑÿ·ÅÒÿ·Åêþ­ÅëÿÅûÿ·Åýÿ·Ç&Ç&Ç&Ç&Ç7ÿkÇ9ÿšÇ:ÿÜǵþðÇ·þðÉ&É&É&É&É7ÿkÉ9ÿšÉ:ÿÜɵþðÉ·þðÐÿ­Ðÿ­Ð&Ð&Ð;ÿÉÑÿ­Ñÿ­Ñ&Ñ&Ñ;ÿÉÒÿ­Òÿ­Ò&Ò&Ò;ÿÉáÿaá2ÿÁá7ÿuá9ÿká:ÿ­á<ÿ<á\ÿ·ágÿÁá‘ÿÁá¯ÿÁá°ÿÁá´ÿDáµþá¶ÿDá·þáºÿ·á»ÿ<áÐÿÁáÑÿÁáÒÿÁáêÿ<áëÿ·ã6ÿ·ããÿ·ãùÿ·åÿšè&êþøêþæêþøêÿNêÿNê$ÿaê&ÿÜê2ÿÜêDÿDêHÿêLÿÜêRÿêXÿDêbÿaêdÿÜêgÿÜêiÿDêjÿDêkÿDêlÿDêmÿDênÿDêpÿêqÿêrÿêsÿêyÿêzÿê{ÿê|ÿê}ÿê~ÿDêÿDê€ÿDêÿDê‘ÿÜê ÿDê¡ÿê­ÿaê®ÿaê¯ÿÜê°ÿÜê±ÿê´ÿÓê¶ÿÓêÇÿaêÉÿaêÐÿÜêÑÿÜêÒÿÜêûÿÜêýÿÜëÿaëÿ·ëÿaìÿkìKìÿkù6ÿ·ùãÿ·ùùÿ·û6&ûµÿÓû·ÿÓûã&ûù&ý6&ýµÿÓý·ÿÓýã&ýù& MH@ mþ Íýçýé  GÌþBGÌSf  €¯ JBits ûþšmãB²‹`#cÕVeraSansObÿÿÿÿ6ÿÿþ628I00@                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              "                      "       #                       #     $               $    &              &    ÿÿÿð_<õº²Vúº¼”aýçþ mloganalyzer-3.6.5/src/statistics.php0000644000175000017500000001141612225176641017031 0ustar danieldaniel Shows Statistic, Charts and more * * All directives are explained within this file * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // *** Default includes and procedures *** // define('IN_PHPLOGCON', true); $gl_root_path = './'; // Now include necessary include files! include($gl_root_path . 'include/functions_common.php'); include($gl_root_path . 'include/functions_frontendhelpers.php'); include($gl_root_path . 'include/functions_filters.php'); // Include LogStream facility include($gl_root_path . 'classes/logstream.class.php'); InitPhpLogCon(); InitSourceConfigs(); InitFrontEndDefaults(); // Only in WebFrontEnd InitFilterHelpers(); // Helpers for frontend filtering! // --- // --- CONTENT Vars // --- // --- BEGIN Custom Code if ( isset($content['Charts']) ) { // This will enable to Stats View $content['statsenabled'] = true; // PreProcess Charts Array for display! $i = 0; // Help counter! foreach ($content['Charts'] as $myChartID => &$myChart ) { // Only process if chart is enabled if ( isset($myChart['chart_enabled']) && $myChart['chart_enabled'] == 1 ) { // Set Chart ID $myChart['CHART_ID'] = $myChartID; // --- Set display name for chart type switch($myChart['chart_type']) { case CHART_CAKE: $myChart['CHART_TYPE_DISPLAYNAME'] = $content['LN_CHART_TYPE_CAKE']; break; case CHART_BARS_VERTICAL: $myChart['CHART_TYPE_DISPLAYNAME'] = $content['LN_CHART_TYPE_BARS_VERTICAL']; break; case CHART_BARS_HORIZONTAL: $myChart['CHART_TYPE_DISPLAYNAME'] = $content['LN_CHART_TYPE_BARS_HORIZONTAL']; break; default: $myChart['CHART_TYPE_DISPLAYNAME'] = $content['LN_GEN_ERROR_INVALIDTYPE']; break; } // --- // --- Set display name for chart field if ( isset($myChart['chart_field']) && isset($fields[$myChart['chart_field']]) && isset($fields[$myChart['chart_field']]['FieldCaption']) ) $myChart['CHART_FIELD_DISPLAYNAME'] = $fields[$myChart['chart_field']]['FieldCaption']; else $myChart['CHART_FIELD_DISPLAYNAME'] = $myChart['chart_field']; // --- // --- Set showpercent display if ( $myChart['showpercent'] == 1 ) $myChart['showpercent_display'] = "Yes"; else $myChart['showpercent_display'] = "No"; // --- // --- Set Chart default Filterstring if ( strlen($myChart['chart_defaultfilter']) > 0 ) $myChart['chart_defaultfilter_urldecoded'] = urlencode($myChart['chart_defaultfilter']); else $myChart['chart_defaultfilter_urldecoded'] = ""; // --- // --- Set CSS Class if ( $i % 2 == 0 ) { $myChart['cssclass'] = "line1"; $myChart['rowbegin'] = ''; $myChart['rowend'] = ''; } else { $myChart['cssclass'] = "line2"; $myChart['rowbegin'] = ''; $myChart['rowend'] = ''; } $i++; // --- } } } else { // This will disable to Stats View and show an error message $content['statsenabled'] = false; // Set error code $content['ISERROR'] = true; $content['ERROR_MSG'] = GetErrorMessage(ERROR_CHARTS_NOTCONFIGURED); $content['detailederror_code'] = ERROR_CHARTS_NOTCONFIGURED; } // --- // --- BEGIN CREATE TITLE $content['TITLE'] = InitPageTitle(); // Append custom title part! $content['TITLE'] .= " :: " . $content['LN_MENU_STATISTICS']; // --- END CREATE TITLE // --- Parsen and Output InitTemplateParser(); $page -> parser($content, "statistics.html"); $page -> output(); // --- //include($gl_root_path . 'include/functions_installhelpers.php'); //ConvertCustomCharts(); ?>loganalyzer-3.6.5/src/css/0000755000175000017500000000000012225176641014713 5ustar danieldanielloganalyzer-3.6.5/src/css/defaults.css0000644000175000017500000000376712225176641017251 0ustar danieldaniel/* Generic Style definitions */ .ExpansionPlus { background-image: url("../images/icons/navigate_plus.png"); background-repeat: no-repeat; background-position: left center; padding-left: 20px; } .ExpansionMinus { background-image: url("../images/icons/navigate_minus.png"); background-repeat: no-repeat; background-position: left center; padding-left: 20px; } .HiddenContent { visibility: hidden; /* position: relative; */ display: none; } .ShownContent { visibility: visible; display: inline; } .borderless { border:0px solid; background-color: transparent; } .borderlessbuttons { border:0px solid; background-color: transparent; width:20px; padding: 0px; } .inlinebutton { float:left; position: relative; border:0px solid; background-color: transparent; padding: 0px; margin: 0px; } .SelectSavedFilter { margin-top: 2px; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .syslogdetails, a.syslogdetails, a.syslogdetails:link, a.syslogdetails:active, a.syslogdetails:visited { font-weight:normal; text-decoration:none; position:relative; overflow:visible; } .syslogdetails { position:relative; overflow:visible; z-index:4; } .syslogdetails:hover { position:relative; /*this is the key*/ font-weight:normal; z-index:5; } .syslogdetails span { position:relative; overflow:visible; display: none; z-index:-1; } /*the span will display just on :hover state*/ .syslogdetails_popup span { display:block; position:absolute; overflow:auto; z-index:5; /* top:15px; */ /* left:15px; */ } .gridline { vertical-align: top; height: 16px; } /* * POPUP Helper Styles */ .popupdetails { position: absolute; visibility: hidden; z-index:1 } .popupdetails:hover { position: absolute; visibility: hidden; z-index: 2; } .popupdetails_popup { position: absolute; visibility: visible; z-index: 2; } loganalyzer-3.6.5/src/css/highlight.css0000644000175000017500000000201012225176641017365 0ustar danieldaniel/* Generic Style definitions */ .highlight_1 { color: #F61313; background-color: #FFFFFF; } .highlight_2 { color: #F66913; background-color: #FFFFFF; } .highlight_3 { color: #17911C; background-color: #FFFFFF; } .highlight_4 { color: #C01695; background-color: #FFFFFF; } .highlight_5 { color: #1D618B; background-color: #FFFFFF; } .highlight_6 { color: #6C9117; background-color: #FFFFFF; } .highlight_7 { color: #0F2B7F; background-color: #FFFFFF; } .highlight_8 { color: #541791; background-color: #FFFFFF; } .highlight_9 { color: #146043; background-color: #FFFFFF; } .highlight_10 { color: #FF5451; background-color: #333333; } .highlight_11 { color: #F8C858; background-color: #333333; } .highlight_12 { color: #FCFF84; background-color: #333333; } .highlight_13 { color: #CEF07A; background-color: #333333; } .highlight_14 { color: #7AF0C2; background-color: #333333; } .highlight_15 { color: #84AFFF; background-color: #333333; } .highlight_16 { color: #A684FF; background-color: #333333; } loganalyzer-3.6.5/src/css/menu.css0000644000175000017500000000225212225176641016372 0ustar danieldaniel #menu { z-index: 10; /* width: 16px; /* set width of menu */ } #menu ul { /* remove bullets and list indents */ z-index: 10; position: relative; /* position: absolute;*/ display: block; list-style: none; white-space:nowrap; margin: 0; padding: 0; vertical-align: text-top; } /* style, color and size links and headings to suit */ #menu a, #menu h2 { display: block; margin: 0px; padding: 1px 1px; } #menu h2 { font-size: 10px; font-weight: bold; text-align: center; } #menu a { text-decoration: none; } #menu a:hover { text-decoration: none; } #menu li { text-align: left; /* make the list elements a containing block for the nested lists */ position: relative; } #menu ul li ul li { border-width: 1px; border-style: solid; border-color: #44617D #203040 #203040 #44617D; } #menu ul ul { z-index: 2; white-space: nowrap; position: absolute; top: 12px; /*14px; */ left: 0px; /* to position them to the right of their containing block */ width: auto; min-width: 250px; /* workaround for FF */ height: 16px; } div#menu ul ul, div#menu ul li:hover ul ul { display: none; } div#menu ul li:hover ul, div#menu ul ul li:hover ul { display: block; } loganalyzer-3.6.5/src/details.php0000644000175000017500000004016312225176641016265 0ustar danieldaniel Shows all possible details of a syslog message * * All directives are explained within this file * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // *** Default includes and procedures *** // define('IN_PHPLOGCON', true); $gl_root_path = './'; // Now include necessary include files! include($gl_root_path . 'include/functions_common.php'); include($gl_root_path . 'include/functions_frontendhelpers.php'); include($gl_root_path . 'include/functions_filters.php'); // Include LogStream facility include($gl_root_path . 'classes/logstream.class.php'); InitPhpLogCon(); InitSourceConfigs(); InitFrontEndDefaults(); // Only in WebFrontEnd InitFilterHelpers(); // Helpers for frontend filtering! // --- // --- Define Extra Stylesheet! //$content['EXTRA_STYLESHEET'] = '' . "\r\n"; //$content['EXTRA_STYLESHEET'] .= ''; // --- // --- CONTENT Vars if ( isset($_GET['uid']) ) { // Now check by numeric as uid can be larger than INT values if ( is_numeric($_GET['uid']) ) $content['uid_current'] = $_GET['uid']; else $content['uid_current'] = UID_UNKNOWN; } else $content['uid_current'] = UID_UNKNOWN; // Copy UID for later use ... $content['uid_fromgetrequest'] = $content['uid_current']; // Init Pager variables $content['uid_previous'] = UID_UNKNOWN; $content['uid_next'] = UID_UNKNOWN; $content['uid_first'] = UID_UNKNOWN; $content['uid_last'] = UID_UNKNOWN; $content['main_pagerenabled'] = false; $content['main_pager_first_found'] = false; $content['main_pager_previous_found'] = false; $content['main_pager_next_found'] = false; $content['main_pager_last_found'] = false; // --- // --- If set read direction property! // Set direction default $content['read_direction'] = EnumReadDirection::Backward; if ( isset($_GET['direction']) ) { if ( $_GET['direction'] == "next" ) { $content['skiprecords'] = 1; $content['read_direction'] = EnumReadDirection::Backward; } else if ( $_GET['direction'] == "previous" ) { $content['skiprecords'] = 1; $content['read_direction'] = EnumReadDirection::Forward; } else if ( $_GET['direction'] == "desc" ) { $content['read_direction'] = EnumReadDirection::Forward; } } // Read filter property in if ( isset($_POST['filter']) ) $myfilter = $_POST['filter']; else if ( isset($_GET['filter']) ) $myfilter = $_GET['filter']; else $myfilter = ""; // --- // Init Sorting variables $content['sorting'] = ""; $content['searchstr'] = $myfilter; $content['highlightstr'] = ""; $content['EXPAND_HIGHLIGHT'] = "false"; // --- BEGIN Custom Code if ( isset($content['Sources'][$currentSourceID]) ) // && $content['uid_current'] != UID_UNKNOWN ) // && $content['Sources'][$currentSourceID]['SourceType'] == SOURCE_DISK ) { // Obtain and get the Config Object $stream_config = $content['Sources'][$currentSourceID]['ObjRef']; // Create LogStream Object $stream = $stream_config->LogStreamFactory($stream_config); $stream->SetFilter($content['searchstr']); // --- Init the fields we need foreach($fields as $mycolkey => $myfield) { $content['fields'][$mycolkey]['FieldID'] = $mycolkey; $content['fields'][$mycolkey]['FieldCaption'] = $myfield['FieldCaption']; $content['fields'][$mycolkey]['FieldType'] = $myfield['FieldType']; $content['fields'][$mycolkey]['DefaultWidth'] = $myfield['DefaultWidth']; // Append to columns array $content['AllColumns'][] = $mycolkey; } // --- $res = $stream->Open( $content['AllColumns'], true ); if ( $res == SUCCESS ) { // Set Read direction $stream->SetReadDirection($content['read_direction']); // Set current ID and init Counter $uID = $content['uid_current']; if ( $uID != UID_UNKNOWN ) // We know the UID, so read from where we know $ret = $stream->Read($uID, $logArray); else // Unknown UID, so we start from first! $ret = $stream->ReadNext($uID, $logArray); // --- If set we move forward / backward! if ( isset($content['skiprecords']) && $content['skiprecords'] >= 1 ) { $counter = 0; while( $counter < $content['skiprecords'] && ($ret = $stream->ReadNext($uID, $logArray)) == SUCCESS) { // Increment Counter $counter++; } } // --- // Set new current uid! if ( isset($uID) && $uID != UID_UNKNOWN ) $content['uid_current'] = $uID; // now we know enough to set the page title! $content['TITLE'] = "LogAnalyzer :: " . $content['LN_DETAILS_DETAILSFORMSG'] . " '" . $uID . "'"; // We found matching records, so continue if ( $ret == SUCCESS ) { // --- PreChecks to be done // Set Record Count $content['main_recordcount'] = $stream->GetMessageCount(); if ( $content['main_recordcount'] != -1 ) $content['main_recordcount_found'] = true; else $content['main_recordcount_found'] = false; // --- // Loop through fields - Copy value into fields list! We are going to use this list here $counter = 0; foreach($content['fields'] as $mycolkey => $myfield) { if ( isset($logArray[$mycolkey]) && ( is_array($logArray[$mycolkey]) || (is_string($logArray[$mycolkey]) && strlen($logArray[$mycolkey]) > 0)) || (is_numeric($logArray[$mycolkey])) ) { $content['fields'][$mycolkey]['fieldenabled'] = true; // // Default copy value into array! // $content['fields'][$mycolkey]['FieldValue'] = $logArray[$mycolkey]; // --- Set CSS Class if ( $counter % 2 == 0 ) $content['fields'][$mycolkey]['cssclass'] = "line1"; else $content['fields'][$mycolkey]['cssclass'] = "line2"; if ( $mycolkey == SYSLOG_MESSAGE ) $content['fields'][$mycolkey]['menucssclass'] = "cellmenu1_naked"; else $content['fields'][$mycolkey]['menucssclass'] = "cellmenu1"; // --- // Set defaults $content['fields'][$mycolkey]['fieldbgcolor'] = ""; $content['fields'][$mycolkey]['hasdetails'] = "false"; if ( $content['fields'][$mycolkey]['FieldType'] == FILTER_TYPE_DATE ) { $content['fields'][$mycolkey]['fieldvalue'] = GetFormatedDate($logArray[$mycolkey]); // TODO: Show more! } else if ( $content['fields'][$mycolkey]['FieldType'] == FILTER_TYPE_NUMBER ) { $content['fields'][$mycolkey]['fieldvalue'] = $logArray[$mycolkey]; // Special style classes and colours for SYSLOG_FACILITY if ( $mycolkey == SYSLOG_FACILITY ) { // if ( isset($logArray[$mycolkey][SYSLOG_FACILITY]) && strlen($logArray[$mycolkey][SYSLOG_FACILITY]) > 0) if ( isset($logArray[$mycolkey]) && is_numeric($logArray[$mycolkey]) ) { $content['fields'][$mycolkey]['fieldbgcolor'] = 'bgcolor="' . $facility_colors[ $logArray[SYSLOG_FACILITY] ] . '" '; $content['fields'][$mycolkey]['cssclass'] = "lineColouredBlack"; // Set Human readable Facility! $content['fields'][$mycolkey]['fieldvalue'] = GetFacilityDisplayName( $logArray[$mycolkey] ); } else { // Use default colour! $content['fields'][$mycolkey]['fieldbgcolor'] = 'bgcolor="' . $facility_colors[SYSLOG_LOCAL0] . '" '; } } else if ( $mycolkey == SYSLOG_SEVERITY ) { // if ( isset($logArray[$mycolkey][SYSLOG_SEVERITY]) && strlen($logArray[$mycolkey][SYSLOG_SEVERITY]) > 0) if ( isset($logArray[$mycolkey]) && is_numeric($logArray[$mycolkey]) ) { $content['fields'][$mycolkey]['fieldbgcolor'] = 'bgcolor="' . $severity_colors[ $logArray[SYSLOG_SEVERITY] ] . '" '; $content['fields'][$mycolkey]['cssclass'] = "lineColouredWhite"; // Set Human readable Facility! $content['fields'][$mycolkey]['fieldvalue'] = GetSeverityDisplayName( $logArray[$mycolkey] ); } else { // Use default colour! $content['fields'][$mycolkey]['fieldbgcolor'] = 'bgcolor="' . $severity_colors[SYSLOG_INFO] . '" '; } } else if ( $mycolkey == SYSLOG_MESSAGETYPE ) { // if ( isset($logArray[$mycolkey][SYSLOG_MESSAGETYPE]) ) if ( isset($logArray[$mycolkey]) && is_numeric($logArray[$mycolkey]) ) { $content['fields'][$mycolkey]['fieldbgcolor'] = 'bgcolor="' . $msgtype_colors[ $logArray[SYSLOG_MESSAGETYPE] ] . '" '; $content['fields'][$mycolkey]['cssclass'] = "lineColouredBlack"; // Set Human readable Facility! $content['fields'][$mycolkey]['fieldvalue'] = GetMessageTypeDisplayName( $logArray[$mycolkey] ); } else { // Use default colour! $content['fields'][$mycolkey]['fieldbgcolor'] = 'bgcolor="' . $msgtype_colors[IUT_Unknown] . '" '; } } } else if ( $content['fields'][$mycolkey]['FieldType'] == FILTER_TYPE_STRING ) { if ( $mycolkey == SYSLOG_MESSAGE ) $content['fields'][$mycolkey]['fieldvalue'] = ReplaceLineBreaksInString( GetStringWithHTMLCodes($logArray[$mycolkey]) ); else // kindly copy! $content['fields'][$mycolkey]['fieldvalue'] = ReplaceLineBreaksInString( $logArray[$mycolkey] ); // --- HOOK here to add context links! AddContextLinks($content['fields'][$mycolkey]['fieldvalue']); // --- } // Increment helpcounter $counter++; } else $content['fields'][$mycolkey]['fieldenabled'] = false; } // --- Now Check for dynamic fields! $counter = 0; foreach($logArray as $mydynkey => $mydynvalue) { // Check if field is already in fields array if ( !isset($content['fields'][$mydynkey]) && isset($mydynvalue) && strlen($mydynvalue) > 0 ) { $content['dynamicfields'][$mydynkey]['dynfieldkey'] = $mydynkey; $content['dynamicfields'][$mydynkey]['dynfieldvalue'] = $mydynvalue; // --- Set CSS Class if ( $counter % 2 == 0 ) $content['dynamicfields'][$mydynkey]['dyncssclass'] = "line1"; else $content['dynamicfields'][$mydynkey]['dyncssclass'] = "line2"; // --- // Increment helpcounter $counter++; } } // Enable dynamic Fields if ( isset($content['dynamicfields']) ) $content['dynamicfieldsenabled'] = "true"; // --- // echo "
    ";
    //	var_dump($content['dynamicfields']);
    //	echo "
    "; // Enable pager if the count is above 1 or we don't know the record count! if ( $content['main_recordcount'] > 1 || $content['main_recordcount'] == -1 ) { // Enable Pager in any case here! $content['main_pagerenabled'] = true; // --- Handle uid_first page button if ( $content['uid_fromgetrequest'] == $content['uid_first'] && $content['read_direction'] != EnumReadDirection::Forward ) $content['main_pager_first_found'] = false; else { // Probe next item ! $ret = $stream->ReadNext($uID, $tmpArray); if ( $content['read_direction'] == EnumReadDirection::Backward ) { if ( $content['uid_fromgetrequest'] != UID_UNKNOWN ) $content['main_pager_first_found'] = true; else $content['main_pager_first_found'] = false; } else { if ( $ret == SUCCESS && $uID != $content['uid_fromgetrequest']) $content['main_pager_first_found'] = true; else $content['main_pager_first_found'] = false; } } // --- // --- Handle uid_last page button if ( $content['uid_fromgetrequest'] == $content['uid_last'] && $content['read_direction'] != EnumReadDirection::Backward ) $content['main_pager_last_found'] = false; else { // Probe next item ! $ret = $stream->ReadNext($uID, $tmpArray); if ( $content['read_direction'] == EnumReadDirection::Forward ) { if ( $ret != SUCCESS || $uID != $content['uid_current'] ) $content['main_pager_last_found'] = true; else $content['main_pager_last_found'] = false; } else { if ( $ret == SUCCESS && $uID != $content['uid_current'] ) $content['main_pager_last_found'] = true; else $content['main_pager_last_found'] = false; } } // --- // --- Handle uid_last page button // Option the last UID from the stream! // $content['uid_last'] = $stream->GetLastPageUID(); // $content['uid_first'] = $stream->GetFirstPageUID(); // --- Handle uid_first and uid_previousbutton if ( $content['uid_current'] == $content['uid_first'] || !$content['main_pager_first_found'] ) { $content['main_pager_first_found'] = false; $content['main_pager_previous_found'] = false; } else { $content['main_pager_first_found'] = true; $content['main_pager_previous_found'] = true; } // --- // --- Handle uid_next and uid_last button if ( /*$content['uid_current'] == $content['uid_last'] ||*/ !$content['main_pager_last_found'] ) { $content['main_pager_next_found'] = false; $content['main_pager_last_found'] = false; } else { $content['main_pager_next_found'] = true; $content['main_pager_last_found'] = true; } // --- } else // Disable pager in this case! $content['main_pagerenabled'] = false; // This will enable to Main SyslogView $content['messageenabled'] = "true"; } else { // Disable view and print error state! $content['messageenabled'] = "false"; // Set error code $content['error_code'] = $ret; if ( $ret == ERROR_UNDEFINED ) $content['detailederror'] = "Undefined error happened within the logstream."; else $content['detailederror'] = "Unknown or unhandeled error occured."; // Add extra error stuff if ( isset($extraErrorDescription) ) $content['detailederror'] .= "

    " . GetAndReplaceLangStr( $content['LN_SOURCES_ERROR_EXTRAMSG'], $extraErrorDescription); } } else { // This will disable to Main SyslogView and show an error message $content['messageenabled'] = "false"; // Set error code $content['error_code'] = $ret; if ( $ret == ERROR_FILE_NOT_FOUND ) $content['detailederror'] = $content['LN_ERROR_FILE_NOT_FOUND']; else if ( $ret == ERROR_FILE_NOT_READABLE ) $content['detailederror'] = $content['LN_ERROR_FILE_NOT_READABLE']; else $content['detailederror'] = $content['LN_ERROR_UNKNOWN']; } // Close file! $stream->Close(); } // --- // --- BEGIN CREATE TITLE $content['TITLE'] = InitPageTitle(); if ( $content['messageenabled'] == "true" ) { // Append custom title part! $content['TITLE'] .= " :: Details for '" . $content['uid_current'] . "'"; } else { // APpend to title Page title $content['TITLE'] .= " :: Unknown uid"; } // --- END CREATE TITLE // --- Parsen and Output InitTemplateParser(); $page -> parser($content, "details.html"); $page -> output(); // --- ?>loganalyzer-3.6.5/src/.htaccess0000644000175000017500000000002112225176641015712 0ustar danieldanielOptions -indexes loganalyzer-3.6.5/src/classes/0000755000175000017500000000000012225176641015560 5ustar danieldanielloganalyzer-3.6.5/src/classes/enums.class.php0000644000175000017500000000374212225176641020532 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- /** * ENUM of available ReadDirection. */ abstract class EnumReadDirection { const Forward = 1; const Backward = 2; } /** * ENUM of available Sorting Orders. */ abstract class EnumSortingOrder { const Ascending = 1; const Descending = 2; } /** * Available modes of seek */ abstract class EnumSeek { const BOS = 1; // seek from begin stream const EOS = 2; // seek from end of stream const UID = 3; // seek from position uid (which MUST be a *valid* uid!) } ?> loganalyzer-3.6.5/src/classes/logstreamdb.class.php0000644000175000017500000017105012225176641021704 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Required Includes! require_once($gl_root_path . 'include/constants_errors.php'); // --- class LogStreamDB extends LogStream { private $_dbhandle = null; // Helper to store the database records private $bufferedRecords = null; private $_currentRecordStart = 0; private $_currentRecordNum = 0; private $_totalRecordCount = -1; private $_previousPageUID = -1; private $_lastPageUID = -1; private $_firstPageUID = -1; private $_currentPageNumber = 0; private $_SQLwhereClause = ""; private $_myDBQuery = null; // Constructor public function LogStreamDB($streamConfigObj) { $this->_logStreamConfigObj = $streamConfigObj; if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) { // Probe if a function exists! if ( !function_exists("mysql_connect") ) DieWithFriendlyErrorMsg("Error, MYSQL Extensions are not enabled! Function 'mysql_connect' does not exist."); } } /** * Open and verifies the database conncetion * * @param arrProperties array in: Properties wish list. * @return integer Error stat */ public function Open($arrProperties) { global $dbmapping; // Initialise Basic stuff within the Classs $this->RunBasicInits(); // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Copy the Property Array $this->_arrProperties = $arrProperties; // Check if DB Mapping exists if ( !isset($dbmapping[ $this->_logStreamConfigObj->DBTableType ]) ) return ERROR_DB_INVALIDDBMAPPING; // Create SQL Where Clause first! $res = $this->CreateSQLWhereClause(); if ( $res != SUCCESS ) return $res; // Success, this means we init the Pagenumber to ONE! $this->_currentPageNumber = 1; // reached this point means success! return SUCCESS; } /* * Helper function to clear the current querystring! */ public function ResetFilters() { // Clear _SQLwhereClause variable! $this->_SQLwhereClause = ""; } /** * Close the database connection. * * @return integer Error state */ public function Close() { if ($this->_dbhandle) mysql_close($this->_dbhandle); $this->_dbhandle = null; return SUCCESS; } /** * Verify if the database connection exists! * * @return integer Error state */ public function Verify() { // Try to connect to the database if ( $this->_dbhandle == null ) { // Forces to open a new link in all cases! $this->_dbhandle = @mysql_connect($this->_logStreamConfigObj->DBServer,$this->_logStreamConfigObj->DBUser,$this->_logStreamConfigObj->DBPassword, true); if (!$this->_dbhandle) { if ( isset($php_errormsg) ) { global $extraErrorDescription; $extraErrorDescription = $php_errormsg; } // Return error code return ERROR_DB_CONNECTFAILED; } } // Select the database now! $bRet = @mysql_select_db($this->_logStreamConfigObj->DBName, $this->_dbhandle); if(!$bRet) { if ( isset($php_errormsg) ) { global $extraErrorDescription; $extraErrorDescription = $php_errormsg; } // Return error code return ERROR_DB_CANNOTSELECTDB; } // Check if the table exists! $numTables = @mysql_num_rows( mysql_query("SHOW TABLES LIKE '%" . $this->_logStreamConfigObj->DBTableName . "%'")); if( $numTables <= 0 ) return ERROR_DB_TABLENOTFOUND; // reached this point means success ;)! return SUCCESS; } /* * Implementation of VerifyFields: Checks if fields exist in table */ public function VerifyFields( $arrProperitesIn ) { global $dbmapping, $fields; // Get List of Indexes as Array $arrFieldKeys = $this->GetFieldsAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { // echo $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "
    "; if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrFieldKeys) ) { OutputDebugMessage("LogStreamDB|VerifyFields: Found Field for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_ULTRADEBUG); continue; } else { // Index is missing for this field! OutputDebugMessage("LogStreamDB|VerifyFields: Missing Field for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_WARN); return ERROR_DB_DBFIELDNOTFOUND; } } // Successfull return SUCCESS; } /* * Implementation of VerifyIndexes: Checks if indexes exist for desired fields */ public function VerifyIndexes( $arrProperitesIn ) { global $dbmapping, $fields; // Get List of Indexes as Array $arrIndexKeys = $this->GetIndexesAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { // echo $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "
    "; if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrIndexKeys) ) { OutputDebugMessage("LogStreamDB|VerifyIndexes: Found INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_ULTRADEBUG); continue; } else { // Index is missing for this field! OutputDebugMessage("LogStreamDB|VerifyIndexes: Missing INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_WARN); return ERROR_DB_INDEXESMISSING; } } // Successfull return SUCCESS; } /* * Implementation of VerifyChecksumTrigger: Checks if checksum trigger exists */ public function VerifyChecksumTrigger( $myTriggerProperty ) { global $dbmapping, $fields; // Get List of Triggers as Array $arrIndexTriggers = $this->GetTriggersAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; $szDBName = $this->_logStreamConfigObj->DBName; $szTableName = $this->_logStreamConfigObj->DBTableName; $szDBTriggerField = $dbmapping[$szTableType]['DBMAPPINGS'][$myTriggerProperty]; // Create Triggername | lowercase! $szTriggerName = strtolower( $szDBName . "_" . $szTableName . "_" . $szDBTriggerField ); // Try to find logstream trigger if ( count($arrIndexTriggers) > 0 ) { if ( in_array($szTriggerName, $arrIndexTriggers) ) return SUCCESS; else { // Index is missing for this field! OutputDebugMessage("LogStreamDB|VerifyChecksumTrigger: Missing TRIGGER '" . $szTriggerName . "' for Table '" . $szTableName . "'", DEBUG_WARN); return ERROR_DB_TRIGGERMISSING; } } else { // Index is missing for this field! OutputDebugMessage("LogStreamDB|VerifyChecksumTrigger: No TRIGGERS found in your database", DEBUG_WARN); return ERROR_DB_TRIGGERMISSING; } } /* * Implementation of CreateMissingIndexes: Checks if indexes exist for desired fields */ public function CreateMissingIndexes( $arrProperitesIn ) { global $dbmapping, $fields, $querycount; // Get List of Indexes as Array $arrIndexKeys = $this->GetIndexesAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrIndexKeys) ) continue; else { // Update Table schema now! $szSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " ADD INDEX ( " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " )"; // Index is missing for this field! OutputDebugMessage("LogStreamDB|CreateMissingIndexes: Createing missing INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' - " . $szSql, DEBUG_INFO); // Add missing INDEX now! $myQuery = mysql_query($szSql, $this->_dbhandle); if (!$myQuery) { // Return failure! $this->PrintDebugError("Dynamically Adding INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' failed with Statement: '" . $szSql . "'"); return ERROR_DB_INDEXFAILED; } } } // Successfull return SUCCESS; } /* * Implementation of CreateMissingFields: Checks if indexes exist for desired fields */ public function CreateMissingFields( $arrProperitesIn ) { global $dbmapping, $fields, $querycount; // Get List of Indexes as Array $arrFieldKeys = $this->GetFieldsAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrFieldKeys) ) continue; else { if ( $this->HandleMissingField( $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrProperitesIn ) == SUCCESS ) { // Index is missing for this field! OutputDebugMessage("LogStreamDB|CreateMissingFields: Createing missing FIELD for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], DEBUG_INFO); } else { // Return failure! $this->PrintDebugError("Dynamically Adding FIELD for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' failed!"); return ERROR_DB_ADDDBFIELDFAILED; } } } // Successfull return SUCCESS; } /* * Implementation of GetCreateMissingTriggerSQL: Creates SQL needed to create a TRIGGER */ public function GetCreateMissingTriggerSQL( $myDBTriggerField, $myDBTriggerCheckSumField ) { global $dbmapping, $fields, $querycount; // Get List of Triggers as Array $szDBName = $this->_logStreamConfigObj->DBName; $szTableName = $this->_logStreamConfigObj->DBTableName; // Create Triggername $szTriggerName = $szDBName . "_" . $szTableName . "_" . $myDBTriggerField; // Create TRIGGER SQL! $szSql = "CREATE TRIGGER " . $szTriggerName . " BEFORE INSERT ON `" . $szTableName . "` FOR EACH ROW BEGIN SET NEW." . $myDBTriggerCheckSumField . " = crc32(NEW." . $myDBTriggerField . "); END ;"; return $szSql; } /* * Implementation of CreateMissingTrigger: Creates missing triggers ! */ public function CreateMissingTrigger( $myTriggerProperty, $myCheckSumProperty ) { global $dbmapping, $fields, $querycount; // Get List of Triggers as Array $szTableName = $this->_logStreamConfigObj->DBTableName; $szTableType = $this->_logStreamConfigObj->DBTableType; $szDBTriggerField = $dbmapping[$szTableType]['DBMAPPINGS'][$myTriggerProperty]; $szDBTriggerCheckSumField = $dbmapping[$szTableType]['DBMAPPINGS'][$myCheckSumProperty]; // Get SQL Code to create the trigger! $szSql = $this->GetCreateMissingTriggerSQL( $szDBTriggerField, $szDBTriggerCheckSumField ); // Index is missing for this field! OutputDebugMessage("LogStreamDB|CreateMissingTrigger: Creating missing TRIGGER for '" . $szTableName . "' - $szDBTriggerCheckSumField = crc32(NEW.$szDBTriggerField)" . $szSql, DEBUG_INFO); // Add missing INDEX now! $myQuery = mysql_query($szSql, $this->_dbhandle); if (!$myQuery) { // Return failure! $this->PrintDebugError("Dynamically Adding TRIGGER for '" . $szTableName . "' failed!

    If you want to manually add the TRIGGER, use the following SQL Command:
    " . str_replace("\n", "
    ", $szSql) . "
    "); return ERROR_DB_TRIGGERFAILED; } // Successfull return SUCCESS; } /* * Implementation of ChangeChecksumFieldUnsigned: Changes the Checkusm field to unsigned! */ public function ChangeChecksumFieldUnsigned() { global $dbmapping, $fields, $querycount; // Get variables $szTableType = $this->_logStreamConfigObj->DBTableType; // Change Checksumfield to use UNSIGNED! $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` CHANGE `" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "` `" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "` INT(11) UNSIGNED NOT NULL DEFAULT '0'"; // Update Table schema now! $myQuery = mysql_query($szUpdateSql, $this->_dbhandle); if (!$myQuery) { // Return failure! $this->PrintDebugError("ER_BAD_FIELD_ERROR - Failed to Change field '" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "' from signed to unsigned with sql statement: '" . $szUpdateSql . "'"); return ERROR_DB_CHECKSUMCHANGEFAILED; } // return results return SUCCESS; } /* * Implementation of VerifyChecksumField: Verifies if the checkusm field is signed or unsigned! */ public function VerifyChecksumField() { global $dbmapping, $fields, $querycount; // Get variables $szTableType = $this->_logStreamConfigObj->DBTableType; // Create SQL and Get INDEXES for table! $szSql = "SHOW COLUMNS FROM `" . $this->_logStreamConfigObj->DBTableName . "` WHERE Field = '" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "'"; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Get result! $myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC); if (strpos( strtolower($myRow['Type']), "unsigned") === false ) { // return error code! return ERROR_DB_CHECKSUMERROR; } // Free query now mysql_free_result ($myQuery); // Increment for the Footer Stats $querycount++; } // return results return SUCCESS; } /** * Read the data from a specific uID which means in this * case beginning with from the Database ID * * @param uID integer in/out: unique id of the data row * @param arrProperitesOut array out: array filled with properties * @return integer Error state * @see ReadNext() */ public function Read($uID, &$arrProperitesOut) { // Seek the first uID! if ( $this->Sseek($uID, EnumSeek::UID, 0) == SUCCESS) { // Read the next record! $ret = $this->ReadNext($uID, $arrProperitesOut); } else $ret = ERROR_NOMORERECORDS; // return result! return $ret; } /** * Read the next line from the file depending on the current * read direction. * * Hint: If the current stream becomes unavailable an error * stated is retuned. A typical case is if a log rotation * changed the original data source. * * @param uID integer out: uID is the offset of data row * @param arrProperitesOut array out: properties * @return integer Error state * @see ReadNext */ public function ReadNext(&$uID, &$arrProperitesOut, $bParseMessage = true) { // Helpers needed for DB Mapping global $content, $gl_starttime; global $dbmapping, $fields; $szTableType = $this->_logStreamConfigObj->DBTableType; // define $ret $ret = SUCCESS; do { // No buffer? then read from DB! if ( $this->bufferedRecords == null ) $ret = $this->ReadNextRecordsFromDB($uID); else { if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) ) { // We need to load new records, so clear the old ones first! $this->ResetBufferedRecords(); // Set new Record start, will be used in the SQL Statement! $this->_currentRecordStart = $this->_currentRecordNum; // + 1; // Now read new ones $ret = $this->ReadNextRecordsFromDB($uID); // Check if we found more records if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) ) $ret = ERROR_NOMORERECORDS; } } if ( $ret == SUCCESS && $this->_arrProperties != null ) { // Init and set variables foreach ( $this->_arrProperties as $property ) { // Check if mapping exists if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$property]) ) { // Copy property if available! $dbfieldname = $dbmapping[$szTableType]['DBMAPPINGS'][$property]; if ( isset($this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]) ) { if ( isset($fields[$property]['FieldType']) && $fields[$property]['FieldType'] == FILTER_TYPE_DATE ) // Handle as date! $arrProperitesOut[$property] = GetEventTime( $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname] ); else $arrProperitesOut[$property] = $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]; } else $arrProperitesOut[$property] = ''; } else $arrProperitesOut[$property] = ''; } // Run optional Message Parsers now if ( isset($arrProperitesOut[SYSLOG_MESSAGE]) ) { $retParser = $this->_logStreamConfigObj->ProcessMsgParsers($arrProperitesOut[SYSLOG_MESSAGE], $arrProperitesOut); // Check if we have to skip the message! if ( $retParser == ERROR_MSG_SKIPMESSAGE ) $ret = $retParser; } // Set uID to the PropertiesOut! //DEBUG -> $this->_currentRecordNum; $uID = $arrProperitesOut[SYSLOG_UID] = $this->bufferedRecords[$this->_currentRecordNum][$dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID]]; // Increment $_currentRecordNum $this->_currentRecordNum++; } // Check how long we are running. If only two seconds of execution time are left, we abort further reading! $scriptruntime = intval(microtime_float() - $gl_starttime); if ( $content['MaxExecutionTime'] > 0 && $scriptruntime > ($content['MaxExecutionTime']-2) ) { // This may display a warning message, so the user knows we stopped reading records because of the script timeout. $content['logstream_warning'] = "false"; $content['logstream_warning_details'] = $content['LN_WARNING_LOGSTREAMDISK_TIMEOUT']; $content['logstream_warning_code'] = ERROR_FILE_NOMORETIME; // Return error code return ERROR_FILE_NOMORETIME; } // This additional filter check will take care on dynamic fields from the message parser! } while ( $this->ApplyFilters($ret, $arrProperitesOut) != SUCCESS && $ret == SUCCESS ); // reached here means return result! return $ret; } /** * Implementation of Seek */ public function Sseek(&$uID, $mode, $numrecs) { // predefine return value $ret = SUCCESS; switch ($mode) { case EnumSeek::UID: // if ( $uID == UID_UNKNOWN ) // set uID to first ID! { // No buffer? then read from DB! if ( $this->bufferedRecords == null ) $ret = $this->ReadNextRecordsFromDB($uID); if ( $ret == SUCCESS ) { $this->_currentRecordNum = 0; $uID = $this->bufferedRecords[ $this->_currentRecordNum ]; } } break; } // Return result! return $ret; } /** * GetMessageCount will return the count of Message. * If this count is not available, the function will * return the default -1 */ public function GetMessageCount() { return $this->_totalRecordCount; } /** * This function returns the first UID for previous PAGE, if availbale! * Otherwise will return -1! */ public function GetPreviousPageUID() { return $this->_previousPageUID; } /** * This function returns the FIRST UID for the FIRST PAGE! * Will be done by a seperated SQL Statement. */ public function GetFirstPageUID() { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Only perform query if row counting is enabled! if ( strlen($this->_SQLwhereClause) > 0 && !$this->_logStreamConfigObj->DBEnableRowCounting ) return $this->_firstPageUID; $szSql = "SELECT MAX(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") FROM `" . $this->_logStreamConfigObj->DBTableName . "` " . $this->_SQLwhereClause; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // obtain first and only row $myRow = mysql_fetch_row($myQuery); $this->_firstPageUID = $myRow[0]; // Free query now mysql_free_result ($myQuery); // Increment for the Footer Stats $querycount++; } // Return result! return $this->_firstPageUID; } /** * This function returns the first UID for the last PAGE! * Will be done by a seperated SQL Statement. */ public function GetLastPageUID() { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Only perform query if row counting is enabled! if ( strlen($this->_SQLwhereClause) > 0 && !$this->_logStreamConfigObj->DBEnableRowCounting ) return $this->_lastPageUID; $szSql = "SELECT MIN(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") FROM `" . $this->_logStreamConfigObj->DBTableName . "` " . $this->_SQLwhereClause; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // obtain first and only row $myRow = mysql_fetch_row($myQuery); $this->_lastPageUID = $myRow[0]; // Free query now mysql_free_result ($myQuery); // Increment for the Footer Stats $querycount++; } // Return result! return $this->_lastPageUID; } /** * This function returns the current Page number, if availbale! * Otherwise will return 0! We also assume that this function is * only called once DB is open! */ public function GetCurrentPageNumber() { return $this->_currentPageNumber; } /* * Implementation of IsPropertySortable * * For now, sorting is only possible for the UID Property! */ public function IsPropertySortable($myProperty) { global $fields; // TODO: HARDCODED | FOR NOW only FALSE! return false; if ( isset($fields[$myProperty]) && $myProperty == SYSLOG_UID ) return true; else return false; } /** * Implementation of GetLogStreamStats * * Returns an Array og logstream statsdata * Count of Data Items * Total Filesize */ public function GetLogStreamStats() { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Perform if Connection is true! if ( $this->_dbhandle != null ) { // Obtain Stats data for this table! $szSql = "SHOW TABLE STATUS FROM `" . $this->_logStreamConfigObj->DBName . "`"; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Loop through results while ($myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC)) { // Set tablename! $tableName = $myRow['Name']; $myStats = null; $myStats[] = array( 'StatsDisplayName' => 'Table name', 'StatsValue' => $tableName ); // copy usefull statsdata if ( isset($myRow['Engine']) ) $myStats[] = array( 'StatsDisplayName' => 'Table engine', 'StatsValue' => $myRow['Engine'] ); if ( isset($myRow['Rows']) ) $myStats[] = array( 'StatsDisplayName' => 'Rowcount', 'StatsValue' => $myRow['Rows'] ); if ( isset($myRow['Data_length']) ) $myStats[] = array( 'StatsDisplayName' => 'Table filesize (bytes)', 'StatsValue' => $myRow['Data_length'] ); if ( isset($myRow['Collation']) ) $myStats[] = array( 'StatsDisplayName' => 'Collation', 'StatsValue' => $myRow['Collation'] ); if ( isset($myRow['Comment']) ) $myStats[] = array( 'StatsDisplayName' => 'Comment', 'StatsValue' => $myRow['Comment'] ); $stats[]['STATSDATA'] = $myStats; } // Free query now mysql_free_result ($myQuery); // Increment for the Footer Stats $querycount++; } // return results! return $stats; } else return null; } /** * Implementation of GetLogStreamTotalRowCount * * Returns the total amount of rows in the main datatable */ public function GetLogStreamTotalRowCount() { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Set default rowcount $rowcount = null; // Perform if Connection is true! if ( $this->_dbhandle != null ) { // SHOW TABLE STATUS FROM $szSql = "SELECT count(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") as Counter FROM `" . $this->_logStreamConfigObj->DBTableName . "`"; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Obtain RowCount! $myRow = mysql_fetch_row($myQuery); $rowcount = $myRow[0]; // Free query now mysql_free_result ($myQuery); // Increment for the Footer Stats $querycount++; } } //return result return $rowcount; } /** * Implementation of the CleanupLogdataByDate function! Returns affected rows! */ public function CleanupLogdataByDate( $nDateTimeStamp ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Set default rowcount $rowcount = null; // Perform if Connection is true! if ( $this->_dbhandle != null ) { // --- Init Filters if necessary! if ( $this->_filters == null ) $this->SetFilter( "" ); // This will init filters! // Create SQL Where Clause! $this->CreateSQLWhereClause(); // --- // --- Add default WHERE clause if ( strlen($this->_SQLwhereClause) > 0 ) $szWhere = $this->_SQLwhereClause; else $szWhere = ""; // Add Datefilter if necessary! if ( $nDateTimeStamp > 0 ) { if ( strlen($szWhere) > 0 ) $szWhere .= " AND "; else $szWhere = " WHERE "; // Append Date Filter! $szWhere .= " UNIX_TIMESTAMP(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ") < " . $nDateTimeStamp; } // --- // DELETE DATA NOW! $szSql = "DELETE FROM `" . $this->_logStreamConfigObj->DBTableName . "`" . $szWhere; OutputDebugMessage("LogStreamDB|CleanupLogdataByDate: Created SQL Query:
    " . $szSql, DEBUG_DEBUG); $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Get affected rows and return! $rowcount = mysql_affected_rows(); // Reset AUTO_INCREMENT if all records were deleted! if ( $nDateTimeStamp == 0 ) { $szSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " AUTO_INCREMENT=0"; $myQuery = mysql_query($szSql, $this->_dbhandle); // error occured, output DEBUG message if (!$myQuery) $this->PrintDebugError("CleanupLogdataByDate failed to reset AUTO_INCREMENT for '" . $this->_logStreamConfigObj->DBTableName . "' table. "); } // Free result not needed here! //mysql_free_result ($myQuery); } else { // error occured, output DEBUG message $this->PrintDebugError("CleanupLogdataByDate failed with SQL Statement ' " . $szSql . " '"); } } //return affected rows return $rowcount; } /* * Implementation of the UpdateAllMessageChecksum * * Update all missing checksum properties in the current database */ public function UpdateAllMessageChecksum( ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // UPDATE DATA NOW! $szSql = "UPDATE " . $this->_logStreamConfigObj->DBTableName . " SET " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = crc32(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_MESSAGE] . ") " . " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " IS NULL OR " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = 0"; // Output Debug Informations OutputDebugMessage("LogStreamDB|UpdateAllMessageChecksum: Running Created SQL Query:
    " . $szSql, DEBUG_ULTRADEBUG); // Running SQL Query $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Debug Output OutputDebugMessage("LogStreamDB|UpdateAllMessageChecksum: Successfully updated Checksum of '" . mysql_affected_rows($this->_dbhandle) . "' datarecords", DEBUG_INFO); // Return success return SUCCESS; } else { // error occured, output DEBUG message $this->PrintDebugError("SaveMessageChecksum failed with SQL Statement ' " . $szSql . " '"); // Failed return ERROR; } } /* * Implementation of the SaveMessageChecksum * * Creates an database UPDATE Statement and performs it! */ public function SaveMessageChecksum( $arrProperitesIn ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; if ( isset($arrProperitesIn[SYSLOG_UID]) && isset($arrProperitesIn[MISC_CHECKSUM]) && isset($dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM]) ) { // UPDATE DATA NOW! $szSql = "UPDATE " . $this->_logStreamConfigObj->DBTableName . " SET " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = " . $arrProperitesIn[MISC_CHECKSUM] . " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " = " . $arrProperitesIn[SYSLOG_UID]; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Return success return SUCCESS; } else { // error occured, output DEBUG message $this->PrintDebugError("SaveMessageChecksum failed with SQL Statement ' " . $szSql . " '"); // Failed return ERROR; } } else // Missing important properties return ERROR; } /** * Implementation of ConsolidateItemListByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function ConsolidateItemListByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder) { global $content, $dbmapping, $fields; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; // Check if fields are available if ( !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]) || !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId]) ) return ERROR_DB_DBFIELDNOTFOUND; // --- Set Options $nConsFieldType = $fields[$szConsFieldId]['FieldType']; if ( $nSortingOrder == SORTING_ORDER_DESC ) $szSortingOrder = "DESC"; else $szSortingOrder = "ASC"; // --- // --- Set DB Field names $myDBConsFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]; $myDBGroupByFieldName = $myDBConsFieldName; $myDBQueryFields = $myDBConsFieldName . ", "; // Set Sorted Field if ( $szConsFieldId == $szSortFieldId ) $myDBSortedFieldName = "itemcount"; else $myDBSortedFieldName = $szSortFieldId; // --- // Special handling for date fields if ( $nConsFieldType == FILTER_TYPE_DATE ) { // Helper variable for the select statement $mySelectFieldName = $myDBGroupByFieldName . "Grouped"; $myDBQueryFieldName = "DATE( " . $myDBConsFieldName . ") AS " . $myDBGroupByFieldName ; } // Set Limit String if ( $nRecordLimit > 0 ) $szLimitSql = " LIMIT " . $nRecordLimit; else $szLimitSql = ""; // Create SQL Where Clause! if ( $this->_SQLwhereClause == "" ) { $res = $this->CreateSQLWhereClause(); if ( $res != SUCCESS ) return $res; } // Create SQL String now! $szSql = "SELECT " . $myDBQueryFields . "count(" . $myDBConsFieldName . ") as itemcount " . " FROM `" . $this->_logStreamConfigObj->DBTableName . "`" . $this->_SQLwhereClause . " GROUP BY " . $myDBGroupByFieldName . " ORDER BY " . $myDBSortedFieldName . " " . $szSortingOrder . $szLimitSql ; // Output Debug Informations OutputDebugMessage("LogStreamDB|ConsolidateItemListByField: Running Created SQL Query:
    " . $szSql, DEBUG_ULTRADEBUG); // Perform Database Query $myquery = mysql_query($szSql, $this->_dbhandle); if ( !$myquery ) return ERROR_DB_QUERYFAILED; // Initialize Array variable $aResult = array(); // read data records while ($myRow = mysql_fetch_array($myquery, MYSQL_ASSOC)) { // Create new row $aNewRow = array(); foreach ( $myRow as $myFieldName => $myFieldValue ) { if ( $myFieldName == $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId] ) $aNewRow[$szConsFieldId] = $myFieldValue; else $aNewRow[$myFieldName] = $myFieldValue; } // Add new row to result $aResult[] = $aNewRow; } // return finished array if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } /** * Implementation of ConsolidateDataByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function ConsolidateDataByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder, $aIncludeCustomFields = null, $bIncludeLogStreamFields = false, $bIncludeMinMaxDateFields = false) { global $content, $dbmapping, $fields; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; // Check if fields are available if ( !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]) || !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId]) ) return ERROR_DB_DBFIELDNOTFOUND; // --- Set Options $nConsFieldType = $fields[$szConsFieldId]['FieldType']; if ( $nSortingOrder == SORTING_ORDER_DESC ) $szSortingOrder = "DESC"; else $szSortingOrder = "ASC"; // --- // --- Set DB Field names $myDBConsFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]; $myDBGroupByFieldName = $myDBConsFieldName; // Check which fields to include if ( $aIncludeCustomFields != null ) { $myDBQueryFields = ""; foreach ( $aIncludeCustomFields as $myFieldName ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName]) ) $myDBQueryFields .= $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", "; } // Append Sortingfield if ( !in_array($szConsFieldId, $aIncludeCustomFields) ) $myDBQueryFields .= $myDBConsFieldName . ", "; } else if ( $bIncludeLogStreamFields ) { $myDBQueryFields = ""; foreach ( $this->_arrProperties as $myFieldName ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName]) ) $myDBQueryFields .= $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", "; } } else // Only Include ConsolidateField $myDBQueryFields = $myDBConsFieldName . ", "; // Add Min and Max fields for DATE if desired if ( $bIncludeMinMaxDateFields ) { $myDBQueryFields .= "Min(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ") as firstoccurrence_date, "; $myDBQueryFields .= "Max(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ") as lastoccurrence_date, "; } if ( $szConsFieldId == $szSortFieldId ) $myDBSortedFieldName = "itemcount"; else $myDBSortedFieldName = $szSortFieldId; // --- // Special handling for date fields if ( $nConsFieldType == FILTER_TYPE_DATE ) { // Helper variable for the select statement $mySelectFieldName = $myDBGroupByFieldName . "Grouped"; $myDBQueryFieldName = "DATE( " . $myDBConsFieldName . ") AS " . $myDBGroupByFieldName ; } // Set Limit String if ( $nRecordLimit > 0 ) $szLimitSql = " LIMIT " . $nRecordLimit; else $szLimitSql = ""; // Create SQL Where Clause! if ( strlen($this->_SQLwhereClause) <= 0 ) { $res = $this->CreateSQLWhereClause(); if ( $res != SUCCESS ) return $res; } // Create SQL String now! $szSql = "SELECT " . $myDBQueryFields . "count(" . $myDBConsFieldName . ") as itemcount " . " FROM `" . $this->_logStreamConfigObj->DBTableName . "`" . $this->_SQLwhereClause . " GROUP BY " . $myDBGroupByFieldName . " ORDER BY " . $myDBSortedFieldName . " " . $szSortingOrder . $szLimitSql ; // Output Debug Informations OutputDebugMessage("LogStreamDB|ConsolidateDataByField: Running Created SQL Query:
    " . $szSql, DEBUG_ULTRADEBUG); // Perform Database Query $myquery = mysql_query($szSql, $this->_dbhandle); if ( !$myquery ) return ERROR_DB_QUERYFAILED; // Initialize Array variable $aResult = array(); // read data records while ($myRow = mysql_fetch_array($myquery, MYSQL_ASSOC)) { // Create new row $aNewRow = array(); foreach ( $myRow as $myFieldName => $myFieldValue ) { $myFieldID = $this->GetFieldIDbyDatabaseMapping($szTableType, $myFieldName); $aNewRow[ $myFieldID ] = $myFieldValue; /* if ( $myFieldName == $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId] ) $aNewRow[$szConsFieldId] = $myFieldValue; else { $aNewRow[$myFieldName] = $myFieldValue; */ // } } // Add new row to result $aResult[] = $aNewRow; } // return finished array if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } /** * Implementation of GetCountSortedByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function GetCountSortedByField($szFieldId, $nFieldType, $nRecordLimit) { global $content, $dbmapping; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId]) ) { // Set DB Field name first! $myDBFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId]; $myDBQueryFieldName = $myDBFieldName; $mySelectFieldName = $myDBFieldName; // Special handling for date fields if ( $nFieldType == FILTER_TYPE_DATE ) { // Helper variable for the select statement $mySelectFieldName = $mySelectFieldName . "Grouped"; $myDBQueryFieldName = "DATE( " . $myDBFieldName . ") AS " . $mySelectFieldName ; } // Create SQL Where Clause! if ( $this->_SQLwhereClause == "" ) { $res = $this->CreateSQLWhereClause(); if ( $res != SUCCESS ) return $res; } // Create SQL String now! $szSql = "SELECT " . $myDBQueryFieldName . ", " . "count(" . $myDBFieldName . ") as TotalCount " . " FROM `" . $this->_logStreamConfigObj->DBTableName . "`" . $this->_SQLwhereClause . " GROUP BY " . $mySelectFieldName . " ORDER BY TotalCount DESC" . " LIMIT " . $nRecordLimit; // Perform Database Query $myquery = mysql_query($szSql, $this->_dbhandle); if ( !$myquery ) return ERROR_DB_QUERYFAILED; // Initialize Array variable $aResult = array(); // read data records while ($myRow = mysql_fetch_array($myquery, MYSQL_ASSOC)) $aResult[ $myRow[$mySelectFieldName] ] = $myRow['TotalCount']; // return finished array if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } else { // return error code, field mapping not found return ERROR_DB_DBFIELDNOTFOUND; } } /* * ============= Beginn of private functions ============= */ /* * This function expects the filters to already being set earlier. * Otherwise no usual WHERE Clause can be created! */ private function CreateSQLWhereClause() { if ( $this->_filters != null ) { global $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Reset WhereClause $this->_SQLwhereClause = ""; // --- Build Query Array $arrayQueryProperties = $this->_arrProperties; if ( isset($this->_arrFilterProperties) && $this->_arrFilterProperties != null) { foreach ( $this->_arrFilterProperties as $filterproperty ) { if ( $this->_arrProperties == null || !in_array($filterproperty, $this->_arrProperties) ) $arrayQueryProperties[] = $filterproperty; } } // --- // Loop through all available properties foreach( $arrayQueryProperties as $propertyname ) { // If the property exists in the filter array, we have something to filter for ^^! if ( array_key_exists($propertyname, $this->_filters) ) { // Process all filters foreach( $this->_filters[$propertyname] as $myfilter ) { // Only perform if database mapping is available for this filter! if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$propertyname]) ) { switch( $myfilter[FILTER_TYPE] ) { case FILTER_TYPE_STRING: // --- Either make a LIKE or a equal query! if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHFULL ) { // Set addnot to nothing $addnod = ""; // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) { $szSearchBegin = " = '"; $szSearchEnd = "' "; } else { $szSearchBegin = " <> '"; $szSearchEnd = "' "; } // --- } else if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHREGEX ) { // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) $addnod = ""; else $addnod = " NOT"; // --- $szSearchBegin = " REGEXP '"; $szSearchEnd = "' "; } else { // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) $addnod = ""; else $addnod = " NOT"; // --- $szSearchBegin = " LIKE '%"; $szSearchEnd = "%' "; } // --- // --- If Syslog message, we have AND handling, otherwise OR! if ( $propertyname == SYSLOG_MESSAGE ) $addor = " AND "; else { // If we exclude filters, we need to combine with AND if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) $addor = " OR "; else $addor = " AND "; } // --- // Now Create LIKE Filters if ( isset($tmpfilters[$propertyname]) ) $tmpfilters[$propertyname][FILTER_VALUE] .= $addor . $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . $addnod . $szSearchBegin . DB_RemoveBadChars($myfilter[FILTER_VALUE]) . $szSearchEnd; else { $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_STRING; $tmpfilters[$propertyname][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . $addnod . $szSearchBegin . DB_RemoveBadChars($myfilter[FILTER_VALUE]) . $szSearchEnd; } break; case FILTER_TYPE_NUMBER: // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_EXCLUDE ) { // Add to filterset $szArrayKey = $propertyname . "-NOT"; if ( isset($tmpfilters[$szArrayKey]) ) $tmpfilters[$szArrayKey][FILTER_VALUE] .= ", " . $myfilter[FILTER_VALUE]; else { $tmpfilters[$szArrayKey][FILTER_TYPE] = FILTER_TYPE_NUMBER; $tmpfilters[$szArrayKey][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " NOT IN (" . DB_RemoveBadChars($myfilter[FILTER_VALUE]); } } else { // Add to filterset if ( isset($tmpfilters[$propertyname]) ) $tmpfilters[$propertyname][FILTER_VALUE] .= ", " . $myfilter[FILTER_VALUE]; else { $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_NUMBER; $tmpfilters[$propertyname][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " IN (" . DB_RemoveBadChars($myfilter[FILTER_VALUE]); } } // --- break; case FILTER_TYPE_DATE: if ( isset($tmpfilters[$propertyname]) ) $tmpfilters[$propertyname][FILTER_VALUE] .= " AND "; else { $tmpfilters[$propertyname][FILTER_VALUE] = ""; $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_DATE; } if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { // Get current timestamp $nNowTimeStamp = time(); if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR ) $nNowTimeStamp -= 60 * 60; // One Hour! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_12HOURS ) $nNowTimeStamp -= 60 * 60 * 12; // 12 Hours! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_24HOURS ) $nNowTimeStamp -= 60 * 60 * 24; // 24 Hours! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_7DAYS ) $nNowTimeStamp -= 60 * 60 * 24 * 7; // 7 days else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_31DAYS ) $nNowTimeStamp -= 60 * 60 * 24 * 31; // 31 days else { // Set filter to unknown and Abort in this case! $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_UNKNOWN; break; } // Append filter $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $nNowTimeStamp) . "'"; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_FROM ) { // Obtain Event struct for the time! $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $myeventtime[EVTIME_TIMESTAMP]) . "'"; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_TO ) { // Obtain Event struct for the time! $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " < '" . date("Y-m-d H:i:s", $myeventtime[EVTIME_TIMESTAMP]) . "'"; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_DATE ) { // Obtain Event struct for the time! $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $myeventtime[EVTIME_TIMESTAMP]) . "' AND " . $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " < '" . date("Y-m-d H:i:s", ($myeventtime[EVTIME_TIMESTAMP]+86400) ) . "'"; } break; default: // Nothing to do! break; } } else { // Check how to treat not found db mappings / filters if ( GetConfigSetting("TreatNotFoundFiltersAsTrue", 0, CFGLEVEL_USER) == 0 ) return ERROR_DB_DBFIELDNOTFOUND; } } } } // Check and combine all filters now! if ( isset($tmpfilters) ) { // Append filters foreach( $tmpfilters as $tmpfilter ) { // Init WHERE or Append AND if ( strlen($this->_SQLwhereClause) > 0 ) $this->_SQLwhereClause .= " AND "; else $this->_SQLwhereClause = " WHERE "; switch( $tmpfilter[FILTER_TYPE] ) { case FILTER_TYPE_STRING: $this->_SQLwhereClause .= "( " . $tmpfilter[FILTER_VALUE] . ") "; break; case FILTER_TYPE_NUMBER: $this->_SQLwhereClause .= $tmpfilter[FILTER_VALUE] . ") "; break; case FILTER_TYPE_DATE: $this->_SQLwhereClause .= $tmpfilter[FILTER_VALUE]; break; default: // Should not happen, wrong filters! // We add a dummy into the where clause, just as a place holder $this->_SQLwhereClause .= " 1=1 "; break; } } } // echo $this->_SQLwhereClause; //$dbmapping[$szTableType][SYSLOG_UID] } else // No filters means nothing to do! return SUCCESS; } /* * Destroy the SQL QUery! */ private function DestroyMainSQLQuery() { // create query if necessary! if ( $this->_myDBQuery != null ) { // Free Query ressources mysql_free_result ($this->_myDBQuery); $this->_myDBQuery = null; } // return success state if reached this point! return SUCCESS; } /* * This helper function will read the next records into the buffer. */ private function ReadNextRecordsFromDB($uID) { global $querycount; // Clear SQL Query first! $this->DestroyMainSQLQuery(); // return error if there was one! if ( ($res = $this->CreateMainSQLQuery($uID)) != SUCCESS ) return $res; // Append LIMIT clause // $szSql .= " LIMIT " . $this->_currentRecordStart . ", " . $this->_logStreamConfigObj->RecordsPerQuery; // Copy rows into the buffer! $iBegin = $this->_currentRecordNum; while ($myRow = mysql_fetch_array($this->_myDBQuery, MYSQL_ASSOC)) { // Check if result was successfull! if ( $myRow === FALSE || !$myRow ) break; // Keys will be converted into lowercase! $this->bufferedRecords[$iBegin] = array_change_key_case($myRow, CASE_LOWER); $iBegin++; } // --- Check if results were found if ( $iBegin == $this->_currentRecordNum ) return ERROR_NOMORERECORDS; // --- // Free Query ressources // mysql_free_result ($myquery); // Only obtain count if enabled and not done before if ( $this->_logStreamConfigObj->DBEnableRowCounting && $this->_totalRecordCount == -1 ) { $this->_totalRecordCount = $this->GetRowCountFromTable(); if ( $this->_totalRecordCount <= 0 ) return ERROR_NOMORERECORDS; } // Increment for the Footer Stats $querycount++; // return success state if reached this point! return SUCCESS; } /* * Create the SQL QUery! */ private function CreateMainSQLQuery($uID) { global $querycount; // Get SQL Statement $szSql = $this->CreateSQLStatement($uID); // --- Append LIMIT $szSql .= " LIMIT " . $this->_logStreamConfigObj->RecordsPerQuery; // --- // Perform Database Query $this->_myDBQuery = mysql_query($szSql, $this->_dbhandle); if ( !$this->_myDBQuery ) { // Check if a field is missing! if ( mysql_errno() == 1054 ) { // Handle missing field and try again! if ( $this->HandleMissingField() == SUCCESS ) { $this->_myDBQuery = mysql_query($szSql, $this->_dbhandle); if ( !$this->_myDBQuery ) { $this->PrintDebugError("Invalid SQL: ".$szSql); return ERROR_DB_QUERYFAILED; } } else // Failed to add field dynamically return ERROR_DB_QUERYFAILED; } else { $this->PrintDebugError("Invalid SQL: ".$szSql); return ERROR_DB_QUERYFAILED; } } else { // Skip one entry in this case if ( $this->_currentRecordStart > 0 ) { // Throw away $myRow = mysql_fetch_array($this->_myDBQuery, MYSQL_ASSOC); } } // Increment for the Footer Stats $querycount++; // Output Debug Informations OutputDebugMessage("LogStreamDB|CreateMainSQLQuery: Created SQL Query:
    " . $szSql, DEBUG_DEBUG); // return success state if reached this point! return SUCCESS; } /* * Creates the SQL Statement we are going to use! */ private function CreateSQLStatement($uID, $includeFields = true) { global $dbmapping; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; $szSortColumn = $this->_logStreamConfigObj->SortColumn; // Create Basic SQL String if ( $this->_logStreamConfigObj->DBEnableRowCounting ) // with SQL_CALC_FOUND_ROWS $sqlString = "SELECT SQL_CALC_FOUND_ROWS " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID]; else // without row calc $sqlString = "SELECT " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID]; // Append fields if needed if ( $includeFields && $this->_arrProperties != null ) { // Loop through all requested fields foreach ( $this->_arrProperties as $myproperty ) { // SYSLOG_UID already added! if ( $myproperty != SYSLOG_UID && isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) ) { // Append field! $sqlString .= ", " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]; } } } // Append FROM 'table'! $sqlString .= " FROM `" . $this->_logStreamConfigObj->DBTableName . "`"; // Append precreated where clause $sqlString .= $this->_SQLwhereClause; // Append UID QUERY! if ( $uID != -1 ) { if ( $this->_readDirection == EnumReadDirection::Forward ) $myOperator = ">="; else $myOperator = "<="; if ( strlen($this->_SQLwhereClause) > 0 ) $sqlString .= " AND " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " $myOperator $uID"; else $sqlString .= " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " $myOperator $uID"; } // Append ORDER clause if ( $this->_readDirection == EnumReadDirection::Forward ) $sqlString .= " ORDER BY " . $dbmapping[$szTableType]['DBMAPPINGS'][$szSortColumn]; else if ( $this->_readDirection == EnumReadDirection::Backward ) $sqlString .= " ORDER BY " . $dbmapping[$szTableType]['DBMAPPINGS'][$szSortColumn] . " DESC"; // return SQL result string: return $sqlString; } /* * Reset record buffer in this function! */ private function ResetBufferedRecords() { if ( isset($this->bufferedRecords) ) { // Loop through all subrecords first! foreach ($this->bufferedRecords as $mykey => $myrecord) unset( $this->bufferedRecords[$mykey] ); // Set buffered records to NULL! $this->bufferedRecords = null; } } /* * Helper function to display SQL Errors for now! */ private function PrintDebugError($szErrorMsg) { global $extraErrorDescription; $errdesc = mysql_error(); $errno = mysql_errno(); $errormsg="$szErrorMsg
    "; $errormsg.="Detail error: $errdesc
    "; $errormsg.="Error Code: $errno
    "; // Add to additional error output $extraErrorDescription = $errormsg; //Output! OutputDebugMessage("LogStreamDB|PrintDebugError: $errormsg", DEBUG_ERROR); } /* * Returns the number of possible records by using a query */ private function GetRowCountByString($szQuery) { if ($myQuery = mysql_query($szQuery)) { $num_rows = mysql_num_rows($myQuery); mysql_free_result ($myQuery); } return $num_rows; } /* * Returns the number of possible records by using an existing queryid */ private function GetRowCountByQueryID($myQuery) { $num_rows = mysql_num_rows($myQuery); return $num_rows; } /* * Returns the number of possible records by using a select count statement! */ private function GetRowCountFromTable() { if ( $myquery = mysql_query("Select FOUND_ROWS();", $this->_dbhandle) ) { // Get first and only row! $myRow = mysql_fetch_array($myquery); // copy row count $numRows = $myRow[0]; } else $numRows = -1; // return result! return $numRows; /* OLD slow code! global $dbmapping,$querycount; $szTableType = $this->_logStreamConfigObj->DBTableType; // Create Statement and perform query! $szSql = "SELECT count(" . $dbmapping[$szTableType][SYSLOG_UID] . ") FROM " . $this->_logStreamConfigObj->DBTableName . $this->_SQLwhereClause; if ($myQuery = mysql_query($szSql, $this->_dbhandle)) { // obtain first and only row $myRow = mysql_fetch_row($myQuery); $numRows = $myRow[0]; // Increment for the Footer Stats $querycount++; // Free query now mysql_free_result ($myQuery); } else $numRows = -1; */ } /* * Function handles missing database fields automatically! */ private function HandleMissingField( $szMissingField = null, $arrProperties = null ) { global $dbmapping, $fields; // Get Err description $errdesc = mysql_error(); // Try to get missing field from SQL Error of not specified as argument if ( $szMissingField == null ) { if ( preg_match("/Unknown column '(.*?)' in '(.*?)'$/", $errdesc, $errOutArr ) ) $szMissingField = $errOutArr[1]; else { $this->PrintDebugError("ER_BAD_FIELD_ERROR - SQL Statement: ". $errdesc); return ERROR_DB_DBFIELDNOTFOUND; } } // Set Properties to default if NULL if ( $arrProperties == null ) $arrProperties = $this->_arrProperties; // Get Tabletype $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperties as $myproperty ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && $szMissingField == $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] ) { // Create SQL Numeric field $szUpdateSql = ""; $szUnsigned = ""; if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_NUMBER ) { // This will add the checksum field as unsigned automatically! if ( $myproperty == MISC_CHECKSUM ) $szUnsigned = "UNSIGNED"; $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` int(11) " . $szUnsigned . " NOT NULL DEFAULT '0'"; } if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_STRING ) $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` varchar(60) NOT NULL DEFAULT ''"; if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_DATE ) $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"; if ( strlen($szUpdateSql) > 0 ) { // Update Table schema now! $myQuery = mysql_query($szUpdateSql, $this->_dbhandle); if (!$myQuery) { // Return failure! $this->PrintDebugError("ER_BAD_FIELD_ERROR - Dynamically Adding field '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' with Statement failed: '" . $szUpdateSql . "'"); return ERROR_DB_ADDDBFIELDFAILED; } } else { // Return failure! $this->PrintDebugError("ER_BAD_FIELD_ERROR - Field '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' is missing has to be added manually to the database layout!'"); return ERROR_DB_ADDDBFIELDFAILED; } } } // Reached this point means success! return SUCCESS; } /* * Helper function to return a list of Indexes for the logstream table */ private function GetIndexesAsArray() { global $querycount; // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Init Array $arrIndexKeys = array(); // Create SQL and Get INDEXES for table! $szSql = "SHOW INDEX FROM `" . $this->_logStreamConfigObj->DBTableName . "`"; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Loop through results while ($myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC)) { // Add to index keys $arrIndexKeys[] = strtolower($myRow['Key_name']); } // Free query now mysql_free_result ($myQuery); // Increment for the Footer Stats $querycount++; } // return Array return $arrIndexKeys; } /* * Helper function to return a list of Fields from the logstream table */ private function GetFieldsAsArray() { global $querycount; // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Init Array $arrFieldKeys = array(); // Create SQL and Get INDEXES for table! $szSql = "SHOW FIELDS FROM `" . $this->_logStreamConfigObj->DBTableName . "`"; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Loop through results while ($myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC)) { // Add to index keys $arrFieldKeys[] = strtolower($myRow['Field']); } // Free query now mysql_free_result ($myQuery); // Increment for the Footer Stats $querycount++; } // return Array return $arrFieldKeys; } /* * Helper function to return a list of Indexes for the logstream table */ private function GetTriggersAsArray() { global $querycount; // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Init Array $arrIndexTriggers = array(); // Create SQL and Get INDEXES for table! $szSql = "SHOW TRIGGERS"; $myQuery = mysql_query($szSql, $this->_dbhandle); if ($myQuery) { // Loop through results while ($myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC)) { // print_r ( $myRow ); // Add to index keys $arrIndexTriggers[] = strtolower($myRow['Trigger']); } // Free query now mysql_free_result ($myQuery); // Increment for the Footer Stats $querycount++; } // return Array return $arrIndexTriggers; } // --- End of Class! } ?>loganalyzer-3.6.5/src/classes/msgparser.class.php0000644000175000017500000000457112225176641021407 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- abstract class MsgParser{ // Public configuration properties public $_MsgNormalize = 0; // If set to one, the msg will be reconstructed if successfully parsed before // Public Information properties public $_ClassName = 'Default Messageparser'; public $_ClassDescription = 'This is a placeholder for the message parser description!'; public $_ClassRequiredFields = null; public $_ClassHelpArticle = "http://www.monitorware.com/en/Articles/"; /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public abstract function ParseMsg($szMsg, &$arrArguments); } ?>loganalyzer-3.6.5/src/classes/reports/0000755000175000017500000000000012306337457017262 5ustar danieldanielloganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary.class.php0000644000175000017500000004447112225176641027000 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes! require_once($gl_root_path . 'classes/reports/report.class.php'); // --- class Report_eventsummary extends Report { // Common Properties public $_reportVersion = 1; // Internally Version of the ReportEngine public $_reportID = "report.eventlog.eventsummary.class"; // ID for the report, needs to be unique! public $_reportFileBasicName = "report.eventlog.eventsummary"; // Basic Filename for reportfiles public $_reportTitle = "EventLog Summary Report"; // Display name for the report public $_reportDescription = "This is a EventLog Summary Report"; public $_reportHelpArticle = "http://loganalyzer.adiscon.com/plugins/reports/eventlog-eventsummary"; public $_reportNeedsInit = false; // True means that this report needs additional init stuff public $_reportInitialized = false; // True means report is installed // Advanced Report Options private $_maxHosts = 20; // Threshold for maximum hosts to analyse! private $_maxEventsPerHost = 100; // Threshold for maximum amount of events to analyse per host private $_colorThreshold = 10; // Threshold for coloured display of Eventcounter // Constructor public function Report_eventsummary() { // $this->_logStreamConfigObj = $streamConfigObj; // Fill fields we need for this report $this->_arrProperties[] = SYSLOG_UID; $this->_arrProperties[] = SYSLOG_DATE; $this->_arrProperties[] = SYSLOG_HOST; $this->_arrProperties[] = SYSLOG_MESSAGETYPE; // $this->_arrProperties[] = SYSLOG_FACILITY; $this->_arrProperties[] = SYSLOG_SEVERITY; $this->_arrProperties[] = SYSLOG_EVENT_ID; // $this->_arrProperties[] = SYSLOG_EVENT_LOGTYPE; $this->_arrProperties[] = SYSLOG_EVENT_SOURCE; // $this->_arrProperties[] = SYSLOG_EVENT_CATEGORY; // $this->_arrProperties[] = SYSLOG_EVENT_USER; $this->_arrProperties[] = SYSLOG_MESSAGE; $this->_arrProperties[] = MISC_CHECKSUM; // Init Customfilters Array $this->_arrCustomFilters['_maxHosts'] = array ( 'InternalID' => '_maxHosts', 'DisplayLangID' => 'ln_report_maxHosts_displayname', 'DescriptLangID'=> 'ln_report_maxHosts_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 20, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); $this->_arrCustomFilters['_maxEventsPerHost'] = array ( 'InternalID' => '_maxEventsPerHost', 'DisplayLangID' => 'ln_report_maxEventsPerHost_displayname', 'DescriptLangID'=> 'ln_report_maxEventsPerHost_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 100, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); $this->_arrCustomFilters['_colorThreshold'] = array ( 'InternalID' => '_colorThreshold', 'DisplayLangID' => 'ln_report_colorThreshold_displayname', 'DescriptLangID'=> 'ln_report_colorThreshold_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 10, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); } /** * startDataProcessing, analysing data * * @param arrProperties array in: Properties wish list. * @return integer Error stat */ public function startDataProcessing() { global $content, $severity_colors, $gl_starttime, $fields; // Create Filter string, append filter for EventLog Type msgs! $szFilters = $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_NT_EventReport . ",=" . IUT_WEVTMONV2; // Include EventLog v1 and v2 // Set Filter string $this->_streamObj->SetFilter( $szFilters ); // Need to Open stream first! $res = $this->_streamObj->Open( $this->_arrProperties, true ); if ( $res == SUCCESS ) { // Set to common content variables $this->SetCommonContentVariables(); // Set report specific content variables $content["_colorThreshold"] = $this->_colorThreshold; // --- Report logic starts here $content["report_rendertime"] = ""; // Step 1: Gather Summaries // Obtain data from the logstream! $content["report_summary"] = $this->_streamObj->ConsolidateDataByField( SYSLOG_SEVERITY, 0, SYSLOG_SEVERITY, SORTING_ORDER_DESC, null, false ); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s, "; // If data is valid, we have an array! if ( is_array($content["report_summary"]) && count($content["report_summary"]) > 0 ) { // Count Total Events $iTotalEvents = 0; foreach ($content["report_summary"] as &$tmpReportData ) { $tmpReportData['DisplayName'] = GetSeverityDisplayName( $tmpReportData[SYSLOG_SEVERITY] ); $tmpReportData['bgcolor'] = $severity_colors[ $tmpReportData[SYSLOG_SEVERITY] ]; $iTotalEvents += $tmpReportData['itemcount']; } // Prepent Item with totalevents count $totalItem['DisplayName'] = "Total Events"; $totalItem['bgcolor'] = "#999999"; $totalItem['itemcount'] = $iTotalEvents; // Prepent to array array_unshift( $content["report_summary"], $totalItem ); } else return ERROR_REPORT_NODATA; // Get List of hosts $content["report_computers"] = $this->_streamObj->ConsolidateItemListByField( SYSLOG_HOST, $this->_maxHosts, SYSLOG_HOST, SORTING_ORDER_DESC ); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s, "; if ( is_array($content["report_computers"]) && count($content["report_computers"]) > 0 ) { // Create plain hosts list for Consolidate function foreach ( $content["report_computers"] as $tmpComputer ) $arrHosts[] = $tmpComputer[SYSLOG_HOST]; } else return ERROR_REPORT_NODATA; // This function will consolidate the Events based per Host! $this->ConsolidateEventsPerHost($arrHosts); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // --- } else return $ret; // Return success! return SUCCESS; } /** * InitReport, empty * */ public function InitReport() { // Nothing to do return SUCCESS; } /** * RemoveReport, empty * */ public function RemoveReport() { // Nothing to do return SUCCESS; } /** * validateLicense, check license code * */ public function validateLicense() { // This is a free report! return SUCCESS; } /** * Init advanced settings from _customFilters string */ public function InitAdvancedSettings() { // Parse and Split _customFilters if ( strlen($this->_customFilters) > 0 ) { // First of all split by comma $tmpFilterValues = explode( ",", $this->_customFilters ); //Loop through mappings foreach ($tmpFilterValues as &$myFilterValue ) { // Split subvalues $tmpArray = explode( "=>", $myFilterValue ); // Set into temporary array $tmpfilterid = trim($tmpArray[0]); // Set advanced property if ( isset($this->_arrCustomFilters[$tmpfilterid]) ) { // Copy New value first! $szNewVal = trim($tmpArray[1]); // Negated logic if ( $this->_arrCustomFilters[$tmpfilterid][FILTER_TYPE] == FILTER_TYPE_NUMBER && !(isset($this->_arrCustomFilters[$tmpfilterid]['MinValue']) && intval($szNewVal) < $this->_arrCustomFilters[$tmpfilterid]['MinValue']) && !(isset($this->_arrCustomFilters[$tmpfilterid]['MaxValue']) && intval($szNewVal) >= $this->_arrCustomFilters[$tmpfilterid]['MaxValue']) ) { if ( $tmpfilterid == '_maxHosts' ) $this->_maxHosts = intval($szNewVal); else if ( $tmpfilterid == '_maxEventsPerHost' ) $this->_maxEventsPerHost = intval($szNewVal); else if ( $tmpfilterid == '_colorThreshold' ) $this->_colorThreshold = intval($szNewVal); } else { // Write to debuglog OutputDebugMessage("Failed setting advanced report option property '" . $tmpfilterid . "', value not in value range!", DEBUG_ERROR); } } } } } /* * Implementation of CheckLogStreamSource */ public function CheckLogStreamSource( $mySourceID ) { // Call basic report Check function $res = $this->CheckLogStreamSourceByPropertyArray( $mySourceID, array(SYSLOG_HOST, MISC_CHECKSUM, SYSLOG_DATE, SYSLOG_SEVERITY, SYSLOG_MESSAGETYPE), SYSLOG_MESSAGE ); // return results! return $res; } /* * Implementation of CreateLogStreamIndexes | Will create missing INDEXES */ public function CreateLogStreamIndexes( $mySourceID ) { // Call basic report Check function $res = $this->CreateLogStreamIndexesByPropertyArray( $mySourceID, array(SYSLOG_HOST, MISC_CHECKSUM, SYSLOG_DATE, SYSLOG_SEVERITY, SYSLOG_MESSAGETYPE) ); // return results! return $res; } /* * Implementation of CreateLogStreamIndexes | Will create missing TRIGGER */ public function CreateLogStreamTrigger( $mySourceID ) { // Call basic report Check function $res = $this->CreateLogStreamTriggerByPropertyArray( $mySourceID, SYSLOG_MESSAGE, MISC_CHECKSUM ); // return results! return $res; } // --- Private functions... /** * Helper function to consolidate events */ private function ConsolidateEventsPerHost( $arrHosts ) { global $content, $gl_starttime, $fields; // Now open the stream for data processing $res = $this->_streamObj->Open( $this->_arrProperties, true ); if ( $res == SUCCESS ) { // --- New Method to consolidate data! // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // Update all Checksums first! $this->_streamObj->UpdateAllMessageChecksum(); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; foreach ( $arrHosts as $myHost ) { // Set custom filters $this->_streamObj->ResetFilters(); $this->_streamObj->SetFilter( $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_NT_EventReport . ",=" . IUT_WEVTMONV2 ); $this->_streamObj->RemoveFilters( SYSLOG_HOST ); $this->_streamObj->AppendFilter( $fields[SYSLOG_HOST]['SearchField'] . ":=" . $myHost ); // Set Host Item Basics if not set yet $content["report_consdata"][ $myHost ][SYSLOG_HOST] = $myHost; // Get Data for single host $content["report_consdata"][ $myHost ]['cons_events'] = $this->_streamObj->ConsolidateDataByField( MISC_CHECKSUM, $this->_maxEventsPerHost, MISC_CHECKSUM, SORTING_ORDER_DESC, null, true, true ); //print_r ($fields[SYSLOG_MESSAGE]); foreach ( $content["report_consdata"][ $myHost ]['cons_events'] as &$myConsData ) { // Set Basic data entries if (!isset( $content['filter_severity_list'][$myConsData[SYSLOG_SEVERITY]] )) $myConsData[SYSLOG_SEVERITY] = SYSLOG_NOTICE; // Set default in this case } } // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // --- /* OLD CODE // Init uid helper $uID = UID_UNKNOWN; // Set position to BEGIN of FILE $this->_streamObj->Sseek($uID, EnumSeek::BOS, 0); // Start reading data $ret = $this->_streamObj->Read($uID, $logArray); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // Found first data record if ( $ret == SUCCESS ) { do { // Check if Event from host is in our hosts array if ( in_array($logArray[SYSLOG_HOST], $arrHosts) ) { // Set Host Item Basics if not set yet if ( !isset($content["report_consdata"][ $logArray[SYSLOG_HOST] ][SYSLOG_HOST]) ) { $content["report_consdata"][ $logArray[SYSLOG_HOST] ][SYSLOG_HOST] = $logArray[SYSLOG_HOST]; } // Calc checksum if ( !isset($logArray[MISC_CHECKSUM]) || $logArray[MISC_CHECKSUM] == 0 ) { // Calc crc32 from message, we use this as index $logArray[MISC_CHECKSUM] = crc32( $logArray[SYSLOG_MESSAGE] ); // Maybe useful somewhere else: sprintf( "%u", crc32 ( $logArray[SYSLOG_MESSAGE] )); $strChecksum = $logArray[MISC_CHECKSUM]; // Save calculated Checksum into DB! $this->_streamObj->SaveMessageChecksum($logArray); } else // Get checksum $strChecksum = $logArray[MISC_CHECKSUM]; // Check if entry exists in result array if ( isset($content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]) ) { // Increment counter and set First/Last Event date $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]['itemcount']++; // Set FirstEvent date if necessary! if ( $logArray[SYSLOG_DATE][EVTIME_TIMESTAMP] < $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]['FirstEvent_Date'][EVTIME_TIMESTAMP] ) $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]['FirstEvent_Date'] = $logArray[SYSLOG_DATE]; // Set LastEvent date if necessary! if ( $logArray[SYSLOG_DATE][EVTIME_TIMESTAMP] > $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]['LastEvent_Date'][EVTIME_TIMESTAMP] ) $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]['LastEvent_Date'] = $logArray[SYSLOG_DATE]; } else { // Set Basic data entries $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ][SYSLOG_SEVERITY] = $logArray[SYSLOG_SEVERITY]; $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ][SYSLOG_EVENT_ID] = $logArray[SYSLOG_EVENT_ID]; $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ][SYSLOG_EVENT_SOURCE] = $logArray[SYSLOG_EVENT_SOURCE]; $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ][SYSLOG_MESSAGE] = $logArray[SYSLOG_MESSAGE]; // Set Counter and First/Last Event date $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]['itemcount'] = 1; $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]['FirstEvent_Date'] = $logArray[SYSLOG_DATE]; $content["report_consdata"][ $logArray[SYSLOG_HOST] ]['cons_events'][ $strChecksum ]['LastEvent_Date'] = $logArray[SYSLOG_DATE]; } } // Get next data record $ret = $this->_streamObj->ReadNext($uID, $logArray); } while ( $ret == SUCCESS ); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; } */ // Start Postprocessing foreach( $content["report_consdata"] as &$tmpConsolidatedComputer ) { // First use callback function to sort array uasort($tmpConsolidatedComputer['cons_events'], "MultiSortArrayByItemCountDesc"); // Remove entries according to _maxEventsPerHost if ( count($tmpConsolidatedComputer['cons_events']) > $this->_maxEventsPerHost ) { $iDropCount = 0; do { array_pop($tmpConsolidatedComputer['cons_events']); $iDropCount++; } while ( count($tmpConsolidatedComputer['cons_events']) > $this->_maxEventsPerHost ); // Append a dummy entry which shows count of all other events if ( $iDropCount > 0 ) { $lastEntry[SYSLOG_SEVERITY] = SYSLOG_NOTICE; $lastEntry[SYSLOG_EVENT_ID] = "-"; $lastEntry[SYSLOG_EVENT_SOURCE] = $content['LN_GEN_ALL_OTHER_EVENTS']; $lastEntry[SYSLOG_MESSAGE] = $content['LN_GEN_ALL_OTHER_EVENTS']; $lastEntry['itemcount'] = $iDropCount; $lastEntry['FirstEvent_Date'] = "-"; $lastEntry['LastEvent_Date'] = "-"; $tmpConsolidatedComputer['cons_events'][] = $lastEntry; } } // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // PostProcess Events! foreach( $tmpConsolidatedComputer["cons_events"] as &$tmpMyEvent ) { $tmpMyEvent['FirstEvent_Date_Formatted'] = GetFormatedDate( $tmpMyEvent['firstoccurrence_date'] ); $tmpMyEvent['LastEvent_Date_Formatted'] = GetFormatedDate( $tmpMyEvent['lastoccurrence_date'] ); $tmpMyEvent['syslogseverity_text'] = $content['filter_severity_list'][ $tmpMyEvent['syslogseverity'] ]["DisplayName"]; $tmpMyEvent['syslogseverity_bgcolor'] = $this->GetSeverityBGColor($tmpMyEvent['syslogseverity']); } } // --- } // Work done! return SUCCESS; } /* * Helper function to obtain Severity background color */ private function GetSeverityBGColor( $nSeverity ) { global $severity_colors; if ( isset( $severity_colors[$nSeverity] ) ) return $severity_colors[$nSeverity]; else return $severity_colors[SYSLOG_INFO]; //Default } } ?>loganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary/0000755000175000017500000000000012225176641025151 5ustar danieldaniel././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary/report.eventlog.eventsummary.template.htmlloganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary/report.eventlog.eventsummary.temp0000644000175000017500000001275412225176641033744 0ustar danieldaniel {report_title}
    {report_title}
    {LN_REPORT_GENERATEDTIME} {report_gentime}
    {report_comment}
    {LN_REPORT_FILTERS}
    {FilterType} {FilterDisplay}


    {ln_report_summary}
    {ln_report_event_summary}
    {DisplayName} {itemcount}
    {ln_report_computer_summary}
    {FROMHOST}({itemcount}),


    {ln_report_consolidation}

    {FROMHOST}

    {ln_report_number} {ln_report_count} {ln_report_firstevent} {ln_report_lastevent} {ln_report_process} {ln_report_severity} {ln_report_eventid} {ln_report_description}
    {ZAEHLER} {itemcount} {itemcount} {FirstEvent_Date_Formatted} {LastEvent_Date_Formatted} {sourceproc} {syslogseverity_text} {id} {msg}
    Made by Adiscon GmbH (2009-2011)  Report Version {report_version}  Partners:  Rsyslog |  WinSyslog {LN_REPORT_FOOTER_ENDERED}: {report_rendertime}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}
    ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary/report.eventlog.eventsummary.template.pdfloganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary/report.eventlog.eventsummary.temp0000644000175000017500000001137612225176641033743 0ustar danieldaniel {report_title}

    {report_title}

    {LN_REPORT_GENERATEDTIME} {report_gentime}

    {report_comment}


    {LN_REPORT_FILTERS}
    {FilterType} {FilterDisplay}

    {ln_report_summary}

    {ln_report_event_summary}
    {DisplayName} {itemcount}

    {ln_report_computer_summary}
    {FROMHOST}({itemcount}),

    {ln_report_consolidation}

    {FROMHOST}

    {ln_report_number} {ln_report_count} {ln_report_firstevent} {ln_report_lastevent} {ln_report_process} {ln_report_severity} {ln_report_eventid}
    {ZAEHLER} {itemcount} {itemcount} {FirstEvent_Date_Formatted} {LastEvent_Date_Formatted} {sourceproc} {syslogseverity_text} {id}
    {ln_report_description} {msg:wordwrap:32}


    Made by Adiscon GmbH (2009-2011)  Report Version {report_version} Partners: Rsyslog |  WinSyslog
    {LN_REPORT_FOOTER_ENDERED}: {report_rendertime}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}
    ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary/report.eventlog.eventsummary.lang.en.phploganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary/report.eventlog.eventsummary.lang0000644000175000017500000000466312225176641033720 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ global $content; // Global Stuff $content['ln_report_event_summary'] = "Event Summary"; $content['ln_report_computer_summary'] = "Computer Summary"; $content['ln_report_consolidation'] = "Events Consolidated per Host"; $content['ln_report_summary'] = "Report Summary"; $content['ln_report_number'] = "No."; $content['ln_report_firstevent'] = "First Event"; $content['ln_report_lastevent'] = "Last Event"; $content['ln_report_process'] = "Process"; $content['ln_report_severity'] = "Type"; $content['ln_report_eventid'] = "Event ID"; $content['ln_report_description'] = "Description"; $content['ln_report_count'] = "Count"; $content['ln_report_maxHosts_displayname'] = "Max hosts"; $content['ln_report_maxHosts_description'] = "The maximum number of hosts which will be displayed."; $content['ln_report_maxEventsPerHost_displayname'] = "Max Events per host"; $content['ln_report_maxEventsPerHost_description'] = "The maximum number of events displayed per host."; $content['ln_report_colorThreshold_displayname'] = "Counter Threshold"; $content['ln_report_colorThreshold_description'] = "If the amount of consolidated events is higher then this threshold, the countfield will be marked red."; $content['ln_report_'] = ""; $content['ln_report_'] = ""; $content['ln_report_'] = ""; $content['ln_report_'] = ""; $content['ln_report_'] = ""; $content['ln_report_'] = ""; $content['ln_report_'] = ""; ?>loganalyzer-3.6.5/src/classes/reports/report.eventlog.eventsummary/report.eventlog.eventsummary.css0000644000175000017500000002410712225176641033562 0ustar danieldaniel/* Generell Tag Classes */ BODY { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; color: #000000; background-color: #f9f9f9; scrollbar-face-color: #DEE3E7; scrollbar-highlight-color: #FFFFFF; scrollbar-shadow-color: #DEE3E7; scrollbar-3dlight-color: #D1D7DC; scrollbar-arrow-color: #006699; scrollbar-track-color: #EFEFEF; scrollbar-darkshadow-color: #98AAB1; } TD { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #000000 } /* Default Link Classes */ a:link,a:active,a:visited,a.postlink { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-decoration:none; background-color: transparent; color:#38140E; } a:hover { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; color:#CC0000; } /*---*/ /* Context Link Classes */ a.contextlink:link,a.contextlink:active,a.contextlink:visited,a.contextlink { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; background-color: transparent; color:#3814BB; text-decoration:underline; } a.contextlink:hover { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight:bold; color:#3844FF; text-decoration:none; } /*---*/ img { border: 0px; } /* Title Classes */ .title { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight:bold; background-color: #C6B097; color: #032D5D; border: 1px solid; border-color: #ACBED6 #3B679B #3B679B #ACBED6; height: 20px; text-align:center; vertical-align:middle; } A.title, A.title:active, A.title:visited { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight:bold; COLOR: #ED9D10; TEXT-DECORATION: none; } A.title:hover { COLOR: #982D00; TEXT-DECORATION: none; } .titleSecond { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #E3D2AE; background-image: url(images/bg_4.png); background-repeat: repeat-x; color: #1A3745; height: 18px; text-align:center; vertical-align:middle; } /* Default Font Classes */ font { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; } /* Table / Border Classes */ .table_with_border { background-color:#EEF2F6; border:1px solid; border-color: #CCCCCC #000000 #000000 #CCCCCC; } .table_with_border_second { background-color:#D5E0E7; border:1px solid; border-color: #CCCCCC #000000 #000000 #CCCCCC; } .table_with_border_light { background-color:#CCCCCC; border:1px #AAAAAA solid; } .with_border { text-indent:3px; background-color:#CCCCCC; border:1px #AAAAAA solid; } .with_border_alternate { text-indent:3px; background-color:#CCCCCC; border:1px #AAAAAA ridge; } .mainheader { border:1px solid; background-color:#C7CBD1; border-color: #44617D #203040 #203040 #44617D; } .mainfooter { height: 20px; background-color:#DDDDDD; border-top: #97A8B9 1px solid; border-bottom: #6592BD 1px solid; } .imageborder { border:1px solid; border-color: #44617D #203040 #203040 #44617D; } /* Cells for listening */ .line0 { font-size: 7pt; color: #000000; background-color: #DDDDDD; } .line0:hover { background-color:#F9F9F9; } .line1 { font-size: 7pt; color: #000000; background-color: #EEEEEE; } .line1:hover { background-color:#F9F9F9; } .line2 { font-size: 7pt; color: #000000; background-color: #F5F5F5; } .line2:hover { background-color:#F9F9F9; } .tableBackground { font-size: 10px; color: #000000; background-color: #F5F5F5; } .lineColouredWhite, .lineColouredWhite:hover, a.lineColouredWhite { font-size: 10px; color: #FFFFFF; } .lineColouredBlack, .lineColouredBlack:hover, a.lineColouredBlack { font-size: 10px; color: #000000; } /* TOP Menu Classes */ .topmenu1begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #4E6485; } .topmenu1 { height: 16px; border:1px ridge; border-color: #79AABE #09506C #79AABE #79AABE; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #4E6485; } .topmenu1:hover { color: #FFFF99; border:1px inset; border-color: #79AABE #09506C #79AABE #79AABE; background-color: #6A88B8; text-decoration: none; } .topmenuend { height: 16px; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #4E6485; } .topmenuextra { height: 16px; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #B8D4E0; } .topmenu2begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #7A92A6; } .topmenu2 { height: 16px; border:1px ridge; border-color: #BDEEFF #79AABE #09506C #09506C; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #7A92A6; } .topmenu2:hover { color: #FFFF99; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; background-color: #6A88B8; text-decoration: none; } .topmenu2_link, A.topmenu2_link { color: #FFDD22; } .topmenu2_link:hover, A.topmenu2_link:hover { color: #FFFF99; text-decoration: none; } .topmenu2end { height: 16px; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #7A92A6; } .topmenu3begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #D4DAE3; } .topmenu3 { height: 16px; border:1px ridge; border-color: #BDEEFF #79AABE #09506C #09506C; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Arial, Verdana, Helvetica, sans-serif; color: #FFFFFF; background-color: #D4DAE3; } .topmenu3:hover { color: #FFFF99; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; background-color: #ACCBFD; text-decoration: none; } .topmenu3end { height: 16px; font: 10px Arial, Verdana, Helvetica, sans-serif; color: #FFFFFF; background-color: #D4DAE3; } .topmenu1_link, a.topmenu1_link, a.topmenu1_link:visited, .topmenu2_link, a.topmenu2_link, a.topmenu2_link:visited, .topmenu3_link, a.topmenu3_link, a.topmenu3_link:visited { vertical-align: middle; height: 16px; color: #FFDD22; font-weight:bold; text-decoration: none; } .topmenu1_link:hover, .topmenu2_link:hover, .topmenu3_link:hover { vertical-align: middle; color: #FFFF99; font-weight:bold; text-decoration: none; } /* Cell Columns */ .cellmenu1 { border:1px ridge; border-color: #79AABE #09506C #09506C #79AABE; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #2E79A0; color: #FFFFFF; } .cellmenu1_naked { border:1px ridge; border-color: #79AABE #09506C #09506C #79AABE; background-color: #2E79A0; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; color: #FFFFFF; } .cellmenu1:hover .cellmenu1_naked:hover { color: #FFFF99; text-decoration: none; } A.cellmenu1_link { color: #FFFF55; text-decoration: underline; } A.cellmenu1_link:hover { color: #FFBB55; text-decoration: none; } .cellmenu2 { border:1px inset; border-color: #79AABE #09506C #09506C #79AABE; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #9FDAF1; color: #393327; } .cellmenu2_naked { text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; color: #393327; border:1px inset; border-color: #79AABE #09506C #09506C #79AABE; background-color: #9FDAF1; } .cellmenu2:hover, .cellmenu2_naked:hover { color: #A31D32; text-decoration: none; } /* Usefull Text Classes */ .ErrorMsg { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; COLOR: #FF0000; } .PriorityEmergency { color: #FFFFFF; background-color: #ff4444; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityAlert { color: #FFFFFF; background-color: #dd00dd; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityCrit { color: #FFFFFF; background-color: #dd9900; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityError { color: #FFFFFF; background-color: #CC0000; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityWarning { color: #FFFFFF; background-color: #FFAA00; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityNotice { color: #FFFFFF; background-color: #66CC33; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityInfo { color: #000000; background-color: #ABF1FF; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityDebug { color: #FFFFFF; background-color: #3333ff; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } /* Form elements */ select, input, button, textarea { background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .SearchFormControl { height: 20px; margin: 2px; background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .SearchFormTextbox { height: 20px; margin: 2px; background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .highlighted { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; color: #BB0000 } loganalyzer-3.6.5/src/classes/reports/report.eventlog.auditsummary/0000755000175000017500000000000012306337457025142 5ustar danieldaniel././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.eventlog.auditsummary/report.eventlog.auditsummary.template.pdfloganalyzer-3.6.5/src/classes/reports/report.eventlog.auditsummary/report.eventlog.auditsummary.temp0000644000175000017500000001501612225176641033710 0ustar danieldaniel {report_title}

    {report_title}

    {LN_REPORT_GENERATEDTIME} {report_gentime}

    {report_comment}


    {LN_REPORT_FILTERS}
    {FilterType} {FilterDisplay}

    {ln_report_summary}

    {ln_report_audit_summary}
    {DisplayName} {itemcount}
    {ln_report_consolidated_summary}
    {TargetLink}({itemcount}), {TargetLink}({itemcount}),

    {ln_report_consolidation}

    {DataCaption}

    {ln_report_number} {ln_report_count} {ln_report_firstevent} {ln_report_lastevent} {ln_report_user} {ln_report_host}
    {ZAEHLER} {itemcount} {itemcount} {FirstEvent_Date_Formatted} {LastEvent_Date_Formatted} {user} {FROMHOST}

    {report_detaildata_users_caption}

    {ln_report_number} {ln_report_count} {ln_report_user}
    {ZAEHLER} {itemcount} {itemcount} {user}

    {report_detaildata_hosts_caption}

    {ln_report_number} {ln_report_count} {ln_report_host}
    {ZAEHLER} {itemcount} {itemcount} {FROMHOST}


    Made by Adiscon GmbH (2009-2012)  Report Version {report_version} Partners: Rsyslog |  WinSyslog
    {LN_REPORT_FOOTER_ENDERED}: {report_rendertime}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}
    ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.eventlog.auditsummary/report.eventlog.auditsummary.template.htmlloganalyzer-3.6.5/src/classes/reports/report.eventlog.auditsummary/report.eventlog.auditsummary.temp0000644000175000017500000001766512225176641033724 0ustar danieldaniel {report_title}
    {report_title}
    {LN_REPORT_GENERATEDTIME} {report_gentime}
    {report_comment}
    {LN_REPORT_FILTERS}
    {FilterType} {FilterDisplay}


    {ln_report_summary}
    {ln_report_audit_summary}
    {DisplayName} {itemcount}
    {ln_report_consolidated_summary}
    {TargetLink}({itemcount}), {TargetLink}({itemcount}),


    {ln_report_consolidation}


    {DataCaption}
    {ln_report_number} {ln_report_count} {ln_report_firstevent} {ln_report_lastevent} {ln_report_user} {ln_report_severity} {ln_report_host}
    {ZAEHLER} {itemcount} {itemcount} {FirstEvent_Date_Formatted} {LastEvent_Date_Formatted} {user} {syslogseverity_text} {FROMHOST}


    {ln_report_detailactions}
    {report_detaildata_users_caption} {report_detaildata_hosts_caption}
    {ln_report_number} {ln_report_count} {ln_report_user}
    {ZAEHLER} {itemcount} {itemcount} {user}
    {ln_report_number} {ln_report_count} {ln_report_host}
    {ZAEHLER} {itemcount} {itemcount} {FROMHOST}
    Made by Adiscon GmbH (2009-2012)  Report Version {report_version}  Partners:  Rsyslog |  WinSyslog {LN_REPORT_FOOTER_ENDERED}: {report_rendertime}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}
    loganalyzer-3.6.5/src/classes/reports/report.eventlog.auditsummary/report.eventlog.auditsummary.css0000644000175000017500000002410712225176641033534 0ustar danieldaniel/* Generell Tag Classes */ BODY { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; color: #000000; background-color: #f9f9f9; scrollbar-face-color: #DEE3E7; scrollbar-highlight-color: #FFFFFF; scrollbar-shadow-color: #DEE3E7; scrollbar-3dlight-color: #D1D7DC; scrollbar-arrow-color: #006699; scrollbar-track-color: #EFEFEF; scrollbar-darkshadow-color: #98AAB1; } TD { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #000000 } /* Default Link Classes */ a:link,a:active,a:visited,a.postlink { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-decoration:none; background-color: transparent; color:#38140E; } a:hover { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; color:#CC0000; } /*---*/ /* Context Link Classes */ a.contextlink:link,a.contextlink:active,a.contextlink:visited,a.contextlink { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; background-color: transparent; color:#3814BB; text-decoration:underline; } a.contextlink:hover { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight:bold; color:#3844FF; text-decoration:none; } /*---*/ img { border: 0px; } /* Title Classes */ .title { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight:bold; background-color: #C6B097; color: #032D5D; border: 1px solid; border-color: #ACBED6 #3B679B #3B679B #ACBED6; height: 20px; text-align:center; vertical-align:middle; } A.title, A.title:active, A.title:visited { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight:bold; COLOR: #ED9D10; TEXT-DECORATION: none; } A.title:hover { COLOR: #982D00; TEXT-DECORATION: none; } .titleSecond { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #E3D2AE; background-image: url(images/bg_4.png); background-repeat: repeat-x; color: #1A3745; height: 18px; text-align:center; vertical-align:middle; } /* Default Font Classes */ font { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; } /* Table / Border Classes */ .table_with_border { background-color:#EEF2F6; border:1px solid; border-color: #CCCCCC #000000 #000000 #CCCCCC; } .table_with_border_second { background-color:#D5E0E7; border:1px solid; border-color: #CCCCCC #000000 #000000 #CCCCCC; } .table_with_border_light { background-color:#CCCCCC; border:1px #AAAAAA solid; } .with_border { text-indent:3px; background-color:#CCCCCC; border:1px #AAAAAA solid; } .with_border_alternate { text-indent:3px; background-color:#CCCCCC; border:1px #AAAAAA ridge; } .mainheader { border:1px solid; background-color:#C7CBD1; border-color: #44617D #203040 #203040 #44617D; } .mainfooter { height: 20px; background-color:#DDDDDD; border-top: #97A8B9 1px solid; border-bottom: #6592BD 1px solid; } .imageborder { border:1px solid; border-color: #44617D #203040 #203040 #44617D; } /* Cells for listening */ .line0 { font-size: 7pt; color: #000000; background-color: #DDDDDD; } .line0:hover { background-color:#F9F9F9; } .line1 { font-size: 7pt; color: #000000; background-color: #EEEEEE; } .line1:hover { background-color:#F9F9F9; } .line2 { font-size: 7pt; color: #000000; background-color: #F5F5F5; } .line2:hover { background-color:#F9F9F9; } .tableBackground { font-size: 10px; color: #000000; background-color: #F5F5F5; } .lineColouredWhite, .lineColouredWhite:hover, a.lineColouredWhite { font-size: 10px; color: #FFFFFF; } .lineColouredBlack, .lineColouredBlack:hover, a.lineColouredBlack { font-size: 10px; color: #000000; } /* TOP Menu Classes */ .topmenu1begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #4E6485; } .topmenu1 { height: 16px; border:1px ridge; border-color: #79AABE #09506C #79AABE #79AABE; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #4E6485; } .topmenu1:hover { color: #FFFF99; border:1px inset; border-color: #79AABE #09506C #79AABE #79AABE; background-color: #6A88B8; text-decoration: none; } .topmenuend { height: 16px; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #4E6485; } .topmenuextra { height: 16px; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #B8D4E0; } .topmenu2begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #7A92A6; } .topmenu2 { height: 16px; border:1px ridge; border-color: #BDEEFF #79AABE #09506C #09506C; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #7A92A6; } .topmenu2:hover { color: #FFFF99; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; background-color: #6A88B8; text-decoration: none; } .topmenu2_link, A.topmenu2_link { color: #FFDD22; } .topmenu2_link:hover, A.topmenu2_link:hover { color: #FFFF99; text-decoration: none; } .topmenu2end { height: 16px; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #7A92A6; } .topmenu3begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #D4DAE3; } .topmenu3 { height: 16px; border:1px ridge; border-color: #BDEEFF #79AABE #09506C #09506C; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Arial, Verdana, Helvetica, sans-serif; color: #FFFFFF; background-color: #D4DAE3; } .topmenu3:hover { color: #FFFF99; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; background-color: #ACCBFD; text-decoration: none; } .topmenu3end { height: 16px; font: 10px Arial, Verdana, Helvetica, sans-serif; color: #FFFFFF; background-color: #D4DAE3; } .topmenu1_link, a.topmenu1_link, a.topmenu1_link:visited, .topmenu2_link, a.topmenu2_link, a.topmenu2_link:visited, .topmenu3_link, a.topmenu3_link, a.topmenu3_link:visited { vertical-align: middle; height: 16px; color: #FFDD22; font-weight:bold; text-decoration: none; } .topmenu1_link:hover, .topmenu2_link:hover, .topmenu3_link:hover { vertical-align: middle; color: #FFFF99; font-weight:bold; text-decoration: none; } /* Cell Columns */ .cellmenu1 { border:1px ridge; border-color: #79AABE #09506C #09506C #79AABE; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #2E79A0; color: #FFFFFF; } .cellmenu1_naked { border:1px ridge; border-color: #79AABE #09506C #09506C #79AABE; background-color: #2E79A0; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; color: #FFFFFF; } .cellmenu1:hover .cellmenu1_naked:hover { color: #FFFF99; text-decoration: none; } A.cellmenu1_link { color: #FFFF55; text-decoration: underline; } A.cellmenu1_link:hover { color: #FFBB55; text-decoration: none; } .cellmenu2 { border:1px inset; border-color: #79AABE #09506C #09506C #79AABE; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #9FDAF1; color: #393327; } .cellmenu2_naked { text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; color: #393327; border:1px inset; border-color: #79AABE #09506C #09506C #79AABE; background-color: #9FDAF1; } .cellmenu2:hover, .cellmenu2_naked:hover { color: #A31D32; text-decoration: none; } /* Usefull Text Classes */ .ErrorMsg { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; COLOR: #FF0000; } .PriorityEmergency { color: #FFFFFF; background-color: #ff4444; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityAlert { color: #FFFFFF; background-color: #dd00dd; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityCrit { color: #FFFFFF; background-color: #dd9900; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityError { color: #FFFFFF; background-color: #CC0000; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityWarning { color: #FFFFFF; background-color: #FFAA00; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityNotice { color: #FFFFFF; background-color: #66CC33; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityInfo { color: #000000; background-color: #ABF1FF; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityDebug { color: #FFFFFF; background-color: #3333ff; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } /* Form elements */ select, input, button, textarea { background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .SearchFormControl { height: 20px; margin: 2px; background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .SearchFormTextbox { height: 20px; margin: 2px; background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .highlighted { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; color: #BB0000 } loganalyzer-3.6.5/src/classes/reports/report.class.php0000644000175000017500000006037412225176641022420 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- // Include LogStream facility include_once($gl_root_path . 'classes/logstream.class.php'); abstract class Report { // Common Properties public $_reportVersion = 1; // Internally Version of the ReportEngine public $_reportID = "report.syslog.base.class"; // ID for the report, needs to be unique! - Format report.Category.ReportID.class public $_reportFileBasicName = "report.syslog.base"; // Basic Filename for reportfiles public $_reportTitle = "Base Report Class"; // Display name for the report public $_reportDescription = "This is the base class for all reports"; public $_reportHelpArticle = "http://"; public $_reportNeedsInit = false; // True means that this report needs additional init stuff public $_reportInitialized = false; // True means report is installed // SavedReport Configuration Properties protected $_customTitle = ""; protected $_customComment = ""; protected $_filterString = ""; // Filterstring like used in the search view protected $_arrCustomFilters = null; // Array contains list of available custom filters, used for admin interface! protected $_customFilters = ""; // Xml Filterstring containing values for the custom filters protected $_outputFormat = REPORT_OUTPUT_HTML; // Default HTML Output protected $_outputTarget = REPORT_TARGET_STDOUT;// Default is stdout protected $_arrOutputTargetDetails = null; // Array containing helper settings for the output Target protected $_scheduleSettings = ""; protected $_mySourceID = ""; protected $_arrProperties = null; // List of properties we need for the main logstream query! // License properties protected $_licenseName = ""; protected $_licenseKey = ""; // Helper Objects protected $_reportcontent = null; protected $_baseFileName = ""; public $_streamCfgObj = null; public $_streamObj = null; // Begin Abstract Function definitions! /** * This function process the data * Will return -1 on failure! */ public abstract function startDataProcessing(); /** * This function checks if the license is valid * Will return -1 on failure! */ public abstract function validateLicense(); /** * This function inits data for the report */ public abstract function InitReport(); /** * This function removes data for the report */ public abstract function RemoveReport(); /** * This function will init advanced settings from _customFilters string */ public abstract function InitAdvancedSettings(); /** * If the reports needs to optimize the logstream, it is checked and verified by this function */ public abstract function CheckLogStreamSource( $mySourceID ); /** * If the reports needs INDEXES, these are created by this function */ public abstract function CreateLogStreamIndexes( $mySourceID ); /** * If the reports needs a TRIGGER, these are created by this function */ public abstract function CreateLogStreamTrigger( $mySourceID ); /** * verifyDataSource, verifies if data is accessable and * contains what we need * * @param arrProperties array in: Properties wish list. * @return integer Error stat */ public function verifyDataSource() { global $content; if ( $this->_streamCfgObj == null ) { if ( isset($content['Sources'][$this->_mySourceID]['ObjRef']) ) { // Obtain and get the Config Object $this->_streamCfgObj = $content['Sources'][$this->_mySourceID]['ObjRef']; // Fix Filename manually for FILE LOGSTREAM! if ( $content['Sources'][$this->_mySourceID]['SourceType'] == SOURCE_DISK ) $this->_streamCfgObj->FileName = CheckAndPrependRootPath( $content['Sources'][$this->_mySourceID]['DiskFile'] ); } else return ERROR_SOURCENOTFOUND; } if ( $this->_streamObj == null ) { // Create LogStream Object $this->_streamObj = $this->_streamCfgObj->LogStreamFactory($this->_streamCfgObj); } // Check datasource and return result $res = $this->_streamObj->Verify(); return $res; } /** * This function checks if we have a valid template for the selected output * Will return error code on failure! */ public function validateOutputTemplate( $szOutputID ) { global $content, $gl_root_path; $szDirectory = $gl_root_path . 'classes/reports/'; $szIncludeFile = $szDirectory . $this->_reportFileBasicName . "." . $szOutputID; if ( file_exists($szIncludeFile) ) { // Success! return SUCCESS; } else { // Template file not found! return ERROR_FILE_NOT_FOUND; } } /** * Helper function using the template parser to create the report */ public function CreateReportFromData() { // Create new template parser $page = new Template(); $page -> set_path ( $gl_root_path . "classes/reports/" ); // Run Parser $page -> parser($this->_reportcontent, $this->_baseFileName); // Return result! return $page -> result(); } /* * Helper function to set the OutputType */ public function SetOutputFormat($newOutputType) { // Set new Outputtype $this->_outputFormat = $newOutputType; // Get include path $szIncludePath = $this->GetReportIncludePath(); // Set Filebasename $this->_baseFileName = $this->_reportFileBasicName . ".template." . $this->_outputFormat; // Set to HTML Template if is missing! if ( !is_file( $szIncludePath . $this->_baseFileName) ) $this->_baseFileName = $this->_reportFileBasicName . ".template." . REPORT_OUTPUT_HTML; } /* * Helper function to set the OutputTarget */ public function SetOutputTarget($newOutputTarget) { // TODO: Check if Outputtarget EXISTS! // Set new OutputTarget $this->_outputTarget = $newOutputTarget; } /* * Helper function to set the OutputTarget */ public function SetOutputTargetDetails($newOutputTargetDetailsStr) { // Only set if valid string if ( strlen($newOutputTargetDetailsStr) > 0 ) { // First of all split by comma $tmpValues = explode( ",", $newOutputTargetDetailsStr ); //Loop through mappings foreach ($tmpValues as &$myValue ) { if ( strlen(trim($myValue)) > 0 ) { // Split subvalues $tmpArray = explode( "=>", $myValue ); // Get tmp fieldID $tmpFieldID = trim($tmpArray[0]); // Set into Details Array $this->_arrOutputTargetDetails[$tmpFieldID] = trim($tmpArray[1]); } } } } /* * Helper function to set the Scheduled Settings */ public function SetScheduleSettings($newScheduleSettings) { // Set new ScheduleSettings $this->_scheduleSettings = $newScheduleSettings; } /* * Helper function to set the FilterString */ public function SetFilterString($newFilterString) { // Set new Outputtype $this->_filterString = $newFilterString; } /* * Helper function to set the FilterString */ public function SetCustomFilters($newAdvancedOptions) { // Set new Outputtype $this->_customFilters = $newAdvancedOptions; // Call report function to init advanced settings! $this->InitAdvancedSettings(); } /* * Helper function to set the FilterString */ public function SetCustomTitle($newCustomTitle) { // Set new Custom Title $this->_customTitle = $newCustomTitle; } /* * Helper function to set the FilterString */ public function SetCustomComment($newCustomComment) { // Set new Custom Comment $this->_customComment = $newCustomComment; } /* * Helper function to set the FilterString */ public function SetSourceID($newSourceID) { global $content; // check if valid! if ( isset($content['Sources'][$newSourceID]) ) $this->_mySourceID = $newSourceID; else { OutputDebugMessage("SetSourceID failed, ID '" . $newSourceID . "' is not a valid Logstream Source", DEBUG_ERROR); return; } } /* * Helper function to set the FilterString */ public function SetCommonContentVariables() { global $content, $fields; $content["report_title"] = $this->GetCustomTitle(); $content["report_comment"] = $this->GetCustomComment(); $content["report_version"] = $this->GetReportVersion(); $content["report_gentime"] = date(DATE_RFC822); // Create array for readable filters display $myFilters = $this->_streamObj->ReturnFiltersArray(); if ( $myFilters != null ) { // Enable display of filters $content["report_filters_enabled"] = true; foreach ( $myFilters as $myFieldID => $myFieldFilters ) { // Init Filterstring entry $aNewDisplayFilter = array(); $aNewDisplayFilter['FilterDisplay'] = ""; $aNewDisplayFilter['FieldID'] = $myFieldID; if ( isset($fields[$myFieldID]['FieldCaption']) ) $aNewDisplayFilter['FilterCaption'] = $fields[$myFieldID]['FieldCaption']; else $aNewDisplayFilter['FilterCaption'] = $myFieldID; foreach ( $myFieldFilters as $tmpFilter ) { // Date field means special handling! if ( $myFieldID == SYSLOG_DATE ) { // Set Filtertype Display $aNewDisplayFilter['FilterType'] = $content['LN_REPORT_FILTERTYPE_DATE']; // Append Datefilter to Title // $content["report_title"] .= if ( $tmpFilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { $aNewDisplayFilter['FilterDisplay'] = $content['LN_FILTER_DATELASTX'] . " "; switch ( $tmpFilter[FILTER_VALUE] ) { case DATE_LASTX_HOUR: $aNewDisplayFilter['FilterDisplay'] .= "'" . $content['LN_DATE_LASTX_HOUR'] . "'"; break; case DATE_LASTX_12HOURS: $aNewDisplayFilter['FilterDisplay'] .= "'" . $content['LN_DATE_LASTX_12HOURS'] . "'"; break; case DATE_LASTX_24HOURS: $aNewDisplayFilter['FilterDisplay'] .= "'" . $content['LN_DATE_LASTX_24HOURS'] . "'"; break; case DATE_LASTX_7DAYS: $aNewDisplayFilter['FilterDisplay'] .= "'" . $content['LN_DATE_LASTX_7DAYS'] . "'"; break; case DATE_LASTX_31DAYS: $aNewDisplayFilter['FilterDisplay'] .= "'" . $content['LN_DATE_LASTX_31DAYS'] . "'"; break; } } else if ( $tmpFilter[FILTER_DATEMODE] == DATEMODE_RANGE_FROM ) $aNewDisplayFilter['FilterDisplay'] = $content["LN_FILTER_DATEFROM"] . " " . GetFormatedDate( $tmpFilter[FILTER_VALUE] ); else if ( $tmpFilter[FILTER_DATEMODE] == DATEMODE_RANGE_TO ) $aNewDisplayFilter['FilterDisplay'] = $content["LN_FILTER_DATETO"] . " " . GetFormatedDate( $tmpFilter[FILTER_VALUE] ); // Add to title! $content["report_title"] .= " - " . $aNewDisplayFilter['FilterDisplay']; } else if ( $tmpFilter[FILTER_TYPE] == FILTER_TYPE_STRING ) { // Set Filtertype Display $aNewDisplayFilter['FilterType'] = $content['LN_REPORT_FILTERTYPE_STRING']; // Set Filterdisplay $aNewDisplayFilter['FilterDisplay'] = $aNewDisplayFilter['FilterCaption'] . " "; if ( $tmpFilter[FILTER_MODE] & FILTER_MODE_INCLUDE ) { if ( $tmpFilter[FILTER_MODE] & FILTER_MODE_SEARCHFULL ) $aNewDisplayFilter['FilterDisplay'] .= "equals '" . $tmpFilter[FILTER_VALUE] . "'"; else $aNewDisplayFilter['FilterDisplay'] .= "contains '" . $tmpFilter[FILTER_VALUE] . "'"; } else if ( $tmpFilter[FILTER_MODE] & FILTER_MODE_EXCLUDE ) { if ( $tmpFilter[FILTER_MODE] & FILTER_MODE_SEARCHFULL ) $aNewDisplayFilter['FilterDisplay'] .= "does not equal '" . $tmpFilter[FILTER_VALUE] . "'"; else $aNewDisplayFilter['FilterDisplay'] .= "does not contain '" . $tmpFilter[FILTER_VALUE] . "'"; } } else if ( $tmpFilter[FILTER_TYPE] == FILTER_TYPE_NUMBER ) { // Set Filtertype Display $aNewDisplayFilter['FilterType'] = $content['LN_REPORT_FILTERTYPE_NUMBER']; // Set Filterdisplay $aNewDisplayFilter['FilterDisplay'] = $aNewDisplayFilter['FilterCaption'] . " "; if ( $tmpFilter[FILTER_MODE] & FILTER_MODE_INCLUDE ) $aNewDisplayFilter['FilterDisplay'] .= "== " . $tmpFilter[FILTER_VALUE]; else if ( $tmpFilter[FILTER_MODE] & FILTER_MODE_EXCLUDE ) $aNewDisplayFilter['FilterDisplay'] .= "!= " . $tmpFilter[FILTER_VALUE]; } // Add to display filter array if ( strlen($aNewDisplayFilter['FilterDisplay']) > 0 ) $content["report_filters"][] = $aNewDisplayFilter; } } } else { // Disable display of filters $content["report_filters_enabled"] = false; } } /* * Helper function to return the arrProperties */ public function GetRequiredProperties() { // return Filebasename return $this->_arrProperties; } /* * Helper function to return the BaseFileName */ public function GetBaseFileName() { // return Filebasename return $this->_baseFileName; } /* * Helper function to return the CustomTitle */ public function GetCustomTitle() { // return Filebasename return $this->_customTitle; } /* * Helper function to return the CustomComment */ public function GetCustomComment() { // return Filebasename return $this->_customComment; } /* * Helper function to return the ReportVersion */ public function GetReportVersion() { // return Filebasename return $this->_reportVersion; } /* * Helper function to return the custom filter definitions */ public function GetCustomFiltersDefs() { return $this->_arrCustomFilters; } /* * Helper function to return the array of OutputTarget details */ public function GetOutputTargetDetails() { return $this->_arrOutputTargetDetails; } /* * Helper function to return the OutputTarget */ public function GetOutputTarget() { // return OutputTarget return $this->_outputTarget; } /* * Helper function to trigger initialisation */ public function RunBasicInits() { $this->SetOutputType( REPORT_OUTPUT_HTML ); } /* * Helper function to set settings from savedreport! */ public function InitFromSavedReport( $mySavedReport ) { global $content; // Copy settings from saved report! $this->SetSourceID( $mySavedReport["sourceid"] ); $this->SetCustomTitle( $mySavedReport["customTitle"] ); $this->SetCustomComment( $mySavedReport["customComment"] ); $this->SetFilterString( $mySavedReport["filterString"] ); $this->SetCustomFilters( $mySavedReport["customFilters"] ); $this->SetOutputFormat( $mySavedReport["outputFormat"] ); $this->SetOutputTarget( $mySavedReport["outputTarget"] ); $this->SetOutputTargetDetails( $mySavedReport["outputTargetDetails"] ); $this->SetScheduleSettings( $mySavedReport["scheduleSettings"] ); } /* * Helper function to get the report include path */ public function GetReportIncludePath() { global $gl_root_path; return $gl_root_path . 'classes/reports/' . $this->_reportFileBasicName . "/"; } /* * Helper function to init custom language strings from report! */ public function InitReportLanguageFile($szReportIncludePath) { // Include Custom language file if available IncludeLanguageFile( $szReportIncludePath . $this->_reportFileBasicName . ".lang.en.php" ); } /* * This function outputs the report to the browser in the desired format! */ public function OutputReport($szOutputBuffer, &$szErrorStr) { global $gl_root_path; // Helper variable, init with buffer $szFinalOutput = $szOutputBuffer; $res = SUCCESS; // Simple HTML Output! if ( $this->_outputFormat == REPORT_OUTPUT_HTML ) { // do nothing } else if ( $this->_outputFormat == REPORT_OUTPUT_PDF ) { // Convert into PDF! include_once($gl_root_path . 'classes/html2fpdf/html2fpdf.php'); // $pdf=new HTML2FPDF('landscape'); $pdf=new HTML2FPDF(); $pdf->UseCss(true); $pdf->AddPage(); // $pdf->SetFontSize(12); $pdf->WriteHTML( $szOutputBuffer ); $szFinalOutput = $pdf->Output('', 'S'); // Output to STANDARD Input! } // Simple HTML Output! if ( $this->_outputTarget == REPORT_TARGET_STDOUT ) { // Check if we need another header if ( $this->_outputFormat == REPORT_OUTPUT_PDF ) Header('Content-Type: application/pdf'); // Kindly output to browser echo $szFinalOutput; $res = SUCCESS; } else if ( $this->_outputTarget == REPORT_TARGET_FILE ) { // Get Filename first if ( isset($this->_arrOutputTargetDetails['filename']) ) { // Get Filename property $szFilename = $this->_arrOutputTargetDetails['filename']; // Create file and Write Report into it! $handle = @fopen($szFilename, "w"); if ( $handle === false ) { $szErrorStr = "Could not create '" . $szFilename . "'!"; $res = ERROR; } else { fwrite($handle, $szFinalOutput); fflush($handle); fclose($handle); // For result $szErrorStr = "Results were saved into '" . $szFilename . "'"; $res = SUCCESS; } } else { $szErrorStr = "The parameter 'filename' was missing."; $res = ERROR; } } // return result return $res; } /** * If the reports needs to optimize the logstream, it is checked and verified by this function */ public function CheckLogStreamSourceByPropertyArray( $mySourceID, $arrProperties, $myTriggerProperty ) { global $content, $fields; $res = SUCCESS; if ( $this->_streamCfgObj == null ) { if ( isset($content['Sources'][$mySourceID]) ) { // Obtain and get the Config Object $this->_streamCfgObj = $content['Sources'][$mySourceID]['ObjRef']; // Return success if logstream is FILE based! if ( $content['Sources'][$mySourceID]['SourceType'] == SOURCE_DISK ) return SUCCESS; } else return ERROR_SOURCENOTFOUND; } if ( $this->_streamObj == null ) { // Create LogStream Object $this->_streamObj = $this->_streamCfgObj->LogStreamFactory($this->_streamCfgObj); } // Check datasource and return result $res = $this->_streamObj->Verify(); if ( $res == SUCCESS ) { // Will check if all necessary fields are available! $res = $this->_streamObj->VerifyFields( $this->_arrProperties ); if ($res != SUCCESS ) return $res; // Will check if TRIGGERS are installed! Requires SUPER access in database logstream! if ( $arrProperties != null ) { // Will check if certain INDEXES do exists for database logstream! $res = $this->_streamObj->VerifyIndexes( $arrProperties ); if ($res != SUCCESS ) return $res; } // Will check if checksum field is correctly configured for database logstream! $res = $this->_streamObj->VerifyChecksumField( ); if ($res != SUCCESS ) return $res; // Will check if TRIGGERS are installed! Requires SUPER access in database logstream! if ( $myTriggerProperty != null ) { $res = $this->_streamObj->VerifyChecksumTrigger( $myTriggerProperty ); if ($res != SUCCESS ) return $res; } } // return results! return $res; } /** * If the reports needs extra FIELDS, they are created by this function */ public function CreateMissingLogStreamFields( $mySourceID ) { global $content, $fields; $res = SUCCESS; if ( $this->_streamCfgObj == null ) { if ( isset($content['Sources'][$mySourceID]) ) { // Obtain and get the Config Object $this->_streamCfgObj = $content['Sources'][$mySourceID]['ObjRef']; // Return success if logstream is FILE based! if ( $content['Sources'][$mySourceID]['SourceType'] == SOURCE_DISK ) return SUCCESS; } else return ERROR_SOURCENOTFOUND; } if ( $this->_streamObj == null ) { // Create LogStream Object $this->_streamObj = $this->_streamCfgObj->LogStreamFactory($this->_streamCfgObj); } // Check datasource and return result $res = $this->_streamObj->Verify(); if ( $res == SUCCESS ) { // Will add missing fields for this database logstream ! $res = $this->_streamObj->CreateMissingFields( $this->_arrProperties ); if ($res != SUCCESS ) return $res; } // return results! return $res; } /** * If the reports needs INDEXES, they are created by this function */ public function CreateLogStreamIndexesByPropertyArray( $mySourceID, $arrProperties ) { global $content, $fields; $res = SUCCESS; if ( $this->_streamCfgObj == null ) { if ( isset($content['Sources'][$mySourceID]) ) { // Obtain and get the Config Object $this->_streamCfgObj = $content['Sources'][$mySourceID]['ObjRef']; // Return success if logstream is FILE based! if ( $content['Sources'][$mySourceID]['SourceType'] == SOURCE_DISK ) return SUCCESS; } else return ERROR_SOURCENOTFOUND; } if ( $this->_streamObj == null ) { // Create LogStream Object $this->_streamObj = $this->_streamCfgObj->LogStreamFactory($this->_streamCfgObj); } // Check datasource and return result $res = $this->_streamObj->Verify(); if ( $res == SUCCESS ) { // Will check if certain INDEXES do exists for database logstream classes! $res = $this->_streamObj->CreateMissingIndexes( $arrProperties ); if ($res != SUCCESS ) return $res; } // return results! return $res; } /** * If the reports needs INDEXES, these are created by this function */ public function CreateLogStreamTriggerByPropertyArray( $mySourceID, $myTriggerProperty, $myChecksumProperty ) { global $content, $fields; $res = SUCCESS; if ( $this->_streamCfgObj == null ) { if ( isset($content['Sources'][$mySourceID]) ) { // Obtain and get the Config Object $this->_streamCfgObj = $content['Sources'][$mySourceID]['ObjRef']; // Return success if logstream is FILE based! if ( $content['Sources'][$mySourceID]['SourceType'] == SOURCE_DISK ) return SUCCESS; } else return ERROR_SOURCENOTFOUND; } if ( $this->_streamObj == null ) { // Create LogStream Object $this->_streamObj = $this->_streamCfgObj->LogStreamFactory($this->_streamCfgObj); } // Check datasource and return result $res = $this->_streamObj->Verify(); if ( $res == SUCCESS ) { // Will check if certain INDEXES do exists for database logstream classes! $res = $this->_streamObj->CreateMissingTrigger( $myTriggerProperty, $myChecksumProperty ); if ($res != SUCCESS ) return $res; } // return results! return $res; } /** * If the reports needs INDEXES, these are created by this function */ public function ChangeChecksumFieldUnsigned( $mySourceID ) { global $content, $fields; $res = SUCCESS; if ( $this->_streamCfgObj == null ) { if ( isset($content['Sources'][$mySourceID]) ) { // Obtain and get the Config Object $this->_streamCfgObj = $content['Sources'][$mySourceID]['ObjRef']; // Return success if logstream is FILE based! if ( $content['Sources'][$mySourceID]['SourceType'] == SOURCE_DISK ) return SUCCESS; } else return ERROR_SOURCENOTFOUND; } if ( $this->_streamObj == null ) { // Create LogStream Object $this->_streamObj = $this->_streamCfgObj->LogStreamFactory($this->_streamCfgObj); } // Check datasource and return result $res = $this->_streamObj->Verify(); if ( $res == SUCCESS ) { // Will change the Checksum Field to UNSIGNED INT $res = $this->_streamObj->ChangeChecksumFieldUnsigned( ); if ($res != SUCCESS ) return $res; } // return results! return $res; } } ?>loganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary.class.php0000644000175000017500000004216012225176641026665 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes! require_once($gl_root_path . 'classes/reports/report.class.php'); // --- class Report_syslogsummary extends Report { // Common Properties public $_reportVersion = 1; // Internally Version of the ReportEngine public $_reportID = "report.syslog.syslogsummary.class"; // ID for the report, needs to be unique! public $_reportFileBasicName = "report.syslog.syslogsummary"; // Basic Filename for reportfiles public $_reportTitle = "Syslog Summary Report"; // Display name for the report public $_reportDescription = "This is a Syslog Summary Report"; public $_reportHelpArticle = "http://loganalyzer.adiscon.com/plugins/reports/syslog-syslogsummary"; public $_reportNeedsInit = false; // True means that this report needs additional init stuff public $_reportInitialized = false; // True means report is installed // Advanced Report Options private $_maxHosts = 20; // Threshold for maximum hosts to analyse! private $_maxMsgsPerHost = 100; // Threshold for maximum amount of syslogmessages to analyse per host private $_colorThreshold = 10; // Threshold for coloured display of Eventcounter // Constructor public function Report_syslogsummary() { // $this->_logStreamConfigObj = $streamConfigObj; // Fill fields we need for this report $this->_arrProperties[] = SYSLOG_UID; $this->_arrProperties[] = SYSLOG_DATE; $this->_arrProperties[] = SYSLOG_HOST; $this->_arrProperties[] = SYSLOG_MESSAGETYPE; $this->_arrProperties[] = SYSLOG_FACILITY; $this->_arrProperties[] = SYSLOG_SEVERITY; $this->_arrProperties[] = SYSLOG_SYSLOGTAG; // $this->_arrProperties[] = SYSLOG_PROCESSID; $this->_arrProperties[] = SYSLOG_MESSAGE; $this->_arrProperties[] = MISC_CHECKSUM; // Init Customfilters Array $this->_arrCustomFilters['_maxHosts'] = array ( 'InternalID' => '_maxHosts', 'DisplayLangID' => 'ln_report_maxHosts_displayname', 'DescriptLangID'=> 'ln_report_maxHosts_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 20, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); $this->_arrCustomFilters['_maxMsgsPerHost'] = array ( 'InternalID' => '_maxMsgsPerHost', 'DisplayLangID' => 'ln_report_maxMsgsPerHost_displayname', 'DescriptLangID'=> 'ln_report_maxMsgsPerHost_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 100, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); $this->_arrCustomFilters['_colorThreshold'] = array ( 'InternalID' => '_colorThreshold', 'DisplayLangID' => 'ln_report_colorThreshold_displayname', 'DescriptLangID'=> 'ln_report_colorThreshold_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 10, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); } /** * startDataProcessing, analysing data * * @param arrProperties array in: Properties wish list. * @return integer Error stat */ public function startDataProcessing() { global $content, $severity_colors, $gl_starttime, $fields; // Create Filter string, append filter for EventLog Type msgs! $szFilters = $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_Syslog; // Set Filter string $this->_streamObj->SetFilter( $szFilters ); // Need to Open stream first! $res = $this->_streamObj->Open( $this->_arrProperties, true ); if ( $res == SUCCESS ) { // Set to common content variables $this->SetCommonContentVariables(); // Set report specific content variables $content["_colorThreshold"] = $this->_colorThreshold; // --- Report logic starts here $content["report_rendertime"] = ""; // Step 1: Gather Summaries // Obtain data from the logstream! $content["report_summary"] = $this->_streamObj->ConsolidateDataByField( SYSLOG_SEVERITY, 0, SYSLOG_SEVERITY, SORTING_ORDER_DESC, null, false ); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s, "; // If data is valid, we have an array! if ( is_array($content["report_summary"]) && count($content["report_summary"]) > 0 ) { // Count Total Events $iTotalEvents = 0; foreach ($content["report_summary"] as &$tmpReportData ) { $tmpReportData['DisplayName'] = $this->GetSeverityDisplayName( $tmpReportData[SYSLOG_SEVERITY] ); $tmpReportData['bgcolor'] = $this->GetSeverityBGColor( $tmpReportData[SYSLOG_SEVERITY] ); // $severity_colors[ $tmpReportData[SYSLOG_SEVERITY] ]; $iTotalEvents += $tmpReportData['itemcount']; } // Prepent Item with totalevents count $totalItem['DisplayName'] = "Total Events"; $totalItem['bgcolor'] = "#999999"; $totalItem['itemcount'] = $iTotalEvents; // Prepent to array array_unshift( $content["report_summary"], $totalItem ); } else return ERROR_REPORT_NODATA; // Get List of hosts $content["report_computers"] = $this->_streamObj->ConsolidateItemListByField( SYSLOG_HOST, $this->_maxHosts, SYSLOG_HOST, SORTING_ORDER_DESC ); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s, "; if ( is_array($content["report_computers"]) && count($content["report_computers"]) > 0 ) { // Create plain hosts list for Consolidate function foreach ( $content["report_computers"] as $tmpComputer ) $arrHosts[] = $tmpComputer[SYSLOG_HOST]; } else return ERROR_REPORT_NODATA; // This function will consolidate the Events based per Host! $this->ConsolidateSyslogmessagesPerHost($arrHosts); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // --- } else return $ret; // Return success! return SUCCESS; } /** * InitReport, empty * */ public function InitReport() { // Nothing to do return SUCCESS; } /** * RemoveReport, empty * */ public function RemoveReport() { // Nothing to do return SUCCESS; } /** * validateLicense, check license code * */ public function validateLicense() { // This is a free report! return SUCCESS; } /** * Init advanced settings from _customFilters string */ public function InitAdvancedSettings() { // Parse and Split _customFilters if ( strlen($this->_customFilters) > 0 ) { // First of all split by comma $tmpFilterValues = explode( ",", $this->_customFilters ); //Loop through mappings foreach ($tmpFilterValues as &$myFilterValue ) { // Split subvalues $tmpArray = explode( "=>", $myFilterValue ); // Set into temporary array $tmpfilterid = trim($tmpArray[0]); // Set advanced property if ( isset($this->_arrCustomFilters[$tmpfilterid]) ) { // Copy New value first! $szNewVal = trim($tmpArray[1]); // Negated logic if ( $this->_arrCustomFilters[$tmpfilterid][FILTER_TYPE] == FILTER_TYPE_NUMBER && !(isset($this->_arrCustomFilters[$tmpfilterid]['MinValue']) && intval($szNewVal) < $this->_arrCustomFilters[$tmpfilterid]['MinValue']) && !(isset($this->_arrCustomFilters[$tmpfilterid]['MaxValue']) && intval($szNewVal) >= $this->_arrCustomFilters[$tmpfilterid]['MaxValue']) ) { if ( $tmpfilterid == '_maxHosts' ) $this->_maxHosts = intval($szNewVal); else if ( $tmpfilterid == '_maxMsgsPerHost' ) $this->_maxMsgsPerHost = intval($szNewVal); else if ( $tmpfilterid == '_colorThreshold' ) $this->_colorThreshold = intval($szNewVal); } else { // Write to debuglog OutputDebugMessage("Failed setting advanced report option property '" . $tmpfilterid . "', value not in value range!", DEBUG_ERROR); } } } } } /* * Implementation of CheckLogStreamSource */ public function CheckLogStreamSource( $mySourceID ) { // Call basic report Check function $res = $this->CheckLogStreamSourceByPropertyArray( $mySourceID, array(SYSLOG_HOST, MISC_CHECKSUM, SYSLOG_DATE, SYSLOG_SEVERITY, SYSLOG_MESSAGETYPE), SYSLOG_MESSAGE ); // return results! return $res; } /* * Implementation of CreateLogStreamIndexes | Will create missing INDEXES */ public function CreateLogStreamIndexes( $mySourceID ) { // Call basic report Check function $res = $this->CreateLogStreamIndexesByPropertyArray( $mySourceID, array(SYSLOG_HOST, MISC_CHECKSUM, SYSLOG_DATE, SYSLOG_SEVERITY, SYSLOG_MESSAGETYPE) ); // return results! return $res; } /* * Implementation of CreateLogStreamIndexes | Will create missing INDEXES */ public function CreateLogStreamTrigger( $mySourceID ) { // Call basic report Check function $res = $this->CreateLogStreamTriggerByPropertyArray( $mySourceID, SYSLOG_MESSAGE, MISC_CHECKSUM ); // return results! return $res; } // --- Private functions... /** * Helper function to consolidate syslogmessages */ private function ConsolidateSyslogmessagesPerHost( $arrHosts ) { global $content, $gl_starttime, $fields; // Now open the stream for data processing $res = $this->_streamObj->Open( $this->_arrProperties, true ); if ( $res == SUCCESS ) { // --- New Method to consolidate data! // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // Update all Checksums first! $this->_streamObj->UpdateAllMessageChecksum(); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; foreach ( $arrHosts as $myHost ) { // Set custom filters $this->_streamObj->ResetFilters(); $this->_streamObj->SetFilter( $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_Syslog ); $this->_streamObj->RemoveFilters( SYSLOG_HOST ); $this->_streamObj->AppendFilter( $fields[SYSLOG_HOST]['SearchField'] . ":=" . $myHost ); // Set Host Item Basics if not set yet $content["report_consdata"][ $myHost ][SYSLOG_HOST] = $myHost; // Get Data for single host $content["report_consdata"][ $myHost ]['cons_msgs'] = $this->_streamObj->ConsolidateDataByField( MISC_CHECKSUM, $this->_maxMsgsPerHost, MISC_CHECKSUM, SORTING_ORDER_DESC, null, true, true ); // Only process results if valid! if ( is_array($content["report_consdata"][ $myHost ]['cons_msgs']) ) { foreach ( $content["report_consdata"][ $myHost ]['cons_msgs'] as &$myConsData ) { // Set Basic data entries if (!isset( $content['filter_facility_list'][$myConsData[SYSLOG_FACILITY]] )) $myConsData[SYSLOG_FACILITY] = SYSLOG_LOCAL0; // Set default in this case if (!isset( $content['filter_severity_list'][$myConsData[SYSLOG_SEVERITY]] )) $myConsData[SYSLOG_SEVERITY] = SYSLOG_NOTICE; // Set default in this case } } else { // Write to debuglog OutputDebugMessage("Failed consolidating data for '" . $myHost . "' with error " . $content["report_consdata"][ $myHost ]['cons_msgs'], DEBUG_ERROR); // Set to empty array $content["report_consdata"][ $myHost ]['cons_msgs'] = array(); } } // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // --- // --- Start Postprocessing foreach( $content["report_consdata"] as &$tmpConsolidatedComputer ) { // First use callback function to sort array uasort($tmpConsolidatedComputer['cons_msgs'], "MultiSortArrayByItemCountDesc"); // Remove entries according to _maxMsgsPerHost if ( count($tmpConsolidatedComputer['cons_msgs']) > $this->_maxMsgsPerHost ) { $iDropCount = 0; do { array_pop($tmpConsolidatedComputer['cons_msgs']); $iDropCount++; } while ( count($tmpConsolidatedComputer['cons_msgs']) > $this->_maxMsgsPerHost ); // Append a dummy entry which shows count of all other events if ( $iDropCount > 0 ) { $lastEntry[SYSLOG_SEVERITY] = SYSLOG_NOTICE; $lastEntry[SYSLOG_FACILITY] = SYSLOG_LOCAL0; $lastEntry[SYSLOG_SYSLOGTAG] = $content['LN_GEN_ALL_OTHER_EVENTS']; $lastEntry[SYSLOG_MESSAGE] = $content['LN_GEN_ALL_OTHER_EVENTS']; $lastEntry['itemcount'] = $iDropCount; $lastEntry['firstoccurrence_date'] = "-"; $lastEntry['lastoccurrence_date'] = "-"; $tmpConsolidatedComputer['cons_msgs'][] = $lastEntry; } } // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // PostProcess Events! foreach( $tmpConsolidatedComputer["cons_msgs"] as &$tmpMyEvent ) { $tmpMyEvent['FirstOccurrence_Date_Formatted'] = GetFormatedDate( $tmpMyEvent['firstoccurrence_date'] ); $tmpMyEvent['LastOccurrence_Date_Formatted'] = GetFormatedDate( $tmpMyEvent['lastoccurrence_date'] ); $tmpMyEvent['syslogseverity_text'] = $this->GetSeverityDisplayName($tmpMyEvent['syslogseverity']); //$content['filter_severity_list'][ $tmpMyEvent['syslogseverity'] ]["DisplayName"]; $tmpMyEvent['syslogfacility_text'] = $this->GetFacilityDisplayName($tmpMyEvent['syslogfacility']); //$content['filter_facility_list'][ $tmpMyEvent['syslogfacility'] ]["DisplayName"]; $tmpMyEvent['syslogseverity_bgcolor'] = $this->GetSeverityBGColor($tmpMyEvent['syslogseverity']); $tmpMyEvent['syslogfacility_bgcolor'] = $this->GetSeverityBGColor($tmpMyEvent['syslogfacility']); } } // --- } // Work done! return SUCCESS; } /* * Helper function to convert a facility string into a facility number */ private function GetFacilityDisplayName($nFacility) { global $content; if ( isset($nFacility) && is_numeric($nFacility) ) { foreach ( $content['filter_facility_list'] as $myfacility ) { // check if valid! if ( $myfacility['ID'] == $nFacility ) return $myfacility['DisplayName']; } } // If we reach this point, facility is not valid return $content['LN_GEN_UNKNOWN']; } /* * Helper function to convert a severity string into a severity number */ private function GetSeverityDisplayName($nSeverity) { global $content; if ( isset($nSeverity) && is_numeric($nSeverity) ) { foreach ( $content['filter_severity_list'] as $myseverity ) { // check if valid! if ( $myseverity['ID'] == $nSeverity ) return $myseverity['DisplayName']; } } // If we reach this point, severity is not valid return $content['LN_GEN_UNKNOWN']; } /* * Helper function to obtain Severity background color */ private function GetSeverityBGColor( $nSeverity ) { global $severity_colors; if ( isset( $severity_colors[$nSeverity] ) ) return $severity_colors[$nSeverity]; else return $severity_colors[SYSLOG_INFO]; //Default } /* * Helper function to obtain Severity background color */ private function GetFacilityBGColor( $nFacility ) { global $facility_colors; if ( isset( $facility_colors[$nFacility] ) ) return $facility_colors[$nFacility]; else return $facility_colors[SYSLOG_LOCAL0]; //Default } //--- } ?>loganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff.class.php0000644000175000017500000003721612225176641026553 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes! require_once($gl_root_path . 'classes/reports/report.class.php'); // --- class Report_logonlogoff extends Report { // Common Properties public $_reportVersion = 1; // Internally Version of the ReportEngine public $_reportID = "report.eventlog.logonlogoff.class"; // ID for the report, needs to be unique! public $_reportFileBasicName = "report.eventlog.logonlogoff"; // Basic Filename for reportfiles public $_reportTitle = "EventLog Logon/Logoff Report"; // Display name for the report public $_reportDescription = "This is a EventLog Logon/Logoff Summary Report"; public $_reportHelpArticle = "http://loganalyzer.adiscon.com/plugins/reports/eventlog-logonlogoff"; public $_reportNeedsInit = false; // True means that this report needs additional init stuff public $_reportInitialized = false; // True means report is installed // Advanced Report Options private $_maxHosts = 20; // Threshold for maximum hosts to analyse! private $_maxLogOnLogOffsPerHost = 100; // Threshold for maximum amount of logon/logoffs to analyse per host private $_colorThreshold = 10; // Threshold for coloured display of Eventcounter // Constructor public function Report_logonlogoff() { // $this->_logStreamConfigObj = $streamConfigObj; // Fill fields we need for this report $this->_arrProperties[] = SYSLOG_UID; $this->_arrProperties[] = SYSLOG_DATE; $this->_arrProperties[] = SYSLOG_HOST; $this->_arrProperties[] = SYSLOG_MESSAGETYPE; $this->_arrProperties[] = SYSLOG_SEVERITY; $this->_arrProperties[] = SYSLOG_EVENT_ID; $this->_arrProperties[] = SYSLOG_EVENT_SOURCE; $this->_arrProperties[] = SYSLOG_EVENT_USER; // $this->_arrProperties[] = SYSLOG_MESSAGE; $this->_arrProperties[] = MISC_CHECKSUM; // Init Customfilters Array $this->_arrCustomFilters['_maxHosts'] = array ( 'InternalID' => '_maxHosts', 'DisplayLangID' => 'ln_report_maxHosts_displayname', 'DescriptLangID'=> 'ln_report_maxHosts_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 20, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); $this->_arrCustomFilters['_maxLogOnLogOffsPerHost'] = array ( 'InternalID' => '_maxLogOnLogOffsPerHost', 'DisplayLangID' => 'ln_report_maxLogOnLogOffsPerHost_displayname', 'DescriptLangID'=> 'ln_report_maxLogOnLogOffsPerHost_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 100, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); $this->_arrCustomFilters['_colorThreshold'] = array ( 'InternalID' => '_colorThreshold', 'DisplayLangID' => 'ln_report_colorThreshold_displayname', 'DescriptLangID'=> 'ln_report_colorThreshold_description', FILTER_TYPE => FILTER_TYPE_NUMBER, 'DefaultValue' => 10, 'MinValue' => 1, /* 'MaxValue' => 0,*/ ); } /** * startDataProcessing, analysing data * * @param arrProperties array in: Properties wish list. * @return integer Error stat */ public function startDataProcessing() { global $content, $severity_colors, $gl_starttime, $fields; // Create Filter string, append filter for EventLog Type msgs! $szFilters = $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_NT_EventReport . ",=" . IUT_WEVTMONV2 . " "; /* Include EventLog v1 and v2 */ // Set Filter string $this->_streamObj->SetFilter( $szFilters ); // Need to Open stream first! $res = $this->_streamObj->Open( $this->_arrProperties, true ); if ( $res == SUCCESS ) { // Set to common content variables $this->SetCommonContentVariables(); // Set report specific content variables $content["_colorThreshold"] = $this->_colorThreshold; // --- Report logic starts here $content["report_rendertime"] = ""; // Step 1: Gather Summaries // Obtain data from the logstream! $content["report_summary"] = $this->_streamObj->ConsolidateDataByField( SYSLOG_HOST, 0, SYSLOG_HOST, SORTING_ORDER_DESC, null, false ); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s, "; // If data is valid, we have an array! if ( is_array($content["report_summary"]) && count($content["report_summary"]) > 0 ) { // Count Total Events $iTotalEvents = 0; foreach ($content["report_summary"] as &$tmpReportData ) { $tmpReportData['DisplayName'] = $tmpReportData[SYSLOG_HOST]; $tmpReportData['bgcolor'] = "#BBBBBB"; // $severity_colors[ $tmpReportData[SYSLOG_SEVERITY] ]; $iTotalEvents += $tmpReportData['itemcount']; } // Prepent Item with totalevents count $totalItem['DisplayName'] = "Total Events"; $totalItem['bgcolor'] = "#999999"; $totalItem['itemcount'] = $iTotalEvents; // Prepent to array array_unshift( $content["report_summary"], $totalItem ); } else return ERROR_REPORT_NODATA; // This function will consolidate the Events based per Host! $this->ConsolidateLogonLogoffs(); // ($arrHosts); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // --- } else return $ret; // Return success! return SUCCESS; } /** * InitReport, empty * */ public function InitReport() { // Nothing to do return SUCCESS; } /** * RemoveReport, empty * */ public function RemoveReport() { // Nothing to do return SUCCESS; } /** * validateLicense, check license code * */ public function validateLicense() { // This is a free report! return SUCCESS; } /** * Init advanced settings from _customFilters string */ public function InitAdvancedSettings() { // Parse and Split _customFilters if ( strlen($this->_customFilters) > 0 ) { // First of all split by comma $tmpFilterValues = explode( ",", $this->_customFilters ); //Loop through mappings foreach ($tmpFilterValues as &$myFilterValue ) { // Split subvalues $tmpArray = explode( "=>", $myFilterValue ); // Set into temporary array $tmpfilterid = trim($tmpArray[0]); // Set advanced property if ( isset($this->_arrCustomFilters[$tmpfilterid]) ) { // Copy New value first! $szNewVal = trim($tmpArray[1]); // Negated logic if ( $this->_arrCustomFilters[$tmpfilterid][FILTER_TYPE] == FILTER_TYPE_NUMBER && !(isset($this->_arrCustomFilters[$tmpfilterid]['MinValue']) && intval($szNewVal) < $this->_arrCustomFilters[$tmpfilterid]['MinValue']) && !(isset($this->_arrCustomFilters[$tmpfilterid]['MaxValue']) && intval($szNewVal) >= $this->_arrCustomFilters[$tmpfilterid]['MaxValue']) ) { if ( $tmpfilterid == '_maxHosts' ) $this->_maxHosts = intval($szNewVal); else if ( $tmpfilterid == '_maxLogOnLogOffsPerHost' ) $this->_maxLogOnLogOffsPerHost = intval($szNewVal); else if ( $tmpfilterid == '_colorThreshold' ) $this->_colorThreshold = intval($szNewVal); } else { // Write to debuglog OutputDebugMessage("Failed setting advanced report option property '" . $tmpfilterid . "', value not in value range!", DEBUG_ERROR); } } } } } /* * Implementation of CheckLogStreamSource */ public function CheckLogStreamSource( $mySourceID ) { // Call basic report Check function $res = $this->CheckLogStreamSourceByPropertyArray( $mySourceID, array(SYSLOG_HOST, MISC_CHECKSUM, SYSLOG_DATE, SYSLOG_EVENT_ID, SYSLOG_MESSAGETYPE), null ); // return results! return $res; } /* * Implementation of CreateLogStreamIndexes | Will create missing INDEXES */ public function CreateLogStreamIndexes( $mySourceID ) { // Call basic report Check function $res = $this->CreateLogStreamIndexesByPropertyArray( $mySourceID, array(SYSLOG_HOST, MISC_CHECKSUM, SYSLOG_DATE, SYSLOG_EVENT_ID, SYSLOG_MESSAGETYPE) ); // return results! return $res; } /* * Implementation of CreateLogStreamIndexes | Will create missing TRIGGER */ public function CreateLogStreamTrigger( $mySourceID ) { // Dummy return SUCCESS! return SUCCESS; } // --- Private functions... /** * Helper function to consolidate events */ private function ConsolidateLogonLogoffs() // ( $arrHosts ) { global $content, $gl_starttime, $fields; // Now open the stream for data processing $res = $this->_streamObj->Open( $this->_arrProperties, true ); if ( $res == SUCCESS ) { // --- New Method to consolidate data! // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // Update all Checksums first! //not needed $this->_streamObj->UpdateAllMessageChecksum(); // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // Get all LOGON Data // Set custom filters $this->_streamObj->ResetFilters(); $this->_streamObj->SetFilter( $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_NT_EventReport . ",=" . IUT_WEVTMONV2 . " " . $fields[SYSLOG_EVENT_ID]['SearchField'] . ":=528,4624" ); /* Include EventIDs for new and old Eventlog API*/ $content["report_consdata"]['logon']['cons_events'] = $this->_streamObj->ConsolidateDataByField( SYSLOG_EVENT_USER, $this->_maxLogOnLogOffsPerHost, SYSLOG_EVENT_USER, SORTING_ORDER_DESC, null, true, true ); foreach ( $content["report_consdata"]['logon']['cons_events'] as &$myConsData ) { // Set Basic data entries if (!isset( $content['filter_severity_list'][$myConsData[SYSLOG_SEVERITY]] )) $myConsData[SYSLOG_SEVERITY] = SYSLOG_NOTICE; // Set default in this case } // Set Basic properties $content["report_consdata"]['logon']['DataCaption'] = "Logon Events"; // Get all LOGOFF Data // Set custom filters $this->_streamObj->ResetFilters(); $this->_streamObj->SetFilter( $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_NT_EventReport . ",=" . IUT_WEVTMONV2 . " " . $fields[SYSLOG_EVENT_ID]['SearchField'] . ":=538,4634" ); /* Include EventIDs for new and old Eventlog API*/ $content["report_consdata"]['logoff']['cons_events'] = $this->_streamObj->ConsolidateDataByField( SYSLOG_EVENT_USER, $this->_maxLogOnLogOffsPerHost, SYSLOG_EVENT_USER, SORTING_ORDER_DESC, null, true, true ); foreach ( $content["report_consdata"]['logoff']['cons_events'] as &$myConsData ) { // Set Basic data entries if (!isset( $content['filter_severity_list'][$myConsData[SYSLOG_SEVERITY]] )) $myConsData[SYSLOG_SEVERITY] = SYSLOG_NOTICE; // Set default in this case } // Set Basic properties $content["report_consdata"]['logoff']['DataCaption'] = "Logoff Events"; /* foreach ( $arrHosts as $myHost ) { // Set custom filters $this->_streamObj->ResetFilters(); $this->_streamObj->SetFilter( $this->_filterString . " " . $fields[SYSLOG_MESSAGETYPE]['SearchField'] . ":=" . IUT_NT_EventReport . ",=" . IUT_WEVTMONV2 . " " . $fields[SYSLOG_HOST]['SearchField'] . ":=" . $myHost ); // Set Host Item Basics if not set yet $content["report_consdata"][ $myHost ][SYSLOG_HOST] = $myHost; // Get Data for single host $content["report_consdata"][ $myHost ]['cons_events'] = $this->_streamObj->ConsolidateDataByField( SYSLOG_EVENT_ID, $this->_maxLogOnLogOffsPerHost, SYSLOG_EVENT_USER, SORTING_ORDER_DESC, null, true, true ); //print_r ($fields[SYSLOG_MESSAGE]); foreach ( $content["report_consdata"][ $myHost ]['cons_events'] as &$myConsData ) { // Set Basic data entries if (!isset( $content['filter_severity_list'][$myConsData[SYSLOG_SEVERITY]] )) $myConsData[SYSLOG_SEVERITY] = SYSLOG_NOTICE; // Set default in this case } } */ // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // --- // Start Postprocessing foreach( $content["report_consdata"] as &$tmpConsolidatedData ) { // First use callback function to sort array uasort($tmpConsolidatedData['cons_events'], "MultiSortArrayByItemCountDesc"); /* // Remove entries according to _maxLogOnLogOffsPerHost if ( count($tmpConsolidatedComputer['cons_events']) > $this->_maxLogOnLogOffsPerHost ) { $iDropCount = 0; do { array_pop($tmpConsolidatedComputer['cons_events']); $iDropCount++; } while ( count($tmpConsolidatedComputer['cons_events']) > $this->_maxLogOnLogOffsPerHost ); // Append a dummy entry which shows count of all other events if ( $iDropCount > 0 ) { $lastEntry[SYSLOG_SEVERITY] = SYSLOG_NOTICE; $lastEntry[SYSLOG_EVENT_ID] = "-"; $lastEntry[SYSLOG_EVENT_SOURCE] = $content['LN_GEN_ALL_OTHER_EVENTS']; $lastEntry[SYSLOG_MESSAGE] = $content['LN_GEN_ALL_OTHER_EVENTS']; $lastEntry['itemcount'] = $iDropCount; $lastEntry['FirstEvent_Date'] = "-"; $lastEntry['LastEvent_Date'] = "-"; $tmpConsolidatedComputer['cons_events'][] = $lastEntry; } } */ // TimeStats $nowtime = microtime_float(); $content["report_rendertime"] .= number_format($nowtime - $gl_starttime, 2, '.', '') . "s "; // PostProcess Events! foreach( $tmpConsolidatedData["cons_events"] as &$tmpMyEvent ) { $tmpMyEvent['FirstEvent_Date_Formatted'] = GetFormatedDate( $tmpMyEvent['firstoccurrence_date'] ); $tmpMyEvent['LastEvent_Date_Formatted'] = GetFormatedDate( $tmpMyEvent['lastoccurrence_date'] ); $tmpMyEvent['syslogseverity_text'] = $content['filter_severity_list'][ $tmpMyEvent['syslogseverity'] ]["DisplayName"]; $tmpMyEvent['syslogseverity_bgcolor'] = $this->GetSeverityBGColor($tmpMyEvent['syslogseverity']); } } // --- } // Work done! return SUCCESS; } /* * Helper function to obtain Severity background color */ private function GetSeverityBGColor( $nSeverity ) { global $severity_colors; if ( isset( $severity_colors[$nSeverity] ) ) return $severity_colors[$nSeverity]; else return $severity_colors[SYSLOG_INFO]; //Default } } ?>loganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary/0000755000175000017500000000000012225176641025045 5ustar danieldaniel././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary/report.syslog.syslogsummary.template.pdfloganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary/report.syslog.syslogsummary.templa0000644000175000017500000001147312225176641034046 0ustar danieldaniel {report_title}

    {report_title}

    {LN_REPORT_GENERATEDTIME} {report_gentime}

    {report_comment}


    {LN_REPORT_FILTERS}
    {FilterType} {FilterDisplay}

    {ln_report_summary}

    {ln_report_event_summary}
    {DisplayName} {itemcount}

    {ln_report_computer_summary}
    {FROMHOST}({itemcount}),

    {ln_report_consolidation}

    {FROMHOST}

    {ln_report_number} {ln_report_count} {ln_report_firstoccurrence} {ln_report_lastoccurrence} {ln_report_severity} {ln_report_facility} {ln_report_syslogtag}
    {ZAEHLER} {itemcount} {itemcount} {FirstOccurrence_Date_Formatted} {LastOccurrence_Date_Formatted} {syslogseverity_text} {syslogfacility_text} {syslogtag}
    {ln_report_description} {msg:wordwrap:32}


    Made by Adiscon GmbH (2009-2011)  Report Version {report_version} Partners: Rsyslog |  WinSyslog
    {LN_REPORT_FOOTER_ENDERED}: {report_rendertime}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}
    ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary/report.syslog.syslogsummary.lang.en.phploganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary/report.syslog.syslogsummary.lang.e0000644000175000017500000000512012225176641033720 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ global $content; // Global Stuff $content['ln_report_event_summary'] = "Syslog Summary"; $content['ln_report_computer_summary'] = "Computer Summary"; $content['ln_report_consolidation'] = "Syslogmessages consolidated per Host"; $content['ln_report_summary'] = "Report Summary"; $content['ln_report_number'] = "No."; $content['ln_report_firstoccurrence'] = "First Occurrence"; $content['ln_report_lastoccurrence'] = "Last Occurrence"; $content['ln_report_process'] = "Process"; $content['ln_report_facility'] = "Facility"; $content['ln_report_severity'] = "Severity"; $content['ln_report_syslogtag'] = "Syslogtag"; $content['ln_report_description'] = "Description"; $content['ln_report_count'] = "Count"; $content['ln_report_maxHosts_displayname'] = "Max hosts"; $content['ln_report_maxHosts_description'] = "The maximum number of hosts which will be displayed."; $content['ln_report_maxMsgsPerHost_displayname'] = "Max Syslogmessages per host"; $content['ln_report_maxMsgsPerHost_description'] = "The maximum number of syslogmessages displayed per host."; $content['ln_report_colorThreshold_displayname'] = "Counter Threshold"; $content['ln_report_colorThreshold_description'] = "If the amount of consolidated events is higher then this threshold, the countfield will be marked red."; $content['ln_report_unknown_facility'] = "Unknown Facility"; $content['ln_report_unknown_severity'] = "Unknown Severity"; $content['ln_report_'] = ""; $content['ln_report_'] = ""; $content['ln_report_'] = ""; $content['ln_report_'] = ""; $content['ln_report_'] = ""; ?>././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary/report.syslog.syslogsummary.template.htmlloganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary/report.syslog.syslogsummary.templa0000644000175000017500000001436112225176641034045 0ustar danieldaniel {report_title}
    {report_title}
    {LN_REPORT_GENERATEDTIME} {report_gentime}
    {report_comment}
    {LN_REPORT_FILTERS}
    {FilterType} {FilterDisplay}


    {ln_report_summary}
    {ln_report_event_summary}
    {DisplayName} {itemcount}
    {ln_report_computer_summary}
    {FROMHOST}({itemcount}),


    {ln_report_consolidation}

    {FROMHOST}

    {ln_report_number} {ln_report_count} {ln_report_firstoccurrence} {ln_report_lastoccurrence} {ln_report_severity} {ln_report_facility} {ln_report_syslogtag} {ln_report_description}
    {ZAEHLER} {itemcount} {itemcount} {FirstOccurrence_Date_Formatted} {LastOccurrence_Date_Formatted} {syslogseverity_text} {syslogfacility_text} {syslogtag} {msg}
    Made by Adiscon GmbH (2009-2011)  Report Version {report_version}  Partners:  Rsyslog |  WinSyslog {LN_REPORT_FOOTER_ENDERED}: {report_rendertime}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}
    {LN_DEBUGLEVEL} {LN_DEBUGMESSAGE}
    {DBGLEVELTXT}
    {DBGMSG}
    loganalyzer-3.6.5/src/classes/reports/report.syslog.syslogsummary/report.syslog.syslogsummary.css0000644000175000017500000002410712225176641033352 0ustar danieldaniel/* Generell Tag Classes */ BODY { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; color: #000000; background-color: #f9f9f9; scrollbar-face-color: #DEE3E7; scrollbar-highlight-color: #FFFFFF; scrollbar-shadow-color: #DEE3E7; scrollbar-3dlight-color: #D1D7DC; scrollbar-arrow-color: #006699; scrollbar-track-color: #EFEFEF; scrollbar-darkshadow-color: #98AAB1; } TD { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #000000 } /* Default Link Classes */ a:link,a:active,a:visited,a.postlink { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-decoration:none; background-color: transparent; color:#38140E; } a:hover { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; color:#CC0000; } /*---*/ /* Context Link Classes */ a.contextlink:link,a.contextlink:active,a.contextlink:visited,a.contextlink { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; background-color: transparent; color:#3814BB; text-decoration:underline; } a.contextlink:hover { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight:bold; color:#3844FF; text-decoration:none; } /*---*/ img { border: 0px; } /* Title Classes */ .title { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight:bold; background-color: #C6B097; color: #032D5D; border: 1px solid; border-color: #ACBED6 #3B679B #3B679B #ACBED6; height: 20px; text-align:center; vertical-align:middle; } A.title, A.title:active, A.title:visited { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight:bold; COLOR: #ED9D10; TEXT-DECORATION: none; } A.title:hover { COLOR: #982D00; TEXT-DECORATION: none; } .titleSecond { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #E3D2AE; background-image: url(images/bg_4.png); background-repeat: repeat-x; color: #1A3745; height: 18px; text-align:center; vertical-align:middle; } /* Default Font Classes */ font { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; } /* Table / Border Classes */ .table_with_border { background-color:#EEF2F6; border:1px solid; border-color: #CCCCCC #000000 #000000 #CCCCCC; } .table_with_border_second { background-color:#D5E0E7; border:1px solid; border-color: #CCCCCC #000000 #000000 #CCCCCC; } .table_with_border_light { background-color:#CCCCCC; border:1px #AAAAAA solid; } .with_border { text-indent:3px; background-color:#CCCCCC; border:1px #AAAAAA solid; } .with_border_alternate { text-indent:3px; background-color:#CCCCCC; border:1px #AAAAAA ridge; } .mainheader { border:1px solid; background-color:#C7CBD1; border-color: #44617D #203040 #203040 #44617D; } .mainfooter { height: 20px; background-color:#DDDDDD; border-top: #97A8B9 1px solid; border-bottom: #6592BD 1px solid; } .imageborder { border:1px solid; border-color: #44617D #203040 #203040 #44617D; } /* Cells for listening */ .line0 { font-size: 7pt; color: #000000; background-color: #DDDDDD; } .line0:hover { background-color:#F9F9F9; } .line1 { font-size: 7pt; color: #000000; background-color: #EEEEEE; } .line1:hover { background-color:#F9F9F9; } .line2 { font-size: 7pt; color: #000000; background-color: #F5F5F5; } .line2:hover { background-color:#F9F9F9; } .tableBackground { font-size: 10px; color: #000000; background-color: #F5F5F5; } .lineColouredWhite, .lineColouredWhite:hover, a.lineColouredWhite { font-size: 10px; color: #FFFFFF; } .lineColouredBlack, .lineColouredBlack:hover, a.lineColouredBlack { font-size: 10px; color: #000000; } /* TOP Menu Classes */ .topmenu1begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #4E6485; } .topmenu1 { height: 16px; border:1px ridge; border-color: #79AABE #09506C #79AABE #79AABE; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #4E6485; } .topmenu1:hover { color: #FFFF99; border:1px inset; border-color: #79AABE #09506C #79AABE #79AABE; background-color: #6A88B8; text-decoration: none; } .topmenuend { height: 16px; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #4E6485; } .topmenuextra { height: 16px; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #B8D4E0; } .topmenu2begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #7A92A6; } .topmenu2 { height: 16px; border:1px ridge; border-color: #BDEEFF #79AABE #09506C #09506C; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #7A92A6; } .topmenu2:hover { color: #FFFF99; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; background-color: #6A88B8; text-decoration: none; } .topmenu2_link, A.topmenu2_link { color: #FFDD22; } .topmenu2_link:hover, A.topmenu2_link:hover { color: #FFFF99; text-decoration: none; } .topmenu2end { height: 16px; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #7A92A6; } .topmenu3begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #D4DAE3; } .topmenu3 { height: 16px; border:1px ridge; border-color: #BDEEFF #79AABE #09506C #09506C; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Arial, Verdana, Helvetica, sans-serif; color: #FFFFFF; background-color: #D4DAE3; } .topmenu3:hover { color: #FFFF99; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; background-color: #ACCBFD; text-decoration: none; } .topmenu3end { height: 16px; font: 10px Arial, Verdana, Helvetica, sans-serif; color: #FFFFFF; background-color: #D4DAE3; } .topmenu1_link, a.topmenu1_link, a.topmenu1_link:visited, .topmenu2_link, a.topmenu2_link, a.topmenu2_link:visited, .topmenu3_link, a.topmenu3_link, a.topmenu3_link:visited { vertical-align: middle; height: 16px; color: #FFDD22; font-weight:bold; text-decoration: none; } .topmenu1_link:hover, .topmenu2_link:hover, .topmenu3_link:hover { vertical-align: middle; color: #FFFF99; font-weight:bold; text-decoration: none; } /* Cell Columns */ .cellmenu1 { border:1px ridge; border-color: #79AABE #09506C #09506C #79AABE; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #2E79A0; color: #FFFFFF; } .cellmenu1_naked { border:1px ridge; border-color: #79AABE #09506C #09506C #79AABE; background-color: #2E79A0; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; color: #FFFFFF; } .cellmenu1:hover .cellmenu1_naked:hover { color: #FFFF99; text-decoration: none; } A.cellmenu1_link { color: #FFFF55; text-decoration: underline; } A.cellmenu1_link:hover { color: #FFBB55; text-decoration: none; } .cellmenu2 { border:1px inset; border-color: #79AABE #09506C #09506C #79AABE; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #9FDAF1; color: #393327; } .cellmenu2_naked { text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; color: #393327; border:1px inset; border-color: #79AABE #09506C #09506C #79AABE; background-color: #9FDAF1; } .cellmenu2:hover, .cellmenu2_naked:hover { color: #A31D32; text-decoration: none; } /* Usefull Text Classes */ .ErrorMsg { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; COLOR: #FF0000; } .PriorityEmergency { color: #FFFFFF; background-color: #ff4444; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityAlert { color: #FFFFFF; background-color: #dd00dd; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityCrit { color: #FFFFFF; background-color: #dd9900; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityError { color: #FFFFFF; background-color: #CC0000; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityWarning { color: #FFFFFF; background-color: #FFAA00; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityNotice { color: #FFFFFF; background-color: #66CC33; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityInfo { color: #000000; background-color: #ABF1FF; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityDebug { color: #FFFFFF; background-color: #3333ff; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } /* Form elements */ select, input, button, textarea { background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .SearchFormControl { height: 20px; margin: 2px; background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .SearchFormTextbox { height: 20px; margin: 2px; background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .highlighted { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; color: #BB0000 } loganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff/0000755000175000017500000000000012225176641024725 5ustar danieldaniel././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff/report.eventlog.logonlogoff.template.pdfloganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff/report.eventlog.logonlogoff.templa0000644000175000017500000000772512225176641033613 0ustar danieldaniel {report_title}

    {report_title}

    {LN_REPORT_GENERATEDTIME} {report_gentime}

    {report_comment}


    {LN_REPORT_FILTERS}
    {FilterType} {FilterDisplay}

    {ln_report_summary}

    {ln_report_logonoff_summary}
    {DisplayName} {itemcount}

    {ln_report_consolidation}

    {DataCaption}

    {ln_report_number} {ln_report_count} {ln_report_firstevent} {ln_report_lastevent} {ln_report_user} {ln_report_severity} {ln_report_host}
    {ZAEHLER} {itemcount} {itemcount} {FirstEvent_Date_Formatted} {LastEvent_Date_Formatted} {user} {syslogseverity_text} {FROMHOST}


    Made by Adiscon GmbH (2009-2011)  Report Version {report_version} Partners: Rsyslog |  WinSyslog
    {LN_REPORT_FOOTER_ENDERED}: {report_rendertime}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}
    loganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff/report.eventlog.logonlogoff.css0000644000175000017500000002410712225176641033112 0ustar danieldaniel/* Generell Tag Classes */ BODY { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; color: #000000; background-color: #f9f9f9; scrollbar-face-color: #DEE3E7; scrollbar-highlight-color: #FFFFFF; scrollbar-shadow-color: #DEE3E7; scrollbar-3dlight-color: #D1D7DC; scrollbar-arrow-color: #006699; scrollbar-track-color: #EFEFEF; scrollbar-darkshadow-color: #98AAB1; } TD { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #000000 } /* Default Link Classes */ a:link,a:active,a:visited,a.postlink { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-decoration:none; background-color: transparent; color:#38140E; } a:hover { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; color:#CC0000; } /*---*/ /* Context Link Classes */ a.contextlink:link,a.contextlink:active,a.contextlink:visited,a.contextlink { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight: bold; background-color: transparent; color:#3814BB; text-decoration:underline; } a.contextlink:hover { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-weight:bold; color:#3844FF; text-decoration:none; } /*---*/ img { border: 0px; } /* Title Classes */ .title { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight:bold; background-color: #C6B097; color: #032D5D; border: 1px solid; border-color: #ACBED6 #3B679B #3B679B #ACBED6; height: 20px; text-align:center; vertical-align:middle; } A.title, A.title:active, A.title:visited { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight:bold; COLOR: #ED9D10; TEXT-DECORATION: none; } A.title:hover { COLOR: #982D00; TEXT-DECORATION: none; } .titleSecond { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #E3D2AE; background-image: url(images/bg_4.png); background-repeat: repeat-x; color: #1A3745; height: 18px; text-align:center; vertical-align:middle; } /* Default Font Classes */ font { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; } /* Table / Border Classes */ .table_with_border { background-color:#EEF2F6; border:1px solid; border-color: #CCCCCC #000000 #000000 #CCCCCC; } .table_with_border_second { background-color:#D5E0E7; border:1px solid; border-color: #CCCCCC #000000 #000000 #CCCCCC; } .table_with_border_light { background-color:#CCCCCC; border:1px #AAAAAA solid; } .with_border { text-indent:3px; background-color:#CCCCCC; border:1px #AAAAAA solid; } .with_border_alternate { text-indent:3px; background-color:#CCCCCC; border:1px #AAAAAA ridge; } .mainheader { border:1px solid; background-color:#C7CBD1; border-color: #44617D #203040 #203040 #44617D; } .mainfooter { height: 20px; background-color:#DDDDDD; border-top: #97A8B9 1px solid; border-bottom: #6592BD 1px solid; } .imageborder { border:1px solid; border-color: #44617D #203040 #203040 #44617D; } /* Cells for listening */ .line0 { font-size: 7pt; color: #000000; background-color: #DDDDDD; } .line0:hover { background-color:#F9F9F9; } .line1 { font-size: 7pt; color: #000000; background-color: #EEEEEE; } .line1:hover { background-color:#F9F9F9; } .line2 { font-size: 7pt; color: #000000; background-color: #F5F5F5; } .line2:hover { background-color:#F9F9F9; } .tableBackground { font-size: 10px; color: #000000; background-color: #F5F5F5; } .lineColouredWhite, .lineColouredWhite:hover, a.lineColouredWhite { font-size: 10px; color: #FFFFFF; } .lineColouredBlack, .lineColouredBlack:hover, a.lineColouredBlack { font-size: 10px; color: #000000; } /* TOP Menu Classes */ .topmenu1begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #4E6485; } .topmenu1 { height: 16px; border:1px ridge; border-color: #79AABE #09506C #79AABE #79AABE; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #4E6485; } .topmenu1:hover { color: #FFFF99; border:1px inset; border-color: #79AABE #09506C #79AABE #79AABE; background-color: #6A88B8; text-decoration: none; } .topmenuend { height: 16px; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #4E6485; } .topmenuextra { height: 16px; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #B8D4E0; } .topmenu2begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #7A92A6; } .topmenu2 { height: 16px; border:1px ridge; border-color: #BDEEFF #79AABE #09506C #09506C; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #7A92A6; } .topmenu2:hover { color: #FFFF99; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; background-color: #6A88B8; text-decoration: none; } .topmenu2_link, A.topmenu2_link { color: #FFDD22; } .topmenu2_link:hover, A.topmenu2_link:hover { color: #FFFF99; text-decoration: none; } .topmenu2end { height: 16px; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; font: 10px Verdana, Arial, Helvetica, sans-serif; color: #FFFFFF; background-color: #7A92A6; } .topmenu3begin { height: 16px; border:0px; padding: 2px 2px 0px 2px; vertical-align: middle; background-color: #D4DAE3; } .topmenu3 { height: 16px; border:1px ridge; border-color: #BDEEFF #79AABE #09506C #09506C; padding: 2px 2px 0px 2px; vertical-align: middle; font: 10px Arial, Verdana, Helvetica, sans-serif; color: #FFFFFF; background-color: #D4DAE3; } .topmenu3:hover { color: #FFFF99; border:1px inset; border-color: #BDEEFF #79AABE #09506C #09506C; background-color: #ACCBFD; text-decoration: none; } .topmenu3end { height: 16px; font: 10px Arial, Verdana, Helvetica, sans-serif; color: #FFFFFF; background-color: #D4DAE3; } .topmenu1_link, a.topmenu1_link, a.topmenu1_link:visited, .topmenu2_link, a.topmenu2_link, a.topmenu2_link:visited, .topmenu3_link, a.topmenu3_link, a.topmenu3_link:visited { vertical-align: middle; height: 16px; color: #FFDD22; font-weight:bold; text-decoration: none; } .topmenu1_link:hover, .topmenu2_link:hover, .topmenu3_link:hover { vertical-align: middle; color: #FFFF99; font-weight:bold; text-decoration: none; } /* Cell Columns */ .cellmenu1 { border:1px ridge; border-color: #79AABE #09506C #09506C #79AABE; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #2E79A0; color: #FFFFFF; } .cellmenu1_naked { border:1px ridge; border-color: #79AABE #09506C #09506C #79AABE; background-color: #2E79A0; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; color: #FFFFFF; } .cellmenu1:hover .cellmenu1_naked:hover { color: #FFFF99; text-decoration: none; } A.cellmenu1_link { color: #FFFF55; text-decoration: underline; } A.cellmenu1_link:hover { color: #FFBB55; text-decoration: none; } .cellmenu2 { border:1px inset; border-color: #79AABE #09506C #09506C #79AABE; text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; background-color: #9FDAF1; color: #393327; } .cellmenu2_naked { text-indent:0px; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight:bold; color: #393327; border:1px inset; border-color: #79AABE #09506C #09506C #79AABE; background-color: #9FDAF1; } .cellmenu2:hover, .cellmenu2_naked:hover { color: #A31D32; text-decoration: none; } /* Usefull Text Classes */ .ErrorMsg { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; COLOR: #FF0000; } .PriorityEmergency { color: #FFFFFF; background-color: #ff4444; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityAlert { color: #FFFFFF; background-color: #dd00dd; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityCrit { color: #FFFFFF; background-color: #dd9900; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityError { color: #FFFFFF; background-color: #CC0000; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityWarning { color: #FFFFFF; background-color: #FFAA00; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityNotice { color: #FFFFFF; background-color: #66CC33; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityInfo { color: #000000; background-color: #ABF1FF; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } .PriorityDebug { color: #FFFFFF; background-color: #3333ff; border-top: black 1px solid; border-bottom: black 1px solid; border-right: gray 1px solid; } /* Form elements */ select, input, button, textarea { background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .SearchFormControl { height: 20px; margin: 2px; background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .SearchFormTextbox { height: 20px; margin: 2px; background-color: #E8E7E2; color:#000000; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; border: 1px solid; border-color: #233B51 #124A7C #124A7C #233B51; } .highlighted { font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; color: #BB0000 } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff/report.eventlog.logonlogoff.template.htmlloganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff/report.eventlog.logonlogoff.templa0000644000175000017500000001137212225176641033604 0ustar danieldaniel {report_title}
    {report_title}
    {LN_REPORT_GENERATEDTIME} {report_gentime}
    {report_comment}
    {LN_REPORT_FILTERS}
    {FilterType} {FilterDisplay}


    {ln_report_summary}
    {ln_report_logonoff_summary}
    {DisplayName} {itemcount}


    {ln_report_consolidation}

    {DataCaption}

    {ln_report_number} {ln_report_count} {ln_report_firstevent} {ln_report_lastevent} {ln_report_user} {ln_report_severity} {ln_report_host}
    {ZAEHLER} {itemcount} {itemcount} {FirstEvent_Date_Formatted} {LastEvent_Date_Formatted} {user} {syslogseverity_text} {FROMHOST}
    Made by Adiscon GmbH (2009-2011)  Report Version {report_version}  Partners:  Rsyslog |  WinSyslog {LN_REPORT_FOOTER_ENDERED}: {report_rendertime}  | {LN_FOOTER_DBQUERIES}: {TOTALQUERIES}
    ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootloganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff/report.eventlog.logonlogoff.lang.en.phploganalyzer-3.6.5/src/classes/reports/report.eventlog.logonlogoff/report.eventlog.logonlogoff.lang.e0000644000175000017500000000443312225176641033466 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ global $content; // Global Stuff $content['ln_report_logonoff_summary'] = "Summary of Logon/Logoff events"; $content['ln_report_consolidation'] = "Logon / Logoff Events consolidated per User"; $content['ln_report_summary'] = "Report Summary"; $content['ln_report_number'] = "No."; $content['ln_report_firstevent'] = "First Event"; $content['ln_report_lastevent'] = "Last Event"; $content['ln_report_user'] = "Domain & Username"; $content['ln_report_severity'] = "Type"; $content['ln_report_host'] = "Servername"; $content['ln_report_description'] = "Description"; $content['ln_report_count'] = "Count"; $content['ln_report_maxHosts_displayname'] = "Max hosts"; $content['ln_report_maxHosts_description'] = "The maximum number of hosts which will be displayed."; $content['ln_report_maxLogOnLogOffsPerHost_displayname'] = "Max Logon/Logoffs per host/user"; $content['ln_report_maxLogOnLogOffsPerHost_description'] = "The maximum number of Logon/Logoff events displayed per host/user."; $content['ln_report_colorThreshold_displayname'] = "Counter Threshold"; $content['ln_report_colorThreshold_description'] = "If the amount of consolidated events is higher then this threshold, the countfield will be marked red."; $content['ln_report_'] = ""; ?>loganalyzer-3.6.5/src/classes/class_template.php0000644000175000017500000002322212225176641021272 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- class Template { var $path = ''; var $filename = ''; var $extension = ''; var $template, $vars, $page; function Template ($fname = '') { if ($fname) $this->filename = $fname; } function set_path ($path) { $this->path = $path; } function set_extension ($ext) { $this->extension = $ext; } function set_templatefile ($fname) { $this->filename = $fname; } function set_template ($template) { $this->template = $template; } function set_values ($vars) { $this->vars = $vars; } function add_value ($name, $value) { $this->vars[$name] = $value; } function add_array ($name, $values) { if (is_array($values)) $this->vars[$name][] = $values; } function add_list ($name, $values) { if (is_array($values)) foreach ($values as $value) $this->vars[$name][] = array($name => $value); } function parser ($vars = '', $filename = '') { // BEGIN DELTA MOD // For MiscShowPageRenderStats if ( GetConfigSetting("MiscShowPageRenderStats", 1, CFGLEVEL_USER) == 1 ) FinishPageRenderStats( $vars ); // END DELTA MOD if ($filename) $this->filename = $filename; if ($vars) $this->vars = $vars; if (!isset($this->template)) { $fname = $this->path . $this->filename . $this->extension; $this->template = $this->load_file($fname); } $this->page = $this->template_parser( $this->template, $this->vars, $this->path, $this->extension ); } function result () { return $this->page; } function output () { echo $this->page; } function create_file ($fname) { if ($datafile = @fopen($fname, 'w')) { fputs($datafile, $this->page); fclose($datafile); return true; } else { return false; } } // Moved into Class function load_file($fname) { if (@is_file($fname)) return join('', file($fname)); else { // BEGIN DELTA MOD DieWithErrorMsg( "Could not find the template ".$fname.""); // END DELTA MOD } } function template_parser($template, $values, $path = '', $ext = '') { while (preg_match("", $template, $matches)) $template = str_replace( "", $this->load_file( $path . $matches[1] . $ext), $template ); $template = $this->template_parser_sub($template, $values); $template = str_replace("\t", " ", $template); $template = preg_replace("/ +/", " ", $template); return $template; } function template_parser_sub($template, $values) { if (is_array($values)) { foreach ($values as $k => $v) { if (is_array($v)) { $len = strlen($k); $lp = strpos($template, ""); if (is_int($lp)) { if ($rp = strpos($template, "")) { $page = substr($template, 0, $lp); $iter = substr($template, $lp + 15 + $len, $rp - $lp - $len - 15); $rowcnt = 0; $zaehler = 1; foreach ($v as $subval) { $subval['COUNTER'] = $rowcnt%2; $subval['ODDROW'] = $rowcnt%2; $subval['ROWCNT'] = $rowcnt++; $subval['ZAEHLER'] = $zaehler++; $page .= $this->template_parser_sub($iter, $subval); } $template = $page . substr($template, $rp + 13 + $len); } } } else { // FIXED BY ANDRE | Do not convert OBJECTS into strings! if ( !is_object($k) && !is_object($v) ) { // Replace normal variables $template = str_replace('{'.$k.'}', "$v", $template); // Replace variables with options, use Callback function! $template = preg_replace( '/{'.$k.':(.*?):(.*?)}/ie', 'InsertTemplateVariable("$v", "\\1", "\\2")', $template ); } } } } if (preg_match_all("", $template, $matches)) { foreach ($matches[1] as $block) { if (isset($values[$block])) { $template = str_replace("", "", $template); $template = str_replace("", "", $template); } else if ($blockend = strpos($template, "")) { $blockbeg = strpos($template, ""); $template = substr($template, 0, $blockbeg) . substr($template, $blockend + 13 + strlen($block)); } } } // else if (preg_match_all( '', $template, $matches, PREG_SET_ORDER) ) { // echo $matches[0][0]; // exit; foreach ($matches as $block) { $blockname = $block[1]; $not = $block[2]; $blockvalue = $block[3]; if ((@$values[$blockname] == $blockvalue && !$not) || (@$values[$blockname] != $blockvalue && $not)) { $template = str_replace( "", "", $template ); $template = str_replace( "", "", $template ); } else if ($blockend = strpos( $template, "")) { $blockbeg = strpos($template, ""); $template = substr($template, 0, $blockbeg) . substr($template, $blockend + 18 + strlen($blockname) + strlen($blockvalue) + strlen($not)); } } } if (preg_match_all( '', $template, $matches, PREG_SET_ORDER) ) { // echo $matches[0][1]; // echo $matches[0][2]; // echo $matches[0][3]; // exit; foreach ($matches as $block) { $blockname = $block[1]; $cmp = $block[2]; $blockstrvalue = $block[3]; // If $ get from content variable! if ( strpos($blockstrvalue, "$") !== false ) { // Trunscate $ $szVarId = substr( $blockstrvalue, 1 ); if ( isset($this->vars[$szVarId]) ) $blockvalue = intval($this->vars[$szVarId]); else $blockvalue = intval($blockstrvalue); } else // Plain number value $blockvalue = intval($blockstrvalue); if ( isset($values[$blockname]) ) { //echo "$cmp == '>' && @$values[$blockname] > $blockvalue
    "; // Perform comparison if ( ($cmp == '>' && @$values[$blockname] > $blockvalue) || ($cmp == '>=' && @$values[$blockname] >= $blockvalue) || ($cmp == '<' && @$values[$blockname] < $blockvalue) || ($cmp == '<=' && @$values[$blockname] <= $blockvalue) ) { $template = str_replace( "", "", $template ); $template = str_replace( "", "", $template ); } else if ($blockend = strpos( $template, "")) { $blockbeg = strpos($template, ""); $template = substr($template, 0, $blockbeg) . substr($template, $blockend + 18 + strlen($blockname) + strlen($blockstrvalue) + strlen($cmp)); } } else { $template = str_replace( "", "", $template ); $template = str_replace( "", "", $template ); } } } // return processed template return $template; } } function InsertTemplateVariable($szValue, $szOperation, $szOption) { // Set Default $szResult = $szValue; switch ( $szOperation ) { case "trunscate": if ( is_numeric($szOption) && strlen($szValue) > $szOption) $szResult = substr($szValue, 0, $szOption) . " ..."; break; case "forcelinebreak": if ( is_numeric($szOption) && strlen($szValue) > $szOption) $szResult = wordwrap($szValue, $szOption, "
    ", true); break; case "wordwrap": if ( is_numeric($szOption) && strlen($szValue) > $szOption) $szResult = wordwrap($szValue, $szOption, " ", true); break; default: // Nothing break; } // return result return $szResult; } ?>loganalyzer-3.6.5/src/classes/logstreamlineparsersyslog.class.php0000644000175000017500000001345212225176641024725 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- class LogStreamLineParsersyslog extends LogStreamLineParser { // protected $_arrProperties = null; // Constructor public function LogStreamLineParsersyslog() { return; // Nothing } /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public function ParseLine($szLine, &$arrArguments) { // Set IUT Property first! $arrArguments[SYSLOG_MESSAGETYPE] = IUT_Syslog; // Sample (Syslog): Mar 10 14:45:44 debandre anacron[3226]: Job `cron.daily' terminated (mailing output) if ( preg_match("/(...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32})\[(.*?)\]:(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1] . " " . $out[2]); $arrArguments[SYSLOG_HOST] = $out[3]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[4]; $arrArguments[SYSLOG_PROCESSID] = $out[5]; $arrArguments[SYSLOG_MESSAGE] = $out[6]; } // Sample (Syslog): Mar 10 14:45:39 debandre syslogd 1.4.1#18: restart else if ( preg_match("/(...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32}):(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1] . " " . $out[2]); $arrArguments[SYSLOG_HOST] = $out[3]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[4]; $arrArguments[SYSLOG_MESSAGE] = $out[5]; } // Sample (Syslog): Mar 10 14:45:39 debandre syslogd restart else if ( preg_match("/(...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32}) (.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1] . " " . $out[2]); $arrArguments[SYSLOG_HOST] = $out[3]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[4]; $arrArguments[SYSLOG_MESSAGE] = $out[5]; } // Sample (Syslog): Mar 7 17:18:35 debandre exiting on signal 15 else if ( preg_match("/(...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1] . " " . $out[2]); $arrArguments[SYSLOG_HOST] = $out[3]; $arrArguments[SYSLOG_MESSAGE] = $out[4]; } // Sample (RSyslog): 2008-03-28T11:07:40+01:00 localhost rger: test 1 else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?):(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_HOST] = $out[2]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[3]; $arrArguments[SYSLOG_MESSAGE] = $out[4]; } // Sample (RSyslog): 2008-03-28T11:07:40.591633+01:00 localhost rger: test 1 else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}\.[0-9]{1,6}.[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?):(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_HOST] = $out[2]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[3]; $arrArguments[SYSLOG_MESSAGE] = $out[4]; } // Sample: 2008-03-28T15:17:05.480876+01:00,**NO MATCH** else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}\.[0-9]{1,6}.[0-9]{1,2}:[0-9]{1,2}),(.*?)$/", $szLine, $out ) ) { // Some kind of debug message or something ... $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_MESSAGE] = $out[2]; } else { if ( isset($arrArguments[SYSLOG_MESSAGE]) && strlen($arrArguments[SYSLOG_MESSAGE]) > 0 ) OutputDebugMessage("Unparseable syslog msg - '" . $arrArguments[SYSLOG_MESSAGE] . "'", DEBUG_ERROR); } // If SyslogTag is set, we check for MessageType! if ( isset($arrArguments[SYSLOG_SYSLOGTAG]) ) { if ( strpos($arrArguments[SYSLOG_SYSLOGTAG], "EvntSLog" ) !== false ) $arrArguments[SYSLOG_MESSAGETYPE] = IUT_NT_EventReport; } // Return success! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/logstreamconfigdb.class.php0000644000175000017500000000643612225176641023077 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- class LogStreamConfigDB extends LogStreamConfig { public $DBServer = '127.0.0.1'; public $DBPort = 3306; public $DBName = ''; public $DBUser = ''; public $DBPassword = ''; public $DBType = DB_MYSQL; // Default = MYSQL! public $DBTableType = 'winsyslog'; // Default = WINSYSLOG DB Layout! public $DBTableName = 'systemevents'; // Default Tabelname from WINSYSLOG public $DBEnableRowCounting = true; // Default RowCounting is enabled! // Runtime configuration variables public $RecordsPerQuery = 100; // This will determine how to limit sql statements public $IDsPerQuery = 5000; // When we query ID's, we read a lot more the datarecords at once! public $SortColumn = SYSLOG_UID; // Default sorting column // public $FileName = ''; // public $LineParserType = "syslog"; // Default = Syslog! // public $_lineParser = null; public function LogStreamFactory($o) { // An instance is created, then include the logstreamdisk class as well! global $gl_root_path; require_once($gl_root_path . 'classes/logstreamdb.class.php'); // // Create and set LineParser Instance // $this->_lineParser = $this->CreateLineParser(); //$RecordsPerQuery //$_pageCount // return LogStreamDisk instance return new LogStreamDB($o); } /* private function CreateLineParser() { // We need to include Line Parser on demand! global $gl_root_path; require_once($gl_root_path . 'classes/logstreamlineparser.class.php'); // Probe if file exists then include it! $strIncludeFile = 'classes/logstreamlineparser' . $this->LineParserType . '.class.php'; $strClassName = "LogStreamLineParser" . $this->LineParserType; if ( is_file($strIncludeFile) ) { require_once($strIncludeFile); // TODO! Create Parser based on Source Config! //return LineParser Instance return new $strClassName(); } else DieWithErrorMsg("Couldn't locate LineParser include file '" . $strIncludeFile . "'"); } */ } ?> loganalyzer-3.6.5/src/classes/logstreampdo.class.php0000644000175000017500000023233412225176641022104 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Required Includes! require_once($gl_root_path . 'include/constants_errors.php'); // --- class LogStreamPDO extends LogStream { private $_dbhandle = null; // Helper to store the database records private $bufferedRecords = null; private $_currentRecordStart = 0; private $_currentRecordNum = 0; private $_totalRecordCount = -1; private $_previousPageUID = -1; private $_lastPageUID = -1; private $_firstPageUID = -1; private $_currentPageNumber = -1; private $_SQLwhereClause = ""; private $_myDBQuery = null; // Constructor public function LogStreamPDO($streamConfigObj) { $this->_logStreamConfigObj = $streamConfigObj; // Verify if Extension is enabled if ( extension_loaded('pdo') == 0 ) DieWithFriendlyErrorMsg("Error, PDO Extensions are not enabled or installed! This Source can not operate."); /* if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) { // Probe if a function exists! if ( !function_exists("mysql_connect") ) DieWithFriendlyErrorMsg("Error, MYSQL Extensions are not enabled! Function 'mysql_connect' does not exist."); } */ } /** * Open and verifies the database conncetion * * @param arrProperties array in: Properties wish list. * @return integer Error stat */ public function Open($arrProperties) { global $dbmapping; // Initialise Basic stuff within the Classs $this->RunBasicInits(); // Verify database driver and connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Copy the Property Array $this->_arrProperties = $arrProperties; // Check if DB Mapping exists if ( !isset($dbmapping[ $this->_logStreamConfigObj->DBTableType ]) ) return ERROR_DB_INVALIDDBMAPPING; // Create SQL Where Clause first! $res = $this->CreateSQLWhereClause(); if ( $res != SUCCESS ) return $res; // Only obtain rowcount if enabled and not done before if ( $this->_logStreamConfigObj->DBEnableRowCounting && $this->_totalRecordCount == -1 ) $this->_totalRecordCount = $this->GetRowCountFromTable(); // Success, this means we init the Pagenumber to ONE! //$this->_currentPageNumber = 1; // reached this point means success! return SUCCESS; } /* * Helper function to clear the current querystring! */ public function ResetFilters() { // Clear _SQLwhereClause variable! $this->_SQLwhereClause = ""; } /** * Close the database connection. * * @return integer Error state */ public function Close() { // trigger closing database query! $this->DestroyMainSQLQuery(); // TODO CLOSE DB CONN?! return true; } /** * Verify if the database connection exists! * * @return integer Error state */ public function Verify() { global $content, $dbmapping; // Create DSN String $myDBDriver = $this->_logStreamConfigObj->GetPDODatabaseType(); $myDsn = $this->_logStreamConfigObj->CreateConnectDSN(); if ( strlen($myDsn) > 0 ) { // Check if configured driver is actually loaded! //print_r(PDO::getAvailableDrivers()); if ( !in_array($myDBDriver, PDO::getAvailableDrivers()) ) { global $extraErrorDescription; $extraErrorDescription = "PDO Database Driver not loaded: " . $myDBDriver . "
    Please check your php configuration extensions"; // OutputDebugMessage("LogStreamPDO|Verify: $extraErrorDescription", DEBUG_ERROR); // return error code return ERROR_DB_INVALIDDBDRIVER; } try { // Try to connect to the database $this->_dbhandle = new PDO( $myDsn, $this->_logStreamConfigObj->DBUser, $this->_logStreamConfigObj->DBPassword /*, array(PDO::ATTR_TIMEOUT =>25)*/); //$this->_dbhandle->setAttribute(PDO::ATTR_TIMEOUT, 25); } catch (PDOException $e) { global $extraErrorDescription; $extraErrorDescription = "PDO Database Connection failed: " . $e->getMessage(); // Append extra data if admin user if ( isset($content['SESSION_ISADMIN']) && $content['SESSION_ISADMIN'] ) $extraErrorDescription .= "
    AdminDebug - DSN: " . $myDsn; // Debug Output // OutputDebugMessage("LogStreamPDO|Verify: $extraErrorDescription", DEBUG_ERROR); // return error code return ERROR_DB_CONNECTFAILED; } // Check if Table Mapping exists if ( !isset($dbmapping[$this->_logStreamConfigObj->DBTableType]) ) { // Return error return ERROR_DB_INVALIDDBMAPPING; } // Check if table exists try { // This is one way to check if the table exists! But I don't really like it tbh -.- $szIdField = $dbmapping[$this->_logStreamConfigObj->DBTableType]['DBMAPPINGS'][SYSLOG_UID]; $szTestQuery = "SELECT MAX(" . $szIdField . ") FROM " . $this->_logStreamConfigObj->DBTableName; $tmpStmnt = $this->_dbhandle->prepare( $szTestQuery ); $tmpStmnt->execute(); $colcount = $tmpStmnt->columnCount(); if ( $colcount <= 0 ) return ERROR_DB_TABLENOTFOUND; } catch (PDOException $e) { global $extraErrorDescription; $extraErrorDescription = "Could not find table: " . $e->getMessage(); // OutputDebugMessage("LogStreamPDO|Verify: $extraErrorDescription", DEBUG_ERROR); // return error code return ERROR_DB_TABLENOTFOUND; } } else { // Invalid DB Driver! return ERROR_DB_INVALIDDBDRIVER; } // reached this point means success ;)! return SUCCESS; } /* * Implementation of VerifyFields: Checks if fields exist in table */ public function VerifyFields( $arrProperitesIn ) { global $dbmapping, $fields; // Get List of Indexes as Array $arrFieldKeys = $this->GetFieldsAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // FIELD Listing failed! Nothing we can do in this case! if ( $arrFieldKeys == null ) return SUCCESS; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { // echo $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "
    "; if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrFieldKeys) ) { OutputDebugMessage("LogStreamPDO|VerifyFields: Found Field for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_ULTRADEBUG); continue; } else { // Index is missing for this field! OutputDebugMessage("LogStreamPDO|VerifyFields: Missing Field for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_WARN); return ERROR_DB_DBFIELDNOTFOUND; } } // Successfull return SUCCESS; } /* * Implementation of VerifyIndexes: Checks if indexes exist for desired fields */ public function VerifyIndexes( $arrProperitesIn ) { global $dbmapping, $fields; // Get List of Indexes as Array $arrIndexKeys = $this->GetIndexesAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // INDEX Listing failed! Nothing we can do in this case! if ( !isset($arrIndexKeys) )// == null ) return SUCCESS; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { if ( count($arrIndexKeys) <= 0 ) { // NO INDEXES at all! OutputDebugMessage("LogStreamPDO|VerifyIndexes: NO INDEXES found !", DEBUG_WARN); return ERROR_DB_INDEXESMISSING; } if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrIndexKeys) ) { OutputDebugMessage("LogStreamPDO|VerifyIndexes: Found INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_ULTRADEBUG); continue; } else { // Index is missing for this field! OutputDebugMessage("LogStreamPDO|VerifyIndexes: Missing INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_WARN); return ERROR_DB_INDEXESMISSING; } } // Successfull return SUCCESS; } /* * Implementation of VerifyChecksumTrigger: Checks if checksum trigger exists */ public function VerifyChecksumTrigger( $myTriggerProperty ) { global $dbmapping, $fields; // Avoid Check if TRIGGERS are not supported! if ( $this->_logStreamConfigObj->GetPDOTriggersSupported() == false ) return SUCCESS; // Get List of Triggers as Array $arrIndexTriggers = $this->GetTriggersAsArray(); // TRIGGER Listing failed! Nothing we can do in this case! if ( !isset($arrIndexTriggers) )// == null ) // if ( $arrIndexTriggers == null ) return SUCCESS; $szTableType = $this->_logStreamConfigObj->DBTableType; $szDBName = $this->_logStreamConfigObj->DBName; $szTableName = $this->_logStreamConfigObj->DBTableName; $szDBTriggerField = $dbmapping[$szTableType]['DBMAPPINGS'][$myTriggerProperty]; // Create Triggername | lowercase! $szTriggerName = strtolower($szDBName . "_" . $szTableName . "_" . $szDBTriggerField); // Try to find logstream trigger if ( count($arrIndexTriggers) > 0 ) { if ( in_array($szTriggerName, $arrIndexTriggers) ) { OutputDebugMessage("LogStreamPDO|VerifyChecksumTrigger: Found TRIGGER '" . $szTriggerName. "' for table '" . $szTableName . "'", DEBUG_ULTRADEBUG); return SUCCESS; } else { // Index is missing for this field! OutputDebugMessage("LogStreamPDO|VerifyChecksumTrigger: Missing TRIGGER '" . $szTriggerName . "' for Table '" . $szTableName . "'", DEBUG_WARN); return ERROR_DB_TRIGGERMISSING; } } else { // Index is missing for this field! OutputDebugMessage("LogStreamPDO|VerifyChecksumTrigger: No TRIGGERS found in your database", DEBUG_WARN); return ERROR_DB_TRIGGERMISSING; } } /* * Implementation of CreateMissingIndexes: Checks if indexes exist for desired fields */ public function CreateMissingIndexes( $arrProperitesIn ) { global $dbmapping, $fields, $querycount; // Get List of Indexes as Array $arrIndexKeys = $this->GetIndexesAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrIndexKeys) ) continue; else { // Update Table schema now! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) $szSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD INDEX ( " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " )"; else if ( $this->_logStreamConfigObj->DBType == DB_PGSQL ) $szSql = "CREATE INDEX " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "_idx ON \"" . $this->_logStreamConfigObj->DBTableName . "\" (" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . ");"; else if ( $this->_logStreamConfigObj->DBType == DB_MSSQL ) $szSql = "CREATE INDEX " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "_idx ON " . $this->_logStreamConfigObj->DBTableName . " (" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . ");"; else // Not supported in this case! return ERROR_DB_INDEXFAILED; // Index is missing for this field! OutputDebugMessage("LogStreamPDO|CreateMissingIndexes: Createing missing INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' - " . $szSql, DEBUG_INFO); // Add missing INDEX now! $myQuery = $this->_dbhandle->query($szSql); if (!$myQuery) { // Return failure! $this->PrintDebugError("Dynamically Adding INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' failed with Statement: '" . $szSql . "'"); return ERROR_DB_INDEXFAILED; } else // Free query now $myQuery->closeCursor(); } } // Successfull return SUCCESS; } /* * Implementation of CreateMissingFields: Checks if indexes exist for desired fields */ public function CreateMissingFields( $arrProperitesIn ) { global $dbmapping, $fields, $querycount; // Get List of Indexes as Array $arrFieldKeys = $this->GetFieldsAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrFieldKeys) ) continue; else { if ( $this->HandleMissingField( $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrProperitesIn ) == SUCCESS ) { // Index is missing for this field! OutputDebugMessage("LogStreamPDO|CreateMissingFields: Createing missing FIELD for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], DEBUG_INFO); } else { // Return failure! $this->PrintDebugError("Dynamically Adding FIELD for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' failed!"); return ERROR_DB_ADDDBFIELDFAILED; } } } // Successfull return SUCCESS; } /* * Implementation of GetCreateMissingTriggerSQL: Creates SQL needed to create a TRIGGER */ public function GetCreateMissingTriggerSQL( $myDBTriggerField, $myDBTriggerCheckSumField ) { global $dbmapping, $fields, $querycount; // Get List of Triggers as Array $szDBName = $this->_logStreamConfigObj->DBName; $szTableName = $this->_logStreamConfigObj->DBTableName; // Create Triggername $szTriggerName = strtolower($szDBName . "_" . $szTableName . "_" . $myDBTriggerField); // Create TRIGGER SQL! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) $szSql ="CREATE TRIGGER " . $szTriggerName . " BEFORE INSERT ON `" . $szTableName . "` FOR EACH ROW BEGIN SET NEW." . $myDBTriggerCheckSumField . " = crc32(NEW." . $myDBTriggerField . "); END ;"; else if ( $this->_logStreamConfigObj->DBType == DB_PGSQL ) // Experimental Trigger Support for POSTGRESQL $szSql =" CREATE LANGUAGE plpgsql ; CREATE FUNCTION " . $szTriggerName . "() RETURNS trigger AS $" . $szTriggerName . "$ BEGIN NEW." . $myDBTriggerCheckSumField . " := hashtext(NEW." . $myDBTriggerField . "); RETURN NEW; END; $" . $szTriggerName . "$ LANGUAGE plpgsql; CREATE TRIGGER " . $szTriggerName . " BEFORE INSERT OR UPDATE ON \"" . $szTableName . "\" FOR EACH ROW EXECUTE PROCEDURE " . $szTriggerName . "(); "; else if ( $this->_logStreamConfigObj->DBType == DB_MSSQL ) { // Trigger code for MSSQL! $szSql ="CREATE TRIGGER " . $szTriggerName . " ON " . $szTableName . " AFTER INSERT AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Insert statements for trigger here UPDATE " . $szTableName . " SET " . $myDBTriggerCheckSumField . " = checksum(I." . $myDBTriggerField . ") FROM " . $szTableName . " JOIN inserted I on " . $szTableName . "." . $dbmapping[$szTableType]['DBMAPPINGS']['SYSLOG_UID'] . " = I." . $dbmapping[$szTableType]['DBMAPPINGS']['SYSLOG_UID'] . " END "; } else // NOT SUPPORTED return null; return $szSql; } /* * Implementation of CreateMissingTrigger: Creates missing triggers ! */ public function CreateMissingTrigger( $myTriggerProperty, $myCheckSumProperty ) { global $dbmapping, $fields, $querycount; // Avoid if TRIGGERS are not supported! if ( $this->_logStreamConfigObj->GetPDOTriggersSupported() == false ) return SUCCESS; // Get List of Triggers as Array $szTableName = $this->_logStreamConfigObj->DBTableName; $szTableType = $this->_logStreamConfigObj->DBTableType; $szDBTriggerField = $dbmapping[$szTableType]['DBMAPPINGS'][$myTriggerProperty]; $szDBTriggerCheckSumField = $dbmapping[$szTableType]['DBMAPPINGS'][$myCheckSumProperty]; // Get SQL Code to create the trigger! $szSql = $this->GetCreateMissingTriggerSQL( $szDBTriggerField, $szDBTriggerCheckSumField ); // Index is missing for this field! OutputDebugMessage("LogStreamPDO|CreateMissingTrigger: Creating missing TRIGGER for '" . $szTableName . "' - $szDBTriggerCheckSumField = crc32(NEW.$szDBTriggerField)" . $szSql, DEBUG_INFO); // Add missing INDEX now! $myQuery = $this->_dbhandle->query($szSql); if (!$myQuery) { // Return failure! $this->PrintDebugError("Dynamically Adding TRIGGER for '" . $szTableName . "' failed!

    If you want to manually add the TRIGGER, use the following SQL Command:
    " . str_replace("\n", "
    ", $szSql) . "
    "); return ERROR_DB_TRIGGERFAILED; } else // Free query now $myQuery->closeCursor(); // Successfull return SUCCESS; } /* * Implementation of ChangeChecksumFieldUnsigned: Changes the Checkusm field to unsigned! */ public function ChangeChecksumFieldUnsigned() { global $dbmapping, $fields, $querycount; // Get variables $szTableType = $this->_logStreamConfigObj->DBTableType; // TODO if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) // Change Checksumfield to use UNSIGNED! $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` CHANGE `" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "` `" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "` INT(11) UNSIGNED NOT NULL DEFAULT '0'"; // Update Table schema now! $myQuery = $this->_dbhandle->query($szUpdateSql); if (!$myQuery) { // Return failure! $this->PrintDebugError("ER_BAD_FIELD_ERROR - Failed to Change field '" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "' from signed to unsigned with sql statement: '" . $szUpdateSql . "'"); return ERROR_DB_CHECKSUMCHANGEFAILED; } else // Free query now $myQuery->closeCursor(); // return results return SUCCESS; } /* * Implementation of VerifyChecksumField: Verifies if the checkusm field is signed or unsigned! */ public function VerifyChecksumField() { global $dbmapping, $fields, $querycount; // Get variables $szTableType = $this->_logStreamConfigObj->DBTableType; // Create SQL and Get INDEXES for table! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) $szSql = "SHOW COLUMNS FROM `" . $this->_logStreamConfigObj->DBTableName . "` WHERE Field = '" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "'"; else // NOT SUPPORTED or NEEDED return SUCCESS; // Run Query to check the Checksum field! $myQuery = $this->_dbhandle->query($szSql); if ($myQuery) { // Get result! $myRow = $myQuery->fetch(PDO::FETCH_ASSOC); if (strpos( strtolower($myRow['Type']), "unsigned") === false ) { // return error code! return ERROR_DB_CHECKSUMERROR; } // Free query now $myQuery->closeCursor(); // Increment for the Footer Stats $querycount++; } // return results return SUCCESS; } /** * Read the data from a specific uID which means in this * case beginning with from the Database ID * * @param uID integer in/out: unique id of the data row * @param arrProperitesOut array out: array filled with properties * @return integer Error state * @see ReadNext() */ public function Read($uID, &$arrProperitesOut) { // Seek the first uID! if ( $this->Sseek($uID, EnumSeek::UID, 0) == SUCCESS) { // Read the next record! $ret = $this->ReadNext($uID, $arrProperitesOut); } else $ret = ERROR_NOMORERECORDS; // return result! return $ret; } /** * Read the next line from the file depending on the current * read direction. * * Hint: If the current stream becomes unavailable an error * stated is retuned. A typical case is if a log rotation * changed the original data source. * * @param uID integer out: uID is the offset of data row * @param arrProperitesOut array out: properties * @return integer Error state * @see ReadNext */ public function ReadNext(&$uID, &$arrProperitesOut, $bParseMessage = true) { // Helpers needed for DB Mapping global $content, $gl_starttime; global $dbmapping, $fields; $szTableType = $this->_logStreamConfigObj->DBTableType; // define $ret $ret = SUCCESS; do { // No buffer? then read from DB! if ( $this->bufferedRecords == null ) $ret = $this->ReadNextRecordsFromDB($uID); else { if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) ) { // We need to load new records, so clear the old ones first! $this->ResetBufferedRecords(); // Set new Record start, will be used in the SQL Statement! $this->_currentRecordStart = $this->_currentRecordNum; // + 1; // Now read new ones $ret = $this->ReadNextRecordsFromDB($uID); // Check if we found more records if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) ) $ret = ERROR_NOMORERECORDS; } } if ( $ret == SUCCESS && $this->_arrProperties != null ) { // Init and set variables foreach ( $this->_arrProperties as $property ) { // Check if mapping exists if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$property]) ) { // Copy property if available! $dbfieldname = $dbmapping[$szTableType]['DBMAPPINGS'][$property]; if ( isset($this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]) ) { if ( isset($fields[$property]['FieldType']) && $fields[$property]['FieldType'] == FILTER_TYPE_DATE ) // Handle as date! $arrProperitesOut[$property] = GetEventTime( $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname] ); else $arrProperitesOut[$property] = $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]; } else $arrProperitesOut[$property] = ''; } else $arrProperitesOut[$property] = ''; } // Run optional Message Parsers now if ( isset($arrProperitesOut[SYSLOG_MESSAGE]) ) { $retParser = $this->_logStreamConfigObj->ProcessMsgParsers($arrProperitesOut[SYSLOG_MESSAGE], $arrProperitesOut); // Check if we have to skip the message! if ( $retParser == ERROR_MSG_SKIPMESSAGE ) $ret = $retParser; } // Set uID to the PropertiesOut! //DEBUG -> $this->_currentRecordNum; $uID = $arrProperitesOut[SYSLOG_UID] = $this->bufferedRecords[$this->_currentRecordNum][$dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID]]; // Increment $_currentRecordNum $this->_currentRecordNum++; } // Check how long we are running. If only two seconds of execution time are left, we abort further reading! $scriptruntime = intval(microtime_float() - $gl_starttime); if ( $content['MaxExecutionTime'] > 0 && $scriptruntime > ($content['MaxExecutionTime']-2) ) { // This may display a warning message, so the user knows we stopped reading records because of the script timeout. $content['logstream_warning'] = "false"; $content['logstream_warning_details'] = $content['LN_WARNING_LOGSTREAMDISK_TIMEOUT']; $content['logstream_warning_code'] = ERROR_FILE_NOMORETIME; // Return error code return ERROR_FILE_NOMORETIME; } // This additional filter check will take care on dynamic fields from the message parser! } while ( $this->ApplyFilters($ret, $arrProperitesOut) != SUCCESS && $ret == SUCCESS ); // reached here means return result! return $ret; } /** * Implementation of Seek */ public function Sseek(&$uID, $mode, $numrecs) { // predefine return value $ret = SUCCESS; switch ($mode) { case EnumSeek::UID: // if ( $uID == UID_UNKNOWN ) // set uID to first ID! { // No buffer? then read from DB! if ( $this->bufferedRecords == null ) $ret = $this->ReadNextRecordsFromDB($uID); if ( $ret == SUCCESS ) { $this->_currentRecordNum = 0; $uID = $this->bufferedRecords[ $this->_currentRecordNum ]; } } /* else { // Obtain fieldname for uID global $dbmapping; $uidfieldname = $dbmapping[$this->_logStreamConfigObj->DBTableType][SYSLOG_UID]; // Clear if necessary! if ( $this->bufferedRecords == null ) $this->ResetBufferedRecords(); // Loop through all records for now, maybe optimized later! $bFound = false; $tmpuID = $uID; $ret = ERROR_NOMORERECORDS; // Set Default error code! // Set totalpages number if available if ( $this->_totalRecordCount != -1 ) $totalpages = intval($this->_totalRecordCount / $this->_logStreamConfigObj->_pageCount); else $totalpages = 1; while( $bFound == false && $this->ReadNextIDsFromDB() == SUCCESS ) { foreach ( $this->bufferedRecords as $myRecord ) { if ( $myRecord[$uidfieldname] == $uID ) { $bFound = true; $ret = SUCCESS; break; // Break foreach loop! } else { $tmpuID = $myRecord[$uidfieldname]; // Only Increment $_currentRecordNum $this->_currentRecordNum++; } // Increment our Pagenumber if needed! if ( $this->_currentRecordNum % $this->_logStreamConfigObj->_pageCount == 0 ) $this->_currentPageNumber++; } if ( $this->_currentPageNumber > 1 && $this->_readDirection == EnumReadDirection::Forward) $this->_currentPageNumber = $totalpages - $this->_currentPageNumber + 1; //--- Extra check to set the correct $_previousPageUID! if ( $this->_currentRecordNum > $this->_logStreamConfigObj->_pageCount && isset($this->bufferedRecords[$this->_currentRecordNum - 50][$uidfieldname]) ) { $this->_previousPageUID = $this->bufferedRecords[$this->_currentRecordNum - $this->_logStreamConfigObj->_pageCount - 1][$uidfieldname]; } // TODO! Handle the case where previous ID is not set in the bufferedrecords! //--- // We need to load new records, so clear the old ones first! $this->ResetBufferedRecords(); // Set new Record start, will be used in the SQL Statement! $this->_currentRecordStart = $this->_currentRecordNum; } // Delete buffered records, then they will be read automatically in ReadNext() $this->ResetBufferedRecords(); } */ break; } // Return result! return $ret; } /** * GetMessageCount will return the count of Message. * If this count is not available, the function will * return the default -1 */ public function GetMessageCount() { return $this->_totalRecordCount; } /** * This function returns the first UID for previous PAGE, if availbale! * Otherwise will return -1! */ public function GetPreviousPageUID() { return $this->_previousPageUID; } /** * This function returns the FIRST UID for the FIRST PAGE! * Will be done by a seperated SQL Statement. */ public function GetFirstPageUID() { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; $szSql = "SELECT MAX(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") FROM `" . $this->_logStreamConfigObj->DBTableName . "`" . $this->_SQLwhereClause; $myQuery = $this->_dbhandle->query($szSql); if ( $myQuery ) { $myRow = $myQuery->fetchColumn(); $this->_firstPageUID = $myRow; // $myRow[0]; // Free query now $myQuery->closeCursor(); // Increment for the Footer Stats $querycount++; } //echo $szSql . "
    " . $this->_firstPageUID; //exit; // finally return result! return $this->_firstPageUID; } /** * This function returns the first UID for the last PAGE! * Will be done by a seperated SQL Statement. */ public function GetLastPageUID() { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; $szSql = "SELECT MIN(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") FROM `" . $this->_logStreamConfigObj->DBTableName . "`" . $this->_SQLwhereClause; $myQuery = $this->_dbhandle->query($szSql); if ( $myQuery ) { $myRow = $myQuery->fetchColumn(); $this->_lastPageUID = $myRow; // $myRow[0]; // Free query now $myQuery->closeCursor(); // Increment for the Footer Stats $querycount++; } //echo $szSql . "
    " . $this->_lastPageUID; //exit; // finally return result! return $this->_lastPageUID; } /** * This function returns the current Page number, if availbale! * Otherwise will return 0! We also assume that this function is * only called once DB is open! */ public function GetCurrentPageNumber() { return $this->_currentPageNumber; } /* * Implementation of IsPropertySortable * * For now, sorting is only possible for the UID Property! */ public function IsPropertySortable($myProperty) { global $fields; // TODO: HARDCODED | FOR NOW only FALSE! return false; if ( isset($fields[$myProperty]) && $myProperty == SYSLOG_UID ) return true; else return false; } /** * Implementation of GetLogStreamStats * * Returns an Array og logstream statsdata * Count of Data Items * Total Filesize */ public function GetLogStreamStats() { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Perform if Connection is true! if ( $this->_dbhandle != null ) { $tableName = $this->_logStreamConfigObj->DBTableName; // SHOW TABLE STATUS FROM $stats = NULL; $szSql = "SELECT count(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") as Counter FROM " . $this->_logStreamConfigObj->DBTableName; $myQuery = $this->_dbhandle->query($szSql); if ( $myQuery ) { // Set tablename! $tableName = $this->_logStreamConfigObj->DBTableName; $myStats[] = array( 'StatsDisplayName' => 'TableName', 'StatsValue' => $tableName ); // obtain first and only row $myRow = $myQuery->fetchColumn(); $myStats[] = array( 'StatsDisplayName' => 'Rows', 'StatsValue' => $myRow ); $stats[]['STATSDATA'] = $myStats; // Free query now $myQuery->closeCursor(); // Increment for the Footer Stats $querycount++; } // return results! return $stats; } else return null; } /** * Implementation of GetLogStreamTotalRowCount * * Returns the total amount of rows in the main datatable */ public function GetLogStreamTotalRowCount() { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Set default rowcount $rowcount = null; // Perform if Connection is true! if ( $this->_dbhandle != null ) { // Get Total Rowcount $szSql = "SELECT count(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") as Counter FROM " . $this->_logStreamConfigObj->DBTableName; $myQuery = $this->_dbhandle->query($szSql); if ( $myQuery ) { // Obtain RowCount! $myRow = $myQuery->fetchColumn(); $rowcount = $myRow; // Free query now $myQuery->closeCursor(); // Increment for the Footer Stats $querycount++; } } //return result return $rowcount; } /** * Implementation of the CleanupLogdataByDate function! Returns affected rows! */ public function CleanupLogdataByDate( $nDateTimeStamp ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Set default rowcount $rowcount = null; // Perform if Connection is true! if ( $this->_dbhandle != null ) { // --- Init Filters if necessary! if ( $this->_filters == null ) $this->SetFilter( "" ); // This will init filters! // Create SQL Where Clause! $this->CreateSQLWhereClause(); // --- // --- Add default WHERE clause if ( strlen($this->_SQLwhereClause) > 0 ) $szWhere = $this->_SQLwhereClause; else $szWhere = ""; // Add Datefilter if necessary! if ( $nDateTimeStamp > 0 ) { if ( strlen($szWhere) > 0 ) $szWhere .= " AND "; else $szWhere = " WHERE "; // Append Date Filter! $szWhere .= $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . " < '" . date('Y-m-d H:i:s', $nDateTimeStamp) . "'"; } // --- // DELETE DATA NOW! $szSql = "DELETE FROM " . $this->_logStreamConfigObj->DBTableName . $szWhere; OutputDebugMessage("LogStreamPDO|CleanupLogdataByDate: Created SQL Query:
    " . $szSql, DEBUG_DEBUG); $myQuery = $this->_dbhandle->query($szSql); if ( $myQuery ) { // Get affected rows and return! $rowcount = $myQuery->rowCount(); // Free query now $myQuery->closeCursor(); } else { // error occured, output DEBUG message $this->PrintDebugError("CleanupLogdataByDate failed with SQL Statement ' " . $szSql . " '"); } } //return affected rows return $rowcount; } /* * Implementation of the UpdateAllMessageChecksum * * Update all missing checksum properties in the current database */ public function UpdateAllMessageChecksum( ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // UPDATE DATA NOW! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) { $szSql = "UPDATE `" . $this->_logStreamConfigObj->DBTableName . "`" . " SET " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = crc32(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_MESSAGE] . ") " . " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " IS NULL OR " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = 0"; } elseif ($this->_logStreamConfigObj->DBType == DB_PGSQL ) { $szSql = "UPDATE \"" . $this->_logStreamConfigObj->DBTableName . "\"" . " SET " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = hashtext(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_MESSAGE] . ") " . " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " IS NULL OR " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = 0"; } elseif ($this->_logStreamConfigObj->DBType == DB_MSSQL ) { $szSql = "UPDATE " . $this->_logStreamConfigObj->DBTableName . " SET " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = checksum(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_MESSAGE] . ") " . " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " IS NULL OR " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = 0"; } else { // Failed | Checksum function not supported! $this->PrintDebugError("UpdateAllMessageChecksum failed, PDO LogStream does not support CRC32 Checksums in SQL Statements!"); return ERROR; } // Output Debug Informations OutputDebugMessage("LogStreamPDO|UpdateAllMessageChecksum: Running Created SQL Query:
    " . $szSql, DEBUG_ULTRADEBUG); // Running SQL Query $myQuery = $this->_dbhandle->query($szSql); if ( $myQuery ) { // Output Debug Informations OutputDebugMessage("LogStreamPDO|UpdateAllMessageChecksum: Successfully updated Checksum of '" . $myQuery->rowCount() . "' datarecords", DEBUG_INFO); // Free query now $myQuery->closeCursor(); // Return success return SUCCESS; } else { // error occured, output DEBUG message $this->PrintDebugError("UpdateAllMessageChecksum failed with SQL Statement ' " . $szSql . " '"); // Failed return ERROR; } } /* * Implementation of the SaveMessageChecksum * * Creates an database UPDATE Statement and performs it! */ public function SaveMessageChecksum( $arrProperitesIn ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; if ( isset($arrProperitesIn[SYSLOG_UID]) && isset($arrProperitesIn[MISC_CHECKSUM]) && isset($dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM]) ) { // DELETE DATA NOW! $szSql = "UPDATE " . $this->_logStreamConfigObj->DBTableName . " SET " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = " . $arrProperitesIn[MISC_CHECKSUM] . " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " = " . $arrProperitesIn[SYSLOG_UID]; $myQuery = $this->_dbhandle->query($szSql); if ( $myQuery ) { // Free query now $myQuery->closeCursor(); // Return success return SUCCESS; } else { // error occured, output DEBUG message $this->PrintDebugError("SaveMessageChecksum failed with SQL Statement ' " . $szSql . " '"); // Failed return ERROR; } } else // Missing important properties return ERROR; } /** * Implementation of ConsolidateItemListByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function ConsolidateItemListByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder) { global $content, $dbmapping, $fields; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; // Check if fields are available if ( !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]) || !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId]) ) return ERROR_DB_DBFIELDNOTFOUND; // --- Set Options $nConsFieldType = $fields[$szConsFieldId]['FieldType']; if ( $nSortingOrder == SORTING_ORDER_DESC ) $szSortingOrder = "DESC"; else $szSortingOrder = "ASC"; // --- // --- Set DB Field names $myDBConsFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]; $myDBGroupByFieldName = $myDBConsFieldName; $myDBQueryFields = $myDBConsFieldName . ", "; // Set Sorted Field if ( $szConsFieldId == $szSortFieldId ) $myDBSortedFieldName = "itemcount"; else $myDBSortedFieldName = $szSortFieldId; // --- // Special handling for date fields if ( $nConsFieldType == FILTER_TYPE_DATE ) { if ( $this->_logStreamConfigObj->DBType == DB_MYSQL || $this->_logStreamConfigObj->DBType == DB_PGSQL ) { // Helper variable for the select statement $mySelectFieldName = $myDBGroupByFieldName . "Grouped"; $myDBQueryFieldName = "DATE( " . $myDBConsFieldName . ") AS " . $myDBGroupByFieldName ; } else if($this->_logStreamConfigObj->DBType == DB_MSSQL ) { // TODO FIND A WAY FOR MSSQL! } } // Set Limit String if ( $nRecordLimit > 0 ) { // Append LIMIT in this case! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL || $this->_logStreamConfigObj->DBType == DB_PGSQL ) $szLimitSql = " LIMIT " . $nRecordLimit; else $szLimitSql = ""; // TODO FIND A WAY FOR MSSQL! } else $szLimitSql = ""; // Create SQL Where Clause! if ( $this->_SQLwhereClause == "" ) { $res = $this->CreateSQLWhereClause(); if ( $res != SUCCESS ) return $res; } // Create SQL String now! $szSql = "SELECT " . $myDBQueryFields . "count(" . $myDBConsFieldName . ") as itemcount " . " FROM " . $this->_logStreamConfigObj->DBTableName . $this->_SQLwhereClause . " GROUP BY " . $myDBGroupByFieldName . " ORDER BY " . $myDBSortedFieldName . " " . $szSortingOrder . $szLimitSql ; // Perform Database Query $this->_myDBQuery = $this->_dbhandle->query($szSql); if ( !$this->_myDBQuery ) return ERROR_DB_QUERYFAILED; if ( $this->_myDBQuery->rowCount() == 0 ) { $this->_myDBQuery = null; return ERROR_NOMORERECORDS; } // Initialize Array variable $aResult = array(); // Init Helper counter $iCount = 0; // read data records while ( ($myRow = $this->_myDBQuery->fetch(PDO::FETCH_ASSOC)) && $iCount < $nRecordLimit) { // Create new row $aNewRow = array(); foreach ( $myRow as $myFieldName => $myFieldValue ) { if ( $myFieldName == $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId] ) $aNewRow[$szConsFieldId] = $myFieldValue; else $aNewRow[$myFieldName] = $myFieldValue; } // Increment Counter $iCount++; // Add new row to result $aResult[] = $aNewRow; } // Delete handle $this->_myDBQuery = null; // return finished array if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } /** * Implementation of ConsolidateDataByField * * In the PDO DB Logstream, the database will do most of the work * * @return integer Error stat */ public function ConsolidateDataByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder, $aIncludeCustomFields = null, $bIncludeLogStreamFields = false, $bIncludeMinMaxDateFields = false) { global $content, $dbmapping, $fields;; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; // Check if fields are available if ( !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]) || !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId]) ) return ERROR_DB_DBFIELDNOTFOUND; // --- Set Options $nConsFieldType = $fields[$szConsFieldId]['FieldType']; if ( $nSortingOrder == SORTING_ORDER_DESC ) $szSortingOrder = "DESC"; else $szSortingOrder = "ASC"; // --- // --- Set DB Field names $myDBConsFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]; $myDBGroupByFieldName = $myDBConsFieldName; // Check which fields to include if ( $aIncludeCustomFields != null ) { $myDBQueryFields = ""; foreach ( $aIncludeCustomFields as $myFieldName ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName]) ) { if ( $this->_logStreamConfigObj->DBType == DB_PGSQL || $this->_logStreamConfigObj->DBType == DB_MSSQL ) $myDBQueryFields .= "Max(" . $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ") AS " . $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", "; else // Default for other PDO Engines $myDBQueryFields .= $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", "; } } // Append Sortingfield if ( !in_array($szConsFieldId, $aIncludeCustomFields) ) { if ( $this->_logStreamConfigObj->DBType == DB_PGSQL || $this->_logStreamConfigObj->DBType == DB_MSSQL ) $myDBQueryFields .= "Max(" . $myDBConsFieldName . ") AS " . $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", "; else // Default for other PDO Engines $myDBQueryFields .= $myDBConsFieldName . ", "; } } else if ( $bIncludeLogStreamFields ) { $myDBQueryFields = ""; foreach ( $this->_arrProperties as $myFieldName ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName]) ) { if ( $this->_logStreamConfigObj->DBType == DB_PGSQL || $this->_logStreamConfigObj->DBType == DB_MSSQL ) $myDBQueryFields .= "Max(" . $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ") AS " . $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", "; else // Default for other PDO Engines $myDBQueryFields .= $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", "; } } } else // Only Include ConsolidateField { if ( $this->_logStreamConfigObj->DBType == DB_PGSQL || $this->_logStreamConfigObj->DBType == DB_MSSQL ) $myDBQueryFields = "Max(" . $myDBConsFieldName . ") as " . $myDBConsFieldName. ", "; else // Default for other PDO Engines $myDBQueryFields = $myDBConsFieldName . ", "; } // Add Min and Max fields for DATE if desired if ( $bIncludeMinMaxDateFields ) { $myDBQueryFields .= "Min(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ") as firstoccurrence_date, "; $myDBQueryFields .= "Max(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ") as lastoccurrence_date, "; } if ( $szConsFieldId == $szSortFieldId ) $myDBSortedFieldName = "itemcount"; else $myDBSortedFieldName = $szSortFieldId; // --- // Special handling for date fields if ( $nConsFieldType == FILTER_TYPE_DATE ) { if ( $this->_logStreamConfigObj->DBType == DB_MYSQL || $this->_logStreamConfigObj->DBType == DB_PGSQL ) { // Helper variable for the select statement $mySelectFieldName = $myDBGroupByFieldName . "Grouped"; $myDBQueryFieldName = "DATE( " . $myDBConsFieldName . ") AS " . $myDBGroupByFieldName ; } else if($this->_logStreamConfigObj->DBType == DB_MSSQL ) { // TODO FIND A WAY FOR MSSQL! // Helper variable for the select statement $mySelectFieldName = $myDBGroupByFieldName . "Grouped"; $myDBQueryFieldName = "DATE( " . $myDBConsFieldName . ") AS " . $myDBGroupByFieldName ; } } // Set Limit String if ( $nRecordLimit > 0 ) { // Append LIMIT in this case! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL || $this->_logStreamConfigObj->DBType == DB_PGSQL ) { $szLimitSqlBefore = ""; $szLimitSqlAfter = " LIMIT " . $nRecordLimit; } else if( $this->_logStreamConfigObj->DBType == DB_MSSQL ) { $szLimitSqlBefore = " TOP(" . $nRecordLimit . ") "; $szLimitSqlAfter = ""; } else { $szLimitSqlBefore = ""; $szLimitSqlAfter = ""; } } else { $szLimitSqlBefore = ""; $szLimitSqlAfter = ""; } // Create SQL String now! $szSql = "SELECT " . $szLimitSqlBefore . $myDBQueryFields . "count(" . $myDBConsFieldName . ") as itemcount " . " FROM " . $this->_logStreamConfigObj->DBTableName . $this->_SQLwhereClause . " GROUP BY " . $myDBGroupByFieldName . " ORDER BY " . $myDBSortedFieldName . " " . $szSortingOrder . $szLimitSqlAfter ; // Output Debug Informations OutputDebugMessage("LogStreamPDO|ConsolidateDataByField: Running Created SQL Query:
    " . $szSql, DEBUG_DEBUG); // Perform Database Query $this->_myDBQuery = $this->_dbhandle->query($szSql); if ( !$this->_myDBQuery ) return ERROR_DB_QUERYFAILED; if ( $this->_myDBQuery->rowCount() == 0 ) { $this->_myDBQuery = null; return ERROR_NOMORERECORDS; } // Initialize Array variable $aResult = array(); // read data records $iCount = 0; while ( ($myRow = $this->_myDBQuery->fetch(PDO::FETCH_ASSOC)) && ($nRecordLimit == 0 || $iCount < $nRecordLimit) ) { // Create new row $aNewRow = array(); foreach ( $myRow as $myFieldName => $myFieldValue ) { $myFieldID = $this->GetFieldIDbyDatabaseMapping($szTableType, $myFieldName); $aNewRow[ $myFieldID ] = $myFieldValue; /* if ( $myFieldName == $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId] ) $aNewRow[$szConsFieldId] = $myFieldValue; else $aNewRow[$myFieldName] = $myFieldValue; */ } // Add new row to result $aResult[] = $aNewRow; // Increment Counter $iCount++; } // Delete handle $this->_myDBQuery = null; // return finished array if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } /** * Implementation of GetCountSortedByField * * In the PDO DB Logstream, the database will do most of the work * * @return integer Error stat */ public function GetCountSortedByField($szFieldId, $nFieldType, $nRecordLimit) { global $content, $dbmapping; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId]) ) { // Set DB Field name first! $myDBFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId]; $myDBQueryFieldName = $myDBFieldName; $mySelectFieldName = $myDBFieldName; // Special handling for date fields if ( $nFieldType == FILTER_TYPE_DATE ) { if ( $this->_logStreamConfigObj->DBType == DB_MYSQL || $this->_logStreamConfigObj->DBType == DB_PGSQL ) { // Helper variable for the select statement $mySelectFieldName = $mySelectFieldName . "grouped"; $myDBQueryFieldName = "DATE( " . $myDBFieldName . ") AS " . $mySelectFieldName ; } else if($this->_logStreamConfigObj->DBType == DB_MSSQL ) { // TODO FIND A WAY FOR MSSQL! } } // Create SQL Where Clause! if ( $this->_SQLwhereClause == "" ) { $res = $this->CreateSQLWhereClause(); if ( $res != SUCCESS ) return $res; } // Create SQL String now! $szSql = "SELECT " . $myDBQueryFieldName . ", " . "count(" . $myDBFieldName . ") as totalcount " . " FROM " . $this->_logStreamConfigObj->DBTableName . $this->_SQLwhereClause . " GROUP BY " . $mySelectFieldName . " ORDER BY totalcount DESC"; // Append LIMIT in this case! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL || $this->_logStreamConfigObj->DBType == DB_PGSQL ) $szSql .= " LIMIT " . $nRecordLimit; // Perform Database Query $this->_myDBQuery = $this->_dbhandle->query($szSql); if ( !$this->_myDBQuery ) return ERROR_DB_QUERYFAILED; if ( $this->_myDBQuery->rowCount() == 0 ) { $this->_myDBQuery = null; return ERROR_NOMORERECORDS; } // Initialize Array variable $aResult = array(); // read data records $iCount = 0; while ( ($myRow = $this->_myDBQuery->fetch(PDO::FETCH_ASSOC)) && $iCount < $nRecordLimit) { if ( isset($myRow[$mySelectFieldName]) ) { $aResult[ $myRow[$mySelectFieldName] ] = $myRow['totalcount']; $iCount++; } } // Delete handle $this->_myDBQuery = null; // return finished array if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } else { // return error code, field mapping not found return ERROR_DB_DBFIELDNOTFOUND; } } /* * ============= Beginn of private functions ============= */ /* * This function expects the filters to already being set earlier. * Otherwise no usual WHERE Clause can be created! */ private function CreateSQLWhereClause() { if ( $this->_filters != null ) { global $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Reset WhereClause $this->_SQLwhereClause = ""; // --- Build Query Array $arrayQueryProperties = $this->_arrProperties; if ( isset($this->_arrFilterProperties) && $this->_arrFilterProperties != null) { foreach ( $this->_arrFilterProperties as $filterproperty ) { if ( $this->_arrProperties == null || !in_array($filterproperty, $this->_arrProperties) ) $arrayQueryProperties[] = $filterproperty; } } // --- // Loop through all available properties foreach( $arrayQueryProperties as $propertyname ) { // If the property exists in the filter array, we have something to filter for ^^! if ( array_key_exists($propertyname, $this->_filters) ) { // Process all filters foreach( $this->_filters[$propertyname] as $myfilter ) { // Only perform if database mapping is available for this filter! if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$propertyname]) ) { switch( $myfilter[FILTER_TYPE] ) { case FILTER_TYPE_STRING: // --- Either make a LIKE or a equal query! if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHFULL ) { // Set addnot to nothing $addnod = ""; // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) { $szSearchBegin = " = '"; $szSearchEnd = "' "; } else { $szSearchBegin = " <> '"; $szSearchEnd = "' "; } // --- } else if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHREGEX ) { //REGEXP Supported by MYSQL if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) { // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) $addnod = " "; else $addnod = " NOT"; // --- $szSearchBegin = "REGEXP '"; $szSearchEnd = "' "; } //REGEXP Supported by POSTGRESQL else if ( $this->_logStreamConfigObj->DBType == DB_PGSQL ) { // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) $addnod = " "; else $addnod = " !"; // --- $szSearchBegin = "~* '"; $szSearchEnd = "' "; } else //Fallback use LIKE { // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) $addnod = " "; else $addnod = " NOT"; // --- // Database Layer does not support REGEXP $szSearchBegin = "LIKE '%"; $szSearchEnd = "%' "; } } else { // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) $addnod = ""; else $addnod = " NOT"; // --- $szSearchBegin = " LIKE '%"; $szSearchEnd = "%' "; } // --- // --- If Syslog message, we have AND handling, otherwise OR! if ( $propertyname == SYSLOG_MESSAGE ) $addor = " AND "; else { // If we exclude filters, we need to combine with AND if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) $addor = " OR "; else $addor = " AND "; } // --- // Not create LIKE Filters if ( isset($tmpfilters[$propertyname]) ) $tmpfilters[$propertyname][FILTER_VALUE] .= $addor . $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . $addnod . $szSearchBegin . DB_RemoveBadChars($myfilter[FILTER_VALUE], $this->_logStreamConfigObj->DBType) . $szSearchEnd; else { $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_STRING; $tmpfilters[$propertyname][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . $addnod . $szSearchBegin . DB_RemoveBadChars($myfilter[FILTER_VALUE], $this->_logStreamConfigObj->DBType) . $szSearchEnd; } break; case FILTER_TYPE_NUMBER: // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_EXCLUDE ) { // Add to filterset $szArrayKey = $propertyname . "-NOT"; if ( isset($tmpfilters[$szArrayKey]) ) $tmpfilters[$szArrayKey][FILTER_VALUE] .= ", " . $myfilter[FILTER_VALUE]; else { $tmpfilters[$szArrayKey][FILTER_TYPE] = FILTER_TYPE_NUMBER; $tmpfilters[$szArrayKey][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " NOT IN (" . DB_RemoveBadChars($myfilter[FILTER_VALUE], $this->_logStreamConfigObj->DBType); } } else { // Add to filterset if ( isset($tmpfilters[$propertyname]) ) $tmpfilters[$propertyname][FILTER_VALUE] .= ", " . $myfilter[FILTER_VALUE]; else { $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_NUMBER; $tmpfilters[$propertyname][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " IN (" . DB_RemoveBadChars($myfilter[FILTER_VALUE], $this->_logStreamConfigObj->DBType); } } // --- break; case FILTER_TYPE_DATE: if ( isset($tmpfilters[$propertyname]) ) $tmpfilters[$propertyname][FILTER_VALUE] .= " AND "; else { $tmpfilters[$propertyname][FILTER_VALUE] = ""; $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_DATE; } if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { // Get current timestamp $nNowTimeStamp = time(); if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR ) $nNowTimeStamp -= 60 * 60; // One Hour! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_12HOURS ) $nNowTimeStamp -= 60 * 60 * 12; // 12 Hours! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_24HOURS ) $nNowTimeStamp -= 60 * 60 * 24; // 24 Hours! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_7DAYS ) $nNowTimeStamp -= 60 * 60 * 24 * 7; // 7 days else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_31DAYS ) $nNowTimeStamp -= 60 * 60 * 24 * 31; // 31 days else { // Set filter to unknown and Abort in this case! $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_UNKNOWN; break; } // Append filter $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $nNowTimeStamp) . "'"; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_FROM ) { // Obtain Event struct for the time! $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $myeventtime[EVTIME_TIMESTAMP]) . "'"; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_TO ) { // Obtain Event struct for the time! $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " < '" . date("Y-m-d H:i:s", $myeventtime[EVTIME_TIMESTAMP]) . "'"; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_DATE ) { // Obtain Event struct for the time! $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $myeventtime[EVTIME_TIMESTAMP]) . "' AND " . $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " < '" . date("Y-m-d H:i:s", ($myeventtime[EVTIME_TIMESTAMP]+86400) ) . "'"; } break; default: // Nothing to do! break; } } else { // Check how to treat not found db mappings / filters if ( GetConfigSetting("TreatNotFoundFiltersAsTrue", 0, CFGLEVEL_USER) == 0 ) return ERROR_DB_DBFIELDNOTFOUND; } } } } // Check and combine all filters now! if ( isset($tmpfilters) ) { // Append filters foreach( $tmpfilters as $tmpfilter ) { // Init WHERE or Append AND if ( strlen($this->_SQLwhereClause) > 0 ) $this->_SQLwhereClause .= " AND "; else $this->_SQLwhereClause = " WHERE "; switch( $tmpfilter[FILTER_TYPE] ) { case FILTER_TYPE_STRING: $this->_SQLwhereClause .= "( " . $tmpfilter[FILTER_VALUE] . ") "; break; case FILTER_TYPE_NUMBER: $this->_SQLwhereClause .= $tmpfilter[FILTER_VALUE] . ") "; break; case FILTER_TYPE_DATE: $this->_SQLwhereClause .= $tmpfilter[FILTER_VALUE]; break; default: // Should not happen, wrong filters! // We add a dummy into the where clause, just as a place holder $this->_SQLwhereClause .= " 1=1 "; break; } } } //echo $this->_SQLwhereClause; //$dbmapping[$szTableType][SYSLOG_UID] } else // No filters means nothing to do! return SUCCESS; } /* * Create the SQL QUery! */ private function CreateMainSQLQuery($uID) { global $querycount; // Get SQL Statement $szSql = $this->CreateSQLStatement($uID); // --- Append LIMIT if supported by the driver! Why the hell do we still have no unified solution for this crap in the sql language?! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) $szSql .= " LIMIT " . $this->_logStreamConfigObj->RecordsPerQuery; else if ( $this->_logStreamConfigObj->DBType == DB_PGSQL ) $szSql .= " LIMIT " . $this->_logStreamConfigObj->RecordsPerQuery; // --- // Perform Database Query $this->_myDBQuery = $this->_dbhandle->query($szSql); if ( !$this->_myDBQuery ) { // Check if a field is missing! if ( $this->_dbhandle->errorCode() == "42S22" || $this->_dbhandle->errorCode() == "42703" ) // 42S22 Means ER_BAD_FIELD_ERROR { // Handle missing field and try again! if ( $this->HandleMissingField() == SUCCESS ) { $this->_myDBQuery = $this->_dbhandle->query($szSql); if ( !$this->_myDBQuery ) { $this->PrintDebugError( "Invalid SQL: " . $szSql ); return ERROR_DB_QUERYFAILED; } } else // Failed to add field dynamically return ERROR_DB_QUERYFAILED; } else { $this->PrintDebugError( "Invalid SQL: " . $szSql); // . "

    Errorcode: " . $this->_dbhandle->errorCode() ); return ERROR_DB_QUERYFAILED; } } else { // Skip one entry in this case if ( $this->_currentRecordStart > 0 ) { // Throw away $myRow = $this->_myDBQuery->fetch(PDO::FETCH_ASSOC); } } // Increment for the Footer Stats $querycount++; // Output Debug Informations OutputDebugMessage("LogStreamDB|CreateMainSQLQuery: Created SQL Query:
    " . $szSql, DEBUG_DEBUG); // return success state if reached this point! return SUCCESS; } /* * Destroy the SQL QUery! */ private function DestroyMainSQLQuery() { // create query if necessary! if ( $this->_myDBQuery != null ) { // Free Query ressources $this->_myDBQuery->closeCursor(); $this->_myDBQuery = null; } // return success state if reached this point! return SUCCESS; } /* * This helper function will read the next records into the buffer. */ private function ReadNextRecordsFromDB($uID) { global $querycount; // Clear SQL Query first! $this->DestroyMainSQLQuery(); // return error if there was one! if ( ($res = $this->CreateMainSQLQuery($uID)) != SUCCESS ) return $res; // Check rowcount property only on supported drivers, others may always return 0 like oracle PDO Driver if ( $this->_logStreamConfigObj->DBType == DB_MYSQL || $this->_logStreamConfigObj->DBType == DB_MSSQL || $this->_logStreamConfigObj->DBType == DB_PGSQL ) { // return specially with NO RECORDS when 0 records are returned! Otherwise it will be -1 if ( $this->_myDBQuery->rowCount() == 0 ) return ERROR_NOMORERECORDS; } // Copy rows into the buffer! $iBegin = $this->_currentRecordNum; $iCount = 0; while( $this->_logStreamConfigObj->RecordsPerQuery > $iCount) { //Obtain next record $myRow = $this->_myDBQuery->fetch(PDO::FETCH_ASSOC); // Check if result was successfull! if ( $myRow === FALSE || !$myRow ) break; // Keys will be converted into lowercase! $this->bufferedRecords[$iBegin] = array_change_key_case($myRow); $iBegin++; // Increment counter $iCount++; } // --- Check if results were found if ( $iBegin == $this->_currentRecordNum ) return ERROR_NOMORERECORDS; // --- // Increment for the Footer Stats $querycount++; // return success state if reached this point! return SUCCESS; } /* * Creates the SQL Statement we are going to use! */ private function CreateSQLStatement($uID, $includeFields = true) { global $dbmapping; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; $szSortColumn = $this->_logStreamConfigObj->SortColumn; // Create Basic SQL String // if ( $this->_logStreamConfigObj->DBEnableRowCounting ) // with SQL_CALC_FOUND_ROWS // $sqlString = "SELECT SQL_CALC_FOUND_ROWS " . $dbmapping[$szTableType][SYSLOG_UID]; // else // without row calc $sqlString = "SELECT " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID]; // Append fields if needed if ( $includeFields && $this->_arrProperties != null ) { // Loop through all requested fields foreach ( $this->_arrProperties as $myproperty ) { // SYSLOG_UID already added! if ( $myproperty != SYSLOG_UID && isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) ) { // Append field! $sqlString .= ", " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]; } } } // Append FROM 'table'! $sqlString .= " FROM " . $this->_logStreamConfigObj->DBTableName; // Append precreated where clause $sqlString .= $this->_SQLwhereClause; // Append UID QUERY! if ( $uID != -1 ) { if ( $this->_readDirection == EnumReadDirection::Forward ) $myOperator = ">="; else $myOperator = "<="; if ( strlen($this->_SQLwhereClause) > 0 ) $sqlString .= " AND " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " $myOperator $uID"; else $sqlString .= " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " $myOperator $uID"; } // Append ORDER clause if ( $this->_readDirection == EnumReadDirection::Forward ) $sqlString .= " ORDER BY " . $dbmapping[$szTableType]['DBMAPPINGS'][$szSortColumn]; else if ( $this->_readDirection == EnumReadDirection::Backward ) $sqlString .= " ORDER BY " . $dbmapping[$szTableType]['DBMAPPINGS'][$szSortColumn] . " DESC"; //echo $sqlString; //exit; // return SQL result string: return $sqlString; } /* * Reset record buffer in this function! */ private function ResetBufferedRecords() { if ( isset($this->bufferedRecords) ) { // Loop through all subrecords first! foreach ($this->bufferedRecords as $mykey => $myrecord) unset( $this->bufferedRecords[$mykey] ); // Set buffered records to NULL! $this->bufferedRecords = null; } } /* * Helper function to display SQL Errors for now! */ private function PrintDebugError($szErrorMsg) { global $extraErrorDescription; $errdesc = $this->_dbhandle == null ? "" : implode( ";", $this->_dbhandle->errorInfo() ); $errno = $this->_dbhandle == null ? "" : $this->_dbhandle->errorCode(); $errormsg="$szErrorMsg
    "; $errormsg.="Detail error: $errdesc
    "; $errormsg.="Error Code: $errno
    "; // Add to additional error output $extraErrorDescription = $errormsg; //Output! OutputDebugMessage("LogStreamPDO|PrintDebugError: $errormsg", DEBUG_ERROR); } /* * Returns the number of possible records by using a select count statement! */ private function GetRowCountFromTable() { /* if ( $myquery = mysql_query("Select FOUND_ROWS();", $this->_dbhandle) ) { // Get first and only row! $myRow = mysql_fetch_array($myquery); // copy row count $numRows = $myRow[0]; } else $numRows = -1; */ /* OLD slow code! */ global $dbmapping,$querycount; $szTableType = $this->_logStreamConfigObj->DBTableType; // Create Statement and perform query! $szSql = "SELECT count(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") FROM " . $this->_logStreamConfigObj->DBTableName . $this->_SQLwhereClause; $myQuery = $this->_dbhandle->query($szSql); if ($myQuery) { // obtain first and only row $myRow = $myQuery->fetchColumn(); $numRows = $myRow; // $myRow[0]; // Increment for the Footer Stats $querycount++; // Free query now $myQuery->closeCursor(); } else { $this->PrintDebugError("RowCount query failed: " . $szSql); $numRows = -1; } // return result! return $numRows; } /* * Function handles missing database fields automatically! */ private function HandleMissingField( $szMissingField = null, $arrProperties = null ) { global $dbmapping, $fields; // Get Err description $errdesc = $this->_dbhandle->errorInfo(); // Try to get missing field from SQL Error of not specified as argument if ( $szMissingField == null ) { // check matching of error msg! if ( preg_match("/Unknown column '(.*?)' in '(.*?)'$/", $errdesc[2], $errOutArr ) || // MySQL preg_match("/column \"(.*?)\" does not exist/", $errdesc[2], $errOutArr ) || // PostgreSQL preg_match("/Invalid column name '(.*?)'/", $errdesc[2], $errOutArr ) // MSSQL // ERROR: column "checksum" does not exist LINE 1: ... eventsource, eventcategory, eventuser, systemid, checksum, ... ^ ) { $szMissingField = $errOutArr[1]; } else { $this->PrintDebugError("ER_BAD_FIELD_ERROR - SQL Statement: ". $errdesc[2]); return ERROR_DB_DBFIELDNOTFOUND; } } // Set Properties to default if NULL if ( $arrProperties == null ) $arrProperties = $this->_arrProperties; // Get Tabletype $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperties as $myproperty ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && $szMissingField == $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] ) { $szUpdateSql = ""; if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) { // MYSQL Statements if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_NUMBER ) $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` int(11) NOT NULL DEFAULT '0'"; if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_STRING ) $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` varchar(60) NULL"; if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_DATE ) $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'"; } else if ( $this->_logStreamConfigObj->DBType == DB_PGSQL ) { // MYSQL Statements if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_NUMBER ) $szUpdateSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " ADD " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " int NOT NULL DEFAULT '0'"; if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_STRING ) $szUpdateSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " ADD " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " varchar(60) NULL"; if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_DATE ) $szUpdateSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " ADD " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " timestamp without time zone NULL"; } else if ( $this->_logStreamConfigObj->DBType == DB_MSSQL ) { // MYSQL Statements if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_NUMBER ) $szUpdateSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " ADD " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " INT NOT NULL DEFAULT '0'"; if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_STRING ) $szUpdateSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " ADD " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " VARCHAR(60) NULL"; if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_DATE ) $szUpdateSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " ADD " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'"; } // Run SQL Command to add the missing field! if ( strlen($szUpdateSql) > 0 ) { // Update Table schema now! $myQuery = $this->_dbhandle->query($szUpdateSql); if (!$myQuery) { // Return failure! $this->PrintDebugError("ER_BAD_FIELD_ERROR - Dynamically Adding field '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' with Statement failed: '" . $szUpdateSql . "'"); return ERROR_DB_DBFIELDNOTFOUND; } else // Free query now $myQuery->closeCursor(); } else { // Return failure! $this->PrintDebugError("ER_BAD_FIELD_ERROR - Field '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' is missing and failed to be added automatically! The fields has to be added manually to the database layout!'"); global $extraErrorDescription; $extraErrorDescription = "Field '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' was missing and has been automatically added to the database layout."; return ERROR_DB_DBFIELDNOTFOUND; } } } // Reached this point means success! return SUCCESS; } /* * Helper function to return a list of Indexes for the logstream table */ private function GetIndexesAsArray() { global $querycount; // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Init Array $arrIndexKeys = array(); // Create SQL and Get INDEXES for table! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) $szSql = "SHOW INDEX FROM `" . $this->_logStreamConfigObj->DBTableName . "`"; else if ( $this->_logStreamConfigObj->DBType == DB_PGSQL ) $szSql = "SELECT c.relname AS \"Key_name\" FROM pg_catalog.pg_class c JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid JOIN pg_catalog.pg_class t ON i.indrelid = t.oid WHERE c.relkind = 'i' AND t.relname = 'systemevents' AND c.relname LIKE '%idx%'"; else if ( $this->_logStreamConfigObj->DBType == DB_MSSQL ) $szSql = "SELECT sysindexes.name AS Key_name FROM sysobjects, sysindexes WHERE sysobjects.xtype='U' AND sysindexes.id=object_id(sysobjects.name) and sysobjects.name='" . $this->_logStreamConfigObj->DBTableName . "' ORDER BY sysobjects.name ASC"; else // Not supported in this case! return null; OutputDebugMessage("LogStreamPDO|GetIndexesAsArray: List Indexes for '" . $this->_logStreamConfigObj->DBTableName . "' - " . $szSql, DEBUG_ULTRADEBUG); $myQuery = $this->_dbhandle->query($szSql); if ($myQuery) { // Loop through results while ( $myRow = $myQuery->fetch(PDO::FETCH_ASSOC) ) { // Add to index keys if ( $this->_logStreamConfigObj->DBType == DB_PGSQL || $this->_logStreamConfigObj->DBType == DB_MSSQL ) $arrIndexKeys[] = str_replace( "_idx", "", strtolower($myRow['Key_name']) ); else $arrIndexKeys[] = strtolower($myRow['Key_name']); } // Free query now $myQuery->closeCursor(); // Increment for the Footer Stats $querycount++; } // return Array return $arrIndexKeys; } /* * Helper function to return a list of Fields from the logstream table */ private function GetFieldsAsArray() { global $querycount; // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Init Array $arrFieldKeys = array(); // Create SQL and Get FIELDS for table! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) $szSql = "SHOW FIELDS FROM `" . $this->_logStreamConfigObj->DBTableName . "`"; else if ( $this->_logStreamConfigObj->DBType == DB_PGSQL ) $szSql = "SELECT column_name as \"Field\" FROM information_schema.COLUMNS WHERE table_name = '" . $this->_logStreamConfigObj->DBTableName . "'"; else if ( $this->_logStreamConfigObj->DBType == DB_MSSQL ) $szSql = "SELECT syscolumns.name AS Field FROM sysobjects JOIN syscolumns ON sysobjects.id = syscolumns.id WHERE sysobjects.xtype='U' AND sysobjects.name='" . $this->_logStreamConfigObj->DBTableName . "'"; else // Not supported in this case! return null; OutputDebugMessage("LogStreamPDO|GetFieldsAsArray: List Columns for '" . $this->_logStreamConfigObj->DBTableName . "' - " . $szSql, DEBUG_ULTRADEBUG); $myQuery = $this->_dbhandle->query($szSql); if ($myQuery) { // Loop through results while ( $myRow = $myQuery->fetch(PDO::FETCH_ASSOC) ) { // Add to index keys $arrFieldKeys[] = strtolower($myRow['Field']); } // Free query now $myQuery->closeCursor(); // Increment for the Footer Stats $querycount++; } else $this->PrintDebugError("ERROR_DB_QUERYFAILED - GetFieldsAsArray SQL '" . $szSql . "' failed!"); // return Array return $arrFieldKeys; } /* * Helper function to return a list of Indexes for the logstream table */ private function GetTriggersAsArray() { global $querycount; // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Init Array $arrIndexTriggers = array(); // Create SQL and Get INDEXES for table! if ( $this->_logStreamConfigObj->DBType == DB_MYSQL ) $szSql = "SHOW TRIGGERS"; else if ( $this->_logStreamConfigObj->DBType == DB_PGSQL ) $szSql = "SELECT tgname as \"Trigger\" from pg_trigger;"; else if ( $this->_logStreamConfigObj->DBType == DB_MSSQL ) $szSql = "SELECT B.Name as TableName,A.name AS 'Trigger' FROM sysobjects A,sysobjects B WHERE A.xtype='TR' AND A.parent_obj = B.id"; // AND B.Name='systemevents'"; else // Not supported in this case! return null; OutputDebugMessage("LogStreamPDO|GetTriggersAsArray: List Triggers for '" . $this->_logStreamConfigObj->DBTableName . "' - " . $szSql, DEBUG_ULTRADEBUG); $myQuery = $this->_dbhandle->query($szSql); if ($myQuery) { // Loop through results while ( $myRow = $myQuery->fetch(PDO::FETCH_ASSOC) ) { // Add to index keys $arrIndexTriggers[] = strtolower($myRow['Trigger']); } // Free query now $myQuery->closeCursor(); // Increment for the Footer Stats $querycount++; } // return Array return $arrIndexTriggers; } // --- End of Class! } ?>loganalyzer-3.6.5/src/classes/msgparsers/0000755000175000017500000000000012225177166017751 5ustar danieldanielloganalyzer-3.6.5/src/classes/msgparsers/msgparser.eventlog.class.php0000644000175000017500000001011112225176641025402 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'classes/msgparser.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- class MsgParser_eventlog extends MsgParser { // Public Information properties public $_ClassName = 'Adiscon Eventlog Format'; public $_ClassDescription = 'This is a parser for a special format which can be created with Adiscon Eventreporter or MonitorWare Agent.'; public $_ClassRequiredFields = null; public $_ClassHelpArticle = "http://www.monitorware.com/en/Articles/"; // Constructor public function MsgParser_eventlog() { return; // Nothing } /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public function ParseMsg($szMsg, &$arrArguments) { global $content, $fields; //trim the msg first to remove spaces from begin and end $szMsg = trim($szMsg); // Sample (WinSyslog/EventReporter): 7035,XPVS2005\Administrator,Service Control Manager,System,[INF],0,The Adiscon EvntSLog service was successfully sent a start control. // Source: %id%,%user%,%sourceproc%,%NTEventLogType%,%severity%,%category%,%msg%%$CRLF% if ( preg_match("/([0-9]{1,12}),(.*?),(.*?),(.*?),(.*?),([0-9]{1,12}),(.*?)$/", $szMsg, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_EVENT_ID] = $out[1]; $arrArguments[SYSLOG_EVENT_USER] = $out[2]; $arrArguments[SYSLOG_EVENT_SOURCE] = $out[3]; $arrArguments[SYSLOG_EVENT_LOGTYPE] = $out[4]; /// $arrArguments[SYSLOG_SEVERITY] = $out[5]; $arrArguments[SYSLOG_EVENT_CATEGORY] = $out[6]; $arrArguments[SYSLOG_MESSAGE] = $out[7]; if ( $this->_MsgNormalize == 1 ) { //Init tmp msg $szTmpMsg = ""; // Create Field Array to prepend into msg! Reverse Order here $myFields = array( SYSLOG_MESSAGE, SYSLOG_EVENT_CATEGORY, SYSLOG_EVENT_LOGTYPE, SYSLOG_EVENT_SOURCE, SYSLOG_EVENT_USER, SYSLOG_EVENT_ID ); foreach ( $myFields as $myField ) { // Set Field Caption if ( isset($fields[$myField]['FieldCaption']) ) $szFieldName = $fields[$myField]['FieldCaption']; else $szFieldName = $myField; // Append Field into msg $szTmpMsg = $szFieldName . ": '" . $arrArguments[$myField] . "'\n" . $szTmpMsg; } // copy finished MSG back! $arrArguments[SYSLOG_MESSAGE] = $szTmpMsg; } } else { // return no match in this case! return ERROR_MSG_NOMATCH; } // Set IUT Property if success! $arrArguments[SYSLOG_MESSAGETYPE] = IUT_NT_EventReport; // If we reached this position, return success! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/msgparsers/msgparser.apache2.class.php0000644000175000017500000001225412225176641025074 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'classes/msgparser.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- class MsgParser_apache2 extends MsgParser { // Public Information properties public $_ClassName = 'Apache 2 Combined Format'; public $_ClassDescription = 'Parses the combined logfile format from Apache2 webservers.'; public $_ClassRequiredFields = null; public $_ClassHelpArticle = "http://www.monitorware.com/Common/en/Articles/setup_mwagent_webserverlogging_phplogcon_mysql.php"; // Constructor public function MsgParser_apache2() { return; // Nothing } /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public function ParseMsg($szMsg, &$arrArguments) { global $content, $fields; //trim the msg first to remove spaces from begin and end $szMsg = trim($szMsg); //return ERROR_MSG_NOMATCH; // LogFormat "%h %l %u %t \"%r\" %>s %b" common // LogFormat "%{Referer}i -> %U" referer // LogFormat "%{User-agent}i" agent // LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined // Sample (apache2): 127.0.0.1 - - [14/Sep/2008:06:50:15 +0200] "GET / HTTP/1.0" 200 19023 "-" "VoilaBot link checker" // Sample: 65.55.211.112 - - [16/Sep/2008:13:37:47 +0200] "GET /index.php?name=News&file=article&sid=1&theme=Printer HTTP/1.1" 200 4908 "-" "msnbot/1.1 (+http://search.msn.com/msnbot.htm)" if ( preg_match('/(.|.*?) (.|.*?) (.|.*?) \[(.*?)\] "(.*?) (.*?) (.*?)" (.|[0-9]{1,12}) (.|[0-9]{1,12}) "(.|.*?)" "(.*?)("|)$/', $szMsg, $out ) ) { // print_r ( $out ); // exit; // Set generic properties $arrArguments[SYSLOG_HOST] = $out[1]; $arrArguments[SYSLOG_DATE] = GetEventTime($out[4]); // Set weblog specific properties! $arrArguments[SYSLOG_WEBLOG_USER] = $out[3]; $arrArguments[SYSLOG_WEBLOG_METHOD] = $out[5]; if ( strpos($out[6], "?") === false ) { $arrArguments[SYSLOG_WEBLOG_URL] = $out[6]; $arrArguments[SYSLOG_WEBLOG_QUERYSTRING]= ""; } else { $arrArguments[SYSLOG_WEBLOG_URL] = substr( $out[6], 0, strpos($out[6], "?")); $arrArguments[SYSLOG_WEBLOG_QUERYSTRING]= substr( $out[6], strpos($out[6], "?")+1 ); } // Number based fields $arrArguments[SYSLOG_WEBLOG_PVER] = $out[7]; $arrArguments[SYSLOG_WEBLOG_STATUS] = $out[8]; $arrArguments[SYSLOG_WEBLOG_BYTESSEND] = $out[9]; $arrArguments[SYSLOG_WEBLOG_REFERER] = $out[10]; $arrArguments[SYSLOG_WEBLOG_USERAGENT] = $out[11]; // Set msg to whole logline $arrArguments[SYSLOG_MESSAGE] = $out[0]; if ( $this->_MsgNormalize == 1 ) { //Init tmp msg $szTmpMsg = ""; // Create Field Array to prepend into msg! Reverse Order here $myFields = array( SYSLOG_WEBLOG_USER, SYSLOG_WEBLOG_PVER, SYSLOG_WEBLOG_USERAGENT, SYSLOG_WEBLOG_BYTESSEND, SYSLOG_WEBLOG_STATUS, SYSLOG_WEBLOG_REFERER, SYSLOG_WEBLOG_METHOD, SYSLOG_WEBLOG_QUERYSTRING, SYSLOG_WEBLOG_URL ); foreach ( $myFields as $myField ) { // Set Field Caption if ( isset($fields[$myField]['FieldCaption']) ) $szFieldName = $fields[$myField]['FieldCaption']; else $szFieldName = $myField; // Append Field into msg $szTmpMsg = $szFieldName . ": '" . $arrArguments[$myField] . "'\n" . $szTmpMsg; } // copy finished MSG back! $arrArguments[SYSLOG_MESSAGE] = $szTmpMsg; } } else { // return no match in this case! return ERROR_MSG_NOMATCH; } // Set IUT Property if success! $arrArguments[SYSLOG_MESSAGETYPE] = IUT_WEBSERVERLOG; // If we reached this position, return success! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/msgparsers/msgparser.iis.class.php0000644000175000017500000001321012225176641024346 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'classes/msgparser.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- class MsgParser_iis extends MsgParser { // Public Information properties public $_ClassName = 'Microsoft IIS Weblogs'; public $_ClassDescription = 'Parses the common weblog format used by the Microsoft IIS webserver.'; public $_ClassRequiredFields = null; public $_ClassHelpArticle = "http://www.monitorware.com/en/Articles/"; // Constructor public function MsgParser_iis() { return; // Nothing } /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public function ParseMsg($szMsg, &$arrArguments) { global $content, $fields; //trim the msg first to remove spaces from begin and end $szMsg = trim($szMsg); // $iSharpPos = strpos($szMsg, "#"); // if ( $iSharpPos !== false && $iSharpPos == 0 ) // return ERROR_MSG_SKIPMESSAGE; // Special case here, if loglines start with #, they are comments and have to be skipped! if ( ($iSharpPos = strpos($szMsg, "#")) !== false && $iSharpPos == 0 ) { // Only init fields then // Set generic properties $arrArguments[SYSLOG_DATE] = ""; $arrArguments[SYSLOG_HOST] = ""; // Set weblog specific properties! $arrArguments[SYSLOG_WEBLOG_METHOD] = ""; $arrArguments[SYSLOG_WEBLOG_URL] = ""; $arrArguments[SYSLOG_WEBLOG_QUERYSTRING] = ""; $arrArguments[SYSLOG_WEBLOG_USER] = ""; $arrArguments[SYSLOG_WEBLOG_PVER] = ""; $arrArguments[SYSLOG_WEBLOG_USERAGENT] = ""; $arrArguments[SYSLOG_WEBLOG_REFERER] = ""; $arrArguments[SYSLOG_WEBLOG_STATUS] = ""; $arrArguments[SYSLOG_WEBLOG_BYTESSEND] = ""; // Set msg to whole logline $arrArguments[SYSLOG_MESSAGE] = $szMsg; } // LogFormat: date time cs-method cs-uri-stem cs-uri-query cs-username c-ip cs-version cs(User-Agent) cs(Referer) sc-status sc-bytes // Sample: 2008-09-17 00:15:24 GET /Include/MyStyleV2.css - - 208.111.154.249 HTTP/1.0 Mozilla/5.0+(X11;+U;+Linux+i686+(x86_64);+en-US;+rv:1.8.1.11)+Gecko/20080109+(Charlotte/0.9t;+http://www.searchme.com/support/) http://www.adiscon.com/Common/en/News/MWCon-2005-09-12.php 200 1812 if ( preg_match('/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) (.*?) (.|.*?) (.|.*?) (.|.*?) (.|.*?) (.|.*?) (.|.*?) (.|.*?) (.|.*?) (.|.*?)$/', $szMsg, $out ) ) { // print_r ( $out ); // exit; // Set generic properties $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_HOST] = $out[6]; // Set weblog specific properties! $arrArguments[SYSLOG_WEBLOG_METHOD] = $out[2]; $arrArguments[SYSLOG_WEBLOG_URL] = $out[3]; $arrArguments[SYSLOG_WEBLOG_QUERYSTRING]= $out[4]; $arrArguments[SYSLOG_WEBLOG_USER] = $out[5]; $arrArguments[SYSLOG_WEBLOG_PVER] = $out[7]; $arrArguments[SYSLOG_WEBLOG_USERAGENT] = $out[8]; $arrArguments[SYSLOG_WEBLOG_REFERER] = $out[9]; $arrArguments[SYSLOG_WEBLOG_STATUS] = $out[10]; $arrArguments[SYSLOG_WEBLOG_BYTESSEND] = $out[11]; // Set msg to whole logline $arrArguments[SYSLOG_MESSAGE] = $out[0]; if ( $this->_MsgNormalize == 1 ) { //Init tmp msg $szTmpMsg = ""; // Create Field Array to prepend into msg! Reverse Order here $myFields = array( SYSLOG_WEBLOG_USER, SYSLOG_WEBLOG_PVER, SYSLOG_WEBLOG_USERAGENT, SYSLOG_WEBLOG_BYTESSEND, SYSLOG_WEBLOG_STATUS, SYSLOG_WEBLOG_REFERER, SYSLOG_WEBLOG_METHOD, SYSLOG_WEBLOG_QUERYSTRING, SYSLOG_WEBLOG_URL ); foreach ( $myFields as $myField ) { // Set Field Caption if ( isset($fields[$myField]['FieldCaption']) ) $szFieldName = $fields[$myField]['FieldCaption']; else $szFieldName = $myField; // Append Field into msg $szTmpMsg = $szFieldName . ": '" . $arrArguments[$myField] . "'\n" . $szTmpMsg; } // copy finished MSG back! $arrArguments[SYSLOG_MESSAGE] = $szTmpMsg; } } else { // return no match in this case! return ERROR_MSG_NOMATCH; } // Set IUT Property if success! $arrArguments[SYSLOG_MESSAGETYPE] = IUT_WEBSERVERLOG; // If we reached this position, return success! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/msgparsers/msgparser.apache2common.class.php0000644000175000017500000001166712225176641026314 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'classes/msgparser.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- class MsgParser_apache2common extends MsgParser { // Public Information properties public $_ClassName = 'Apache 2 Common Format'; public $_ClassDescription = 'Parses the common logfile format from Apache2 webservers.'; public $_ClassRequiredFields = null; public $_ClassHelpArticle = "http://www.monitorware.com/Common/en/Articles/setup_mwagent_webserverlogging_phplogcon_mysql.php"; // Constructor public function MsgParser_apache2common() { return; // Nothing } /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public function ParseMsg($szMsg, &$arrArguments) { global $content, $fields; //trim the msg first to remove spaces from begin and end $szMsg = trim($szMsg); //return ERROR_MSG_NOMATCH; // LogFormat "%h %l %u %t \"%r\" %>s %b" common // LogFormat "%{Referer}i -> %U" referer // LogFormat "%{User-agent}i" agent // LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined // Sample (apache2): 127.0.0.1 - - [14/Sep/2008:06:50:15 +0200] "GET / HTTP/1.0" 200 19023 // Sample: 65.55.211.112 - - [16/Sep/2008:13:37:47 +0200] "GET /index.php?name=News&file=article&sid=1&theme=Printer HTTP/1.1" 200 4908 if ( preg_match('/(.|.*?) (.|.*?) (.|.*?) \[(.*?)\] "(.*?) (.*?) (.*?)" (.|[0-9]{1,12}) (.|[0-9]{1,12})$/', $szMsg, $out ) ) { // print_r ( $out ); // exit; // Set generic properties $arrArguments[SYSLOG_HOST] = $out[1]; $arrArguments[SYSLOG_DATE] = GetEventTime($out[4]); // Set weblog specific properties! $arrArguments[SYSLOG_WEBLOG_USER] = $out[3]; $arrArguments[SYSLOG_WEBLOG_METHOD] = $out[5]; if ( strpos($out[6], "?") === false ) { $arrArguments[SYSLOG_WEBLOG_URL] = $out[6]; $arrArguments[SYSLOG_WEBLOG_QUERYSTRING]= ""; } else { $arrArguments[SYSLOG_WEBLOG_URL] = substr( $out[6], 0, strpos($out[6], "?")); $arrArguments[SYSLOG_WEBLOG_QUERYSTRING]= substr( $out[6], strpos($out[6], "?")+1 ); } // Number based fields $arrArguments[SYSLOG_WEBLOG_PVER] = $out[7]; $arrArguments[SYSLOG_WEBLOG_STATUS] = $out[8]; $arrArguments[SYSLOG_WEBLOG_BYTESSEND] = $out[9]; // Set msg to whole logline $arrArguments[SYSLOG_MESSAGE] = $out[0]; if ( $this->_MsgNormalize == 1 ) { //Init tmp msg $szTmpMsg = ""; // Create Field Array to prepend into msg! Reverse Order here $myFields = array( SYSLOG_WEBLOG_USER, SYSLOG_WEBLOG_PVER, SYSLOG_WEBLOG_BYTESSEND, SYSLOG_WEBLOG_STATUS, SYSLOG_WEBLOG_METHOD, SYSLOG_WEBLOG_QUERYSTRING, SYSLOG_WEBLOG_URL ); foreach ( $myFields as $myField ) { // Set Field Caption if ( isset($fields[$myField]['FieldCaption']) ) $szFieldName = $fields[$myField]['FieldCaption']; else $szFieldName = $myField; // Append Field into msg $szTmpMsg = $szFieldName . ": '" . $arrArguments[$myField] . "'\n" . $szTmpMsg; } // copy finished MSG back! $arrArguments[SYSLOG_MESSAGE] = $szTmpMsg; } } else { // return no match in this case! return ERROR_MSG_NOMATCH; } // Set IUT Property if success! $arrArguments[SYSLOG_MESSAGETYPE] = IUT_WEBSERVERLOG; // If we reached this position, return success! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/logstreamdisk.class.php0000644000175000017500000006733612225176641022264 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Required Includes! require_once($gl_root_path . 'include/constants_errors.php'); // --- class LogStreamDisk extends LogStream { private $_currentOffset = -1; private $_currentStartPos = -1; private $_fp = null; private $_bEOS = false; const _BUFFER_length = 8192; private $_buffer = false; private $_buffer_length = 0; private $_p_buffer = -1; private $_previousPageUID = -1; private $_lastPageUID = -1; // Constructor public function LogStreamDisk($streamConfigObj) { $this->_logStreamConfigObj = $streamConfigObj; } /** * Open the file with read access. * * @param arrProperties array in: Properties wish list. * @return integer Error stat */ public function Open($arrProperties) { // Initialise Basic stuff within the Classs $this->RunBasicInits(); // Check if file exists! $result = $this->Verify(); if ( $result != SUCCESS) return $result; // Now open the file $this->_fp = fopen($this->_logStreamConfigObj->FileName, 'r'); $this->_currentOffset = ftell($this->_fp); $this->_currentStartPos = $this->_currentOffset; $this->_arrProperties = $arrProperties; return SUCCESS; } /** * Close the file. * * @return integer Error state */ public function Close() { if ( isset($this->_fp) ) { if (!fclose($this->_fp)) { return ERROR_FILE_CANT_CLOSE; } } // return result return SUCCESS; } /** * Verify if the file exists! * * @return integer Error state */ public function Verify() { global $content; // --- Check if Filename is within allowed directories! $szFileDirName = dirname($this->_logStreamConfigObj->FileName) . '/'; $bIsAllowedDir = false; foreach($content['DiskAllowed'] as $szAllowedDir) { if ( strpos($szFileDirName, $szAllowedDir) !== FALSE ) { $bIsAllowedDir = true; break; } } if ( !$bIsAllowedDir ) { global $extraErrorDescription; $extraErrorDescription = GetAndReplaceLangStr( $content['LN_ERROR_PATH_NOT_ALLOWED_EXTRA'], $this->_logStreamConfigObj->FileName, implode(", ", $content['DiskAllowed']) ); return ERROR_PATH_NOT_ALLOWED; } // --- // Check if file exists! if(!file_exists($this->_logStreamConfigObj->FileName)) { return ERROR_FILE_NOT_FOUND; } // Check if file is readable! if(!is_readable($this->_logStreamConfigObj->FileName)) { return ERROR_FILE_NOT_READABLE; } // reached this point means success ;)! return SUCCESS; } private function ReadNextBlock() { $this->_bEOS = false; $bCheckForLastLf = false; if ($this->_readDirection == EnumReadDirection::Backward) { // in this case we have to adjust a few settings $this->_p_buffer = self::_BUFFER_length ; // set the point to the right index // first of all, check if this is the first read if ($this->_buffer == false) { // this means that we have to read from the end fseek($this->_fp, 0, SEEK_END); $this->_currentOffset = ftell($this->_fp); $this->_p_buffer -= 1; // eat EOF $bCheckForLastLf = true; } $orig_offset = ftell($this->_fp) - $this->_buffer_length; if ($orig_offset <= 0) { // apparently we are at BOF so nothing to read return ERROR_EOS; } // jumb to the new position $orig_offset -= self::_BUFFER_length; if ($orig_offset <= 0) { // ok, we have to adjust the buffer pointer $this->_p_buffer += $orig_offset; // note orig_offset is negative, see if $orig_offset = 0; } fseek($this->_fp, $orig_offset); } else { $this->_p_buffer = 0; } $this->_buffer = fread($this->_fp, self::_BUFFER_length); $this->_buffer_length = strlen($this->_buffer); if ($bCheckForLastLf && $this->_buffer[$this->_p_buffer] == "\n") { // skip it (can only occur if you read backwards) $this->_p_buffer--; $this->_currentOffset--; } if ($this->_buffer == false) return ERROR_FILE_EOF; return SUCCESS; } /** * Read the data from a specific uID which means in this * case from a given offset of the file. * * @param uID integer in/out: unique id of the data row * @param arrProperitesOut array out: array filled with properties * @return integer Error state * @see ReadNext() */ public function Read($uID, &$arrProperitesOut) { $this->Sseek($uID, EnumSeek::UID, 0); $tmp = $this->_readDirection; $this->_readDirection = EnumReadDirection::Forward; $ret = $this->ReadNext($uID, $arrProperitesOut); if ($tmp == EnumReadDirection::Backward) { $this->_p_buffer -= 2; $this->_currentStartPos = $this->_currentOffset -= 1; $this->_readDirection = $tmp; // we have to skip one line that we are back on the right position $this->ReadNext($dummy1, $dummy2); } return $ret; } /** * Read the next line from the file depending on the current * read direction. * * Hint: If the current stream becomes unavailable an error * stated is retuned. A typical case is if a log rotation * changed the original data source. * * @param uID integer out: uID is the offset of data row * @param arrProperitesOut array out: properties * @return integer Error state * @see ReadNext */ public function ReadNext(&$uID, &$arrProperitesOut, $bParseMessage = true) { global $content, $gl_starttime; do { // Read next entry first! if ($this->_readDirection == EnumReadDirection::Forward) $ret = $this->ReadNextForwards($uID, $arrProperitesOut); else $ret = $this->ReadNextBackwards($uID, $arrProperitesOut); // Only PARSE on success! if ( $ret == SUCCESS && $bParseMessage) { // Line Parser Hook here $retParser = $this->_logStreamConfigObj->_lineParser->ParseLine($arrProperitesOut[SYSLOG_MESSAGE], $arrProperitesOut); // Run optional Message Parsers now $retParser = $this->_logStreamConfigObj->ProcessMsgParsers($arrProperitesOut[SYSLOG_MESSAGE], $arrProperitesOut); // Check if we have to skip the message! if ( $retParser == ERROR_MSG_SKIPMESSAGE ) $ret = $retParser; // Set uID to the PropertiesOut! $arrProperitesOut[SYSLOG_UID] = $uID; } // Check how long we are running. If only two seconds of execution time are left, we abort further reading! $scriptruntime = intval(microtime_float() - $gl_starttime); if ( $content['MaxExecutionTime'] > 0 && $scriptruntime > ($content['MaxExecutionTime']-2) ) { // This may display a warning message, so the user knows we stopped reading records because of the script timeout. $content['logstream_warning'] = "false"; $content['logstream_warning_details'] = $content['LN_WARNING_LOGSTREAMDISK_TIMEOUT']; $content['logstream_warning_code'] = ERROR_FILE_NOMORETIME; // Return error code return ERROR_FILE_NOMORETIME; } // Loop until the filter applies, or another error occurs, and we still have TIME! } while ( $this->ApplyFilters($ret, $arrProperitesOut) != SUCCESS && $ret == SUCCESS ); // reached here means return result! return $ret; } private function ReadNextForwards(&$uID, &$arrProperitesOut) { if ($this->_bEOS) { return ERROR_EOS; } if ($this->_p_buffer < 0) { // init read $this->ReadNextBlock(); } if (($this->_p_buffer == $this->_buffer_length || $this->_p_buffer == -1) && ($this->ReadNextBlock() != SUCCESS)) { return ERROR_UNDEFINED; } // Init variables dynamically $line = ''; if ( $this->_arrProperties != null ) { foreach ( $this->_arrProperties as $property ) $arrProperitesOut[$property] = ''; } do { $pos = -1; if (($pos = strpos($this->_buffer, "\n", $this->_p_buffer)) !== false) { $uID = $this->_currentStartPos; $logLine = $line . substr($this->_buffer, $this->_p_buffer, $pos - $this->_p_buffer); $arrProperitesOut[SYSLOG_MESSAGE] = $logLine; // the buffer pointer currently points to the linefeed // so we have to increment the pointer to eat it $this->_currentOffset += $pos - $this->_p_buffer + 1; $this->_p_buffer = $pos + 1; $this->_currentStartPos = $this->_currentOffset; return SUCCESS; } $line .= substr($this->_buffer, $this->_p_buffer, $this->_buffer_length - $this->_p_buffer); $this->_currentOffset += $this->_buffer_length - $this->_p_buffer; } while ($this->ReadNextBlock() == SUCCESS); if ( strlen($line) > 0 ) { $uID = $this->_currentStartPos; $arrProperitesOut[SYSLOG_MESSAGE] = $line; $this->_currentStartPos = $this->_currentOffset; return SUCCESS; } return ERROR_UNDEFINED; } private function ReadNextBackwards(&$uID, &$arrProperitesOut) { if ($this->_bEOS) { return ERROR_EOS; } if ($this->_p_buffer < 0) { // a negative buffer means that the we have to adjust // the offset $this->_currentOffset++; if ($this->ReadNextBlock() != SUCCESS) { return ERROR_UNDEFINED; } } // Init variables dynamically $line = ''; foreach ( $this->_arrProperties as $property ) $arrProperitesOut[$property] = ''; do { $pos = -1; $neg_offset = ($this->_buffer_length - $this->_p_buffer) * -1; if (($pos = strrpos($this->_buffer, "\n", $neg_offset)) !== false) { // note that we are at the position of the linefeed, // this is recognize in the next few calculation $uID = $this->_currentOffset -= $this->_p_buffer - $pos; $arrProperitesOut[SYSLOG_MESSAGE] = substr($this->_buffer, $pos + 1, $this->_p_buffer - $pos) . $line; $this->_currentOffset--; // eat the lf $this->_p_buffer = $pos - 1; return SUCCESS; } $line = substr($this->_buffer, 0, $this->_p_buffer) . $line; $this->_currentOffset -= $this->_p_buffer; } while ($this->ReadNextBlock() == SUCCESS); if ( strlen($line) > 0 ) { // this case should only happend if we are on BOF $this->_bEOS = true; $uID = 0; $arrProperitesOut[SYSLOG_MESSAGE] = $line; return SUCCESS; } return ERROR_EOS; } /** * Implementation of Seek */ public function Sseek(&$uID, $mode, $numrecs) { // in any case we reset the buffer $this->ResetBuffer(); $ret = -1; switch ($mode) { case EnumSeek::BOS: $ret = fseek($this->_fp, 0); $this->_currentOffset = $this->_currentStartPos = 0; break; case EnumSeek::EOS: // a simple ReadNextBackup will do all the work // for us, because we have reset the buffer // remember the current readDirection $tmp = $this->_readDirection; $this->_readDirection = EnumReadDirection::Backward; $ret = $this->ReadNextBackwards($uID, $dummy2); if ($tmp == EnumReadDirection::Forward) { // in this case we have to correct the buffer, // because we have read backwards even the current // readDirection is forwards $this->_p_buffer += 2; $this->_currentStartPos = $this->_currentOffset; } $this->_readDirection = $tmp; break; case EnumSeek::UID: $ret = fseek($this->_fp, $uID); $this->_currentOffset = $this->_currentStartPos = $uID; break; } if ($ret != SUCCESS) return ERROR_UNDEFINED; return $this->Skip($uID, $numrecs); } /** * * @param numrecs integer in: If positiv, skip * @return uid integer Error state */ private function Skip($uID, $numrecs) { if ($numrecs == 0) return SUCCESS; if ($numrecs > 0) { /* due to performance reason we use php's fgets instead of ReadNext method while (!feof($this->_fp)) { fgets($this->_fp); $numrecs--; if ($numrecs == 0) { break; } $this->_currentOffset = ftell($this->_fp); } */ while ($this->ReadNextForwards($dummy1, $dummy2) == SUCCESS) { fgets($this->_fp); $numrecs--; //--- Extra check to set the correct $_previousPageUID! if ( $numrecs == $this->_logStreamConfigObj->_pageCount ) $this->_previousPageUID = $this->_currentOffset; //--- if ($numrecs == 0) { break; } $this->_currentOffset = ftell($this->_fp); } } else { while ($this->ReadNextBackwards($dummy1, $dummy2) == SUCCESS) { $numrecs++; //--- Extra check to set the correct $_previousPageUID! if ( $numrecs == $this->_logStreamConfigObj->_pageCount ) $this->_previousPageUID = $this->_currentOffset; //--- if ($numrecs == 0) { break; } } } // where we are? $uID = $this->_currentOffset; if ($numrecs != 0) { // obviously there were not enough records to skip return ERROR_NOMORERECORDS; } return SUCCESS; } /** * Set the filter for the current stream. * * @param filter object in: filter object * @return integer Error state public function SetFilter($filter) { return SUCCESS; } */ /** * GetMessageCount will always return -1 which means * that the message count is not available. We refuse * the request of the message count due to a count would * require to read the whole file which would be a big * pain if the file is e.g. 1 gb. */ public function GetMessageCount() { return -1; } /** * This function returns the first UID for previous PAGE, if availbale! * Otherwise will return -1! */ public function GetPreviousPageUID() { return $this->_previousPageUID; } /** * This function returns the FIRST UID for the FIRST PAGE! * NOT IMPLEMENTED RIGHT NOW! */ public function GetFirstPageUID() { return -1; } /** * This function returns the first UID for the last PAGE! * This is not possible in this logstream, so it always returns -1! */ public function GetLastPageUID() { // Only perform lastUID scan if there are NO filters, for performance REASONS! if ( $this->_filters != null ) return UID_UNKNOWN; // Helper variables $myuid = -1; $counter = 0; $tmpOldDirection = $this->_readDirection; // Store for later use $tmpuID = $this->_currentOffset+1; // Store for later use $tmpArray = array(); if ( $this->_sortOrder == EnumSortingOrder::Ascending ) { // Move to the beginning of END file! $this->Sseek($myuid, EnumSeek::EOS, 0); // Switch reading direction! $this->_readDirection = EnumReadDirection::Backward; } else if ( $this->_sortOrder == EnumSortingOrder::Descending ) { // Move to the beginning of the file! $this->Sseek($myuid, EnumSeek::BOS, 0); // Switch reading direction! $this->_readDirection = EnumReadDirection::Forward; } // Now we move for one page, we do not need to process the syslog messages! $ret = $this->ReadNext($myuid, $tmpArray, false); // Save the current UID as LastPage UID! $this->_lastPageUID = $myuid; // --- Restore reading direction and file position! $this->_readDirection = $tmpOldDirection; $ret = $this->Read($tmpuID, $tmpArray); // if ( $this->_readDirection == EnumReadDirection::Forward ) // $this->Sseek($myuid, EnumSeek::BOS, 0); // else // $this->Sseek($myuid, EnumSeek::EOS, 0); // --- // Return result! return $this->_lastPageUID; } /** * This function returns the current Page number, if availbale! * Otherwise will return -1! */ public function GetCurrentPageNumber() { return -1; } /* * Implementation of IsPropertySortable * * For now, sorting is only possible for the UID Property! */ public function IsPropertySortable($myProperty) { global $fields; // TODO: HARDCODED | FOR NOW only FALSE! return false; if ( isset($fields[$myProperty]) && $myProperty == SYSLOG_UID ) return true; else return false; } /** * Implementation of GetLogStreamStats * * Returns an Array og logstream statsdata * Count of Data Items * Total Filesize */ public function GetLogStreamStats() { // Get some file data! /* // return results! return $stats; } else */ // NOT IMPLEMENTED YET! return null; } /** * Implementation of GetLogStreamTotalRowCount * * not implemented yet! */ public function GetLogStreamTotalRowCount() { //not implemented return null; } /** * Implementation of the CleanupLogdataByDate * * not implemented! */ public function CleanupLogdataByDate( $nDateTimeStamp ) { //not implemented return null; } /* * Implementation of the SaveMessageChecksum * * not implemented! */ public function SaveMessageChecksum( $arrProperitesIn ) { return SUCCESS; } /* * Implementation of the UpdateAllMessageChecksum * * not implemented! */ public function UpdateAllMessageChecksum( ) { return SUCCESS; } /* * Helper function to clear the current querystring! */ public function ResetFilters() { // nothing todo in this logstream return SUCCESS; } /* * Helper function to verify fields | not needed in disk logstream! */ public function VerifyFields( $arrProperitesIn ) { return SUCCESS; } /* * Helper function to create missing fields | not needed in disk logstream! */ public function CreateMissingFields( $arrProperitesIn ) { return SUCCESS; } /* * Helper function to verify indexes | not needed in disk logstream! */ public function VerifyIndexes( $arrProperitesIn ) { return SUCCESS; } /* * Helper function to create missing indexes | not needed in disk logstream! */ public function CreateMissingIndexes( $arrProperitesIn ) { return SUCCESS; } /* * Helper function to verify triggers | not needed in disk logstream! */ public function VerifyChecksumTrigger( $myTriggerProperty ) { return SUCCESS; } /* * Helper function to verify triggers | not needed in disk logstream! */ public function CreateMissingTrigger( $myTriggerProperty, $myCheckSumProperty ) { return SUCCESS; } /* * Helper function to create missing triggers | not needed in disk logstream! */ public function GetCreateMissingTriggerSQL( $myDBTriggerField, $myDBTriggerCheckSumField ) { return SUCCESS; } /* * Helper function to verify checksum field | not needed in disk logstream! */ public function VerifyChecksumField( ) { return SUCCESS; } /* * Helper function to correct the checksum field | not needed in disk logstream! */ public function ChangeChecksumFieldUnsigned( ) { return SUCCESS; } /** * Implementation of ConsolidateItemListByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function ConsolidateItemListByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder) { global $content, $fields; // --- Set Options $nConsFieldType = $fields[$szConsFieldId]['FieldType']; // --- // We loop through all loglines! this may take a while! $uID = UID_UNKNOWN; // Needed to reset file position! $this->Sseek($uID, EnumSeek::BOS, 0); $ret = $this->Read($uID, $logArray); if ( $ret == SUCCESS ) { // Initialize Array variable $aResult = array(); // Loop through messages do { if ( isset($logArray[$szConsFieldId]) ) { if ( $nConsFieldType == FILTER_TYPE_DATE ) { // Convert to FULL Day Date for now! $myFieldData = date( "Y-m-d", $logArray[$szFieldId][EVTIME_TIMESTAMP] ); } else // Just copy the value! $myFieldData = $logArray[$szConsFieldId]; if ( isset($aResult[ $myFieldData ]) ) $aResult[ $myFieldData ]['ItemCount']++; else { // Initialize entry if we haven't exceeded the RecordLImit yet! if ( $nRecordLimit == 0 || count($aResult) < ($nRecordLimit-1) ) // -1 because the last entry will become all others { // Init entry $aResult[ $myFieldData ][$szSortFieldId] = $logArray[$szSortFieldId]; $aResult[ $myFieldData ]['ItemCount'] = 1; } else { // Count record to others if ( isset($aResult[ $content['LN_STATS_OTHERS'] ]) ) $aResult[ $content['LN_STATS_OTHERS'] ]['ItemCount']++; else $aResult[ $content['LN_STATS_OTHERS'] ]['ItemCount'] = 1; } } } } while ( ($ret = $this->ReadNext($uID, $logArray)) == SUCCESS ); // Use callback function to sort array if ( $nSortingOrder == SORTING_ORDER_DESC ) uasort($aResult, "MultiSortArrayByItemCountDesc"); else uasort($aResult, "MultiSortArrayByItemCountAsc"); if ( isset($aResult[ $content['LN_STATS_OTHERS'] ]) ) { // This will move the "Others" Element to the last position! $arrEntryCopy = $aResult[ $content['LN_STATS_OTHERS'] ]; unset($aResult[ $content['LN_STATS_OTHERS'] ]); $aResult[ $content['LN_STATS_OTHERS'] ] = $arrEntryCopy; } // finally return result! if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } else return $ret; } /** * Implementation of ConsolidateDataByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function ConsolidateDataByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder, $aIncludeCustomFields = null, $bIncludeLogStreamFields = false, $bIncludeMinMaxDateFields = false) { global $content, $fields; // --- Set Options $nConsFieldType = $fields[$szConsFieldId]['FieldType']; // --- // We loop through all loglines! this may take a while! $uID = UID_UNKNOWN; // Needed to reset file position! $this->Sseek($uID, EnumSeek::BOS, 0); $ret = $this->Read($uID, $logArray); if ( $ret == SUCCESS ) { // Initialize Array variable $aResult = array(); // Loop through messages do { if ( isset($logArray[$szConsFieldId]) ) { // --- Special Case for the checksum field, we need to generate the checksum ourself! if ( $szConsFieldId == MISC_CHECKSUM ) $logArray[$szConsFieldId] = crc32( $logArray[SYSLOG_MESSAGE] ); // --- if ( $nConsFieldType == FILTER_TYPE_DATE ) { // Convert to FULL Day Date for now! $myFieldData = date( "Y-m-d", $logArray[$szFieldId][EVTIME_TIMESTAMP] ); } else // Just copy the value! $myFieldData = $logArray[$szConsFieldId]; // Extra Check to avoid empty counters! if ( strlen($myFieldData) <= 0 ) $myFieldData = $content['LN_STATS_OTHERS']; if ( isset($aResult[ $myFieldData ]) ) { $aResult[ $myFieldData ]['ItemCount']++; $aResult[ $myFieldData ]['LastOccurrence_Date'] = $logArray[SYSLOG_DATE]; } else { // Initialize entry if we haven't exceeded the RecordLImit yet! if ( $nRecordLimit == 0 || count($aResult) < ($nRecordLimit-1) ) // -1 because the last entry will become all others { // Init entry if ( $bIncludeLogStreamFields ) $aResult[ $myFieldData ] = $logArray; else if ( $aIncludeCustomFields != null ) { foreach ( $aIncludeCustomFields as $myFieldName ) { if ( $logArray[$myFieldName] ) $aResult[ $myFieldData ][$myFieldName] = $logArray[$myFieldName]; } } else $aResult[ $myFieldData ][$szSortFieldId] = $logArray[$szSortFieldId]; $aResult[ $myFieldData ]['ItemCount'] = 1; $aResult[ $myFieldData ]['FirstOccurrence_Date'] = $logArray[SYSLOG_DATE]; $aResult[ $myFieldData ]['LastOccurrence_Date'] = $logArray[SYSLOG_DATE]; } else { // Count record to others if ( isset($aResult[ $content['LN_STATS_OTHERS'] ]) ) $aResult[ $content['LN_STATS_OTHERS'] ]['ItemCount']++; else $aResult[ $content['LN_STATS_OTHERS'] ]['ItemCount'] = 1; } } } } while ( ($ret = $this->ReadNext($uID, $logArray)) == SUCCESS ); // Use callback function to sort array if ( $nSortingOrder == SORTING_ORDER_DESC ) uasort($aResult, "MultiSortArrayByItemCountDesc"); else uasort($aResult, "MultiSortArrayByItemCountAsc"); if ( isset($aResult[ $content['LN_STATS_OTHERS'] ]) ) { // This will move the "Others" Element to the last position! $arrEntryCopy = $aResult[ $content['LN_STATS_OTHERS'] ]; unset($aResult[ $content['LN_STATS_OTHERS'] ]); $aResult[ $content['LN_STATS_OTHERS'] ] = $arrEntryCopy; } // finally return result! if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } else return $ret; } /** * Implementation of GetCountSortedByField * * For now, the disk source needs to loop through the whole file * to consolidate and sort the data * * @return integer Error stat */ public function GetCountSortedByField($szFieldId, $nFieldType, $nRecordLimit) { global $content; // We loop through all loglines! this may take a while! $uID = UID_UNKNOWN; $ret = $this->ReadNext($uID, $logArray); if ( $ret == SUCCESS ) { // Initialize Array variable $aResult = array(); // Loop through messages do { if ( isset($logArray[$szFieldId]) ) { if ( $nFieldType == FILTER_TYPE_DATE ) { // Convert to FULL Day Date for now! $myFieldData = date( "Y-m-d", $logArray[$szFieldId][EVTIME_TIMESTAMP] ); } else // Just copy the value! $myFieldData = $logArray[$szFieldId]; if ( isset($aResult[ $myFieldData ]) ) $aResult[ $myFieldData ]++; else { // Initialize entry if we haven't exceeded the RecordLImit yet! if ( count($aResult) < ($nRecordLimit-1) ) // -1 because the last entry will become all others $aResult[ $myFieldData ] = 1; else { // Count record to others if ( isset($aResult[ $content['LN_STATS_OTHERS'] ]) ) $aResult[ $content['LN_STATS_OTHERS'] ]++; else $aResult[ $content['LN_STATS_OTHERS'] ] = 1; } } } } while ( ($ret = $this->ReadNext($uID, $logArray)) == SUCCESS ); // Sort Array, so the highest count comes first! arsort($aResult); // array_multisort($aResult, SORT_NUMERIC, SORT_DESC); if ( isset($aResult[ $content['LN_STATS_OTHERS'] ]) ) { // This will move the "Others" Element to the last position! $arrEntryCopy = $aResult[ $content['LN_STATS_OTHERS'] ]; unset($aResult[ $content['LN_STATS_OTHERS'] ]); $aResult[ $content['LN_STATS_OTHERS'] ] = $arrEntryCopy; } // finally return result! if ( count($aResult) > 0 ) return $aResult; else return ERROR_NOMORERECORDS; } else return ERROR_NOMORERECORDS; } /** * Set the direction the stream should read data. * * * * @param enumReadDirectionfilter EnumReadDirection in: The new direction. * @return integer Error state * public function SetReadDirection($enumReadDirection) { // only if the read direction change we have do do anything if ($this->_readDirection == $enumReadDirection) return SUCCESS; $this->_readDirection = $enumReadDirection; return SUCCESS; } */ private function ResetBuffer() { $this->_bEOS = false; $this->_buffer = false; $this->_buffer_length = 0; $this->_p_buffer = -1; } } ?>loganalyzer-3.6.5/src/classes/logstreamconfigdisk.class.php0000644000175000017500000001004512225176641023433 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- class LogStreamConfigDisk extends LogStreamConfig { // Public properties public $FileName = ''; public $LineParserType = "syslog"; // Default = Syslog! public $_lineParser = null; public function LogStreamFactory($o) { // An instance is created, then include the logstreamdisk class as well! global $gl_root_path; require_once($gl_root_path . 'classes/logstreamdisk.class.php'); // Create and set LineParser Instance $this->_lineParser = $this->CreateLineParser(); // return LogStreamDisk instance return new LogStreamDisk($o); } private function CreateLineParser() { // We need to include Line Parser on demand! global $gl_root_path; require_once($gl_root_path . 'classes/logstreamlineparser.class.php'); // Probe if file exists then include it! $strIncludeFile = $gl_root_path . 'classes/logstreamlineparser' . $this->LineParserType . '.class.php'; $strClassName = "LogStreamLineParser" . $this->LineParserType; if ( is_file($strIncludeFile) ) { require_once($strIncludeFile); // TODO! Create Parser based on Source Config! //return LineParser Instance return new $strClassName(); } else DieWithErrorMsg("Couldn't locate LineParser include file '" . $strIncludeFile . "'"); } /* * Helper function to Set the FileName property */ public function SetFileName( $szNewVal ) { // Replace dynamic variables if necessary if ( strpos($szNewVal, "%") !== false ) { OutputDebugMessage("LogStreamConfigDisk|SetFileName: Filename before replacing: " . $szNewVal, DEBUG_DEBUG); // Create search and replace array $search = array ( "%y", /* Year with two digits (e.g. 2002 becomes "02") */ "%Y", /* Year with 4 digits */ "%m", /* Month with two digits (e.g. March becomes "03") */ "%M", /* Minute with two digits */ "%d", /* Day of month with two digits (e.g. March, 1st becomes "01") */ "%h", /* Hour as two digits */ "%S", /* Seconds as two digits. It is hardly believed that this ever be used in reality. */ "%w", /* Weekday as one digit. 0 means Sunday, 1 Monday and so on. */ "%W", /* Weekday as three-character string. Possible values are "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat". */ ); $replace = array ( date("y"), date("Y"), date("m"), date("i"), date("d"), date("H"), date("s"), date("w"), date("D"), ); // Do the replacing $szNewVal = str_replace( $search, $replace, $szNewVal ); OutputDebugMessage("LogStreamConfigDisk|SetFileName: Filename after replacing: " . $szNewVal, DEBUG_DEBUG); } // Set Filename Property! $this->FileName = $szNewVal; } } ?>loganalyzer-3.6.5/src/classes/logstreamlineparser.class.php0000644000175000017500000000400012225176641023451 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- abstract class LogStreamLineParser { // protected $_arrProperties = null; /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public abstract function ParseLine($szLine, &$arrArguments); } ?>loganalyzer-3.6.5/src/classes/logstreamconfigmongodb.class.php0000644000175000017500000000501512225176641024127 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- class LogStreamConfigMongoDB extends LogStreamConfig { public $DBServer = '127.0.0.1'; public $DBPort = 27017; public $DBName = 'syslog'; public $DBUser = ''; // Default = No database user! public $DBPassword = ''; // Default = No Password public $DBTableType = 'mongodb'; // Default = Use mongodb layout! public $DBCollection = 'rsyslog'; // Default Tabelname from RSYSLOG // public $DBEnableRowCounting = true; // Default RowCounting is enabled! // Runtime configuration variables public $RecordsPerQuery = 100; // This will determine how to limit sql statements public $IDsPerQuery = 5000; // When we query ID's, we read a lot more the datarecords at once! public $SortColumn = SYSLOG_UID; // Default sorting column // public $FileName = ''; // public $LineParserType = "syslog"; // Default = Syslog! // public $_lineParser = null; public function LogStreamFactory($o) { // An instance is created, then include the logstreamdisk class as well! global $gl_root_path; require_once($gl_root_path . 'classes/logstreammongodb.class.php'); // return LogStreamDisk instance return new LogStreamMongoDB($o); } } ?>loganalyzer-3.6.5/src/classes/logstreammongodb.class.php0000644000175000017500000016135312225176641022751 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Required Includes! require_once($gl_root_path . 'include/constants_errors.php'); // --- class LogStreamMongoDB extends LogStream { private $_dbhandle = null; // Helper to store the database records private $bufferedRecords = null; private $_currentRecordStart = 0; private $_currentRecordNum = 0; private $_totalRecordCount = -1; private $_previousPageUID = -1; private $_lastPageUID = -1; private $_firstPageUID = -1; private $_currentPageNumber = 0; private $_SQLwhereClause = ""; private $_myDBQuery = null; private $_myMongoCon = null; private $_myMongoDB = null; private $_myMongoCollection = null; private $_myMongoFields = null; private $_myMongoQuery = null; // Constructor public function LogStreamMongoDB($streamConfigObj) { $this->_logStreamConfigObj = $streamConfigObj; // Probe if a function exists! if ( !function_exists("bson_encode") ) DieWithFriendlyErrorMsg("Error, MongoDB PHP Driver Extensions is not installed! Please see http://www.php.net/manual/en/mongo.installation.php for installation details."); } /** * Open and verifies the database conncetion * * @param arrProperties array in: Properties wish list. * @return integer Error stat */ public function Open($arrProperties) { global $dbmapping; // Initialise Basic stuff within the Classs $this->RunBasicInits(); // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Copy the Property Array $this->_arrProperties = $arrProperties; // Check if DB Mapping exists if ( !isset($dbmapping[ $this->_logStreamConfigObj->DBTableType ]) ) return ERROR_DB_INVALIDDBMAPPING; // Create Needed Fields Array first! $res = $this->CreateFieldsArray(); if ( $res != SUCCESS ) return $res; // Create Filters for first time! // NEEDED OR NOT? // $res = $this->CreateQueryArray(UID_UNKNOWN); // if ( $res != SUCCESS ) // return $res; // Success, this means we init the Pagenumber to ONE! $this->_currentPageNumber = 1; // reached this point means success! return SUCCESS; } /* * Helper function to clear the current querystring! */ public function ResetFilters() { // Clear _SQLwhereClause variable! $this->_SQLwhereClause = ""; } /** * Close the database connection. * * @return integer Error state */ public function Close() { $bReturn = SUCCESS; if ($this->_myMongoCon) { if (!$this->_myMongoCon->close()) $bReturn = false; // return fail } // Reset variables $this->_myMongoCon = null; $this->_myMongoDB = null; $this->_myMongoCollection = null; return $bReturn; } /** * Verify if the database connection exists! * * @return integer Error state */ public function Verify() { // Try to connect to the database if ( $this->_myMongoCon == null ) { try { // Forces to open a new Connection $this->_myMongoCon = new Mongo("mongodb://" . $this->_logStreamConfigObj->DBServer . ":" . $this->_logStreamConfigObj->DBPort ); // Connect to Mongo Server } catch ( MongoConnectionException $e ) { // Log error! $this->PrintDebugError("Verify:Connect failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_CONNECTFAILED; } } try { $this->_myMongoDB = $this->_myMongoCon->selectDB( $this->_logStreamConfigObj->DBName ); // Connect to Database // Only try to auth if Username is configured if ( strlen($this->_logStreamConfigObj->DBUser) > 0 ) { // TODO: Not tested yet, sample code! $szUsrPwd = $this->_logStreamConfigObj->DBUser . ":mongo:" . $this->_logStreamConfigObj->DBPassword; $hashUsrPwd = md5($szUsrPwd); // Get Nonce $myNonce = $this->_myMongoDB->command(array("getnonce" => 1)); $saltedHash = md5($myNonce["nonce"] . $this->_logStreamConfigObj->DBUser . $hashUsrPwd); $result = $this->_myMongoDB->command(array("authenticate" => 1, "user" => $this->_logStreamConfigObj->DBUser, "nonce" => $myNonce["nonce"], "key" => $saltedHash )); if ( $result["ok"] == 0 ) { // Log error! $this->PrintDebugError("Verify:Auth failed with error ' " . $result["errmsg"] . " '"); // Return error code return ERROR_DB_CANNOTSELECTDB; } } } catch ( MongoException $e ) { // Log error! $this->PrintDebugError("Verify:selectDB failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_CANNOTSELECTDB; } // Check if the table exists! try { $this->_myMongoCollection = $this->_myMongoDB->selectCollection ( $this->_logStreamConfigObj->DBCollection ); } catch ( MongoException $e ) { // Log error! $this->PrintDebugError("Verify:selectCollection failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_TABLENOTFOUND; } // reached this point means success ;)! return SUCCESS; } /* * Implementation of VerifyFields: Checks if fields exist in table */ public function VerifyFields( $arrProperitesIn ) { // Not needed, successfull return SUCCESS; } /* * Implementation of VerifyIndexes: Checks if indexes exist for desired fields */ public function VerifyIndexes( $arrProperitesIn ) { global $dbmapping, $fields; // Get List of Indexes as Array $arrIndexKeys = $this->GetIndexesAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { // echo $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "
    "; if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) ) { if ( in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrIndexKeys) ) { OutputDebugMessage("LogStreamDB|VerifyIndexes: Found INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_ULTRADEBUG); continue; } else { // Index is missing for this field! OutputDebugMessage("LogStreamDB|VerifyIndexes: Missing INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_WARN); return ERROR_DB_INDEXESMISSING; } } } // Successfull return SUCCESS; } /* * Implementation of VerifyChecksumTrigger: Checks if checksum trigger exists */ public function VerifyChecksumTrigger( $myTriggerProperty ) { // Not needed, successfull return SUCCESS; } /* * Implementation of CreateMissingIndexes: Checks if indexes exist for desired fields */ public function CreateMissingIndexes( $arrProperitesIn ) { global $dbmapping, $fields, $querycount; // Get List of Indexes as Array $arrIndexKeys = $this->GetIndexesAsArray(); $szTableType = $this->_logStreamConfigObj->DBTableType; // Loop through all fields to see which one is missing! foreach ( $arrProperitesIn as $myproperty ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) ) { if (in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrIndexKeys) ) continue; else { try { // Add Unique Index for DBMapping $this->_myMongoCollection->ensureIndex(array( $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] => 1) /*, array("unique" => true) */ ); // Index is missing for this field! OutputDebugMessage("LogStreamDB|CreateMissingIndexes: Createing missing INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_INFO); } catch ( MongoException $e ) { // Log error! $this->PrintDebugError("CreateMissingIndexes failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_QUERYFAILED; } // // Return failure! // $this->PrintDebugError("Dynamically Adding INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' failed with Statement: '" . $szSql . "'"); // return ERROR_DB_INDEXFAILED; } } } // Successfull return SUCCESS; } /* * Implementation of CreateMissingFields: Checks if indexes exist for desired fields */ public function CreateMissingFields( $arrProperitesIn ) { // Successfull return SUCCESS; } /* * Implementation of GetCreateMissingTriggerSQL: Creates SQL needed to create a TRIGGER */ public function GetCreateMissingTriggerSQL( $myDBTriggerField, $myDBTriggerCheckSumField ) { // Return nothing return ""; } /* * Implementation of CreateMissingTrigger: Creates missing triggers ! */ public function CreateMissingTrigger( $myTriggerProperty, $myCheckSumProperty ) { // Successfull return SUCCESS; } /* * Implementation of ChangeChecksumFieldUnsigned: Changes the Checkusm field to unsigned! */ public function ChangeChecksumFieldUnsigned() { // return results return SUCCESS; } /* * Implementation of VerifyChecksumField: Verifies if the checkusm field is signed or unsigned! */ public function VerifyChecksumField() { // return results return SUCCESS; } /** * Read the data from a specific uID which means in this * case beginning with from the Database ID * * @param uID integer in/out: unique id of the data row * @param arrProperitesOut array out: array filled with properties * @return integer Error state * @see ReadNext() */ public function Read($uID, &$arrProperitesOut) { // Seek the first uID! if ( $this->Sseek($uID, EnumSeek::UID, 0) == SUCCESS) { // Read the next record! $ret = $this->ReadNext($uID, $arrProperitesOut); } else $ret = ERROR_NOMORERECORDS; // return result! return $ret; } /** * Read the next line from the file depending on the current * read direction. * * Hint: If the current stream becomes unavailable an error * stated is retuned. A typical case is if a log rotation * changed the original data source. * * @param uID integer out: uID is the offset of data row * @param arrProperitesOut array out: properties * @return integer Error state * @see ReadNext */ public function ReadNext(&$uID, &$arrProperitesOut, $bParseMessage = true) { // Helpers needed for DB Mapping global $content, $gl_starttime; global $dbmapping, $fields; $szTableType = $this->_logStreamConfigObj->DBTableType; // define $ret $ret = SUCCESS; do { // No buffer? then read from DB! if ( $this->bufferedRecords == null ) $ret = $this->ReadNextRecordsFromDB($uID); else { if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) ) { // We need to load new records, so clear the old ones first! $this->ResetBufferedRecords(); // Set new Record start, will be used in the SQL Statement! $this->_currentRecordStart = $this->_currentRecordNum; // + 1; // Now read new ones $ret = $this->ReadNextRecordsFromDB($uID); // Check if we found more records if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) ) $ret = ERROR_NOMORERECORDS; } } if ( $ret == SUCCESS && $this->_arrProperties != null ) { // Init and set variables foreach ( $this->_arrProperties as $property ) { // Check if mapping exists if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$property]) ) { // Copy property if available! $dbfieldname = $dbmapping[$szTableType]['DBMAPPINGS'][$property]; if ( isset($this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]) ) { if ( isset($fields[$property]['FieldType']) && $fields[$property]['FieldType'] == FILTER_TYPE_DATE ) // Handle as date! { $myDateField = $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]; if ( gettype($myDateField) == "object" && get_class($myDateField) == "MongoDate" ) { $arrProperitesOut[$property][EVTIME_TIMESTAMP] = $myDateField->sec; $arrProperitesOut[$property][EVTIME_TIMEZONE] = date('O'); // Get default Offset $arrProperitesOut[$property][EVTIME_MICROSECONDS] = $myDateField->usec; } else // Try to parse Date! $arrProperitesOut[$property] = GetEventTime( $myDateField ); } else $arrProperitesOut[$property] = $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]; } else $arrProperitesOut[$property] = ''; } else { $arrProperitesOut[$property] = ''; // echo $property . "=" . $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]; } } // --- Add dynamic fields into record! foreach( $this->bufferedRecords[$this->_currentRecordNum] as $propName => $propValue) { if ( !isset($arrProperitesOut[$propName]) && !$this->CheckFieldnameInMapping($szTableType, $propName) && (isset($propValue) && strlen($propValue) > 0) ) { // Add dynamic Property! if ( gettype($propValue) == "object" && get_class($propValue) == "MongoDate" ) // Handle Date fields $arrProperitesOut[$propName] = GetFormatedDate($propValue->sec); else // Default handling $arrProperitesOut[$propName] = $propValue; } } // --- // Run optional Message Parsers now if ( isset($arrProperitesOut[SYSLOG_MESSAGE]) ) { $retParser = $this->_logStreamConfigObj->ProcessMsgParsers($arrProperitesOut[SYSLOG_MESSAGE], $arrProperitesOut); // Check if we have to skip the message! if ( $retParser == ERROR_MSG_SKIPMESSAGE ) $ret = $retParser; } // Set uID to the PropertiesOut! //DEBUG -> $this->_currentRecordNum; $uID = $arrProperitesOut[SYSLOG_UID] = $this->bufferedRecords[$this->_currentRecordNum][$dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID]]; // Increment $_currentRecordNum $this->_currentRecordNum++; } // Check how long we are running. If only two seconds of execution time are left, we abort further reading! $scriptruntime = intval(microtime_float() - $gl_starttime); if ( $content['MaxExecutionTime'] > 0 && $scriptruntime > ($content['MaxExecutionTime']-2) ) { // This may display a warning message, so the user knows we stopped reading records because of the script timeout. $content['logstream_warning'] = "false"; $content['logstream_warning_details'] = $content['LN_WARNING_LOGSTREAMDISK_TIMEOUT']; $content['logstream_warning_code'] = ERROR_FILE_NOMORETIME; // Return error code return ERROR_FILE_NOMORETIME; } // This additional filter check will take care on dynamic fields from the message parser! } while ( $this->ApplyFilters($ret, $arrProperitesOut) != SUCCESS && $ret == SUCCESS ); // reached here means return result! return $ret; } /** * Implementation of Seek */ public function Sseek(&$uID, $mode, $numrecs) { // predefine return value $ret = SUCCESS; switch ($mode) { case EnumSeek::UID: // if ( $uID == UID_UNKNOWN ) // set uID to first ID! { // No buffer? then read from DB! if ( $this->bufferedRecords == null ) $ret = $this->ReadNextRecordsFromDB($uID); if ( $ret == SUCCESS ) { $this->_currentRecordNum = 0; $uID = $this->bufferedRecords[ $this->_currentRecordNum ]; } } break; } // Return result! return $ret; } /** * GetMessageCount will return the count of Message. * If this count is not available, the function will * return the default -1 */ public function GetMessageCount() { return $this->_totalRecordCount; } /** * This function returns the first UID for previous PAGE, if availbale! * Otherwise will return -1! */ public function GetPreviousPageUID() { return $this->_previousPageUID; } /** * This function returns the FIRST UID for the FIRST PAGE! * Will be done by a seperated SQL Statement. */ public function GetFirstPageUID() { // functions became obselete return UID_UNKNOWN; } /** * This function returns the first UID for the last PAGE! * Will be done by a seperated SQL Statement. */ public function GetLastPageUID() { // functions became obselete return UID_UNKNOWN; } /** * This function returns the current Page number, if availbale! * Otherwise will return 0! We also assume that this function is * only called once DB is open! */ public function GetCurrentPageNumber() { return $this->_currentPageNumber; } /* * Implementation of IsPropertySortable * * For now, sorting is only possible for the UID Property! */ public function IsPropertySortable($myProperty) { global $fields; // TODO: HARDCODED | FOR NOW only FALSE! return false; } /** * Implementation of GetLogStreamStats * * Returns an Array og logstream statsdata * Count of Data Items * Total Filesize */ public function GetLogStreamStats() { global $querycount; $myStats = null; $myList = $this->_myMongoDB->listCollections(); foreach ($myList as $myCollection) { // Set tablename! $tableName = $myCollection->getName(); $myStats[] = array( 'StatsDisplayName' => 'Table name', 'StatsValue' => $tableName ); // copy usefull statsdata $myStats[] = array( 'StatsDisplayName' => 'Datacount', 'StatsValue' => $myCollection->count() ); $myStats[] = array( 'StatsDisplayName' => 'IndexInfo', 'StatsValue' => var_export($myCollection->getIndexInfo(), true) ); // $myStats[] = array( 'StatsDisplayName' => 'validate', 'StatsValue' => var_export($myCollection->validate(), true) ); $stats[]['STATSDATA'] = $myStats; $querycount++; } // return results! return $stats; } /** * Implementation of GetLogStreamTotalRowCount * * Returns the total amount of rows in the main datatable */ public function GetLogStreamTotalRowCount() { global $querycount, $dbmapping; // Set default rowcount $rowcount = null; // Perform if Connection is true! if ( $this->_myMongoCollection != null ) { $rowcount = $this->_myMongoCollection->count(); } //return result return $rowcount; } /** * Implementation of the CleanupLogdataByDate function! Returns affected rows! */ public function CleanupLogdataByDate( $nDateTimeStamp ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Set default rowcount $rowcount = null; if ( $nDateTimeStamp > 0 ) { // Create MongoDate Object from Timestamp $myMongoDate = new MongoDate($nDateTimeStamp); // Create Criteria Array $myCriteria = array( $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] => array('$lte' => $myMongoDate) ); } else { // Use EMPTY array to delete all! $myCriteria = array(); } try { // Get Datacount! $myCursor = $this->_myMongoCollection->find( $myCriteria ); $rowcount = $myCursor->count(); // we have something to delete! if ( $rowcount > 0 ) { // Remove all older records now! $myResult = $this->_myMongoCollection->remove( $myCriteria ); OutputDebugMessage("LogStreamMongoDB|CleanupLogdataByDate: Result of deleting '$rowcount' objects: '$myResult'", DEBUG_DEBUG); // error occured, output DEBUG message // $this->PrintDebugError("CleanupLogdataByDate failed with SQL Statement ' " . $szSql . " '"); } } catch ( MongoCursorException $e ) { // Log error! $this->PrintDebugError("CleanupLogdataByDate failed with error ' " . $e->getMessage() . " '"); } //return affected rows return $rowcount; } /* * Implementation of the UpdateAllMessageChecksum * * Update all missing checksum properties in the current database */ public function UpdateAllMessageChecksum( ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // --- Create Query Array! $myMongoQuery = array(); if ( ($res = $this->CreateQueryArray(UID_UNKNOWN)) != SUCCESS ) return $res; // Copy array $myMongoQuery = $this->_myMongoQuery; // Set default for custom fields! // $myMongoQuery[ $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] ] = array( '$exists' => FALSE); $myMongoQuery[ $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] ] = null; // var_dump ( $myMongoQuery ); // --- // --- Set DB Fields Array $myMongoFields = array(); $myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] ] = true; $myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_MESSAGE] ] = true; // --- // DEBUG CODE: KILL all checksums! // echo $this->_myMongoCollection->update( array ( "_id" => array( '$exists' => TRUE) ), array( '$set' => array($dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] => null) ), array("multiple" => true) ); // exit; // // Append LIMIT clause $iCount = 0; $myCursor = $this->_myMongoCollection->find($myMongoQuery, $myMongoFields); // ->limit(10); // $collection->find(); foreach ($myCursor as $mongoid => $myRow) { // Check if result was successfull! Compare the queried uID and the MONGOID to abort processing if the same ID was returned! Otherwise we have dupplicated results at the end if ( $myRow === FALSE || !$myRow && $myCursor->count() <= 1 ) break; // Create Querydata $myRow[ "_id" ]; // = base_convert($myRow[ "_id" ], 16, 10); // Convert ID from HEX back to DEC // $mongoID = new MongoID( $myRow[ "_id" ] ); $queryArray = array('_id' => $myRow[ "_id" ]); // Create Update Data $updateChecksum = crc32($myRow[ $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_MESSAGE] ]); $updateData = array( '$set' => array($dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] => $updateChecksum) ); // Update data in Collection $this->_myMongoCollection->update( $queryArray, $updateData ); $iCount++; // Debugcounter //var_dump ( $updateData ); //var_dump ( $queryArray ); //var_dump ( $this->_myMongoCollection->findOne($queryArray) ); //exit; } // Debug Output OutputDebugMessage("LogStreamMongoDB|UpdateAllMessageChecksum: Successfully updated Checksum of '" . $iCount . "' datarecords", DEBUG_INFO); return SUCCESS; } /* * Implementation of the SaveMessageChecksum * * Creates an database UPDATE Statement and performs it! */ public function SaveMessageChecksum( $arrProperitesIn ) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; if ( isset($arrProperitesIn[SYSLOG_UID]) && isset($arrProperitesIn[MISC_CHECKSUM]) && isset($dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM]) ) { // Create Querydata $myMongoID = new MongoId( $this->convBaseHelper($arrProperitesIn[SYSLOG_UID], 10, 16) ); $queryArray = array('_id' => $myMongoID); // Create Update Data $updateData = array( '$set' => array($dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] => $arrProperitesIn[MISC_CHECKSUM]) ); try { // Update data in Collection $this->_myMongoCollection->update( $queryArray, $updateData ); } catch ( MongoCursorException $e ) { // Log error! $this->PrintDebugError("SaveMessageChecksum failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_QUERYFAILED; } // Return success return SUCCESS; } else // Missing important properties return ERROR; } /** * Implementation of ConsolidateItemListByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function ConsolidateItemListByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder) { global $content, $dbmapping, $fields; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; // Check if fields are available if ( !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]) || !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId]) ) return ERROR_DB_DBFIELDNOTFOUND; // --- Set Options $nConsFieldType = $fields[$szConsFieldId]['FieldType']; // --- Set DB Field names $myDBConsFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]; $myDBGroupByFieldName = $myDBConsFieldName; // Set Sorted Field if ( $szConsFieldId == $szSortFieldId ) $myDBSortedFieldName = "itemcount"; else $myDBSortedFieldName = $szSortFieldId; // --- // --- Set DB Fields Array $myMongoFields = array(); $myMongoFields[ $myDBConsFieldName ] = true; // --- /* // Special handling for date fields if ( $nConsFieldType == FILTER_TYPE_DATE ) { // Helper variable for the select statement $mySelectFieldName = $myDBGroupByFieldName . "Grouped"; $myDBQueryFieldName = "DATE( " . $myDBConsFieldName . ") AS " . $myDBGroupByFieldName ; } */ // --- Create Query Array! if ( ($res = $this->CreateQueryArray(UID_UNKNOWN)) != SUCCESS ) return $res; // Create Options array $myOptions = array( 'condition' => $this->_myMongoQuery ); // Set default for counter field! $myMongoInit = array( $myDBSortedFieldName => 0 ); // --- // --- Process Data and consolidate! // Create reduce function $groupReduce = "function (obj, prev) { prev." . $myDBSortedFieldName . "++; }"; try { // Output Debug Informations OutputDebugMessage("LogStreamMongoDB|ConsolidateItemListByField: Running MongoDB group query", DEBUG_ULTRADEBUG); // mongodb group is simular to groupby from MYSQL $myResult = $this->_myMongoCollection->group( array($myDBConsFieldName => 1), $myMongoInit, $groupReduce, $myOptions ); } catch ( MongoCursorException $e ) { // Log error! $this->PrintDebugError("ConsolidateItemListByField failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_QUERYFAILED; } // Initialize Array variable $aResult = array(); // Loop through results if ( isset($myResult['retval']) ) { foreach ($myResult['retval'] as $myid => $myRow) { // Create new row for resultarray $aNewRow = array(); foreach ( $myRow as $myFieldName => $myFieldValue ) { if ( !is_array($myFieldValue) && !is_object($myFieldValue) ) // Process normal values { $myFieldID = $this->GetFieldIDbyDatabaseMapping($szTableType, $myFieldName); $aNewRow[ $myFieldID ] = $myFieldValue; } } // Add new row to result $aResult[] = $aNewRow; } } else { // Return error code OutputDebugMessage("LogStreamMongoDB|ConsolidateItemListByField: myResult['retval'] was empty, see myResult: " . var_export($myResult, true) . ")", DEBUG_WARN); return ERROR_NOMORERECORDS; } // return finished array if ( count($aResult) > 0 ) { // Use callback function to sort array if ( $nSortingOrder == SORTING_ORDER_DESC ) uasort($aResult, "MultiSortArrayByItemCountDesc"); else uasort($aResult, "MultiSortArrayByItemCountAsc"); // Check if we have to truncate the array if ($nRecordLimit != 0 && count($aResult) > $nRecordLimit) { // Create new stripped array $aStripResult = array (); for($iCount = 0; $iCount < $nRecordLimit; $iCount++) $aStripResult[$iCount] = $aResult[$iCount]; // Overwrite stripped results $aResult = $aStripResult; } OutputDebugMessage("LogStreamMongoDB|ConsolidateItemListByField: Results Array (count " . count($aResult) . ")", DEBUG_ULTRADEBUG); // OutputDebugMessage("LogStreamMongoDB|ConsolidateItemListByField: Results Array
    " . var_export($aResult, true) . "
    ", DEBUG_ULTRADEBUG); return $aResult; } else return ERROR_NOMORERECORDS; } /** * Implementation of ConsolidateDataByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function ConsolidateDataByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder, $aIncludeCustomFields = null, $bIncludeLogStreamFields = false, $bIncludeMinMaxDateFields = false) { global $content, $dbmapping, $fields; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; // Check if fields are available if ( !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]) || !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId]) ) return ERROR_DB_DBFIELDNOTFOUND; // --- Set Options $nConsFieldType = $fields[$szConsFieldId]['FieldType']; // --- Set DB Field names $myDBConsFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]; $myDBGroupByFieldName = $myDBConsFieldName; // Set Sorted Field if ( $szConsFieldId == $szSortFieldId ) $myDBSortedFieldName = "itemcount"; else $myDBSortedFieldName = $szSortFieldId; // --- // --- Set DB Fields Array $myMongoFields = array(); $myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId] ] = true; $myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId] ] = true; // Check which fields to include if ( $aIncludeCustomFields != null ) { foreach ( $aIncludeCustomFields as $myFieldName ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName]) ) $myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] ] = true; } // Append Sortingfield if ( !in_array($szConsFieldId, $aIncludeCustomFields) ) $myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId] ] = true; } else if ( $bIncludeLogStreamFields ) { // var_dump($this->_arrProperties ); foreach ( $this->_arrProperties as $myFieldName ) { if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName]) ) $myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] ] = true; } } //$myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId] ] = 1; //var_dump($myMongoFields); // --- Create Query Array! if ( ($res = $this->CreateQueryArray(UID_UNKNOWN)) != SUCCESS ) return $res; // Create Options array $myOptions = array( 'condition' => $this->_myMongoQuery ); // Set default for counter field! $myMongoInit = array( $myDBSortedFieldName => 0 ); //TODO, LIMIT not possible currently! // $myMongoQuery[ '$limit' ] = 5; //var_dump($myMongoQuery); // --- // --- Process Data and consolidate! // --- Create reduce function $groupReduce = " function (obj, prev) { try {\n prev.$myDBSortedFieldName++;\n if ( prev.$myDBSortedFieldName == 1 ) { "; // Add fields! foreach( $myMongoFields as $key => $myfield ) { if ( $key != $myDBConsFieldName ) $groupReduce .= " prev.$key = obj.$key;\n"; } $groupReduce .= " } "; if ( $bIncludeMinMaxDateFields ) { $groupReduce .= " if ( prev.firstoccurrence_date == null || prev.firstoccurrence_date > obj." . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . " ) {\n prev.firstoccurrence_date = obj." . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ";\n } if ( prev.lastoccurrence_date == null || prev.lastoccurrence_date < obj." . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . " ) {\n prev.lastoccurrence_date = obj." . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ";\n }"; } $groupReduce .= " } catch ( e ){ // For now ingore error! theerror = e.toString(); } // assert( theerror, \"B3\" ) } "; // --- // --- Create Mongo KEY Array // Workarround to reduce Datekeys by DAY. Otherwise we will run into 20000 unique Key limit if ( $nConsFieldType == FILTER_TYPE_DATE ) // Handle as date! $mongoKey = new MongoCode( "function(doc) { return {" . $myDBConsFieldName . " : new Date( doc." . $myDBConsFieldName . " - (doc." . $myDBConsFieldName . " % 86400) )}; }"); else $mongoKey = array($myDBConsFieldName => 1); /* $mongoKey = new MongoCode( "function() { emit( " . $myDBConsFieldName . ":this." . $myDBConsFieldName . ", {count:1, _id:this._id} ); }"); */ // --- try { // Uncomment for more Debug Informations OutputDebugMessage("LogStreamMongoDB|ConsolidateDataByField: Running MongoDB group query with mongoKey (type $nConsFieldType):
    " . var_export($mongoKey, true) . "
    ", DEBUG_ULTRADEBUG); // mongodb group is simular to groupby from MYSQL $myResult = $this->_myMongoCollection->group( $mongoKey, $myMongoInit, $groupReduce, $myOptions); } catch ( MongoCursorException $e ) { // Log error! $this->PrintDebugError("ConsolidateDataByField failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_QUERYFAILED; } // Initialize Array variable $aResult = array(); // Loop through results if ( isset($myResult['retval']) ) { foreach ($myResult['retval'] as $myid => $myRow) { // Create new row for resultarray $aNewRow = array(); // Handly Datefields for min and max! if ( $bIncludeMinMaxDateFields ) { if ( isset($myRow['firstoccurrence_date']) && isset($myRow['lastoccurrence_date']) ) { $aNewRow['firstoccurrence_date'] = date( "Y-m-d H:i:s ", $myRow['firstoccurrence_date']->sec ); $aNewRow['lastoccurrence_date'] = date( "Y-m-d H:i:s", $myRow['lastoccurrence_date']->sec ); } else { // Get default date $myDate = $myRow[$dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE]]; if ( gettype($myDate) == "object" && get_class($myDate) == "MongoDate" ) { $aNewRow['firstoccurrence_date'] = date( "Y-m-d H:i:s ", $myDate->sec ); $aNewRow['lastoccurrence_date'] = date( "Y-m-d H:i:s", $myDate->sec ); } } //echo "!". gettype($myDate); //echo "!" . $myDate->sec; //var_dump ( $myRow ); //exit; } foreach ( $myRow as $myFieldName => $myFieldValue ) { if ( !is_array($myFieldValue) && !is_object($myFieldValue) ) // Only Copy NON-Array and NON-Object values! { $myFieldID = $this->GetFieldIDbyDatabaseMapping($szTableType, $myFieldName); $aNewRow[ $myFieldID ] = $myFieldValue; } } // Add new row to result $aResult[] = $aNewRow; } } else { // Return error code OutputDebugMessage("LogStreamMongoDB|ConsolidateDataByField: myResult['retval'] was empty, see myResult: " . var_export($myResult, true) . ")", DEBUG_WARN); return ERROR_NOMORERECORDS; } // return finished array if ( count($aResult) > 0 ) { // Use callback function to sort array if ( $nSortingOrder == SORTING_ORDER_DESC ) uasort($aResult, "MultiSortArrayByItemCountDesc"); else uasort($aResult, "MultiSortArrayByItemCountAsc"); // Check if we have to truncate the array if ($nRecordLimit != 0 && count($aResult) > $nRecordLimit) { // Create new stripped array $aStripResult = array (); for($iCount = 0; $iCount < $nRecordLimit; $iCount++) $aStripResult[$iCount] = $aResult[$iCount]; // Overwrite stripped results $aResult = $aStripResult; } OutputDebugMessage("LogStreamMongoDB|ConsolidateDataByField: Results Array (count " . count($aResult) . ")", DEBUG_ULTRADEBUG); // OutputDebugMessage("LogStreamMongoDB|ConsolidateDataByField: Results Array
    " . var_export($aResult, true) . "
    ", DEBUG_ULTRADEBUG); return $aResult; } else return ERROR_NOMORERECORDS; // --- } /** * Implementation of GetCountSortedByField * * In the native MYSQL Logstream, the database will do most of the work * * @return integer Error stat */ public function GetCountSortedByField($szFieldId, $nFieldType, $nRecordLimit) { global $content, $dbmapping, $fields; // Copy helper variables, this is just for better readability $szTableType = $this->_logStreamConfigObj->DBTableType; if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId]) ) { // Set DB Field name first! $myDBFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId]; $myDBQueryFieldName = $myDBFieldName; $mySelectFieldName = $myDBFieldName; // --- Create Query Array! if ( ($res = $this->CreateQueryArray(UID_UNKNOWN)) != SUCCESS ) return $res; // Create Options array $myOptions = array( 'condition' => $this->_myMongoQuery ); // Copy array $myMongoQuery = $this->_myMongoQuery; // Set default for counter field! $myMongoInit = array( 'TotalCount' => 0 ); // --- // --- Process Data and consolidate! // Create reduce function $groupReduce = "function (obj, prev) { prev.TotalCount++; }"; // Workarround to reduce Datekeys by DAY. Otherwise we will run into 20000 unique Key limit if ( isset($fields[$szFieldId]['FieldType']) && $fields[$szFieldId]['FieldType'] == FILTER_TYPE_DATE ) // Handle as date! $mongoKey = new MongoCode( "function(doc) { return {" . $mySelectFieldName . " : new Date( doc." . $mySelectFieldName . " - (doc." . $mySelectFieldName . " % 86400) )}; }"); else $mongoKey = array($mySelectFieldName => 1); try { // Uncomment for more Debug Informations // OutputDebugMessage("LogStreamMongoDB|GetCountSortedByField: Running MongoDB group query with Map Function:
    " . $groupReduce . "
    ", DEBUG_ULTRADEBUG); // mongodb group is simular to groupby from MYSQL $myResult = $this->_myMongoCollection->group( $mongoKey, $myMongoInit, $groupReduce, $myOptions); } catch ( MongoCursorException $e ) { // Log error! $this->PrintDebugError("GetCountSortedByField failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_QUERYFAILED; } // Initialize Array variable $aResult = array(); // Loop through results if ( isset($myResult['retval']) ) { foreach ($myResult['retval'] as $myid => $myRow) { if ( !is_array($myRow[$mySelectFieldName]) && !is_object($myRow[$mySelectFieldName]) ) // Process normal values $aResult[ $myRow[$mySelectFieldName] ] = $myRow['TotalCount']; else { // Special Handling for datetype! if ( gettype($myRow[$mySelectFieldName]) == "object" && get_class($myRow[$mySelectFieldName]) == "MongoDate" ) { if ( !isset($aResult[ date("Y-m-d", $myRow[$mySelectFieldName]->sec) ]) ) $aResult[ date("Y-m-d", $myRow[$mySelectFieldName]->sec) ] = $myRow['TotalCount']; else $aResult[ date("Y-m-d", $myRow[$mySelectFieldName]->sec) ] += $myRow['TotalCount']; } else $aResult[ "Unknown Type" ] = $myRow['TotalCount']; } } } else { // Return error code OutputDebugMessage("LogStreamMongoDB|GetCountSortedByField: myResult['retval'] was empty, see myResult: " . var_export($myResult, true) . ")", DEBUG_WARN); return ERROR_NOMORERECORDS; } // return finished array if ( count($aResult) > 0 ) { // Sort Array arsort($aResult,SORT_NUMERIC); // Check if we have to truncate the array if ($nRecordLimit != 0 && count($aResult) > $nRecordLimit) { // Slice all unecessary entries from array! $aStripResult = array_slice($aResult, 0, $nRecordLimit); // Overwrite stripped results $aResult = $aStripResult; } OutputDebugMessage("LogStreamMongoDB|GetCountSortedByField: Results Array (count " . count($aResult) . ")", DEBUG_ULTRADEBUG); // OutputDebugMessage("LogStreamMongoDB|ConsolidateItemListByField: Results Array
    " . var_export($aResult, true) . "
    ", DEBUG_ULTRADEBUG); // return results return $aResult; } else return ERROR_NOMORERECORDS; } else { // return error code, field mapping not found return ERROR_DB_DBFIELDNOTFOUND; } } /* * ============= Beginn of private functions ============= */ /* * Helper function to create the Field Array */ private function CreateFieldsArray() { global $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Init Array $this->_myMongoFields = array(); // Init Fields Array foreach ( $this->_arrProperties as $property ) { // Check if mapping exists if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$property]) ) { $this->_myMongoFields[ $dbmapping[$szTableType]['DBMAPPINGS'][$property] ] = true; } } // Success return SUCCESS; } /* * Helper function to create the Query Array */ private function CreateQueryArray($uID) { global $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // Init Array $this->_myMongoQuery = array(); if ( $this->_filters != null ) { // Loop through all available properties foreach( $this->_arrProperties as $propertyname ) { // If the property exists in the filter array, we have something to filter for ^^! if ( array_key_exists($propertyname, $this->_filters) ) { // Process all filters foreach( $this->_filters[$propertyname] as $myfilter ) { // Only perform if database mapping is available for this filter! if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$propertyname]) ) { $szMongoPropID = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname]; switch( $myfilter[FILTER_TYPE] ) { case FILTER_TYPE_STRING: // --- Either make a LIKE or a equal query! if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHFULL ) { // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) { if ( $propertyname == SYSLOG_MESSAGE ) // If we filter for Syslog MSG, we use $ALL to match all values $this->_myMongoQuery[ $szMongoPropID ]['$all'][] = $myfilter[FILTER_VALUE]; else // We use $in by default to get results for each value $this->_myMongoQuery[ $szMongoPropID ]['$in'][] = $myfilter[FILTER_VALUE]; } else // $ne equals NOT EQUAL $this->_myMongoQuery[ $szMongoPropID ]['$ne'][] = $myfilter[FILTER_VALUE]; // --- } else if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHREGEX ) { // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) { // Use REGEX to filter for values, NOT TESTED YET! $this->_myMongoQuery[ $szMongoPropID ]['$regex'][] = $myfilter[FILTER_VALUE]; } else // Negate the query using $NOT operator. $this->_myMongoQuery[ $szMongoPropID ]['$not']['$regex'][] = $myfilter[FILTER_VALUE]; // --- } else { // This should be a typical LIKE query: Some more checking NEEDED (TODO)! // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE) { if ( $propertyname == SYSLOG_MESSAGE ) // If we filter for Syslog MSG, we use $ALL to match all values $this->_myMongoQuery[ $szMongoPropID ]['$regex'][] = $myfilter[FILTER_VALUE]; // Using REGEX for now! else // We use $in by default to get results for each value $this->_myMongoQuery[ $szMongoPropID ]['$regex'][] = $myfilter[FILTER_VALUE]; // Using REGEX for now! } else // $ne equals NOT EQUAL $this->_myMongoQuery[ $szMongoPropID ]['$nin'][] = $myfilter[FILTER_VALUE]; // --- } // --- break; case FILTER_TYPE_NUMBER: // --- Check if user wants to include or exclude! if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE ) { // We use $in by default to get results for each value $this->_myMongoQuery[ $szMongoPropID ]['$in'][] = intval($myfilter[FILTER_VALUE]); } else { // $ne equals NOT EQUAL $this->_myMongoQuery[ $szMongoPropID ]['$nin'][] = intval($myfilter[FILTER_VALUE]); } // --- break; case FILTER_TYPE_DATE: if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { // Get current timestamp $nNowTimeStamp = time(); if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR ) $nNowTimeStamp -= 60 * 60; // One Hour! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_12HOURS ) $nNowTimeStamp -= 60 * 60 * 12; // 12 Hours! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_24HOURS ) $nNowTimeStamp -= 60 * 60 * 24; // 24 Hours! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_7DAYS ) $nNowTimeStamp -= 60 * 60 * 24 * 7; // 7 days else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_31DAYS ) $nNowTimeStamp -= 60 * 60 * 24 * 31; // 31 days else { // Set filter to unknown and Abort in this case! $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_UNKNOWN; break; } // Create MongoDate Object from Timestamp $myMongoDate = new MongoDate($nNowTimeStamp); // add to query array $this->_myMongoQuery[ $szMongoPropID ]['$gte'] = $myMongoDate; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_FROM ) { // We use $gt (>) by default to get filter by date $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); // Create MongoDate Object from Timestamp $myMongoDate = new MongoDate($myeventtime[EVTIME_TIMESTAMP]); // add to query array $this->_myMongoQuery[ $szMongoPropID ]['$gte'] = $myMongoDate; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_TO ) { // Obtain Event struct for the time! $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); // Create MongoDate Object from Timestamp $myMongoDate = new MongoDate($myeventtime[EVTIME_TIMESTAMP]); // add to query array $this->_myMongoQuery[ $szMongoPropID ]['$lte'] = $myMongoDate; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_DATE ) { // Obtain Event struct for the time! $myeventtime = GetEventTime($myfilter[FILTER_VALUE]); // Create MongoDate Object from Timestamp $myMongoDateTo = new MongoDate($myeventtime[EVTIME_TIMESTAMP] + 86400); $myMongoDateFrom = new MongoDate($myeventtime[EVTIME_TIMESTAMP]); // Add to query array $this->_myMongoQuery[ $szMongoPropID ]['$lte'] = $myMongoDateTo; $this->_myMongoQuery[ $szMongoPropID ]['$gte'] = $myMongoDateFrom; } break; default: // Nothing to do! break; } } } } } //print_r ( array('x' => array( '$gt' => 5, '$lt' => 20 )) ); OutputDebugMessage("CreateQueryArray verbose: " . var_export($this->_myMongoQuery, true), DEBUG_DEBUG); } if ( $uID != UID_UNKNOWN ) { // Add uID Filter as well! $myMongoID = new MongoId( $this->convBaseHelper($uID, 10, 16) ); $this->_myMongoQuery[ $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] ] = array( '$lte' => $myMongoID ); } // Success return SUCCESS; } /* * This helper function will read the next records into the buffer. */ private function ReadNextRecordsFromDB($uID) { global $querycount, $dbmapping; $szTableType = $this->_logStreamConfigObj->DBTableType; // return error if there was one! if ( ($res = $this->CreateQueryArray($uID)) != SUCCESS ) return $res; try { // Debug Informations OutputDebugMessage("LogStreamMongoDB|ReadNextRecordsFromDB: Running FIND ", DEBUG_ULTRADEBUG); // Find Data in MongoCollection $myCursor = $this->_myMongoCollection->find($this->_myMongoQuery)->sort(array("_id" => -1))->limit($this->_logStreamConfigObj->RecordsPerQuery); // , $this->_myMongoFields); // echo "
    ";
    //	var_dump($this->_myMongoQuery);
    //	var_dump(iterator_to_array($myCursor));
    //		echo "
    "; } catch ( MongoCursorException $e ) { // Log error! $this->PrintDebugError("ReadNextRecordsFromDB failed with error ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_QUERYFAILED; } // Uncomment for debug! // OutputDebugMessage("LogStreamMongoDB|ReadNextRecordsFromDB: myCursor->info() =
    " . var_export($myCursor->info(), true) . "
    ", DEBUG_ULTRADEBUG); /* MOVED to find() call aboev // Limit records $myCursor->limit( $this->_logStreamConfigObj->RecordsPerQuery ); // OutputDebugMessage("Cursor verbose: " . var_export($myCursor->explain(), true), DEBUG_DEBUG); $myCursor = $myCursor->sort(array("_id" => -1)); /**/ try { // Copy rows into the buffer! $iBegin = $this->_currentRecordNum; $mongoidprev = -1; foreach ($myCursor as $mongoid => $myRow) { // Check if result was successfull! Compare the queried uID and the MONGOID to abort processing if the same ID was returned! Otherwise we have dupplicated results at the end if ( $myRow === FALSE || !$myRow ) break; // Convert MongoID $mongoid = $this->convBaseHelper($mongoid, 16, 10); // Additional Check to stop processing if ( ($uID == $mongoid && $myCursor->count() <= 1) || (strpos($mongoidprev,$mongoid) !== FALSE) /* Force STRING Type comparison, otherwise PHP will try to compare as NUMBER (INT Limit)!*/ // (count($this->bufferedRecords) > $myCursor->count(true)) ) { // echo count($this->bufferedRecords) . "
    " . $myCursor->count(true) . "
    "; // $mongoidprev
    $mongoid
    "; break; } // Convert ID from HEX back to DEC $myRow[ "_id" ] = $mongoid; // base_convert($mongoid, 16, 10); $mongoidprev = $mongoid; // Helper variable to compare last row // Keys will be converted into lowercase! $this->bufferedRecords[$iBegin] = array_change_key_case( $myRow, CASE_LOWER); $iBegin++; } } catch ( MongoCursorTimeoutException $e ) { // Log error! $this->PrintDebugError("ReadNextRecordsFromDB Timeout while operation ' " . $e->getMessage() . " '"); // Return error code return ERROR_DB_TIMEOUTFAILED; } // Uncomment for debug! // OutputDebugMessage("LogStreamMongoDB|ReadNextRecordsFromDB: bufferedRecords = Array
    " . var_export($this->bufferedRecords, true) . "
    ", DEBUG_ULTRADEBUG); OutputDebugMessage("LogStreamMongoDB|ReadNextRecordsFromDB: ibegin = $iBegin, recordnum = " . $this->_currentRecordNum, DEBUG_ULTRADEBUG); // --- Check if results were found if ( $iBegin == $this->_currentRecordNum ) return ERROR_NOMORERECORDS; // --- // Only obtain count if enabled and not done before if ( /*$this->_logStreamConfigObj->DBEnableRowCounting &&*/ $this->_totalRecordCount == -1 ) { $this->_totalRecordCount = $myCursor->count(); if ( $this->_totalRecordCount <= 0 ) return ERROR_NOMORERECORDS; } // Increment for the Footer Stats $querycount++; // return success state if reached this point! return SUCCESS; } /* * Reset record buffer in this function! */ private function ResetBufferedRecords() { if ( isset($this->bufferedRecords) ) { // Loop through all subrecords first! foreach ($this->bufferedRecords as $mykey => $myrecord) unset( $this->bufferedRecords[$mykey] ); // Set buffered records to NULL! $this->bufferedRecords = null; } } /* * Helper function to return a list of Indexes for the logstream table */ private function GetIndexesAsArray() { global $querycount; // Verify database connection (This also opens the database!) $res = $this->Verify(); if ( $res != SUCCESS ) return $res; // Init Array $arrIndexKeys = array(); $aMongoIndexes = $this->_myMongoCollection->getIndexInfo(); if (is_array($aMongoIndexes) && count($aMongoIndexes) > 0 ) { // LOOP through indexes foreach($aMongoIndexes as $myIndex) { if ( strpos($myIndex['ns'], $this->_logStreamConfigObj->DBCollection) !== FALSE ) { // LOOP through keys foreach($myIndex['key'] as $myKeyID => $myKey) { // Add to index keys $arrIndexKeys[] = strtolower($myKeyID); } } } } //echo "
    " . var_export($this->_myMongoCollection->getIndexInfo(), true) . "
    "; //echo "
    " . var_export($arrIndexKeys, true) . "
    "; //exit; // Increment for the Footer Stats $querycount++; // return Array return $arrIndexKeys; } /* * Helper function to display SQL Errors for now! */ private function PrintDebugError($szErrorMsg) { global $extraErrorDescription; $errormsg="$szErrorMsg
    "; // Add to additional error output $extraErrorDescription = $errormsg; //Output! OutputDebugMessage("LogStreamMongoDB|PrintDebugError: $errormsg", DEBUG_ERROR); } /* * Helper function to workaround larg numbers bug from php base_convert() taken from comments */ function convBaseHelper($str, $frombase=10, $tobase=36) { $str = trim($str); if (intval($frombase) != 10) { $len = strlen($str); $q = 0; for ($i=0; $i<$len; $i++) { $r = base_convert($str[$i], $frombase, 10); $q = bcadd(bcmul($q, $frombase), $r); } } else $q = $str; if (intval($tobase) != 10) { $s = ''; while (bccomp($q, '0', 0) > 0) { $r = intval(bcmod($q, $tobase)); $s = base_convert($r, 10, $tobase) . $s; $q = bcdiv($q, $tobase, 0); } } else $s = $q; return $s; } /* OLD CODE private function convBaseHelper($numberInput, $fromBaseInput, $toBaseInput) { if ($fromBaseInput==$toBaseInput) return $numberInput; $fromBase = str_split($fromBaseInput,1); $toBase = str_split($toBaseInput,1); $number = str_split($numberInput,1); $fromLen=strlen($fromBaseInput); $toLen=strlen($toBaseInput); $numberLen=strlen($numberInput); $retval=''; if ($toBaseInput == '0123456789') { $retval=0; for ($i = 1;$i <= $numberLen; $i++) $retval = bcadd($retval, bcmul(array_search($number[$i-1], $fromBase),bcpow($fromLen,$numberLen-$i))); return $retval; } if ($fromBaseInput != '0123456789') $base10=$this->convBaseHelper($numberInput, $fromBaseInput, '0123456789'); else $base10 = $numberInput; if ($base10loganalyzer-3.6.5/src/classes/logstream.class.php0000644000175000017500000012274712225176641021407 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'classes/msgparser.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- abstract class LogStream { protected $_readDirection = EnumReadDirection::Forward; protected $_sortOrder = EnumSortingOrder::Descending; protected $_filters = null; protected $_current_uId = -1; protected $_logStreamConfigObj = null; protected $_arrProperties = null; protected $_arrFilterProperties = null; // Helper Array to store all detected properties from Filterstring /** * Open the stream for read access. * * @param arrProperties string in: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public abstract function Open($arrProperties); /** * Close the current stream. * * @return integer Error stat */ public abstract function Close(); /** * Verifies the logstream source * * @return integer Error stat */ public abstract function Verify(); /** * Read the next data from the current stream. If it reads * forwards or backwards depends on the current read direction. * * Example for reading forward: * Is the current uID == 4, readDirection set to forwards * ReadNext will provide uID 5 or EOS if no more data exist. * * Exampe for reading backward: * Is the current uID == 4, readDirection set to backwards * ReadNext will provide uID 3. * * Hint: If the current stream becomes unavailable an error * stated is retuned. A typical case is if a log rotation * changed the original data source. * * @param uID integer out: unique id of the data row * @param arrProperitesOut array out: list with properties * @return integer Error state */ public abstract function ReadNext(&$uID, &$arrProperitesOut, $bParseMessage = true); /** * Read the data from a specific uID. * * @param uID integer in: unique id of the data row * @param arrProperitesOut array out: list with properties * @return integer Error state * @see ReadNext() */ public abstract function Read($uID, &$arrProperitesOut); /** * Sseek - a strange seek which has a skip capability * * This method was introduced to enable the upper layer to jump to a specific * position within the stream and/or skip some records. Probably this method is used by * a pager or to navigate from an overview page to a detailed page. * * mm: We had some discussion about the name of the this method. Initially we named * it Seek. While implementing I got pain in the stomach forced me to start a discussion about * the name and the functionality. The outcome is here - a strange seek method. Please do not * confuse it with a seek method, it is no seek, it is a strange seek. rger suggested to name * it diddledaddle, but I still feel uncomfortable with that name. Probably my imagination is * too poor associating any functionality of this method with such a name. So strange seek * is much better. It reminds me that is no seek, but a strange seek which does not work like * a typical seek like fseek in php but in some way similar. Here is how it works: * * If you Sseek to EOS for example and then call a NextRead you do not get a EOS return status. * Instead you will obtain the last record in the stream. The similarity of Sseek with a seek * is when you use Sseek to jump to BOS. After calling a ReadNext will give you the first record * in the stream. Here are some samples: * * * Sample: * To read the last record of a stream, do a * seek(uid_out, EOS, 0) * ReadNext * * For the first record, similarly: * seek(uid_out, BOS, 0) * ReadNext * * To skip the next, say, 49 records from the current position, you first need to know the * current uid. You may have obtained it by a previous ReadNext call. Then, do * seek(uidCURR, UID, 50) * ReadNext * * @param uID integer in/out: is a unique ID from where to start, ignored in all modes except UID. * On return, uID contains the uID of the record seeked to. It is undefined if an error occured. * If no error ocucrred, the next call to ReadNext() will read the record whom's uID has been returned. * @param mode EnumSeek in: how the seek should be performed * @param numrecs integer in: number of records to seek from this position. Use 0 to seek to the * actual position, a positive value to seek the the record numrecs records forward or a negative * value to seek to a position numrecs backward * @return integer Error state */ public abstract function Sseek(&$uID, $mode, $numrecs); /** * If you are interested in how many messages are in the stream, call this method. * But be aware of that some stream can not provide a message count. This is probably * because of performance reason or any other. However, if GetMessageCount return -1 * this does not mean that there is no message in the stream, it is just not countable. * If there is no message 0 will be returned. * * @return integer Amount of messages within the stream. -1 means that no count is available. */ public abstract function GetMessageCount(); /** * This function returns the first UID for previous PAGE, if availbale! Otherwise will * return -1! */ public abstract function GetPreviousPageUID(); /** * This function returns the first UID for the last PAGE, if availbale! Otherwise will * return -1! */ public abstract function GetLastPageUID(); /** * This function returns the FIRST UID for the FIRST PAGE, if availbale! Otherwise will * return -1! */ public abstract function GetFirstPageUID(); /** * This function returns the current Page number, if availbale! Otherwise will * return -1! */ public abstract function GetCurrentPageNumber(); /** * This functions is used by charts/graph generator to obtain data * * @return integer Error stat */ public abstract function GetCountSortedByField($szFieldId, $nFieldType, $nRecordLimit); /** * This functions is used by reports to consolidate data * * @return integer Error stat */ public abstract function ConsolidateDataByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder, $bIncludeLogStreamFields = false, $bIncludeMinMaxDateFields = false); /** * This functions is used by reports to consolidate data * * @return integer Error stat */ public abstract function ConsolidateItemListByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder); /** * Gets a property and checks if the class is able to sort the records * by this property. * * @ Returns either true or false. * */ public abstract function IsPropertySortable($myProperty); /** * This returns an Array of useful statsdata for this logstream source */ public abstract function GetLogStreamStats(); /** * This returns just the count of records of the main data source */ public abstract function GetLogStreamTotalRowCount(); /** * Helper function to cleanup all logdata which is older then the nDateTimeStamp! */ public abstract function CleanupLogdataByDate( $nDateTimeStamp ); /* * Helper function to set the message checksum, this will be used for database based logstream classes only */ public abstract function SaveMessageChecksum( $arrProperitesIn ); /* * Helper function to set the checksum for all messages in the current logstream class */ public abstract function UpdateAllMessageChecksum( ); /* * Helper function for logstream classes to clear filter based stuff */ public abstract function ResetFilters( ); /* * Helper function for logstream classes to check if all fields are available! */ public abstract function VerifyFields( $arrProperitesIn ); /* * Helper function for logstream classes to create missing indexes, only applies to database based logstream classes */ public abstract function CreateMissingFields( $arrProperitesIn ); /* * Helper function for logstream classes to check for data indexes, only applies to database based logstream classes */ public abstract function VerifyIndexes( $arrProperitesIn ); /* * Helper function for logstream classes to create missing indexes, only applies to database based logstream classes */ public abstract function CreateMissingIndexes( $arrProperitesIn ); /* * Helper function for logstream classes to check for missing triggers, only applies to database based logstream classes */ public abstract function VerifyChecksumTrigger( $myTriggerProperty ); /* * Helper function for logstream classes to create missing trigger, only applies to database based logstream classes */ public abstract function CreateMissingTrigger( $myTriggerProperty, $myCheckSumProperty ); /* * Helper function for logstream classes to create the SQL statement needed to create the trigger, only applies to database based logstream classes */ public abstract function GetCreateMissingTriggerSQL( $myDBTriggerField, $myDBTriggerCheckSumField ); /* * Helper function for logstream classes to check if the checksum field is configured correctly */ public abstract function VerifyChecksumField( ); /* * Helper function for logstream classes to change the checksum field from unsigned INT */ public abstract function ChangeChecksumFieldUnsigned( ); /* * Helper functino to trigger initialisation of MsgParsers */ public function RunBasicInits() { $this->_logStreamConfigObj->InitMsgParsers(); } /** * Set the filter for the current stream. * * @param filter object in: filter object * @return integer Error state */ public function SetFilter($szFilters) { // prepend default Filters if ( strlen($this->_logStreamConfigObj->_defaultfilter) > 0 ) $finalfilters = $this->_logStreamConfigObj->_defaultfilter . " " . $szFilters; else $finalfilters = $szFilters; OutputDebugMessage("LogStream|SetFilter: SetFilter combined = '" . $finalfilters . "'. ", DEBUG_DEBUG); // Reset Filters first to make sure we do not add multiple filters! $this->_filters = null; // Parse Filters from string $this->ParseFilters($finalfilters); // return success return SUCCESS; } /** * Append filter definition for the current stream. * * @param filter object in: filter object * @return integer Error state */ public function AppendFilter($szFilters) { OutputDebugMessage("LogStream|AppendFilter: SetFilter combined = '" . $szFilters . "'. ", DEBUG_DEBUG); // Parse Filters from string $this->ParseFilters($szFilters); // return success return SUCCESS; } /** * Remove filters for a specific Fieldtype * * @param filter object in: FieldID * @return integer Error state */ public function RemoveFilters($szFieldID) { // Removing Filters for this field! if ( isset($this->_filters[$szFieldID]) ) unset($this->_filters[$szFieldID]); // return success return SUCCESS; } /** * Set the direction the stream should read data. * * @param enumReadDirectionfilter EnumReadDirection in: The new direction. * @return integer Error state */ public function SetReadDirection($enumReadDirection) { // Set the new read direction! $this->_readDirection = $enumReadDirection; return SUCCESS; } /** * Set the sorting order for the stream * * @param newSortOrder EnumSortingOrder in: The new sort order. * @return integer Error state */ public function SetSortOrder($newSortOrder) { // Set the new read direction! $this->_sortOrder = $newSortOrder; return SUCCESS; } /** * Implementation of ApplyFilters which can be used by all LogStream Classes! * This function performs a check on the filters and actually triggers the * syslog parsers as well. */ public function ApplyFilters($myResults, &$arrProperitesOut) { // IF result was unsuccessfull, return success - nothing we can do here. if ( $myResults >= ERROR ) return SUCCESS; // Evaluation default is true $bFinalEval = true; // Process all filters if ( $this->_filters != null ) { // Loop through set properties foreach( $arrProperitesOut as $propertyname => $propertyvalue ) { // TODO: NOT SURE IF THIS WILL WORK ON NUMBERS AND OTHER TYPES RIGHT NOW if ( array_key_exists($propertyname, $this->_filters) && isset($propertyvalue) /* && !(is_string($propertyvalue) && strlen($propertyvalue) <= 0)*/ /* Negative because it only matters if the propvalure is a string*/ ) { // Perform first loop to determine the bEval Default foreach( $this->_filters[$propertyname] as $myfilter ) { if ( ($myfilter[FILTER_TYPE] == FILTER_TYPE_NUMBER) || ($myfilter[FILTER_TYPE] == FILTER_TYPE_STRING && $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE && $propertyname != SYSLOG_MESSAGE) ) { $bEval = false; break; // IF found one INCLUDE or NUMERIC filter, the default has to be false! } else $bEval = true; } // Extra var needed for number checks! $bIsOrFilter = false; // If enabled we need to check for numbereval later $bOrFilter = false; // Perform second loop through all filters, to perform filtering foreach( $this->_filters[$propertyname] as $myfilter ) { switch( $myfilter[FILTER_TYPE] ) { case FILTER_TYPE_STRING: // Only filter if value is non zero if ( strlen($propertyvalue) > 0 && strlen($myfilter[FILTER_VALUE]) > 0 ) { // If Syslog message, we have AND handling! if ( $propertyname == SYSLOG_MESSAGE ) { // Include Filter if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE ) { if ( stripos($propertyvalue, $myfilter[FILTER_VALUE]) === false ) $bEval = false; } // Exclude Filter else if ( $myfilter[FILTER_MODE] & FILTER_MODE_EXCLUDE ) { if ( stripos($propertyvalue, $myfilter[FILTER_VALUE]) !== false ) $bEval = false; } } // Otherwise we use OR Handling! else { // Include Filter if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE ) { // Set isOrFilter to true in this case $bIsOrFilter = true; if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHFULL ) { if ( strtolower($propertyvalue) == strtolower($myfilter[FILTER_VALUE]) ) $bOrFilter = true; } else { if ( stripos($propertyvalue, $myfilter[FILTER_VALUE]) !== false ) $bOrFilter = true; } } // Exclude Filter - handeled with AND filtering! else if ( $myfilter[FILTER_MODE] & FILTER_MODE_EXCLUDE ) { if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHFULL ) { if ( strtolower($propertyvalue) == strtolower($myfilter[FILTER_VALUE]) ) $bEval = false; } else { if ( stripos($propertyvalue, $myfilter[FILTER_VALUE]) !== false ) $bEval = false; } } break; } } else { // Either filter value or property value was empty! // This means we have no match $bEval = false; } break; case FILTER_TYPE_NUMBER: $bIsOrFilter = true; // Default is set to TRUE if ( is_numeric($arrProperitesOut[$propertyname]) ) { if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE ) { if ( $myfilter[FILTER_VALUE] == $arrProperitesOut[$propertyname] ) $bOrFilter = true; else $bOrFilter = false; } else if ( $myfilter[FILTER_MODE] & FILTER_MODE_EXCLUDE ) { if ( $myfilter[FILTER_VALUE] == $arrProperitesOut[$propertyname] ) $bOrFilter = false; else $bOrFilter = true; } } else { // If wanted, we treat this filter as a success! if ( GetConfigSetting("TreatNotFoundFiltersAsTrue", 0, CFGLEVEL_USER) == 1 ) $bOrFilter = true; else $bOrFilter = false; } break; case FILTER_TYPE_DATE: // Get Log TimeStamp $nLogTimeStamp = $arrProperitesOut[$propertyname][EVTIME_TIMESTAMP]; if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX ) { // Get current timestamp $nNowTimeStamp = time(); if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR ) $nLastXTime = 60 * 60; // One Hour! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_12HOURS ) $nLastXTime = 60 * 60 * 12; // 12 Hours! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_24HOURS ) $nLastXTime = 60 * 60 * 24; // 24 Hours! else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_7DAYS ) $nLastXTime = 60 * 60 * 24 * 7; // 7 days else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_31DAYS ) $nLastXTime = 60 * 60 * 24 * 31; // 31 days else // WTF default? $nLastXTime = 86400; // If Nowtime + LastX is higher then the log timestamp, the this logline is to old for us. if ( ($nNowTimeStamp - $nLastXTime) > $nLogTimeStamp ) $bEval = false; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_FROM ) { // Get filter timestamp! $nFromTimeStamp = GetTimeStampFromTimeString($myfilter[FILTER_VALUE]); // If logtime is smaller then FromTime, then the Event is outside of our scope! if ( $nLogTimeStamp < $nFromTimeStamp ) $bEval = false; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_TO ) { // Get filter timestamp! // echo $myfilter[FILTER_VALUE]; $nToTimeStamp = GetTimeStampFromTimeString($myfilter[FILTER_VALUE]); // If logtime is smaller then FromTime, then the Event is outside of our scope! if ( $nLogTimeStamp > $nToTimeStamp ) $bEval = false; } else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_DATE ) { // Get filter timestamp! // echo $myfilter[FILTER_VALUE]; $nDateTimeStamp = GetTimeStampFromTimeString($myfilter[FILTER_VALUE]); // If not on logfile day, the Event is outside of our scope! if ( $nLogTimeStamp < $nDateTimeStamp || $nLogTimeStamp > ($nDateTimeStamp+86400) ) $bEval = false; } break; default: // TODO! break; } // If was number filter, we apply it the evaluation. if ( $bIsOrFilter ) // && $bOrFilter ) { // Fixed binary comparison to | instead of &! $bEval |= $bOrFilter; //echo "!" . $bOrFilter . "-" . $bEval . "!
    "; } // else // $bEval &= $bOrFilter; } // Combine filters with AND $bFinalEval &= $bEval; } } // Check if evaluation was successfull if ( !$bFinalEval ) { // unmatching filter, reset property array foreach ( $this->_arrProperties as $property ) $arrProperitesOut[$property] = ''; // return error! return ERROR_FILTER_NOT_MATCH; } // Reached this point means filters did match! return SUCCESS; } else // No filters at all means success! return SUCCESS; } /** * Helper function to obtain internal Filters Array */ public function ReturnFiltersArray() { return $this->_filters; } /** * Helper function to find a fieldkey by using the SearchField */ public function ReturnFilterKeyBySearchField($szSearchField) { global $fields; foreach ($fields as $myField) { if ( $myField['SearchField'] == $szSearchField ) return $myField['FieldID']; } return FALSE; } /** * Helper function to return all fields needed for filters * Can be helpful for functions which need to add filtering fields */ public function ReturnFieldsByFilters() { global $fields; if ( $this->_filters != null ) { // Return array keys $aResult = array_keys($this->_filters); return $aResult; } else // No fields at all! return null; } /* * Helper function to get the internal Field ID by database field name! */ public function GetFieldIDbyDatabaseMapping($szTableType, $szFieldName) { global $content, $dbmapping; foreach( $dbmapping[$szTableType]['DBMAPPINGS'] as $myFieldID => $myDBMapping ) { if ( $myDBMapping == $szFieldName ) return $myFieldID; } // Default return! return $szFieldName; } /* * Helper function to check a if a fieldname exists in the mapping */ public function CheckFieldnameInMapping($szTableType, $szFieldName) { global $content, $dbmapping; foreach( $dbmapping[$szTableType]['DBMAPPINGS'] as $myFieldID => $myDBMapping ) { if ( $myDBMapping == $szFieldName ) return true; // return found! } // Default FALSE! return false; } /* * --- PIRVATE HELPERS! */ /** * Helper function to parse filters into a useful filter array we can work with. */ private function ParseFilters($szFilters) { global $fields; if ( isset($szFilters) && strlen($szFilters) > 0 ) { //OLD $tmpEntries = explode(" ", $szFilters); // Use RegEx for intelligent splitting $szFilterRgx = '/[\s]++(?=(?:(?:[^"]*+"){2})*+[^"]*+$)(?=(?:(?:[^\']*+\'){2})*+[^\']*+$)(?=(?:[^()]*+\([^()]*+\))*+[^()]*+$)/x'; $tmpEntries = preg_split($szFilterRgx, $szFilters, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); //DEBUG print_r ( $tmpEntries ); foreach($tmpEntries as $myEntry) { // Continue if empty filter! if ( strlen(trim($myEntry)) <= 0 ) continue; if ( ($pos = strpos($myEntry, ":")) !== false && ($pos > 0 && substr($myEntry, $pos-1,1) != '\\') /* Only if character before is no backslash! */ ) { // Split key and value $tmpArray = explode(":", $myEntry, 2); //print_r ( $tmpArray ); // Continue if empty filter! if ( strlen(trim($tmpArray[FILTER_TMP_VALUE])) == 0 ) continue; // Check for multiple values! if ( strpos($tmpArray[FILTER_TMP_VALUE], ",") ) { // Split by comma and fill tmp Value array $tmpValueArray = explode(",", $tmpArray[FILTER_TMP_VALUE]); foreach($tmpValueArray as $myValueEntry) { // Append to temp array $tmpValues[] = array( FILTER_TMP_MODE => $this->SetFilterIncludeMode($myValueEntry), FILTER_TMP_VALUE => $myValueEntry ); } } // Handle filter based switch( $tmpArray[FILTER_TMP_KEY] ) { case "facility": $tmpKeyName = SYSLOG_FACILITY; $tmpFilterType = FILTER_TYPE_NUMBER; // --- Extra Check to convert string representations into numbers! if ( isset($tmpValues) ) { foreach( $tmpValues as $mykey => $szValue ) { if ( !is_numeric($szValue[FILTER_TMP_VALUE]) ) { $tmpFacilityCode = $this->ConvertFacilityString($szValue[FILTER_TMP_VALUE]); if ( $tmpFacilityCode != -1 ) $tmpValues[$mykey][FILTER_TMP_VALUE] = $tmpFacilityCode; } } } else { // First set Filter Mode $tmpArray[FILTER_TMP_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE],$tmpFilterType); if ( !is_numeric($tmpArray[FILTER_TMP_VALUE]) ) { $tmpFacilityCode = $this->ConvertFacilityString($tmpArray[FILTER_TMP_VALUE]); if ( $tmpFacilityCode != -1 ) $tmpArray[FILTER_TMP_VALUE] = $tmpFacilityCode; } } // --- break; case "severity": $tmpKeyName = SYSLOG_SEVERITY; $tmpFilterType = FILTER_TYPE_NUMBER; // --- Extra Check to convert string representations into numbers! if ( isset($tmpValues) ) { foreach( $tmpValues as $mykey => $szValue ) { if ( !is_numeric($szValue[FILTER_TMP_VALUE]) ) { $tmpFacilityCode = $this->ConvertSeverityString($szValue[FILTER_TMP_VALUE]); if ( $tmpFacilityCode != -1 ) $tmpValues[$mykey][FILTER_TMP_VALUE] = $tmpFacilityCode; } } } else { // First set Filter Mode $tmpArray[FILTER_TMP_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE], $tmpFilterType); if ( !is_numeric($tmpArray[FILTER_TMP_VALUE]) ) { $tmpFacilityCode = $this->ConvertSeverityString($tmpArray[FILTER_TMP_VALUE]); if ( $tmpFacilityCode != -1 ) $tmpArray[FILTER_TMP_VALUE] = $tmpFacilityCode; } } // --- break; case "messagetype": $tmpKeyName = SYSLOG_MESSAGETYPE; $tmpFilterType = FILTER_TYPE_NUMBER; // --- Extra Check to convert string representations into numbers! if ( isset($tmpValues) ) { foreach( $tmpValues as $mykey => $szValue ) { if ( !is_numeric($szValue[FILTER_TMP_VALUE]) ) { $tmpMsgTypeCode = $this->ConvertMessageTypeString($szValue[FILTER_TMP_VALUE]); if ( $tmpMsgTypeCode != -1 ) $tmpValues[$mykey][FILTER_TMP_VALUE] = $tmpMsgTypeCode; } } /* OBSELETE CODE foreach( $tmpValues as $mykey => $szValue ) { // First set Filter Mode $tmpValues[$mykey][FILTER_TMP_MODE] = $this->SetFilterIncludeMode($szValue); } */ } else { // First set Filter Mode $tmpArray[FILTER_TMP_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE], $tmpFilterType); if ( !is_numeric($tmpArray[FILTER_TMP_VALUE]) ) { $tmpMsgTypeCode = $this->ConvertMessageTypeString($tmpArray[FILTER_TMP_VALUE]); if ( $tmpMsgTypeCode != -1 ) $tmpArray[FILTER_TMP_VALUE] = $tmpMsgTypeCode; } } // --- break; /* BEGIN Eventlog based fields */ case "eventid": $tmpKeyName = SYSLOG_EVENT_ID; $tmpFilterType = FILTER_TYPE_NUMBER; // --- Extra numeric Check if ( isset($tmpValues) ) { foreach( $tmpValues as $mykey => $szValue ) { if ( is_numeric($szValue[FILTER_TMP_VALUE]) ) $tmpValues[$mykey][FILTER_TMP_VALUE] = $szValue[FILTER_TMP_VALUE]; else $tmpValues[$mykey][FILTER_TMP_VALUE] = ""; } } else { // First set Filter Mode $tmpArray[FILTER_TMP_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE], $tmpFilterType); if ( !is_numeric($tmpArray[FILTER_TMP_VALUE]) ) $tmpArray[FILTER_TMP_VALUE] = ""; } // --- break; case "eventcategory": $tmpKeyName = SYSLOG_EVENT_CATEGORY; $tmpFilterType = FILTER_TYPE_NUMBER; // --- Extra numeric Check if ( isset($tmpValues) ) { foreach( $tmpValues as $mykey => $szValue ) { if ( is_numeric($szValue[FILTER_TMP_VALUE]) ) $tmpValues[$mykey][FILTER_TMP_VALUE] = $szValue[FILTER_TMP_VALUE]; else $tmpValues[$mykey][FILTER_TMP_VALUE] = ""; } } else { // First set Filter Mode $tmpArray[FILTER_TMP_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE], $tmpFilterType); if ( !is_numeric($tmpArray[FILTER_TMP_VALUE]) ) $tmpArray[FILTER_TMP_VALUE] = ""; } // --- break; case "eventlogtype": $tmpKeyName = SYSLOG_EVENT_LOGTYPE; $tmpFilterType = FILTER_TYPE_STRING; break; case "eventlogsource": $tmpKeyName = SYSLOG_EVENT_SOURCE; $tmpFilterType = FILTER_TYPE_STRING; break; case "eventuser": $tmpKeyName = SYSLOG_EVENT_USER; $tmpFilterType = FILTER_TYPE_STRING; break; /* END Eventlog based fields */ case "syslogtag": $tmpKeyName = SYSLOG_SYSLOGTAG; $tmpFilterType = FILTER_TYPE_STRING; break; case "source": $tmpKeyName = SYSLOG_HOST; $tmpFilterType = FILTER_TYPE_STRING; break; case "datefrom": $tmpKeyName = SYSLOG_DATE; $tmpFilterType = FILTER_TYPE_DATE; $tmpTimeMode = DATEMODE_RANGE_FROM; break; case "dateto": $tmpKeyName = SYSLOG_DATE; $tmpFilterType = FILTER_TYPE_DATE; $tmpTimeMode = DATEMODE_RANGE_TO; break; case "datelastx": $tmpKeyName = SYSLOG_DATE; $tmpFilterType = FILTER_TYPE_DATE; $tmpTimeMode = DATEMODE_LASTX; break; case "timereported": $tmpKeyName = SYSLOG_DATE; $tmpFilterType = FILTER_TYPE_DATE; $tmpTimeMode = DATEMODE_RANGE_DATE; break; case "processid": $tmpKeyName = SYSLOG_PROCESSID; $tmpFilterType = FILTER_TYPE_STRING; break; /* BEGIN WebLog based fields */ case SYSLOG_WEBLOG_USER: $tmpKeyName = SYSLOG_WEBLOG_USER; $tmpFilterType = FILTER_TYPE_STRING; break; case SYSLOG_WEBLOG_METHOD: $tmpKeyName = SYSLOG_WEBLOG_METHOD; $tmpFilterType = FILTER_TYPE_STRING; break; case SYSLOG_WEBLOG_URL: $tmpKeyName = SYSLOG_WEBLOG_URL; $tmpFilterType = FILTER_TYPE_STRING; break; case SYSLOG_WEBLOG_QUERYSTRING: $tmpKeyName = SYSLOG_WEBLOG_QUERYSTRING; $tmpFilterType = FILTER_TYPE_STRING; break; case SYSLOG_WEBLOG_PVER: $tmpKeyName = SYSLOG_WEBLOG_PVER; $tmpFilterType = FILTER_TYPE_STRING; break; case SYSLOG_WEBLOG_STATUS: $tmpKeyName = SYSLOG_WEBLOG_STATUS; $tmpFilterType = FILTER_TYPE_NUMBER; // --- Extra numeric Check if ( isset($tmpValues) ) { foreach( $tmpValues as $mykey => $szValue ) { if ( is_numeric($szValue[FILTER_TMP_VALUE]) ) $tmpValues[$mykey][FILTER_TMP_VALUE] = $szValue[FILTER_TMP_VALUE]; else $tmpValues[$mykey][FILTER_TMP_VALUE] = ""; } } else { // First set Filter Mode $tmpArray[FILTER_TMP_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE], $tmpFilterType); if ( !is_numeric($tmpArray[FILTER_TMP_VALUE]) ) $tmpArray[FILTER_TMP_VALUE] = ""; } // --- break; case SYSLOG_WEBLOG_BYTESSEND: $tmpKeyName = SYSLOG_WEBLOG_BYTESSEND; $tmpFilterType = FILTER_TYPE_NUMBER; // --- Extra numeric Check if ( isset($tmpValues) ) { foreach( $tmpValues as $mykey => $szValue ) { if ( is_numeric($szValue[FILTER_TMP_VALUE]) ) $tmpValues[$mykey][FILTER_TMP_VALUE] = $szValue[FILTER_TMP_VALUE]; else $tmpValues[$mykey][FILTER_TMP_VALUE] = ""; } } else { // First set Filter Mode $tmpArray[FILTER_TMP_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE], $tmpFilterType); if ( !is_numeric($tmpArray[FILTER_TMP_VALUE]) ) $tmpArray[FILTER_TMP_VALUE] = ""; } // --- break; case SYSLOG_WEBLOG_REFERER: $tmpKeyName = SYSLOG_WEBLOG_REFERER; $tmpFilterType = FILTER_TYPE_STRING; break; case SYSLOG_WEBLOG_USERAGENT: $tmpKeyName = SYSLOG_WEBLOG_USERAGENT; $tmpFilterType = FILTER_TYPE_STRING; break; /* END WebLog based fields */ default: // Custom Field, try to find field! $szSearchFilterKey = $tmpArray[FILTER_TMP_KEY]; foreach ($fields as $aField) { if ($aField['SearchField'] == $szSearchFilterKey) { $tmpKeyName = $aField['FieldID']; break; } } if ( isset($fields[$tmpKeyName]) && isset($fields[$tmpKeyName]['SearchField']) ) { $tmpFilterType = $fields[$tmpKeyName]['FieldType']; // Handle numeric fields! if ( $tmpFilterType == FILTER_TYPE_NUMBER ) { // --- Extra numeric Check if ( isset($tmpValues) ) { foreach( $tmpValues as $mykey => $szValue ) { if ( is_numeric($szValue[FILTER_TMP_VALUE]) ) $tmpValues[$mykey][FILTER_TMP_VALUE] = $szValue[FILTER_TMP_VALUE]; else $tmpValues[$mykey][FILTER_TMP_VALUE] = ""; } } else { // First set Filter Mode $tmpArray[FILTER_TMP_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE], $tmpFilterType); if ( !is_numeric($tmpArray[FILTER_TMP_VALUE]) ) $tmpArray[FILTER_TMP_VALUE] = ""; } // --- } // Nothing to do actually! // else if ( $tmpFilterType == FILTER_TYPE_STRING ) } else // Unknown filter $tmpFilterType = FILTER_TYPE_UNKNOWN; //done! } // Add to detected filter array if ( $this->_arrFilterProperties == null || !in_array($tmpKeyName, $this->_arrFilterProperties) ) $this->_arrFilterProperties[] = $tmpKeyName; // Ignore if unknown filter! if ( $tmpFilterType != FILTER_TYPE_UNKNOWN ) { // --- Set Filter! $this->_filters[$tmpKeyName][][FILTER_TYPE] = $tmpFilterType; $iNum = count($this->_filters[$tmpKeyName]) - 1; if ( isset($tmpTimeMode) ) { $this->_filters[$tmpKeyName][$iNum][FILTER_DATEMODE] = $tmpTimeMode; $this->_filters[$tmpKeyName][$iNum][FILTER_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE]); // remove FilterMode characters from value $this->_filters[$tmpKeyName][$iNum][FILTER_VALUE] = $tmpArray[FILTER_TMP_VALUE]; //echo $this->_filters[$tmpKeyName][$iNum][FILTER_VALUE]; //exit; } else if ( isset($tmpValues) ) { //print_r( $tmpValues ); foreach( $tmpValues as $szValue ) { // Continue if empty! if ( strlen($szValue[FILTER_TMP_VALUE]) == 0 ) continue; if ( isset($this->_filters[$tmpKeyName][$iNum][FILTER_VALUE]) ) { // Create new Filter! $this->_filters[$tmpKeyName][][FILTER_TYPE] = $tmpFilterType; $iNum = count($this->_filters[$tmpKeyName]) - 1; } // Set Filter Mode if ( isset($szValue[FILTER_TMP_MODE]) ) $this->_filters[$tmpKeyName][$iNum][FILTER_MODE] = $szValue[FILTER_TMP_MODE]; else $this->_filters[$tmpKeyName][$iNum][FILTER_MODE] = $this->SetFilterIncludeMode($szValue[FILTER_TMP_VALUE]); // Set Value $this->_filters[$tmpKeyName][$iNum][FILTER_VALUE] = $szValue[FILTER_TMP_VALUE]; } } else { // Set Filter Mode if ( isset($tmpArray[FILTER_TMP_MODE]) ) $this->_filters[$tmpKeyName][$iNum][FILTER_MODE] = $tmpArray[FILTER_TMP_MODE]; else $this->_filters[$tmpKeyName][$iNum][FILTER_MODE] = $this->SetFilterIncludeMode($tmpArray[FILTER_TMP_VALUE]); // Set Filter value! $this->_filters[$tmpKeyName][$iNum][FILTER_VALUE] = $tmpArray[FILTER_TMP_VALUE]; } // Reverse string prepareation $searchArray = array( '/(?_filters[$tmpKeyName][$iNum][FILTER_VALUE] = str_replace( '+', ' ', $this->_filters[$tmpKeyName][$iNum][FILTER_VALUE]); $this->_filters[$tmpKeyName][$iNum][FILTER_VALUE] = preg_replace( $searchArray, $replaceArray, $this->_filters[$tmpKeyName][$iNum][FILTER_VALUE] ); // --- } // Unset unused variables if ( isset($tmpArray) ) unset($tmpArray); if ( isset($tmpValues) ) unset($tmpValues); if ( isset($tmpTimeMode) ) unset($tmpTimeMode); } else { // No ":", so we treat it as message filter! $this->_filters[SYSLOG_MESSAGE][][FILTER_TYPE] = FILTER_TYPE_STRING; $iNum = count($this->_filters[SYSLOG_MESSAGE]) - 1; $this->_filters[SYSLOG_MESSAGE][$iNum][FILTER_MODE] = $this->SetFilterIncludeMode($myEntry); // Replace "\:" with ":", so we can filter with it ^^ if ( strpos($myEntry, ":") !== false ) $myEntry = str_replace("\\:", ":", $myEntry); // Check for Begin and Ending Quotes and remove them from the search value! $myEntry = preg_replace('/\\"/i', "$1", $myEntry); // Assign value to filter array $this->_filters[SYSLOG_MESSAGE][$iNum][FILTER_VALUE] = $myEntry; } } } // Debug print // print_r ($this->_filters); } /* * Helper function needed in SetFilterIncludeMode */ private function SetFilterIncludeMode(&$szValue, $myFilterType = FILTER_TYPE_STRING) // Default = String! { // Init BIT! $myBits = FILTER_MODE_INCLUDE; // If Filter is Included $pos = strpos($szValue, "+"); if ( $pos !== false && $pos == 0 ) { //trunscate + $szValue = substr( $szValue, 1); $myBits = FILTER_MODE_INCLUDE; } // If Filter is Excluded $pos = strpos($szValue, "-"); if ( $pos !== false && $pos == 0 ) { //trunscate - $szValue = substr( $szValue, 1); $myBits = FILTER_MODE_EXCLUDE; } // If Filter is a FULL text match! $pos = strpos($szValue, "="); if ( $pos !== false && $pos == 0 ) { //trunscate - $szValue = substr( $szValue, 1); // Add BIT if not NUMBER FIELD! if ( $myFilterType != FILTER_TYPE_NUMBER ) $myBits |= FILTER_MODE_SEARCHFULL; } // If Filter is a REGEX match! $pos = strpos($szValue, "~"); if ( $pos !== false && $pos == 0 ) { //trunscate - $szValue = substr( $szValue, 1); // Add BIT if not NUMBER FIELD! if ( $myFilterType != FILTER_TYPE_NUMBER ) $myBits |= FILTER_MODE_SEARCHREGEX; } // --- // return result return $myBits; } /* * Helper function to convert a facility string into a facility number */ private function ConvertFacilityString($szValue) { global $content; foreach ( $content['filter_facility_list'] as $myfacility ) { if ( stripos( $myfacility['DisplayName'], $szValue) !== false ) return $myfacility['ID']; } // reached here means we failed to convert the facility! return -1; } /* * Helper function to convert a severity string into a severity number */ private function ConvertSeverityString($szValue) { global $content; foreach ( $content['filter_severity_list'] as $myfacility ) { if ( stripos( $myfacility['DisplayName'], $szValue) !== false ) return $myfacility['ID']; } // reached here means we failed to convert the facility! return -1; } /* * Helper function to convert a messagetype string into a messagetype number */ private function ConvertMessageTypeString($szValue) { global $content; foreach ( $content['filter_messagetype_list'] as $mymsgtype ) { if ( stripos( $mymsgtype['DisplayName'], $szValue) !== false ) return $mymsgtype['ID']; } // reached here means we failed to convert the facility! return -1; } } ?>loganalyzer-3.6.5/src/classes/jpgraph/0000755000175000017500000000000012225176641017213 5ustar danieldanielloganalyzer-3.6.5/src/classes/jpgraph/jpgraph_pie.php0000644000175000017500000015052212225176641022221 0ustar danieldaniel array(136,34,40,45,46,62,63,134,74,10,120,136,141,168,180,77,209,218,346,395,89,430), "pastel" => array(27,415,128,59,66,79,105,110,42,147,152,230,236,240,331,337,405,38), "water" => array(8,370,24,40,335,56,213,237,268,14,326,387,10,388), "sand" => array(27,168,34,170,19,50,65,72,131,209,46,393)); protected $theme="earth"; protected $setslicecolors=array(); protected $labeltype=0; // Default to percentage protected $pie_border=true,$pie_interior_border=true; public $value; protected $ishadowcolor='',$ishadowdrop=4; protected $ilabelposadj=1; protected $legendcsimtargets = array(),$legendcsimwintargets = array(); protected $legendcsimalts = array(); protected $adjusted_data = array(); public $guideline = null; protected $guidelinemargin=10,$iShowGuideLineForSingle = false; protected $iGuideLineCurve = false,$iGuideVFactor=1.4,$iGuideLineRFactor=0.8; protected $la = array(); // Holds the exact angle for each label //--------------- // CONSTRUCTOR function __construct($data) { $this->data = array_reverse($data); $this->title = new Text(""); $this->title->SetFont(FF_FONT1,FS_BOLD); $this->value = new DisplayValue(); $this->value->Show(); $this->value->SetFormat('%.1f%%'); $this->guideline = new LineProperty(); } //--------------- // PUBLIC METHODS function SetCenter($x,$y=0.5) { $this->posx = $x; $this->posy = $y; } // Enable guideline and set drwaing policy function SetGuideLines($aFlg=true,$aCurved=true,$aAlways=false) { $this->guideline->Show($aFlg); $this->iShowGuideLineForSingle = $aAlways; $this->iGuideLineCurve = $aCurved; } // Adjuste the distance between labels and labels and pie function SetGuideLinesAdjust($aVFactor,$aRFactor=0.8) { $this->iGuideVFactor=$aVFactor; $this->iGuideLineRFactor=$aRFactor; } function SetColor($aColor) { $this->color = $aColor; } function SetSliceColors($aColors) { $this->setslicecolors = $aColors; } function SetShadow($aColor='darkgray',$aDropWidth=4) { $this->ishadowcolor = $aColor; $this->ishadowdrop = $aDropWidth; } function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') { $this->csimtargets=array_reverse($aTargets); if( is_array($aWinTargets) ) $this->csimwintargets=array_reverse($aWinTargets); if( is_array($aAlts) ) $this->csimalts=array_reverse($aAlts); } function GetCSIMareas() { return $this->csimareas; } function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { //Slice number, ellipse centre (x,y), height, width, start angle, end angle while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI; while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI; $sa = 2*M_PI - $sa; $ea = 2*M_PI - $ea; // Special case when we have only one slice since then both start and end // angle will be == 0 if( abs($sa - $ea) < 0.0001 ) { $sa=2*M_PI; $ea=0; } //add coordinates of the centre to the map $xc = floor($xc);$yc=floor($yc); $coords = "$xc, $yc"; //add coordinates of the first point on the arc to the map $xp = floor(($radius*cos($ea))+$xc); $yp = floor($yc-$radius*sin($ea)); $coords.= ", $xp, $yp"; //add coordinates every 0.2 radians $a=$ea+0.2; // If we cross the 360-limit with a slice we need to handle // the fact that end angle is smaller than start if( $sa < $ea ) { while ($a <= 2*M_PI) { $xp = floor($radius*cos($a)+$xc); $yp = floor($yc-$radius*sin($a)); $coords.= ", $xp, $yp"; $a += 0.2; } $a -= 2*M_PI; } while ($a < $sa) { $xp = floor($radius*cos($a)+$xc); $yp = floor($yc-$radius*sin($a)); $coords.= ", $xp, $yp"; $a += 0.2; } //Add the last point on the arc $xp = floor($radius*cos($sa)+$xc); $yp = floor($yc-$radius*sin($sa)); $coords.= ", $xp, $yp"; if( !empty($this->csimtargets[$i]) ) { $this->csimareas .= "csimtargets[$i]."\""; $tmp=""; if( !empty($this->csimwintargets[$i]) ) { $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; } if( !empty($this->csimalts[$i]) ) { $tmp=sprintf($this->csimalts[$i],$this->data[$i]); $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; } $this->csimareas .= " />\n"; } } function SetTheme($aTheme) { if( in_array($aTheme,array_keys($this->themearr)) ) $this->theme = $aTheme; else JpGraphError::RaiseL(15001,$aTheme);//("PiePLot::SetTheme() Unknown theme: $aTheme"); } function ExplodeSlice($e,$radius=20) { if( ! is_integer($e) ) JpGraphError::RaiseL(15002);//('Argument to PiePlot::ExplodeSlice() must be an integer'); $this->explode_radius[$e]=$radius; } function ExplodeAll($radius=20) { $this->explode_all=true; $this->explode_r = $radius; } function Explode($aExplodeArr) { if( !is_array($aExplodeArr) ) { JpGraphError::RaiseL(15003); //("Argument to PiePlot::Explode() must be an array with integer distances."); } $this->explode_radius = $aExplodeArr; } function SetStartAngle($aStart) { if( $aStart < 0 || $aStart > 360 ) { JpGraphError::RaiseL(15004);//('Slice start angle must be between 0 and 360 degrees.'); } if( $aStart == 0 ) { $this->startangle = 0; } else { $this->startangle = 360-$aStart; $this->startangle *= M_PI/180; } } // Size in percentage function SetSize($aSize) { if( ($aSize>0 && $aSize<=0.5) || ($aSize>10 && $aSize<1000) ) $this->radius = $aSize; else JpGraphError::RaiseL(15006); //("PiePlot::SetSize() Radius for pie must either be specified as a fraction [0, 0.5] of the size of the image or as an absolute size in pixels in the range [10, 1000]"); } // Set label arrays function SetLegends($aLegend) { $this->legends = $aLegend; } // Set text labels for slices function SetLabels($aLabels,$aLblPosAdj="auto") { $this->labels = array_reverse($aLabels); $this->ilabelposadj=$aLblPosAdj; } function SetLabelPos($aLblPosAdj) { $this->ilabelposadj=$aLblPosAdj; } // Should we display actual value or percentage? function SetLabelType($aType) { if( $aType < 0 || $aType > 2 ) JpGraphError::RaiseL(15008,$aType); //("PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not $t)."); $this->labeltype = $aType; } // Deprecated. function SetValueType($aType) { $this->SetLabelType($aType); } // Should the circle around a pie plot be displayed function ShowBorder($exterior=true,$interior=true) { $this->pie_border = $exterior; $this->pie_interior_border = $interior; } // Setup the legends function Legend($graph) { $colors = array_keys($graph->img->rgb->rgb_table); sort($colors); $ta=$this->themearr[$this->theme]; $n = count($this->data); if( $this->setslicecolors==null ) { $numcolors=count($ta); if( class_exists('PiePlot3D',false) && ($this instanceof PiePlot3D) ) { $ta = array_reverse(array_slice($ta,0,$n)); } } else { $this->setslicecolors = array_slice($this->setslicecolors,0,$n); $numcolors=count($this->setslicecolors); if( $graph->pieaa && !($this instanceof PiePlot3D) ) { $this->setslicecolors = array_reverse($this->setslicecolors); } } $sum=0; for($i=0; $i < $n; ++$i) $sum += $this->data[$i]; // Bail out with error if the sum is 0 if( $sum==0 ) JpGraphError::RaiseL(15009);//("Illegal pie plot. Sum of all data is zero for Pie!"); // Make sure we don't plot more values than data points // (in case the user added more legends than data points) $n = min(count($this->legends),count($this->data)); if( $this->legends != "" ) { $this->legends = array_reverse(array_slice($this->legends,0,$n)); } for( $i=$n-1; $i >= 0; --$i ) { $l = $this->legends[$i]; // Replace possible format with actual values if( count($this->csimalts) > $i ) { $fmt = $this->csimalts[$i]; } else { $fmt = "%d"; // Deafult Alt if no other has been specified } if( $this->labeltype==0 ) { $l = sprintf($l,100*$this->data[$i]/$sum); $alt = sprintf($fmt,$this->data[$i]); } elseif( $this->labeltype == 1) { $l = sprintf($l,$this->data[$i]); $alt = sprintf($fmt,$this->data[$i]); } else { $l = sprintf($l,$this->adjusted_data[$i]); $alt = sprintf($fmt,$this->adjusted_data[$i]); } if( empty($this->csimwintargets[$i]) ) { $wintarg = ''; } else { $wintarg = $this->csimwintargets[$i]; } if( $this->setslicecolors==null ) { $graph->legend->Add($l,$colors[$ta[$i%$numcolors]],"",0,$this->csimtargets[$i],$alt,$wintarg); } else { $graph->legend->Add($l,$this->setslicecolors[$i%$numcolors],"",0,$this->csimtargets[$i],$alt,$wintarg); } } } // Adjust the rounded percetage value so that the sum of // of the pie slices are always 100% // Using the Hare/Niemeyer method function AdjPercentage($aData,$aPrec=0) { $mul=100; if( $aPrec > 0 && $aPrec < 3 ) { if( $aPrec == 1 ) $mul=1000; else $mul=10000; } $tmp = array(); $result = array(); $quote_sum=0; $n = count($aData) ; for( $i=0, $sum=0; $i < $n; ++$i ) $sum+=$aData[$i]; foreach($aData as $index => $value) { $tmp_percentage=$value/$sum*$mul; $result[$index]=floor($tmp_percentage); $tmp[$index]=$tmp_percentage-$result[$index]; $quote_sum+=$result[$index]; } if( $quote_sum == $mul) { if( $mul > 100 ) { $tmp = $mul / 100; for( $i=0; $i < $n; ++$i ) { $result[$i] /= $tmp ; } } return $result; } arsort($tmp,SORT_NUMERIC); reset($tmp); for($i=0; $i < $mul-$quote_sum; $i++) { $result[key($tmp)]++; next($tmp); } if( $mul > 100 ) { $tmp = $mul / 100; for( $i=0; $i < $n; ++$i ) { $result[$i] /= $tmp ; } } return $result; } function Stroke($img,$aaoption=0) { // aaoption is used to handle antialias // aaoption == 0 a normal pie // aaoption == 1 just the body // aaoption == 2 just the values // Explode scaling. If anti alias we scale the image // twice and we also need to scale the exploding distance $expscale = $aaoption === 1 ? 2 : 1; if( $this->labeltype == 2 ) { // Adjust the data so that it will add up to 100% $this->adjusted_data = $this->AdjPercentage($this->data); } $colors = array_keys($img->rgb->rgb_table); sort($colors); $ta=$this->themearr[$this->theme]; $n = count($this->data); if( $this->setslicecolors==null ) { $numcolors=count($ta); } else { // We need to create an array of colors as long as the data // since we need to reverse it to get the colors in the right order $numcolors=count($this->setslicecolors); $i = 2*$numcolors; while( $n > $i ) { $this->setslicecolors = array_merge($this->setslicecolors,$this->setslicecolors); $i += $n; } $tt = array_slice($this->setslicecolors,0,$n % $numcolors); $this->setslicecolors = array_merge($this->setslicecolors,$tt); $this->setslicecolors = array_reverse($this->setslicecolors); } // Draw the slices $sum=0; for($i=0; $i < $n; ++$i) $sum += $this->data[$i]; // Bail out with error if the sum is 0 if( $sum==0 ) { JpGraphError::RaiseL(15009);//("Sum of all data is 0 for Pie."); } // Set up the pie-circle if( $this->radius <= 1 ) { $radius = floor($this->radius*min($img->width,$img->height)); } else { $radius = $aaoption === 1 ? $this->radius*2 : $this->radius; } if( $this->posx <= 1 && $this->posx > 0 ) { $xc = round($this->posx*$img->width); } else { $xc = $this->posx ; } if( $this->posy <= 1 && $this->posy > 0 ) { $yc = round($this->posy*$img->height); } else { $yc = $this->posy ; } $n = count($this->data); if( $this->explode_all ) { for($i=0; $i < $n; ++$i) { $this->explode_radius[$i]=$this->explode_r; } } // If we have a shadow and not just drawing the labels if( $this->ishadowcolor != "" && $aaoption !== 2) { $accsum=0; $angle2 = $this->startangle; $img->SetColor($this->ishadowcolor); for($i=0; $sum > 0 && $i < $n; ++$i) { $j = $n-$i-1; $d = $this->data[$i]; $angle1 = $angle2; $accsum += $d; $angle2 = $this->startangle+2*M_PI*$accsum/$sum; if( empty($this->explode_radius[$j]) ) { $this->explode_radius[$j]=0; } if( $d < 0.00001 ) continue; $la = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1); $xcm = $xc + $this->explode_radius[$j]*cos($la)*$expscale; $ycm = $yc - $this->explode_radius[$j]*sin($la)*$expscale; $xcm += $this->ishadowdrop*$expscale; $ycm += $this->ishadowdrop*$expscale; $_sa = round($angle1*180/M_PI); $_ea = round($angle2*180/M_PI); // The CakeSlice method draws a full circle in case of start angle = end angle // for pie slices we don't want this behaviour unless we only have one // slice in the pie in case it is the wanted behaviour if( $_ea-$_sa > 0.1 || $n==1 ) { $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1, $angle1*180/M_PI,$angle2*180/M_PI,$this->ishadowcolor); } } } //-------------------------------------------------------------------------------- // This is the main loop to draw each cake slice //-------------------------------------------------------------------------------- // Set up the accumulated sum, start angle for first slice and border color $accsum=0; $angle2 = $this->startangle; $img->SetColor($this->color); // Loop though all the slices if there is a pie to draw (sum>0) // There are n slices in total for($i=0; $sum>0 && $i < $n; ++$i) { // $j is the actual index used for the slice $j = $n-$i-1; // Make sure we havea valid distance to explode the slice if( empty($this->explode_radius[$j]) ) { $this->explode_radius[$j]=0; } // The actual numeric value for the slice $d = $this->data[$i]; $angle1 = $angle2; // Accumlate the sum $accsum += $d; // The new angle when we add the "size" of this slice // angle1 is then the start and angle2 the end of this slice $angle2 = $this->NormAngle($this->startangle+2*M_PI*$accsum/$sum); // We avoid some trouble by not allowing end angle to be 0, in that case // we translate to 360 // la is used to hold the label angle, which is centered on the slice if( $angle2 < 0.0001 && $angle1 > 0.0001 ) { $this->la[$i] = 2*M_PI - (abs(2*M_PI-$angle1)/2.0+$angle1); } elseif( $angle1 > $angle2 ) { // The case where the slice crosses the 3 a'clock line // Remember that the slices are counted clockwise and // labels are counted counter clockwise so we need to revert with 2 PI $this->la[$i] = 2*M_PI-$this->NormAngle($angle1 + ((2*M_PI - $angle1)+$angle2)/2); } else { $this->la[$i] = 2*M_PI - (abs($angle2-$angle1)/2.0+$angle1); } // Too avoid rounding problems we skip the slice if it is too small if( $d < 0.00001 ) continue; // If the user has specified an array of colors for each slice then use // that a color otherwise use the theme array (ta) of colors if( $this->setslicecolors==null ) { $slicecolor=$colors[$ta[$i%$numcolors]]; } else { $slicecolor=$this->setslicecolors[$i%$numcolors]; } // $_sa = round($angle1*180/M_PI); // $_ea = round($angle2*180/M_PI); // $_la = round($this->la[$i]*180/M_PI); // echo "Slice#$i: ang1=$_sa , ang2=$_ea, la=$_la, color=$slicecolor
    "; // If we have enabled antialias then we don't draw any border so // make the bordedr color the same as the slice color if( $this->pie_interior_border && $aaoption===0 ) { $img->SetColor($this->color); } else { $img->SetColor($slicecolor); } $arccolor = $this->pie_border && $aaoption===0 ? $this->color : ""; // Calculate the x,y coordinates for the base of this slice taking // the exploded distance into account. Here we use the mid angle as the // ray of extension and we have the mid angle handy as it is also the // label angle $xcm = $xc + $this->explode_radius[$j]*cos($this->la[$i])*$expscale; $ycm = $yc - $this->explode_radius[$j]*sin($this->la[$i])*$expscale; // If we are not just drawing the labels then draw this cake slice if( $aaoption !== 2 ) { $_sa = round($angle1*180/M_PI); $_ea = round($angle2*180/M_PI); $_la = round($this->la[$i]*180/M_PI); //echo "[$i] sa=$_sa, ea=$_ea, la[$i]=$_la, (color=$slicecolor)
    "; // The CakeSlice method draws a full circle in case of start angle = end angle // for pie slices we want this in case the slice have a value larger than 99% of the // total sum if( abs($_ea-$_sa) >= 1 || $d == $sum ) { $img->CakeSlice($xcm,$ycm,$radius-1,$radius-1,$_sa,$_ea,$slicecolor,$arccolor); } } // If the CSIM is used then make sure we register a CSIM area for this slice as well if( $this->csimtargets && $aaoption !== 1 ) { $this->AddSliceToCSIM($i,$xcm,$ycm,$radius,$angle1,$angle2); } } // Format the titles for each slice if( $aaoption !== 2 ) { for( $i=0; $i < $n; ++$i) { if( $this->labeltype==0 ) { if( $sum != 0 ) $l = 100.0*$this->data[$i]/$sum; else $l = 0.0; } elseif( $this->labeltype==1 ) { $l = $this->data[$i]*1.0; } else { $l = $this->adjusted_data[$i]; } if( isset($this->labels[$i]) && is_string($this->labels[$i]) ) $this->labels[$i]=sprintf($this->labels[$i],$l); else $this->labels[$i]=$l; } } if( $this->value->show && $aaoption !== 1 ) { $this->StrokeAllLabels($img,$xc,$yc,$radius); } // Adjust title position if( $aaoption !== 1 ) { $this->title->SetPos($xc, $yc-$this->title->GetFontHeight($img)-$radius-$this->title->margin, "center","bottom"); $this->title->Stroke($img); } } //--------------- // PRIVATE METHODS function NormAngle($a) { while( $a < 0 ) $a += 2*M_PI; while( $a > 2*M_PI ) $a -= 2*M_PI; return $a; } function Quadrant($a) { $a=$this->NormAngle($a); if( $a > 0 && $a <= M_PI/2 ) return 0; if( $a > M_PI/2 && $a <= M_PI ) return 1; if( $a > M_PI && $a <= 1.5*M_PI ) return 2; if( $a > 1.5*M_PI ) return 3; } function StrokeGuideLabels($img,$xc,$yc,$radius) { $n = count($this->labels); //----------------------------------------------------------------------- // Step 1 of the algorithm is to construct a number of clusters // a cluster is defined as all slices within the same quadrant (almost) // that has an angular distance less than the treshold //----------------------------------------------------------------------- $tresh_hold=25 * M_PI/180; // 25 degrees difference to be in a cluster $incluster=false; // flag if we are currently in a cluster or not $clusters = array(); // array of clusters $cidx=-1; // running cluster index // Go through all the labels and construct a number of clusters for($i=0; $i < $n-1; ++$i) { // Calc the angle distance between two consecutive slices $a1=$this->la[$i]; $a2=$this->la[$i+1]; $q1 = $this->Quadrant($a1); $q2 = $this->Quadrant($a2); $diff = abs($a1-$a2); if( $diff < $tresh_hold ) { if( $incluster ) { $clusters[$cidx][1]++; // Each cluster can only cover one quadrant // Do we cross a quadrant ( and must break the cluster) if( $q1 != $q2 ) { // If we cross a quadrant boundary we normally start a // new cluster. However we need to take the 12'a clock // and 6'a clock positions into a special consideration. // Case 1: WE go from q=1 to q=2 if the last slice on // the cluster for q=1 is close to 12'a clock and the // first slice in q=0 is small we extend the previous // cluster if( $q1 == 1 && $q2 == 0 && $a2 > (90-15)*M_PI/180 ) { if( $i < $n-2 ) { $a3 = $this->la[$i+2]; // If there isn't a cluster coming up with the next-next slice // we extend the previous cluster to cover this slice as well if( abs($a3-$a2) >= $tresh_hold ) { $clusters[$cidx][1]++; $i++; } } } elseif( $q1 == 3 && $q2 == 2 && $a2 > (270-15)*M_PI/180 ) { if( $i < $n-2 ) { $a3 = $this->la[$i+2]; // If there isn't a cluster coming up with the next-next slice // we extend the previous cluster to cover this slice as well if( abs($a3-$a2) >= $tresh_hold ) { $clusters[$cidx][1]++; $i++; } } } if( $q1==2 && $q2==1 && $a2 > (180-15)*M_PI/180 ) { $clusters[$cidx][1]++; $i++; } $incluster = false; } } elseif( $q1 == $q2) { $incluster = true; // Now we have a special case for quadrant 0. If we previously // have a cluster of one in quadrant 0 we just extend that // cluster. If we don't do this then we risk that the label // for the cluster of one will cross the guide-line if( $q1 == 0 && $cidx > -1 && $clusters[$cidx][1] == 1 && $this->Quadrant($this->la[$clusters[$cidx][0]]) == 0 ) { $clusters[$cidx][1]++; } else { $cidx++; $clusters[$cidx][0] = $i; $clusters[$cidx][1] = 1; } } else { // Create a "cluster" of one since we are just crossing // a quadrant $cidx++; $clusters[$cidx][0] = $i; $clusters[$cidx][1] = 1; } } else { if( $incluster ) { // Add the last slice $clusters[$cidx][1]++; $incluster = false; } else { // Create a "cluster" of one $cidx++; $clusters[$cidx][0] = $i; $clusters[$cidx][1] = 1; } } } // Handle the very last slice if( $incluster ) { $clusters[$cidx][1]++; } else { // Create a "cluster" of one $cidx++; $clusters[$cidx][0] = $i; $clusters[$cidx][1] = 1; } /* if( true ) { // Debug printout in labels for( $i=0; $i <= $cidx; ++$i ) { for( $j=0; $j < $clusters[$i][1]; ++$j ) { $a = $this->la[$clusters[$i][0]+$j]; $aa = round($a*180/M_PI); $q = $this->Quadrant($a); $this->labels[$clusters[$i][0]+$j]="[$q:$aa] $i:$j"; } } } */ //----------------------------------------------------------------------- // Step 2 of the algorithm is use the clusters and draw the labels // and guidelines //----------------------------------------------------------------------- // We use the font height as the base factor for how far we need to // spread the labels in the Y-direction. $this->value->ApplyFont($img); $fh = $img->GetFontHeight(); $origvstep=$fh*$this->iGuideVFactor; $this->value->SetMargin(0); // Number of clusters found $nc = count($clusters); // Walk through all the clusters for($i=0; $i < $nc; ++$i) { // Start angle and number of slices in this cluster $csize = $clusters[$i][1]; $a = $this->la[$clusters[$i][0]]; $q = $this->Quadrant($a); // Now set up the start and end conditions to make sure that // in each cluster we walk through the all the slices starting with the slice // closest to the equator. Since all slices are numbered clockwise from "3'a clock" // we have different conditions depending on in which quadrant the slice lies within. if( $q == 0 ) { $start = $csize-1; $idx = $start; $step = -1; $vstep = -$origvstep; } elseif( $q == 1 ) { $start = 0; $idx = $start; $step = 1; $vstep = -$origvstep; } elseif( $q == 2 ) { $start = $csize-1; $idx = $start; $step = -1; $vstep = $origvstep; } elseif( $q == 3 ) { $start = 0; $idx = $start; $step = 1; $vstep = $origvstep; } // Walk through all slices within this cluster for($j=0; $j < $csize; ++$j) { // Now adjust the position of the labels in each cluster starting // with the slice that is closest to the equator of the pie $a = $this->la[$clusters[$i][0]+$idx]; // Guide line start in the center of the arc of the slice $r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)]; $x = round($r*cos($a)+$xc); $y = round($yc-$r*sin($a)); // The distance from the arc depends on chosen font and the "R-Factor" $r += $fh*$this->iGuideLineRFactor; // Should the labels be placed curved along the pie or in straight columns // outside the pie? if( $this->iGuideLineCurve ) $xt=round($r*cos($a)+$xc); // If this is the first slice in the cluster we need some first time // proessing if( $idx == $start ) { if( ! $this->iGuideLineCurve ) $xt=round($r*cos($a)+$xc); $yt=round($yc-$r*sin($a)); // Some special consideration in case this cluster starts // in quadrant 1 or 3 very close to the "equator" (< 20 degrees) // and the previous clusters last slice is within the tolerance. // In that case we add a font height to this labels Y-position // so it doesn't collide with // the slice in the previous cluster $prevcluster = ($i + ($nc-1) ) % $nc; $previdx=$clusters[$prevcluster][0]+$clusters[$prevcluster][1]-1; if( $q == 1 && $a > 160*M_PI/180 ) { // Get the angle for the previous clusters last slice $diff = abs($a-$this->la[$previdx]); if( $diff < $tresh_hold ) { $yt -= $fh; } } elseif( $q == 3 && $a > 340*M_PI/180 ) { // We need to subtract 360 to compare angle distance between // q=0 and q=3 $diff = abs($a-$this->la[$previdx]-360*M_PI/180); if( $diff < $tresh_hold ) { $yt += $fh; } } } else { // The step is at minimum $vstep but if the slices are relatively large // we make sure that we add at least a step that corresponds to the vertical // distance between the centers at the arc on the slice $prev_a = $this->la[$clusters[$i][0]+($idx-$step)]; $dy = abs($radius*(sin($a)-sin($prev_a))*1.2); if( $vstep > 0 ) $yt += max($vstep,$dy); else $yt += min($vstep,-$dy); } $label = $this->labels[$clusters[$i][0]+$idx]; if( $csize == 1 ) { // A "meta" cluster with only one slice $r = $radius+$this->explode_radius[$n-1-($clusters[$i][0]+$idx)]; $rr = $r+$img->GetFontHeight()/2; $xt=round($rr*cos($a)+$xc); $yt=round($yc-$rr*sin($a)); $this->StrokeLabel($label,$img,$xc,$yc,$a,$r); if( $this->iShowGuideLineForSingle ) $this->guideline->Stroke($img,$x,$y,$xt,$yt); } else { $this->guideline->Stroke($img,$x,$y,$xt,$yt); if( $q==1 || $q==2 ) { // Left side of Pie $this->guideline->Stroke($img,$xt,$yt,$xt-$this->guidelinemargin,$yt); $lbladj = -$this->guidelinemargin-5; $this->value->halign = "right"; $this->value->valign = "center"; } else { // Right side of pie $this->guideline->Stroke($img,$xt,$yt,$xt+$this->guidelinemargin,$yt); $lbladj = $this->guidelinemargin+5; $this->value->halign = "left"; $this->value->valign = "center"; } $this->value->Stroke($img,$label,$xt+$lbladj,$yt); } // Udate idx to point to next slice in the cluster to process $idx += $step; } } } function StrokeAllLabels($img,$xc,$yc,$radius) { // First normalize all angles for labels $n = count($this->la); for($i=0; $i < $n; ++$i) { $this->la[$i] = $this->NormAngle($this->la[$i]); } if( $this->guideline->iShow ) { $this->StrokeGuideLabels($img,$xc,$yc,$radius); } else { $n = count($this->labels); for($i=0; $i < $n; ++$i) { $this->StrokeLabel($this->labels[$i],$img,$xc,$yc, $this->la[$i], $radius + $this->explode_radius[$n-1-$i]); } } } // Position the labels of each slice function StrokeLabel($label,$img,$xc,$yc,$a,$r) { // Default value if( $this->ilabelposadj === 'auto' ) $this->ilabelposadj = 0.65; // We position the values diferently depending on if they are inside // or outside the pie if( $this->ilabelposadj < 1.0 ) { $this->value->SetAlign('center','center'); $this->value->margin = 0; $xt=round($this->ilabelposadj*$r*cos($a)+$xc); $yt=round($yc-$this->ilabelposadj*$r*sin($a)); $this->value->Stroke($img,$label,$xt,$yt); } else { $this->value->halign = "left"; $this->value->valign = "top"; $this->value->margin = 0; // Position the axis title. // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text // that intersects with the extension of the corresponding axis. The code looks a little // bit messy but this is really the only way of having a reasonable position of the // axis titles. $this->value->ApplyFont($img); $h=$img->GetTextHeight($label); // For numeric values the format of the display value // must be taken into account if( is_numeric($label) ) { if( $label > 0 ) $w=$img->GetTextWidth(sprintf($this->value->format,$label)); else $w=$img->GetTextWidth(sprintf($this->value->negformat,$label)); } else $w=$img->GetTextWidth($label); if( $this->ilabelposadj > 1.0 && $this->ilabelposadj < 5.0) { $r *= $this->ilabelposadj; } $r += $img->GetFontHeight()/1.5; $xt=round($r*cos($a)+$xc); $yt=round($yc-$r*sin($a)); // Normalize angle while( $a < 0 ) $a += 2*M_PI; while( $a > 2*M_PI ) $a -= 2*M_PI; if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0; if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI; if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1; if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI); if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI; if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI); if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1; if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI); if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0; $this->value->Stroke($img,$label,$xt-$dx*$w,$yt-$dy*$h); } } } // Class //=================================================== // CLASS PiePlotC // Description: Same as a normal pie plot but with a // filled circle in the center //=================================================== class PiePlotC extends PiePlot { private $imidsize=0.5; // Fraction of total width private $imidcolor='white'; public $midtitle=''; private $middlecsimtarget='',$middlecsimwintarget='',$middlecsimalt=''; function __construct($data,$aCenterTitle='') { parent::__construct($data); $this->midtitle = new Text(); $this->midtitle->ParagraphAlign('center'); } function SetMid($aTitle,$aColor='white',$aSize=0.5) { $this->midtitle->Set($aTitle); $this->imidsize = $aSize ; $this->imidcolor = $aColor ; } function SetMidTitle($aTitle) { $this->midtitle->Set($aTitle); } function SetMidSize($aSize) { $this->imidsize = $aSize ; } function SetMidColor($aColor) { $this->imidcolor = $aColor ; } function SetMidCSIM($aTarget,$aAlt='',$aWinTarget='') { $this->middlecsimtarget = $aTarget; $this->middlecsimwintarget = $aWinTarget; $this->middlecsimalt = $aAlt; } function AddSliceToCSIM($i,$xc,$yc,$radius,$sa,$ea) { //Slice number, ellipse centre (x,y), radius, start angle, end angle while( $sa > 2*M_PI ) $sa = $sa - 2*M_PI; while( $ea > 2*M_PI ) $ea = $ea - 2*M_PI; $sa = 2*M_PI - $sa; $ea = 2*M_PI - $ea; // Special case when we have only one slice since then both start and end // angle will be == 0 if( abs($sa - $ea) < 0.0001 ) { $sa=2*M_PI; $ea=0; } // Add inner circle first point $xp = floor(($this->imidsize*$radius*cos($ea))+$xc); $yp = floor($yc-($this->imidsize*$radius*sin($ea))); $coords = "$xp, $yp"; //add coordinates every 0.25 radians $a=$ea+0.25; // If we cross the 360-limit with a slice we need to handle // the fact that end angle is smaller than start if( $sa < $ea ) { while ($a <= 2*M_PI) { $xp = floor($radius*cos($a)+$xc); $yp = floor($yc-$radius*sin($a)); $coords.= ", $xp, $yp"; $a += 0.25; } $a -= 2*M_PI; } while ($a < $sa) { $xp = floor(($this->imidsize*$radius*cos($a)+$xc)); $yp = floor($yc-($this->imidsize*$radius*sin($a))); $coords.= ", $xp, $yp"; $a += 0.25; } // Make sure we end at the last point $xp = floor(($this->imidsize*$radius*cos($sa)+$xc)); $yp = floor($yc-($this->imidsize*$radius*sin($sa))); $coords.= ", $xp, $yp"; // Straight line to outer circle $xp = floor($radius*cos($sa)+$xc); $yp = floor($yc-$radius*sin($sa)); $coords.= ", $xp, $yp"; //add coordinates every 0.25 radians $a=$sa - 0.25; while ($a > $ea) { $xp = floor($radius*cos($a)+$xc); $yp = floor($yc-$radius*sin($a)); $coords.= ", $xp, $yp"; $a -= 0.25; } //Add the last point on the arc $xp = floor($radius*cos($ea)+$xc); $yp = floor($yc-$radius*sin($ea)); $coords.= ", $xp, $yp"; // Close the arc $xp = floor(($this->imidsize*$radius*cos($ea))+$xc); $yp = floor($yc-($this->imidsize*$radius*sin($ea))); $coords .= ", $xp, $yp"; if( !empty($this->csimtargets[$i]) ) { $this->csimareas .= "csimtargets[$i]."\""; if( !empty($this->csimwintargets[$i]) ) { $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; } if( !empty($this->csimalts[$i]) ) { $tmp=sprintf($this->csimalts[$i],$this->data[$i]); $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; } $this->csimareas .= " />\n"; } } function Stroke($img,$aaoption=0) { // Stroke the pie but don't stroke values $tmp = $this->value->show; $this->value->show = false; parent::Stroke($img,$aaoption); $this->value->show = $tmp; $xc = round($this->posx*$img->width); $yc = round($this->posy*$img->height); $radius = floor($this->radius * min($img->width,$img->height)) ; if( $this->imidsize > 0 && $aaoption !== 2 ) { if( $this->ishadowcolor != "" ) { $img->SetColor($this->ishadowcolor); $img->FilledCircle($xc+$this->ishadowdrop,$yc+$this->ishadowdrop, round($radius*$this->imidsize)); } $img->SetColor($this->imidcolor); $img->FilledCircle($xc,$yc,round($radius*$this->imidsize)); if( $this->pie_border && $aaoption === 0 ) { $img->SetColor($this->color); $img->Circle($xc,$yc,round($radius*$this->imidsize)); } if( !empty($this->middlecsimtarget) ) $this->AddMiddleCSIM($xc,$yc,round($radius*$this->imidsize)); } if( $this->value->show && $aaoption !== 1) { $this->StrokeAllLabels($img,$xc,$yc,$radius); $this->midtitle->SetPos($xc,$yc,'center','center'); $this->midtitle->Stroke($img); } } function AddMiddleCSIM($xc,$yc,$r) { $xc=round($xc);$yc=round($yc);$r=round($r); $this->csimareas .= "middlecsimtarget."\""; if( !empty($this->middlecsimwintarget) ) { $this->csimareas .= " target=\"".$this->middlecsimwintarget."\""; } if( !empty($this->middlecsimalt) ) { $tmp = $this->middlecsimalt; $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; } $this->csimareas .= " />\n"; } function StrokeLabel($label,$img,$xc,$yc,$a,$r) { if( $this->ilabelposadj === 'auto' ) $this->ilabelposadj = (1-$this->imidsize)/2+$this->imidsize; parent::StrokeLabel($label,$img,$xc,$yc,$a,$r); } } //=================================================== // CLASS PieGraph // Description: //=================================================== class PieGraph extends Graph { private $posx, $posy, $radius; private $legends=array(); public $plots=array(); public $pieaa = false ; //--------------- // CONSTRUCTOR function __construct($width=300,$height=200,$cachedName="",$timeout=0,$inline=1) { parent::__construct($width,$height,$cachedName,$timeout,$inline); $this->posx=$width/2; $this->posy=$height/2; $this->SetColor(array(255,255,255)); } //--------------- // PUBLIC METHODS function Add($aObj) { if( is_array($aObj) && count($aObj) > 0 ) $cl = $aObj[0]; else $cl = $aObj; if( $cl instanceof Text ) $this->AddText($aObj); elseif( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) $this->AddIcon($aObj); else { if( is_array($aObj) ) { $n = count($aObj); for($i=0; $i < $n; ++$i ) { $this->plots[] = $aObj[$i]; } } else { $this->plots[] = $aObj; } } } function SetAntiAliasing($aFlg=true) { $this->pieaa = $aFlg; } function SetColor($c) { $this->SetMarginColor($c); } function DisplayCSIMAreas() { $csim=""; foreach($this->plots as $p ) { $csim .= $p->GetCSIMareas(); } $csim.= $this->legend->GetCSIMareas(); if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) { $this->img->SetColor($this->csimcolor); $n = count($coords[0]); for ($i=0; $i < $n; $i++) { if ($coords[1][$i]=="poly") { preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts); $this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]); $m = count($pts[0]); for ($j=0; $j < $m; $j++) { $this->img->LineTo($pts[1][$j],$pts[2][$j]); } } else if ($coords[1][$i]=="rect") { $pts = preg_split('/,/', $coords[2][$i]); $this->img->SetStartPoint($pts[0],$pts[1]); $this->img->LineTo($pts[2],$pts[1]); $this->img->LineTo($pts[2],$pts[3]); $this->img->LineTo($pts[0],$pts[3]); $this->img->LineTo($pts[0],$pts[1]); } } } } // Method description function Stroke($aStrokeFileName="") { // If the filename is the predefined value = '_csim_special_' // we assume that the call to stroke only needs to do enough // to correctly generate the CSIM maps. // We use this variable to skip things we don't strictly need // to do to generate the image map to improve performance // a best we can. Therefor you will see a lot of tests !$_csim in the // code below. $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); // If we are called the second time (perhaps the user has called GetHTMLImageMap() // himself then the legends have alsready been populated once in order to get the // CSIM coordinats. Since we do not want the legends to be populated a second time // we clear the legends $this->legend->Clear(); // We need to know if we have stroked the plot in the // GetCSIMareas. Otherwise the CSIM hasn't been generated // and in the case of GetCSIM called before stroke to generate // CSIM without storing an image to disk GetCSIM must call Stroke. $this->iHasStroked = true; $n = count($this->plots); if( $this->pieaa ) { if( !$_csim ) { if( $this->background_image != "" ) { $this->StrokeFrameBackground(); } else { $this->StrokeFrame(); $this->StrokeBackgroundGrad(); } } $w = $this->img->width; $h = $this->img->height; $oldimg = $this->img->img; $this->img->CreateImgCanvas(2*$w,2*$h); $this->img->SetColor( $this->margin_color ); $this->img->FilledRectangle(0,0,2*$w-1,2*$h-1); // Make all icons *2 i size since we will be scaling down the // imahe to do the anti aliasing $ni = count($this->iIcons); for($i=0; $i < $ni; ++$i) { $this->iIcons[$i]->iScale *= 2 ; if( $this->iIcons[$i]->iX > 1 ) $this->iIcons[$i]->iX *= 2 ; if( $this->iIcons[$i]->iY > 1 ) $this->iIcons[$i]->iY *= 2 ; } $this->StrokeIcons(); for($i=0; $i < $n; ++$i) { if( $this->plots[$i]->posx > 1 ) $this->plots[$i]->posx *= 2 ; if( $this->plots[$i]->posy > 1 ) $this->plots[$i]->posy *= 2 ; $this->plots[$i]->Stroke($this->img,1); if( $this->plots[$i]->posx > 1 ) $this->plots[$i]->posx /= 2 ; if( $this->plots[$i]->posy > 1 ) $this->plots[$i]->posy /= 2 ; } $indent = $this->doframe ? ($this->frame_weight + ($this->doshadow ? $this->shadow_width : 0 )) : 0 ; $indent += $this->framebevel ? $this->framebeveldepth + 1 : 0 ; $this->img->CopyCanvasH($oldimg,$this->img->img,$indent,$indent,$indent,$indent, $w-2*$indent,$h-2*$indent,2*($w-$indent),2*($h-$indent)); $this->img->img = $oldimg ; $this->img->width = $w ; $this->img->height = $h ; for($i=0; $i < $n; ++$i) { $this->plots[$i]->Stroke($this->img,2); // Stroke labels $this->plots[$i]->Legend($this); } } else { if( !$_csim ) { if( $this->background_image != "" ) { $this->StrokeFrameBackground(); } else { $this->StrokeFrame(); $this->StrokeBackgroundGrad(); } } $this->StrokeIcons(); for($i=0; $i < $n; ++$i) { $this->plots[$i]->Stroke($this->img); $this->plots[$i]->Legend($this); } } $this->legend->Stroke($this->img); $this->footer->Stroke($this->img); $this->StrokeTitles(); if( !$_csim ) { // Stroke texts if( $this->texts != null ) { $n = count($this->texts); for($i=0; $i < $n; ++$i ) { $this->texts[$i]->Stroke($this->img); } } if( _JPG_DEBUG ) { $this->DisplayCSIMAreas(); } // Should we do any final image transformation if( $this->iImgTrans ) { if( !class_exists('ImgTrans',false) ) { require_once('jpgraph_imgtrans.php'); //JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.'); } $tform = new ImgTrans($this->img->img); $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, $this->iImgTransDirection,$this->iImgTransHighQ, $this->iImgTransMinSize,$this->iImgTransFillColor, $this->iImgTransBorder); } // If the filename is given as the special "__handle" // then the image handler is returned and the image is NOT // streamed back if( $aStrokeFileName == _IMG_HANDLER ) { return $this->img->img; } else { // Finally stream the generated picture $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline, $aStrokeFileName); } } } } // Class /* EOF */ ?> loganalyzer-3.6.5/src/classes/jpgraph/lang/0000755000175000017500000000000012225176641020134 5ustar danieldanielloganalyzer-3.6.5/src/classes/jpgraph/lang/prod.inc.php0000644000175000017500000004471512225176641022374 0ustar danieldaniel,) $_jpg_messages = array( /* ** Headers already sent error. This is formatted as HTML different since this will be sent back directly as text */ 10 => array('
    JpGraph Error: HTTP headers have already been sent.
    Caused by output from file %s at line %d.
    Explanation:
    HTTP headers have already been sent back to the browser indicating the data as text before the library got a chance to send it\'s image HTTP header to this browser. This makes it impossible for the library to send back image data to the browser (since that would be interpretated as text by the browser and show up as junk text).

    Most likely you have some text in your script before the call to Graph::Stroke(). If this texts gets sent back to the browser the browser will assume that all data is plain text. Look for any text, even spaces and newlines, that might have been sent back to the browser.

    For example it is a common mistake to leave a blank line before the opening "<?php".

    ',2), 11 => array(DEFAULT_ERROR_MESSAGE.'11',0), 12 => array(DEFAULT_ERROR_MESSAGE.'12',0), 13 => array(DEFAULT_ERROR_MESSAGE.'13',0), 2001 => array(DEFAULT_ERROR_MESSAGE.'2001',0), 2002 => array(DEFAULT_ERROR_MESSAGE.'2002',0), 2003 => array(DEFAULT_ERROR_MESSAGE.'2003',0), 2004 => array(DEFAULT_ERROR_MESSAGE.'2004',0), 2005 => array(DEFAULT_ERROR_MESSAGE.'2005',0), 2006 => array(DEFAULT_ERROR_MESSAGE.'2006',0), 2007 => array(DEFAULT_ERROR_MESSAGE.'2007',0), 2008 => array(DEFAULT_ERROR_MESSAGE.'2008',0), 2009 => array(DEFAULT_ERROR_MESSAGE.'2009',0), 2010 => array(DEFAULT_ERROR_MESSAGE.'2010',0), 2011 => array(DEFAULT_ERROR_MESSAGE.'2011',0), 2012 => array(DEFAULT_ERROR_MESSAGE.'2012',0), 2013 => array(DEFAULT_ERROR_MESSAGE.'2013',0), 2014 => array(DEFAULT_ERROR_MESSAGE.'2014',0), 3001 => array(DEFAULT_ERROR_MESSAGE.'3001',0), 4002 => array(DEFAULT_ERROR_MESSAGE.'4002',0), 5001 => array(DEFAULT_ERROR_MESSAGE.'5001',0), 5002 => array(DEFAULT_ERROR_MESSAGE.'5002',0), 5003 => array(DEFAULT_ERROR_MESSAGE.'5003',0), 5004 => array(DEFAULT_ERROR_MESSAGE.'5004',0), 6001 => array(DEFAULT_ERROR_MESSAGE.'6001',0), 6002 => array(DEFAULT_ERROR_MESSAGE.'6002',0), 6003 => array(DEFAULT_ERROR_MESSAGE.'6003',0), 6004 => array(DEFAULT_ERROR_MESSAGE.'6004',0), 6005 => array(DEFAULT_ERROR_MESSAGE.'6005',0), 6006 => array(DEFAULT_ERROR_MESSAGE.'6006',0), 6007 => array(DEFAULT_ERROR_MESSAGE.'6007',0), 6008 => array(DEFAULT_ERROR_MESSAGE.'6008',0), 6009 => array(DEFAULT_ERROR_MESSAGE.'6009',0), 6010 => array(DEFAULT_ERROR_MESSAGE.'6010',0), 6011 => array(DEFAULT_ERROR_MESSAGE.'6011',0), 6012 => array(DEFAULT_ERROR_MESSAGE.'6012',0), 6015 => array(DEFAULT_ERROR_MESSAGE.'6015',0), 6016 => array(DEFAULT_ERROR_MESSAGE.'6016',0), 6017 => array(DEFAULT_ERROR_MESSAGE.'6017',0), 6018 => array(DEFAULT_ERROR_MESSAGE.'6018',0), 6019 => array(DEFAULT_ERROR_MESSAGE.'6019',0), 6020 => array(DEFAULT_ERROR_MESSAGE.'6020',0), 6021 => array(DEFAULT_ERROR_MESSAGE.'6021',0), 6022 => array(DEFAULT_ERROR_MESSAGE.'6022',0), 6023 => array(DEFAULT_ERROR_MESSAGE.'6023',0), 6024 => array(DEFAULT_ERROR_MESSAGE.'6024',0), 6025 => array(DEFAULT_ERROR_MESSAGE.'6025',0), 6027 => array(DEFAULT_ERROR_MESSAGE.'6027',0), 6028 => array(DEFAULT_ERROR_MESSAGE.'6028',0), 6029 => array(DEFAULT_ERROR_MESSAGE.'6029',0), 6030 => array(DEFAULT_ERROR_MESSAGE.'6030',0), 6031 => array(DEFAULT_ERROR_MESSAGE.'6031',0), 6032 => array(DEFAULT_ERROR_MESSAGE.'6032',0), 6033 => array(DEFAULT_ERROR_MESSAGE.'6033',0), 7001 => array(DEFAULT_ERROR_MESSAGE.'7001',0), 8001 => array(DEFAULT_ERROR_MESSAGE.'8001',0), 8002 => array(DEFAULT_ERROR_MESSAGE.'8002',0), 8003 => array(DEFAULT_ERROR_MESSAGE.'8003',0), 8004 => array(DEFAULT_ERROR_MESSAGE.'8004',0), 9001 => array(DEFAULT_ERROR_MESSAGE.'9001',0), 10001 => array(DEFAULT_ERROR_MESSAGE.'10001',0), 10002 => array(DEFAULT_ERROR_MESSAGE.'10002',0), 10003 => array(DEFAULT_ERROR_MESSAGE.'10003',0), 11001 => array(DEFAULT_ERROR_MESSAGE.'11001',0), 11002 => array(DEFAULT_ERROR_MESSAGE.'11002',0), 11003 => array(DEFAULT_ERROR_MESSAGE.'11003',0), 11004 => array(DEFAULT_ERROR_MESSAGE.'11004',0), 11005 => array(DEFAULT_ERROR_MESSAGE.'11005',0), 12001 => array(DEFAULT_ERROR_MESSAGE.'12001',0), 12002 => array(DEFAULT_ERROR_MESSAGE.'12002',0), 12003 => array(DEFAULT_ERROR_MESSAGE.'12003',0), 12004 => array(DEFAULT_ERROR_MESSAGE.'12004',0), 12005 => array(DEFAULT_ERROR_MESSAGE.'12005',0), 12006 => array(DEFAULT_ERROR_MESSAGE.'12006',0), 12007 => array(DEFAULT_ERROR_MESSAGE.'12007',0), 12008 => array(DEFAULT_ERROR_MESSAGE.'12008',0), 12009 => array(DEFAULT_ERROR_MESSAGE.'12009',0), 12010 => array(DEFAULT_ERROR_MESSAGE.'12010',0), 12011 => array(DEFAULT_ERROR_MESSAGE.'12011',0), 12012 => array(DEFAULT_ERROR_MESSAGE.'12012',0), 14001 => array(DEFAULT_ERROR_MESSAGE.'14001',0), 14002 => array(DEFAULT_ERROR_MESSAGE.'14002',0), 14003 => array(DEFAULT_ERROR_MESSAGE.'14003',0), 14004 => array(DEFAULT_ERROR_MESSAGE.'14004',0), 14005 => array(DEFAULT_ERROR_MESSAGE.'14005',0), 14006 => array(DEFAULT_ERROR_MESSAGE.'14006',0), 14007 => array(DEFAULT_ERROR_MESSAGE.'14007',0), 15001 => array(DEFAULT_ERROR_MESSAGE.'15001',0), 15002 => array(DEFAULT_ERROR_MESSAGE.'15002',0), 15003 => array(DEFAULT_ERROR_MESSAGE.'15003',0), 15004 => array(DEFAULT_ERROR_MESSAGE.'15004',0), 15005 => array(DEFAULT_ERROR_MESSAGE.'15005',0), 15006 => array(DEFAULT_ERROR_MESSAGE.'15006',0), 15007 => array(DEFAULT_ERROR_MESSAGE.'15007',0), 15008 => array(DEFAULT_ERROR_MESSAGE.'15008',0), 15009 => array(DEFAULT_ERROR_MESSAGE.'15009',0), 15010 => array(DEFAULT_ERROR_MESSAGE.'15010',0), 15011 => array(DEFAULT_ERROR_MESSAGE.'15011',0), 16001 => array(DEFAULT_ERROR_MESSAGE.'16001',0), 16002 => array(DEFAULT_ERROR_MESSAGE.'16002',0), 16003 => array(DEFAULT_ERROR_MESSAGE.'16003',0), 16004 => array(DEFAULT_ERROR_MESSAGE.'16004',0), 17001 => array(DEFAULT_ERROR_MESSAGE.'17001',0), 17002 => array(DEFAULT_ERROR_MESSAGE.'17002',0), 17004 => array(DEFAULT_ERROR_MESSAGE.'17004',0), 18001 => array(DEFAULT_ERROR_MESSAGE.'18001',0), 18002 => array(DEFAULT_ERROR_MESSAGE.'18002',0), 18003 => array(DEFAULT_ERROR_MESSAGE.'18003',0), 18004 => array(DEFAULT_ERROR_MESSAGE.'18004',0), 18005 => array(DEFAULT_ERROR_MESSAGE.'18005',0), 18006 => array(DEFAULT_ERROR_MESSAGE.'18006',0), 18007 => array(DEFAULT_ERROR_MESSAGE.'18007',0), 18008 => array(DEFAULT_ERROR_MESSAGE.'18008',0), 19001 => array(DEFAULT_ERROR_MESSAGE.'19001',0), 19002 => array(DEFAULT_ERROR_MESSAGE.'19002',0), 19003 => array(DEFAULT_ERROR_MESSAGE.'19003',0), 20001 => array(DEFAULT_ERROR_MESSAGE.'20001',0), 20002 => array(DEFAULT_ERROR_MESSAGE.'20002',0), 20003 => array(DEFAULT_ERROR_MESSAGE.'20003',0), 21001 => array(DEFAULT_ERROR_MESSAGE.'21001',0), 23001 => array(DEFAULT_ERROR_MESSAGE.'23001',0), 23002 => array(DEFAULT_ERROR_MESSAGE.'23002',0), 23003 => array(DEFAULT_ERROR_MESSAGE.'23003',0), 24001 => array(DEFAULT_ERROR_MESSAGE.'24001',0), 24002 => array(DEFAULT_ERROR_MESSAGE.'24002',0), 24003 => array(DEFAULT_ERROR_MESSAGE.'24003',0), 24004 => array(DEFAULT_ERROR_MESSAGE.'24004',0), 25001 => array(DEFAULT_ERROR_MESSAGE.'25001',0), 25002 => array(DEFAULT_ERROR_MESSAGE.'25002',0), 25003 => array(DEFAULT_ERROR_MESSAGE.'25003',0), 25004 => array(DEFAULT_ERROR_MESSAGE.'25004',0), 25005 => array(DEFAULT_ERROR_MESSAGE.'25005',0), 25006 => array(DEFAULT_ERROR_MESSAGE.'25006',0), 25007 => array(DEFAULT_ERROR_MESSAGE.'25007',0), 25008 => array(DEFAULT_ERROR_MESSAGE.'25008',0), 25009 => array(DEFAULT_ERROR_MESSAGE.'25009',0), 25010 => array(DEFAULT_ERROR_MESSAGE.'25010',0), 25011 => array(DEFAULT_ERROR_MESSAGE.'25011',0), 25012 => array(DEFAULT_ERROR_MESSAGE.'25012',0), 25013 => array(DEFAULT_ERROR_MESSAGE.'25013',0), 25014 => array(DEFAULT_ERROR_MESSAGE.'25014',0), 25015 => array(DEFAULT_ERROR_MESSAGE.'25015',0), 25016 => array(DEFAULT_ERROR_MESSAGE.'25016',0), 25017 => array(DEFAULT_ERROR_MESSAGE.'25017',0), 25018 => array(DEFAULT_ERROR_MESSAGE.'25018',0), 25019 => array(DEFAULT_ERROR_MESSAGE.'25019',0), 25020 => array(DEFAULT_ERROR_MESSAGE.'25020',0), 25021 => array(DEFAULT_ERROR_MESSAGE.'25021',0), 25022 => array(DEFAULT_ERROR_MESSAGE.'25022',0), 25023 => array(DEFAULT_ERROR_MESSAGE.'25023',0), 25024 => array(DEFAULT_ERROR_MESSAGE.'25024',0), 25025 => array(DEFAULT_ERROR_MESSAGE.'25025',0), 25026 => array(DEFAULT_ERROR_MESSAGE.'25026',0), 25027 => array(DEFAULT_ERROR_MESSAGE.'25027',0), 25028 => array(DEFAULT_ERROR_MESSAGE.'25028',0), 25029 => array(DEFAULT_ERROR_MESSAGE.'25029',0), 25030 => array(DEFAULT_ERROR_MESSAGE.'25030',0), 25031 => array(DEFAULT_ERROR_MESSAGE.'25031',0), 25032 => array(DEFAULT_ERROR_MESSAGE.'25032',0), 25033 => array(DEFAULT_ERROR_MESSAGE.'25033',0), 25034 => array(DEFAULT_ERROR_MESSAGE.'25034',0), 25035 => array(DEFAULT_ERROR_MESSAGE.'25035',0), 25036 => array(DEFAULT_ERROR_MESSAGE.'25036',0), 25037 => array(DEFAULT_ERROR_MESSAGE.'25037',0), 25038 => array(DEFAULT_ERROR_MESSAGE.'25038',0), 25039 => array(DEFAULT_ERROR_MESSAGE.'25039',0), 25040 => array(DEFAULT_ERROR_MESSAGE.'25040',0), 25041 => array(DEFAULT_ERROR_MESSAGE.'25041',0), 25042 => array(DEFAULT_ERROR_MESSAGE.'25042',0), 25043 => array(DEFAULT_ERROR_MESSAGE.'25043',0), 25044 => array(DEFAULT_ERROR_MESSAGE.'25044',0), 25045 => array(DEFAULT_ERROR_MESSAGE.'25045',0), 25046 => array(DEFAULT_ERROR_MESSAGE.'25046',0), 25047 => array(DEFAULT_ERROR_MESSAGE.'25047',0), 25048 => array(DEFAULT_ERROR_MESSAGE.'25048',0), 25049 => array(DEFAULT_ERROR_MESSAGE.'25049',0), 25050 => array(DEFAULT_ERROR_MESSAGE.'25050',0), 25051 => array(DEFAULT_ERROR_MESSAGE.'25051',0), 25052 => array(DEFAULT_ERROR_MESSAGE.'25052',0), 25053 => array(DEFAULT_ERROR_MESSAGE.'25053',0), 25054 => array(DEFAULT_ERROR_MESSAGE.'25054',0), 25055 => array(DEFAULT_ERROR_MESSAGE.'25055',0), 25056 => array(DEFAULT_ERROR_MESSAGE.'25056',0), 25057 => array(DEFAULT_ERROR_MESSAGE.'25057',0), 25058 => array(DEFAULT_ERROR_MESSAGE.'25058',0), 25059 => array(DEFAULT_ERROR_MESSAGE.'25059',0), 25060 => array(DEFAULT_ERROR_MESSAGE.'25060',0), 25061 => array(DEFAULT_ERROR_MESSAGE.'25061',0), 25062 => array(DEFAULT_ERROR_MESSAGE.'25062',0), 25063 => array(DEFAULT_ERROR_MESSAGE.'25063',0), 25064 => array(DEFAULT_ERROR_MESSAGE.'25064',0), 25065 => array(DEFAULT_ERROR_MESSAGE.'25065',0), 25066 => array(DEFAULT_ERROR_MESSAGE.'25066',0), 25067 => array(DEFAULT_ERROR_MESSAGE.'25067',0), 25068 => array(DEFAULT_ERROR_MESSAGE.'25068',0), 25069 => array(DEFAULT_ERROR_MESSAGE.'25069',0), 25070 => array(DEFAULT_ERROR_MESSAGE.'25070',0), 25071 => array(DEFAULT_ERROR_MESSAGE.'25071',0), 25072 => array(DEFAULT_ERROR_MESSAGE.'25072',0), 25073 => array(DEFAULT_ERROR_MESSAGE.'25073',0), 25074 => array(DEFAULT_ERROR_MESSAGE.'25074',0), 25075 => array(DEFAULT_ERROR_MESSAGE.'25075',0), 25077 => array(DEFAULT_ERROR_MESSAGE.'25077',0), 25078 => array(DEFAULT_ERROR_MESSAGE.'25078',0), 25079 => array(DEFAULT_ERROR_MESSAGE.'25079',0), 25080 => array(DEFAULT_ERROR_MESSAGE.'25080',0), 25081 => array(DEFAULT_ERROR_MESSAGE.'25081',0), 25082 => array(DEFAULT_ERROR_MESSAGE.'25082',0), 25083 => array(DEFAULT_ERROR_MESSAGE.'25083',0), 25084 => array(DEFAULT_ERROR_MESSAGE.'25084',0), 25085 => array(DEFAULT_ERROR_MESSAGE.'25085',0), 25086 => array(DEFAULT_ERROR_MESSAGE.'25086',0), 25087 => array(DEFAULT_ERROR_MESSAGE.'25087',0), 25088 => array(DEFAULT_ERROR_MESSAGE.'25088',0), 25089 => array(DEFAULT_ERROR_MESSAGE.'25089',0), 25090 => array(DEFAULT_ERROR_MESSAGE.'25090',0), 25091 => array(DEFAULT_ERROR_MESSAGE.'25091',0), 25092 => array(DEFAULT_ERROR_MESSAGE.'25092',0), 25093 => array(DEFAULT_ERROR_MESSAGE.'25093',0), 25094 => array(DEFAULT_ERROR_MESSAGE.'25094',0), 25095 => array(DEFAULT_ERROR_MESSAGE.'25095',0), 25096 => array(DEFAULT_ERROR_MESSAGE.'25096',0), 25097 => array(DEFAULT_ERROR_MESSAGE.'25097',0), 25098 => array(DEFAULT_ERROR_MESSAGE.'25098',0), 25099 => array(DEFAULT_ERROR_MESSAGE.'25099',0), 25100 => array(DEFAULT_ERROR_MESSAGE.'25100',0), 25101 => array(DEFAULT_ERROR_MESSAGE.'25101',0), 25102 => array(DEFAULT_ERROR_MESSAGE.'25102',0), 25103 => array(DEFAULT_ERROR_MESSAGE.'25103',0), 25104 => array(DEFAULT_ERROR_MESSAGE.'25104',0), 25105 => array(DEFAULT_ERROR_MESSAGE.'25105',0), 25106 => array(DEFAULT_ERROR_MESSAGE.'25106',0), 25107 => array(DEFAULT_ERROR_MESSAGE.'25107',0), 25108 => array(DEFAULT_ERROR_MESSAGE.'25108',0), 25109 => array(DEFAULT_ERROR_MESSAGE.'25109',0), 25110 => array(DEFAULT_ERROR_MESSAGE.'25110',0), 25111 => array(DEFAULT_ERROR_MESSAGE.'25111',0), 25112 => array(DEFAULT_ERROR_MESSAGE.'25112',0), 25113 => array(DEFAULT_ERROR_MESSAGE.'25113',0), 25114 => array(DEFAULT_ERROR_MESSAGE.'25114',0), 25115 => array(DEFAULT_ERROR_MESSAGE.'25115',0), 25116 => array(DEFAULT_ERROR_MESSAGE.'25116',0), 25117 => array(DEFAULT_ERROR_MESSAGE.'25117',0), 25118 => array(DEFAULT_ERROR_MESSAGE.'25118',0), 25119 => array(DEFAULT_ERROR_MESSAGE.'25119',0), 25120 => array(DEFAULT_ERROR_MESSAGE.'25120',0), 25121 => array(DEFAULT_ERROR_MESSAGE.'25121',0), 25122 => array(DEFAULT_ERROR_MESSAGE.'25122',0), 25123 => array(DEFAULT_ERROR_MESSAGE.'25123',0), 25124 => array(DEFAULT_ERROR_MESSAGE.'25124',0), 25125 => array(DEFAULT_ERROR_MESSAGE.'25125',0), 25126 => array(DEFAULT_ERROR_MESSAGE.'25126',0), 25127 => array(DEFAULT_ERROR_MESSAGE.'25127',0), 25128 => array(DEFAULT_ERROR_MESSAGE.'25128',0), 25129 => array(DEFAULT_ERROR_MESSAGE.'25129',0), 25130 => array(DEFAULT_ERROR_MESSAGE.'25130',0), 25131 => array(DEFAULT_ERROR_MESSAGE.'25131',0), 25500 => array(DEFAULT_ERROR_MESSAGE.'25500',0), 24003 => array(DEFAULT_ERROR_MESSAGE.'24003',0), 24004 => array(DEFAULT_ERROR_MESSAGE.'24004',0), 24005 => array(DEFAULT_ERROR_MESSAGE.'24005',0), 24006 => array(DEFAULT_ERROR_MESSAGE.'24006',0), 24007 => array(DEFAULT_ERROR_MESSAGE.'24007',0), 24008 => array(DEFAULT_ERROR_MESSAGE.'24008',0), 24009 => array(DEFAULT_ERROR_MESSAGE.'24009',0), 24010 => array(DEFAULT_ERROR_MESSAGE.'24010',0), 24011 => array(DEFAULT_ERROR_MESSAGE.'24011',0), 24012 => array(DEFAULT_ERROR_MESSAGE.'24012',0), 24013 => array(DEFAULT_ERROR_MESSAGE.'24013',0), 24014 => array(DEFAULT_ERROR_MESSAGE.'24014',0), 24015 => array(DEFAULT_ERROR_MESSAGE.'24015',0), 22001 => array(DEFAULT_ERROR_MESSAGE.'22001',0), 22002 => array(DEFAULT_ERROR_MESSAGE.'22002',0), 22004 => array(DEFAULT_ERROR_MESSAGE.'22004',0), 22005 => array(DEFAULT_ERROR_MESSAGE.'22005',0), 22006 => array(DEFAULT_ERROR_MESSAGE.'22006',0), 22007 => array(DEFAULT_ERROR_MESSAGE.'22007',0), 22008 => array(DEFAULT_ERROR_MESSAGE.'22008',0), 22009 => array(DEFAULT_ERROR_MESSAGE.'22009',0), 22010 => array(DEFAULT_ERROR_MESSAGE.'22010',0), 22011 => array(DEFAULT_ERROR_MESSAGE.'22011',0), 22012 => array(DEFAULT_ERROR_MESSAGE.'22012',0), 22013 => array(DEFAULT_ERROR_MESSAGE.'22013',0), 22014 => array(DEFAULT_ERROR_MESSAGE.'22014',0), 22015 => array(DEFAULT_ERROR_MESSAGE.'22015',0), 22016 => array(DEFAULT_ERROR_MESSAGE.'22016',0), 22017 => array(DEFAULT_ERROR_MESSAGE.'22017',0), 22018 => array(DEFAULT_ERROR_MESSAGE.'22018',0), 22019 => array(DEFAULT_ERROR_MESSAGE.'22019',0), 22020 => array(DEFAULT_ERROR_MESSAGE.'22020',0), 13001 => array(DEFAULT_ERROR_MESSAGE.'13001',0), 13002 => array(DEFAULT_ERROR_MESSAGE.'13002',0), 1001 => array(DEFAULT_ERROR_MESSAGE.'1001',0), 1002 => array(DEFAULT_ERROR_MESSAGE.'1002',0), 1003 => array(DEFAULT_ERROR_MESSAGE.'1003',0), 1004 => array(DEFAULT_ERROR_MESSAGE.'1004',0), 1005 => array(DEFAULT_ERROR_MESSAGE.'1005',0), 1006 => array(DEFAULT_ERROR_MESSAGE.'1006',0), 1007 => array(DEFAULT_ERROR_MESSAGE.'1007',0), 1008 => array(DEFAULT_ERROR_MESSAGE.'1008',0), 1009 => array(DEFAULT_ERROR_MESSAGE.'1009',0), 1010 => array(DEFAULT_ERROR_MESSAGE.'1010',0), 1011 => array(DEFAULT_ERROR_MESSAGE.'1011',0), 26000 => array(DEFAULT_ERROR_MESSAGE.'26000',0), 26001 => array(DEFAULT_ERROR_MESSAGE.'26001',0), 26002 => array(DEFAULT_ERROR_MESSAGE.'26002',0), 26003 => array(DEFAULT_ERROR_MESSAGE.'26003',0), 26004 => array(DEFAULT_ERROR_MESSAGE.'26004',0), 26005 => array(DEFAULT_ERROR_MESSAGE.'26005',0), 26006 => array(DEFAULT_ERROR_MESSAGE.'26006',0), 26007 => array(DEFAULT_ERROR_MESSAGE.'26007',0), 26008 => array(DEFAULT_ERROR_MESSAGE.'26008',0), 26009 => array(DEFAULT_ERROR_MESSAGE.'26009',0), 26010 => array(DEFAULT_ERROR_MESSAGE.'26010',0), 26011 => array(DEFAULT_ERROR_MESSAGE.'26011',0), 26012 => array(DEFAULT_ERROR_MESSAGE.'26012',0), 26013 => array(DEFAULT_ERROR_MESSAGE.'26013',0), 26014 => array(DEFAULT_ERROR_MESSAGE.'26014',0), 26015 => array(DEFAULT_ERROR_MESSAGE.'26015',0), 26016 => array(DEFAULT_ERROR_MESSAGE.'26016',0), 27001 => array(DEFAULT_ERROR_MESSAGE.'27001',0), 27002 => array(DEFAULT_ERROR_MESSAGE.'27002',0), 27003 => array(DEFAULT_ERROR_MESSAGE.'27003',0), 27004 => array(DEFAULT_ERROR_MESSAGE.'27004',0), 27005 => array(DEFAULT_ERROR_MESSAGE.'27005',0), 27006 => array(DEFAULT_ERROR_MESSAGE.'27006',0), 27007 => array(DEFAULT_ERROR_MESSAGE.'27007',0), 27008 => array(DEFAULT_ERROR_MESSAGE.'27008',0), 27009 => array(DEFAULT_ERROR_MESSAGE.'27009',0), 27010 => array(DEFAULT_ERROR_MESSAGE.'27010',0), 27011 => array(DEFAULT_ERROR_MESSAGE.'27011',0), 27012 => array(DEFAULT_ERROR_MESSAGE.'27012',0), 27013 => array(DEFAULT_ERROR_MESSAGE.'27013',0), 27014 => array(DEFAULT_ERROR_MESSAGE.'27014',0), 27015 => array(DEFAULT_ERROR_MESSAGE.'27015',0), 28001 => array(DEFAULT_ERROR_MESSAGE.'28001',0), 28002 => array(DEFAULT_ERROR_MESSAGE.'28002',0), 28003 => array(DEFAULT_ERROR_MESSAGE.'28003',0), 28004 => array(DEFAULT_ERROR_MESSAGE.'28004',0), 28005 => array(DEFAULT_ERROR_MESSAGE.'28005',0), 28006 => array(DEFAULT_ERROR_MESSAGE.'28006',0), 28007 => array(DEFAULT_ERROR_MESSAGE.'28007',0), 29201 => array(DEFAULT_ERROR_MESSAGE.'28001',0), 29202 => array(DEFAULT_ERROR_MESSAGE.'28002',0), 29203 => array(DEFAULT_ERROR_MESSAGE.'28003',0), 29204 => array(DEFAULT_ERROR_MESSAGE.'28004',0), 29205 => array(DEFAULT_ERROR_MESSAGE.'28005',0), 29206 => array(DEFAULT_ERROR_MESSAGE.'28006',0), 29207 => array(DEFAULT_ERROR_MESSAGE.'28007',0), 29208 => array(DEFAULT_ERROR_MESSAGE.'28008',0), 29209 => array(DEFAULT_ERROR_MESSAGE.'28009',0), 29210 => array(DEFAULT_ERROR_MESSAGE.'28010',0), ); ?> loganalyzer-3.6.5/src/classes/jpgraph/lang/en.inc.php0000644000175000017500000011226412225176641022025 0ustar danieldaniel,) $_jpg_messages = array( /* ** Headers already sent error. This is formatted as HTML different since this will be sent back directly as text */ 10 => array('
    JpGraph Error: HTTP headers have already been sent.
    Caused by output from file %s at line %d.
    Explanation:
    HTTP headers have already been sent back to the browser indicating the data as text before the library got a chance to send it\'s image HTTP header to this browser. This makes it impossible for the library to send back image data to the browser (since that would be interpretated as text by the browser and show up as junk text).

    Most likely you have some text in your script before the call to Graph::Stroke(). If this texts gets sent back to the browser the browser will assume that all data is plain text. Look for any text, even spaces and newlines, that might have been sent back to the browser.

    For example it is a common mistake to leave a blank line before the opening "<?php".

    ',2), /* ** Setup errors */ 11 => array('No path specified for CACHE_DIR. Please specify CACHE_DIR manually in jpg-config.inc',0), 12 => array('No path specified for TTF_DIR and path can not be determined automatically. Please specify TTF_DIR manually (in jpg-config.inc).',0), 13 => array('The installed PHP version (%s) is not compatible with this release of the library. The library requires at least PHP version %s',2), /* ** jpgraph_bar */ 2001 => array('Number of colors is not the same as the number of patterns in BarPlot::SetPattern()',0), 2002 => array('Unknown pattern specified in call to BarPlot::SetPattern()',0), 2003 => array('Number of X and Y points are not equal. Number of X-points: %d Number of Y-points: %d',2), 2004 => array('All values for a barplot must be numeric. You have specified value nr [%d] == %s',2), 2005 => array('You have specified an empty array for shadow colors in the bar plot.',0), 2006 => array('Unknown position for values on bars : %s',1), 2007 => array('Cannot create GroupBarPlot from empty plot array.',0), 2008 => array('Group bar plot element nbr %d is undefined or empty.',0), 2009 => array('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the GroupBar plot from an array of BarPlot or AccBarPlot objects. (Class = %s)',1), 2010 => array('Cannot create AccBarPlot from empty plot array.',0), 2011 => array('Acc bar plot element nbr %d is undefined or empty.',1), 2012 => array('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects. (Class=%s)',1), 2013 => array('You have specified an empty array for shadow colors in the bar plot.',0), 2014 => array('Number of datapoints for each data set in accbarplot must be the same',0), 2015 => array('Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-coordinates',0), /* ** jpgraph_date */ 3001 => array('It is only possible to use either SetDateAlign() or SetTimeAlign() but not both',0), /* ** jpgraph_error */ 4002 => array('Error in input data to LineErrorPlot. Number of data points must be a multiple of 3',0), /* ** jpgraph_flags */ 5001 => array('Unknown flag size (%d).',1), 5002 => array('Flag index %s does not exist.',1), 5003 => array('Invalid ordinal number (%d) specified for flag index.',1), 5004 => array('The (partial) country name %s does not have a corresponding flag image. The flag may still exist but under another name, e.g. instead of "usa" try "united states".',1), /* ** jpgraph_gantt */ 6001 => array('Internal error. Height for ActivityTitles is < 0',0), 6002 => array('You can\'t specify negative sizes for Gantt graph dimensions. Use 0 to indicate that you want the library to automatically determine a dimension.',0), 6003 => array('Invalid format for Constrain parameter at index=%d in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Constrain-To,Constrain-Type)',1), 6004 => array('Invalid format for Progress parameter at index=%d in CreateSimple(). Parameter must start with index 0 and contain arrays of (Row,Progress)',1), 6005 => array('SetScale() is not meaningful with Gantt charts.',0), 6006 => array('Cannot autoscale Gantt chart. No dated activities exist. [GetBarMinMax() start >= n]',0), 6007 => array('Sanity check for automatic Gantt chart size failed. Either the width (=%d) or height (=%d) is larger than MAX_GANTTIMG_SIZE. This could potentially be caused by a wrong date in one of the activities.',2), 6008 => array('You have specified a constrain from row=%d to row=%d which does not have any activity',2), 6009 => array('Unknown constrain type specified from row=%d to row=%d',2), 6010 => array('Illegal icon index for Gantt builtin icon [%d]',1), 6011 => array('Argument to IconImage must be string or integer',0), 6012 => array('Unknown type in Gantt object title specification',0), 6015 => array('Illegal vertical position %d',1), 6016 => array('Date string (%s) specified for Gantt activity can not be interpretated. Please make sure it is a valid time string, e.g. 2005-04-23 13:30',1), 6017 => array('Unknown date format in GanttScale (%s).',1), 6018 => array('Interval for minutes must divide the hour evenly, e.g. 1,5,10,12,15,20,30 etc You have specified an interval of %d minutes.',1), 6019 => array('The available width (%d) for minutes are to small for this scale to be displayed. Please use auto-sizing or increase the width of the graph.',1), 6020 => array('Interval for hours must divide the day evenly, e.g. 0:30, 1:00, 1:30, 4:00 etc. You have specified an interval of %d',1), 6021 => array('Unknown formatting style for week.',0), 6022 => array('Gantt scale has not been specified.',0), 6023 => array('If you display both hour and minutes the hour interval must be 1 (Otherwise it doesn\'t make sense to display minutes).',0), 6024 => array('CSIM Target must be specified as a string. Start of target is: %d',1), 6025 => array('CSIM Alt text must be specified as a string. Start of alt text is: %d',1), 6027 => array('Progress value must in range [0, 1]',0), 6028 => array('Specified height (%d) for gantt bar is out of range.',1), 6029 => array('Offset for vertical line must be in range [0,1]',0), 6030 => array('Unknown arrow direction for link.',0), 6031 => array('Unknown arrow type for link.',0), 6032 => array('Internal error: Unknown path type (=%d) specified for link.',1), 6033 => array('Array of fonts must contain arrays with 3 elements, i.e. (Family, Style, Size)',0), /* ** jpgraph_gradient */ 7001 => array('Unknown gradient style (=%d).',1), /* ** jpgraph_iconplot */ 8001 => array('Mix value for icon must be between 0 and 100.',0), 8002 => array('Anchor position for icons must be one of "top", "bottom", "left", "right" or "center"',0), 8003 => array('It is not possible to specify both an image file and a country flag for the same icon.',0), 8004 => array('In order to use Country flags as icons you must include the "jpgraph_flags.php" file.',0), /* ** jpgraph_imgtrans */ 9001 => array('Value for image transformation out of bounds. Vanishing point on horizon must be specified as a value between 0 and 1.',0), /* ** jpgraph_lineplot */ 10001 => array('LinePlot::SetFilled() is deprecated. Use SetFillColor()',0), 10002 => array('Plot too complicated for fast line Stroke. Use standard Stroke()',0), 10003 => array('Each plot in an accumulated lineplot must have the same number of data points.',0), /* ** jpgraph_log */ 11001 => array('Your data contains non-numeric values.',0), 11002 => array('Negative data values can not be used in a log scale.',0), 11003 => array('Your data contains non-numeric values.',0), 11004 => array('Scale error for logarithmic scale. You have a problem with your data values. The max value must be greater than 0. It is mathematically impossible to have 0 in a logarithmic scale.',0), 11005 => array('Specifying tick interval for a logarithmic scale is undefined. Remove any calls to SetTextLabelStart() or SetTextTickInterval() on the logarithmic scale.',0), /* ** jpgraph_mgraph */ 12001 => array("You are using GD 2.x and are trying to use a background images on a non truecolor image. To use background images with GD 2.x it is necessary to enable truecolor by setting the USE_TRUECOLOR constant to TRUE. Due to a bug in GD 2.0.1 using any truetype fonts with truecolor images will result in very poor quality fonts.",0), 12002 => array('Incorrect file name for MGraph::SetBackgroundImage() : %s Must have a valid image extension (jpg,gif,png) when using auto detection of image type',1), 12003 => array('Unknown file extension (%s) in MGraph::SetBackgroundImage() for filename: %s',2), 12004 => array('The image format of your background image (%s) is not supported in your system configuration. ',1), 12005 => array('Can\'t read background image: %s',1), 12006 => array('Illegal sizes specified for width or height when creating an image, (width=%d, height=%d)',2), 12007 => array('Argument to MGraph::Add() is not a valid GD image handle.',0), 12008 => array('Your PHP (and GD-lib) installation does not appear to support any known graphic formats.',0), 12009 => array('Your PHP installation does not support the chosen graphic format: %s',1), 12010 => array('Can\'t create or stream image to file %s Check that PHP has enough permission to write a file to the current directory.',1), 12011 => array('Can\'t create truecolor image. Check that you really have GD2 library installed.',0), 12012 => array('Can\'t create image. Check that you really have GD2 library installed.',0), /* ** jpgraph_pie3d */ 14001 => array('Pie3D::ShowBorder() . Deprecated function. Use Pie3D::SetEdge() to control the edges around slices.',0), 14002 => array('PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees.',0), 14003 => array('Internal assertion failed. Pie3D::Pie3DSlice',0), 14004 => array('Slice start angle must be between 0 and 360 degrees.',0), 14005 => array('Pie3D Internal error: Trying to wrap twice when looking for start index',0,), 14006 => array('Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking.',0), 14007 => array('Width for 3D Pie is 0. Specify a size > 0',0), /* ** jpgraph_pie */ 15001 => array('PiePLot::SetTheme() Unknown theme: %s',1), 15002 => array('Argument to PiePlot::ExplodeSlice() must be an integer',0), 15003 => array('Argument to PiePlot::Explode() must be an array with integer distances.',0), 15004 => array('Slice start angle must be between 0 and 360 degrees.',0), 15005 => array('PiePlot::SetFont() is deprecated. Use PiePlot->value->SetFont() instead.',0), 15006 => array('PiePlot::SetSize() Radius for pie must either be specified as a fraction [0, 0.5] of the size of the image or as an absolute size in pixels in the range [10, 1000]',0), 15007 => array('PiePlot::SetFontColor() is deprecated. Use PiePlot->value->SetColor() instead.',0), 15008 => array('PiePlot::SetLabelType() Type for pie plots must be 0 or 1 (not %d).',1), 15009 => array('Illegal pie plot. Sum of all data is zero for Pie Plot',0), 15010 => array('Sum of all data is 0 for Pie.',0), 15011 => array('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.',0), /* ** jpgraph_plotband */ 16001 => array('Density for pattern must be between 1 and 100. (You tried %f)',1), 16002 => array('No positions specified for pattern.',0), 16003 => array('Unknown pattern specification (%d)',0), 16004 => array('Min value for plotband is larger than specified max value. Please correct.',0), /* ** jpgraph_polar */ 17001 => array('Polar plots must have an even number of data point. Each data point is a tuple (angle,radius).',0), 17002 => array('Unknown alignment specified for X-axis title. (%s)',1), //17003 => array('Set90AndMargin() is not supported for polar graphs.',0), 17004 => array('Unknown scale type for polar graph. Must be "lin" or "log"',0), /* ** jpgraph_radar */ 18001 => array('Client side image maps not supported for RadarPlots.',0), 18002 => array('RadarGraph::SupressTickMarks() is deprecated. Use HideTickMarks() instead.',0), 18003 => array('Illegal scale for radarplot (%s). Must be \'lin\' or \'log\'',1), 18004 => array('Radar Plot size must be between 0.1 and 1. (Your value=%f)',1), 18005 => array('RadarPlot Unsupported Tick density: %d',1), 18006 => array('Minimum data %f (Radar plots should only be used when all data points > 0)',1), 18007 => array('Number of titles does not match number of points in plot.',0), 18008 => array('Each radar plot must have the same number of data points.',0), /* ** jpgraph_regstat */ 19001 => array('Spline: Number of X and Y coordinates must be the same',0), 19002 => array('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.',0), 19003 => array('Bezier: Number of X and Y coordinates must be the same',0), /* ** jpgraph_scatter */ 20001 => array('Fieldplots must have equal number of X and Y points.',0), 20002 => array('Fieldplots must have an angle specified for each X and Y points.',0), 20003 => array('Scatterplot must have equal number of X and Y points.',0), /* ** jpgraph_stock */ 21001 => array('Data values for Stock charts must contain an even multiple of %d data points.',1), /* ** jpgraph_plotmark */ 23001 => array('This marker "%s" does not exist in color with index: %d',2), 23002 => array('Mark color index too large for marker "%s"',1), 23003 => array('A filename must be specified if you set the mark type to MARK_IMG.',0), /* ** jpgraph_utils */ 24001 => array('FuncGenerator : No function specified. ',0), 24002 => array('FuncGenerator : Syntax error in function specification ',0), 24003 => array('DateScaleUtils: Unknown tick type specified in call to GetTicks()',0), 24004 => array('ReadCSV2: Column count mismatch in %s line %d',2), /* ** jpgraph */ 25001 => array('This PHP installation is not configured with the GD library. Please recompile PHP with GD support to run JpGraph. (Neither function imagetypes() nor imagecreatefromstring() does exist)',0), 25002 => array('Your PHP installation does not seem to have the required GD library. Please see the PHP documentation on how to install and enable the GD library.',0), 25003 => array('General PHP error : At %s:%d : %s',3), 25004 => array('General PHP error : %s ',1), 25005 => array('Can\'t access PHP_SELF, PHP global variable. You can\'t run PHP from command line if you want to use the \'auto\' naming of cache or image files.',0), 25006 => array('Usage of FF_CHINESE (FF_BIG5) font family requires that your PHP setup has the iconv() function. By default this is not compiled into PHP (needs the "--width-iconv" when configured).',0), 25007 => array('You are trying to use the locale (%s) which your PHP installation does not support. Hint: Use \'\' to indicate the default locale for this geographic region.',1), 25008 => array('Image width/height argument in Graph::Graph() must be numeric',0), 25009 => array('You must specify what scale to use with a call to Graph::SetScale()',0), 25010 => array('Graph::Add() You tried to add a null plot to the graph.',0), 25011 => array('Graph::AddY2() You tried to add a null plot to the graph.',0), 25012 => array('Graph::AddYN() You tried to add a null plot to the graph.',0), 25013 => array('You can only add standard plots to multiple Y-axis',0), 25014 => array('Graph::AddText() You tried to add a null text to the graph.',0), 25015 => array('Graph::AddLine() You tried to add a null line to the graph.',0), 25016 => array('Graph::AddBand() You tried to add a null band to the graph.',0), 25017 => array('You are using GD 2.x and are trying to use a background images on a non truecolor image. To use background images with GD 2.x it is necessary to enable truecolor by setting the USE_TRUECOLOR constant to TRUE. Due to a bug in GD 2.0.1 using any truetype fonts with truecolor images will result in very poor quality fonts.',0), 25018 => array('Incorrect file name for Graph::SetBackgroundImage() : "%s" Must have a valid image extension (jpg,gif,png) when using auto detection of image type',1), 25019 => array('Unknown file extension (%s) in Graph::SetBackgroundImage() for filename: "%s"',2), 25020 => array('Graph::SetScale(): Specified Max value must be larger than the specified Min value.',0), 25021 => array('Unknown scale specification for Y-scale. (%s)',1), 25022 => array('Unknown scale specification for X-scale. (%s)',1), 25023 => array('Unsupported Y2 axis type: "%s" Must be one of (lin,log,int)',1), 25024 => array('Unsupported Y axis type: "%s" Must be one of (lin,log,int)',1), 25025 => array('Unsupported Tick density: %d',1), 25026 => array('Can\'t draw unspecified Y-scale. You have either: 1. Specified an Y axis for auto scaling but have not supplied any plots. 2. Specified a scale manually but have forgot to specify the tick steps',0), 25027 => array('Can\'t open cached CSIM "%s" for reading.',1), 25028 => array('Apache/PHP does not have permission to write to the CSIM cache directory (%s). Check permissions.',1), 25029 => array('Can\'t write CSIM "%s" for writing. Check free space and permissions.',1), 25030 => array('Missing script name in call to StrokeCSIM(). You must specify the name of the actual image script as the first parameter to StrokeCSIM().',0), 25031 => array('You must specify what scale to use with a call to Graph::SetScale().',0), 25032 => array('No plots for Y-axis nbr:%d',1), 25033 => array('',0), 25034 => array('Can\'t draw unspecified X-scale. No plots specified.',0), 25035 => array('You have enabled clipping. Clipping is only supported for graphs at 0 or 90 degrees rotation. Please adjust you current angle (=%d degrees) or disable clipping.',1), 25036 => array('Unknown AxisStyle() : %s',1), 25037 => array('The image format of your background image (%s) is not supported in your system configuration. ',1), 25038 => array('Background image seems to be of different type (has different file extension) than specified imagetype. Specified: %s File: %s',2), 25039 => array('Can\'t read background image: "%s"',1), 25040 => array('It is not possible to specify both a background image and a background country flag.',0), 25041 => array('In order to use Country flags as backgrounds you must include the "jpgraph_flags.php" file.',0), 25042 => array('Unknown background image layout',0), 25043 => array('Unknown title background style.',0), 25044 => array('Cannot use auto scaling since it is impossible to determine a valid min/max value of the Y-axis (only null values).',0), 25045 => array('Font families FF_HANDWRT and FF_BOOK are no longer available due to copyright problem with these fonts. Fonts can no longer be distributed with JpGraph. Please download fonts from http://corefonts.sourceforge.net/',0), 25046 => array('Specified TTF font family (id=%d) is unknown or does not exist. Please note that TTF fonts are not distributed with JpGraph for copyright reasons. You can find the MS TTF WEB-fonts (arial, courier etc) for download at http://corefonts.sourceforge.net/',1), 25047 => array('Style %s is not available for font family %s',2), 25048 => array('Unknown font style specification [%s].',1), 25049 => array('Font file "%s" is not readable or does not exist.',1), 25050 => array('First argument to Text::Text() must be a string.',0), 25051 => array('Invalid direction specified for text.',0), 25052 => array('PANIC: Internal error in SuperScript::Stroke(). Unknown vertical alignment for text',0), 25053 => array('PANIC: Internal error in SuperScript::Stroke(). Unknown horizontal alignment for text',0), 25054 => array('Internal error: Unknown grid axis %s',1), 25055 => array('Axis::SetTickDirection() is deprecated. Use Axis::SetTickSide() instead',0), 25056 => array('SetTickLabelMargin() is deprecated. Use Axis::SetLabelMargin() instead.',0), 25057 => array('SetTextTicks() is deprecated. Use SetTextTickInterval() instead.',0), 25058 => array('Text label interval must be specified >= 1.',0), 25059 => array('SetLabelPos() is deprecated. Use Axis::SetLabelSide() instead.',0), 25060 => array('Unknown alignment specified for X-axis title. (%s)',1), 25061 => array('Unknown alignment specified for Y-axis title. (%s)',1), 25062 => array('Labels at an angle are not supported on Y-axis',0), 25063 => array('Ticks::SetPrecision() is deprecated. Use Ticks::SetLabelFormat() (or Ticks::SetFormatCallback()) instead',0), 25064 => array('Minor or major step size is 0. Check that you haven\'t got an accidental SetTextTicks(0) in your code. If this is not the case you might have stumbled upon a bug in JpGraph. Please report this and if possible include the data that caused the problem',0), 25065 => array('Tick positions must be specified as an array()',0), 25066 => array('When manually specifying tick positions and labels the number of labels must be the same as the number of specified ticks.',0), 25067 => array('Your manually specified scale and ticks is not correct. The scale seems to be too small to hold any of the specified tick marks.',0), 25068 => array('A plot has an illegal scale. This could for example be that you are trying to use text auto scaling to draw a line plot with only one point or that the plot area is too small. It could also be that no input data value is numeric (perhaps only \'-\' or \'x\')',0), 25069 => array('Grace must be larger then 0',0), 25070 => array('Either X or Y data arrays contains non-numeric values. Check that the data is really specified as numeric data and not as strings. It is an error to specify data for example as \'-2345.2\' (using quotes).',0), 25071 => array('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.',0), 25072 => array('You have specified a max value with SetAutoMax() which is smaller than the minimum value used for the scale. This is not possible.',0), 25073 => array('Internal error. Integer scale algorithm comparison out of bound (r=%f)',1), 25074 => array('Internal error. The scale range is negative (%f) [for %s scale] This problem could potentially be caused by trying to use \"illegal\" values in the input data arrays (like trying to send in strings or only NULL values) which causes the auto scaling to fail.',2), 25075 => array('Can\'t automatically determine ticks since min==max.',0), 25077 => array('Adjustment factor for color must be > 0',0), 25078 => array('Unknown color: %s',1), 25079 => array('Unknown color specification: %s, size=%d',2), 25080 => array('Alpha parameter for color must be between 0.0 and 1.0',0), 25081 => array('Selected graphic format is either not supported or unknown [%s]',1), 25082 => array('Illegal sizes specified for width or height when creating an image, (width=%d, height=%d)',2), 25083 => array('Illegal image size when copying image. Size for copied to image is 1 pixel or less.',0), 25084 => array('Failed to create temporary GD canvas. Possible Out of memory problem.',0), 25085 => array('An image can not be created from the supplied string. It is either in a format not supported or the string is representing an corrupt image.',0), 25086 => array('You only seem to have GD 1.x installed. To enable Alphablending requires GD 2.x or higher. Please install GD or make sure the constant USE_GD2 is specified correctly to reflect your installation. By default it tries to auto detect what version of GD you have installed. On some very rare occasions it may falsely detect GD2 where only GD1 is installed. You must then set USE_GD2 to false.',0), 25087 => array('This PHP build has not been configured with TTF support. You need to recompile your PHP installation with FreeType support.',0), 25088 => array('You have a misconfigured GD font support. The call to imagefontwidth() fails.',0), 25089 => array('You have a misconfigured GD font support. The call to imagefontheight() fails.',0), 25090 => array('Unknown direction specified in call to StrokeBoxedText() [%s]',1), 25091 => array('Internal font does not support drawing text at arbitrary angle. Use TTF fonts instead.',0), 25092 => array('There is either a configuration problem with TrueType or a problem reading font file "%s" Make sure file exists and is in a readable place for the HTTP process. (If \'basedir\' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try upgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library.',1), 25093 => array('Can not read font file "%s" in call to Image::GetBBoxTTF. Please make sure that you have set a font before calling this method and that the font is installed in the TTF directory.',1), 25094 => array('Direction for text most be given as an angle between 0 and 90.',0), 25095 => array('Unknown font font family specification. ',0), 25096 => array('Can\'t allocate any more colors in palette image. Image has already allocated maximum of %d colors and the palette is now full. Change to a truecolor image instead',0), 25097 => array('Color specified as empty string in PushColor().',0), 25098 => array('Negative Color stack index. Unmatched call to PopColor()',0), 25099 => array('Parameters for brightness and Contrast out of range [-1,1]',0), 25100 => array('Problem with color palette and your GD setup. Please disable anti-aliasing or use GD2 with true-color. If you have GD2 library installed please make sure that you have set the USE_GD2 constant to true and truecolor is enabled.',0), 25101 => array('Illegal numeric argument to SetLineStyle(): (%d)',1), 25102 => array('Illegal string argument to SetLineStyle(): %s',1), 25103 => array('Illegal argument to SetLineStyle %s',1), 25104 => array('Unknown line style: %s',1), 25105 => array('NULL data specified for a filled polygon. Check that your data is not NULL.',0), 25106 => array('Image::FillToBorder : Can not allocate more colors',0), 25107 => array('Can\'t write to file "%s". Check that the process running PHP has enough permission.',1), 25108 => array('Can\'t stream image. This is most likely due to a faulty PHP/GD setup. Try to recompile PHP and use the built-in GD library that comes with PHP.',0), 25109 => array('Your PHP (and GD-lib) installation does not appear to support any known graphic formats. You need to first make sure GD is compiled as a module to PHP. If you also want to use JPEG images you must get the JPEG library. Please see the PHP docs for details.',0), 25110 => array('Your PHP installation does not support the chosen graphic format: %s',1), 25111 => array('Can\'t delete cached image %s. Permission problem?',1), 25112 => array('Cached imagefile (%s) has file date in the future.',1), 25113 => array('Can\'t delete cached image "%s". Permission problem?',1), 25114 => array('PHP has not enough permissions to write to the cache file "%s". Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.',1), 25115 => array('Can\'t set permission for cached image "%s". Permission problem?',1), 25116 => array('Cant open file from cache "%s"',1), 25117 => array('Can\'t open cached image "%s" for reading.',1), 25118 => array('Can\'t create directory "%s". Make sure PHP has write permission to this directory.',1), 25119 => array('Can\'t set permissions for "%s". Permission problems?',1), 25120 => array('Position for legend must be given as percentage in range 0-1',0), 25121 => array('Empty input data array specified for plot. Must have at least one data point.',0), 25122 => array('Stroke() must be implemented by concrete subclass to class Plot',0), 25123 => array('You can\'t use a text X-scale with specified X-coords. Use a "int" or "lin" scale instead.',0), 25124 => array('The input data array must have consecutive values from position 0 and forward. The given y-array starts with empty values (NULL)',0), 25125 => array('Illegal direction for static line',0), 25126 => array('Can\'t create truecolor image. Check that the GD2 library is properly setup with PHP.',0), 25127 => array('The library has been configured for automatic encoding conversion of Japanese fonts. This requires that PHP has the mb_convert_encoding() function. Your PHP installation lacks this function (PHP needs the "--enable-mbstring" when compiled).',0), 25128 => array('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.',0), 25129 => array('Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines.',0), 25130 => array('Too small plot area. (%d x %d). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins.',2), 25131 => array('StrokeBoxedText2() only supports TTF fonts and not built-in bitmap fonts.',0), /* ** jpgraph_led */ 25500 => array('Multibyte strings must be enabled in the PHP installation in order to run the LED module so that the function mb_strlen() is available. See PHP documentation for more information.',0), /* **--------------------------------------------------------------------------------------------- ** Pro-version strings **--------------------------------------------------------------------------------------------- */ /* ** jpgraph_table */ 27001 => array('GTextTable: Invalid argument to Set(). Array argument must be 2 dimensional',0), 27002 => array('GTextTable: Invalid argument to Set()',0), 27003 => array('GTextTable: Wrong number of arguments to GTextTable::SetColor()',0), 27004 => array('GTextTable: Specified cell range to be merged is not valid.',0), 27005 => array('GTextTable: Cannot merge already merged cells in the range: (%d,%d) to (%d,%d)',4), 27006 => array('GTextTable: Column argument = %d is outside specified table size.',1), 27007 => array('GTextTable: Row argument = %d is outside specified table size.',1), 27008 => array('GTextTable: Column and row size arrays must match the dimensions of the table',0), 27009 => array('GTextTable: Number of table columns or rows are 0. Make sure Init() or Set() is called.',0), 27010 => array('GTextTable: No alignment specified in call to SetAlign()',0), 27011 => array('GTextTable: Unknown alignment specified in SetAlign(). Horizontal=%s, Vertical=%s',2), 27012 => array('GTextTable: Internal error. Invalid alignment specified =%s',1), 27013 => array('GTextTable: Argument to FormatNumber() must be a string.',0), 27014 => array('GTextTable: Table is not initilaized with either a call to Set() or Init()',0), 27015 => array('GTextTable: Cell image constrain type must be TIMG_WIDTH or TIMG_HEIGHT',0), /* ** jpgraph_windrose */ 22001 => array('Total percentage for all windrose legs in a windrose plot can not exceed 100%% !\n(Current max is: %d)',1), 22002 => array('Graph is too small to have a scale. Please make the graph larger.',0), 22004 => array('Label specification for windrose directions must have 16 values (one for each compass direction).',0), 22005 => array('Line style for radial lines must be on of ("solid","dotted","dashed","longdashed") ',0), 22006 => array('Illegal windrose type specified.',0), 22007 => array('To few values for the range legend.',0), 22008 => array('Internal error: Trying to plot free Windrose even though type is not a free windrose',0), 22009 => array('You have specified the same direction twice, once with an angle and once with a compass direction (%f degrees)',0), 22010 => array('Direction must either be a numeric value or one of the 16 compass directions',0), 22011 => array('Windrose index must be numeric or direction label. You have specified index=%d',1), 22012 => array('Windrose radial axis specification contains a direction which is not enabled.',0), 22013 => array('You have specified the look&feel for the same compass direction twice, once with text and once with index (Index=%d)',1), 22014 => array('Index for compass direction must be between 0 and 15.',0), 22015 => array('You have specified an undefined Windrose plot type.',0), 22016 => array('Windrose leg index must be numeric or direction label.',0), 22017 => array('Windrose data contains a direction which is not enabled. Please adjust what labels are displayed.',0), 22018 => array('You have specified data for the same compass direction twice, once with text and once with index (Index=%d)',1), 22019 => array('Index for direction must be between 0 and 15. You can\'t specify angles for a Regular Windplot, only index and compass directions.',0), 22020 => array('Windrose plot is too large to fit the specified Graph size. Please use WindrosePlot::SetSize() to make the plot smaller or increase the size of the Graph in the initial WindroseGraph() call.',0), 22021 => array('It is only possible to add Text, IconPlot or WindrosePlot to a Windrose Graph',0), /* ** jpgraph_odometer */ 13001 => array('Unknown needle style (%d).',1), 13002 => array('Value for odometer (%f) is outside specified scale [%f,%f]',3), /* ** jpgraph_barcode */ 1001 => array('Unknown encoder specification: %s',1), 1002 => array('Data validation failed. Can\'t encode [%s] using encoding "%s"',2), 1003 => array('Internal encoding error. Trying to encode %s is not possible in Code 128',1), 1004 => array('Internal barcode error. Unknown UPC-E encoding type: %s',1), 1005 => array('Internal error. Can\'t encode character tuple (%s, %s) in Code-128 charset C',2), 1006 => array('Internal encoding error for CODE 128. Trying to encode control character in CHARSET != A',0), 1007 => array('Internal encoding error for CODE 128. Trying to encode DEL in CHARSET != B',0), 1008 => array('Internal encoding error for CODE 128. Trying to encode small letters in CHARSET != B',0), 1009 => array('Encoding using CODE 93 is not yet supported.',0), 1010 => array('Encoding using POSTNET is not yet supported.',0), 1011 => array('Non supported barcode backend for type %s',1), /* ** PDF417 */ 26000 => array('PDF417: The PDF417 module requires that the PHP installation must support the function bcmod(). This is normally enabled at compile time. See documentation for more information.',0), 26001 => array('PDF417: Number of Columns must be >= 1 and <= 30',0), 26002 => array('PDF417: Error level must be between 0 and 8',0), 26003 => array('PDF417: Invalid format for input data to encode with PDF417',0), 26004 => array('PDF417: Can\'t encode given data with error level %d and %d columns since it results in too many symbols or more than 90 rows.',2), 26005 => array('PDF417: Can\'t open file "%s" for writing',1), 26006 => array('PDF417: Internal error. Data files for PDF417 cluster %d is corrupted.',1), 26007 => array('PDF417: Internal error. GetPattern: Illegal Code Value = %d (row=%d)',2), 26008 => array('PDF417: Internal error. Mode not found in mode list!! mode=%d',1), 26009 => array('PDF417: Encode error: Illegal character. Can\'t encode character with ASCII code=%d',1), 26010 => array('PDF417: Internal error: No input data in decode.',0), 26011 => array('PDF417: Encoding error. Can\'t use numeric encoding on non-numeric data.',0), 26012 => array('PDF417: Internal error. No input data to decode for Binary compressor.',0), 26013 => array('PDF417: Internal error. Checksum error. Coefficient tables corrupted.',0), 26014 => array('PDF417: Internal error. No data to calculate codewords on.',0), 26015 => array('PDF417: Internal error. State transition table entry 0 is NULL. Entry 1 = (%s)',1), 26016 => array('PDF417: Internal error: Unrecognized state transition mode in decode.',0), /* ** jpgraph_contour */ 28001 => array('Third argument to Contour must be an array of colors.',0), 28002 => array('Number of colors must equal the number of isobar lines specified',0), 28003 => array('ContourPlot Internal Error: isobarHCrossing: Coloumn index too large (%d)',1), 28004 => array('ContourPlot Internal Error: isobarHCrossing: Row index too large (%d)',1), 28005 => array('ContourPlot Internal Error: isobarVCrossing: Row index too large (%d)',1), 28006 => array('ContourPlot Internal Error: isobarVCrossing: Col index too large (%d)',1), 28007 => array('ContourPlot interpolation factor is too large (>5)',0), /* * jpgraph_matrix and colormap */ 29201 => array('Min range value must be less or equal to max range value for colormaps',0), 29202 => array('The distance between min and max value is too small for numerical precision',0), 29203 => array('Number of color quantification level must be at least %d',1), 29204 => array('Number of colors (%d) is invalid for this colormap. It must be a number that can be written as: %d + k*%d',3), 29205 => array('Colormap specification out of range. Must be an integer in range [0,%d]',1), 29206 => array('Invalid object added to MatrixGraph',0), 29207 => array('Empty input data specified for MatrixPlot',0), 29208 => array('Unknown side specifiction for matrix labels "%s"',1), 29209 => array('CSIM Target matrix must be the same size as the data matrix (csim=%d x %d, data=%d x %d)',4), 29210 => array('CSIM Target for matrix labels does not match the number of labels (csim=%d, labels=%d)',2), ); ?> loganalyzer-3.6.5/src/classes/jpgraph/lang/de.inc.php0000644000175000017500000012473012225176641022014 0ustar danieldaniel,) $_jpg_messages = array( /* ** Headers wurden bereits gesendet - Fehler. Dies wird als HTML formatiert, weil es direkt als text zurueckgesendet wird */ 10 => array('
    JpGraph Fehler: HTTP header wurden bereits gesendet.
    Fehler in der Datei %s in der Zeile %d.
    Erklärung:
    HTTP header wurden bereits zum Browser gesendet, wobei die Daten als Text gekennzeichnet wurden, bevor die Bibliothek die Chance hatte, seinen Bild-HTTP-Header zum Browser zu schicken. Dies verhindert, dass die Bibliothek Bilddaten zum Browser schicken kann (weil sie vom Browser als Text interpretiert würden und daher nur Mist dargestellt würde).

    Wahrscheinlich steht Text im Skript bevor Graph::Stroke() aufgerufen wird. Wenn dieser Text zum Browser gesendet wird, nimmt dieser an, dass die gesamten Daten aus Text bestehen. Such nach irgendwelchem Text, auch nach Leerzeichen und Zeilenumbrüchen, die eventuell bereits zum Browser gesendet wurden.

    Zum Beispiel ist ein oft auftretender Fehler, eine Leerzeile am Anfang der Datei oder vor Graph::Stroke() zu lassen."<?php".

    ',2), /* ** Setup Fehler */ 11 => array('Es wurde kein Pfad für CACHE_DIR angegeben. Bitte gib einen Pfad CACHE_DIR in der Datei jpg-config.inc an.',0), 12 => array('Es wurde kein Pfad für TTF_DIR angegeben und der Pfad kann nicht automatisch ermittelt werden. Bitte gib den Pfad in der Datei jpg-config.inc an.',0), 13 => array('The installed PHP version (%s) is not compatible with this release of the library. The library requires at least PHP version %s',2), /* ** jpgraph_bar */ 2001 => array('Die Anzahl der Farben ist nicht gleich der Anzahl der Vorlagen in BarPlot::SetPattern().',0), 2002 => array('Unbekannte Vorlage im Aufruf von BarPlot::SetPattern().',0), 2003 => array('Anzahl der X- und Y-Koordinaten sind nicht identisch. Anzahl der X-Koordinaten: %d; Anzahl der Y-Koordinaten: %d.',2), 2004 => array('Alle Werte für ein Balkendiagramm (barplot) müssen numerisch sein. Du hast den Wert nr [%d] == %s angegeben.',2), 2005 => array('Du hast einen leeren Vektor für die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0), 2006 => array('Unbekannte Position für die Werte der Balken: %s.',1), 2007 => array('Kann GroupBarPlot nicht aus einem leeren Vektor erzeugen.',0), 2008 => array('GroupBarPlot Element nbr %d wurde nicht definiert oder ist leer.',0), 2009 => array('Eins der Objekte, das an GroupBar weitergegeben wurde ist kein Balkendiagramm (BarPlot). Versichere Dich, dass Du den GroupBarPlot aus einem Vektor von Balkendiagrammen (barplot) oder AccBarPlot-Objekten erzeugst. (Class = %s)',1), 2010 => array('Kann AccBarPlot nicht aus einem leeren Vektor erzeugen.',0), 2011 => array('AccBarPlot-Element nbr %d wurde nicht definiert oder ist leer.',1), 2012 => array('Eins der Objekte, das an AccBar weitergegeben wurde ist kein Balkendiagramm (barplot). Versichere Dich, dass Du den AccBar-Plot aus einem Vektor von Balkendiagrammen (barplot) erzeugst. (Class=%s)',1), 2013 => array('Du hast einen leeren Vektor für die Schattierungsfarben im Balkendiagramm (barplot) angegeben.',0), 2014 => array('Die Anzahl der Datenpunkte jeder Datenreihe in AccBarPlot muss gleich sein.',0), 2015 => array('Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-coordinates',0), /* ** jpgraph_date */ 3001 => array('Es ist nur möglich, entweder SetDateAlign() oder SetTimeAlign() zu benutzen, nicht beides!',0), /* ** jpgraph_error */ 4002 => array('Fehler bei den Eingabedaten von LineErrorPlot. Die Anzahl der Datenpunkte mus ein Mehrfaches von drei sein!',0), /* ** jpgraph_flags */ 5001 => array('Unbekannte Flaggen-Größe (%d).',1), 5002 => array('Der Flaggen-Index %s existiert nicht.',1), 5003 => array('Es wurde eine ungültige Ordnungszahl (%d) für den Flaggen-Index angegeben.',1), 5004 => array('Der Landesname %s hat kein korrespondierendes Flaggenbild. Die Flagge mag existieren, abr eventuell unter einem anderen Namen, z.B. versuche "united states" statt "usa".',1), /* ** jpgraph_gantt */ 6001 => array('Interner Fehler. Die Höhe für ActivityTitles ist < 0.',0), 6002 => array('Es dürfen keine negativen Werte für die Gantt-Diagramm-Dimensionen angegeben werden. Verwende 0, wenn die Dimensionen automatisch ermittelt werden sollen.',0), 6003 => array('Ungültiges Format für den Bedingungs-Parameter bei Index=%d in CreateSimple(). Der Parameter muss bei index 0 starten und Vektoren in der Form (Row,Constrain-To,Constrain-Type) enthalten.',1), 6004 => array('Ungültiges Format für den Fortschritts-Parameter bei Index=%d in CreateSimple(). Der Parameter muss bei Index 0 starten und Vektoren in der Form (Row,Progress) enthalten.',1), 6005 => array('SetScale() ist nicht sinnvoll bei Gantt-Diagrammen.',0), 6006 => array('Das Gantt-Diagramm kann nicht automatisch skaliert werden. Es existieren keine Aktivitäten mit Termin. [GetBarMinMax() start >= n]',0), 6007 => array('Plausibiltätsprüfung für die automatische Gantt-Diagramm-Größe schlug fehl. Entweder die Breite (=%d) oder die Höhe (=%d) ist größer als MAX_GANTTIMG_SIZE. Dies kann möglicherweise durch einen falschen Wert bei einer Aktivität hervorgerufen worden sein.',2), 6008 => array('Du hast eine Bedingung angegeben von Reihe=%d bis Reihe=%d, die keine Aktivität hat.',2), 6009 => array('Unbekannter Bedingungstyp von Reihe=%d bis Reihe=%d',2), 6010 => array('Ungültiger Icon-Index für das eingebaute Gantt-Icon [%d]',1), 6011 => array('Argument für IconImage muss entweder ein String oder ein Integer sein.',0), 6012 => array('Unbekannter Typ bei der Gantt-Objekt-Title-Definition.',0), 6015 => array('Ungültige vertikale Position %d',1), 6016 => array('Der eingegebene Datums-String (%s) für eine Gantt-Aktivität kann nicht interpretiert werden. Versichere Dich, dass es ein gültiger Datumsstring ist, z.B. 2005-04-23 13:30',1), 6017 => array('Unbekannter Datumstyp in GanttScale (%s).',1), 6018 => array('Intervall für Minuten muss ein gerader Teiler einer Stunde sein, z.B. 1,5,10,12,15,20,30, etc. Du hast ein Intervall von %d Minuten angegeben.',1), 6019 => array('Die vorhandene Breite (%d) für die Minuten ist zu klein, um angezeigt zu werden. Bitte benutze die automatische Größenermittlung oder vergrößere die Breite des Diagramms.',1), 6020 => array('Das Intervall für die Stunden muss ein gerader Teiler eines Tages sein, z.B. 0:30, 1:00, 1:30, 4:00, etc. Du hast ein Intervall von %d eingegeben.',1), 6021 => array('Unbekanntes Format für die Woche.',0), 6022 => array('Die Gantt-Skala wurde nicht eingegeben.',0), 6023 => array('Wenn Du sowohl Stunden als auch Minuten anzeigen lassen willst, muss das Stunden-Interval gleich 1 sein (anderenfalls ist es nicht sinnvoll, Minuten anzeigen zu lassen).',0), 6024 => array('Das CSIM-Ziel muss als String angegeben werden. Der Start des Ziels ist: %d',1), 6025 => array('Der CSIM-Alt-Text muss als String angegeben werden. Der Beginn des Alt-Textes ist: %d',1), 6027 => array('Der Fortschrittswert muss im Bereich [0, 1] liegen.',0), 6028 => array('Die eingegebene Höhe (%d) für GanttBar ist nicht im zulässigen Bereich.',1), 6029 => array('Der Offset für die vertikale Linie muss im Bereich [0,1] sein.',0), 6030 => array('Unbekannte Pfeilrichtung für eine Verbindung.',0), 6031 => array('Unbekannter Pfeiltyp für eine Verbindung.',0), 6032 => array('Interner Fehler: Unbekannter Pfadtyp (=%d) für eine Verbindung.',1), 6033 => array('Array of fonts must contain arrays with 3 elements, i.e. (Family, Style, Size)',0), /* ** jpgraph_gradient */ 7001 => array('Unbekannter Gradiententyp (=%d).',1), /* ** jpgraph_iconplot */ 8001 => array('Der Mix-Wert für das Icon muss zwischen 0 und 100 sein.',0), 8002 => array('Die Ankerposition für Icons muss entweder "top", "bottom", "left", "right" oder "center" sein.',0), 8003 => array('Es ist nicht möglich, gleichzeitig ein Bild und eine Landesflagge für dasselbe Icon zu definieren',0), 8004 => array('Wenn Du Landesflaggen benutzen willst, musst Du die Datei "jpgraph_flags.php" hinzufügen (per include).',0), /* ** jpgraph_imgtrans */ 9001 => array('Der Wert für die Bildtransformation ist außerhalb des zulässigen Bereichs. Der verschwindende Punkt am Horizont muss als Wert zwischen 0 und 1 angegeben werden.',0), /* ** jpgraph_lineplot */ 10001 => array('Die Methode LinePlot::SetFilled() sollte nicht mehr benutzt werden. Benutze lieber SetFillColor()',0), 10002 => array('Der Plot ist zu kompliziert für FastLineStroke. Benutze lieber den StandardStroke()',0), 10003 => array('Each plot in an accumulated lineplot must have the same number of data points.',0), /* ** jpgraph_log */ 11001 => array('Deine Daten enthalten nicht-numerische Werte.',0), 11002 => array('Negative Werte können nicht für logarithmische Achsen verwendet werden.',0), 11003 => array('Deine Daten enthalten nicht-numerische Werte.',0), 11004 => array('Skalierungsfehler für die logarithmische Achse. Es gibt ein Problem mit den Daten der Achse. Der größte Wert muss größer sein als Null. Es ist mathematisch nicht möglich, einen Wert gleich Null in der Skala zu haben.',0), 11005 => array('Das Tick-Intervall für die logarithmische Achse ist nicht definiert. Lösche jeden Aufruf von SetTextLabelStart() oder SetTextTickInterval() bei der logarithmischen Achse.',0), /* ** jpgraph_mgraph */ 12001 => array("Du benutzt GD 2.x und versuchst ein Nicht-Truecolor-Bild als Hintergrundbild zu benutzen. Um Hintergrundbilder mit GD 2.x zu benutzen, ist es notwendig Truecolor zu aktivieren, indem die USE_TRUECOLOR-Konstante auf TRUE gesetzt wird. Wegen eines Bugs in GD 2.0.1 ist die Qualität der Truetype-Schriften sehr schlecht, wenn man Truetype-Schriften mit Truecolor-Bildern verwendet.",0), 12002 => array('Ungültiger Dateiname für MGraph::SetBackgroundImage() : %s. Die Datei muss eine gültige Dateierweiterung haben (jpg,gif,png), wenn die automatische Typerkennung verwendet wird.',1), 12003 => array('Unbekannte Dateierweiterung (%s) in MGraph::SetBackgroundImage() für Dateiname: %s',2), 12004 => array('Das Bildformat des Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterstützt. ',1), 12005 => array('Das Hintergrundbild kann nicht gelesen werden: %s',1), 12006 => array('Es wurden ungültige Größen für Breite oder Höhe beim Erstellen des Bildes angegeben, (Breite=%d, Höhe=%d)',2), 12007 => array('Das Argument für MGraph::Add() ist nicht gültig für GD.',0), 12008 => array('Deine PHP- (und GD-lib-) Installation scheint keine bekannten Bildformate zu unterstützen.',0), 12009 => array('Deine PHP-Installation unterstützt das gewählte Bildformat nicht: %s',1), 12010 => array('Es konnte kein Bild als Datei %s erzeugt werden. Überprüfe, ob Du die entsprechenden Schreibrechte im aktuellen Verzeichnis hast.',1), 12011 => array('Es konnte kein Truecolor-Bild erzeugt werden. Überprüfe, ob Du wirklich die GD2-Bibliothek installiert hast.',0), 12012 => array('Es konnte kein Bild erzeugt werden. Überprüfe, ob Du wirklich die GD2-Bibliothek installiert hast.',0), /* ** jpgraph_pie3d */ 14001 => array('Pie3D::ShowBorder(). Missbilligte Funktion. Benutze Pie3D::SetEdge(), um die Ecken der Tortenstücke zu kontrollieren.',0), 14002 => array('PiePlot3D::SetAngle() 3D-Torten-Projektionswinkel muss zwischen 5 und 85 Grad sein.',0), 14003 => array('Interne Festlegung schlug fehl. Pie3D::Pie3DSlice',0), 14004 => array('Tortenstück-Startwinkel muss zwischen 0 und 360 Grad sein.',0), 14005 => array('Pie3D Interner Fehler: Versuch, zweimal zu umhüllen bei der Suche nach dem Startindex.',0,), 14006 => array('Pie3D Interner Fehler: Z-Sortier-Algorithmus für 3D-Tortendiagramme funktioniert nicht einwandfrei (2). Versuch, zweimal zu umhüllen beim Erstellen des Bildes.',0), 14007 => array('Die Breite für das 3D-Tortendiagramm ist 0. Gib eine Breite > 0 an.',0), /* ** jpgraph_pie */ 15001 => array('PiePLot::SetTheme() Unbekannter Stil: %s',1), 15002 => array('Argument für PiePlot::ExplodeSlice() muss ein Integer-Wert sein',0), 15003 => array('Argument für PiePlot::Explode() muss ein Vektor mit Integer-Werten sein.',0), 15004 => array('Tortenstück-Startwinkel muss zwischen 0 und 360 Grad sein.',0), 15005 => array('PiePlot::SetFont() sollte nicht mehr verwendet werden. Benutze stattdessen PiePlot->value->SetFont().',0), 15006 => array('PiePlot::SetSize() Radius für Tortendiagramm muss entweder als Bruch [0, 0.5] der Bildgröße oder als Absoluwert in Pixel im Bereich [10, 1000] angegeben werden.',0), 15007 => array('PiePlot::SetFontColor() sollte nicht mehr verwendet werden. Benutze stattdessen PiePlot->value->SetColor()..',0), 15008 => array('PiePlot::SetLabelType() der Typ für Tortendiagramme muss entweder 0 or 1 sein (nicht %d).',1), 15009 => array('Ungültiges Tortendiagramm. Die Summe aller Daten ist Null.',0), 15010 => array('Die Summe aller Daten ist Null.',0), 15011 => array('Um Bildtransformationen benutzen zu können, muss die Datei jpgraph_imgtrans.php eingefügt werden (per include).',0), /* ** jpgraph_plotband */ 16001 => array('Die Dichte für das Pattern muss zwischen 1 und 100 sein. (Du hast %f eingegeben)',1), 16002 => array('Es wurde keine Position für das Pattern angegeben.',0), 16003 => array('Unbekannte Pattern-Definition (%d)',0), 16004 => array('Der Mindeswert für das PlotBand ist größer als der Maximalwert. Bitte korrigiere dies!',0), /* ** jpgraph_polar */ 17001 => array('PolarPlots müssen eine gerade Anzahl von Datenpunkten haben. Jeder Datenpunkt ist ein Tupel (Winkel, Radius).',0), 17002 => array('Unbekannte Ausrichtung für X-Achsen-Titel. (%s)',1), //17003 => array('Set90AndMargin() wird für PolarGraph nicht unterstützt.',0), 17004 => array('Unbekannter Achsentyp für PolarGraph. Er muss entweder \'lin\' oder \'log\' sein.',0), /* ** jpgraph_radar */ 18001 => array('ClientSideImageMaps werden für RadarPlots nicht unterstützt.',0), 18002 => array('RadarGraph::SupressTickMarks() sollte nicht mehr verwendet werden. Benutze stattdessen HideTickMarks().',0), 18003 => array('Ungültiger Achsentyp für RadarPlot (%s). Er muss entweder \'lin\' oder \'log\' sein.',1), 18004 => array('Die RadarPlot-Größe muss zwischen 0.1 und 1 sein. (Dein Wert=%f)',1), 18005 => array('RadarPlot: nicht unterstützte Tick-Dichte: %d',1), 18006 => array('Minimum Daten %f (RadarPlots sollten nur verwendet werden, wenn alle Datenpunkte einen Wert > 0 haben).',1), 18007 => array('Die Anzahl der Titel entspricht nicht der Anzahl der Datenpunkte.',0), 18008 => array('Jeder RadarPlot muss die gleiche Anzahl von Datenpunkten haben.',0), /* ** jpgraph_regstat */ 19001 => array('Spline: Anzahl der X- und Y-Koordinaten muss gleich sein.',0), 19002 => array('Ungültige Dateneingabe für Spline. Zwei oder mehr aufeinanderfolgende X-Werte sind identisch. Jeder eigegebene X-Wert muss unterschiedlich sein, weil vom mathematischen Standpunkt ein Eins-zu-Eins-Mapping vorliegen muss, d.h. jeder X-Wert korrespondiert mit exakt einem Y-Wert.',0), 19003 => array('Bezier: Anzahl der X- und Y-Koordinaten muss gleich sein.',0), /* ** jpgraph_scatter */ 20001 => array('Fieldplots müssen die gleiche Anzahl von X und Y Datenpunkten haben.',0), 20002 => array('Bei Fieldplots muss ein Winkel für jeden X und Y Datenpunkt angegeben werden.',0), 20003 => array('Scatterplots müssen die gleiche Anzahl von X- und Y-Datenpunkten haben.',0), /* ** jpgraph_stock */ 21001 => array('Die Anzahl der Datenwerte für Stock-Charts müssen ein Mehrfaches von %d Datenpunkten sein.',1), /* ** jpgraph_plotmark */ 23001 => array('Der Marker "%s" existiert nicht in der Farbe: %d',2), 23002 => array('Der Farb-Index ist zu hoch für den Marker "%s"',1), 23003 => array('Ein Dateiname muss angegeben werden, wenn Du den Marker-Typ auf MARK_IMG setzt.',0), /* ** jpgraph_utils */ 24001 => array('FuncGenerator : Keine Funktion definiert. ',0), 24002 => array('FuncGenerator : Syntax-Fehler in der Funktionsdefinition ',0), 24003 => array('DateScaleUtils: Unknown tick type specified in call to GetTicks()',0), 24004 => array('ReadCSV2: Die anzahl der spalten fehler in %s reihe %d',2), /* ** jpgraph */ 25001 => array('Diese PHP-Installation ist nicht mit der GD-Bibliothek kompiliert. Bitte kompiliere PHP mit GD-Unterstützung neu, damit JpGraph funktioniert. (Weder die Funktion imagetypes() noch imagecreatefromstring() existiert!)',0), 25002 => array('Diese PHP-Installation scheint nicht die benötigte GD-Bibliothek zu unterstützen. Bitte schau in der PHP-Dokumentation nach, wie man die GD-Bibliothek installiert und aktiviert.',0), 25003 => array('Genereller PHP Fehler : Bei %s:%d : %s',3), 25004 => array('Genereller PHP Fehler : %s ',1), 25005 => array('PHP_SELF, die PHP-Global-Variable kann nicht ermittelt werden. PHP kann nicht von der Kommandozeile gestartet werden, wenn der Cache oder die Bilddateien automatisch benannt werden sollen.',0), 25006 => array('Die Benutzung der FF_CHINESE (FF_BIG5) Schriftfamilie benötigt die iconv() Funktion in Deiner PHP-Konfiguration. Dies wird nicht defaultmäßig in PHP kompiliert (benötigt "--width-iconv" bei der Konfiguration).',0), 25007 => array('Du versuchst das lokale (%s) zu verwenden, was von Deiner PHP-Installation nicht unterstützt wird. Hinweis: Benutze \'\', um das defaultmäßige Lokale für diese geographische Region festzulegen.',1), 25008 => array('Die Bild-Breite und Höhe in Graph::Graph() müssen numerisch sein',0), 25009 => array('Die Skalierung der Achsen muss angegeben werden mit Graph::SetScale()',0), 25010 => array('Graph::Add() Du hast versucht, einen leeren Plot zum Graph hinzuzufügen.',0), 25011 => array('Graph::AddY2() Du hast versucht, einen leeren Plot zum Graph hinzuzufügen.',0), 25012 => array('Graph::AddYN() Du hast versucht, einen leeren Plot zum Graph hinzuzufügen.',0), 25013 => array('Es können nur Standard-Plots zu multiplen Y-Achsen hinzugefügt werden',0), 25014 => array('Graph::AddText() Du hast versucht, einen leeren Text zum Graph hinzuzufügen.',0), 25015 => array('Graph::AddLine() Du hast versucht, eine leere Linie zum Graph hinzuzufügen.',0), 25016 => array('Graph::AddBand() Du hast versucht, ein leeres Band zum Graph hinzuzufügen.',0), 25017 => array('Du benutzt GD 2.x und versuchst, ein Hintergrundbild in einem Truecolor-Bild zu verwenden. Um Hintergrundbilder mit GD 2.x zu verwenden, ist es notwendig, Truecolor zu aktivieren, indem die USE_TRUECOLOR-Konstante auf TRUE gesetzt wird. Wegen eines Bugs in GD 2.0.1 ist die Qualität der Schrift sehr schlecht, wenn Truetype-Schrift in Truecolor-Bildern verwendet werden.',0), 25018 => array('Falscher Dateiname für Graph::SetBackgroundImage() : "%s" muss eine gültige Dateinamenerweiterung (jpg,gif,png) haben, wenn die automatische Dateityperkennung verwenndet werden soll.',1), 25019 => array('Unbekannte Dateinamenerweiterung (%s) in Graph::SetBackgroundImage() für Dateiname: "%s"',2), 25020 => array('Graph::SetScale(): Dar Maximalwert muss größer sein als der Mindestwert.',0), 25021 => array('Unbekannte Achsendefinition für die Y-Achse. (%s)',1), 25022 => array('Unbekannte Achsendefinition für die X-Achse. (%s)',1), 25023 => array('Nicht unterstützter Y2-Achsentyp: "%s" muss einer von (lin,log,int) sein.',1), 25024 => array('Nicht unterstützter X-Achsentyp: "%s" muss einer von (lin,log,int) sein.',1), 25025 => array('Nicht unterstützte Tick-Dichte: %d',1), 25026 => array('Nicht unterstützter Typ der nicht angegebenen Y-Achse. Du hast entweder: 1. einen Y-Achsentyp für automatisches Skalieren definiert, aber keine Plots angegeben. 2. eine Achse direkt definiert, aber vergessen, die Tick-Dichte zu festzulegen.',0), 25027 => array('Kann cached CSIM "%s" zum Lesen nicht öffnen.',1), 25028 => array('Apache/PHP hat keine Schreibrechte, in das CSIM-Cache-Verzeichnis (%s) zu schreiben. Überprüfe die Rechte.',1), 25029 => array('Kann nicht in das CSIM "%s" schreiben. Überprüfe die Schreibrechte und den freien Speicherplatz.',1), 25030 => array('Fehlender Skriptname für StrokeCSIM(). Der Name des aktuellen Skriptes muss als erster Parameter von StrokeCSIM() angegeben werden.',0), 25031 => array('Der Achsentyp muss mittels Graph::SetScale() angegeben werden.',0), 25032 => array('Es existieren keine Plots für die Y-Achse nbr:%d',1), 25033 => array('',0), 25034 => array('Undefinierte X-Achse kann nicht gezeichnet werden. Es wurden keine Plots definiert.',0), 25035 => array('Du hast Clipping aktiviert. Clipping wird nur für Diagramme mit 0 oder 90 Grad Rotation unterstützt. Bitte verändere Deinen Rotationswinkel (=%d Grad) dementsprechend oder deaktiviere Clipping.',1), 25036 => array('Unbekannter Achsentyp AxisStyle() : %s',1), 25037 => array('Das Bildformat Deines Hintergrundbildes (%s) wird von Deiner System-Konfiguration nicht unterstützt. ',1), 25038 => array('Das Hintergrundbild scheint von einem anderen Typ (unterschiedliche Dateierweiterung) zu sein als der angegebene Typ. Angegebenen: %s; Datei: %s',2), 25039 => array('Hintergrundbild kann nicht gelesen werden: "%s"',1), 25040 => array('Es ist nicht möglich, sowohl ein Hintergrundbild als auch eine Hintergrund-Landesflagge anzugeben.',0), 25041 => array('Um Landesflaggen als Hintergrund benutzen zu können, muss die Datei "jpgraph_flags.php" eingefügt werden (per include).',0), 25042 => array('Unbekanntes Hintergrundbild-Layout',0), 25043 => array('Unbekannter Titelhintergrund-Stil.',0), 25044 => array('Automatisches Skalieren kann nicht verwendet werden, weil es unmöglich ist, einen gültigen min/max Wert für die Y-Achse zu ermitteln (nur Null-Werte).',0), 25045 => array('Die Schriftfamilien FF_HANDWRT und FF_BOOK sind wegen Copyright-Problemen nicht mehr verfügbar. Diese Schriften können nicht mehr mit JpGraph verteilt werden. Bitte lade Dir Schriften von http://corefonts.sourceforge.net/ herunter.',0), 25046 => array('Angegebene TTF-Schriftfamilie (id=%d) ist unbekannt oder existiert nicht. Bitte merke Dir, dass TTF-Schriften wegen Copyright-Problemen nicht mit JpGraph mitgeliefert werden. Du findest MS-TTF-Internetschriften (arial, courier, etc.) zum Herunterladen unter http://corefonts.sourceforge.net/',1), 25047 => array('Stil %s ist nicht verfügbar für Schriftfamilie %s',2), 25048 => array('Unbekannte Schriftstildefinition [%s].',1), 25049 => array('Schriftdatei "%s" ist nicht lesbar oder existiert nicht.',1), 25050 => array('Erstes Argument für Text::Text() muss ein String sein.',0), 25051 => array('Ungültige Richtung angegeben für Text.',0), 25052 => array('PANIK: Interner Fehler in SuperScript::Stroke(). Unbekannte vertikale Ausrichtung für Text.',0), 25053 => array('PANIK: Interner Fehler in SuperScript::Stroke(). Unbekannte horizontale Ausrichtung für Text.',0), 25054 => array('Interner Fehler: Unbekannte Grid-Achse %s',1), 25055 => array('Axis::SetTickDirection() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetTickSide().',0), 25056 => array('SetTickLabelMargin() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetLabelMargin().',0), 25057 => array('SetTextTicks() sollte nicht mehr verwendet werden. Benutze stattdessen SetTextTickInterval().',0), 25058 => array('TextLabelIntevall >= 1 muss angegeben werden.',0), 25059 => array('SetLabelPos() sollte nicht mehr verwendet werden. Benutze stattdessen Axis::SetLabelSide().',0), 25060 => array('Unbekannte Ausrichtung angegeben für X-Achsentitel (%s).',1), 25061 => array('Unbekannte Ausrichtung angegeben für Y-Achsentitel (%s).',1), 25062 => array('Label unter einem Winkel werden für die Y-Achse nicht unterstützt.',0), 25063 => array('Ticks::SetPrecision() sollte nicht mehr verwendet werden. Benutze stattdessen Ticks::SetLabelFormat() (oder Ticks::SetFormatCallback()).',0), 25064 => array('Kleinere oder größere Schrittgröße ist 0. Überprüfe, ob Du fälschlicherweise SetTextTicks(0) in Deinem Skript hast. Wenn dies nicht der Fall ist, bist Du eventuell über einen Bug in JpGraph gestolpert. Bitte sende einen Report und füge den Code an, der den Fehler verursacht hat.',0), 25065 => array('Tick-Positionen müssen als array() angegeben werden',0), 25066 => array('Wenn die Tick-Positionen und -Label von Hand eingegeben werden, muss die Anzahl der Ticks und der Label gleich sein.',0), 25067 => array('Deine von Hand eingegebene Achse und Ticks sind nicht korrekt. Die Skala scheint zu klein zu sein für den Tickabstand.',0), 25068 => array('Ein Plot hat eine ungültige Achse. Dies kann beispielsweise der Fall sein, wenn Du automatisches Text-Skalieren verwendest, um ein Liniendiagramm zu zeichnen mit nur einem Datenpunkt, oder wenn die Bildfläche zu klein ist. Es kann auch der Fall sein, dass kein Datenpunkt einen numerischen Wert hat (vielleicht nur \'-\' oder \'x\').',0), 25069 => array('Grace muss größer sein als 0',0), 25070 => array('Deine Daten enthalten nicht-numerische Werte.',0), 25071 => array('Du hast mit SetAutoMin() einen Mindestwert angegeben, der größer ist als der Maximalwert für die Achse. Dies ist nicht möglich.',0), 25072 => array('Du hast mit SetAutoMax() einen Maximalwert angegeben, der kleiner ist als der Minimalwert der Achse. Dies ist nicht möglich.',0), 25073 => array('Interner Fehler. Der Integer-Skalierungs-Algorithmus-Vergleich ist außerhalb der Grenzen (r=%f).',1), 25074 => array('Interner Fehler. Der Skalierungsbereich ist negativ (%f) [für %s Achse]. Dieses Problem könnte verursacht werden durch den Versuch, \'ungültige\' Werte in die Daten-Vektoren einzugeben (z.B. nur String- oder NULL-Werte), was beim automatischen Skalieren einen Fehler erzeugt.',2), 25075 => array('Die automatischen Ticks können nicht gesetzt werden, weil min==max.',0), 25077 => array('Einstellfaktor für die Farbe muss größer sein als 0',0), 25078 => array('Unbekannte Farbe: %s',1), 25079 => array('Unbekannte Farbdefinition: %s, Größe=%d',2), 25080 => array('Der Alpha-Parameter für Farben muss zwischen 0.0 und 1.0 liegen.',0), 25081 => array('Das ausgewählte Grafikformat wird entweder nicht unterstützt oder ist unbekannt [%s]',1), 25082 => array('Es wurden ungültige Größen für Breite und Höhe beim Erstellen des Bildes definiert (Breite=%d, Höhe=%d).',2), 25083 => array('Es wurde eine ungültige Größe beim Kopieren des Bildes angegeben. Die Größe für das kopierte Bild wurde auf 1 Pixel oder weniger gesetzt.',0), 25084 => array('Fehler beim Erstellen eines temporären GD-Canvas. Möglicherweise liegt ein Arbeitsspeicherproblem vor.',0), 25085 => array('Ein Bild kann nicht aus dem angegebenen String erzeugt werden. Er ist entweder in einem nicht unterstützen Format oder er represäntiert ein kaputtes Bild.',0), 25086 => array('Du scheinst nur GD 1.x installiert zu haben. Um Alphablending zu aktivieren, ist GD 2.x oder höher notwendig. Bitte installiere GD 2.x oder versichere Dich, dass die Konstante USE_GD2 richtig gesetzt ist. Standardmäßig wird die installierte GD-Version automatisch erkannt. Ganz selten wird GD2 erkannt, obwohl nur GD1 installiert ist. Die Konstante USE_GD2 muss dann zu "false" gesetzt werden.',0), 25087 => array('Diese PHP-Version wurde ohne TTF-Unterstützung konfiguriert. PHP muss mit TTF-Unterstützung neu kompiliert und installiert werden.',0), 25088 => array('Die GD-Schriftunterstützung wurde falsch konfiguriert. Der Aufruf von imagefontwidth() ist fehlerhaft.',0), 25089 => array('Die GD-Schriftunterstützung wurde falsch konfiguriert. Der Aufruf von imagefontheight() ist fehlerhaft.',0), 25090 => array('Unbekannte Richtung angegeben im Aufruf von StrokeBoxedText() [%s].',1), 25091 => array('Die interne Schrift untestützt das Schreiben von Text in einem beliebigen Winkel nicht. Benutze stattdessen TTF-Schriften.',0), 25092 => array('Es liegt entweder ein Konfigurationsproblem mit TrueType oder ein Problem beim Lesen der Schriftdatei "%s" vor. Versichere Dich, dass die Datei existiert und Leserechte und -pfad vergeben sind. (wenn \'basedir\' restriction in PHP aktiviert ist, muss die Schriftdatei im Dokumentwurzelverzeichnis abgelegt werden). Möglicherweise ist die FreeType-Bibliothek falsch installiert. Versuche, mindestens zur FreeType-Version 2.1.13 zu aktualisieren und kompiliere GD mit einem korrekten Setup neu, damit die FreeType-Bibliothek gefunden werden kann.',1), 25093 => array('Die Schriftdatei "%s" kann nicht gelesen werden beim Aufruf von Image::GetBBoxTTF. Bitte versichere Dich, dass die Schrift gesetzt wurde, bevor diese Methode aufgerufen wird, und dass die Schrift im TTF-Verzeichnis installiert ist.',1), 25094 => array('Die Textrichtung muss in einem Winkel zwischen 0 und 90 engegeben werden.',0), 25095 => array('Unbekannte Schriftfamilien-Definition. ',0), 25096 => array('Der Farbpalette können keine weiteren Farben zugewiesen werden. Dem Bild wurde bereits die größtmögliche Anzahl von Farben (%d) zugewiesen und die Palette ist voll. Verwende stattdessen ein TrueColor-Bild',0), 25097 => array('Eine Farbe wurde als leerer String im Aufruf von PushColor() angegegeben.',0), 25098 => array('Negativer Farbindex. Unpassender Aufruf von PopColor().',0), 25099 => array('Die Parameter für Helligkeit und Kontrast sind außerhalb des zulässigen Bereichs [-1,1]',0), 25100 => array('Es liegt ein Problem mit der Farbpalette und dem GD-Setup vor. Bitte deaktiviere anti-aliasing oder verwende GD2 mit TrueColor. Wenn die GD2-Bibliothek installiert ist, versichere Dich, dass die Konstante USE_GD2 auf "true" gesetzt und TrueColor aktiviert ist.',0), 25101 => array('Ungültiges numerisches Argument für SetLineStyle(): (%d)',1), 25102 => array('Ungültiges String-Argument für SetLineStyle(): %s',1), 25103 => array('Ungültiges Argument für SetLineStyle %s',1), 25104 => array('Unbekannter Linientyp: %s',1), 25105 => array('Es wurden NULL-Daten für ein gefülltes Polygon angegeben. Sorge dafür, dass keine NULL-Daten angegeben werden.',0), 25106 => array('Image::FillToBorder : es können keine weiteren Farben zugewiesen werden.',0), 25107 => array('In Datei "%s" kann nicht geschrieben werden. Überprüfe die aktuellen Schreibrechte.',1), 25108 => array('Das Bild kann nicht gestreamt werden. Möglicherweise liegt ein Fehler im PHP/GD-Setup vor. Kompiliere PHP neu und verwende die eingebaute GD-Bibliothek, die mit PHP angeboten wird.',0), 25109 => array('Deine PHP- (und GD-lib-) Installation scheint keine bekannten Grafikformate zu unterstützen. Sorge zunächst dafür, dass GD als PHP-Modul kompiliert ist. Wenn Du außerdem JPEG-Bilder verwenden willst, musst Du die JPEG-Bibliothek installieren. Weitere Details sind in der PHP-Dokumentation zu finden.',0), 25110 => array('Dein PHP-Installation unterstützt das gewählte Grafikformat nicht: %s',1), 25111 => array('Das gecachete Bild %s kann nicht gelöscht werden. Problem mit den Rechten?',1), 25112 => array('Das Datum der gecacheten Datei (%s) liegt in der Zukunft.',1), 25113 => array('Das gecachete Bild %s kann nicht gelöscht werden. Problem mit den Rechten?',1), 25114 => array('PHP hat nicht die erforderlichen Rechte, um in die Cache-Datei %s zu schreiben. Bitte versichere Dich, dass der Benutzer, der PHP anwendet, die entsprechenden Schreibrechte für die Datei hat, wenn Du das Cache-System in JPGraph verwenden willst.',1), 25115 => array('Berechtigung für gecachetes Bild %s kann nicht gesetzt werden. Problem mit den Rechten?',1), 25116 => array('Datei kann nicht aus dem Cache %s geöffnet werden',1), 25117 => array('Gecachetes Bild %s kann nicht zum Lesen geöffnet werden.',1), 25118 => array('Verzeichnis %s kann nicht angelegt werden. Versichere Dich, dass PHP die Schreibrechte in diesem Verzeichnis hat.',1), 25119 => array('Rechte für Datei %s können nicht gesetzt werden. Problem mit den Rechten?',1), 25120 => array('Die Position für die Legende muss als Prozentwert im Bereich 0-1 angegeben werden.',0), 25121 => array('Eine leerer Datenvektor wurde für den Plot eingegeben. Es muss wenigstens ein Datenpunkt vorliegen.',0), 25122 => array('Stroke() muss als Subklasse der Klasse Plot definiert sein.',0), 25123 => array('Du kannst keine Text-X-Achse mit X-Koordinaten verwenden. Benutze stattdessen eine "int" oder "lin" Achse.',0), 25124 => array('Der Eingabedatenvektor mus aufeinanderfolgende Werte von 0 aufwärts beinhalten. Der angegebene Y-Vektor beginnt mit leeren Werten (NULL).',0), 25125 => array('Ungültige Richtung für statische Linie.',0), 25126 => array('Es kann kein TrueColor-Bild erzeugt werden. Überprüfe, ob die GD2-Bibliothek und PHP korrekt aufgesetzt wurden.',0), 25127 => array('The library has been configured for automatic encoding conversion of Japanese fonts. This requires that PHP has the mb_convert_encoding() function. Your PHP installation lacks this function (PHP needs the "--enable-mbstring" when compiled).',0), 25128 => array('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.',0), 25129 => array('Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines.',0), 25130 => array('Too small plot area. (%d x %d). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins.',2), 25131 => array('StrokeBoxedText2() only supports TTF fonts and not built-in bitmap fonts.',0), /* ** jpgraph_led */ 25500 => array('Multibyte strings must be enabled in the PHP installation in order to run the LED module so that the function mb_strlen() is available. See PHP documentation for more information.',0), /* **--------------------------------------------------------------------------------------------- ** Pro-version strings **--------------------------------------------------------------------------------------------- */ /* ** jpgraph_table */ 27001 => array('GTextTable: Ungültiges Argument für Set(). Das Array-Argument muss 2-- dimensional sein.',0), 27002 => array('GTextTable: Ungültiges Argument für Set()',0), 27003 => array('GTextTable: Falsche Anzahl von Argumenten für GTextTable::SetColor()',0), 27004 => array('GTextTable: Angegebener Zellenbereich, der verschmolzen werden soll, ist ungültig.',0), 27005 => array('GTextTable: Bereits verschmolzene Zellen im Bereich (%d,%d) bis (%d,%d) können nicht ein weiteres Mal verschmolzen werden.',4), 27006 => array('GTextTable: Spalten-Argument = %d liegt außerhalb der festgelegten Tabellengröße.',1), 27007 => array('GTextTable: Zeilen-Argument = %d liegt außerhalb der festgelegten Tabellengröße.',1), 27008 => array('GTextTable: Spalten- und Zeilengröße müssen zu den Dimensionen der Tabelle passen.',0), 27009 => array('GTextTable: Die Anzahl der Tabellenspalten oder -zeilen ist 0. Versichere Dich, dass die Methoden Init() oder Set() aufgerufen werden.',0), 27010 => array('GTextTable: Es wurde keine Ausrichtung beim Aufruf von SetAlign() angegeben.',0), 27011 => array('GTextTable: Es wurde eine unbekannte Ausrichtung beim Aufruf von SetAlign() abgegeben. Horizontal=%s, Vertikal=%s',2), 27012 => array('GTextTable: Interner Fehler. Es wurde ein ungültiges Argument festgeleget %s',1), 27013 => array('GTextTable: Das Argument für FormatNumber() muss ein String sein.',0), 27014 => array('GTextTable: Die Tabelle wurde weder mit einem Aufruf von Set() noch von Init() initialisiert.',0), 27015 => array('GTextTable: Der Zellenbildbedingungstyp muss entweder TIMG_WIDTH oder TIMG_HEIGHT sein.',0), /* ** jpgraph_windrose */ 22001 => array('Die Gesamtsumme der prozentualen Anteile aller Windrosenarme darf 100%% nicht überschreiten!\n(Aktuell max: %d)',1), 22002 => array('Das Bild ist zu klein für eine Skala. Bitte vergrößere das Bild.',0), 22004 => array('Die Etikettendefinition für Windrosenrichtungen müssen 16 Werte haben (eine für jede Kompassrichtung).',0), 22005 => array('Der Linientyp für radiale Linien muss einer von ("solid","dotted","dashed","longdashed") sein.',0), 22006 => array('Es wurde ein ungültiger Windrosentyp angegeben.',0), 22007 => array('Es wurden zu wenig Werte für die Bereichslegende angegeben.',0), 22008 => array('Interner Fehler: Versuch, eine freie Windrose zu plotten, obwohl der Typ keine freie Windrose ist.',0), 22009 => array('Du hast die gleiche Richtung zweimal angegeben, einmal mit einem Winkel und einmal mit einer Kompassrichtung (%f Grad).',0), 22010 => array('Die Richtung muss entweder ein numerischer Wert sein oder eine der 16 Kompassrichtungen',0), 22011 => array('Der Windrosenindex muss ein numerischer oder Richtungswert sein. Du hast angegeben Index=%d',1), 22012 => array('Die radiale Achsendefinition für die Windrose enthält eine nicht aktivierte Richtung.',0), 22013 => array('Du hast dasselbe Look&Feel für die gleiche Kompassrichtung zweimal engegeben, einmal mit Text und einmal mit einem Index (Index=%d)',1), 22014 => array('Der Index für eine Kompassrichtung muss zwischen 0 und 15 sein.',0), 22015 => array('Du hast einen unbekannten Windrosenplottyp angegeben.',0), 22016 => array('Der Windrosenarmindex muss ein numerischer oder ein Richtungswert sein.',0), 22017 => array('Die Windrosendaten enthalten eine Richtung, die nicht aktiviert ist. Bitte berichtige, welche Label angezeigt werden sollen.',0), 22018 => array('Du hast für dieselbe Kompassrichtung zweimal Daten angegeben, einmal mit Text und einmal mit einem Index (Index=%d)',1), 22019 => array('Der Index für eine Richtung muss zwischen 0 und 15 sein. Winkel dürfen nicht für einen regelmäßigen Windplot angegeben werden, sondern entweder ein Index oder eine Kompassrichtung.',0), 22020 => array('Der Windrosenplot ist zu groß für die angegebene Bildgröße. Benutze entweder WindrosePlot::SetSize(), um den Plot kleiner zu machen oder vergrößere das Bild im ursprünglichen Aufruf von WindroseGraph().',0), 22021 => array('It is only possible to add Text, IconPlot or WindrosePlot to a Windrose Graph',0), /* ** jpgraph_odometer */ 13001 => array('Unbekannter Nadeltypstil (%d).',1), 13002 => array('Ein Wert für das Odometer (%f) ist außerhalb des angegebenen Bereichs [%f,%f]',3), /* ** jpgraph_barcode */ 1001 => array('Unbekannte Kodier-Specifikation: %s',1), 1002 => array('datenvalidierung schlug fehl. [%s] kann nicht mittels der Kodierung "%s" kodiert werden',2), 1003 => array('Interner Kodierfehler. Kodieren von %s ist nicht möglich in Code 128',1), 1004 => array('Interner barcode Fehler. Unbekannter UPC-E Kodiertyp: %s',1), 1005 => array('Interner Fehler. Das Textzeichen-Tupel (%s, %s) kann nicht im Code-128 Zeichensatz C kodiert werden.',2), 1006 => array('Interner Kodierfehler für CODE 128. Es wurde versucht, CTRL in CHARSET != A zu kodieren.',0), 1007 => array('Interner Kodierfehler für CODE 128. Es wurde versucht, DEL in CHARSET != B zu kodieren.',0), 1008 => array('Interner Kodierfehler für CODE 128. Es wurde versucht, kleine Buchstaben in CHARSET != B zu kodieren.',0), 1009 => array('Kodieren mittels CODE 93 wird noch nicht unterstützt.',0), 1010 => array('Kodieren mittels POSTNET wird noch nicht unterstützt.',0), 1011 => array('Nicht untrstütztes Barcode-Backend für den Typ %s',1), /* ** PDF417 */ 26000 => array('PDF417: The PDF417 module requires that the PHP installation must support the function bcmod(). This is normally enabled at compile time. See documentation for more information.',0), 26001 => array('PDF417: Die Anzahl der Spalten muss zwischen 1 und 30 sein.',0), 26002 => array('PDF417: Der Fehler-Level muss zwischen 0 und 8 sein.',0), 26003 => array('PDF417: Ungültiges Format für Eingabedaten, um sie mit PDF417 zu kodieren.',0), 26004 => array('PDF417: die eigebenen Daten können nicht mit Fehler-Level %d und %d spalten kodiert werden, weil daraus zu viele Symbole oder mehr als 90 Zeilen resultieren.',2), 26005 => array('PDF417: Die Datei "%s" kann nicht zum Schreiben geöffnet werden.',1), 26006 => array('PDF417: Interner Fehler. Die Eingabedatendatei für PDF417-Cluster %d ist fehlerhaft.',1), 26007 => array('PDF417: Interner Fehler. GetPattern: Ungültiger Code-Wert %d (Zeile %d)',2), 26008 => array('PDF417: Interner Fehler. Modus wurde nicht in der Modusliste!! Modus %d',1), 26009 => array('PDF417: Kodierfehler: Ungültiges Zeichen. Zeichen kann nicht mit ASCII-Code %d kodiert werden.',1), 26010 => array('PDF417: Interner Fehler: Keine Eingabedaten beim Dekodieren.',0), 26011 => array('PDF417: Kodierfehler. Numerisches Kodieren bei nicht-numerischen Daten nicht möglich.',0), 26012 => array('PDF417: Interner Fehler. Es wurden für den Binary-Kompressor keine Daten zum Dekodieren eingegeben.',0), 26013 => array('PDF417: Interner Fehler. Checksum Fehler. Koeffiziententabellen sind fehlerhaft.',0), 26014 => array('PDF417: Interner Fehler. Es wurden keine Daten zum Berechnen von Kodewörtern eingegeben.',0), 26015 => array('PDF417: Interner Fehler. Ein Eintrag 0 in die Statusübertragungstabellen ist nicht NULL. Eintrag 1 = (%s)',1), 26016 => array('PDF417: Interner Fehler: Nichtregistrierter Statusübertragungsmodus beim Dekodieren.',0), /* ** jpgraph_contour */ 28001 => array('Dritten parameter fur Contour muss ein vector der fargen sind.',0), 28002 => array('Die anzahlen der farges jeder isobar linien muss gleich sein.',0), 28003 => array('ContourPlot Interner Fehler: isobarHCrossing: Spalten index ist zu hoch (%d)',1), 28004 => array('ContourPlot Interner Fehler: isobarHCrossing: Reihe index ist zu hoch (%d)',1), 28005 => array('ContourPlot Interner Fehler: isobarVCrossing: Reihe index ist zu hoch (%d)',1), 28006 => array('ContourPlot Interner Fehler: isobarVCrossing: Spalten index ist zu hoch (%d)',1), 28007 => array('ContourPlot. Interpolation faktor ist zu hoch (>5)',0), /* * jpgraph_matrix and colormap */ 29201 => array('Min range value must be less or equal to max range value for colormaps',0), 29202 => array('The distance between min and max value is too small for numerical precision',0), 29203 => array('Number of color quantification level must be at least %d',1), 29204 => array('Number of colors (%d) is invalid for this colormap. It must be a number that can be written as: %d + k*%d',3), 29205 => array('Colormap specification out of range. Must be an integer in range [0,%d]',1), 29206 => array('Invalid object added to MatrixGraph',0), 29207 => array('Empty input data specified for MatrixPlot',0), 29208 => array('Unknown side specifiction for matrix labels "%s"',1), 29209 => array('CSIM Target matrix must be the same size as the data matrix (csim=%d x %d, data=%d x %d)',4), 29210 => array('CSIM Target for matrix labels does not match the number of labels (csim=%d, labels=%d)',2), ); ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_line.php0000644000175000017500000005635212225176641022401 0ustar danieldanielmark = new PlotMark() ; $this->color = ColorFactory::getColor(); $this->fill_color = $this->color; } //--------------- // PUBLIC METHODS function SetFilled($aFlg=true) { $this->filled = $aFlg; } function SetBarCenter($aFlag=true) { $this->barcenter=$aFlag; } function SetStyle($aStyle) { $this->line_style=$aStyle; } function SetStepStyle($aFlag=true) { $this->step_style = $aFlag; } function SetColor($aColor) { parent::SetColor($aColor); } function SetFillFromYMin($f=true) { $this->fillFromMin = $f ; } function SetFillFromYMax($f=true) { $this->fillFromMax = $f ; } function SetFillColor($aColor,$aFilled=true) { //$this->color = $aColor; $this->fill_color=$aColor; $this->filled=$aFilled; } function SetFillGradient($aFromColor,$aToColor,$aNumColors=100,$aFilled=true) { $this->fillgrad_fromcolor = $aFromColor; $this->fillgrad_tocolor = $aToColor; $this->fillgrad_numcolors = $aNumColors; $this->filled = $aFilled; $this->fillgrad = true; } function Legend($graph) { if( $this->legend!="" ) { if( $this->filled && !$this->fillgrad ) { $graph->legend->Add($this->legend, $this->fill_color,$this->mark,0, $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); } elseif( $this->fillgrad ) { $color=array($this->fillgrad_fromcolor,$this->fillgrad_tocolor); // In order to differentiate between gradients and cooors specified as an RGB triple $graph->legend->Add($this->legend,$color,"",-2 /* -GRAD_HOR */, $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); } else { $graph->legend->Add($this->legend, $this->color,$this->mark,$this->line_style, $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); } } } function AddArea($aMin=0,$aMax=0,$aFilled=LP_AREA_NOT_FILLED,$aColor="gray9",$aBorder=LP_AREA_BORDER) { if($aMin > $aMax) { // swap $tmp = $aMin; $aMin = $aMax; $aMax = $tmp; } $this->filledAreas[] = array($aMin,$aMax,$aColor,$aFilled,$aBorder); } // Gets called before any axis are stroked function PreStrokeAdjust($graph) { // If another plot type have already adjusted the // offset we don't touch it. // (We check for empty in case the scale is a log scale // and hence doesn't contain any xlabel_offset) if( empty($graph->xaxis->scale->ticks->xlabel_offset) || $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { if( $this->center ) { ++$this->numpoints; $a=0.5; $b=0.5; } else { $a=0; $b=0; } $graph->xaxis->scale->ticks->SetXLabelOffset($a); $graph->SetTextScaleOff($b); //$graph->xaxis->scale->ticks->SupressMinorTickMarks(); } } function SetFastStroke($aFlg=true) { $this->iFastStroke = $aFlg; } function FastStroke($img,$xscale,$yscale,$aStartPoint=0,$exist_x=true) { // An optimized stroke for many data points with no extra // features but 60% faster. You can't have values or line styles, or null // values in plots. $numpoints=count($this->coords[0]); if( $this->barcenter ) { $textadj = 0.5-$xscale->text_scale_off; } else { $textadj = 0; } $img->SetColor($this->color); $img->SetLineWeight($this->weight); $pnts=$aStartPoint; while( $pnts < $numpoints ) { if( $exist_x ) { $x=$this->coords[1][$pnts]; } else { $x=$pnts+$textadj; } $xt = $xscale->Translate($x); $y=$this->coords[0][$pnts]; $yt = $yscale->Translate($y); if( is_numeric($y) ) { $cord[] = $xt; $cord[] = $yt; } elseif( $y == '-' && $pnts > 0 ) { // Just ignore } else { JpGraphError::RaiseL(10002);//('Plot too complicated for fast line Stroke. Use standard Stroke()'); } ++$pnts; } // WHILE $img->Polygon($cord,false,true); } function Stroke($img,$xscale,$yscale) { $idx=0; $numpoints=count($this->coords[0]); if( isset($this->coords[1]) ) { if( count($this->coords[1])!=$numpoints ) { JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); //("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); } else { $exist_x = true; } } else { $exist_x = false; } if( $this->barcenter ) { $textadj = 0.5-$xscale->text_scale_off; } else { $textadj = 0; } // Find the first numeric data point $startpoint=0; while( $startpoint < $numpoints && !is_numeric($this->coords[0][$startpoint]) ) { ++$startpoint; } // Bail out if no data points if( $startpoint == $numpoints ) return; if( $this->iFastStroke ) { $this->FastStroke($img,$xscale,$yscale,$startpoint,$exist_x); return; } if( $exist_x ) { $xs=$this->coords[1][$startpoint]; } else { $xs= $textadj+$startpoint; } $img->SetStartPoint($xscale->Translate($xs), $yscale->Translate($this->coords[0][$startpoint])); if( $this->filled ) { if( $this->fillFromMax ) { //$max = $yscale->GetMaxVal(); $cord[$idx++] = $xscale->Translate($xs); $cord[$idx++] = $yscale->scale_abs[1]; } else { $min = $yscale->GetMinVal(); if( $min > 0 || $this->fillFromMin ) { $fillmin = $yscale->scale_abs[0];//Translate($min); } else { $fillmin = $yscale->Translate(0); } $cord[$idx++] = $xscale->Translate($xs); $cord[$idx++] = $fillmin; } } $xt = $xscale->Translate($xs); $yt = $yscale->Translate($this->coords[0][$startpoint]); $cord[$idx++] = $xt; $cord[$idx++] = $yt; $yt_old = $yt; $xt_old = $xt; $y_old = $this->coords[0][$startpoint]; $this->value->Stroke($img,$this->coords[0][$startpoint],$xt,$yt); $img->SetColor($this->color); $img->SetLineWeight($this->weight); $img->SetLineStyle($this->line_style); $pnts=$startpoint+1; $firstnonumeric = false; while( $pnts < $numpoints ) { if( $exist_x ) { $x=$this->coords[1][$pnts]; } else { $x=$pnts+$textadj; } $xt = $xscale->Translate($x); $yt = $yscale->Translate($this->coords[0][$pnts]); $y=$this->coords[0][$pnts]; if( $this->step_style ) { // To handle null values within step style we need to record the // first non numeric value so we know from where to start if the // non value is '-'. if( is_numeric($y) ) { $firstnonumeric = false; if( is_numeric($y_old) ) { $img->StyleLine($xt_old,$yt_old,$xt,$yt_old); $img->StyleLine($xt,$yt_old,$xt,$yt); } elseif( $y_old == '-' ) { $img->StyleLine($xt_first,$yt_first,$xt,$yt_first); $img->StyleLine($xt,$yt_first,$xt,$yt); } else { $yt_old = $yt; $xt_old = $xt; } $cord[$idx++] = $xt; $cord[$idx++] = $yt_old; $cord[$idx++] = $xt; $cord[$idx++] = $yt; } elseif( $firstnonumeric==false ) { $firstnonumeric = true; $yt_first = $yt_old; $xt_first = $xt_old; } } else { $tmp1=$y; $prev=$this->coords[0][$pnts-1]; if( $tmp1==='' || $tmp1===NULL || $tmp1==='X' ) $tmp1 = 'x'; if( $prev==='' || $prev===null || $prev==='X' ) $prev = 'x'; if( is_numeric($y) || (is_string($y) && $y != '-') ) { if( is_numeric($y) && (is_numeric($prev) || $prev === '-' ) ) { $img->StyleLineTo($xt,$yt); } else { $img->SetStartPoint($xt,$yt); } } if( $this->filled && $tmp1 !== '-' ) { if( $tmp1 === 'x' ) { $cord[$idx++] = $cord[$idx-3]; $cord[$idx++] = $fillmin; } elseif( $prev === 'x' ) { $cord[$idx++] = $xt; $cord[$idx++] = $fillmin; $cord[$idx++] = $xt; $cord[$idx++] = $yt; } else { $cord[$idx++] = $xt; $cord[$idx++] = $yt; } } else { if( is_numeric($tmp1) && (is_numeric($prev) || $prev === '-' ) ) { $cord[$idx++] = $xt; $cord[$idx++] = $yt; } } } $yt_old = $yt; $xt_old = $xt; $y_old = $y; $this->StrokeDataValue($img,$this->coords[0][$pnts],$xt,$yt); ++$pnts; } if( $this->filled ) { $cord[$idx++] = $xt; if( $this->fillFromMax ) { $cord[$idx++] = $yscale->scale_abs[1]; } else { if( $min > 0 || $this->fillFromMin ) { $cord[$idx++] = $yscale->Translate($min); } else { $cord[$idx++] = $yscale->Translate(0); } } if( $this->fillgrad ) { $img->SetLineWeight(1); $grad = new Gradient($img); $grad->SetNumColors($this->fillgrad_numcolors); $grad->FilledFlatPolygon($cord,$this->fillgrad_fromcolor,$this->fillgrad_tocolor); $img->SetLineWeight($this->weight); } else { $img->SetColor($this->fill_color); $img->FilledPolygon($cord); } if( $this->weight > 0 ) { $img->SetLineWeight($this->weight); $img->SetColor($this->color); // Remove first and last coordinate before drawing the line // sine we otherwise get the vertical start and end lines which // doesn't look appropriate $img->Polygon(array_slice($cord,2,count($cord)-4)); } } if(!empty($this->filledAreas)) { $minY = $yscale->Translate($yscale->GetMinVal()); $factor = ($this->step_style ? 4 : 2); for($i = 0; $i < sizeof($this->filledAreas); ++$i) { // go through all filled area elements ordered by insertion // fill polygon array $areaCoords[] = $cord[$this->filledAreas[$i][0] * $factor]; $areaCoords[] = $minY; $areaCoords = array_merge($areaCoords, array_slice($cord, $this->filledAreas[$i][0] * $factor, ($this->filledAreas[$i][1] - $this->filledAreas[$i][0] + ($this->step_style ? 0 : 1)) * $factor)); $areaCoords[] = $areaCoords[sizeof($areaCoords)-2]; // last x $areaCoords[] = $minY; // last y if($this->filledAreas[$i][3]) { $img->SetColor($this->filledAreas[$i][2]); $img->FilledPolygon($areaCoords); $img->SetColor($this->color); } // Check if we should draw the frame. // If not we still re-draw the line since it might have been // partially overwritten by the filled area and it doesn't look // very good. if( $this->filledAreas[$i][4] ) { $img->Polygon($areaCoords); } else { $img->Polygon($cord); } $areaCoords = array(); } } if( $this->mark->type == -1 || $this->mark->show == false ) return; for( $pnts=0; $pnts<$numpoints; ++$pnts) { if( $exist_x ) { $x=$this->coords[1][$pnts]; } else { $x=$pnts+$textadj; } $xt = $xscale->Translate($x); $yt = $yscale->Translate($this->coords[0][$pnts]); if( is_numeric($this->coords[0][$pnts]) ) { if( !empty($this->csimtargets[$pnts]) ) { if( !empty($this->csimwintargets[$pnts]) ) { $this->mark->SetCSIMTarget($this->csimtargets[$pnts],$this->csimwintargets[$pnts]); } else { $this->mark->SetCSIMTarget($this->csimtargets[$pnts]); } $this->mark->SetCSIMAlt($this->csimalts[$pnts]); } if( $exist_x ) { $x=$this->coords[1][$pnts]; } else { $x=$pnts; } $this->mark->SetCSIMAltVal($this->coords[0][$pnts],$x); $this->mark->Stroke($img,$xt,$yt); $this->csimareas .= $this->mark->GetCSIMAreas(); } } } } // Class //=================================================== // CLASS AccLinePlot // Description: //=================================================== class AccLinePlot extends Plot { protected $plots=null,$nbrplots=0; private $iStartEndZero=true; //--------------- // CONSTRUCTOR function __construct($plots) { $this->plots = $plots; $this->nbrplots = count($plots); $this->numpoints = $plots[0]->numpoints; // Verify that all plots have the same number of data points for( $i=1; $i < $this->nbrplots; ++$i ) { if( $plots[$i]->numpoints != $this->numpoints ) { JpGraphError::RaiseL(10003);//('Each plot in an accumulated lineplot must have the same number of data points',0) } } for($i=0; $i < $this->nbrplots; ++$i ) { $this->LineInterpolate($this->plots[$i]->coords[0]); } } //--------------- // PUBLIC METHODS function Legend($graph) { foreach( $this->plots as $p ) { $p->DoLegend($graph); } } function Max() { list($xmax) = $this->plots[0]->Max(); $nmax=0; $n = count($this->plots); for($i=0; $i < $n; ++$i) { $nc = count($this->plots[$i]->coords[0]); $nmax = max($nmax,$nc); list($x) = $this->plots[$i]->Max(); $xmax = Max($xmax,$x); } for( $i = 0; $i < $nmax; $i++ ) { // Get y-value for line $i by adding the // individual bars from all the plots added. // It would be wrong to just add the // individual plots max y-value since that // would in most cases give to large y-value. $y=$this->plots[0]->coords[0][$i]; for( $j = 1; $j < $this->nbrplots; $j++ ) { $y += $this->plots[ $j ]->coords[0][$i]; } $ymax[$i] = $y; } $ymax = max($ymax); return array($xmax,$ymax); } function Min() { $nmax=0; list($xmin,$ysetmin) = $this->plots[0]->Min(); $n = count($this->plots); for($i=0; $i < $n; ++$i) { $nc = count($this->plots[$i]->coords[0]); $nmax = max($nmax,$nc); list($x,$y) = $this->plots[$i]->Min(); $xmin = Min($xmin,$x); $ysetmin = Min($y,$ysetmin); } for( $i = 0; $i < $nmax; $i++ ) { // Get y-value for line $i by adding the // individual bars from all the plots added. // It would be wrong to just add the // individual plots min y-value since that // would in most cases give to small y-value. $y=$this->plots[0]->coords[0][$i]; for( $j = 1; $j < $this->nbrplots; $j++ ) { $y += $this->plots[ $j ]->coords[0][$i]; } $ymin[$i] = $y; } $ymin = Min($ysetmin,Min($ymin)); return array($xmin,$ymin); } // Gets called before any axis are stroked function PreStrokeAdjust($graph) { // If another plot type have already adjusted the // offset we don't touch it. // (We check for empty in case the scale is a log scale // and hence doesn't contain any xlabel_offset) if( empty($graph->xaxis->scale->ticks->xlabel_offset) || $graph->xaxis->scale->ticks->xlabel_offset == 0 ) { if( $this->center ) { ++$this->numpoints; $a=0.5; $b=0.5; } else { $a=0; $b=0; } $graph->xaxis->scale->ticks->SetXLabelOffset($a); $graph->SetTextScaleOff($b); $graph->xaxis->scale->ticks->SupressMinorTickMarks(); } } function SetInterpolateMode($aIntMode) { $this->iStartEndZero=$aIntMode; } // Replace all '-' with an interpolated value. We use straightforward // linear interpolation. If the data starts with one or several '-' they // will be replaced by the the first valid data point function LineInterpolate(&$aData) { $n=count($aData); $i=0; // If first point is undefined we will set it to the same as the first // valid data if( $aData[$i]==='-' ) { // Find the first valid data while( $i < $n && $aData[$i]==='-' ) { ++$i; } if( $i < $n ) { for($j=0; $j < $i; ++$j ) { if( $this->iStartEndZero ) $aData[$i] = 0; else $aData[$j] = $aData[$i]; } } else { // All '-' => Error return false; } } while($i < $n) { while( $i < $n && $aData[$i] !== '-' ) { ++$i; } if( $i < $n ) { $pstart=$i-1; // Now see how long this segment of '-' are while( $i < $n && $aData[$i] === '-' ) { ++$i; } if( $i < $n ) { $pend=$i; $size=$pend-$pstart; $k=($aData[$pend]-$aData[$pstart])/$size; // Replace the segment of '-' with a linear interpolated value. for($j=1; $j < $size; ++$j ) { $aData[$pstart+$j] = $aData[$pstart] + $j*$k ; } } else { // There are no valid end point. The '-' goes all the way to the end // In that case we just set all the remaining values the the same as the // last valid data point. for( $j=$pstart+1; $j < $n; ++$j ) if( $this->iStartEndZero ) { $aData[$j] = 0; } else { $aData[$j] = $aData[$pstart] ; } } } } return true; } // To avoid duplicate of line drawing code here we just // change the y-values for each plot and then restore it // after we have made the stroke. We must do this copy since // it wouldn't be possible to create an acc line plot // with the same graphs, i.e AccLinePlot(array($pl,$pl,$pl)); // since this method would have a side effect. function Stroke($img,$xscale,$yscale) { $img->SetLineWeight($this->weight); $this->numpoints = count($this->plots[0]->coords[0]); // Allocate array $coords[$this->nbrplots][$this->numpoints]=0; for($i=0; $i<$this->numpoints; $i++) { $coords[0][$i]=$this->plots[0]->coords[0][$i]; $accy=$coords[0][$i]; for($j=1; $j<$this->nbrplots; ++$j ) { $coords[$j][$i] = $this->plots[$j]->coords[0][$i]+$accy; $accy = $coords[$j][$i]; } } for($j=$this->nbrplots-1; $j>=0; --$j) { $p=$this->plots[$j]; for( $i=0; $i<$this->numpoints; ++$i) { $tmp[$i]=$p->coords[0][$i]; $p->coords[0][$i]=$coords[$j][$i]; } $p->Stroke($img,$xscale,$yscale); for( $i=0; $i<$this->numpoints; ++$i) { $p->coords[0][$i]=$tmp[$i]; } $p->coords[0][]=$tmp; } } } // Class /* EOF */ ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_legend.inc.php0000644000175000017500000004253312225176641023454 0ustar danieldanielhide=$aHide; } function SetHColMargin($aXMarg) { $this->xmargin = $aXMarg; } function SetVColMargin($aSpacing) { $this->ylinespacing = $aSpacing ; } function SetLeftMargin($aXMarg) { $this->xlmargin = $aXMarg; } // Synonym function SetLineSpacing($aSpacing) { $this->ylinespacing = $aSpacing ; } function SetShadow($aShow='gray',$aWidth=4) { if( is_string($aShow) ) { $this->shadow_color = $aShow; $this->shadow=true; } else { $this->shadow = $aShow; } $this->shadow_width = $aWidth; } function SetMarkAbsSize($aSize) { $this->mark_abs_vsize = $aSize ; $this->mark_abs_hsize = $aSize ; } function SetMarkAbsVSize($aSize) { $this->mark_abs_vsize = $aSize ; } function SetMarkAbsHSize($aSize) { $this->mark_abs_hsize = $aSize ; } function SetLineWeight($aWeight) { $this->weight = $aWeight; } function SetFrameWeight($aWeight) { $this->frameweight = $aWeight; } function SetLayout($aDirection=LEGEND_VERT) { $this->layout_n = $aDirection==LEGEND_VERT ? 1 : 99 ; } function SetColumns($aCols) { $this->layout_n = $aCols ; } function SetReverse($f=true) { $this->reverse = $f ; } // Set color on frame around box function SetColor($aFontColor,$aColor='black') { $this->font_color=$aFontColor; $this->color=$aColor; } function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { $this->font_family = $aFamily; $this->font_style = $aStyle; $this->font_size = $aSize; } function SetPos($aX,$aY,$aHAlign='right',$aVAlign='top') { $this->Pos($aX,$aY,$aHAlign,$aVAlign); } function SetAbsPos($aX,$aY,$aHAlign='right',$aVAlign='top') { $this->xabspos=$aX; $this->yabspos=$aY; $this->halign=$aHAlign; $this->valign=$aVAlign; } function Pos($aX,$aY,$aHAlign='right',$aVAlign='top') { if( !($aX<1 && $aY<1) ) { JpGraphError::RaiseL(25120);//(" Position for legend must be given as percentage in range 0-1"); } $this->xpos=$aX; $this->ypos=$aY; $this->halign=$aHAlign; $this->valign=$aVAlign; } function SetFillColor($aColor) { $this->fill_color=$aColor; } function Clear() { $this->txtcol = array(); } function Add($aTxt,$aColor,$aPlotmark='',$aLinestyle=0,$csimtarget='',$csimalt='',$csimwintarget='') { $this->txtcol[]=array($aTxt,$aColor,$aPlotmark,$aLinestyle,$csimtarget,$csimalt,$csimwintarget); } function GetCSIMAreas() { return $this->csimareas; } function SetBackgroundGradient($aFrom='navy',$aTo='silver',$aGradType=2) { $this->bkg_gradtype=$aGradType; $this->bkg_gradfrom = $aFrom; $this->bkg_gradto = $aTo; } function Stroke($aImg) { // Constant $fillBoxFrameWeight=1; if( $this->hide ) return; $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); if( $this->reverse ) { $this->txtcol = array_reverse($this->txtcol); } $n=count($this->txtcol); if( $n == 0 ) return; // Find out the max width and height of each column to be able // to size the legend box. $numcolumns = ($n > $this->layout_n ? $this->layout_n : $n); for( $i=0; $i < $numcolumns; ++$i ) { $colwidth[$i] = $aImg->GetTextWidth($this->txtcol[$i][0]) + 2*$this->xmargin + 2*$this->mark_abs_hsize; $colheight[$i] = 0; } // Find our maximum height in each row $rows = 0 ; $rowheight[0] = 0; for( $i=0; $i < $n; ++$i ) { $h = max($this->mark_abs_vsize,$aImg->GetTextHeight($this->txtcol[$i][0]))+$this->ylinespacing; // Makes sure we always have a minimum of 1/4 (1/2 on each side) of the mark as space // between two vertical legend entries //$h = round(max($h,$this->mark_abs_vsize+$this->ymargin)); //echo "Textheight #$i: tetxheight=".$aImg->GetTextHeight($this->txtcol[$i][0]).', '; //echo "h=$h ({$this->mark_abs_vsize},{$this->ymargin})
    "; if( $i % $numcolumns == 0 ) { $rows++; $rowheight[$rows-1] = 0; } $rowheight[$rows-1] = max($rowheight[$rows-1],$h); } $abs_height = 0; for( $i=0; $i < $rows; ++$i ) { $abs_height += $rowheight[$i] ; } // Make sure that the height is at least as high as mark size + ymargin $abs_height = max($abs_height,$this->mark_abs_vsize); $abs_height += $this->ybottom_margin; // Find out the maximum width in each column for( $i=$numcolumns; $i < $n; ++$i ) { $colwidth[$i % $numcolumns] = max( $aImg->GetTextWidth($this->txtcol[$i][0])+2*$this->xmargin+2*$this->mark_abs_hsize, $colwidth[$i % $numcolumns]); } // Get the total width $mtw = 0; for( $i=0; $i < $numcolumns; ++$i ) { $mtw += $colwidth[$i] ; } // remove the last rows interpace margin (since there is no next row) $abs_height -= $this->ylinespacing; // Find out maximum width we need for legend box $abs_width = $mtw+$this->xlmargin+($numcolumns-1)*$this->mark_abs_hsize; if( $this->xabspos === -1 && $this->yabspos === -1 ) { $this->xabspos = $this->xpos*$aImg->width ; $this->yabspos = $this->ypos*$aImg->height ; } // Positioning of the legend box if( $this->halign == 'left' ) { $xp = $this->xabspos; } elseif( $this->halign == 'center' ) { $xp = $this->xabspos - $abs_width/2; } else { $xp = $aImg->width - $this->xabspos - $abs_width; } $yp=$this->yabspos; if( $this->valign == 'center' ) { $yp-=$abs_height/2; } elseif( $this->valign == 'bottom' ) { $yp-=$abs_height; } // Stroke legend box $aImg->SetColor($this->color); $aImg->SetLineWeight($this->frameweight); $aImg->SetLineStyle('solid'); if( $this->shadow ) { $aImg->ShadowRectangle($xp,$yp, $xp+$abs_width+$this->shadow_width+2, $yp+$abs_height+$this->shadow_width+2, $this->fill_color,$this->shadow_width+2,$this->shadow_color); } else { $aImg->SetColor($this->fill_color); $aImg->FilledRectangle($xp,$yp,$xp+$abs_width,$yp+$abs_height); $aImg->SetColor($this->color); $aImg->Rectangle($xp,$yp,$xp+$abs_width,$yp+$abs_height); } if( $this->bkg_gradtype >= 0 ) { $grad = new Gradient($aImg); $grad->FilledRectangle($xp+1, $yp+1, $xp+$abs_width-3, $yp+$abs_height-3, $this->bkg_gradfrom, $this->bkg_gradto, $this->bkg_gradtype); } // x1,y1 is the position for the legend marker + text // The vertical position is the baseline position for the text // and every marker is adjusted acording to that. // For multiline texts this get more complicated. $x1 = $xp + $this->xlmargin; $y1 = $yp + $rowheight[0] - $this->ylinespacing + 2 ; // The ymargin is included in rowheight // Now, y1 is the bottom vertical position of the first legend, i.e if // the legend has multiple lines it is the bottom line. $grad = new Gradient($aImg); $patternFactory = null; // Now stroke each legend in turn // Each plot has added the following information to the legend // p[0] = Legend text // p[1] = Color, // p[2] = For markers a reference to the PlotMark object // p[3] = For lines the line style, for gradient the negative gradient style // p[4] = CSIM target // p[5] = CSIM Alt text $i = 1 ; $row = 0; foreach($this->txtcol as $p) { // STROKE DEBUG BOX if( _JPG_DEBUG ) { $aImg->SetLineWeight(1); $aImg->SetColor('red'); $aImg->SetLineStyle('solid'); $aImg->Rectangle($x1,$y1,$xp+$abs_width-1,$y1-$rowheight[$row]); } $aImg->SetLineWeight($this->weight); $x1 = round($x1)+1; // We add one to not collide with the border $y1=round($y1); // This is the center offset up from the baseline which is // considered the "center" of the marks. This gets slightly complicated since // we need to consider if the text is a multiline paragraph or if it is only // a single line. The reason is that for single line the y1 corresponds to the baseline // and that is fine. However for a multiline paragraph there is no single baseline // and in that case the y1 corresponds to the lowest y for the bounding box. In that // case we center the mark in the middle of the paragraph if( !preg_match('/\n/',$p[0]) ) { // Single line $marky = ceil($y1-$this->mark_abs_vsize/2)-1; } else { // Paragraph $marky = $y1 - $aImg->GetTextHeight($p[0])/2; // echo "y1=$y1, p[o]={$p[0]}, marky=$marky
    "; } //echo "
    Mark #$i: marky=$marky
    "; $x1 += $this->mark_abs_hsize; if ( !empty($p[2]) && $p[2]->GetType() > -1 ) { // Make a plot mark legend. This is constructed with a mark which // is run through with a line // First construct a bit of the line that looks exactly like the // line in the plot $aImg->SetColor($p[1]); if( is_string($p[3]) || $p[3]>0 ) { $aImg->SetLineStyle($p[3]); $aImg->StyleLine($x1-$this->mark_abs_hsize,$marky,$x1+$this->mark_abs_hsize,$marky); } // Stroke a mark with the standard size // (As long as it is not an image mark ) if( $p[2]->GetType() != MARK_IMG ) { // Clear any user callbacks since we ont want them called for // the legend marks $p[2]->iFormatCallback = ''; $p[2]->iFormatCallback2 = ''; // Since size for circles is specified as the radius // this means that we must half the size to make the total // width behave as the other marks if( $p[2]->GetType() == MARK_FILLEDCIRCLE || $p[2]->GetType() == MARK_CIRCLE ) { $p[2]->SetSize(min($this->mark_abs_vsize,$this->mark_abs_hsize)/2); $p[2]->Stroke($aImg,$x1,$marky); } else { $p[2]->SetSize(min($this->mark_abs_vsize,$this->mark_abs_hsize)); $p[2]->Stroke($aImg,$x1,$marky); } } } elseif ( !empty($p[2]) && (is_string($p[3]) || $p[3]>0 ) ) { // Draw a styled line $aImg->SetColor($p[1]); $aImg->SetLineStyle($p[3]); $aImg->StyleLine($x1-$this->mark_abs_hsize,$marky,$x1+$this->mark_abs_hsize,$marky); $aImg->StyleLine($x1-$this->mark_abs_hsize,$marky+1,$x1+$this->mark_abs_hsize,$marky+1); } else { // Draw a colored box $color = $p[1] ; // We make boxes slightly larger to better show $boxsize = max($this->mark_abs_vsize,$this->mark_abs_hsize) + 2 ; $ym = $marky-ceil($boxsize/2) ; // Marker y-coordinate // We either need to plot a gradient or a // pattern. To differentiate we use a kludge. // Patterns have a p[3] value of < -100 if( $p[3] < -100 ) { // p[1][0] == iPattern, p[1][1] == iPatternColor, p[1][2] == iPatternDensity if( $patternFactory == null ) { $patternFactory = new RectPatternFactory(); } $prect = $patternFactory->Create($p[1][0],$p[1][1],1); $prect->SetBackground($p[1][3]); $prect->SetDensity($p[1][2]+1); $prect->SetPos(new Rectangle($x1,$ym,$boxsize,$boxsize)); $prect->Stroke($aImg); $prect=null; } else { if( is_array($color) && count($color)==2 ) { // The client want a gradient color $grad->FilledRectangle($x1-$boxsize/2,$ym, $x1+$boxsize/2,$ym+$boxsize, $color[0],$color[1],-$p[3]); } else { $aImg->SetColor($p[1]); $aImg->FilledRectangle($x1-$boxsize/2,$ym, $x1+$boxsize/2,$ym+$boxsize); } $aImg->SetColor($this->color); $aImg->SetLineWeight($fillBoxFrameWeight); $aImg->Rectangle($x1-$boxsize/2,$ym, $x1+$boxsize/2,$ym+$boxsize); } } $aImg->SetColor($this->font_color); $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $aImg->SetTextAlign('left','baseline'); $debug=false; $aImg->StrokeText($x1+$this->mark_abs_hsize+$this->xmargin,$y1,$p[0], 0,'left',$debug); // Add CSIM for Legend if defined if( !empty($p[4]) ) { $xs = $x1 - $this->mark_abs_hsize ; $ys = $y1 + 1 ; $xe = $x1 + $aImg->GetTextWidth($p[0]) + $this->mark_abs_hsize + $this->xmargin ; $ye = $y1-$rowheight[$row]+1; $coords = "$xs,$ys,$xe,$y1,$xe,$ye,$xs,$ye"; if( ! empty($p[4]) ) { $this->csimareas .= "csimareas .= " target=\"".$p[6]."\""; } if( !empty($p[5]) ) { $tmp=sprintf($p[5],$p[0]); $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; } $this->csimareas .= " />\n"; } } if( $i >= $this->layout_n ) { $x1 = $xp+$this->xlmargin; $row++; if( !empty($rowheight[$row]) ) $y1 += $rowheight[$row]; $i = 1; } else { $x1 += $colwidth[($i-1) % $numcolumns] ; ++$i; } } } } // Class ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_plotmark.inc.php0000644000175000017500000004225612225176641024051 0ustar danieldanieltitle = new Text(); $this->title->Hide(); $this->csimareas = ''; $this->type=-1; } //--------------- // PUBLIC METHODS function SetType($aType,$aFileName='',$aScale=1.0) { $this->type = $aType; if( $aType == MARK_IMG && $aFileName=='' ) { JpGraphError::RaiseL(23003);//('A filename must be specified if you set the mark type to MARK_IMG.'); } $this->iFileName = $aFileName; $this->iScale = $aScale; } function SetCallback($aFunc) { $this->iFormatCallback = $aFunc; } function SetCallbackYX($aFunc) { $this->iFormatCallback2 = $aFunc; } function GetType() { return $this->type; } function SetColor($aColor) { $this->color=$aColor; } function SetFillColor($aFillColor) { $this->fill_color = $aFillColor; } function SetWeight($aWeight) { $this->weight = $aWeight; } // Synonym for SetWidth() function SetSize($aWidth) { $this->width=$aWidth; } function SetWidth($aWidth) { $this->width=$aWidth; } function SetDefaultWidth() { switch( $this->type ) { case MARK_CIRCLE: case MARK_FILLEDCIRCLE: $this->width=4; break; default: $this->width=7; } } function GetWidth() { return $this->width; } function Hide($aHide=true) { $this->show = !$aHide; } function Show($aShow=true) { $this->show = $aShow; } function SetCSIMAltVal($aY,$aX='') { $this->yvalue=$aY; $this->xvalue=$aX; } function SetCSIMTarget($aTarget,$aWinTarget='') { $this->csimtarget=$aTarget; $this->csimwintarget=$aWinTarget; } function SetCSIMAlt($aAlt) { $this->csimalt=$aAlt; } function GetCSIMAreas(){ return $this->csimareas; } function AddCSIMPoly($aPts) { $coords = round($aPts[0]).", ".round($aPts[1]); $n = count($aPts)/2; for( $i=1; $i < $n; ++$i){ $coords .= ", ".round($aPts[2*$i]).", ".round($aPts[2*$i+1]); } $this->csimareas=""; if( !empty($this->csimtarget) ) { $this->csimareas .= "csimtarget)."\""; if( !empty($this->csimwintarget) ) { $this->csimareas .= " target=\"".$this->csimwintarget."\" "; } if( !empty($this->csimalt) ) { $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue); $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\""; } $this->csimareas .= " />\n"; } } function AddCSIMCircle($x,$y,$r) { $x = round($x); $y=round($y); $r=round($r); $this->csimareas=""; if( !empty($this->csimtarget) ) { $this->csimareas .= "csimtarget)."\""; if( !empty($this->csimwintarget) ) { $this->csimareas .= " target=\"".$this->csimwintarget."\" "; } if( !empty($this->csimalt) ) { $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue); $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; } $this->csimareas .= " />\n"; } } function Stroke($img,$x,$y) { if( !$this->show ) return; if( $this->iFormatCallback != '' || $this->iFormatCallback2 != '' ) { if( $this->iFormatCallback != '' ) { $f = $this->iFormatCallback; list($width,$color,$fcolor) = call_user_func($f,$this->yvalue); $filename = $this->iFileName; $imgscale = $this->iScale; } else { $f = $this->iFormatCallback2; list($width,$color,$fcolor,$filename,$imgscale) = call_user_func($f,$this->yvalue,$this->xvalue); if( $filename=="" ) $filename = $this->iFileName; if( $imgscale=="" ) $imgscale = $this->iScale; } if( $width=="" ) $width = $this->width; if( $color=="" ) $color = $this->color; if( $fcolor=="" ) $fcolor = $this->fill_color; } else { $fcolor = $this->fill_color; $color = $this->color; $width = $this->width; $filename = $this->iFileName; $imgscale = $this->iScale; } if( $this->type == MARK_IMG || ($this->type >= MARK_FLAG1 && $this->type <= MARK_FLAG4 ) || $this->type >= MARK_IMG_PUSHPIN ) { // Note: For the builtin images we use the "filename" parameter // to denote the color $anchor_x = 0.5; $anchor_y = 0.5; switch( $this->type ) { case MARK_FLAG1: case MARK_FLAG2: case MARK_FLAG3: case MARK_FLAG4: $this->markimg = FlagCache::GetFlagImgByName($this->type-MARK_FLAG1+1,$filename); break; case MARK_IMG : // Load an image and use that as a marker // Small optimization, if we have already read an image don't // waste time reading it again. if( $this->markimg == '' || !($this->oldfilename === $filename) ) { $this->markimg = Graph::LoadBkgImage('',$filename); $this->oldfilename = $filename ; } break; case MARK_IMG_PUSHPIN: case MARK_IMG_SPUSHPIN: case MARK_IMG_LPUSHPIN: if( $this->imgdata_pushpins == null ) { require_once 'imgdata_pushpins.inc.php'; $this->imgdata_pushpins = new ImgData_PushPins(); } $this->markimg = $this->imgdata_pushpins->GetImg($this->type,$filename); list($anchor_x,$anchor_y) = $this->imgdata_pushpins->GetAnchor(); break; case MARK_IMG_SQUARE: if( $this->imgdata_squares == null ) { require_once 'imgdata_squares.inc.php'; $this->imgdata_squares = new ImgData_Squares(); } $this->markimg = $this->imgdata_squares->GetImg($this->type,$filename); list($anchor_x,$anchor_y) = $this->imgdata_squares->GetAnchor(); break; case MARK_IMG_STAR: if( $this->imgdata_stars == null ) { require_once 'imgdata_stars.inc.php'; $this->imgdata_stars = new ImgData_Stars(); } $this->markimg = $this->imgdata_stars->GetImg($this->type,$filename); list($anchor_x,$anchor_y) = $this->imgdata_stars->GetAnchor(); break; case MARK_IMG_BEVEL: if( $this->imgdata_bevels == null ) { require_once 'imgdata_bevels.inc.php'; $this->imgdata_bevels = new ImgData_Bevels(); } $this->markimg = $this->imgdata_bevels->GetImg($this->type,$filename); list($anchor_x,$anchor_y) = $this->imgdata_bevels->GetAnchor(); break; case MARK_IMG_DIAMOND: if( $this->imgdata_diamonds == null ) { require_once 'imgdata_diamonds.inc.php'; $this->imgdata_diamonds = new ImgData_Diamonds(); } $this->markimg = $this->imgdata_diamonds->GetImg($this->type,$filename); list($anchor_x,$anchor_y) = $this->imgdata_diamonds->GetAnchor(); break; case MARK_IMG_BALL: case MARK_IMG_SBALL: case MARK_IMG_MBALL: case MARK_IMG_LBALL: if( $this->imgdata_balls == null ) { require_once 'imgdata_balls.inc.php'; $this->imgdata_balls = new ImgData_Balls(); } $this->markimg = $this->imgdata_balls->GetImg($this->type,$filename); list($anchor_x,$anchor_y) = $this->imgdata_balls->GetAnchor(); break; } $w = $img->GetWidth($this->markimg); $h = $img->GetHeight($this->markimg); $dw = round($imgscale * $w ); $dh = round($imgscale * $h ); // Do potential rotation list($x,$y) = $img->Rotate($x,$y); $dx = round($x-$dw*$anchor_x); $dy = round($y-$dh*$anchor_y); $this->width = max($dx,$dy); $img->Copy($this->markimg,$dx,$dy,0,0,$dw,$dh,$w,$h); if( !empty($this->csimtarget) ) { $this->csimareas = "csimtarget)."\""; if( !empty($this->csimwintarget) ) { $this->csimareas .= " target=\"".$this->csimwintarget."\" "; } if( !empty($this->csimalt) ) { $tmp=sprintf($this->csimalt,$this->yvalue,$this->xvalue); $this->csimareas .= " title=\"$tmp\" alt=\"$tmp\" "; } $this->csimareas .= " />\n"; } // Stroke title $this->title->Align("center","top"); $this->title->Stroke($img,$x,$y+round($dh/2)); return; } $weight = $this->weight; $dx=round($width/2,0); $dy=round($width/2,0); $pts=0; switch( $this->type ) { case MARK_SQUARE: $c[]=$x-$dx;$c[]=$y-$dy; $c[]=$x+$dx;$c[]=$y-$dy; $c[]=$x+$dx;$c[]=$y+$dy; $c[]=$x-$dx;$c[]=$y+$dy; $c[]=$x-$dx;$c[]=$y-$dy; $pts=5; break; case MARK_UTRIANGLE: ++$dx;++$dy; $c[]=$x-$dx;$c[]=$y+0.87*$dy; // tan(60)/2*$dx $c[]=$x;$c[]=$y-0.87*$dy; $c[]=$x+$dx;$c[]=$y+0.87*$dy; $c[]=$x-$dx;$c[]=$y+0.87*$dy; // tan(60)/2*$dx $pts=4; break; case MARK_DTRIANGLE: ++$dx;++$dy; $c[]=$x;$c[]=$y+0.87*$dy; // tan(60)/2*$dx $c[]=$x-$dx;$c[]=$y-0.87*$dy; $c[]=$x+$dx;$c[]=$y-0.87*$dy; $c[]=$x;$c[]=$y+0.87*$dy; // tan(60)/2*$dx $pts=4; break; case MARK_DIAMOND: $c[]=$x;$c[]=$y+$dy; $c[]=$x-$dx;$c[]=$y; $c[]=$x;$c[]=$y-$dy; $c[]=$x+$dx;$c[]=$y; $c[]=$x;$c[]=$y+$dy; $pts=5; break; case MARK_LEFTTRIANGLE: $c[]=$x;$c[]=$y; $c[]=$x;$c[]=$y+2*$dy; $c[]=$x+$dx*2;$c[]=$y; $c[]=$x;$c[]=$y; $pts=4; break; case MARK_RIGHTTRIANGLE: $c[]=$x-$dx*2;$c[]=$y; $c[]=$x;$c[]=$y+2*$dy; $c[]=$x;$c[]=$y; $c[]=$x-$dx*2;$c[]=$y; $pts=4; break; case MARK_FLASH: $dy *= 2; $c[]=$x+$dx/2; $c[]=$y-$dy; $c[]=$x-$dx+$dx/2; $c[]=$y+$dy*0.7-$dy; $c[]=$x+$dx/2; $c[]=$y+$dy*1.3-$dy; $c[]=$x-$dx+$dx/2; $c[]=$y+2*$dy-$dy; $img->SetLineWeight($weight); $img->SetColor($color); $img->Polygon($c); $img->SetLineWeight(1); $this->AddCSIMPoly($c); break; } if( $pts>0 ) { $this->AddCSIMPoly($c); $img->SetLineWeight($weight); $img->SetColor($fcolor); $img->FilledPolygon($c); $img->SetColor($color); $img->Polygon($c); $img->SetLineWeight(1); } elseif( $this->type==MARK_CIRCLE ) { $img->SetColor($color); $img->Circle($x,$y,$width); $this->AddCSIMCircle($x,$y,$width); } elseif( $this->type==MARK_FILLEDCIRCLE ) { $img->SetColor($fcolor); $img->FilledCircle($x,$y,$width); $img->SetColor($color); $img->Circle($x,$y,$width); $this->AddCSIMCircle($x,$y,$width); } elseif( $this->type==MARK_CROSS ) { // Oversize by a pixel to match the X $img->SetColor($color); $img->SetLineWeight($weight); $img->Line($x,$y+$dy+1,$x,$y-$dy-1); $img->Line($x-$dx-1,$y,$x+$dx+1,$y); $this->AddCSIMCircle($x,$y,$dx); } elseif( $this->type==MARK_X ) { $img->SetColor($color); $img->SetLineWeight($weight); $img->Line($x+$dx,$y+$dy,$x-$dx,$y-$dy); $img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy); $this->AddCSIMCircle($x,$y,$dx+$dy); } elseif( $this->type==MARK_STAR ) { $img->SetColor($color); $img->SetLineWeight($weight); $img->Line($x+$dx,$y+$dy,$x-$dx,$y-$dy); $img->Line($x-$dx,$y+$dy,$x+$dx,$y-$dy); // Oversize by a pixel to match the X $img->Line($x,$y+$dy+1,$x,$y-$dy-1); $img->Line($x-$dx-1,$y,$x+$dx+1,$y); $this->AddCSIMCircle($x,$y,$dx+$dy); } // Stroke title $this->title->Align("center","center"); $this->title->Stroke($img,$x,$y); } } // Class //======================================================================== // CLASS ImgData // Description: Base class for all image data classes that contains the // real image data. //======================================================================== class ImgData { protected $name = ''; // Each subclass gives a name protected $an = array(); // Data array names protected $colors = array(); // Available colors protected $index = array(); // Index for colors protected $maxidx = 0 ; // Max color index protected $anchor_x=0.5, $anchor_y=0.5 ; // Where is the center of the image function __construct() { // Empty } // Create a GD image from the data and return a GD handle function GetImg($aMark,$aIdx) { $n = $this->an[$aMark]; if( is_string($aIdx) ) { if( !in_array($aIdx,$this->colors) ) { JpGraphError::RaiseL(23001,$this->name,$aIdx);//('This marker "'.($this->name).'" does not exist in color: '.$aIdx); } $idx = $this->index[$aIdx]; } elseif( !is_integer($aIdx) || (is_integer($aIdx) && $aIdx > $this->maxidx ) ) { JpGraphError::RaiseL(23002,$this->name);//('Mark color index too large for marker "'.($this->name).'"'); } else $idx = $aIdx ; return Image::CreateFromString(base64_decode($this->{$n}[$idx][1])); } function GetAnchor() { return array($this->anchor_x,$this->anchor_y); } } // Keep a global flag cache to reduce memory usage $_gFlagCache=array( 1 => null, 2 => null, 3 => null, 4 => null, ); // Only supposed to b called as statics class FlagCache { static function GetFlagImgByName($aSize,$aName) { global $_gFlagCache; require_once('jpgraph_flags.php'); if( $_gFlagCache[$aSize] === null ) { $_gFlagCache[$aSize] = new FlagImages($aSize); } $f = $_gFlagCache[$aSize]; $idx = $f->GetIdxByName($aName,$aFullName); return $f->GetImgByIdx($idx); } } ?>loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_errhandler.inc.php0000644000175000017500000002715412225176641024346 0ustar danieldaniellt = $_jpg_messages; } function Get($errnbr,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) { GLOBAL $__jpg_err_locale; if( !isset($this->lt[$errnbr]) ) { return 'Internal error: The specified error message ('.$errnbr.') does not exist in the chosen locale ('.$__jpg_err_locale.')'; } $ea = $this->lt[$errnbr]; $j=0; if( $a1 !== null ) { $argv[$j++] = $a1; if( $a2 !== null ) { $argv[$j++] = $a2; if( $a3 !== null ) { $argv[$j++] = $a3; if( $a4 !== null ) { $argv[$j++] = $a4; if( $a5 !== null ) { $argv[$j++] = $a5; } } } } } $numargs = $j; if( $ea[1] != $numargs ) { // Error message argument count do not match. // Just return the error message without arguments. return $ea[0]; } switch( $numargs ) { case 1: $msg = sprintf($ea[0],$argv[0]); break; case 2: $msg = sprintf($ea[0],$argv[0],$argv[1]); break; case 3: $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2]); break; case 4: $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2],$argv[3]); break; case 5: $msg = sprintf($ea[0],$argv[0],$argv[1],$argv[2],$argv[3],$argv[4]); break; case 0: default: $msg = sprintf($ea[0]); break; } return $msg; } } // // A wrapper class that is used to access the specified error object // (to hide the global error parameter and avoid having a GLOBAL directive // in all methods. // class JpGraphError { private static $__iImgFlg = true; private static $__iLogFile = ''; private static $__iTitle = 'JpGraph Error: '; public static function Raise($aMsg,$aHalt=true){ throw new JpGraphException($aMsg); } public static function SetErrLocale($aLoc) { GLOBAL $__jpg_err_locale ; $__jpg_err_locale = $aLoc; } public static function RaiseL($errnbr,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) { throw new JpGraphExceptionL($errnbr,$a1,$a2,$a3,$a4,$a5); } public static function SetImageFlag($aFlg=true) { self::$__iImgFlg = $aFlg; } public static function GetImageFlag() { return self::$__iImgFlg; } public static function SetLogFile($aFile) { self::$__iLogFile = $aFile; } public static function GetLogFile() { return self::$__iLogFile; } public static function SetTitle($aTitle) { self::$__iTitle = $aTitle; } public static function GetTitle() { return self::$__iTitle; } } class JpGraphException extends Exception { // Redefine the exception so message isn't optional public function __construct($message, $code = 0) { // make sure everything is assigned properly parent::__construct($message, $code); } // custom string representation of object public function _toString() { return __CLASS__ . ": [{$this->code}]: {$this->message} at " . basename($this->getFile()) . ":" . $this->getLine() . "\n" . $this->getTraceAsString() . "\n"; } // custom representation of error as an image public function Stroke() { if( JpGraphError::GetImageFlag() ) { $errobj = new JpGraphErrObjectImg(); $errobj->SetTitle(JpGraphError::GetTitle()); } else { $errobj = new JpGraphErrObject(); $errobj->SetTitle(JpGraphError::GetTitle()); $errobj->SetStrokeDest(JpGraphError::GetLogFile()); } $errobj->Raise($this->getMessage()); } static public function defaultHandler(Exception $exception) { global $__jpg_OldHandler; if( $exception instanceof JpGraphException ) { $exception->Stroke(); } else { // Restore old handler if( $__jpg_OldHandler !== NULL ) { set_exception_handler($__jpg_OldHandler); } throw $exception; } } } class JpGraphExceptionL extends JpGraphException { // Redefine the exception so message isn't optional public function __construct($errcode,$a1=null,$a2=null,$a3=null,$a4=null,$a5=null) { // make sure everything is assigned properly $errtxt = new ErrMsgText(); JpGraphError::SetTitle('JpGraph Error: '.$errcode); parent::__construct($errtxt->Get($errcode,$a1,$a2,$a3,$a4,$a5), 0); } } // Setup the default handler global $__jpg_OldHandler; $__jpg_OldHandler = set_exception_handler(array('JpGraphException','defaultHandler')); // // First of all set up a default error handler // //============================================================= // The default trivial text error handler. //============================================================= class JpGraphErrObject { protected $iTitle = "JpGraph error: "; protected $iDest = false; function __construct() { // Empty. Reserved for future use } function SetTitle($aTitle) { $this->iTitle = $aTitle; } function SetStrokeDest($aDest) { $this->iDest = $aDest; } // If aHalt is true then execution can't continue. Typical used for fatal errors function Raise($aMsg,$aHalt=false) { if( $this->iDest != '' ) { if( $this->iDest == 'syslog' ) { error_log($this->iTitle.$aMsg); } else { $str = '['.date('r').'] '.$this->iTitle.$aMsg."\n"; $f = @fopen($this->iDest,'a'); if( $f ) { @fwrite($f,$str); @fclose($f); } } } else { $aMsg = $this->iTitle.$aMsg; // Check SAPI and if we are called from the command line // send the error to STDERR instead if( PHP_SAPI == 'cli' ) { fwrite(STDERR,$aMsg); } else { echo $aMsg; } } if( $aHalt ) exit(1); } } //============================================================== // An image based error handler //============================================================== class JpGraphErrObjectImg extends JpGraphErrObject { function __construct() { parent::__construct(); // Empty. Reserved for future use } function Raise($aMsg,$aHalt=true) { $img_iconerror = 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAAAaV'. 'BMVEX//////2Xy8mLl5V/Z2VvMzFi/v1WyslKlpU+ZmUyMjEh/'. 'f0VyckJlZT9YWDxMTDjAwMDy8sLl5bnY2K/MzKW/v5yyspKlpY'. 'iYmH+MjHY/PzV/f2xycmJlZVlZWU9MTEXY2Ms/PzwyMjLFTjea'. 'AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACx'. 'IAAAsSAdLdfvwAAAAHdElNRQfTBgISOCqusfs5AAABLUlEQVR4'. '2tWV3XKCMBBGWfkranCIVClKLd/7P2Q3QsgCxjDTq+6FE2cPH+'. 'xJ0Ogn2lQbsT+Wrs+buAZAV4W5T6Bs0YXBBwpKgEuIu+JERAX6'. 'wM2rHjmDdEITmsQEEmWADgZm6rAjhXsoMGY9B/NZBwJzBvn+e3'. 'wHntCAJdGu9SviwIwoZVDxPB9+Rc0TSEbQr0j3SA1gwdSn6Db0'. '6Tm1KfV6yzWGQO7zdpvyKLKBDmRFjzeB3LYgK7r6A/noDAfjtS'. 'IXaIzbJSv6WgUebTMV4EoRB8a2mQiQjgtF91HdKDKZ1gtFtQjk'. 'YcWaR5OKOhkYt+ZsTFdJRfPAApOpQYJTNHvCRSJR6SJngQadfc'. 'vd69OLMddVOPCGVnmrFD8bVYd3JXfxXPtLR/+mtv59/ALWiiMx'. 'qL72fwAAAABJRU5ErkJggg==' ; if( function_exists("imagetypes") ) { $supported = imagetypes(); } else { $supported = 0; } if( !function_exists('imagecreatefromstring') ) { $supported = 0; } if( ob_get_length() || headers_sent() || !($supported & IMG_PNG) ) { // Special case for headers already sent or that the installation doesn't support // the PNG format (which the error icon is encoded in). // Dont return an image since it can't be displayed die($this->iTitle.' '.$aMsg); } $aMsg = wordwrap($aMsg,55); $lines = substr_count($aMsg,"\n"); // Create the error icon GD $erricon = Image::CreateFromString(base64_decode($img_iconerror)); // Create an image that contains the error text. $w=400; $h=100 + 15*max(0,$lines-3); $img = new Image($w,$h); // Drop shadow $img->SetColor("gray"); $img->FilledRectangle(5,5,$w-1,$h-1,10); $img->SetColor("gray:0.7"); $img->FilledRectangle(5,5,$w-3,$h-3,10); // Window background $img->SetColor("lightblue"); $img->FilledRectangle(1,1,$w-5,$h-5); $img->CopyCanvasH($img->img,$erricon,5,30,0,0,40,40); // Window border $img->SetColor("black"); $img->Rectangle(1,1,$w-5,$h-5); $img->Rectangle(0,0,$w-4,$h-4); // Window top row $img->SetColor("darkred"); for($y=3; $y < 18; $y += 2 ) $img->Line(1,$y,$w-6,$y); // "White shadow" $img->SetColor("white"); // Left window edge $img->Line(2,2,2,$h-5); $img->Line(2,2,$w-6,2); // "Gray button shadow" $img->SetColor("darkgray"); // Gray window shadow $img->Line(2,$h-6,$w-5,$h-6); $img->Line(3,$h-7,$w-5,$h-7); // Window title $m = floor($w/2-5); $l = 110; $img->SetColor("lightgray:1.3"); $img->FilledRectangle($m-$l,2,$m+$l,16); // Stroke text $img->SetColor("darkred"); $img->SetFont(FF_FONT2,FS_BOLD); $img->StrokeText($m-90,15,$this->iTitle); $img->SetColor("black"); $img->SetFont(FF_FONT1,FS_NORMAL); $txt = new Text($aMsg,52,25); $txt->Align("left","top"); $txt->Stroke($img); if ($this->iDest) { $img->Stream($this->iDest); } else { $img->Headers(); $img->Stream(); } if( $aHalt ) die(); } } if( ! USE_IMAGE_ERROR_HANDLER ) { JpGraphError::SetImageFlag(false); } ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_gradient.php0000644000175000017500000004154412225176641023244 0ustar danieldanielimg = $img; } function SetNumColors($aNum) { $this->numcolors=$aNum; } //--------------- // PUBLIC METHODS // Produce a gradient filled rectangle with a smooth transition between // two colors. // ($xl,$yt) Top left corner // ($xr,$yb) Bottom right // $from_color Starting color in gradient // $to_color End color in the gradient // $style Which way is the gradient oriented? function FilledRectangle($xl,$yt,$xr,$yb,$from_color,$to_color,$style=1) { $this->img->SetLineWeight(1); switch( $style ) { case GRAD_VER: $steps = ceil(abs($xr-$xl)+1); $delta = $xr>=$xl ? 1 : -1; $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); for( $i=0, $x=$xl; $i < $steps; ++$i ) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yt,$x,$yb); $x += $delta; } break; case GRAD_HOR: $steps = ceil(abs($yb-$yt)+1); $delta = $yb >= $yt ? 1 : -1; $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); for($i=0,$y=$yt; $i < $steps; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($xl,$y,$xr,$y); $y += $delta; } break; case GRAD_MIDHOR: $steps = ceil(abs($yb-$yt)/2); $delta = $yb >= $yt ? 1 : -1; $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); for($y=$yt, $i=0; $i < $steps; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($xl,$y,$xr,$y); $y += $delta; } --$i; if( abs($yb-$yt) % 2 == 1 ) { --$steps; } for($j=0; $j < $steps; ++$j, --$i) { $this->img->current_color = $colors[$i]; $this->img->Line($xl,$y,$xr,$y); $y += $delta; } $this->img->Line($xl,$y,$xr,$y); break; case GRAD_MIDVER: $steps = ceil(abs($xr-$xl)/2); $delta = $xr>=$xl ? 1 : -1; $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); for($x=$xl, $i=0; $i < $steps; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } --$i; if( abs($xr-$xl) % 2 == 1 ) { --$steps; } for($j=0; $j < $steps; ++$j, --$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } $this->img->Line($x,$yb,$x,$yt); break; case GRAD_WIDE_MIDVER: $diff = ceil(abs($xr-$xl)); $steps = floor(abs($diff)/3); $firststep = $diff - 2*$steps ; $delta = $xr >= $xl ? 1 : -1; $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); for($x=$xl, $i=0; $i < $firststep; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } --$i; $this->img->current_color = $colors[$i]; for($j=0; $j< $steps; ++$j) { $this->img->Line($x,$yb,$x,$yt); $x += $delta; } for($j=0; $j < $steps; ++$j, --$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } break; case GRAD_WIDE_MIDHOR: $diff = ceil(abs($yb-$yt)); $steps = floor(abs($diff)/3); $firststep = $diff - 2*$steps ; $delta = $yb >= $yt? 1 : -1; $this->GetColArray($from_color,$to_color,$firststep,$colors,$this->numcolors); for($y=$yt, $i=0; $i < $firststep; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($xl,$y,$xr,$y); $y += $delta; } --$i; $this->img->current_color = $colors[$i]; for($j=0; $j < $steps; ++$j) { $this->img->Line($xl,$y,$xr,$y); $y += $delta; } for($j=0; $j < $steps; ++$j, --$i) { $this->img->current_color = $colors[$i]; $this->img->Line($xl,$y,$xr,$y); $y += $delta; } break; case GRAD_LEFT_REFLECTION: $steps1 = ceil(0.3*abs($xr-$xl)); $delta = $xr>=$xl ? 1 : -1; $from_color = $this->img->rgb->Color($from_color); $adj = 1.4; $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2])))); $from_color2 = array(min(255,$from_color[0]+$m), min(255,$from_color[1]+$m), min(255,$from_color[2]+$m)); $this->GetColArray($from_color2,$to_color,$steps1,$colors,$this->numcolors); $n = count($colors); for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } $steps2 = max(1,ceil(0.08*abs($xr-$xl))); $this->img->SetColor($to_color); for($j=0; $j< $steps2; ++$j) { $this->img->Line($x,$yb,$x,$yt); $x += $delta; } $steps = abs($xr-$xl)-$steps1-$steps2; $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors); $n = count($colors); for($i=0; $i < $steps && $i < $n; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } break; case GRAD_RIGHT_REFLECTION: $steps1 = ceil(0.7*abs($xr-$xl)); $delta = $xr>=$xl ? 1 : -1; $this->GetColArray($from_color,$to_color,$steps1,$colors,$this->numcolors); $n = count($colors); for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } $steps2 = max(1,ceil(0.08*abs($xr-$xl))); $this->img->SetColor($to_color); for($j=0; $j< $steps2; ++$j) { $this->img->Line($x,$yb,$x,$yt); $x += $delta; } $from_color = $this->img->rgb->Color($from_color); $adj = 1.4; $m = ($adj-1.0)*(255-min(255,min($from_color[0],min($from_color[1],$from_color[2])))); $from_color = array(min(255,$from_color[0]+$m), min(255,$from_color[1]+$m), min(255,$from_color[2]+$m)); $steps = abs($xr-$xl)-$steps1-$steps2; $this->GetColArray($to_color,$from_color,$steps,$colors,$this->numcolors); $n = count($colors); for($i=0; $i < $steps && $i < $n; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } break; case GRAD_CENTER: $steps = ceil(min(($yb-$yt)+1,($xr-$xl)+1)/2); $this->GetColArray($from_color,$to_color,$steps,$colors,$this->numcolors); $dx = ($xr-$xl)/2; $dy = ($yb-$yt)/2; $x=$xl;$y=$yt;$x2=$xr;$y2=$yb; $n = count($colors); for($x=$xl, $i=0; $x < $xl+$dx && $y < $yt+$dy && $i < $n; ++$x, ++$y, --$x2, --$y2, ++$i) { $this->img->current_color = $colors[$i]; $this->img->Rectangle($x,$y,$x2,$y2); } $this->img->Line($x,$y,$x2,$y2); break; case GRAD_RAISED_PANEL: // right to left $steps1 = $xr-$xl; $delta = $xr>=$xl ? 1 : -1; $this->GetColArray($to_color,$from_color,$steps1,$colors,$this->numcolors); $n = count($colors); for($x=$xl, $i=0; $i < $steps1 && $i < $n; ++$i) { $this->img->current_color = $colors[$i]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } // left to right $xr -= 3; $xl += 3; $yb -= 3; $yt += 3; $steps2 = $xr-$xl; $delta = $xr>=$xl ? 1 : -1; for($x=$xl, $j=$steps2; $j >= 0; --$j) { $this->img->current_color = $colors[$j]; $this->img->Line($x,$yb,$x,$yt); $x += $delta; } break; case GRAD_DIAGONAL: // use the longer dimension to determine the required number of steps. // first loop draws from one corner to the mid-diagonal and the second // loop draws from the mid-diagonal to the opposing corner. if($xr-$xl > $yb - $yt) { // width is greater than height -> use x-dimension for steps $steps = $xr-$xl; $delta = $xr>=$xl ? 1 : -1; $this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors); $n = count($colors); for($x=$xl, $i=0; $i < $steps && $i < $n; ++$i) { $this->img->current_color = $colors[$i]; $y = $yt+($i/$steps)*($yb-$yt)*$delta; $this->img->Line($x,$yt,$xl,$y); $x += $delta; } for($x=$xl, $i = 0; $i < $steps && $i < $n; ++$i) { $this->img->current_color = $colors[$steps+$i]; $y = $yt+($i/$steps)*($yb-$yt)*$delta; $this->img->Line($x,$yb,$xr,$y); $x += $delta; } } else { // height is greater than width -> use y-dimension for steps $steps = $yb-$yt; $delta = $yb>=$yt ? 1 : -1; $this->GetColArray($from_color,$to_color,$steps*2,$colors,$this->numcolors); $n = count($colors); for($y=$yt, $i=0; $i < $steps && $i < $n; ++$i) { $this->img->current_color = $colors[$i]; $x = $xl+($i/$steps)*($xr-$xl)*$delta; $this->img->Line($x,$yt,$xl,$y); $y += $delta; } for($y=$yt, $i = 0; $i < $steps && $i < $n; ++$i) { $this->img->current_color = $colors[$steps+$i]; $x = $xl+($i/$steps)*($xr-$xl)*$delta; $this->img->Line($x,$yb,$xr,$y); $x += $delta; } } break; default: JpGraphError::RaiseL(7001,$style); //("Unknown gradient style (=$style)."); break; } } // Fill a special case of a polygon with a flat bottom // with a gradient. Can be used for filled line plots. // Please note that this is NOT a generic gradient polygon fill // routine. It assumes that the bottom is flat (like a drawing // of a mountain) function FilledFlatPolygon($pts,$from_color,$to_color) { if( count($pts) == 0 ) return; $maxy=$pts[1]; $miny=$pts[1]; $n = count($pts) ; for( $i=0, $idx=0; $i < $n; $i += 2) { $x = round($pts[$i]); $y = round($pts[$i+1]); $miny = min($miny,$y); $maxy = max($maxy,$y); } $colors = array(); $this->GetColArray($from_color,$to_color,abs($maxy-$miny)+1,$colors,$this->numcolors); for($i=$miny, $idx=0; $i <= $maxy; ++$i ) { $colmap[$i] = $colors[$idx++]; } $n = count($pts)/2 ; $idx = 0 ; while( $idx < $n-1 ) { $p1 = array(round($pts[$idx*2]),round($pts[$idx*2+1])); $p2 = array(round($pts[++$idx*2]),round($pts[$idx*2+1])); // Find the largest rectangle we can fill $y = max($p1[1],$p2[1]) ; for($yy=$maxy; $yy > $y; --$yy) { $this->img->current_color = $colmap[$yy]; $this->img->Line($p1[0],$yy,$p2[0]-1,$yy); } if( $p1[1] == $p2[1] ) { continue; } // Fill the rest using lines (slow...) $slope = ($p2[0]-$p1[0])/($p1[1]-$p2[1]); $x1 = $p1[0]; $x2 = $p2[0]-1; $start = $y; if( $p1[1] > $p2[1] ) { while( $y >= $p2[1] ) { $x1=$slope*($start-$y)+$p1[0]; $this->img->current_color = $colmap[$y]; $this->img->Line($x1,$y,$x2,$y); --$y; } } else { while( $y >= $p1[1] ) { $x2=$p2[0]+$slope*($start-$y); $this->img->current_color = $colmap[$y]; $this->img->Line($x1,$y,$x2,$y); --$y; } } } } //--------------- // PRIVATE METHODS // Add to the image color map the necessary colors to do the transition // between the two colors using $numcolors intermediate colors function GetColArray($from_color,$to_color,$arr_size,&$colors,$numcols=100) { if( $arr_size==0 ) { return; } // If color is given as text get it's corresponding r,g,b values $from_color = $this->img->rgb->Color($from_color); $to_color = $this->img->rgb->Color($to_color); $rdelta=($to_color[0]-$from_color[0])/$numcols; $gdelta=($to_color[1]-$from_color[1])/$numcols; $bdelta=($to_color[2]-$from_color[2])/$numcols; $colorsperstep = $numcols/$arr_size; $prevcolnum = -1; $from_alpha = $from_color[3]; $to_alpha = $to_color[3]; $adelta = ( $to_alpha - $from_alpha ) / $numcols ; for ($i=0; $i < $arr_size; ++$i) { $colnum = floor($colorsperstep*$i); if ( $colnum == $prevcolnum ) { $colors[$i] = $colidx; } else { $r = floor($from_color[0] + $colnum*$rdelta); $g = floor($from_color[1] + $colnum*$gdelta); $b = floor($from_color[2] + $colnum*$bdelta); $alpha = $from_alpha + $colnum*$adelta; $colidx = $this->img->rgb->Allocate(sprintf("#%02x%02x%02x",$r,$g,$b),$alpha); $colors[$i] = $colidx; } $prevcolnum = $colnum; } } } // Class ?> loganalyzer-3.6.5/src/classes/jpgraph/jpg-config.inc.php0000644000175000017500000001413112225176641022517 0ustar danieldaniel loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_bar.php0000644000175000017500000013042212225176641022205 0ustar danieldanielnumpoints; } //--------------- // PUBLIC METHODS // Set a drop shadow for the bar (or rather an "up-right" shadow) function SetShadow($aColor="black",$aHSize=3,$aVSize=3,$aShow=true) { $this->bar_shadow=$aShow; $this->bar_shadow_color=$aColor; $this->bar_shadow_vsize=$aVSize; $this->bar_shadow_hsize=$aHSize; // Adjust the value margin to compensate for shadow $this->value->margin += $aVSize; } // DEPRECATED use SetYBase instead function SetYMin($aYStartValue) { //die("JpGraph Error: Deprecated function SetYMin. Use SetYBase() instead."); $this->ybase=$aYStartValue; } // Specify the base value for the bars function SetYBase($aYStartValue) { $this->ybase=$aYStartValue; } // The method will take the specified pattern anre // return a pattern index that corresponds to the original // patterm being rotated 90 degreees. This is needed when plottin // Horizontal bars function RotatePattern($aPat,$aRotate=true) { $rotate = array(1 => 2, 2 => 1, 3 => 3, 4 => 5, 5 => 4, 6 => 6, 7 => 7, 8 => 8); if( $aRotate ) { return $rotate[$aPat]; } else { return $aPat; } } function Legend($graph) { if( $this->grad && $this->legend!="" && !$this->fill ) { $color=array($this->grad_fromcolor,$this->grad_tocolor); // In order to differentiate between gradients and cooors specified as an RGB triple $graph->legend->Add($this->legend,$color,"",-$this->grad_style, $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); } elseif( $this->legend!="" && ($this->iPattern > -1 || is_array($this->iPattern)) ) { if( is_array($this->iPattern) ) { $p1 = $this->RotatePattern( $this->iPattern[0], $graph->img->a == 90 ); $p2 = $this->iPatternColor[0]; $p3 = $this->iPatternDensity[0]; } else { $p1 = $this->RotatePattern( $this->iPattern, $graph->img->a == 90 ); $p2 = $this->iPatternColor; $p3 = $this->iPatternDensity; } if( $p3 < 90 ) $p3 += 5; $color = array($p1,$p2,$p3,$this->fill_color); // A kludge: Too mark that we add a pattern we use a type value of < 100 $graph->legend->Add($this->legend,$color,"",-101, $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); } elseif( $this->fill_color && $this->legend!="" ) { if( is_array($this->fill_color) ) { $graph->legend->Add($this->legend,$this->fill_color[0],"",0, $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); } else { $graph->legend->Add($this->legend,$this->fill_color,"",0, $this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); } } } // Gets called before any axis are stroked function PreStrokeAdjust($graph) { parent::PreStrokeAdjust($graph); // If we are using a log Y-scale we want the base to be at the // minimum Y-value unless the user have specifically set some other // value than the default. if( substr($graph->axtype,-3,3)=="log" && $this->ybase==0 ) $this->ybase = $graph->yaxis->scale->GetMinVal(); // For a "text" X-axis scale we will adjust the // display of the bars a little bit. if( substr($graph->axtype,0,3)=="tex" ) { // Position the ticks between the bars $graph->xaxis->scale->ticks->SetXLabelOffset(0.5,0); // Center the bars if( $this->abswidth > -1 ) { $graph->SetTextScaleAbsCenterOff($this->abswidth); } else { if( $this->align == "center" ) $graph->SetTextScaleOff(0.5-$this->width/2); elseif( $this->align == "right" ) $graph->SetTextScaleOff(1-$this->width); } } elseif( ($this instanceof AccBarPlot) || ($this instanceof GroupBarPlot) ) { // We only set an absolute width for linear and int scale // for text scale the width will be set to a fraction of // the majstep width. if( $this->abswidth == -1 ) { // Not set // set width to a visuable sensible default $this->abswidth = $graph->img->plotwidth/(2*$this->numpoints); } } } function Min() { $m = parent::Min(); if( $m[1] >= $this->ybase ) $m[1] = $this->ybase; return $m; } function Max() { $m = parent::Max(); if( $m[1] <= $this->ybase ) $m[1] = $this->ybase; return $m; } // Specify width as fractions of the major stepo size function SetWidth($aWidth) { if( $aWidth > 1 ) { // Interpret this as absolute width $this->abswidth=$aWidth; } else { $this->width=$aWidth; } } // Specify width in absolute pixels. If specified this // overrides SetWidth() function SetAbsWidth($aWidth) { $this->abswidth=$aWidth; } function SetAlign($aAlign) { $this->align=$aAlign; } function SetNoFill() { $this->grad = false; $this->fill_color=false; $this->fill=false; } function SetFillColor($aColor) { // Do an extra error check if the color is specified as an RGB array triple // In that case convert it to a hex string since it will otherwise be // interpretated as an array of colors for each individual bar. $aColor = RGB::tryHexConversion($aColor); $this->fill = true ; $this->fill_color=$aColor; } function SetFillGradient($aFromColor,$aToColor=null,$aStyle=null) { $this->grad = true; $this->grad_fromcolor = $aFromColor; $this->grad_tocolor = $aToColor; $this->grad_style = $aStyle; } function SetValuePos($aPos) { $this->valuepos = $aPos; } function SetPattern($aPattern, $aColor='black'){ if( is_array($aPattern) ) { $n = count($aPattern); $this->iPattern = array(); $this->iPatternDensity = array(); if( is_array($aColor) ) { $this->iPatternColor = array(); if( count($aColor) != $n ) { JpGraphError::RaiseL(2001);//('NUmber of colors is not the same as the number of patterns in BarPlot::SetPattern()'); } } else { $this->iPatternColor = $aColor; } for( $i=0; $i < $n; ++$i ) { $this->_SetPatternHelper($aPattern[$i], $this->iPattern[$i], $this->iPatternDensity[$i]); if( is_array($aColor) ) { $this->iPatternColor[$i] = $aColor[$i]; } } } else { $this->_SetPatternHelper($aPattern, $this->iPattern, $this->iPatternDensity); $this->iPatternColor = $aColor; } } function _SetPatternHelper($aPattern, &$aPatternValue, &$aDensity){ switch( $aPattern ) { case PATTERN_DIAG1: $aPatternValue= 1; $aDensity = 92; break; case PATTERN_DIAG2: $aPatternValue= 1; $aDensity = 78; break; case PATTERN_DIAG3: $aPatternValue= 2; $aDensity = 92; break; case PATTERN_DIAG4: $aPatternValue= 2; $aDensity = 78; break; case PATTERN_CROSS1: $aPatternValue= 8; $aDensity = 90; break; case PATTERN_CROSS2: $aPatternValue= 8; $aDensity = 78; break; case PATTERN_CROSS3: $aPatternValue= 8; $aDensity = 65; break; case PATTERN_CROSS4: $aPatternValue= 7; $aDensity = 90; break; case PATTERN_STRIPE1: $aPatternValue= 5; $aDensity = 94; break; case PATTERN_STRIPE2: $aPatternValue= 5; $aDensity = 85; break; default: JpGraphError::RaiseL(2002); //('Unknown pattern specified in call to BarPlot::SetPattern()'); } } function Stroke($img,$xscale,$yscale) { $numpoints = count($this->coords[0]); if( isset($this->coords[1]) ) { if( count($this->coords[1])!=$numpoints ) { JpGraphError::RaiseL(2003,count($this->coords[1]),$numpoints); //"Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])."Number of Y-points:$numpoints"); } else { $exist_x = true; } } else { $exist_x = false; } $numbars=count($this->coords[0]); // Use GetMinVal() instead of scale[0] directly since in the case // of log scale we get a correct value. Log scales will have negative // values for values < 1 while still not representing negative numbers. if( $yscale->GetMinVal() >= 0 ) $zp=$yscale->scale_abs[0]; else { $zp=$yscale->Translate(0); } if( $this->abswidth > -1 ) { $abswidth=$this->abswidth; } else { $abswidth=round($this->width*$xscale->scale_factor,0); } // Count pontetial pattern array to avoid doing the count for each iteration if( is_array($this->iPattern) ) { $np = count($this->iPattern); } $grad = null; for($i=0; $i < $numbars; ++$i) { // If value is NULL, or 0 then don't draw a bar at all if ($this->coords[0][$i] === null || $this->coords[0][$i] === '' ) continue; if( $exist_x ) { $x=$this->coords[1][$i]; } else { $x=$i; } $x=$xscale->Translate($x); // Comment Note: This confuses the positioning when using acc together with // grouped bars. Workaround for fixing #191 /* if( !$xscale->textscale ) { if($this->align=="center") $x -= $abswidth/2; elseif($this->align=="right") $x -= $abswidth; } */ // Stroke fill color and fill gradient $pts=array( $x,$zp, $x,$yscale->Translate($this->coords[0][$i]), $x+$abswidth,$yscale->Translate($this->coords[0][$i]), $x+$abswidth,$zp); if( $this->grad ) { if( $grad === null ) { $grad = new Gradient($img); } if( is_array($this->grad_fromcolor) ) { // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be // an array to specify both (from, to style) for each individual bar. The way to know the difference is // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB // triple. $ng = count($this->grad_fromcolor); if( $ng === 3 ) { if( is_numeric($this->grad_fromcolor[0]) && $this->grad_fromcolor[0] > 0 && $this->grad_fromcolor[0] < 256 ) { // RGB Triple $fromcolor = $this->grad_fromcolor; $tocolor = $this->grad_tocolor; $style = $this->grad_style; } else { $fromcolor = $this->grad_fromcolor[$i % $ng][0]; $tocolor = $this->grad_fromcolor[$i % $ng][1]; $style = $this->grad_fromcolor[$i % $ng][2]; } } else { $fromcolor = $this->grad_fromcolor[$i % $ng][0]; $tocolor = $this->grad_fromcolor[$i % $ng][1]; $style = $this->grad_fromcolor[$i % $ng][2]; } $grad->FilledRectangle($pts[2],$pts[3], $pts[6],$pts[7], $fromcolor,$tocolor,$style); } else { $grad->FilledRectangle($pts[2],$pts[3], $pts[6],$pts[7], $this->grad_fromcolor,$this->grad_tocolor,$this->grad_style); } } elseif( !empty($this->fill_color) ) { if(is_array($this->fill_color)) { $img->PushColor($this->fill_color[$i % count($this->fill_color)]); } else { $img->PushColor($this->fill_color); } $img->FilledPolygon($pts); $img->PopColor(); } // Remember value of this bar $val=$this->coords[0][$i]; if( !empty($val) && !is_numeric($val) ) { JpGraphError::RaiseL(2004,$i,$val); //'All values for a barplot must be numeric. You have specified value['.$i.'] == \''.$val.'\''); } // Determine the shadow if( $this->bar_shadow && $val != 0) { $ssh = $this->bar_shadow_hsize; $ssv = $this->bar_shadow_vsize; // Create points to create a "upper-right" shadow if( $val > 0 ) { $sp[0]=$pts[6]; $sp[1]=$pts[7]; $sp[2]=$pts[4]; $sp[3]=$pts[5]; $sp[4]=$pts[2]; $sp[5]=$pts[3]; $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; $sp[8]=$pts[4]+$ssh; $sp[9]=$pts[5]-$ssv; $sp[10]=$pts[6]+$ssh; $sp[11]=$pts[7]-$ssv; } elseif( $val < 0 ) { $sp[0]=$pts[4]; $sp[1]=$pts[5]; $sp[2]=$pts[6]; $sp[3]=$pts[7]; $sp[4]=$pts[0]; $sp[5]=$pts[1]; $sp[6]=$pts[0]+$ssh; $sp[7]=$pts[1]-$ssv; $sp[8]=$pts[6]+$ssh; $sp[9]=$pts[7]-$ssv; $sp[10]=$pts[4]+$ssh; $sp[11]=$pts[5]-$ssv; } if( is_array($this->bar_shadow_color) ) { $numcolors = count($this->bar_shadow_color); if( $numcolors == 0 ) { JpGraphError::RaiseL(2005);//('You have specified an empty array for shadow colors in the bar plot.'); } $img->PushColor($this->bar_shadow_color[$i % $numcolors]); } else { $img->PushColor($this->bar_shadow_color); } $img->FilledPolygon($sp); $img->PopColor(); } // Stroke the pattern if( is_array($this->iPattern) ) { $f = new RectPatternFactory(); if( is_array($this->iPatternColor) ) { $pcolor = $this->iPatternColor[$i % $np]; } else { $pcolor = $this->iPatternColor; } $prect = $f->Create($this->iPattern[$i % $np],$pcolor,1); $prect->SetDensity($this->iPatternDensity[$i % $np]); if( $val < 0 ) { $rx = $pts[0]; $ry = $pts[1]; } else { $rx = $pts[2]; $ry = $pts[3]; } $width = abs($pts[4]-$pts[0])+1; $height = abs($pts[1]-$pts[3])+1; $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); $prect->Stroke($img); } else { if( $this->iPattern > -1 ) { $f = new RectPatternFactory(); $prect = $f->Create($this->iPattern,$this->iPatternColor,1); $prect->SetDensity($this->iPatternDensity); if( $val < 0 ) { $rx = $pts[0]; $ry = $pts[1]; } else { $rx = $pts[2]; $ry = $pts[3]; } $width = abs($pts[4]-$pts[0])+1; $height = abs($pts[1]-$pts[3])+1; $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); $prect->Stroke($img); } } // Stroke the outline of the bar if( is_array($this->color) ) { $img->SetColor($this->color[$i % count($this->color)]); } else { $img->SetColor($this->color); } $pts[] = $pts[0]; $pts[] = $pts[1]; if( $this->weight > 0 ) { $img->SetLineWeight($this->weight); $img->Polygon($pts); } // Determine how to best position the values of the individual bars $x=$pts[2]+($pts[4]-$pts[2])/2; $this->value->SetMargin(5); if( $this->valuepos=='top' ) { $y=$pts[3]; if( $img->a === 90 ) { if( $val < 0 ) { $this->value->SetAlign('right','center'); } else { $this->value->SetAlign('left','center'); } } else { if( $val < 0 ) { $this->value->SetMargin(-5); $y=$pts[1]; $this->value->SetAlign('center','bottom'); } else { $this->value->SetAlign('center','bottom'); } } $this->value->Stroke($img,$val,$x,$y); } elseif( $this->valuepos=='max' ) { $y=$pts[3]; if( $img->a === 90 ) { if( $val < 0 ) $this->value->SetAlign('left','center'); else $this->value->SetAlign('right','center'); } else { if( $val < 0 ) { $this->value->SetAlign('center','bottom'); } else { $this->value->SetAlign('center','top'); } } $this->value->SetMargin(-5); $this->value->Stroke($img,$val,$x,$y); } elseif( $this->valuepos=='center' ) { $y = ($pts[3] + $pts[1])/2; $this->value->SetAlign('center','center'); $this->value->SetMargin(0); $this->value->Stroke($img,$val,$x,$y); } elseif( $this->valuepos=='bottom' || $this->valuepos=='min' ) { $y=$pts[1]; if( $img->a === 90 ) { if( $val < 0 ) $this->value->SetAlign('right','center'); else $this->value->SetAlign('left','center'); } $this->value->SetMargin(3); $this->value->Stroke($img,$val,$x,$y); } else { JpGraphError::RaiseL(2006,$this->valuepos); //'Unknown position for values on bars :'.$this->valuepos); } // Create the client side image map $rpts = $img->ArrRotate($pts); $csimcoord=round($rpts[0]).", ".round($rpts[1]); for( $j=1; $j < 4; ++$j){ $csimcoord .= ", ".round($rpts[2*$j]).", ".round($rpts[2*$j+1]); } if( !empty($this->csimtargets[$i]) ) { $this->csimareas .= 'csimareas .= " href=\"".htmlentities($this->csimtargets[$i])."\""; if( !empty($this->csimwintargets[$i]) ) { $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; } $sval=''; if( !empty($this->csimalts[$i]) ) { $sval=sprintf($this->csimalts[$i],$this->coords[0][$i]); $this->csimareas .= " title=\"$sval\" alt=\"$sval\" "; } $this->csimareas .= " />\n"; } } return true; } } // Class //=================================================== // CLASS GroupBarPlot // Description: Produce grouped bar plots //=================================================== class GroupBarPlot extends BarPlot { private $plots, $nbrplots=0; //--------------- // CONSTRUCTOR function GroupBarPlot($plots) { $this->width=0.7; $this->plots = $plots; $this->nbrplots = count($plots); if( $this->nbrplots < 1 ) { JpGraphError::RaiseL(2007);//('Cannot create GroupBarPlot from empty plot array.'); } for($i=0; $i < $this->nbrplots; ++$i ) { if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { JpGraphError::RaiseL(2008,$i);//("Group bar plot element nbr $i is undefined or empty."); } } $this->numpoints = $plots[0]->numpoints; $this->width=0.7; } //--------------- // PUBLIC METHODS function Legend($graph) { $n = count($this->plots); for($i=0; $i < $n; ++$i) { $c = get_class($this->plots[$i]); if( !($this->plots[$i] instanceof BarPlot) ) { JpGraphError::RaiseL(2009,$c); //('One of the objects submitted to GroupBar is not a BarPlot. Make sure that you create the Group Bar plot from an array of BarPlot or AccBarPlot objects. (Class = '.$c.')'); } $this->plots[$i]->DoLegend($graph); } } function Min() { list($xmin,$ymin) = $this->plots[0]->Min(); $n = count($this->plots); for($i=0; $i < $n; ++$i) { list($xm,$ym) = $this->plots[$i]->Min(); $xmin = max($xmin,$xm); $ymin = min($ymin,$ym); } return array($xmin,$ymin); } function Max() { list($xmax,$ymax) = $this->plots[0]->Max(); $n = count($this->plots); for($i=0; $i < $n; ++$i) { list($xm,$ym) = $this->plots[$i]->Max(); $xmax = max($xmax,$xm); $ymax = max($ymax,$ym); } return array($xmax,$ymax); } function GetCSIMareas() { $n = count($this->plots); $csimareas=''; for($i=0; $i < $n; ++$i) { $csimareas .= $this->plots[$i]->csimareas; } return $csimareas; } // Stroke all the bars next to each other function Stroke($img,$xscale,$yscale) { $tmp=$xscale->off; $n = count($this->plots); $subwidth = $this->width/$this->nbrplots ; for( $i=0; $i < $n; ++$i ) { $this->plots[$i]->ymin=$this->ybase; $this->plots[$i]->SetWidth($subwidth); // If the client have used SetTextTickInterval() then // major_step will be > 1 and the positioning will fail. // If we assume it is always one the positioning will work // fine with a text scale but this will not work with // arbitrary linear scale $xscale->off = $tmp+$i*round($xscale->scale_factor* $subwidth); $this->plots[$i]->Stroke($img,$xscale,$yscale); } $xscale->off=$tmp; } } // Class //=================================================== // CLASS AccBarPlot // Description: Produce accumulated bar plots //=================================================== class AccBarPlot extends BarPlot { private $plots=null,$nbrplots=0; //--------------- // CONSTRUCTOR function __construct($plots) { $this->plots = $plots; $this->nbrplots = count($plots); if( $this->nbrplots < 1 ) { JpGraphError::RaiseL(2010);//('Cannot create AccBarPlot from empty plot array.'); } for($i=0; $i < $this->nbrplots; ++$i ) { if( empty($this->plots[$i]) || !isset($this->plots[$i]) ) { JpGraphError::RaiseL(2011,$i);//("Acc bar plot element nbr $i is undefined or empty."); } } // We can only allow individual plost which do not have specified X-positions for($i=0; $i < $this->nbrplots; ++$i ) { if( !empty($this->plots[$i]->coords[1]) ) { JpGraphError::RaiseL(2015); //'Individual bar plots in an AccBarPlot or GroupBarPlot can not have specified X-positions.'); } } // Use 0 weight by default which means that the individual bar // weights will be used per part n the accumulated bar $this->SetWeight(0); $this->numpoints = $plots[0]->numpoints; $this->value = new DisplayValue(); } //--------------- // PUBLIC METHODS function Legend($graph) { $n = count($this->plots); for( $i=$n-1; $i >= 0; --$i ) { $c = get_class($this->plots[$i]); if( !($this->plots[$i] instanceof BarPlot) ) { JpGraphError::RaiseL(2012,$c); //('One of the objects submitted to AccBar is not a BarPlot. Make sure that you create the AccBar plot from an array of BarPlot objects.(Class='.$c.')'); } $this->plots[$i]->DoLegend($graph); } } function Max() { list($xmax) = $this->plots[0]->Max(); $nmax=0; for($i=0; $i < count($this->plots); ++$i) { $n = count($this->plots[$i]->coords[0]); $nmax = max($nmax,$n); list($x) = $this->plots[$i]->Max(); $xmax = max($xmax,$x); } for( $i = 0; $i < $nmax; $i++ ) { // Get y-value for bar $i by adding the // individual bars from all the plots added. // It would be wrong to just add the // individual plots max y-value since that // would in most cases give to large y-value. $y=0; if( !isset($this->plots[0]->coords[0][$i]) ) { JpGraphError::RaiseL(2014); } if( $this->plots[0]->coords[0][$i] > 0 ) $y=$this->plots[0]->coords[0][$i]; for( $j = 1; $j < $this->nbrplots; $j++ ) { if( !isset($this->plots[$j]->coords[0][$i]) ) { JpGraphError::RaiseL(2014); } if( $this->plots[$j]->coords[0][$i] > 0 ) $y += $this->plots[$j]->coords[0][$i]; } $ymax[$i] = $y; } $ymax = max($ymax); // Bar always start at baseline if( $ymax <= $this->ybase ) $ymax = $this->ybase; return array($xmax,$ymax); } function Min() { $nmax=0; list($xmin,$ysetmin) = $this->plots[0]->Min(); for($i=0; $i < count($this->plots); ++$i) { $n = count($this->plots[$i]->coords[0]); $nmax = max($nmax,$n); list($x,$y) = $this->plots[$i]->Min(); $xmin = Min($xmin,$x); $ysetmin = Min($y,$ysetmin); } for( $i = 0; $i < $nmax; $i++ ) { // Get y-value for bar $i by adding the // individual bars from all the plots added. // It would be wrong to just add the // individual plots max y-value since that // would in most cases give to large y-value. $y=0; if( $this->plots[0]->coords[0][$i] < 0 ) $y=$this->plots[0]->coords[0][$i]; for( $j = 1; $j < $this->nbrplots; $j++ ) { if( $this->plots[$j]->coords[0][$i] < 0 ) $y += $this->plots[ $j ]->coords[0][$i]; } $ymin[$i] = $y; } $ymin = Min($ysetmin,Min($ymin)); // Bar always start at baseline if( $ymin >= $this->ybase ) $ymin = $this->ybase; return array($xmin,$ymin); } // Stroke acc bar plot function Stroke($img,$xscale,$yscale) { $pattern=NULL; $img->SetLineWeight($this->weight); $grad=null; for($i=0; $i < $this->numpoints-1; $i++) { $accy = 0; $accy_neg = 0; for($j=0; $j < $this->nbrplots; ++$j ) { $img->SetColor($this->plots[$j]->color); if ( $this->plots[$j]->coords[0][$i] >= 0) { $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); $accyt=$yscale->Translate($accy); $accy+=$this->plots[$j]->coords[0][$i]; } else { //if ( $this->plots[$j]->coords[0][$i] < 0 || $accy_neg < 0 ) { $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); $accyt=$yscale->Translate($accy_neg); $accy_neg+=$this->plots[$j]->coords[0][$i]; } $xt=$xscale->Translate($i); if( $this->abswidth > -1 ) { $abswidth=$this->abswidth; } else { $abswidth=round($this->width*$xscale->scale_factor,0); } $pts=array($xt,$accyt,$xt,$yt,$xt+$abswidth,$yt,$xt+$abswidth,$accyt); if( $this->bar_shadow ) { $ssh = $this->bar_shadow_hsize; $ssv = $this->bar_shadow_vsize; // We must also differ if we are a positive or negative bar. if( $j === 0 ) { // This gets extra complicated since we have to // see all plots to see if we are negative. It could // for example be that all plots are 0 until the very // last one. We therefore need to save the initial setup // for both the negative and positive case // In case the final bar is positive $sp[0]=$pts[6]+1; $sp[1]=$pts[7]; $sp[2]=$pts[6]+$ssh; $sp[3]=$pts[7]-$ssv; // In case the final bar is negative $nsp[0]=$pts[0]; $nsp[1]=$pts[1]; $nsp[2]=$pts[0]+$ssh; $nsp[3]=$pts[1]-$ssv; $nsp[4]=$pts[6]+$ssh; $nsp[5]=$pts[7]-$ssv; $nsp[10]=$pts[6]+1; $nsp[11]=$pts[7]; } if( $j === $this->nbrplots-1 ) { // If this is the last plot of the bar and // the total value is larger than 0 then we // add the shadow. if( is_array($this->bar_shadow_color) ) { $numcolors = count($this->bar_shadow_color); if( $numcolors == 0 ) { JpGraphError::RaiseL(2013);//('You have specified an empty array for shadow colors in the bar plot.'); } $img->PushColor($this->bar_shadow_color[$i % $numcolors]); } else { $img->PushColor($this->bar_shadow_color); } if( $accy > 0 ) { $sp[4]=$pts[4]+$ssh; $sp[5]=$pts[5]-$ssv; $sp[6]=$pts[2]+$ssh; $sp[7]=$pts[3]-$ssv; $sp[8]=$pts[2]; $sp[9]=$pts[3]-1; $sp[10]=$pts[4]+1; $sp[11]=$pts[5]; $img->FilledPolygon($sp,4); } elseif( $accy_neg < 0 ) { $nsp[6]=$pts[4]+$ssh; $nsp[7]=$pts[5]-$ssv; $nsp[8]=$pts[4]+1; $nsp[9]=$pts[5]; $img->FilledPolygon($nsp,4); } $img->PopColor(); } } // If value is NULL or 0, then don't draw a bar at all if ($this->plots[$j]->coords[0][$i] == 0 ) continue; if( $this->plots[$j]->grad ) { if( $grad === null ) { $grad = new Gradient($img); } if( is_array($this->plots[$j]->grad_fromcolor) ) { // The first argument (grad_fromcolor) can be either an array or a single color. If it is an array // then we have two choices. It can either a) be a single color specified as an RGB triple or it can be // an array to specify both (from, to style) for each individual bar. The way to know the difference is // to investgate the first element. If this element is an integer [0,255] then we assume it is an RGB // triple. $ng = count($this->plots[$j]->grad_fromcolor); if( $ng === 3 ) { if( is_numeric($this->plots[$j]->grad_fromcolor[0]) && $this->plots[$j]->grad_fromcolor[0] > 0 && $this->plots[$j]->grad_fromcolor[0] < 256 ) { // RGB Triple $fromcolor = $this->plots[$j]->grad_fromcolor; $tocolor = $this->plots[$j]->grad_tocolor; $style = $this->plots[$j]->grad_style; } else { $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0]; $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1]; $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2]; } } else { $fromcolor = $this->plots[$j]->grad_fromcolor[$i % $ng][0]; $tocolor = $this->plots[$j]->grad_fromcolor[$i % $ng][1]; $style = $this->plots[$j]->grad_fromcolor[$i % $ng][2]; } $grad->FilledRectangle($pts[2],$pts[3], $pts[6],$pts[7], $fromcolor,$tocolor,$style); } else { $grad->FilledRectangle($pts[2],$pts[3], $pts[6],$pts[7], $this->plots[$j]->grad_fromcolor, $this->plots[$j]->grad_tocolor, $this->plots[$j]->grad_style); } } else { if (is_array($this->plots[$j]->fill_color) ) { $numcolors = count($this->plots[$j]->fill_color); $fillcolor = $this->plots[$j]->fill_color[$i % $numcolors]; // If the bar is specified to be non filled then the fill color is false if( $fillcolor !== false ) { $img->SetColor($this->plots[$j]->fill_color[$i % $numcolors]); } } else { $fillcolor = $this->plots[$j]->fill_color; if( $fillcolor !== false ) { $img->SetColor($this->plots[$j]->fill_color); } } if( $fillcolor !== false ) { $img->FilledPolygon($pts); } } $img->SetColor($this->plots[$j]->color); // Stroke the pattern if( $this->plots[$j]->iPattern > -1 ) { if( $pattern===NULL ) { $pattern = new RectPatternFactory(); } $prect = $pattern->Create($this->plots[$j]->iPattern,$this->plots[$j]->iPatternColor,1); $prect->SetDensity($this->plots[$j]->iPatternDensity); if( $this->plots[$j]->coords[0][$i] < 0 ) { $rx = $pts[0]; $ry = $pts[1]; } else { $rx = $pts[2]; $ry = $pts[3]; } $width = abs($pts[4]-$pts[0])+1; $height = abs($pts[1]-$pts[3])+1; $prect->SetPos(new Rectangle($rx,$ry,$width,$height)); $prect->Stroke($img); } // CSIM array if( $i < count($this->plots[$j]->csimtargets) ) { // Create the client side image map $rpts = $img->ArrRotate($pts); $csimcoord=round($rpts[0]).", ".round($rpts[1]); for( $k=1; $k < 4; ++$k){ $csimcoord .= ", ".round($rpts[2*$k]).", ".round($rpts[2*$k+1]); } if( ! empty($this->plots[$j]->csimtargets[$i]) ) { $this->csimareas.= 'csimareas.= " href=\"".$this->plots[$j]->csimtargets[$i]."\" "; if( ! empty($this->plots[$j]->csimwintargets[$i]) ) { $this->csimareas.= " target=\"".$this->plots[$j]->csimwintargets[$i]."\" "; } $sval=''; if( !empty($this->plots[$j]->csimalts[$i]) ) { $sval=sprintf($this->plots[$j]->csimalts[$i],$this->plots[$j]->coords[0][$i]); $this->csimareas .= " title=\"$sval\" "; } $this->csimareas .= " alt=\"$sval\" />\n"; } } $pts[] = $pts[0]; $pts[] = $pts[1]; $img->SetLineWeight($this->plots[$j]->weight); $img->Polygon($pts); $img->SetLineWeight(1); } // Daw potential bar around the entire accbar bar if( $this->weight > 0 ) { $y=$yscale->Translate(0); $img->SetColor($this->color); $img->SetLineWeight($this->weight); $img->Rectangle($pts[0],$y,$pts[6],$pts[5]); } // Draw labels for each acc.bar $x=$pts[2]+($pts[4]-$pts[2])/2; if($this->bar_shadow) $x += $ssh; // First stroke the accumulated value for the entire bar // This value is always placed at the top/bottom of the bars if( $accy_neg < 0 ) { $y=$yscale->Translate($accy_neg); $this->value->Stroke($img,$accy_neg,$x,$y); } else { $y=$yscale->Translate($accy); $this->value->Stroke($img,$accy,$x,$y); } $accy = 0; $accy_neg = 0; for($j=0; $j < $this->nbrplots; ++$j ) { // We don't print 0 values in an accumulated bar plot if( $this->plots[$j]->coords[0][$i] == 0 ) continue; if ($this->plots[$j]->coords[0][$i] > 0) { $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy); $accyt=$yscale->Translate($accy); if( $this->plots[$j]->valuepos=='center' ) { $y = $accyt-($accyt-$yt)/2; } elseif( $this->plots[$j]->valuepos=='bottom' ) { $y = $accyt; } else { // top or max $y = $accyt-($accyt-$yt); } $accy+=$this->plots[$j]->coords[0][$i]; if( $this->plots[$j]->valuepos=='center' ) { $this->plots[$j]->value->SetAlign("center","center"); $this->plots[$j]->value->SetMargin(0); } elseif( $this->plots[$j]->valuepos=='bottom' ) { $this->plots[$j]->value->SetAlign('center','bottom'); $this->plots[$j]->value->SetMargin(2); } else { $this->plots[$j]->value->SetAlign('center','top'); $this->plots[$j]->value->SetMargin(1); } } else { $yt=$yscale->Translate($this->plots[$j]->coords[0][$i]+$accy_neg); $accyt=$yscale->Translate($accy_neg); $accy_neg+=$this->plots[$j]->coords[0][$i]; if( $this->plots[$j]->valuepos=='center' ) { $y = $accyt-($accyt-$yt)/2; } elseif( $this->plots[$j]->valuepos=='bottom' ) { $y = $accyt; } else { $y = $accyt-($accyt-$yt); } if( $this->plots[$j]->valuepos=='center' ) { $this->plots[$j]->value->SetAlign("center","center"); $this->plots[$j]->value->SetMargin(0); } elseif( $this->plots[$j]->valuepos=='bottom' ) { $this->plots[$j]->value->SetAlign('center',$j==0 ? 'bottom':'top'); $this->plots[$j]->value->SetMargin(-2); } else { $this->plots[$j]->value->SetAlign('center','bottom'); $this->plots[$j]->value->SetMargin(-1); } } $this->plots[$j]->value->Stroke($img,$this->plots[$j]->coords[0][$i],$x,$y); } } return true; } } // Class /* EOF */ ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph.php0000644000175000017500000060314112225176641021364 0ustar danieldanielGet(11,$file,$lineno); die($msg); } else { define('CACHE_DIR', $_SERVER['TEMP'] . '/'); } } else { define('CACHE_DIR','/tmp/jpgraph_cache/'); } } } elseif( !defined('CACHE_DIR') ) { define('CACHE_DIR', ''); } // // Setup path for western/latin TTF fonts // if (!defined('TTF_DIR')) { if (strstr( PHP_OS, 'WIN') ) { $sroot = getenv('SystemRoot'); if( empty($sroot) ) { $t = new ErrMsgText(); $msg = $t->Get(12,$file,$lineno); die($msg); } else { define('TTF_DIR', $sroot.'/fonts/'); } } else { define('TTF_DIR','/usr/share/fonts/truetype/'); } } // // Setup path for MultiByte TTF fonts (japanese, chinese etc.) // if (!defined('MBTTF_DIR')) { if (strstr( PHP_OS, 'WIN') ) { $sroot = getenv('SystemRoot'); if( empty($sroot) ) { $t = new ErrMsgText(); $msg = $t->Get(12,$file,$lineno); die($msg); } else { define('MBTTF_DIR', $sroot.'/fonts/'); } } else { define('MBTTF_DIR','/usr/share/fonts/truetype/'); } } // // Check minimum PHP version // function CheckPHPVersion($aMinVersion) { list($majorC, $minorC, $editC) = preg_split('/[\/.-]/', PHP_VERSION); list($majorR, $minorR, $editR) = preg_split('/[\/.-]/', $aMinVersion); if ($majorC != $majorR) return false; if ($majorC < $majorR) return false; // same major - check minor if ($minorC > $minorR) return true; if ($minorC < $minorR) return false; // and same minor if ($editC >= $editR) return true; return true; } // // Make sure PHP version is high enough // if( !CheckPHPVersion(MIN_PHPVERSION) ) { JpGraphError::RaiseL(13,PHP_VERSION,MIN_PHPVERSION); die(); } // // Make GD sanity check // if( !function_exists("imagetypes") || !function_exists('imagecreatefromstring') ) { JpGraphError::RaiseL(25001); //("This PHP installation is not configured with the GD library. Please recompile PHP with GD support to run JpGraph. (Neither function imagetypes() nor imagecreatefromstring() does exist)"); } // // Setup PHP error handler // function _phpErrorHandler($errno,$errmsg,$filename, $linenum, $vars) { // Respect current error level if( $errno & error_reporting() ) { JpGraphError::RaiseL(25003,basename($filename),$linenum,$errmsg); } } if( INSTALL_PHP_ERR_HANDLER ) { set_error_handler("_phpErrorHandler"); } // // Check if there were any warnings, perhaps some wrong includes by the user. In this // case we raise it immediately since otherwise the image will not show and makes // debugging difficult. This is controlled by the user setting CATCH_PHPERRMSG // if( isset($GLOBALS['php_errormsg']) && CATCH_PHPERRMSG && !preg_match('/|Deprecated|/i', $GLOBALS['php_errormsg']) ) { JpGraphError::RaiseL(25004,$GLOBALS['php_errormsg']); } // Useful mathematical function function sign($a) {return $a >= 0 ? 1 : -1;} // // Utility function to generate an image name based on the filename we // are running from and assuming we use auto detection of graphic format // (top level), i.e it is safe to call this function // from a script that uses JpGraph // function GenImgName() { // Determine what format we should use when we save the images $supported = imagetypes(); if( $supported & IMG_PNG ) $img_format="png"; elseif( $supported & IMG_GIF ) $img_format="gif"; elseif( $supported & IMG_JPG ) $img_format="jpeg"; elseif( $supported & IMG_WBMP ) $img_format="wbmp"; elseif( $supported & IMG_XPM ) $img_format="xpm"; if( !isset($_SERVER['PHP_SELF']) ) { JpGraphError::RaiseL(25005); //(" Can't access PHP_SELF, PHP global variable. You can't run PHP from command line if you want to use the 'auto' naming of cache or image files."); } $fname = basename($_SERVER['PHP_SELF']); if( !empty($_SERVER['QUERY_STRING']) ) { $q = @$_SERVER['QUERY_STRING']; $fname .= '_'.preg_replace("/\W/", "_", $q).'.'.$img_format; } else { $fname = substr($fname,0,strlen($fname)-4).'.'.$img_format; } return $fname; } //=================================================== // CLASS JpgTimer // Description: General timing utility class to handle // time measurement of generating graphs. Multiple // timers can be started. //=================================================== class JpgTimer { private $start, $idx; function __construct() { $this->idx=0; } // Push a new timer start on stack function Push() { list($ms,$s)=explode(" ",microtime()); $this->start[$this->idx++]=floor($ms*1000) + 1000*$s; } // Pop the latest timer start and return the diff with the // current time function Pop() { assert($this->idx>0); list($ms,$s)=explode(" ",microtime()); $etime=floor($ms*1000) + (1000*$s); $this->idx--; return $etime-$this->start[$this->idx]; } } // Class //=================================================== // CLASS DateLocale // Description: Hold localized text used in dates //=================================================== class DateLocale { public $iLocale = 'C'; // environmental locale be used by default private $iDayAbb = null, $iShortDay = null, $iShortMonth = null, $iMonthName = null; function __construct() { settype($this->iDayAbb, 'array'); settype($this->iShortDay, 'array'); settype($this->iShortMonth, 'array'); settype($this->iMonthName, 'array'); $this->Set('C'); } function Set($aLocale) { if ( in_array($aLocale, array_keys($this->iDayAbb)) ){ $this->iLocale = $aLocale; return TRUE; // already cached nothing else to do! } $pLocale = setlocale(LC_TIME, 0); // get current locale for LC_TIME if (is_array($aLocale)) { foreach ($aLocale as $loc) { $res = @setlocale(LC_TIME, $loc); if ( $res ) { $aLocale = $loc; break; } } } else { $res = @setlocale(LC_TIME, $aLocale); } if ( ! $res ) { JpGraphError::RaiseL(25007,$aLocale); //("You are trying to use the locale ($aLocale) which your PHP installation does not support. Hint: Use '' to indicate the default locale for this geographic region."); return FALSE; } $this->iLocale = $aLocale; for( $i = 0, $ofs = 0 - strftime('%w'); $i < 7; $i++, $ofs++ ) { $day = strftime('%a', strtotime("$ofs day")); $day[0] = strtoupper($day[0]); $this->iDayAbb[$aLocale][]= $day[0]; $this->iShortDay[$aLocale][]= $day; } for($i=1; $i<=12; ++$i) { list($short ,$full) = explode('|', strftime("%b|%B",strtotime("2001-$i-01"))); $this->iShortMonth[$aLocale][] = ucfirst($short); $this->iMonthName [$aLocale][] = ucfirst($full); } setlocale(LC_TIME, $pLocale); return TRUE; } function GetDayAbb() { return $this->iDayAbb[$this->iLocale]; } function GetShortDay() { return $this->iShortDay[$this->iLocale]; } function GetShortMonth() { return $this->iShortMonth[$this->iLocale]; } function GetShortMonthName($aNbr) { return $this->iShortMonth[$this->iLocale][$aNbr]; } function GetLongMonthName($aNbr) { return $this->iMonthName[$this->iLocale][$aNbr]; } function GetMonth() { return $this->iMonthName[$this->iLocale]; } } // Global object handlers $gDateLocale = new DateLocale(); $gJpgDateLocale = new DateLocale(); //======================================================= // CLASS Footer // Description: Encapsulates the footer line in the Graph //======================================================= class Footer { public $iLeftMargin = 3, $iRightMargin = 3, $iBottomMargin = 3 ; public $left,$center,$right; private $iTimer=null, $itimerpoststring=''; function __construct() { $this->left = new Text(); $this->left->ParagraphAlign('left'); $this->center = new Text(); $this->center->ParagraphAlign('center'); $this->right = new Text(); $this->right->ParagraphAlign('right'); } function SetTimer($aTimer,$aTimerPostString='') { $this->iTimer = $aTimer; $this->itimerpoststring = $aTimerPostString; } function SetMargin($aLeft=3,$aRight=3,$aBottom=3) { $this->iLeftMargin = $aLeft; $this->iRightMargin = $aRight; $this->iBottomMargin = $aBottom; } function Stroke($aImg) { $y = $aImg->height - $this->iBottomMargin; $x = $this->iLeftMargin; $this->left->Align('left','bottom'); $this->left->Stroke($aImg,$x,$y); $x = ($aImg->width - $this->iLeftMargin - $this->iRightMargin)/2; $this->center->Align('center','bottom'); $this->center->Stroke($aImg,$x,$y); $x = $aImg->width - $this->iRightMargin; $this->right->Align('right','bottom'); if( $this->iTimer != null ) { $this->right->Set( $this->right->t . sprintf('%.3f',$this->iTimer->Pop()/1000.0) . $this->itimerpoststring ); } $this->right->Stroke($aImg,$x,$y); } } //=================================================== // CLASS Graph // Description: Main class to handle graphs //=================================================== class Graph { public $cache=null; // Cache object (singleton) public $img=null; // Img object (singleton) public $plots=array(); // Array of all plot object in the graph (for Y 1 axis) public $y2plots=array(); // Array of all plot object in the graph (for Y 2 axis) public $ynplots=array(); public $xscale=null; // X Scale object (could be instance of LinearScale or LogScale public $yscale=null,$y2scale=null, $ynscale=array(); public $iIcons = array(); // Array of Icons to add to public $cache_name; // File name to be used for the current graph in the cache directory public $xgrid=null; // X Grid object (linear or logarithmic) public $ygrid=null,$y2grid=null; //dito for Y public $doframe=true,$frame_color='black', $frame_weight=1; // Frame around graph public $boxed=false, $box_color='black', $box_weight=1; // Box around plot area public $doshadow=false,$shadow_width=4,$shadow_color='gray@0.5'; // Shadow for graph public $xaxis=null; // X-axis (instane of Axis class) public $yaxis=null, $y2axis=null, $ynaxis=array(); // Y axis (instance of Axis class) public $margin_color=array(230,230,230); // Margin color of graph public $plotarea_color=array(255,255,255); // Plot area color public $title,$subtitle,$subsubtitle; // Title and subtitle(s) text object public $axtype="linlin"; // Type of axis public $xtick_factor,$ytick_factor; // Factor to determine the maximum number of ticks depending on the plot width public $texts=null, $y2texts=null; // Text object to ge shown in the graph public $lines=null, $y2lines=null; public $bands=null, $y2bands=null; public $text_scale_off=0, $text_scale_abscenteroff=-1; // Text scale in fractions and for centering bars public $background_image='',$background_image_type=-1,$background_image_format="png"; public $background_image_bright=0,$background_image_contr=0,$background_image_sat=0; public $background_image_xpos=0,$background_image_ypos=0; public $image_bright=0, $image_contr=0, $image_sat=0; public $inline; public $showcsim=0,$csimcolor="red";//debug stuff, draw the csim boundaris on the image if <>0 public $grid_depth=DEPTH_BACK; // Draw grid under all plots as default public $iAxisStyle = AXSTYLE_SIMPLE; public $iCSIMdisplay=false,$iHasStroked = false; public $footer; public $csimcachename = '', $csimcachetimeout = 0, $iCSIMImgAlt=''; public $iDoClipping = false; public $y2orderback=true; public $tabtitle; public $bkg_gradtype=-1,$bkg_gradstyle=BGRAD_MARGIN; public $bkg_gradfrom='navy', $bkg_gradto='silver'; public $plot_gradtype=-1,$plot_gradstyle=BGRAD_MARGIN; public $plot_gradfrom='silver', $plot_gradto='navy'; public $titlebackground = false; public $titlebackground_color = 'lightblue', $titlebackground_style = 1, $titlebackground_framecolor = 'blue', $titlebackground_framestyle = 2, $titlebackground_frameweight = 1, $titlebackground_bevelheight = 3 ; public $titlebkg_fillstyle=TITLEBKG_FILLSTYLE_SOLID; public $titlebkg_scolor1='black',$titlebkg_scolor2='white'; public $framebevel = false, $framebeveldepth = 2 ; public $framebevelborder = false, $framebevelbordercolor='black'; public $framebevelcolor1='white@0.4', $framebevelcolor2='black@0.4'; public $background_image_mix=100; public $background_cflag = ''; public $background_cflag_type = BGIMG_FILLPLOT; public $background_cflag_mix = 100; public $iImgTrans=false, $iImgTransHorizon = 100,$iImgTransSkewDist=150, $iImgTransDirection = 1, $iImgTransMinSize = true, $iImgTransFillColor='white',$iImgTransHighQ=false, $iImgTransBorder=false,$iImgTransHorizonPos=0.5; public $legend; protected $iYAxisDeltaPos=50; protected $iIconDepth=DEPTH_BACK; protected $iAxisLblBgType = 0, $iXAxisLblBgFillColor = 'lightgray', $iXAxisLblBgColor = 'black', $iYAxisLblBgFillColor = 'lightgray', $iYAxisLblBgColor = 'black'; protected $iTables=NULL; // aWIdth Width in pixels of image // aHeight Height in pixels of image // aCachedName Name for image file in cache directory // aTimeOut Timeout in minutes for image in cache // aInline If true the image is streamed back in the call to Stroke() // If false the image is just created in the cache function __construct($aWidth=300,$aHeight=200,$aCachedName='',$aTimeout=0,$aInline=true) { if( !is_numeric($aWidth) || !is_numeric($aHeight) ) { JpGraphError::RaiseL(25008);//('Image width/height argument in Graph::Graph() must be numeric'); } // Automatically generate the image file name based on the name of the script that // generates the graph if( $aCachedName == 'auto' ) { $aCachedName=GenImgName(); } // Should the image be streamed back to the browser or only to the cache? $this->inline=$aInline; $this->img = new RotImage($aWidth,$aHeight); $this->cache = new ImgStreamCache(); // Window doesn't like '?' in the file name so replace it with an '_' $aCachedName = str_replace("?","_",$aCachedName); $this->SetupCache($aCachedName, $aTimeout); $this->title = new Text(); $this->title->ParagraphAlign('center'); $this->title->SetFont(FF_FONT2,FS_BOLD); $this->title->SetMargin(5); $this->title->SetAlign('center'); $this->subtitle = new Text(); $this->subtitle->ParagraphAlign('center'); $this->subtitle->SetMargin(3); $this->subtitle->SetAlign('center'); $this->subsubtitle = new Text(); $this->subsubtitle->ParagraphAlign('center'); $this->subsubtitle->SetMargin(3); $this->subsubtitle->SetAlign('center'); $this->legend = new Legend(); $this->footer = new Footer(); // If the cached version exist just read it directly from the // cache, stream it back to browser and exit if( $aCachedName!='' && READ_CACHE && $aInline ) { if( $this->cache->GetAndStream($this->img,$aCachedName) ) { exit(); } } $this->SetTickDensity(); // Normal density $this->tabtitle = new GraphTabTitle(); } function SetupCache($aFilename,$aTimeout=60) { $this->cache_name = $aFilename; $this->cache->SetTimeOut($aTimeout); } // Enable final image perspective transformation function Set3DPerspective($aDir=1,$aHorizon=100,$aSkewDist=120,$aQuality=false,$aFillColor='#FFFFFF',$aBorder=false,$aMinSize=true,$aHorizonPos=0.5) { $this->iImgTrans = true; $this->iImgTransHorizon = $aHorizon; $this->iImgTransSkewDist= $aSkewDist; $this->iImgTransDirection = $aDir; $this->iImgTransMinSize = $aMinSize; $this->iImgTransFillColor=$aFillColor; $this->iImgTransHighQ=$aQuality; $this->iImgTransBorder=$aBorder; $this->iImgTransHorizonPos=$aHorizonPos; } function SetUserFont($aNormal,$aBold='',$aItalic='',$aBoldIt='') { $this->img->ttf->SetUserFont($aNormal,$aBold,$aItalic,$aBoldIt); } function SetUserFont1($aNormal,$aBold='',$aItalic='',$aBoldIt='') { $this->img->ttf->SetUserFont1($aNormal,$aBold,$aItalic,$aBoldIt); } function SetUserFont2($aNormal,$aBold='',$aItalic='',$aBoldIt='') { $this->img->ttf->SetUserFont2($aNormal,$aBold,$aItalic,$aBoldIt); } function SetUserFont3($aNormal,$aBold='',$aItalic='',$aBoldIt='') { $this->img->ttf->SetUserFont3($aNormal,$aBold,$aItalic,$aBoldIt); } // Set Image format and optional quality function SetImgFormat($aFormat,$aQuality=75) { $this->img->SetImgFormat($aFormat,$aQuality); } // Should the grid be in front or back of the plot? function SetGridDepth($aDepth) { $this->grid_depth=$aDepth; } function SetIconDepth($aDepth) { $this->iIconDepth=$aDepth; } // Specify graph angle 0-360 degrees. function SetAngle($aAngle) { $this->img->SetAngle($aAngle); } function SetAlphaBlending($aFlg=true) { $this->img->SetAlphaBlending($aFlg); } // Shortcut to image margin function SetMargin($lm,$rm,$tm,$bm) { $this->img->SetMargin($lm,$rm,$tm,$bm); } function SetY2OrderBack($aBack=true) { $this->y2orderback = $aBack; } // Rotate the graph 90 degrees and set the margin // when we have done a 90 degree rotation function Set90AndMargin($lm=0,$rm=0,$tm=0,$bm=0) { $lm = $lm ==0 ? floor(0.2 * $this->img->width) : $lm ; $rm = $rm ==0 ? floor(0.1 * $this->img->width) : $rm ; $tm = $tm ==0 ? floor(0.2 * $this->img->height) : $tm ; $bm = $bm ==0 ? floor(0.1 * $this->img->height) : $bm ; $adj = ($this->img->height - $this->img->width)/2; $this->img->SetMargin($tm-$adj,$bm-$adj,$rm+$adj,$lm+$adj); $this->img->SetCenter(floor($this->img->width/2),floor($this->img->height/2)); $this->SetAngle(90); if( empty($this->yaxis) || empty($this->xaxis) ) { JpgraphError::RaiseL(25009);//('You must specify what scale to use with a call to Graph::SetScale()'); } $this->xaxis->SetLabelAlign('right','center'); $this->yaxis->SetLabelAlign('center','bottom'); } function SetClipping($aFlg=true) { $this->iDoClipping = $aFlg ; } // Add a plot object to the graph function Add($aPlot) { if( $aPlot == null ) { JpGraphError::RaiseL(25010);//("Graph::Add() You tried to add a null plot to the graph."); } if( is_array($aPlot) && count($aPlot) > 0 ) { $cl = $aPlot[0]; } else { $cl = $aPlot; } if( $cl instanceof Text ) $this->AddText($aPlot); elseif( class_exists('PlotLine',false) && ($cl instanceof PlotLine) ) $this->AddLine($aPlot); elseif( class_exists('PlotBand',false) && ($cl instanceof PlotBand) ) $this->AddBand($aPlot); elseif( class_exists('IconPlot',false) && ($cl instanceof IconPlot) ) $this->AddIcon($aPlot); elseif( class_exists('GTextTable',false) && ($cl instanceof GTextTable) ) $this->AddTable($aPlot); else { if( is_array($aPlot) ) { $this->plots = array_merge($this->plots,$aPlot); } else { $this->plots[] = $aPlot; } } } function AddTable($aTable) { if( is_array($aTable) ) { for($i=0; $i < count($aTable); ++$i ) { $this->iTables[]=$aTable[$i]; } } else { $this->iTables[] = $aTable ; } } function AddIcon($aIcon) { if( is_array($aIcon) ) { for($i=0; $i < count($aIcon); ++$i ) { $this->iIcons[]=$aIcon[$i]; } } else { $this->iIcons[] = $aIcon ; } } // Add plot to second Y-scale function AddY2($aPlot) { if( $aPlot == null ) { JpGraphError::RaiseL(25011);//("Graph::AddY2() You tried to add a null plot to the graph."); } if( is_array($aPlot) && count($aPlot) > 0 ) { $cl = $aPlot[0]; } else { $cl = $aPlot; } if( $cl instanceof Text ) { $this->AddText($aPlot,true); } elseif( class_exists('PlotLine',false) && ($cl instanceof PlotLine) ) { $this->AddLine($aPlot,true); } elseif( class_exists('PlotBand',false) && ($cl instanceof PlotBand) ) { $this->AddBand($aPlot,true); } else { $this->y2plots[] = $aPlot; } } // Add plot to the extra Y-axises function AddY($aN,$aPlot) { if( $aPlot == null ) { JpGraphError::RaiseL(25012);//("Graph::AddYN() You tried to add a null plot to the graph."); } if( is_array($aPlot) && count($aPlot) > 0 ) { $cl = $aPlot[0]; } else { $cl = $aPlot; } if( ($cl instanceof Text) || (class_exists('PlotLine',false) && ($cl instanceof PlotLine)) || (class_exists('PlotBand',false) && ($cl instanceof PlotBand)) ) { JpGraph::RaiseL(25013);//('You can only add standard plots to multiple Y-axis'); } else { $this->ynplots[$aN][] = $aPlot; } } // Add text object to the graph function AddText($aTxt,$aToY2=false) { if( $aTxt == null ) { JpGraphError::RaiseL(25014);//("Graph::AddText() You tried to add a null text to the graph."); } if( $aToY2 ) { if( is_array($aTxt) ) { for($i=0; $i < count($aTxt); ++$i ) { $this->y2texts[]=$aTxt[$i]; } } else { $this->y2texts[] = $aTxt; } } else { if( is_array($aTxt) ) { for($i=0; $i < count($aTxt); ++$i ) { $this->texts[]=$aTxt[$i]; } } else { $this->texts[] = $aTxt; } } } // Add a line object (class PlotLine) to the graph function AddLine($aLine,$aToY2=false) { if( $aLine == null ) { JpGraphError::RaiseL(25015);//("Graph::AddLine() You tried to add a null line to the graph."); } if( $aToY2 ) { if( is_array($aLine) ) { for($i=0; $i < count($aLine); ++$i ) { //$this->y2lines[]=$aLine[$i]; $this->y2plots[]=$aLine[$i]; } } else { //$this->y2lines[] = $aLine; $this->y2plots[]=$aLine; } } else { if( is_array($aLine) ) { for($i=0; $ilines[]=$aLine[$i]; $this->plots[]=$aLine[$i]; } } else { //$this->lines[] = $aLine; $this->plots[] = $aLine; } } } // Add vertical or horizontal band function AddBand($aBand,$aToY2=false) { if( $aBand == null ) { JpGraphError::RaiseL(25016);//(" Graph::AddBand() You tried to add a null band to the graph."); } if( $aToY2 ) { if( is_array($aBand) ) { for($i=0; $i < count($aBand); ++$i ) { $this->y2bands[] = $aBand[$i]; } } else { $this->y2bands[] = $aBand; } } else { if( is_array($aBand) ) { for($i=0; $i < count($aBand); ++$i ) { $this->bands[] = $aBand[$i]; } } else { $this->bands[] = $aBand; } } } function SetPlotGradient($aFrom='navy',$aTo='silver',$aGradType=2) { $this->plot_gradtype=$aGradType; $this->plot_gradfrom = $aFrom; $this->plot_gradto = $aTo; } function SetBackgroundGradient($aFrom='navy',$aTo='silver',$aGradType=2,$aStyle=BGRAD_FRAME) { $this->bkg_gradtype=$aGradType; $this->bkg_gradstyle=$aStyle; $this->bkg_gradfrom = $aFrom; $this->bkg_gradto = $aTo; } // Set a country flag in the background function SetBackgroundCFlag($aName,$aBgType=BGIMG_FILLPLOT,$aMix=100) { $this->background_cflag = $aName; $this->background_cflag_type = $aBgType; $this->background_cflag_mix = $aMix; } // Alias for the above method function SetBackgroundCountryFlag($aName,$aBgType=BGIMG_FILLPLOT,$aMix=100) { $this->background_cflag = $aName; $this->background_cflag_type = $aBgType; $this->background_cflag_mix = $aMix; } // Specify a background image function SetBackgroundImage($aFileName,$aBgType=BGIMG_FILLPLOT,$aImgFormat='auto') { // Get extension to determine image type if( $aImgFormat == 'auto' ) { $e = explode('.',$aFileName); if( !$e ) { JpGraphError::RaiseL(25018,$aFileName);//('Incorrect file name for Graph::SetBackgroundImage() : '.$aFileName.' Must have a valid image extension (jpg,gif,png) when using autodetection of image type'); } $valid_formats = array('png', 'jpg', 'gif'); $aImgFormat = strtolower($e[count($e)-1]); if ($aImgFormat == 'jpeg') { $aImgFormat = 'jpg'; } elseif (!in_array($aImgFormat, $valid_formats) ) { JpGraphError::RaiseL(25019,$aImgFormat);//('Unknown file extension ($aImgFormat) in Graph::SetBackgroundImage() for filename: '.$aFileName); } } $this->background_image = $aFileName; $this->background_image_type=$aBgType; $this->background_image_format=$aImgFormat; } function SetBackgroundImageMix($aMix) { $this->background_image_mix = $aMix ; } // Adjust background image position function SetBackgroundImagePos($aXpos,$aYpos) { $this->background_image_xpos = $aXpos ; $this->background_image_ypos = $aYpos ; } // Specify axis style (boxed or single) function SetAxisStyle($aStyle) { $this->iAxisStyle = $aStyle ; } // Set a frame around the plot area function SetBox($aDrawPlotFrame=true,$aPlotFrameColor=array(0,0,0),$aPlotFrameWeight=1) { $this->boxed = $aDrawPlotFrame; $this->box_weight = $aPlotFrameWeight; $this->box_color = $aPlotFrameColor; } // Specify color for the plotarea (not the margins) function SetColor($aColor) { $this->plotarea_color=$aColor; } // Specify color for the margins (all areas outside the plotarea) function SetMarginColor($aColor) { $this->margin_color=$aColor; } // Set a frame around the entire image function SetFrame($aDrawImgFrame=true,$aImgFrameColor=array(0,0,0),$aImgFrameWeight=1) { $this->doframe = $aDrawImgFrame; $this->frame_color = $aImgFrameColor; $this->frame_weight = $aImgFrameWeight; } function SetFrameBevel($aDepth=3,$aBorder=false,$aBorderColor='black',$aColor1='white@0.4',$aColor2='darkgray@0.4',$aFlg=true) { $this->framebevel = $aFlg ; $this->framebeveldepth = $aDepth ; $this->framebevelborder = $aBorder ; $this->framebevelbordercolor = $aBorderColor ; $this->framebevelcolor1 = $aColor1 ; $this->framebevelcolor2 = $aColor2 ; $this->doshadow = false ; } // Set the shadow around the whole image function SetShadow($aShowShadow=true,$aShadowWidth=5,$aShadowColor='darkgray') { $this->doshadow = $aShowShadow; $this->shadow_color = $aShadowColor; $this->shadow_width = $aShadowWidth; $this->footer->iBottomMargin += $aShadowWidth; $this->footer->iRightMargin += $aShadowWidth; } // Specify x,y scale. Note that if you manually specify the scale // you must also specify the tick distance with a call to Ticks::Set() function SetScale($aAxisType,$aYMin=1,$aYMax=1,$aXMin=1,$aXMax=1) { $this->axtype = $aAxisType; if( $aYMax < $aYMin || $aXMax < $aXMin ) { JpGraphError::RaiseL(25020);//('Graph::SetScale(): Specified Max value must be larger than the specified Min value.'); } $yt=substr($aAxisType,-3,3); if( $yt == 'lin' ) { $this->yscale = new LinearScale($aYMin,$aYMax); } elseif( $yt == 'int' ) { $this->yscale = new LinearScale($aYMin,$aYMax); $this->yscale->SetIntScale(); } elseif( $yt == 'log' ) { $this->yscale = new LogScale($aYMin,$aYMax); } else { JpGraphError::RaiseL(25021,$aAxisType);//("Unknown scale specification for Y-scale. ($aAxisType)"); } $xt=substr($aAxisType,0,3); if( $xt == 'lin' || $xt == 'tex' ) { $this->xscale = new LinearScale($aXMin,$aXMax,'x'); $this->xscale->textscale = ($xt == 'tex'); } elseif( $xt == 'int' ) { $this->xscale = new LinearScale($aXMin,$aXMax,'x'); $this->xscale->SetIntScale(); } elseif( $xt == 'dat' ) { $this->xscale = new DateScale($aXMin,$aXMax,'x'); } elseif( $xt == 'log' ) { $this->xscale = new LogScale($aXMin,$aXMax,'x'); } else { JpGraphError::RaiseL(25022,$aAxisType);//(" Unknown scale specification for X-scale. ($aAxisType)"); } $this->xaxis = new Axis($this->img,$this->xscale); $this->yaxis = new Axis($this->img,$this->yscale); $this->xgrid = new Grid($this->xaxis); $this->ygrid = new Grid($this->yaxis); $this->ygrid->Show(); } // Specify secondary Y scale function SetY2Scale($aAxisType='lin',$aY2Min=1,$aY2Max=1) { if( $aAxisType == 'lin' ) { $this->y2scale = new LinearScale($aY2Min,$aY2Max); } elseif( $aAxisType == 'int' ) { $this->y2scale = new LinearScale($aY2Min,$aY2Max); $this->y2scale->SetIntScale(); } elseif( $aAxisType == 'log' ) { $this->y2scale = new LogScale($aY2Min,$aY2Max); } else { JpGraphError::RaiseL(25023,$aAxisType);//("JpGraph: Unsupported Y2 axis type: $aAxisType\nMust be one of (lin,log,int)"); } $this->y2axis = new Axis($this->img,$this->y2scale); $this->y2axis->scale->ticks->SetDirection(SIDE_LEFT); $this->y2axis->SetLabelSide(SIDE_RIGHT); $this->y2axis->SetPos('max'); $this->y2axis->SetTitleSide(SIDE_RIGHT); // Deafult position is the max x-value $this->y2grid = new Grid($this->y2axis); } // Set the delta position (in pixels) between the multiple Y-axis function SetYDeltaDist($aDist) { $this->iYAxisDeltaPos = $aDist; } // Specify secondary Y scale function SetYScale($aN,$aAxisType="lin",$aYMin=1,$aYMax=1) { if( $aAxisType == 'lin' ) { $this->ynscale[$aN] = new LinearScale($aYMin,$aYMax); } elseif( $aAxisType == 'int' ) { $this->ynscale[$aN] = new LinearScale($aYMin,$aYMax); $this->ynscale[$aN]->SetIntScale(); } elseif( $aAxisType == 'log' ) { $this->ynscale[$aN] = new LogScale($aYMin,$aYMax); } else { JpGraphError::RaiseL(25024,$aAxisType);//("JpGraph: Unsupported Y axis type: $aAxisType\nMust be one of (lin,log,int)"); } $this->ynaxis[$aN] = new Axis($this->img,$this->ynscale[$aN]); $this->ynaxis[$aN]->scale->ticks->SetDirection(SIDE_LEFT); $this->ynaxis[$aN]->SetLabelSide(SIDE_RIGHT); } // Specify density of ticks when autoscaling 'normal', 'dense', 'sparse', 'verysparse' // The dividing factor have been determined heuristically according to my aesthetic // sense (or lack off) y.m.m.v ! function SetTickDensity($aYDensity=TICKD_NORMAL,$aXDensity=TICKD_NORMAL) { $this->xtick_factor=30; $this->ytick_factor=25; switch( $aYDensity ) { case TICKD_DENSE: $this->ytick_factor=12; break; case TICKD_NORMAL: $this->ytick_factor=25; break; case TICKD_SPARSE: $this->ytick_factor=40; break; case TICKD_VERYSPARSE: $this->ytick_factor=100; break; default: JpGraphError::RaiseL(25025,$densy);//("JpGraph: Unsupported Tick density: $densy"); } switch( $aXDensity ) { case TICKD_DENSE: $this->xtick_factor=15; break; case TICKD_NORMAL: $this->xtick_factor=30; break; case TICKD_SPARSE: $this->xtick_factor=45; break; case TICKD_VERYSPARSE: $this->xtick_factor=60; break; default: JpGraphError::RaiseL(25025,$densx);//("JpGraph: Unsupported Tick density: $densx"); } } // Get a string of all image map areas function GetCSIMareas() { if( !$this->iHasStroked ) { $this->Stroke(_CSIM_SPECIALFILE); } $csim = $this->title->GetCSIMAreas(); $csim .= $this->subtitle->GetCSIMAreas(); $csim .= $this->subsubtitle->GetCSIMAreas(); $csim .= $this->legend->GetCSIMAreas(); if( $this->y2axis != NULL ) { $csim .= $this->y2axis->title->GetCSIMAreas(); } if( $this->texts != null ) { $n = count($this->texts); for($i=0; $i < $n; ++$i ) { $csim .= $this->texts[$i]->GetCSIMAreas(); } } if( $this->y2texts != null && $this->y2scale != null ) { $n = count($this->y2texts); for($i=0; $i < $n; ++$i ) { $csim .= $this->y2texts[$i]->GetCSIMAreas(); } } if( $this->yaxis != null && $this->xaxis != null ) { $csim .= $this->yaxis->title->GetCSIMAreas(); $csim .= $this->xaxis->title->GetCSIMAreas(); } $n = count($this->plots); for( $i=0; $i < $n; ++$i ) { $csim .= $this->plots[$i]->GetCSIMareas(); } $n = count($this->y2plots); for( $i=0; $i < $n; ++$i ) { $csim .= $this->y2plots[$i]->GetCSIMareas(); } $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { $m = count($this->ynplots[$i]); for($j=0; $j < $m; ++$j ) { $csim .= $this->ynplots[$i][$j]->GetCSIMareas(); } } $n = count($this->iTables); for( $i=0; $i < $n; ++$i ) { $csim .= $this->iTables[$i]->GetCSIMareas(); } return $csim; } // Get a complete .. tag for the final image map function GetHTMLImageMap($aMapName) { $im = "\n"; $im .= $this->GetCSIMareas(); $im .= ""; return $im; } function CheckCSIMCache($aCacheName,$aTimeOut=60) { global $_SERVER; if( $aCacheName=='auto' ) { $aCacheName=basename($_SERVER['PHP_SELF']); } $urlarg = $this->GetURLArguments(); $this->csimcachename = CSIMCACHE_DIR.$aCacheName.$urlarg; $this->csimcachetimeout = $aTimeOut; // First determine if we need to check for a cached version // This differs from the standard cache in the sense that the // image and CSIM map HTML file is written relative to the directory // the script executes in and not the specified cache directory. // The reason for this is that the cache directory is not necessarily // accessible from the HTTP server. if( $this->csimcachename != '' ) { $dir = dirname($this->csimcachename); $base = basename($this->csimcachename); $base = strtok($base,'.'); $suffix = strtok('.'); $basecsim = $dir.'/'.$base.'?'.$urlarg.'_csim_.html'; $baseimg = $dir.'/'.$base.'?'.$urlarg.'.'.$this->img->img_format; $timedout=false; // Does it exist at all ? if( file_exists($basecsim) && file_exists($baseimg) ) { // Check that it hasn't timed out $diff=time()-filemtime($basecsim); if( $this->csimcachetimeout>0 && ($diff > $this->csimcachetimeout*60) ) { $timedout=true; @unlink($basecsim); @unlink($baseimg); } else { if ($fh = @fopen($basecsim, "r")) { fpassthru($fh); return true; } else { JpGraphError::RaiseL(25027,$basecsim);//(" Can't open cached CSIM \"$basecsim\" for reading."); } } } } return false; } // Build the argument string to be used with the csim images static function GetURLArguments($aAddRecursiveBlocker=false) { if( $aAddRecursiveBlocker ) { // This is a JPGRAPH internal defined that prevents // us from recursively coming here again $urlarg = _CSIM_DISPLAY.'=1'; } // Now reconstruct any user URL argument reset($_GET); while( list($key,$value) = each($_GET) ) { if( is_array($value) ) { foreach ( $value as $k => $v ) { $urlarg .= '&'.$key.'%5B'.$k.'%5D='.urlencode($v); } } else { $urlarg .= '&'.$key.'='.urlencode($value); } } // It's not ideal to convert POST argument to GET arguments // but there is little else we can do. One idea for the // future might be recreate the POST header in case. reset($_POST); while( list($key,$value) = each($_POST) ) { if( is_array($value) ) { foreach ( $value as $k => $v ) { $urlarg .= '&'.$key.'%5B'.$k.'%5D='.urlencode($v); } } else { $urlarg .= '&'.$key.'='.urlencode($value); } } return $urlarg; } function SetCSIMImgAlt($aAlt) { $this->iCSIMImgAlt = $aAlt; } function StrokeCSIM($aScriptName='auto',$aCSIMName='',$aBorder=0) { if( $aCSIMName=='' ) { // create a random map name srand ((double) microtime() * 1000000); $r = rand(0,100000); $aCSIMName='__mapname'.$r.'__'; } if( $aScriptName=='auto' ) { $aScriptName=basename($_SERVER['PHP_SELF']); } $urlarg = $this->GetURLArguments(true); if( empty($_GET[_CSIM_DISPLAY]) ) { // First determine if we need to check for a cached version // This differs from the standard cache in the sense that the // image and CSIM map HTML file is written relative to the directory // the script executes in and not the specified cache directory. // The reason for this is that the cache directory is not necessarily // accessible from the HTTP server. if( $this->csimcachename != '' ) { $dir = dirname($this->csimcachename); $base = basename($this->csimcachename); $base = strtok($base,'.'); $suffix = strtok('.'); $basecsim = $dir.'/'.$base.'?'.$urlarg.'_csim_.html'; $baseimg = $base.'?'.$urlarg.'.'.$this->img->img_format; // Check that apache can write to directory specified if( file_exists($dir) && !is_writeable($dir) ) { JpgraphError::RaiseL(25028,$dir);//('Apache/PHP does not have permission to write to the CSIM cache directory ('.$dir.'). Check permissions.'); } // Make sure directory exists $this->cache->MakeDirs($dir); // Write the image file $this->Stroke(CSIMCACHE_DIR.$baseimg); // Construct wrapper HTML and write to file and send it back to browser // In the src URL we must replace the '?' with its encoding to prevent the arguments // to be converted to real arguments. $tmp = str_replace('?','%3f',$baseimg); $htmlwrap = $this->GetHTMLImageMap($aCSIMName)."\n". 'img->width.'" height="'.$this->img->height."\" alt=\"".$this->iCSIMImgAlt."\" />\n"; if($fh = @fopen($basecsim,'w') ) { fwrite($fh,$htmlwrap); fclose($fh); echo $htmlwrap; } else { JpGraphError::RaiseL(25029,$basecsim);//(" Can't write CSIM \"$basecsim\" for writing. Check free space and permissions."); } } else { if( $aScriptName=='' ) { JpGraphError::RaiseL(25030);//('Missing script name in call to StrokeCSIM(). You must specify the name of the actual image script as the first parameter to StrokeCSIM().'); } echo $this->GetHTMLImageMap($aCSIMName) . $this->GetCSIMImgHTML($aCSIMName, $aScriptName, $aBorder); } } else { $this->Stroke(); } } function StrokeCSIMImage() { if( @$_GET[_CSIM_DISPLAY] == 1 ) { $this->Stroke(); } } function GetCSIMImgHTML($aCSIMName, $aScriptName='auto', $aBorder=0 ) { if( $aScriptName=='auto' ) { $aScriptName=basename($_SERVER['PHP_SELF']); } $urlarg = $this->GetURLArguments(true); return "\"".$this-iCSIMImgAlt."\" />\n"; } function GetTextsYMinMax($aY2=false) { if( $aY2 ) { $txts = $this->y2texts; } else { $txts = $this->texts; } $n = count($txts); $min=null; $max=null; for( $i=0; $i < $n; ++$i ) { if( $txts[$i]->iScalePosY !== null && $txts[$i]->iScalePosX !== null ) { if( $min === null ) { $min = $max = $txts[$i]->iScalePosY ; } else { $min = min($min,$txts[$i]->iScalePosY); $max = max($max,$txts[$i]->iScalePosY); } } } if( $min !== null ) { return array($min,$max); } else { return null; } } function GetTextsXMinMax($aY2=false) { if( $aY2 ) { $txts = $this->y2texts; } else { $txts = $this->texts; } $n = count($txts); $min=null; $max=null; for( $i=0; $i < $n; ++$i ) { if( $txts[$i]->iScalePosY !== null && $txts[$i]->iScalePosX !== null ) { if( $min === null ) { $min = $max = $txts[$i]->iScalePosX ; } else { $min = min($min,$txts[$i]->iScalePosX); $max = max($max,$txts[$i]->iScalePosX); } } } if( $min !== null ) { return array($min,$max); } else { return null; } } function GetXMinMax() { list($min,$ymin) = $this->plots[0]->Min(); list($max,$ymax) = $this->plots[0]->Max(); $i=0; // Some plots, e.g. PlotLine should not affect the scale // and will return (null,null). We should ignore those // values. while( ($min===null || $max === null) && ($i < count($this->plots)-1) ) { ++$i; list($min,$ymin) = $this->plots[$i]->Min(); list($max,$ymax) = $this->plots[$i]->Max(); } foreach( $this->plots as $p ) { list($xmin,$ymin) = $p->Min(); list($xmax,$ymax) = $p->Max(); if( $xmin !== null && $xmax !== null ) { $min = Min($xmin,$min); $max = Max($xmax,$max); } } if( $this->y2axis != null ) { foreach( $this->y2plots as $p ) { list($xmin,$ymin) = $p->Min(); list($xmax,$ymax) = $p->Max(); $min = Min($xmin,$min); $max = Max($xmax,$max); } } $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { if( $this->ynaxis[$i] != null) { foreach( $this->ynplots[$i] as $p ) { list($xmin,$ymin) = $p->Min(); list($xmax,$ymax) = $p->Max(); $min = Min($xmin,$min); $max = Max($xmax,$max); } } } return array($min,$max); } function AdjustMarginsForTitles() { $totrequired = ($this->title->t != '' ? $this->title->GetTextHeight($this->img) + $this->title->margin + 5 : 0 ) + ($this->subtitle->t != '' ? $this->subtitle->GetTextHeight($this->img) + $this->subtitle->margin + 5 : 0 ) + ($this->subsubtitle->t != '' ? $this->subsubtitle->GetTextHeight($this->img) + $this->subsubtitle->margin + 5 : 0 ) ; $btotrequired = 0; if($this->xaxis != null && !$this->xaxis->hide && !$this->xaxis->hide_labels ) { // Minimum bottom margin if( $this->xaxis->title->t != '' ) { if( $this->img->a == 90 ) { $btotrequired = $this->yaxis->title->GetTextHeight($this->img) + 7 ; } else { $btotrequired = $this->xaxis->title->GetTextHeight($this->img) + 7 ; } } else { $btotrequired = 0; } if( $this->img->a == 90 ) { $this->img->SetFont($this->yaxis->font_family,$this->yaxis->font_style, $this->yaxis->font_size); $lh = $this->img->GetTextHeight('Mg',$this->yaxis->label_angle); } else { $this->img->SetFont($this->xaxis->font_family,$this->xaxis->font_style, $this->xaxis->font_size); $lh = $this->img->GetTextHeight('Mg',$this->xaxis->label_angle); } $btotrequired += $lh + 6; } if( $this->img->a == 90 ) { // DO Nothing. It gets too messy to do this properly for 90 deg... } else{ if( $this->img->top_margin < $totrequired ) { $this->SetMargin($this->img->left_margin,$this->img->right_margin, $totrequired,$this->img->bottom_margin); } if( $this->img->bottom_margin < $btotrequired ) { $this->SetMargin($this->img->left_margin,$this->img->right_margin, $this->img->top_margin,$btotrequired); } } } function StrokeStore($aStrokeFileName) { // Get the handler to prevent the library from sending the // image to the browser $ih = $this->Stroke(_IMG_HANDLER); // Stroke it to a file $this->img->Stream($aStrokeFileName); // Send it back to browser $this->img->Headers(); $this->img->Stream(); } function doAutoscaleXAxis() { //Check if we should autoscale x-axis if( !$this->xscale->IsSpecified() ) { if( substr($this->axtype,0,4) == "text" ) { $max=0; $n = count($this->plots); for($i=0; $i < $n; ++$i ) { $p = $this->plots[$i]; // We need some unfortunate sub class knowledge here in order // to increase number of data points in case it is a line plot // which has the barcenter set. If not it could mean that the // last point of the data is outside the scale since the barcenter // settings means that we will shift the entire plot half a tick step // to the right in oder to align with the center of the bars. if( class_exists('BarPlot',false) ) { $cl = strtolower(get_class($p)); if( (class_exists('BarPlot',false) && ($p instanceof BarPlot)) || empty($p->barcenter) ) { $max=max($max,$p->numpoints-1); } else { $max=max($max,$p->numpoints); } } else { if( empty($p->barcenter) ) { $max=max($max,$p->numpoints-1); } else { $max=max($max,$p->numpoints); } } } $min=0; if( $this->y2axis != null ) { foreach( $this->y2plots as $p ) { $max=max($max,$p->numpoints-1); } } $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { if( $this->ynaxis[$i] != null) { foreach( $this->ynplots[$i] as $p ) { $max=max($max,$p->numpoints-1); } } } $this->xscale->Update($this->img,$min,$max); $this->xscale->ticks->Set($this->xaxis->tick_step,1); $this->xscale->ticks->SupressMinorTickMarks(); } else { list($min,$max) = $this->GetXMinMax(); $lres = $this->GetLinesXMinMax($this->lines); if( $lres ) { list($linmin,$linmax) = $lres ; $min = min($min,$linmin); $max = max($max,$linmax); } $lres = $this->GetLinesXMinMax($this->y2lines); if( $lres ) { list($linmin,$linmax) = $lres ; $min = min($min,$linmin); $max = max($max,$linmax); } $tres = $this->GetTextsXMinMax(); if( $tres ) { list($tmin,$tmax) = $tres ; $min = min($min,$tmin); $max = max($max,$tmax); } $tres = $this->GetTextsXMinMax(true); if( $tres ) { list($tmin,$tmax) = $tres ; $min = min($min,$tmin); $max = max($max,$tmax); } $this->xscale->AutoScale($this->img,$min,$max,round($this->img->plotwidth/$this->xtick_factor)); } //Adjust position of y-axis and y2-axis to minimum/maximum of x-scale if( !is_numeric($this->yaxis->pos) && !is_string($this->yaxis->pos) ) { $this->yaxis->SetPos($this->xscale->GetMinVal()); } } elseif( $this->xscale->IsSpecified() && ( $this->xscale->auto_ticks || !$this->xscale->ticks->IsSpecified()) ) { // The tick calculation will use the user suplied min/max values to determine // the ticks. If auto_ticks is false the exact user specifed min and max // values will be used for the scale. // If auto_ticks is true then the scale might be slightly adjusted // so that the min and max values falls on an even major step. $min = $this->xscale->scale[0]; $max = $this->xscale->scale[1]; $this->xscale->AutoScale($this->img,$min,$max,round($this->img->plotwidth/$this->xtick_factor),false); // Now make sure we show enough precision to accurate display the // labels. If this is not done then the user might end up with // a scale that might actually start with, say 13.5, butdue to rounding // the scale label will ony show 14. if( abs(floor($min)-$min) > 0 ) { // If the user has set a format then we bail out if( $this->xscale->ticks->label_formatstr == '' && $this->xscale->ticks->label_dateformatstr == '' ) { $this->xscale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; } } } // Position the optional Y2 and Yn axis to the rightmost position of the x-axis if( $this->y2axis != null ) { if( !is_numeric($this->y2axis->pos) && !is_string($this->y2axis->pos) ) { $this->y2axis->SetPos($this->xscale->GetMaxVal()); } $this->y2axis->SetTitleSide(SIDE_RIGHT); } $n = count($this->ynaxis); $nY2adj = $this->y2axis != null ? $this->iYAxisDeltaPos : 0; for( $i=0; $i < $n; ++$i ) { if( $this->ynaxis[$i] != null ) { if( !is_numeric($this->ynaxis[$i]->pos) && !is_string($this->ynaxis[$i]->pos) ) { $this->ynaxis[$i]->SetPos($this->xscale->GetMaxVal()); $this->ynaxis[$i]->SetPosAbsDelta($i*$this->iYAxisDeltaPos + $nY2adj); } $this->ynaxis[$i]->SetTitleSide(SIDE_RIGHT); } } } function doAutoScaleYnAxis() { if( $this->y2scale != null) { if( !$this->y2scale->IsSpecified() && count($this->y2plots)>0 ) { list($min,$max) = $this->GetPlotsYMinMax($this->y2plots); $lres = $this->GetLinesYMinMax($this->y2lines); if( is_array($lres) ) { list($linmin,$linmax) = $lres ; $min = min($min,$linmin); $max = max($max,$linmax); } $tres = $this->GetTextsYMinMax(true); if( is_array($tres) ) { list($tmin,$tmax) = $tres ; $min = min($min,$tmin); $max = max($max,$tmax); } $this->y2scale->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor); } elseif( $this->y2scale->IsSpecified() && ( $this->y2scale->auto_ticks || !$this->y2scale->ticks->IsSpecified()) ) { // The tick calculation will use the user suplied min/max values to determine // the ticks. If auto_ticks is false the exact user specifed min and max // values will be used for the scale. // If auto_ticks is true then the scale might be slightly adjusted // so that the min and max values falls on an even major step. $min = $this->y2scale->scale[0]; $max = $this->y2scale->scale[1]; $this->y2scale->AutoScale($this->img,$min,$max, $this->img->plotheight/$this->ytick_factor, $this->y2scale->auto_ticks); // Now make sure we show enough precision to accurate display the // labels. If this is not done then the user might end up with // a scale that might actually start with, say 13.5, butdue to rounding // the scale label will ony show 14. if( abs(floor($min)-$min) > 0 ) { // If the user has set a format then we bail out if( $this->y2scale->ticks->label_formatstr == '' && $this->y2scale->ticks->label_dateformatstr == '' ) { $this->y2scale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; } } } } // // Autoscale the extra Y-axises // $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { if( $this->ynscale[$i] != null) { if( !$this->ynscale[$i]->IsSpecified() && count($this->ynplots[$i])>0 ) { list($min,$max) = $this->GetPlotsYMinMax($this->ynplots[$i]); $this->ynscale[$i]->AutoScale($this->img,$min,$max,$this->img->plotheight/$this->ytick_factor); } elseif( $this->ynscale[$i]->IsSpecified() && ( $this->ynscale[$i]->auto_ticks || !$this->ynscale[$i]->ticks->IsSpecified()) ) { // The tick calculation will use the user suplied min/max values to determine // the ticks. If auto_ticks is false the exact user specifed min and max // values will be used for the scale. // If auto_ticks is true then the scale might be slightly adjusted // so that the min and max values falls on an even major step. $min = $this->ynscale[$i]->scale[0]; $max = $this->ynscale[$i]->scale[1]; $this->ynscale[$i]->AutoScale($this->img,$min,$max, $this->img->plotheight/$this->ytick_factor, $this->ynscale[$i]->auto_ticks); // Now make sure we show enough precision to accurate display the // labels. If this is not done then the user might end up with // a scale that might actually start with, say 13.5, butdue to rounding // the scale label will ony show 14. if( abs(floor($min)-$min) > 0 ) { // If the user has set a format then we bail out if( $this->ynscale[$i]->ticks->label_formatstr == '' && $this->ynscale[$i]->ticks->label_dateformatstr == '' ) { $this->ynscale[$i]->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; } } } } } } function doAutoScaleYAxis() { //Check if we should autoscale y-axis if( !$this->yscale->IsSpecified() && count($this->plots)>0 ) { list($min,$max) = $this->GetPlotsYMinMax($this->plots); $lres = $this->GetLinesYMinMax($this->lines); if( is_array($lres) ) { list($linmin,$linmax) = $lres ; $min = min($min,$linmin); $max = max($max,$linmax); } $tres = $this->GetTextsYMinMax(); if( is_array($tres) ) { list($tmin,$tmax) = $tres ; $min = min($min,$tmin); $max = max($max,$tmax); } $this->yscale->AutoScale($this->img,$min,$max, $this->img->plotheight/$this->ytick_factor); } elseif( $this->yscale->IsSpecified() && ( $this->yscale->auto_ticks || !$this->yscale->ticks->IsSpecified()) ) { // The tick calculation will use the user suplied min/max values to determine // the ticks. If auto_ticks is false the exact user specifed min and max // values will be used for the scale. // If auto_ticks is true then the scale might be slightly adjusted // so that the min and max values falls on an even major step. $min = $this->yscale->scale[0]; $max = $this->yscale->scale[1]; $this->yscale->AutoScale($this->img,$min,$max, $this->img->plotheight/$this->ytick_factor, $this->yscale->auto_ticks); // Now make sure we show enough precision to accurate display the // labels. If this is not done then the user might end up with // a scale that might actually start with, say 13.5, butdue to rounding // the scale label will ony show 14. if( abs(floor($min)-$min) > 0 ) { // If the user has set a format then we bail out if( $this->yscale->ticks->label_formatstr == '' && $this->yscale->ticks->label_dateformatstr == '' ) { $this->yscale->ticks->precision = abs( floor(log10( abs(floor($min)-$min))) )+1; } } } } function InitScaleConstants() { // Setup scale constants if( $this->yscale ) $this->yscale->InitConstants($this->img); if( $this->xscale ) $this->xscale->InitConstants($this->img); if( $this->y2scale ) $this->y2scale->InitConstants($this->img); $n=count($this->ynscale); for($i=0; $i < $n; ++$i) { if( $this->ynscale[$i] ) { $this->ynscale[$i]->InitConstants($this->img); } } } function doPrestrokeAdjustments() { // Do any pre-stroke adjustment that is needed by the different plot types // (i.e bar plots want's to add an offset to the x-labels etc) for($i=0; $i < count($this->plots) ; ++$i ) { $this->plots[$i]->PreStrokeAdjust($this); $this->plots[$i]->DoLegend($this); } // Any plots on the second Y scale? if( $this->y2scale != null ) { for($i=0; $iy2plots) ; ++$i ) { $this->y2plots[$i]->PreStrokeAdjust($this); $this->y2plots[$i]->DoLegend($this); } } // Any plots on the extra Y axises? $n = count($this->ynaxis); for($i=0; $i<$n ; ++$i ) { if( $this->ynplots == null || $this->ynplots[$i] == null) { JpGraphError::RaiseL(25032,$i);//("No plots for Y-axis nbr:$i"); } $m = count($this->ynplots[$i]); for($j=0; $j < $m; ++$j ) { $this->ynplots[$i][$j]->PreStrokeAdjust($this); $this->ynplots[$i][$j]->DoLegend($this); } } } function StrokeBands($aDepth,$aCSIM) { // Stroke bands if( $this->bands != null && !$aCSIM) { for($i=0; $i < count($this->bands); ++$i) { // Stroke all bands that asks to be in the background if( $this->bands[$i]->depth == $aDepth ) { $this->bands[$i]->Stroke($this->img,$this->xscale,$this->yscale); } } } if( $this->y2bands != null && $this->y2scale != null && !$aCSIM ) { for($i=0; $i < count($this->y2bands); ++$i) { // Stroke all bands that asks to be in the foreground if( $this->y2bands[$i]->depth == $aDepth ) { $this->y2bands[$i]->Stroke($this->img,$this->xscale,$this->y2scale); } } } } // Stroke the graph // $aStrokeFileName If != "" the image will be written to this file and NOT // streamed back to the browser function Stroke($aStrokeFileName='') { // Fist make a sanity check that user has specified a scale if( empty($this->yscale) ) { JpGraphError::RaiseL(25031);//('You must specify what scale to use with a call to Graph::SetScale().'); } // Start by adjusting the margin so that potential titles will fit. $this->AdjustMarginsForTitles(); // Give the plot a chance to do any scale adjuments the individual plots // wants to do. Right now this is only used by the contour plot to set scale // limits for($i=0; $i < count($this->plots) ; ++$i ) { $this->plots[$i]->PreScaleSetup($this); } // Init scale constants that are used to calculate the transformation from // world to pixel coordinates $this->InitScaleConstants(); // If the filename is the predefined value = '_csim_special_' // we assume that the call to stroke only needs to do enough // to correctly generate the CSIM maps. // We use this variable to skip things we don't strictly need // to do to generate the image map to improve performance // a best we can. Therefor you will see a lot of tests !$_csim in the // code below. $_csim = ($aStrokeFileName===_CSIM_SPECIALFILE); // If we are called the second time (perhaps the user has called GetHTMLImageMap() // himself then the legends have alsready been populated once in order to get the // CSIM coordinats. Since we do not want the legends to be populated a second time // we clear the legends $this->legend->Clear(); // We need to know if we have stroked the plot in the // GetCSIMareas. Otherwise the CSIM hasn't been generated // and in the case of GetCSIM called before stroke to generate // CSIM without storing an image to disk GetCSIM must call Stroke. $this->iHasStroked = true; // Setup pre-stroked adjustments and Legends $this->doPrestrokeAdjustments(); // Bail out if any of the Y-axis not been specified and // has no plots. (This means it is impossible to do autoscaling and // no other scale was given so we can't possible draw anything). If you use manual // scaling you also have to supply the tick steps as well. if( (!$this->yscale->IsSpecified() && count($this->plots)==0) || ($this->y2scale!=null && !$this->y2scale->IsSpecified() && count($this->y2plots)==0) ) { //$e = "n=".count($this->y2plots)."\n"; // $e = "Can't draw unspecified Y-scale.
    \nYou have either:
    \n"; // $e .= "1. Specified an Y axis for autoscaling but have not supplied any plots
    \n"; // $e .= "2. Specified a scale manually but have forgot to specify the tick steps"; JpGraphError::RaiseL(25026); } // Bail out if no plots and no specified X-scale if( (!$this->xscale->IsSpecified() && count($this->plots)==0 && count($this->y2plots)==0) ) { JpGraphError::RaiseL(25034);//("JpGraph: Can't draw unspecified X-scale.
    No plots.
    "); } // Autoscale the normal Y-axis $this->doAutoScaleYAxis(); // Autoscale all additiopnal y-axis $this->doAutoScaleYnAxis(); // Autoscale the regular x-axis and position the y-axis properly $this->doAutoScaleXAxis(); // If we have a negative values and x-axis position is at 0 // we need to supress the first and possible the last tick since // they will be drawn on top of the y-axis (and possible y2 axis) // The test below might seem strange the reasone being that if // the user hasn't specified a value for position this will not // be set until we do the stroke for the axis so as of now it // is undefined. // For X-text scale we ignore all this since the tick are usually // much further in and not close to the Y-axis. Hence the test // for 'text' if( ($this->yaxis->pos==$this->xscale->GetMinVal() || (is_string($this->yaxis->pos) && $this->yaxis->pos=='min')) && !is_numeric($this->xaxis->pos) && $this->yscale->GetMinVal() < 0 && substr($this->axtype,0,4) != 'text' && $this->xaxis->pos != 'min' ) { //$this->yscale->ticks->SupressZeroLabel(false); $this->xscale->ticks->SupressFirst(); if( $this->y2axis != null ) { $this->xscale->ticks->SupressLast(); } } elseif( !is_numeric($this->yaxis->pos) && $this->yaxis->pos=='max' ) { $this->xscale->ticks->SupressLast(); } if( !$_csim ) { $this->StrokePlotArea(); if( $this->iIconDepth == DEPTH_BACK ) { $this->StrokeIcons(); } } $this->StrokeAxis(false); // Stroke colored bands $this->StrokeBands(DEPTH_BACK,$_csim); if( $this->grid_depth == DEPTH_BACK && !$_csim) { $this->ygrid->Stroke(); $this->xgrid->Stroke(); } // Stroke Y2-axis if( $this->y2axis != null && !$_csim) { $this->y2axis->Stroke($this->xscale); $this->y2grid->Stroke(); } // Stroke yn-axis $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { $this->ynaxis[$i]->Stroke($this->xscale); } $oldoff=$this->xscale->off; if( substr($this->axtype,0,4) == 'text' ) { if( $this->text_scale_abscenteroff > -1 ) { // For a text scale the scale factor is the number of pixel per step. // Hence we can use the scale factor as a substitute for number of pixels // per major scale step and use that in order to adjust the offset so that // an object of width "abscenteroff" becomes centered. $this->xscale->off += round($this->xscale->scale_factor/2)-round($this->text_scale_abscenteroff/2); } else { $this->xscale->off += ceil($this->xscale->scale_factor*$this->text_scale_off*$this->xscale->ticks->minor_step); } } if( $this->iDoClipping ) { $oldimage = $this->img->CloneCanvasH(); } if( ! $this->y2orderback ) { // Stroke all plots for Y1 axis for($i=0; $i < count($this->plots); ++$i) { $this->plots[$i]->Stroke($this->img,$this->xscale,$this->yscale); $this->plots[$i]->StrokeMargin($this->img); } } // Stroke all plots for Y2 axis if( $this->y2scale != null ) { for($i=0; $i< count($this->y2plots); ++$i ) { $this->y2plots[$i]->Stroke($this->img,$this->xscale,$this->y2scale); } } if( $this->y2orderback ) { // Stroke all plots for Y1 axis for($i=0; $i < count($this->plots); ++$i) { $this->plots[$i]->Stroke($this->img,$this->xscale,$this->yscale); $this->plots[$i]->StrokeMargin($this->img); } } $n = count($this->ynaxis); for( $i=0; $i < $n; ++$i ) { $m = count($this->ynplots[$i]); for( $j=0; $j < $m; ++$j ) { $this->ynplots[$i][$j]->Stroke($this->img,$this->xscale,$this->ynscale[$i]); $this->ynplots[$i][$j]->StrokeMargin($this->img); } } if( $this->iIconDepth == DEPTH_FRONT) { $this->StrokeIcons(); } if( $this->iDoClipping ) { // Clipping only supports graphs at 0 and 90 degrees if( $this->img->a == 0 ) { $this->img->CopyCanvasH($oldimage,$this->img->img, $this->img->left_margin,$this->img->top_margin, $this->img->left_margin,$this->img->top_margin, $this->img->plotwidth+1,$this->img->plotheight); } elseif( $this->img->a == 90 ) { $adj = ($this->img->height - $this->img->width)/2; $this->img->CopyCanvasH($oldimage,$this->img->img, $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, $this->img->plotheight+1,$this->img->plotwidth); } else { JpGraphError::RaiseL(25035,$this->img->a);//('You have enabled clipping. Cliping is only supported for graphs at 0 or 90 degrees rotation. Please adjust you current angle (='.$this->img->a.' degrees) or disable clipping.'); } $this->img->Destroy(); $this->img->SetCanvasH($oldimage); } $this->xscale->off=$oldoff; if( $this->grid_depth == DEPTH_FRONT && !$_csim ) { $this->ygrid->Stroke(); $this->xgrid->Stroke(); } // Stroke colored bands $this->StrokeBands(DEPTH_FRONT,$_csim); // Finally draw the axis again since some plots may have nagged // the axis in the edges. if( !$_csim ) { $this->StrokeAxis(); } if( $this->y2scale != null && !$_csim ) { $this->y2axis->Stroke($this->xscale,false); } if( !$_csim ) { $this->StrokePlotBox(); } // The titles and legends never gets rotated so make sure // that the angle is 0 before stroking them $aa = $this->img->SetAngle(0); $this->StrokeTitles(); $this->footer->Stroke($this->img); $this->legend->Stroke($this->img); $this->img->SetAngle($aa); $this->StrokeTexts(); $this->StrokeTables(); if( !$_csim ) { $this->img->SetAngle($aa); // Draw an outline around the image map if(_JPG_DEBUG) { $this->DisplayClientSideaImageMapAreas(); } // Should we do any final image transformation if( $this->iImgTrans ) { if( !class_exists('ImgTrans',false) ) { require_once('jpgraph_imgtrans.php'); //JpGraphError::Raise('In order to use image transformation you must include the file jpgraph_imgtrans.php in your script.'); } $tform = new ImgTrans($this->img->img); $this->img->img = $tform->Skew3D($this->iImgTransHorizon,$this->iImgTransSkewDist, $this->iImgTransDirection,$this->iImgTransHighQ, $this->iImgTransMinSize,$this->iImgTransFillColor, $this->iImgTransBorder); } // If the filename is given as the special "__handle" // then the image handler is returned and the image is NOT // streamed back if( $aStrokeFileName == _IMG_HANDLER ) { return $this->img->img; } else { // Finally stream the generated picture $this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName); } } } function SetAxisLabelBackground($aType,$aXFColor='lightgray',$aXColor='black',$aYFColor='lightgray',$aYColor='black') { $this->iAxisLblBgType = $aType; $this->iXAxisLblBgFillColor = $aXFColor; $this->iXAxisLblBgColor = $aXColor; $this->iYAxisLblBgFillColor = $aYFColor; $this->iYAxisLblBgColor = $aYColor; } function StrokeAxisLabelBackground() { // Types // 0 = No background // 1 = Only X-labels, length of axis // 2 = Only Y-labels, length of axis // 3 = As 1 but extends to width of graph // 4 = As 2 but extends to height of graph // 5 = Combination of 3 & 4 // 6 = Combination of 1 & 2 $t = $this->iAxisLblBgType ; if( $t < 1 ) return; // Stroke optional X-axis label background color if( $t == 1 || $t == 3 || $t == 5 || $t == 6 ) { $this->img->PushColor($this->iXAxisLblBgFillColor); if( $t == 1 || $t == 6 ) { $xl = $this->img->left_margin; $yu = $this->img->height - $this->img->bottom_margin + 1; $xr = $this->img->width - $this->img->right_margin ; $yl = $this->img->height-1-$this->frame_weight; } else { // t==3 || t==5 $xl = $this->frame_weight; $yu = $this->img->height - $this->img->bottom_margin + 1; $xr = $this->img->width - 1 - $this->frame_weight; $yl = $this->img->height-1-$this->frame_weight; } $this->img->FilledRectangle($xl,$yu,$xr,$yl); $this->img->PopColor(); // Check if we should add the vertical lines at left and right edge if( $this->iXAxisLblBgColor !== '' ) { // Hardcode to one pixel wide $this->img->SetLineWeight(1); $this->img->PushColor($this->iXAxisLblBgColor); if( $t == 1 || $t == 6 ) { $this->img->Line($xl,$yu,$xl,$yl); $this->img->Line($xr,$yu,$xr,$yl); } else { $xl = $this->img->width - $this->img->right_margin ; $this->img->Line($xl,$yu-1,$xr,$yu-1); } $this->img->PopColor(); } } if( $t == 2 || $t == 4 || $t == 5 || $t == 6 ) { $this->img->PushColor($this->iYAxisLblBgFillColor); if( $t == 2 || $t == 6 ) { $xl = $this->frame_weight; $yu = $this->frame_weight+$this->img->top_margin; $xr = $this->img->left_margin - 1; $yl = $this->img->height - $this->img->bottom_margin + 1; } else { $xl = $this->frame_weight; $yu = $this->frame_weight; $xr = $this->img->left_margin - 1; $yl = $this->img->height-1-$this->frame_weight; } $this->img->FilledRectangle($xl,$yu,$xr,$yl); $this->img->PopColor(); // Check if we should add the vertical lines at left and right edge if( $this->iXAxisLblBgColor !== '' ) { $this->img->PushColor($this->iXAxisLblBgColor); if( $t == 2 || $t == 6 ) { $this->img->Line($xl,$yu-1,$xr,$yu-1); $this->img->Line($xl,$yl-1,$xr,$yl-1); } else { $this->img->Line($xr+1,$yu,$xr+1,$this->img->top_margin); } $this->img->PopColor(); } } } function StrokeAxis($aStrokeLabels=true) { if( $aStrokeLabels ) { $this->StrokeAxisLabelBackground(); } // Stroke axis if( $this->iAxisStyle != AXSTYLE_SIMPLE ) { switch( $this->iAxisStyle ) { case AXSTYLE_BOXIN : $toppos = SIDE_DOWN; $bottompos = SIDE_UP; $leftpos = SIDE_RIGHT; $rightpos = SIDE_LEFT; break; case AXSTYLE_BOXOUT : $toppos = SIDE_UP; $bottompos = SIDE_DOWN; $leftpos = SIDE_LEFT; $rightpos = SIDE_RIGHT; break; case AXSTYLE_YBOXIN: $toppos = FALSE; $bottompos = SIDE_UP; $leftpos = SIDE_RIGHT; $rightpos = SIDE_LEFT; break; case AXSTYLE_YBOXOUT: $toppos = FALSE; $bottompos = SIDE_DOWN; $leftpos = SIDE_LEFT; $rightpos = SIDE_RIGHT; break; default: JpGRaphError::RaiseL(25036,$this->iAxisStyle); //('Unknown AxisStyle() : '.$this->iAxisStyle); break; } // By default we hide the first label so it doesn't cross the // Y-axis in case the positon hasn't been set by the user. // However, if we use a box we always want the first value // displayed so we make sure it will be displayed. $this->xscale->ticks->SupressFirst(false); // Now draw the bottom X-axis $this->xaxis->SetPos('min'); $this->xaxis->SetLabelSide(SIDE_DOWN); $this->xaxis->scale->ticks->SetSide($bottompos); $this->xaxis->Stroke($this->yscale,$aStrokeLabels); if( $toppos !== FALSE ) { // We also want a top X-axis $this->xaxis = $this->xaxis; $this->xaxis->SetPos('max'); $this->xaxis->SetLabelSide(SIDE_UP); // No title for the top X-axis if( $aStrokeLabels ) { $this->xaxis->title->Set(''); } $this->xaxis->scale->ticks->SetSide($toppos); $this->xaxis->Stroke($this->yscale,$aStrokeLabels); } // Stroke the left Y-axis $this->yaxis->SetPos('min'); $this->yaxis->SetLabelSide(SIDE_LEFT); $this->yaxis->scale->ticks->SetSide($leftpos); $this->yaxis->Stroke($this->xscale,$aStrokeLabels); // Stroke the right Y-axis $this->yaxis->SetPos('max'); // No title for the right side if( $aStrokeLabels ) { $this->yaxis->title->Set(''); } $this->yaxis->SetLabelSide(SIDE_RIGHT); $this->yaxis->scale->ticks->SetSide($rightpos); $this->yaxis->Stroke($this->xscale,$aStrokeLabels); } else { $this->xaxis->Stroke($this->yscale,$aStrokeLabels); $this->yaxis->Stroke($this->xscale,$aStrokeLabels); } } // Private helper function for backgound image static function LoadBkgImage($aImgFormat='',$aFile='',$aImgStr='') { if( $aImgStr != '' ) { return Image::CreateFromString($aImgStr); } // Remove case sensitivity and setup appropriate function to create image // Get file extension. This should be the LAST '.' separated part of the filename $e = explode('.',$aFile); $ext = strtolower($e[count($e)-1]); if ($ext == "jpeg") { $ext = "jpg"; } if( trim($ext) == '' ) { $ext = 'png'; // Assume PNG if no extension specified } if( $aImgFormat == '' ) { $imgtag = $ext; } else { $imgtag = $aImgFormat; } $supported = imagetypes(); if( ( $ext == 'jpg' && !($supported & IMG_JPG) ) || ( $ext == 'gif' && !($supported & IMG_GIF) ) || ( $ext == 'png' && !($supported & IMG_PNG) ) || ( $ext == 'bmp' && !($supported & IMG_WBMP) ) || ( $ext == 'xpm' && !($supported & IMG_XPM) ) ) { JpGraphError::RaiseL(25037,$aFile);//('The image format of your background image ('.$aFile.') is not supported in your system configuration. '); } if( $imgtag == "jpg" || $imgtag == "jpeg") { $f = "imagecreatefromjpeg"; $imgtag = "jpg"; } else { $f = "imagecreatefrom".$imgtag; } // Compare specified image type and file extension if( $imgtag != $ext ) { //$t = "Background image seems to be of different type (has different file extension) than specified imagetype. Specified: '".$aImgFormat."'File: '".$aFile."'"; JpGraphError::RaiseL(25038, $aImgFormat, $aFile); } $img = @$f($aFile); if( !$img ) { JpGraphError::RaiseL(25039,$aFile);//(" Can't read background image: '".$aFile."'"); } return $img; } function StrokePlotGrad() { if( $this->plot_gradtype < 0 ) return; $grad = new Gradient($this->img); $xl = $this->img->left_margin; $yt = $this->img->top_margin; $xr = $xl + $this->img->plotwidth+1 ; $yb = $yt + $this->img->plotheight ; $grad->FilledRectangle($xl,$yt,$xr,$yb,$this->plot_gradfrom,$this->plot_gradto,$this->plot_gradtype); } function StrokeBackgroundGrad() { if( $this->bkg_gradtype < 0 ) return; $grad = new Gradient($this->img); if( $this->bkg_gradstyle == BGRAD_PLOT ) { $xl = $this->img->left_margin; $yt = $this->img->top_margin; $xr = $xl + $this->img->plotwidth+1 ; $yb = $yt + $this->img->plotheight ; $grad->FilledRectangle($xl,$yt,$xr,$yb,$this->bkg_gradfrom,$this->bkg_gradto,$this->bkg_gradtype); } else { $xl = 0; $yt = 0; $xr = $xl + $this->img->width - 1; $yb = $yt + $this->img->height - 1 ; if( $this->doshadow ) { $xr -= $this->shadow_width; $yb -= $this->shadow_width; } if( $this->doframe ) { $yt += $this->frame_weight; $yb -= $this->frame_weight; $xl += $this->frame_weight; $xr -= $this->frame_weight; } $aa = $this->img->SetAngle(0); $grad->FilledRectangle($xl,$yt,$xr,$yb,$this->bkg_gradfrom,$this->bkg_gradto,$this->bkg_gradtype); $aa = $this->img->SetAngle($aa); } } function StrokeFrameBackground() { if( $this->background_image != '' && $this->background_cflag != '' ) { JpGraphError::RaiseL(25040);//('It is not possible to specify both a background image and a background country flag.'); } if( $this->background_image != '' ) { $bkgimg = $this->LoadBkgImage($this->background_image_format,$this->background_image); } elseif( $this->background_cflag != '' ) { if( ! class_exists('FlagImages',false) ) { JpGraphError::RaiseL(25041);//('In order to use Country flags as backgrounds you must include the "jpgraph_flags.php" file.'); } $fobj = new FlagImages(FLAGSIZE4); $dummy=''; $bkgimg = $fobj->GetImgByName($this->background_cflag,$dummy); $this->background_image_mix = $this->background_cflag_mix; $this->background_image_type = $this->background_cflag_type; } else { return ; } $bw = ImageSX($bkgimg); $bh = ImageSY($bkgimg); // No matter what the angle is we always stroke the image and frame // assuming it is 0 degree $aa = $this->img->SetAngle(0); switch( $this->background_image_type ) { case BGIMG_FILLPLOT: // Resize to just fill the plotarea $this->FillMarginArea(); $this->StrokeFrame(); // Special case to hande 90 degree rotated graph corectly if( $aa == 90 ) { $this->img->SetAngle(90); $this->FillPlotArea(); $aa = $this->img->SetAngle(0); $adj = ($this->img->height - $this->img->width)/2; $this->img->CopyMerge($bkgimg, $this->img->bottom_margin-$adj,$this->img->left_margin+$adj, 0,0, $this->img->plotheight+1,$this->img->plotwidth, $bw,$bh,$this->background_image_mix); } else { $this->FillPlotArea(); $this->img->CopyMerge($bkgimg, $this->img->left_margin,$this->img->top_margin+1, 0,0,$this->img->plotwidth+1,$this->img->plotheight, $bw,$bh,$this->background_image_mix); } break; case BGIMG_FILLFRAME: // Fill the whole area from upper left corner, resize to just fit $hadj=0; $vadj=0; if( $this->doshadow ) { $hadj = $this->shadow_width; $vadj = $this->shadow_width; } $this->FillMarginArea(); $this->FillPlotArea(); $this->img->CopyMerge($bkgimg,0,0,0,0,$this->img->width-$hadj,$this->img->height-$vadj, $bw,$bh,$this->background_image_mix); $this->StrokeFrame(); break; case BGIMG_COPY: // Just copy the image from left corner, no resizing $this->FillMarginArea(); $this->FillPlotArea(); $this->img->CopyMerge($bkgimg,0,0,0,0,$bw,$bh, $bw,$bh,$this->background_image_mix); $this->StrokeFrame(); break; case BGIMG_CENTER: // Center original image in the plot area $this->FillMarginArea(); $this->FillPlotArea(); $centerx = round($this->img->plotwidth/2+$this->img->left_margin-$bw/2); $centery = round($this->img->plotheight/2+$this->img->top_margin-$bh/2); $this->img->CopyMerge($bkgimg,$centerx,$centery,0,0,$bw,$bh, $bw,$bh,$this->background_image_mix); $this->StrokeFrame(); break; case BGIMG_FREE: // Just copy the image to the specified location $this->img->CopyMerge($bkgimg, $this->background_image_xpos,$this->background_image_ypos, 0,0,$bw,$bh,$bw,$bh,$this->background_image_mix); $this->StrokeFrame(); // New break; default: JpGraphError::RaiseL(25042);//(" Unknown background image layout"); } $this->img->SetAngle($aa); } // Private // Draw a frame around the image function StrokeFrame() { if( !$this->doframe ) return; if( $this->background_image_type <= 1 && ($this->bkg_gradtype < 0 || ($this->bkg_gradtype > 0 && $this->bkg_gradstyle==BGRAD_PLOT)) ) { $c = $this->margin_color; } else { $c = false; } if( $this->doshadow ) { $this->img->SetColor($this->frame_color); $this->img->ShadowRectangle(0,0,$this->img->width,$this->img->height, $c,$this->shadow_width,$this->shadow_color); } elseif( $this->framebevel ) { if( $c ) { $this->img->SetColor($this->margin_color); $this->img->FilledRectangle(0,0,$this->img->width-1,$this->img->height-1); } $this->img->Bevel(1,1,$this->img->width-2,$this->img->height-2, $this->framebeveldepth, $this->framebevelcolor1,$this->framebevelcolor2); if( $this->framebevelborder ) { $this->img->SetColor($this->framebevelbordercolor); $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); } } else { $this->img->SetLineWeight($this->frame_weight); if( $c ) { $this->img->SetColor($this->margin_color); $this->img->FilledRectangle(0,0,$this->img->width-1,$this->img->height-1); } $this->img->SetColor($this->frame_color); $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); } } function FillMarginArea() { $hadj=0; $vadj=0; if( $this->doshadow ) { $hadj = $this->shadow_width; $vadj = $this->shadow_width; } $this->img->SetColor($this->margin_color); // $this->img->FilledRectangle(0,0,$this->img->width-1-$hadj,$this->img->height-1-$vadj); $this->img->FilledRectangle(0,0,$this->img->width-1-$hadj,$this->img->top_margin); $this->img->FilledRectangle(0,$this->img->top_margin,$this->img->left_margin,$this->img->height-1-$hadj); $this->img->FilledRectangle($this->img->left_margin+1, $this->img->height-$this->img->bottom_margin, $this->img->width-1-$hadj, $this->img->height-1-$hadj); $this->img->FilledRectangle($this->img->width-$this->img->right_margin, $this->img->top_margin+1, $this->img->width-1-$hadj, $this->img->height-$this->img->bottom_margin-1); } function FillPlotArea() { $this->img->PushColor($this->plotarea_color); $this->img->FilledRectangle($this->img->left_margin, $this->img->top_margin, $this->img->width-$this->img->right_margin, $this->img->height-$this->img->bottom_margin); $this->img->PopColor(); } // Stroke the plot area with either a solid color or a background image function StrokePlotArea() { // Note: To be consistent we really should take a possible shadow // into account. However, that causes some problem for the LinearScale class // since in the current design it does not have any links to class Graph which // means it has no way of compensating for the adjusted plotarea in case of a // shadow. So, until I redesign LinearScale we can't compensate for this. // So just set the two adjustment parameters to zero for now. $boxadj = 0; //$this->doframe ? $this->frame_weight : 0 ; $adj = 0; //$this->doshadow ? $this->shadow_width : 0 ; if( $this->background_image != '' || $this->background_cflag != '' ) { $this->StrokeFrameBackground(); } else { $aa = $this->img->SetAngle(0); $this->StrokeFrame(); $aa = $this->img->SetAngle($aa); $this->StrokeBackgroundGrad(); if( $this->bkg_gradtype < 0 || ($this->bkg_gradtype > 0 && $this->bkg_gradstyle==BGRAD_MARGIN) ) { $this->FillPlotArea(); } $this->StrokePlotGrad(); } } function StrokeIcons() { $n = count($this->iIcons); for( $i=0; $i < $n; ++$i ) { $this->iIcons[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); } } function StrokePlotBox() { // Should we draw a box around the plot area? if( $this->boxed ) { $this->img->SetLineWeight(1); $this->img->SetLineStyle('solid'); $this->img->SetColor($this->box_color); for($i=0; $i < $this->box_weight; ++$i ) { $this->img->Rectangle( $this->img->left_margin-$i,$this->img->top_margin-$i, $this->img->width-$this->img->right_margin+$i, $this->img->height-$this->img->bottom_margin+$i); } } } function SetTitleBackgroundFillStyle($aStyle,$aColor1='black',$aColor2='white') { $this->titlebkg_fillstyle = $aStyle; $this->titlebkg_scolor1 = $aColor1; $this->titlebkg_scolor2 = $aColor2; } function SetTitleBackground($aBackColor='gray', $aStyle=TITLEBKG_STYLE1, $aFrameStyle=TITLEBKG_FRAME_NONE, $aFrameColor='black', $aFrameWeight=1, $aBevelHeight=3, $aEnable=true) { $this->titlebackground = $aEnable; $this->titlebackground_color = $aBackColor; $this->titlebackground_style = $aStyle; $this->titlebackground_framecolor = $aFrameColor; $this->titlebackground_framestyle = $aFrameStyle; $this->titlebackground_frameweight = $aFrameWeight; $this->titlebackground_bevelheight = $aBevelHeight ; } function StrokeTitles() { $margin=3; if( $this->titlebackground ) { // Find out height $this->title->margin += 2 ; $h = $this->title->GetTextHeight($this->img)+$this->title->margin+$margin; if( $this->subtitle->t != '' && !$this->subtitle->hide ) { $h += $this->subtitle->GetTextHeight($this->img)+$margin+ $this->subtitle->margin; $h += 2; } if( $this->subsubtitle->t != '' && !$this->subsubtitle->hide ) { $h += $this->subsubtitle->GetTextHeight($this->img)+$margin+ $this->subsubtitle->margin; $h += 2; } $this->img->PushColor($this->titlebackground_color); if( $this->titlebackground_style === TITLEBKG_STYLE1 ) { // Inside the frame if( $this->framebevel ) { $x1 = $y1 = $this->framebeveldepth + 1 ; $x2 = $this->img->width - $this->framebeveldepth - 2 ; $this->title->margin += $this->framebeveldepth + 1 ; $h += $y1 ; $h += 2; } else { $x1 = $y1 = $this->frame_weight; $x2 = $this->img->width - $this->frame_weight-1; } } elseif( $this->titlebackground_style === TITLEBKG_STYLE2 ) { // Cover the frame as well $x1 = $y1 = 0; $x2 = $this->img->width - 1 ; } elseif( $this->titlebackground_style === TITLEBKG_STYLE3 ) { // Cover the frame as well (the difference is that // for style==3 a bevel frame border is on top // of the title background) $x1 = $y1 = 0; $x2 = $this->img->width - 1 ; $h += $this->framebeveldepth ; $this->title->margin += $this->framebeveldepth ; } else { JpGraphError::RaiseL(25043);//('Unknown title background style.'); } if( $this->titlebackground_framestyle === 3 ) { $h += $this->titlebackground_bevelheight*2 + 1 ; $this->title->margin += $this->titlebackground_bevelheight ; } if( $this->doshadow ) { $x2 -= $this->shadow_width ; } $indent=0; if( $this->titlebackground_framestyle == TITLEBKG_FRAME_BEVEL ) { $indent = $this->titlebackground_bevelheight; } if( $this->titlebkg_fillstyle==TITLEBKG_FILLSTYLE_HSTRIPED ) { $this->img->FilledRectangle2($x1+$indent,$y1+$indent,$x2-$indent,$h-$indent, $this->titlebkg_scolor1, $this->titlebkg_scolor2); } elseif( $this->titlebkg_fillstyle==TITLEBKG_FILLSTYLE_VSTRIPED ) { $this->img->FilledRectangle2($x1+$indent,$y1+$indent,$x2-$indent,$h-$indent, $this->titlebkg_scolor1, $this->titlebkg_scolor2,2); } else { // Solid fill $this->img->FilledRectangle($x1,$y1,$x2,$h); } $this->img->PopColor(); $this->img->PushColor($this->titlebackground_framecolor); $this->img->SetLineWeight($this->titlebackground_frameweight); if( $this->titlebackground_framestyle == TITLEBKG_FRAME_FULL ) { // Frame background $this->img->Rectangle($x1,$y1,$x2,$h); } elseif( $this->titlebackground_framestyle == TITLEBKG_FRAME_BOTTOM ) { // Bottom line only $this->img->Line($x1,$h,$x2,$h); } elseif( $this->titlebackground_framestyle == TITLEBKG_FRAME_BEVEL ) { $this->img->Bevel($x1,$y1,$x2,$h,$this->titlebackground_bevelheight); } $this->img->PopColor(); // This is clumsy. But we neeed to stroke the whole graph frame if it is // set to bevel to get the bevel shading on top of the text background if( $this->framebevel && $this->doframe && $this->titlebackground_style === 3 ) { $this->img->Bevel(1,1,$this->img->width-2,$this->img->height-2, $this->framebeveldepth, $this->framebevelcolor1,$this->framebevelcolor2); if( $this->framebevelborder ) { $this->img->SetColor($this->framebevelbordercolor); $this->img->Rectangle(0,0,$this->img->width-1,$this->img->height-1); } } } // Stroke title $y = $this->title->margin; if( $this->title->halign == 'center' ) { $this->title->Center(0,$this->img->width,$y); } elseif( $this->title->halign == 'left' ) { $this->title->SetPos($this->title->margin+2,$y); } elseif( $this->title->halign == 'right' ) { $indent = 0; if( $this->doshadow ) { $indent = $this->shadow_width+2; } $this->title->SetPos($this->img->width-$this->title->margin-$indent,$y,'right'); } $this->title->Stroke($this->img); // ... and subtitle $y += $this->title->GetTextHeight($this->img) + $margin + $this->subtitle->margin; if( $this->subtitle->halign == 'center' ) { $this->subtitle->Center(0,$this->img->width,$y); } elseif( $this->subtitle->halign == 'left' ) { $this->subtitle->SetPos($this->subtitle->margin+2,$y); } elseif( $this->subtitle->halign == 'right' ) { $indent = 0; if( $this->doshadow ) $indent = $this->shadow_width+2; $this->subtitle->SetPos($this->img->width-$this->subtitle->margin-$indent,$y,'right'); } $this->subtitle->Stroke($this->img); // ... and subsubtitle $y += $this->subtitle->GetTextHeight($this->img) + $margin + $this->subsubtitle->margin; if( $this->subsubtitle->halign == 'center' ) { $this->subsubtitle->Center(0,$this->img->width,$y); } elseif( $this->subsubtitle->halign == 'left' ) { $this->subsubtitle->SetPos($this->subsubtitle->margin+2,$y); } elseif( $this->subsubtitle->halign == 'right' ) { $indent = 0; if( $this->doshadow ) $indent = $this->shadow_width+2; $this->subsubtitle->SetPos($this->img->width-$this->subsubtitle->margin-$indent,$y,'right'); } $this->subsubtitle->Stroke($this->img); // ... and fancy title $this->tabtitle->Stroke($this->img); } function StrokeTexts() { // Stroke any user added text objects if( $this->texts != null ) { for($i=0; $i < count($this->texts); ++$i) { $this->texts[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); } } if( $this->y2texts != null && $this->y2scale != null ) { for($i=0; $i < count($this->y2texts); ++$i) { $this->y2texts[$i]->StrokeWithScale($this->img,$this->xscale,$this->y2scale); } } } function StrokeTables() { if( $this->iTables != null ) { $n = count($this->iTables); for( $i=0; $i < $n; ++$i ) { $this->iTables[$i]->StrokeWithScale($this->img,$this->xscale,$this->yscale); } } } function DisplayClientSideaImageMapAreas() { // Debug stuff - display the outline of the image map areas $csim=''; foreach ($this->plots as $p) { $csim.= $p->GetCSIMareas(); } $csim .= $this->legend->GetCSIMareas(); if (preg_match_all("/area shape=\"(\w+)\" coords=\"([0-9\, ]+)\"/", $csim, $coords)) { $this->img->SetColor($this->csimcolor); $n = count($coords[0]); for ($i=0; $i < $n; $i++) { if ( $coords[1][$i] == 'poly' ) { preg_match_all('/\s*([0-9]+)\s*,\s*([0-9]+)\s*,*/',$coords[2][$i],$pts); $this->img->SetStartPoint($pts[1][count($pts[0])-1],$pts[2][count($pts[0])-1]); $m = count($pts[0]); for ($j=0; $j < $m; $j++) { $this->img->LineTo($pts[1][$j],$pts[2][$j]); } } elseif ( $coords[1][$i] == 'rect' ) { $pts = preg_split('/,/', $coords[2][$i]); $this->img->SetStartPoint($pts[0],$pts[1]); $this->img->LineTo($pts[2],$pts[1]); $this->img->LineTo($pts[2],$pts[3]); $this->img->LineTo($pts[0],$pts[3]); $this->img->LineTo($pts[0],$pts[1]); } } } } // Text scale offset in world coordinates function SetTextScaleOff($aOff) { $this->text_scale_off = $aOff; $this->xscale->text_scale_off = $aOff; } // Text width of bar to be centered in absolute pixels function SetTextScaleAbsCenterOff($aOff) { $this->text_scale_abscenteroff = $aOff; } // Get Y min and max values for added lines function GetLinesYMinMax( $aLines ) { $n = count($aLines); if( $n == 0 ) return false; $min = $aLines[0]->scaleposition ; $max = $min ; $flg = false; for( $i=0; $i < $n; ++$i ) { if( $aLines[$i]->direction == HORIZONTAL ) { $flg = true ; $v = $aLines[$i]->scaleposition ; if( $min > $v ) $min = $v ; if( $max < $v ) $max = $v ; } } return $flg ? array($min,$max) : false ; } // Get X min and max values for added lines function GetLinesXMinMax( $aLines ) { $n = count($aLines); if( $n == 0 ) return false ; $min = $aLines[0]->scaleposition ; $max = $min ; $flg = false; for( $i=0; $i < $n; ++$i ) { if( $aLines[$i]->direction == VERTICAL ) { $flg = true ; $v = $aLines[$i]->scaleposition ; if( $min > $v ) $min = $v ; if( $max < $v ) $max = $v ; } } return $flg ? array($min,$max) : false ; } // Get min and max values for all included plots function GetPlotsYMinMax($aPlots) { $n = count($aPlots); $i=0; do { list($xmax,$max) = $aPlots[$i]->Max(); } while( ++$i < $n && !is_numeric($max) ); $i=0; do { list($xmin,$min) = $aPlots[$i]->Min(); } while( ++$i < $n && !is_numeric($min) ); if( !is_numeric($min) || !is_numeric($max) ) { JpGraphError::RaiseL(25044);//('Cannot use autoscaling since it is impossible to determine a valid min/max value of the Y-axis (only null values).'); } for($i=0; $i < $n; ++$i ) { list($xmax,$ymax)=$aPlots[$i]->Max(); list($xmin,$ymin)=$aPlots[$i]->Min(); if (is_numeric($ymax)) $max=max($max,$ymax); if (is_numeric($ymin)) $min=min($min,$ymin); } if( $min == '' ) $min = 0; if( $max == '' ) $max = 0; if( $min == 0 && $max == 0 ) { // Special case if all values are 0 $min=0;$max=1; } return array($min,$max); } } // Class //=================================================== // CLASS LineProperty // Description: Holds properties for a line //=================================================== class LineProperty { public $iWeight=1, $iColor='black', $iStyle='solid', $iShow=true; function __construct($aWeight=1,$aColor='black',$aStyle='solid') { $this->iWeight = $aWeight; $this->iColor = $aColor; $this->iStyle = $aStyle; } function SetColor($aColor) { $this->iColor = $aColor; } function SetWeight($aWeight) { $this->iWeight = $aWeight; } function SetStyle($aStyle) { $this->iStyle = $aStyle; } function Show($aShow=true) { $this->iShow=$aShow; } function Stroke($aImg,$aX1,$aY1,$aX2,$aY2) { if( $this->iShow ) { $aImg->PushColor($this->iColor); $oldls = $aImg->line_style; $oldlw = $aImg->line_weight; $aImg->SetLineWeight($this->iWeight); $aImg->SetLineStyle($this->iStyle); $aImg->StyleLine($aX1,$aY1,$aX2,$aY2); $aImg->PopColor($this->iColor); $aImg->line_style = $oldls; $aImg->line_weight = $oldlw; } } } //=================================================== // CLASS GraphTabTitle // Description: Draw "tab" titles on top of graphs //=================================================== class GraphTabTitle extends Text{ private $corner = 6 , $posx = 7, $posy = 4; private $fillcolor='lightyellow',$bordercolor='black'; private $align = 'left', $width=TABTITLE_WIDTHFIT; function __construct() { $this->t = ''; $this->font_style = FS_BOLD; $this->hide = true; $this->color = 'darkred'; } function SetColor($aTxtColor,$aFillColor='lightyellow',$aBorderColor='black') { $this->color = $aTxtColor; $this->fillcolor = $aFillColor; $this->bordercolor = $aBorderColor; } function SetFillColor($aFillColor) { $this->fillcolor = $aFillColor; } function SetTabAlign($aAlign) { $this->align = $aAlign; } function SetWidth($aWidth) { $this->width = $aWidth ; } function Set($t) { $this->t = $t; $this->hide = false; } function SetCorner($aD) { $this->corner = $aD ; } function Stroke($aImg,$aDummy1=null,$aDummy2=null) { if( $this->hide ) return; $this->boxed = false; $w = $this->GetWidth($aImg) + 2*$this->posx; $h = $this->GetTextHeight($aImg) + 2*$this->posy; $x = $aImg->left_margin; $y = $aImg->top_margin; if( $this->width === TABTITLE_WIDTHFIT ) { if( $this->align == 'left' ) { $p = array($x, $y, $x, $y-$h+$this->corner, $x + $this->corner,$y-$h, $x + $w - $this->corner, $y-$h, $x + $w, $y-$h+$this->corner, $x + $w, $y); } elseif( $this->align == 'center' ) { $x += round($aImg->plotwidth/2) - round($w/2); $p = array($x, $y, $x, $y-$h+$this->corner, $x + $this->corner, $y-$h, $x + $w - $this->corner, $y-$h, $x + $w, $y-$h+$this->corner, $x + $w, $y); } else { $x += $aImg->plotwidth -$w; $p = array($x, $y, $x, $y-$h+$this->corner, $x + $this->corner,$y-$h, $x + $w - $this->corner, $y-$h, $x + $w, $y-$h+$this->corner, $x + $w, $y); } } else { if( $this->width === TABTITLE_WIDTHFULL ) { $w = $aImg->plotwidth ; } else { $w = $this->width ; } // Make the tab fit the width of the plot area $p = array($x, $y, $x, $y-$h+$this->corner, $x + $this->corner,$y-$h, $x + $w - $this->corner, $y-$h, $x + $w, $y-$h+$this->corner, $x + $w, $y); } if( $this->halign == 'left' ) { $aImg->SetTextAlign('left','bottom'); $x += $this->posx; $y -= $this->posy; } elseif( $this->halign == 'center' ) { $aImg->SetTextAlign('center','bottom'); $x += $w/2; $y -= $this->posy; } else { $aImg->SetTextAlign('right','bottom'); $x += $w - $this->posx; $y -= $this->posy; } $aImg->SetColor($this->fillcolor); $aImg->FilledPolygon($p); $aImg->SetColor($this->bordercolor); $aImg->Polygon($p,true); $aImg->SetColor($this->color); $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $aImg->StrokeText($x,$y,$this->t,0,'center'); } } //=================================================== // CLASS SuperScriptText // Description: Format a superscript text //=================================================== class SuperScriptText extends Text { private $iSuper=''; private $sfont_family='',$sfont_style='',$sfont_size=8; private $iSuperMargin=2,$iVertOverlap=4,$iSuperScale=0.65; private $iSDir=0; private $iSimple=false; function __construct($aTxt='',$aSuper='',$aXAbsPos=0,$aYAbsPos=0) { parent::__construct($aTxt,$aXAbsPos,$aYAbsPos); $this->iSuper = $aSuper; } function FromReal($aVal,$aPrecision=2) { // Convert a floating point number to scientific notation $neg=1.0; if( $aVal < 0 ) { $neg = -1.0; $aVal = -$aVal; } $l = floor(log10($aVal)); $a = sprintf("%0.".$aPrecision."f",round($aVal / pow(10,$l),$aPrecision)); $a *= $neg; if( $this->iSimple && ($a == 1 || $a==-1) ) $a = ''; if( $a != '' ) { $this->t = $a.' * 10'; } else { if( $neg == 1 ) { $this->t = '10'; } else { $this->t = '-10'; } } $this->iSuper = $l; } function Set($aTxt,$aSuper='') { $this->t = $aTxt; $this->iSuper = $aSuper; } function SetSuperFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=8) { $this->sfont_family = $aFontFam; $this->sfont_style = $aFontStyle; $this->sfont_size = $aFontSize; } // Total width of text function GetWidth($aImg) { $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $w = $aImg->GetTextWidth($this->t); $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); $w += $aImg->GetTextWidth($this->iSuper); $w += $this->iSuperMargin; return $w; } // Hight of font (approximate the height of the text) function GetFontHeight($aImg) { $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $h = $aImg->GetFontHeight(); $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); $h += $aImg->GetFontHeight(); return $h; } // Hight of text function GetTextHeight($aImg) { $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $h = $aImg->GetTextHeight($this->t); $aImg->SetFont($this->sfont_family,$this->sfont_style,$this->sfont_size); $h += $aImg->GetTextHeight($this->iSuper); return $h; } function Stroke($aImg,$ax=-1,$ay=-1) { // To position the super script correctly we need different // cases to handle the alignmewnt specified since that will // determine how we can interpret the x,y coordinates $w = parent::GetWidth($aImg); $h = parent::GetTextHeight($aImg); switch( $this->valign ) { case 'top': $sy = $this->y; break; case 'center': $sy = $this->y - $h/2; break; case 'bottom': $sy = $this->y - $h; break; default: JpGraphError::RaiseL(25052);//('PANIC: Internal error in SuperScript::Stroke(). Unknown vertical alignment for text'); break; } switch( $this->halign ) { case 'left': $sx = $this->x + $w; break; case 'center': $sx = $this->x + $w/2; break; case 'right': $sx = $this->x; break; default: JpGraphError::RaiseL(25053);//('PANIC: Internal error in SuperScript::Stroke(). Unknown horizontal alignment for text'); break; } $sx += $this->iSuperMargin; $sy += $this->iVertOverlap; // Should we automatically determine the font or // has the user specified it explicetly? if( $this->sfont_family == '' ) { if( $this->font_family <= FF_FONT2 ) { if( $this->font_family == FF_FONT0 ) { $sff = FF_FONT0; } elseif( $this->font_family == FF_FONT1 ) { if( $this->font_style == FS_NORMAL ) { $sff = FF_FONT0; } else { $sff = FF_FONT1; } } else { $sff = FF_FONT1; } $sfs = $this->font_style; $sfz = $this->font_size; } else { // TTF fonts $sff = $this->font_family; $sfs = $this->font_style; $sfz = floor($this->font_size*$this->iSuperScale); if( $sfz < 8 ) $sfz = 8; } $this->sfont_family = $sff; $this->sfont_style = $sfs; $this->sfont_size = $sfz; } else { $sff = $this->sfont_family; $sfs = $this->sfont_style; $sfz = $this->sfont_size; } parent::Stroke($aImg,$ax,$ay); // For the builtin fonts we need to reduce the margins // since the bounding bx reported for the builtin fonts // are much larger than for the TTF fonts. if( $sff <= FF_FONT2 ) { $sx -= 2; $sy += 3; } $aImg->SetTextAlign('left','bottom'); $aImg->SetFont($sff,$sfs,$sfz); $aImg->PushColor($this->color); $aImg->StrokeText($sx,$sy,$this->iSuper,$this->iSDir,'left'); $aImg->PopColor(); } } //=================================================== // CLASS Grid // Description: responsible for drawing grid lines in graph //=================================================== class Grid { protected $img; protected $scale; protected $majorcolor='#DDDDDD',$minorcolor='#EEEEEE'; protected $majortype='solid',$minortype='solid'; protected $show=false, $showMinor=false,$majorweight=1,$minorweight=1; protected $fill=false,$fillcolor=array('#EFEFEF','#BBCCFF'); function __construct($aAxis) { $this->scale = $aAxis->scale; $this->img = $aAxis->img; } function SetColor($aMajColor,$aMinColor=false) { $this->majorcolor=$aMajColor; if( $aMinColor === false ) { $aMinColor = $aMajColor ; } $this->minorcolor = $aMinColor; } function SetWeight($aMajorWeight,$aMinorWeight=1) { $this->majorweight=$aMajorWeight; $this->minorweight=$aMinorWeight; } // Specify if grid should be dashed, dotted or solid function SetLineStyle($aMajorType,$aMinorType='solid') { $this->majortype = $aMajorType; $this->minortype = $aMinorType; } function SetStyle($aMajorType,$aMinorType='solid') { $this->SetLineStyle($aMajorType,$aMinorType); } // Decide if both major and minor grid should be displayed function Show($aShowMajor=true,$aShowMinor=false) { $this->show=$aShowMajor; $this->showMinor=$aShowMinor; } function SetFill($aFlg=true,$aColor1='lightgray',$aColor2='lightblue') { $this->fill = $aFlg; $this->fillcolor = array( $aColor1, $aColor2 ); } // Display the grid function Stroke() { if( $this->showMinor && !$this->scale->textscale ) { $this->DoStroke($this->scale->ticks->ticks_pos,$this->minortype,$this->minorcolor,$this->minorweight); $this->DoStroke($this->scale->ticks->maj_ticks_pos,$this->majortype,$this->majorcolor,$this->majorweight); } else { $this->DoStroke($this->scale->ticks->maj_ticks_pos,$this->majortype,$this->majorcolor,$this->majorweight); } } //-------------- // Private methods // Draw the grid function DoStroke($aTicksPos,$aType,$aColor,$aWeight) { if( !$this->show ) return; $nbrgrids = count($aTicksPos); if( $this->scale->type == 'y' ) { $xl=$this->img->left_margin; $xr=$this->img->width-$this->img->right_margin; if( $this->fill ) { // Draw filled areas $y2 = $aTicksPos[0]; $i=1; while( $i < $nbrgrids ) { $y1 = $y2; $y2 = $aTicksPos[$i++]; $this->img->SetColor($this->fillcolor[$i & 1]); $this->img->FilledRectangle($xl,$y1,$xr,$y2); } } $this->img->SetColor($aColor); $this->img->SetLineWeight($aWeight); // Draw grid lines switch( $aType ) { case 'solid': $style = LINESTYLE_SOLID; break; case 'dotted': $style = LINESTYLE_DOTTED; break; case 'dashed': $style = LINESTYLE_DASHED; break; case 'longdashed': $style = LINESTYLE_LONGDASH; break; default: $style = LINESTYLE_SOLID; break; } for($i=0; $i < $nbrgrids; ++$i) { $y=$aTicksPos[$i]; $this->img->StyleLine($xl,$y,$xr,$y,$style); } } elseif( $this->scale->type == 'x' ) { $yu=$this->img->top_margin; $yl=$this->img->height-$this->img->bottom_margin; $limit=$this->img->width-$this->img->right_margin; if( $this->fill ) { // Draw filled areas $x2 = $aTicksPos[0]; $i=1; while( $i < $nbrgrids ) { $x1 = $x2; $x2 = min($aTicksPos[$i++],$limit) ; $this->img->SetColor($this->fillcolor[$i & 1]); $this->img->FilledRectangle($x1,$yu,$x2,$yl); } } $this->img->SetColor($aColor); $this->img->SetLineWeight($aWeight); // We must also test for limit since we might have // an offset and the number of ticks is calculated with // assumption offset==0 so we might end up drawing one // to many gridlines $i=0; $x=$aTicksPos[$i]; while( $iimg->Line($x,$yl,$x,$yu); elseif( $aType == 'dotted' ) $this->img->DashedLine($x,$yl,$x,$yu,1,6); elseif( $aType == 'dashed' ) $this->img->DashedLine($x,$yl,$x,$yu,2,4); elseif( $aType == 'longdashed' ) $this->img->DashedLine($x,$yl,$x,$yu,8,6); ++$i; } } else { JpGraphError::RaiseL(25054,$this->scale->type);//('Internal error: Unknown grid axis ['.$this->scale->type.']'); } return true; } } // Class //=================================================== // CLASS Axis // Description: Defines X and Y axis. Notes that at the // moment the code is not really good since the axis on // several occasion must know wheter it's an X or Y axis. // This was a design decision to make the code easier to // follow. //=================================================== class AxisPrototype { public $scale=null; public $img=null; public $hide=false,$hide_labels=false; public $title=null; public $font_family=FF_FONT1,$font_style=FS_NORMAL,$font_size=12,$label_angle=0; public $tick_step=1; public $pos = false; public $ticks_label = array(); protected $weight=1; protected $color=array(0,0,0),$label_color=array(0,0,0); protected $ticks_label_colors=null; protected $show_first_label=true,$show_last_label=true; protected $label_step=1; // Used by a text axis to specify what multiple of major steps // should be labeled. protected $labelPos=0; // Which side of the axis should the labels be? protected $title_adjust,$title_margin,$title_side=SIDE_LEFT; protected $tick_label_margin=5; protected $label_halign = '',$label_valign = '', $label_para_align='left'; protected $hide_line=false; protected $iDeltaAbsPos=0; function __construct($img,$aScale,$color = array(0,0,0)) { $this->img = $img; $this->scale = $aScale; $this->color = $color; $this->title=new Text(''); if( $aScale->type == 'y' ) { $this->title_margin = 25; $this->title_adjust = 'middle'; $this->title->SetOrientation(90); $this->tick_label_margin=7; $this->labelPos=SIDE_LEFT; } else { $this->title_margin = 5; $this->title_adjust = 'high'; $this->title->SetOrientation(0); $this->tick_label_margin=5; $this->labelPos=SIDE_DOWN; $this->title_side=SIDE_DOWN; } } function SetLabelFormat($aFormStr) { $this->scale->ticks->SetLabelFormat($aFormStr); } function SetLabelFormatString($aFormStr,$aDate=false) { $this->scale->ticks->SetLabelFormat($aFormStr,$aDate); } function SetLabelFormatCallback($aFuncName) { $this->scale->ticks->SetFormatCallback($aFuncName); } function SetLabelAlign($aHAlign,$aVAlign='top',$aParagraphAlign='left') { $this->label_halign = $aHAlign; $this->label_valign = $aVAlign; $this->label_para_align = $aParagraphAlign; } // Don't display the first label function HideFirstTickLabel($aShow=false) { $this->show_first_label=$aShow; } function HideLastTickLabel($aShow=false) { $this->show_last_label=$aShow; } // Manually specify the major and (optional) minor tick position and labels function SetTickPositions($aMajPos,$aMinPos=NULL,$aLabels=NULL) { $this->scale->ticks->SetTickPositions($aMajPos,$aMinPos,$aLabels); } // Manually specify major tick positions and optional labels function SetMajTickPositions($aMajPos,$aLabels=NULL) { $this->scale->ticks->SetTickPositions($aMajPos,NULL,$aLabels); } // Hide minor or major tick marks function HideTicks($aHideMinor=true,$aHideMajor=true) { $this->scale->ticks->SupressMinorTickMarks($aHideMinor); $this->scale->ticks->SupressTickMarks($aHideMajor); } // Hide zero label function HideZeroLabel($aFlag=true) { $this->scale->ticks->SupressZeroLabel(); } function HideFirstLastLabel() { // The two first calls to ticks method will supress // automatically generated scale values. However, that // will not affect manually specified value, e.g text-scales. // therefor we also make a kludge here to supress manually // specified scale labels. $this->scale->ticks->SupressLast(); $this->scale->ticks->SupressFirst(); $this->show_first_label = false; $this->show_last_label = false; } // Hide the axis function Hide($aHide=true) { $this->hide=$aHide; } // Hide the actual axis-line, but still print the labels function HideLine($aHide=true) { $this->hide_line = $aHide; } function HideLabels($aHide=true) { $this->hide_labels = $aHide; } // Weight of axis function SetWeight($aWeight) { $this->weight = $aWeight; } // Axis color function SetColor($aColor,$aLabelColor=false) { $this->color = $aColor; if( !$aLabelColor ) $this->label_color = $aColor; else $this->label_color = $aLabelColor; } // Title on axis function SetTitle($aTitle,$aAdjustAlign='high') { $this->title->Set($aTitle); $this->title_adjust=$aAdjustAlign; } // Specify distance from the axis function SetTitleMargin($aMargin) { $this->title_margin=$aMargin; } // Which side of the axis should the axis title be? function SetTitleSide($aSideOfAxis) { $this->title_side = $aSideOfAxis; } function SetTickSide($aDir) { $this->scale->ticks->SetSide($aDir); } function SetTickSize($aMajSize,$aMinSize=3) { $this->scale->ticks->SetSize($aMajSize,$aMinSize=3); } // Specify text labels for the ticks. One label for each data point function SetTickLabels($aLabelArray,$aLabelColorArray=null) { $this->ticks_label = $aLabelArray; $this->ticks_label_colors = $aLabelColorArray; } function SetLabelMargin($aMargin) { $this->tick_label_margin=$aMargin; } // Specify that every $step of the ticks should be displayed starting // at $start function SetTextTickInterval($aStep,$aStart=0) { $this->scale->ticks->SetTextLabelStart($aStart); $this->tick_step=$aStep; } // Specify that every $step tick mark should have a label // should be displayed starting function SetTextLabelInterval($aStep) { if( $aStep < 1 ) { JpGraphError::RaiseL(25058);//(" Text label interval must be specified >= 1."); } $this->label_step=$aStep; } function SetLabelSide($aSidePos) { $this->labelPos=$aSidePos; } // Set the font function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { $this->font_family = $aFamily; $this->font_style = $aStyle; $this->font_size = $aSize; } // Position for axis line on the "other" scale function SetPos($aPosOnOtherScale) { $this->pos=$aPosOnOtherScale; } // Set the position of the axis to be X-pixels delta to the right // of the max X-position (used to position the multiple Y-axis) function SetPosAbsDelta($aDelta) { $this->iDeltaAbsPos=$aDelta; } // Specify the angle for the tick labels function SetLabelAngle($aAngle) { $this->label_angle = $aAngle; } } // Class //=================================================== // CLASS Axis // Description: Defines X and Y axis. Notes that at the // moment the code is not really good since the axis on // several occasion must know wheter it's an X or Y axis. // This was a design decision to make the code easier to // follow. //=================================================== class Axis extends AxisPrototype { function __construct($img,$aScale,$color='black') { parent::__construct($img,$aScale,$color); } // Stroke the axis. function Stroke($aOtherAxisScale,$aStrokeLabels=true) { if( $this->hide ) return; if( is_numeric($this->pos) ) { $pos=$aOtherAxisScale->Translate($this->pos); } else { // Default to minimum of other scale if pos not set if( ($aOtherAxisScale->GetMinVal() >= 0 && $this->pos==false) || $this->pos == 'min' ) { $pos = $aOtherAxisScale->scale_abs[0]; } elseif($this->pos == "max") { $pos = $aOtherAxisScale->scale_abs[1]; } else { // If negative set x-axis at 0 $this->pos=0; $pos=$aOtherAxisScale->Translate(0); } } $pos += $this->iDeltaAbsPos; $this->img->SetLineWeight($this->weight); $this->img->SetColor($this->color); $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); if( $this->scale->type == "x" ) { if( !$this->hide_line ) { $this->img->FilledRectangle($this->img->left_margin,$pos,$this->img->width-$this->img->right_margin,$pos+$this->weight-1); } if( $this->title_side == SIDE_DOWN ) { $y = $pos + $this->img->GetFontHeight() + $this->title_margin + $this->title->margin; $yalign = 'top'; } else { $y = $pos - $this->img->GetFontHeight() - $this->title_margin - $this->title->margin; $yalign = 'bottom'; } if( $this->title_adjust=='high' ) { $this->title->SetPos($this->img->width-$this->img->right_margin,$y,'right',$yalign); } elseif( $this->title_adjust=='middle' || $this->title_adjust=='center' ) { $this->title->SetPos(($this->img->width-$this->img->left_margin-$this->img->right_margin)/2+$this->img->left_margin,$y,'center',$yalign); } elseif($this->title_adjust=='low') { $this->title->SetPos($this->img->left_margin,$y,'left',$yalign); } else { JpGraphError::RaiseL(25060,$this->title_adjust);//('Unknown alignment specified for X-axis title. ('.$this->title_adjust.')'); } } elseif( $this->scale->type == "y" ) { // Add line weight to the height of the axis since // the x-axis could have a width>1 and we want the axis to fit nicely together. if( !$this->hide_line ) { $this->img->FilledRectangle($pos-$this->weight+1,$this->img->top_margin,$pos,$this->img->height-$this->img->bottom_margin+$this->weight-1); } $x=$pos ; if( $this->title_side == SIDE_LEFT ) { $x -= $this->title_margin; $x -= $this->title->margin; $halign = 'right'; } else { $x += $this->title_margin; $x += $this->title->margin; $halign = 'left'; } // If the user has manually specified an hor. align // then we override the automatic settings with this // specifed setting. Since default is 'left' we compare // with that. (This means a manually set 'left' align // will have no effect.) if( $this->title->halign != 'left' ) { $halign = $this->title->halign; } if( $this->title_adjust == 'high' ) { $this->title->SetPos($x,$this->img->top_margin,$halign,'top'); } elseif($this->title_adjust=='middle' || $this->title_adjust=='center') { $this->title->SetPos($x,($this->img->height-$this->img->top_margin-$this->img->bottom_margin)/2+$this->img->top_margin,$halign,"center"); } elseif($this->title_adjust=='low') { $this->title->SetPos($x,$this->img->height-$this->img->bottom_margin,$halign,'bottom'); } else { JpGraphError::RaiseL(25061,$this->title_adjust);//('Unknown alignment specified for Y-axis title. ('.$this->title_adjust.')'); } } $this->scale->ticks->Stroke($this->img,$this->scale,$pos); if( $aStrokeLabels ) { if( !$this->hide_labels ) { $this->StrokeLabels($pos); } $this->title->Stroke($this->img); } } //--------------- // PRIVATE METHODS // Draw all the tick labels on major tick marks function StrokeLabels($aPos,$aMinor=false,$aAbsLabel=false) { if( is_array($this->label_color) && count($this->label_color) > 3 ) { $this->ticks_label_colors = $this->label_color; $this->img->SetColor($this->label_color[0]); } else { $this->img->SetColor($this->label_color); } $this->img->SetFont($this->font_family,$this->font_style,$this->font_size); $yoff=$this->img->GetFontHeight()/2; // Only draw labels at major tick marks $nbr = count($this->scale->ticks->maj_ticks_label); // We have the option to not-display the very first mark // (Usefull when the first label might interfere with another // axis.) $i = $this->show_first_label ? 0 : 1 ; if( !$this->show_last_label ) { --$nbr; } // Now run through all labels making sure we don't overshoot the end // of the scale. $ncolor=0; if( isset($this->ticks_label_colors) ) { $ncolor=count($this->ticks_label_colors); } while( $i < $nbr ) { // $tpos holds the absolute text position for the label $tpos=$this->scale->ticks->maj_ticklabels_pos[$i]; // Note. the $limit is only used for the x axis since we // might otherwise overshoot if the scale has been centered // This is due to us "loosing" the last tick mark if we center. if( $this->scale->type == 'x' && $tpos > $this->img->width-$this->img->right_margin+1 ) { return; } // we only draw every $label_step label if( ($i % $this->label_step)==0 ) { // Set specific label color if specified if( $ncolor > 0 ) { $this->img->SetColor($this->ticks_label_colors[$i % $ncolor]); } // If the label has been specified use that and in other case // just label the mark with the actual scale value $m=$this->scale->ticks->GetMajor(); // ticks_label has an entry for each data point and is the array // that holds the labels set by the user. If the user hasn't // specified any values we use whats in the automatically asigned // labels in the maj_ticks_label if( isset($this->ticks_label[$i*$m]) ) { $label=$this->ticks_label[$i*$m]; } else { if( $aAbsLabel ) { $label=abs($this->scale->ticks->maj_ticks_label[$i]); } else { $label=$this->scale->ticks->maj_ticks_label[$i]; } // We number the scale from 1 and not from 0 so increase by one if( $this->scale->textscale && $this->scale->ticks->label_formfunc == '' && ! $this->scale->ticks->HaveManualLabels() ) { ++$label; } } if( $this->scale->type == "x" ) { if( $this->labelPos == SIDE_DOWN ) { if( $this->label_angle==0 || $this->label_angle==90 ) { if( $this->label_halign=='' && $this->label_valign=='') { $this->img->SetTextAlign('center','top'); } else { $this->img->SetTextAlign($this->label_halign,$this->label_valign); } } else { if( $this->label_halign=='' && $this->label_valign=='') { $this->img->SetTextAlign("right","top"); } else { $this->img->SetTextAlign($this->label_halign,$this->label_valign); } } $this->img->StrokeText($tpos,$aPos+$this->tick_label_margin,$label, $this->label_angle,$this->label_para_align); } else { if( $this->label_angle==0 || $this->label_angle==90 ) { if( $this->label_halign=='' && $this->label_valign=='') { $this->img->SetTextAlign("center","bottom"); } else { $this->img->SetTextAlign($this->label_halign,$this->label_valign); } } else { if( $this->label_halign=='' && $this->label_valign=='') { $this->img->SetTextAlign("right","bottom"); } else { $this->img->SetTextAlign($this->label_halign,$this->label_valign); } } $this->img->StrokeText($tpos,$aPos-$this->tick_label_margin-1,$label, $this->label_angle,$this->label_para_align); } } else { // scale->type == "y" //if( $this->label_angle!=0 ) //JpGraphError::Raise(" Labels at an angle are not supported on Y-axis"); if( $this->labelPos == SIDE_LEFT ) { // To the left of y-axis if( $this->label_halign=='' && $this->label_valign=='') { $this->img->SetTextAlign("right","center"); } else { $this->img->SetTextAlign($this->label_halign,$this->label_valign); } $this->img->StrokeText($aPos-$this->tick_label_margin,$tpos,$label,$this->label_angle,$this->label_para_align); } else { // To the right of the y-axis if( $this->label_halign=='' && $this->label_valign=='') { $this->img->SetTextAlign("left","center"); } else { $this->img->SetTextAlign($this->label_halign,$this->label_valign); } $this->img->StrokeText($aPos+$this->tick_label_margin,$tpos,$label,$this->label_angle,$this->label_para_align); } } } ++$i; } } } //=================================================== // CLASS Ticks // Description: Abstract base class for drawing linear and logarithmic // tick marks on axis //=================================================== class Ticks { public $label_formatstr=''; // C-style format string to use for labels public $label_formfunc=''; public $label_dateformatstr=''; public $direction=1; // Should ticks be in(=1) the plot area or outside (=-1) public $supress_last=false,$supress_tickmarks=false,$supress_minor_tickmarks=false; public $maj_ticks_pos = array(), $maj_ticklabels_pos = array(), $ticks_pos = array(), $maj_ticks_label = array(); public $precision; protected $minor_abs_size=3, $major_abs_size=5; protected $scale; protected $is_set=false; protected $supress_zerolabel=false,$supress_first=false; protected $mincolor='',$majcolor=''; protected $weight=1; protected $label_usedateformat=FALSE; function __construct($aScale) { $this->scale=$aScale; $this->precision = -1; } // Set format string for automatic labels function SetLabelFormat($aFormatString,$aDate=FALSE) { $this->label_formatstr=$aFormatString; $this->label_usedateformat=$aDate; } function SetLabelDateFormat($aFormatString) { $this->label_dateformatstr=$aFormatString; } function SetFormatCallback($aCallbackFuncName) { $this->label_formfunc = $aCallbackFuncName; } // Don't display the first zero label function SupressZeroLabel($aFlag=true) { $this->supress_zerolabel=$aFlag; } // Don't display minor tick marks function SupressMinorTickMarks($aHide=true) { $this->supress_minor_tickmarks=$aHide; } // Don't display major tick marks function SupressTickMarks($aHide=true) { $this->supress_tickmarks=$aHide; } // Hide the first tick mark function SupressFirst($aHide=true) { $this->supress_first=$aHide; } // Hide the last tick mark function SupressLast($aHide=true) { $this->supress_last=$aHide; } // Size (in pixels) of minor tick marks function GetMinTickAbsSize() { return $this->minor_abs_size; } // Size (in pixels) of major tick marks function GetMajTickAbsSize() { return $this->major_abs_size; } function SetSize($aMajSize,$aMinSize=3) { $this->major_abs_size = $aMajSize; $this->minor_abs_size = $aMinSize; } // Have the ticks been specified function IsSpecified() { return $this->is_set; } function SetSide($aSide) { $this->direction=$aSide; } // Which side of the axis should the ticks be on function SetDirection($aSide=SIDE_RIGHT) { $this->direction=$aSide; } // Set colors for major and minor tick marks function SetMarkColor($aMajorColor,$aMinorColor='') { $this->SetColor($aMajorColor,$aMinorColor); } function SetColor($aMajorColor,$aMinorColor='') { $this->majcolor=$aMajorColor; // If not specified use same as major if( $aMinorColor == '' ) { $this->mincolor=$aMajorColor; } else { $this->mincolor=$aMinorColor; } } function SetWeight($aWeight) { $this->weight=$aWeight; } } // Class //=================================================== // CLASS LinearTicks // Description: Draw linear ticks on axis //=================================================== class LinearTicks extends Ticks { public $minor_step=1, $major_step=2; public $xlabel_offset=0,$xtick_offset=0; private $label_offset=0; // What offset should the displayed label have // i.e should we display 0,1,2 or 1,2,3,4 or 2,3,4 etc private $text_label_start=0; private $iManualTickPos = NULL, $iManualMinTickPos = NULL, $iManualTickLabels = NULL; private $iAdjustForDST = false; // If a date falls within the DST period add one hour to the diaplyed time function __construct() { $this->precision = -1; } // Return major step size in world coordinates function GetMajor() { return $this->major_step; } // Return minor step size in world coordinates function GetMinor() { return $this->minor_step; } // Set Minor and Major ticks (in world coordinates) function Set($aMajStep,$aMinStep=false) { if( $aMinStep==false ) { $aMinStep=$aMajStep; } if( $aMajStep <= 0 || $aMinStep <= 0 ) { JpGraphError::RaiseL(25064); //(" Minor or major step size is 0. Check that you haven't got an accidental SetTextTicks(0) in your code. If this is not the case you might have stumbled upon a bug in JpGraph. Please report this and if possible include the data that caused the problem."); } $this->major_step=$aMajStep; $this->minor_step=$aMinStep; $this->is_set = true; } function SetMajTickPositions($aMajPos,$aLabels=NULL) { $this->SetTickPositions($aMajPos,NULL,$aLabels); } function SetTickPositions($aMajPos,$aMinPos=NULL,$aLabels=NULL) { if( !is_array($aMajPos) || ($aMinPos!==NULL && !is_array($aMinPos)) ) { JpGraphError::RaiseL(25065);//('Tick positions must be specifued as an array()'); return; } $n=count($aMajPos); if( is_array($aLabels) && (count($aLabels) != $n) ) { JpGraphError::RaiseL(25066);//('When manually specifying tick positions and labels the number of labels must be the same as the number of specified ticks.'); } $this->iManualTickPos = $aMajPos; $this->iManualMinTickPos = $aMinPos; $this->iManualTickLabels = $aLabels; } function HaveManualLabels() { return count($this->iManualTickLabels) > 0; } // Specify all the tick positions manually and possible also the exact labels function _doManualTickPos($aScale) { $n=count($this->iManualTickPos); $m=count($this->iManualMinTickPos); $doLbl=count($this->iManualTickLabels) > 0; $this->maj_ticks_pos = array(); $this->maj_ticklabels_pos = array(); $this->ticks_pos = array(); // Now loop through the supplied positions and translate them to screen coordinates // and store them in the maj_label_positions $minScale = $aScale->scale[0]; $maxScale = $aScale->scale[1]; $j=0; for($i=0; $i < $n ; ++$i ) { // First make sure that the first tick is not lower than the lower scale value if( !isset($this->iManualTickPos[$i]) || $this->iManualTickPos[$i] < $minScale || $this->iManualTickPos[$i] > $maxScale) { continue; } $this->maj_ticks_pos[$j] = $aScale->Translate($this->iManualTickPos[$i]); $this->maj_ticklabels_pos[$j] = $this->maj_ticks_pos[$j]; // Set the minor tick marks the same as major if not specified if( $m <= 0 ) { $this->ticks_pos[$j] = $this->maj_ticks_pos[$j]; } if( $doLbl ) { $this->maj_ticks_label[$j] = $this->iManualTickLabels[$i]; } else { $this->maj_ticks_label[$j]=$this->_doLabelFormat($this->iManualTickPos[$i],$i,$n); } ++$j; } // Some sanity check if( count($this->maj_ticks_pos) < 2 ) { JpGraphError::RaiseL(25067);//('Your manually specified scale and ticks is not correct. The scale seems to be too small to hold any of the specified tickl marks.'); } // Setup the minor tick marks $j=0; for($i=0; $i < $m; ++$i ) { if( empty($this->iManualMinTickPos[$i]) || $this->iManualMinTickPos[$i] < $minScale || $this->iManualMinTickPos[$i] > $maxScale) { continue; } $this->ticks_pos[$j] = $aScale->Translate($this->iManualMinTickPos[$i]); ++$j; } } function _doAutoTickPos($aScale) { $maj_step_abs = $aScale->scale_factor*$this->major_step; $min_step_abs = $aScale->scale_factor*$this->minor_step; if( $min_step_abs==0 || $maj_step_abs==0 ) { JpGraphError::RaiseL(25068);//("A plot has an illegal scale. This could for example be that you are trying to use text autoscaling to draw a line plot with only one point or that the plot area is too small. It could also be that no input data value is numeric (perhaps only '-' or 'x')"); } // We need to make this an int since comparing it below // with the result from round() can give wrong result, such that // (40 < 40) == TRUE !!! $limit = (int)$aScale->scale_abs[1]; if( $aScale->textscale ) { // This can only be true for a X-scale (horizontal) // Define ticks for a text scale. This is slightly different from a // normal linear type of scale since the position might be adjusted // and the labels start at on $label = (float)$aScale->GetMinVal()+$this->text_label_start+$this->label_offset; $start_abs=$aScale->scale_factor*$this->text_label_start; $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; $x = $aScale->scale_abs[0]+$start_abs+$this->xlabel_offset*$min_step_abs; for( $i=0; $label <= $aScale->GetMaxVal()+$this->label_offset; ++$i ) { // Apply format to label $this->maj_ticks_label[$i]=$this->_doLabelFormat($label,$i,$nbrmajticks); $label+=$this->major_step; // The x-position of the tick marks can be different from the labels. // Note that we record the tick position (not the label) so that the grid // happen upon tick marks and not labels. $xtick=$aScale->scale_abs[0]+$start_abs+$this->xtick_offset*$min_step_abs+$i*$maj_step_abs; $this->maj_ticks_pos[$i]=$xtick; $this->maj_ticklabels_pos[$i] = round($x); $x += $maj_step_abs; } } else { $label = $aScale->GetMinVal(); $abs_pos = $aScale->scale_abs[0]; $j=0; $i=0; $step = round($maj_step_abs/$min_step_abs); if( $aScale->type == "x" ) { // For a normal linear type of scale the major ticks will always be multiples // of the minor ticks. In order to avoid any rounding issues the major ticks are // defined as every "step" minor ticks and not calculated separately $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; while( round($abs_pos) <= $limit ) { $this->ticks_pos[] = round($abs_pos); $this->ticks_label[] = $label; if( $step== 0 || $i % $step == 0 && $j < $nbrmajticks ) { $this->maj_ticks_pos[$j] = round($abs_pos); $this->maj_ticklabels_pos[$j] = round($abs_pos); $this->maj_ticks_label[$j]=$this->_doLabelFormat($label,$j,$nbrmajticks); ++$j; } ++$i; $abs_pos += $min_step_abs; $label+=$this->minor_step; } } elseif( $aScale->type == "y" ) { $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal())/$this->major_step)+1; while( round($abs_pos) >= $limit ) { $this->ticks_pos[$i] = round($abs_pos); $this->ticks_label[$i]=$label; if( $step== 0 || $i % $step == 0 && $j < $nbrmajticks) { $this->maj_ticks_pos[$j] = round($abs_pos); $this->maj_ticklabels_pos[$j] = round($abs_pos); $this->maj_ticks_label[$j]=$this->_doLabelFormat($label,$j,$nbrmajticks); ++$j; } ++$i; $abs_pos += $min_step_abs; $label += $this->minor_step; } } } } function AdjustForDST($aFlg=true) { $this->iAdjustForDST = $aFlg; } function _doLabelFormat($aVal,$aIdx,$aNbrTicks) { // If precision hasn't been specified set it to a sensible value if( $this->precision==-1 ) { $t = log10($this->minor_step); if( $t > 0 ) { $precision = 0; } else { $precision = -floor($t); } } else { $precision = $this->precision; } if( $this->label_formfunc != '' ) { $f=$this->label_formfunc; if( $this->label_formatstr == '' ) { $l = call_user_func($f,$aVal); } else { $l = sprintf($this->label_formatstr, call_user_func($f,$aVal)); } } elseif( $this->label_formatstr != '' || $this->label_dateformatstr != '' ) { if( $this->label_usedateformat ) { // Adjust the value to take daylight savings into account if (date("I",$aVal)==1 && $this->iAdjustForDST ) { // DST $aVal+=3600; } $l = date($this->label_formatstr,$aVal); if( $this->label_formatstr == 'W' ) { // If we use week formatting then add a single 'w' in front of the // week number to differentiate it from dates $l = 'w'.$l; } } else { if( $this->label_dateformatstr !== '' ) { // Adjust the value to take daylight savings into account if (date("I",$aVal)==1 && $this->iAdjustForDST ) { // DST $aVal+=3600; } $l = date($this->label_dateformatstr,$aVal); if( $this->label_formatstr == 'W' ) { // If we use week formatting then add a single 'w' in front of the // week number to differentiate it from dates $l = 'w'.$l; } } else { $l = sprintf($this->label_formatstr,$aVal); } } } else { $l = sprintf('%01.'.$precision.'f',round($aVal,$precision)); } if( ($this->supress_zerolabel && $l==0) || ($this->supress_first && $aIdx==0) || ($this->supress_last && $aIdx==$aNbrTicks-1) ) { $l=''; } return $l; } // Stroke ticks on either X or Y axis function _StrokeTicks($aImg,$aScale,$aPos) { $hor = $aScale->type == 'x'; $aImg->SetLineWeight($this->weight); // We need to make this an int since comparing it below // with the result from round() can give wrong result, such that // (40 < 40) == TRUE !!! $limit = (int)$aScale->scale_abs[1]; // A text scale doesn't have any minor ticks if( !$aScale->textscale ) { // Stroke minor ticks $yu = $aPos - $this->direction*$this->GetMinTickAbsSize(); $xr = $aPos + $this->direction*$this->GetMinTickAbsSize(); $n = count($this->ticks_pos); for($i=0; $i < $n; ++$i ) { if( !$this->supress_tickmarks && !$this->supress_minor_tickmarks) { if( $this->mincolor != '') { $aImg->PushColor($this->mincolor); } if( $hor ) { //if( $this->ticks_pos[$i] <= $limit ) $aImg->Line($this->ticks_pos[$i],$aPos,$this->ticks_pos[$i],$yu); } else { //if( $this->ticks_pos[$i] >= $limit ) $aImg->Line($aPos,$this->ticks_pos[$i],$xr,$this->ticks_pos[$i]); } if( $this->mincolor != '' ) { $aImg->PopColor(); } } } } // Stroke major ticks $yu = $aPos - $this->direction*$this->GetMajTickAbsSize(); $xr = $aPos + $this->direction*$this->GetMajTickAbsSize(); $nbrmajticks=round(($aScale->GetMaxVal()-$aScale->GetMinVal()-$this->text_label_start )/$this->major_step)+1; $n = count($this->maj_ticks_pos); for($i=0; $i < $n ; ++$i ) { if(!($this->xtick_offset > 0 && $i==$nbrmajticks-1) && !$this->supress_tickmarks) { if( $this->majcolor != '') { $aImg->PushColor($this->majcolor); } if( $hor ) { //if( $this->maj_ticks_pos[$i] <= $limit ) $aImg->Line($this->maj_ticks_pos[$i],$aPos,$this->maj_ticks_pos[$i],$yu); } else { //if( $this->maj_ticks_pos[$i] >= $limit ) $aImg->Line($aPos,$this->maj_ticks_pos[$i],$xr,$this->maj_ticks_pos[$i]); } if( $this->majcolor != '') { $aImg->PopColor(); } } } } // Draw linear ticks function Stroke($aImg,$aScale,$aPos) { if( $this->iManualTickPos != NULL ) { $this->_doManualTickPos($aScale); } else { $this->_doAutoTickPos($aScale); } $this->_StrokeTicks($aImg,$aScale,$aPos, $aScale->type == 'x' ); } //--------------- // PRIVATE METHODS // Spoecify the offset of the displayed tick mark with the tick "space" // Legal values for $o is [0,1] used to adjust where the tick marks and label // should be positioned within the major tick-size // $lo specifies the label offset and $to specifies the tick offset // this comes in handy for example in bar graphs where we wont no offset for the // tick but have the labels displayed halfway under the bars. function SetXLabelOffset($aLabelOff,$aTickOff=-1) { $this->xlabel_offset=$aLabelOff; if( $aTickOff==-1 ) { // Same as label offset $this->xtick_offset=$aLabelOff; } else { $this->xtick_offset=$aTickOff; } if( $aLabelOff>0 ) { $this->SupressLast(); // The last tick wont fit } } // Which tick label should we start with? function SetTextLabelStart($aTextLabelOff) { $this->text_label_start=$aTextLabelOff; } } // Class //=================================================== // CLASS LinearScale // Description: Handle linear scaling between screen and world //=================================================== class LinearScale { public $textscale=false; // Just a flag to let the Plot class find out if // we are a textscale or not. This is a cludge since // this information is available in Graph::axtype but // we don't have access to the graph object in the Plots // stroke method. So we let graph store the status here // when the linear scale is created. A real cludge... public $type; // is this x or y scale ? public $ticks=null; // Store ticks public $text_scale_off = 0; public $scale_abs=array(0,0); public $scale_factor; // Scale factor between world and screen public $off; // Offset between image edge and plot area public $scale=array(0,0); public $name = 'lin'; public $auto_ticks=false; // When using manual scale should the ticks be automatically set? public $world_abs_size; // Plot area size in pixels (Needed public in jpgraph_radar.php) public $world_size; // Plot area size in world coordinates public $intscale=false; // Restrict autoscale to integers protected $autoscale_min=false; // Forced minimum value, auto determine max protected $autoscale_max=false; // Forced maximum value, auto determine min private $gracetop=0,$gracebottom=0; function __construct($aMin=0,$aMax=0,$aType='y') { assert($aType=='x' || $aType=='y' ); assert($aMin<=$aMax); $this->type=$aType; $this->scale=array($aMin,$aMax); $this->world_size=$aMax-$aMin; $this->ticks = new LinearTicks(); } // Check if scale is set or if we should autoscale // We should do this is either scale or ticks has not been set function IsSpecified() { if( $this->GetMinVal()==$this->GetMaxVal() ) { // Scale not set return false; } return true; } // Set the minimum data value when the autoscaling is used. // Usefull if you want a fix minimum (like 0) but have an // automatic maximum function SetAutoMin($aMin) { $this->autoscale_min=$aMin; } // Set the minimum data value when the autoscaling is used. // Usefull if you want a fix minimum (like 0) but have an // automatic maximum function SetAutoMax($aMax) { $this->autoscale_max=$aMax; } // If the user manually specifies a scale should the ticks // still be set automatically? function SetAutoTicks($aFlag=true) { $this->auto_ticks = $aFlag; } // Specify scale "grace" value (top and bottom) function SetGrace($aGraceTop,$aGraceBottom=0) { if( $aGraceTop<0 || $aGraceBottom < 0 ) { JpGraphError::RaiseL(25069);//(" Grace must be larger then 0"); } $this->gracetop=$aGraceTop; $this->gracebottom=$aGraceBottom; } // Get the minimum value in the scale function GetMinVal() { return $this->scale[0]; } // get maximum value for scale function GetMaxVal() { return $this->scale[1]; } // Specify a new min/max value for sclae function Update($aImg,$aMin,$aMax) { $this->scale=array($aMin,$aMax); $this->world_size=$aMax-$aMin; $this->InitConstants($aImg); } // Translate between world and screen function Translate($aCoord) { if( !is_numeric($aCoord) ) { if( $aCoord != '' && $aCoord != '-' && $aCoord != 'x' ) { JpGraphError::RaiseL(25070);//('Your data contains non-numeric values.'); } return 0; } else { return round($this->off+($aCoord - $this->scale[0]) * $this->scale_factor); } } // Relative translate (don't include offset) usefull when we just want // to know the relative position (in pixels) on the axis function RelTranslate($aCoord) { if( !is_numeric($aCoord) ) { if( $aCoord != '' && $aCoord != '-' && $aCoord != 'x' ) { JpGraphError::RaiseL(25070);//('Your data contains non-numeric values.'); } return 0; } else { return ($aCoord - $this->scale[0]) * $this->scale_factor; } } // Restrict autoscaling to only use integers function SetIntScale($aIntScale=true) { $this->intscale=$aIntScale; } // Calculate an integer autoscale function IntAutoScale($img,$min,$max,$maxsteps,$majend=true) { // Make sure limits are integers $min=floor($min); $max=ceil($max); if( abs($min-$max)==0 ) { --$min; ++$max; } $maxsteps = floor($maxsteps); $gracetop=round(($this->gracetop/100.0)*abs($max-$min)); $gracebottom=round(($this->gracebottom/100.0)*abs($max-$min)); if( is_numeric($this->autoscale_min) ) { $min = ceil($this->autoscale_min); if( $min >= $max ) { JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.'); } } if( is_numeric($this->autoscale_max) ) { $max = ceil($this->autoscale_max); if( $min >= $max ) { JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.'); } } if( abs($min-$max ) == 0 ) { ++$max; --$min; } $min -= $gracebottom; $max += $gracetop; // First get tickmarks as multiples of 1, 10, ... if( $majend ) { list($num1steps,$adj1min,$adj1max,$maj1step) = $this->IntCalcTicks($maxsteps,$min,$max,1); } else { $adj1min = $min; $adj1max = $max; list($num1steps,$maj1step) = $this->IntCalcTicksFreeze($maxsteps,$min,$max,1); } if( abs($min-$max) > 2 ) { // Then get tick marks as 2:s 2, 20, ... if( $majend ) { list($num2steps,$adj2min,$adj2max,$maj2step) = $this->IntCalcTicks($maxsteps,$min,$max,5); } else { $adj2min = $min; $adj2max = $max; list($num2steps,$maj2step) = $this->IntCalcTicksFreeze($maxsteps,$min,$max,5); } } else { $num2steps = 10000; // Dummy high value so we don't choose this } if( abs($min-$max) > 5 ) { // Then get tickmarks as 5:s 5, 50, 500, ... if( $majend ) { list($num5steps,$adj5min,$adj5max,$maj5step) = $this->IntCalcTicks($maxsteps,$min,$max,2); } else { $adj5min = $min; $adj5max = $max; list($num5steps,$maj5step) = $this->IntCalcTicksFreeze($maxsteps,$min,$max,2); } } else { $num5steps = 10000; // Dummy high value so we don't choose this } // Check to see whichof 1:s, 2:s or 5:s fit better with // the requested number of major ticks $match1=abs($num1steps-$maxsteps); $match2=abs($num2steps-$maxsteps); if( !empty($maj5step) && $maj5step > 1 ) { $match5=abs($num5steps-$maxsteps); } else { $match5=10000; // Dummy high value } // Compare these three values and see which is the closest match // We use a 0.6 weight to gravitate towards multiple of 5:s if( $match1 < $match2 ) { if( $match1 < $match5 ) $r=1; else $r=3; } else { if( $match2 < $match5 ) $r=2; else $r=3; } // Minsteps are always the same as maxsteps for integer scale switch( $r ) { case 1: $this->ticks->Set($maj1step,$maj1step); $this->Update($img,$adj1min,$adj1max); break; case 2: $this->ticks->Set($maj2step,$maj2step); $this->Update($img,$adj2min,$adj2max); break; case 3: $this->ticks->Set($maj5step,$maj5step); $this->Update($img,$adj5min,$adj5max); break; default: JpGraphError::RaiseL(25073,$r);//('Internal error. Integer scale algorithm comparison out of bound (r=$r)'); } } // Calculate autoscale. Used if user hasn't given a scale and ticks // $maxsteps is the maximum number of major tickmarks allowed. function AutoScale($img,$min,$max,$maxsteps,$majend=true) { if( !is_numeric($min) || !is_numeric($max) ) { JpGraphError::Raise(25044); } if( $this->intscale ) { $this->IntAutoScale($img,$min,$max,$maxsteps,$majend); return; } if( abs($min-$max) < 0.00001 ) { // We need some difference to be able to autoscale // make it 5% above and 5% below value if( $min==0 && $max==0 ) { // Special case $min=-1; $max=1; } else { $delta = (abs($max)+abs($min))*0.005; $min -= $delta; $max += $delta; } } $gracetop=($this->gracetop/100.0)*abs($max-$min); $gracebottom=($this->gracebottom/100.0)*abs($max-$min); if( is_numeric($this->autoscale_min) ) { $min = $this->autoscale_min; if( $min >= $max ) { JpGraphError::RaiseL(25071);//('You have specified a min value with SetAutoMin() which is larger than the maximum value used for the scale. This is not possible.'); } if( abs($min-$max ) < 0.001 ) { $max *= 1.2; } } if( is_numeric($this->autoscale_max) ) { $max = $this->autoscale_max; if( $min >= $max ) { JpGraphError::RaiseL(25072);//('You have specified a max value with SetAutoMax() which is smaller than the miminum value used for the scale. This is not possible.'); } if( abs($min-$max ) < 0.001 ) { $min *= 0.8; } } $min -= $gracebottom; $max += $gracetop; // First get tickmarks as multiples of 0.1, 1, 10, ... if( $majend ) { list($num1steps,$adj1min,$adj1max,$min1step,$maj1step) = $this->CalcTicks($maxsteps,$min,$max,1,2); } else { $adj1min=$min; $adj1max=$max; list($num1steps,$min1step,$maj1step) = $this->CalcTicksFreeze($maxsteps,$min,$max,1,2,false); } // Then get tick marks as 2:s 0.2, 2, 20, ... if( $majend ) { list($num2steps,$adj2min,$adj2max,$min2step,$maj2step) = $this->CalcTicks($maxsteps,$min,$max,5,2); } else { $adj2min=$min; $adj2max=$max; list($num2steps,$min2step,$maj2step) = $this->CalcTicksFreeze($maxsteps,$min,$max,5,2,false); } // Then get tickmarks as 5:s 0.05, 0.5, 5, 50, ... if( $majend ) { list($num5steps,$adj5min,$adj5max,$min5step,$maj5step) = $this->CalcTicks($maxsteps,$min,$max,2,5); } else { $adj5min=$min; $adj5max=$max; list($num5steps,$min5step,$maj5step) = $this->CalcTicksFreeze($maxsteps,$min,$max,2,5,false); } // Check to see whichof 1:s, 2:s or 5:s fit better with // the requested number of major ticks $match1=abs($num1steps-$maxsteps); $match2=abs($num2steps-$maxsteps); $match5=abs($num5steps-$maxsteps); // Compare these three values and see which is the closest match // We use a 0.8 weight to gravitate towards multiple of 5:s $r=$this->MatchMin3($match1,$match2,$match5,0.8); switch( $r ) { case 1: $this->Update($img,$adj1min,$adj1max); $this->ticks->Set($maj1step,$min1step); break; case 2: $this->Update($img,$adj2min,$adj2max); $this->ticks->Set($maj2step,$min2step); break; case 3: $this->Update($img,$adj5min,$adj5max); $this->ticks->Set($maj5step,$min5step); break; } } //--------------- // PRIVATE METHODS // This method recalculates all constants that are depending on the // margins in the image. If the margins in the image are changed // this method should be called for every scale that is registred with // that image. Should really be installed as an observer of that image. function InitConstants($img) { if( $this->type=='x' ) { $this->world_abs_size=$img->width - $img->left_margin - $img->right_margin; $this->off=$img->left_margin; $this->scale_factor = 0; if( $this->world_size > 0 ) { $this->scale_factor=$this->world_abs_size/($this->world_size*1.0); } } else { // y scale $this->world_abs_size=$img->height - $img->top_margin - $img->bottom_margin; $this->off=$img->top_margin+$this->world_abs_size; $this->scale_factor = 0; if( $this->world_size > 0 ) { $this->scale_factor=-$this->world_abs_size/($this->world_size*1.0); } } $size = $this->world_size * $this->scale_factor; $this->scale_abs=array($this->off,$this->off + $size); } // Initialize the conversion constants for this scale // This tries to pre-calculate as much as possible to speed up the // actual conversion (with Translate()) later on // $start =scale start in absolute pixels (for x-scale this is an y-position // and for an y-scale this is an x-position // $len =absolute length in pixels of scale function SetConstants($aStart,$aLen) { $this->world_abs_size=$aLen; $this->off=$aStart; if( $this->world_size<=0 ) { // This should never ever happen !! JpGraphError::RaiseL(25074); //("You have unfortunately stumbled upon a bug in JpGraph. It seems like the scale range is ".$this->world_size." [for ".$this->type." scale]
    Please report Bug #01 to jpgraph@aditus.nu and include the script that gave this error. This problem could potentially be caused by trying to use \"illegal\" values in the input data arrays (like trying to send in strings or only NULL values) which causes the autoscaling to fail."); } // scale_factor = number of pixels per world unit $this->scale_factor=$this->world_abs_size/($this->world_size*1.0); // scale_abs = start and end points of scale in absolute pixels $this->scale_abs=array($this->off,$this->off+$this->world_size*$this->scale_factor); } // Calculate number of ticks steps with a specific division // $a is the divisor of 10**x to generate the first maj tick intervall // $a=1, $b=2 give major ticks with multiple of 10, ...,0.1,1,10,... // $a=5, $b=2 give major ticks with multiple of 2:s ...,0.2,2,20,... // $a=2, $b=5 give major ticks with multiple of 5:s ...,0.5,5,50,... // We return a vector of // [$numsteps,$adjmin,$adjmax,$minstep,$majstep] // If $majend==true then the first and last marks on the axis will be major // labeled tick marks otherwise it will be adjusted to the closest min tick mark function CalcTicks($maxsteps,$min,$max,$a,$b,$majend=true) { $diff=$max-$min; if( $diff==0 ) { $ld=0; } else { $ld=floor(log10($diff)); } // Gravitate min towards zero if we are close if( $min>0 && $min < pow(10,$ld) ) $min=0; //$majstep=pow(10,$ld-1)/$a; $majstep=pow(10,$ld)/$a; $minstep=$majstep/$b; $adjmax=ceil($max/$minstep)*$minstep; $adjmin=floor($min/$minstep)*$minstep; $adjdiff = $adjmax-$adjmin; $numsteps=$adjdiff/$majstep; while( $numsteps>$maxsteps ) { $majstep=pow(10,$ld)/$a; $numsteps=$adjdiff/$majstep; ++$ld; } $minstep=$majstep/$b; $adjmin=floor($min/$minstep)*$minstep; $adjdiff = $adjmax-$adjmin; if( $majend ) { $adjmin = floor($min/$majstep)*$majstep; $adjdiff = $adjmax-$adjmin; $adjmax = ceil($adjdiff/$majstep)*$majstep+$adjmin; } else { $adjmax=ceil($max/$minstep)*$minstep; } return array($numsteps,$adjmin,$adjmax,$minstep,$majstep); } function CalcTicksFreeze($maxsteps,$min,$max,$a,$b) { // Same as CalcTicks but don't adjust min/max values $diff=$max-$min; if( $diff==0 ) { $ld=0; } else { $ld=floor(log10($diff)); } //$majstep=pow(10,$ld-1)/$a; $majstep=pow(10,$ld)/$a; $minstep=$majstep/$b; $numsteps=floor($diff/$majstep); while( $numsteps > $maxsteps ) { $majstep=pow(10,$ld)/$a; $numsteps=floor($diff/$majstep); ++$ld; } $minstep=$majstep/$b; return array($numsteps,$minstep,$majstep); } function IntCalcTicks($maxsteps,$min,$max,$a,$majend=true) { $diff=$max-$min; if( $diff==0 ) { JpGraphError::RaiseL(25075);//('Can\'t automatically determine ticks since min==max.'); } else { $ld=floor(log10($diff)); } // Gravitate min towards zero if we are close if( $min>0 && $min < pow(10,$ld) ) { $min=0; } if( $ld == 0 ) { $ld=1; } if( $a == 1 ) { $majstep = 1; } else { $majstep=pow(10,$ld)/$a; } $adjmax=ceil($max/$majstep)*$majstep; $adjmin=floor($min/$majstep)*$majstep; $adjdiff = $adjmax-$adjmin; $numsteps=$adjdiff/$majstep; while( $numsteps>$maxsteps ) { $majstep=pow(10,$ld)/$a; $numsteps=$adjdiff/$majstep; ++$ld; } $adjmin=floor($min/$majstep)*$majstep; $adjdiff = $adjmax-$adjmin; if( $majend ) { $adjmin = floor($min/$majstep)*$majstep; $adjdiff = $adjmax-$adjmin; $adjmax = ceil($adjdiff/$majstep)*$majstep+$adjmin; } else { $adjmax=ceil($max/$majstep)*$majstep; } return array($numsteps,$adjmin,$adjmax,$majstep); } function IntCalcTicksFreeze($maxsteps,$min,$max,$a) { // Same as IntCalcTick but don't change min/max values $diff=$max-$min; if( $diff==0 ) { JpGraphError::RaiseL(25075);//('Can\'t automatically determine ticks since min==max.'); } else { $ld=floor(log10($diff)); } if( $ld == 0 ) { $ld=1; } if( $a == 1 ) { $majstep = 1; } else { $majstep=pow(10,$ld)/$a; } $numsteps=floor($diff/$majstep); while( $numsteps > $maxsteps ) { $majstep=pow(10,$ld)/$a; $numsteps=floor($diff/$majstep); ++$ld; } return array($numsteps,$majstep); } // Determine the minimum of three values witha weight for last value function MatchMin3($a,$b,$c,$weight) { if( $a < $b ) { if( $a < ($c*$weight) ) { return 1; // $a smallest } else { return 3; // $c smallest } } elseif( $b < ($c*$weight) ) { return 2; // $b smallest } return 3; // $c smallest } } // Class //=================================================== // CLASS DisplayValue // Description: Used to print data values at data points //=================================================== class DisplayValue { public $margin=5; public $show=false; public $valign='',$halign='center'; public $format='%.1f',$negformat=''; private $ff=FF_FONT1,$fs=FS_NORMAL,$fsize=10; private $iFormCallback=''; private $angle=0; private $color='navy',$negcolor=''; private $iHideZero=false; public $txt=null; function __construct() { $this->txt = new Text(); } function Show($aFlag=true) { $this->show=$aFlag; } function SetColor($aColor,$aNegcolor='') { $this->color = $aColor; $this->negcolor = $aNegcolor; } function SetFont($aFontFamily,$aFontStyle=FS_NORMAL,$aFontSize=10) { $this->ff=$aFontFamily; $this->fs=$aFontStyle; $this->fsize=$aFontSize; } function ApplyFont($aImg) { $aImg->SetFont($this->ff,$this->fs,$this->fsize); } function SetMargin($aMargin) { $this->margin = $aMargin; } function SetAngle($aAngle) { $this->angle = $aAngle; } function SetAlign($aHAlign,$aVAlign='') { $this->halign = $aHAlign; $this->valign = $aVAlign; } function SetFormat($aFormat,$aNegFormat='') { $this->format= $aFormat; $this->negformat= $aNegFormat; } function SetFormatCallback($aFunc) { $this->iFormCallback = $aFunc; } function HideZero($aFlag=true) { $this->iHideZero=$aFlag; } function Stroke($img,$aVal,$x,$y) { if( $this->show ) { if( $this->negformat=='' ) { $this->negformat=$this->format; } if( $this->negcolor=='' ) { $this->negcolor=$this->color; } if( $aVal===NULL || (is_string($aVal) && ($aVal=='' || $aVal=='-' || $aVal=='x' ) ) ) { return; } if( is_numeric($aVal) && $aVal==0 && $this->iHideZero ) { return; } // Since the value is used in different cirumstances we need to check what // kind of formatting we shall use. For example, to display values in a line // graph we simply display the formatted value, but in the case where the user // has already specified a text string we don't fo anything. if( $this->iFormCallback != '' ) { $f = $this->iFormCallback; $sval = call_user_func($f,$aVal); } elseif( is_numeric($aVal) ) { if( $aVal >= 0 ) { $sval=sprintf($this->format,$aVal); } else { $sval=sprintf($this->negformat,$aVal); } } else { $sval=$aVal; } $y = $y-sign($aVal)*$this->margin; $this->txt->Set($sval); $this->txt->SetPos($x,$y); $this->txt->SetFont($this->ff,$this->fs,$this->fsize); if( $this->valign == '' ) { if( $aVal >= 0 ) { $valign = "bottom"; } else { $valign = "top"; } } else { $valign = $this->valign; } $this->txt->Align($this->halign,$valign); $this->txt->SetOrientation($this->angle); if( $aVal > 0 ) { $this->txt->SetColor($this->color); } else { $this->txt->SetColor($this->negcolor); } $this->txt->Stroke($img); } } } //=================================================== // CLASS Plot // Description: Abstract base class for all concrete plot classes //=================================================== class Plot { public $numpoints=0; public $value; public $legend=''; public $coords=array(); public $color='black'; public $hidelegend=false; public $line_weight=1; public $csimtargets=array(),$csimwintargets=array(); // Array of targets for CSIM public $csimareas=''; // Resultant CSIM area tags public $csimalts=null; // ALT:s for corresponding target public $legendcsimtarget='',$legendcsimwintarget=''; public $legendcsimalt=''; protected $weight=1; protected $center=false; function __construct($aDatay,$aDatax=false) { $this->numpoints = count($aDatay); if( $this->numpoints==0 ) { JpGraphError::RaiseL(25121);//("Empty input data array specified for plot. Must have at least one data point."); } $this->coords[0]=$aDatay; if( is_array($aDatax) ) { $this->coords[1]=$aDatax; $n = count($aDatax); for( $i=0; $i < $n; ++$i ) { if( !is_numeric($aDatax[$i]) ) { JpGraphError::RaiseL(25070); } } } $this->value = new DisplayValue(); } // Stroke the plot // "virtual" function which must be implemented by // the subclasses function Stroke($aImg,$aXScale,$aYScale) { JpGraphError::RaiseL(25122);//("JpGraph: Stroke() must be implemented by concrete subclass to class Plot"); } function HideLegend($f=true) { $this->hidelegend = $f; } function DoLegend($graph) { if( !$this->hidelegend ) $this->Legend($graph); } function StrokeDataValue($img,$aVal,$x,$y) { $this->value->Stroke($img,$aVal,$x,$y); } // Set href targets for CSIM function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') { $this->csimtargets=$aTargets; $this->csimwintargets=$aWinTargets; $this->csimalts=$aAlts; } // Get all created areas function GetCSIMareas() { return $this->csimareas; } // "Virtual" function which gets called before any scale // or axis are stroked used to do any plot specific adjustment function PreStrokeAdjust($aGraph) { if( substr($aGraph->axtype,0,4) == "text" && (isset($this->coords[1])) ) { JpGraphError::RaiseL(25123);//("JpGraph: You can't use a text X-scale with specified X-coords. Use a \"int\" or \"lin\" scale instead."); } return true; } // Virtual function to the the concrete plot class to make any changes to the graph // and scale before the stroke process begins function PreScaleSetup($aGraph) { // Empty } // Get minimum values in plot function Min() { if( isset($this->coords[1]) ) { $x=$this->coords[1]; } else { $x=''; } if( $x != '' && count($x) > 0 ) { $xm=min($x); } else { $xm=0; } $y=$this->coords[0]; $cnt = count($y); if( $cnt > 0 ) { $i=0; while( $i<$cnt && !is_numeric($ym=$y[$i]) ) { $i++; } while( $i < $cnt) { if( is_numeric($y[$i]) ) { $ym=min($ym,$y[$i]); } ++$i; } } else { $ym=''; } return array($xm,$ym); } // Get maximum value in plot function Max() { if( isset($this->coords[1]) ) { $x=$this->coords[1]; } else { $x=''; } if( $x!='' && count($x) > 0 ) { $xm=max($x); } else { $xm = $this->numpoints-1; } $y=$this->coords[0]; if( count($y) > 0 ) { $cnt = count($y); $i=0; while( $i<$cnt && !is_numeric($ym=$y[$i]) ) { $i++; } while( $i < $cnt ) { if( is_numeric($y[$i]) ) { $ym=max($ym,$y[$i]); } ++$i; } } else { $ym=''; } return array($xm,$ym); } function SetColor($aColor) { $this->color=$aColor; } function SetLegend($aLegend,$aCSIM='',$aCSIMAlt='',$aCSIMWinTarget='') { $this->legend = $aLegend; $this->legendcsimtarget = $aCSIM; $this->legendcsimwintarget = $aCSIMWinTarget; $this->legendcsimalt = $aCSIMAlt; } function SetWeight($aWeight) { $this->weight=$aWeight; } function SetLineWeight($aWeight=1) { $this->line_weight=$aWeight; } function SetCenter($aCenter=true) { $this->center = $aCenter; } // This method gets called by Graph class to plot anything that should go // into the margin after the margin color has been set. function StrokeMargin($aImg) { return true; } // Framework function the chance for each plot class to set a legend function Legend($aGraph) { if( $this->legend != '' ) { $aGraph->legend->Add($this->legend,$this->color,'',0,$this->legendcsimtarget,$this->legendcsimalt,$this->legendcsimwintarget); } } } // Class // Provide a deterministic list of new colors whenever the getColor() method // is called. Used to automatically set colors of plots. class ColorFactory { static private $iIdx = 0; static private $iColorList = array( 'black', 'blue', 'orange', 'darkgreen', 'red', 'AntiqueWhite3', 'aquamarine3', 'azure4', 'brown', 'cadetblue3', 'chartreuse4', 'chocolate', 'darkblue', 'darkgoldenrod3', 'darkorchid3', 'darksalmon', 'darkseagreen4', 'deepskyblue2', 'dodgerblue4', 'gold3', 'hotpink', 'lawngreen', 'lightcoral', 'lightpink3', 'lightseagreen', 'lightslateblue', 'mediumpurple', 'olivedrab', 'orangered1', 'peru', 'slategray', 'yellow4', 'springgreen2'); static private $iNum = 33; static function getColor() { if( ColorFactory::$iIdx >= ColorFactory::$iNum ) ColorFactory::$iIdx = 0; return ColorFactory::$iColorList[ColorFactory::$iIdx++]; } } // ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_ttf.inc.php0000644000175000017500000005043212225176641023010 0ustar danieldanielg2312 == null ) { include_once 'jpgraph_gb2312.php' ; $this->g2312 = new GB2312toUTF8(); } return $this->g2312->gb2utf8($aTxt); } elseif( $aFF === FF_BIG5 ) { if( !function_exists('iconv') ) { JpGraphError::RaiseL(25006); //('Usage of FF_CHINESE (FF_BIG5) font family requires that your PHP setup has the iconv() function. By default this is not compiled into PHP (needs the "--width-iconv" when configured).'); } return iconv('BIG5','UTF-8',$aTxt); } elseif( ASSUME_EUCJP_ENCODING && ($aFF == FF_MINCHO || $aFF == FF_GOTHIC || $aFF == FF_PMINCHO || $aFF == FF_PGOTHIC) ) { if( !function_exists('mb_convert_encoding') ) { JpGraphError::RaiseL(25127); } return mb_convert_encoding($aTxt, 'UTF-8','EUC-JP'); } elseif( $aFF == FF_DAVID || $aFF == FF_MIRIAM || $aFF == FF_AHRON ) { return LanguageConv::heb_iso2uni($aTxt); } else return $aTxt; } // Translate iso encoding to unicode public static function iso2uni ($isoline){ $uniline=''; for ($i=0; $i < strlen($isoline); $i++){ $thischar=substr($isoline,$i,1); $charcode=ord($thischar); $uniline.=($charcode>175) ? "&#" . (1040+($charcode-176)). ";" : $thischar; } return $uniline; } // Translate greek iso encoding to unicode public static function gr_iso2uni ($isoline) { $uniline=''; for ($i=0; $i < strlen($isoline); $i++) { $thischar=substr($isoline,$i,1); $charcode=ord($thischar); $uniline.=($charcode>179 && $charcode!=183 && $charcode!=187 && $charcode!=189) ? "&#" . (900+($charcode-180)). ";" : $thischar; } return $uniline; } // Translate greek win encoding to unicode public static function gr_win2uni ($winline) { $uniline=''; for ($i=0; $i < strlen($winline); $i++) { $thischar=substr($winline,$i,1); $charcode=ord($thischar); if ($charcode==161 || $charcode==162) { $uniline.="&#" . (740+$charcode). ";"; } else { $uniline.=(($charcode>183 && $charcode!=187 && $charcode!=189) || $charcode==180) ? "&#" . (900+($charcode-180)). ";" : $thischar; } } return $uniline; } public static function heb_iso2uni($isoline) { $isoline = hebrev($isoline); $o = ''; $n = strlen($isoline); for($i=0; $i < $n; $i++) { $c=ord( substr($isoline,$i,1) ); $o .= ($c > 223) && ($c < 251) ? '&#'.(1264+$c).';' : chr($c); } return utf8_encode($o); } } //============================================================= // CLASS TTF // Description: Handle TTF font names and mapping and loading of // font files //============================================================= class TTF { private $font_files,$style_names; function __construct() { // String names for font styles to be used in error messages $this->style_names=array( FS_NORMAL =>'normal', FS_BOLD =>'bold', FS_ITALIC =>'italic', FS_BOLDITALIC =>'bolditalic'); // File names for available fonts $this->font_files=array( FF_COURIER => array(FS_NORMAL =>'cour.ttf', FS_BOLD =>'courbd.ttf', FS_ITALIC =>'couri.ttf', FS_BOLDITALIC =>'courbi.ttf' ), FF_GEORGIA => array(FS_NORMAL =>'georgia.ttf', FS_BOLD =>'georgiab.ttf', FS_ITALIC =>'georgiai.ttf', FS_BOLDITALIC =>'' ), FF_TREBUCHE =>array(FS_NORMAL =>'trebuc.ttf', FS_BOLD =>'trebucbd.ttf', FS_ITALIC =>'trebucit.ttf', FS_BOLDITALIC =>'trebucbi.ttf' ), FF_VERDANA => array(FS_NORMAL =>'verdana.ttf', FS_BOLD =>'verdanab.ttf', FS_ITALIC =>'verdanai.ttf', FS_BOLDITALIC =>'' ), FF_TIMES => array(FS_NORMAL =>'times.ttf', FS_BOLD =>'timesbd.ttf', FS_ITALIC =>'timesi.ttf', FS_BOLDITALIC =>'timesbi.ttf' ), FF_COMIC => array(FS_NORMAL =>'comic.ttf', FS_BOLD =>'comicbd.ttf', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_ARIAL => array(FS_NORMAL =>'arial.ttf', FS_BOLD =>'arialbd.ttf', FS_ITALIC =>'ariali.ttf', FS_BOLDITALIC =>'arialbi.ttf' ) , FF_VERA => array(FS_NORMAL =>'Vera.ttf', FS_BOLD =>'VeraBd.ttf', FS_ITALIC =>'VeraIt.ttf', FS_BOLDITALIC =>'VeraBI.ttf' ), FF_VERAMONO => array(FS_NORMAL =>'VeraMono.ttf', FS_BOLD =>'VeraMoBd.ttf', FS_ITALIC =>'VeraMoIt.ttf', FS_BOLDITALIC =>'VeraMoBI.ttf' ), FF_VERASERIF=> array(FS_NORMAL =>'VeraSe.ttf', FS_BOLD =>'VeraSeBd.ttf', FS_ITALIC =>'', FS_BOLDITALIC =>'' ) , /* Chinese fonts */ FF_SIMSUN => array( FS_NORMAL =>'simsun.ttc', FS_BOLD =>'simhei.ttf', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_CHINESE => array( FS_NORMAL =>CHINESE_TTF_FONT, FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_BIG5 => array( FS_NORMAL =>CHINESE_TTF_FONT, FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), /* Japanese fonts */ FF_MINCHO => array( FS_NORMAL =>MINCHO_TTF_FONT, FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_PMINCHO => array( FS_NORMAL =>PMINCHO_TTF_FONT, FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_GOTHIC => array( FS_NORMAL =>GOTHIC_TTF_FONT, FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_PGOTHIC => array( FS_NORMAL =>PGOTHIC_TTF_FONT, FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), /* Hebrew fonts */ FF_DAVID => array( FS_NORMAL =>'DAVIDNEW.TTF', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_MIRIAM => array( FS_NORMAL =>'MRIAMY.TTF', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_AHRON => array( FS_NORMAL =>'ahronbd.ttf', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), /* Misc fonts */ FF_DIGITAL => array( FS_NORMAL =>'DIGIRU__.TTF', FS_BOLD =>'Digirtu_.ttf', FS_ITALIC =>'Digir___.ttf', FS_BOLDITALIC =>'DIGIRT__.TTF' ), /* This is an experimental font for the speedometer development FF_SPEEDO => array( FS_NORMAL =>'Speedo.ttf', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), */ FF_COMPUTER => array( FS_NORMAL =>'COMPUTER.TTF', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_CALCULATOR => array( FS_NORMAL =>'Triad_xs.ttf', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), /* Dejavu fonts */ FF_DV_SANSSERIF => array( FS_NORMAL =>array('DejaVuSans.ttf'), FS_BOLD =>array('DejaVuSans-Bold.ttf','DejaVuSansBold.ttf'), FS_ITALIC =>array('DejaVuSans-Oblique.ttf','DejaVuSansOblique.ttf'), FS_BOLDITALIC =>array('DejaVuSans-BoldOblique.ttf','DejaVuSansBoldOblique.ttf') ), FF_DV_SANSSERIFMONO => array( FS_NORMAL =>array('DejaVuSansMono.ttf','DejaVuMonoSans.ttf'), FS_BOLD =>array('DejaVuSansMono-Bold.ttf','DejaVuMonoSansBold.ttf'), FS_ITALIC =>array('DejaVuSansMono-Oblique.ttf','DejaVuMonoSansOblique.ttf'), FS_BOLDITALIC =>array('DejaVuSansMono-BoldOblique.ttf','DejaVuMonoSansBoldOblique.ttf') ), FF_DV_SANSSERIFCOND => array( FS_NORMAL =>array('DejaVuSansCondensed.ttf','DejaVuCondensedSans.ttf'), FS_BOLD =>array('DejaVuSansCondensed-Bold.ttf','DejaVuCondensedSansBold.ttf'), FS_ITALIC =>array('DejaVuSansCondensed-Oblique.ttf','DejaVuCondensedSansOblique.ttf'), FS_BOLDITALIC =>array('DejaVuSansCondensed-BoldOblique.ttf','DejaVuCondensedSansBoldOblique.ttf') ), FF_DV_SERIF => array( FS_NORMAL =>array('DejaVuSerif.ttf'), FS_BOLD =>array('DejaVuSerif-Bold.ttf','DejaVuSerifBold.ttf'), FS_ITALIC =>array('DejaVuSerif-Italic.ttf','DejaVuSerifItalic.ttf'), FS_BOLDITALIC =>array('DejaVuSerif-BoldItalic.ttf','DejaVuSerifBoldItalic.ttf') ), FF_DV_SERIFCOND => array( FS_NORMAL =>array('DejaVuSerifCondensed.ttf','DejaVuCondensedSerif.ttf'), FS_BOLD =>array('DejaVuSerifCondensed-Bold.ttf','DejaVuCondensedSerifBold.ttf'), FS_ITALIC =>array('DejaVuSerifCondensed-Italic.ttf','DejaVuCondensedSerifItalic.ttf'), FS_BOLDITALIC =>array('DejaVuSerifCondensed-BoldItalic.ttf','DejaVuCondensedSerifBoldItalic.ttf') ), /* Placeholders for defined fonts */ FF_USERFONT1 => array( FS_NORMAL =>'', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_USERFONT2 => array( FS_NORMAL =>'', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), FF_USERFONT3 => array( FS_NORMAL =>'', FS_BOLD =>'', FS_ITALIC =>'', FS_BOLDITALIC =>'' ), ); } //--------------- // PUBLIC METHODS // Create the TTF file from the font specification function File($family,$style=FS_NORMAL) { $fam = @$this->font_files[$family]; if( !$fam ) { JpGraphError::RaiseL(25046,$family);//("Specified TTF font family (id=$family) is unknown or does not exist. Please note that TTF fonts are not distributed with JpGraph for copyright reasons. You can find the MS TTF WEB-fonts (arial, courier etc) for download at http://corefonts.sourceforge.net/"); } $ff = @$fam[$style]; if( is_array($ff) ) { // There are several optional file names. They are tried in order // and the first one found is used $n = count($ff); } else { $n = 1; $ff = array($ff); } $i = 0; do { $f = $ff[$i]; // All font families are guaranteed to have the normal style if( $f==='' ) JpGraphError::RaiseL(25047,$this->style_names[$style],$this->font_files[$family][FS_NORMAL]);//('Style "'.$this->style_names[$style].'" is not available for font family '.$this->font_files[$family][FS_NORMAL].'.'); if( !$f ) { JpGraphError::RaiseL(25048,$fam);//("Unknown font style specification [$fam]."); } if ($family >= FF_MINCHO && $family <= FF_PGOTHIC) { $f = MBTTF_DIR.$f; } else { $f = TTF_DIR.$f; } ++$i; } while( $i < $n && (file_exists($f) === false || is_readable($f) === false) ); if( !file_exists($f) ) { JpGraphError::RaiseL(25049,$f);//("Font file \"$f\" is not readable or does not exist."); } return $f; } function SetUserFont($aNormal,$aBold='',$aItalic='',$aBoldIt='') { $this->font_files[FF_USERFONT] = array(FS_NORMAL => $aNormal, FS_BOLD => $aBold, FS_ITALIC => $aItalic, FS_BOLDITALIC => $aBoldIt ) ; } function SetUserFont1($aNormal,$aBold='',$aItalic='',$aBoldIt='') { $this->font_files[FF_USERFONT1] = array(FS_NORMAL => $aNormal, FS_BOLD => $aBold, FS_ITALIC => $aItalic, FS_BOLDITALIC => $aBoldIt ) ; } function SetUserFont2($aNormal,$aBold='',$aItalic='',$aBoldIt='') { $this->font_files[FF_USERFONT2] = array(FS_NORMAL => $aNormal, FS_BOLD => $aBold, FS_ITALIC => $aItalic, FS_BOLDITALIC => $aBoldIt ) ; } function SetUserFont3($aNormal,$aBold='',$aItalic='',$aBoldIt='') { $this->font_files[FF_USERFONT3] = array(FS_NORMAL => $aNormal, FS_BOLD => $aBold, FS_ITALIC => $aItalic, FS_BOLDITALIC => $aBoldIt ) ; } } // Class //============================================================================= // CLASS SymChar // Description: Code values for some commonly used characters that // normally isn't available directly on the keyboard, for example // mathematical and greek symbols. //============================================================================= class SymChar { static function Get($aSymb,$aCapital=FALSE) { $iSymbols = array( /* Greek */ array('alpha','03B1','0391'), array('beta','03B2','0392'), array('gamma','03B3','0393'), array('delta','03B4','0394'), array('epsilon','03B5','0395'), array('zeta','03B6','0396'), array('ny','03B7','0397'), array('eta','03B8','0398'), array('theta','03B8','0398'), array('iota','03B9','0399'), array('kappa','03BA','039A'), array('lambda','03BB','039B'), array('mu','03BC','039C'), array('nu','03BD','039D'), array('xi','03BE','039E'), array('omicron','03BF','039F'), array('pi','03C0','03A0'), array('rho','03C1','03A1'), array('sigma','03C3','03A3'), array('tau','03C4','03A4'), array('upsilon','03C5','03A5'), array('phi','03C6','03A6'), array('chi','03C7','03A7'), array('psi','03C8','03A8'), array('omega','03C9','03A9'), /* Money */ array('euro','20AC'), array('yen','00A5'), array('pound','20A4'), /* Math */ array('approx','2248'), array('neq','2260'), array('not','2310'), array('def','2261'), array('inf','221E'), array('sqrt','221A'), array('int','222B'), /* Misc */ array('copy','00A9'), array('para','00A7'), array('tm','2122'), /* Trademark symbol */ array('rtm','00AE'), /* Registered trademark */ array('degree','00b0'), array('lte','2264'), /* Less than or equal */ array('gte','2265'), /* Greater than or equal */ ); $n = count($iSymbols); $i=0; $found = false; $aSymb = strtolower($aSymb); while( $i < $n && !$found ) { $found = $aSymb === $iSymbols[$i++][0]; } if( $found ) { $ca = $iSymbols[--$i]; if( $aCapital && count($ca)==3 ) $s = $ca[2]; else $s = $ca[1]; return sprintf('&#%04d;',hexdec($s)); } else return ''; } } ?> loganalyzer-3.6.5/src/classes/jpgraph/gd_image.inc.php0000644000175000017500000022130112225176641022227 0ustar danieldanielCreateImgCanvas($aWidth,$aHeight); if( $aSetAutoMargin ) { $this->SetAutoMargin(); } if( !$this->SetImgFormat($aFormat) ) { JpGraphError::RaiseL(25081,$aFormat);//("JpGraph: Selected graphic format is either not supported or unknown [$aFormat]"); } $this->ttf = new TTF(); $this->langconv = new LanguageConv(); } // Enable interlacing in images function SetInterlace($aFlg=true) { $this->iInterlace=$aFlg; } // Should we use anti-aliasing. Note: This really slows down graphics! function SetAntiAliasing($aFlg=true) { $this->use_anti_aliasing = $aFlg; if( function_exists('imageantialias') ) { imageantialias($this->img,$aFlg); } else { JpGraphError::RaiseL(25128);//('The function imageantialias() is not available in your PHP installation. Use the GD version that comes with PHP and not the standalone version.') } } function GetAntiAliasing() { return $this->use_anti_aliasing ; } function CreateRawCanvas($aWidth=0,$aHeight=0) { if( $aWidth <= 1 || $aHeight <= 1 ) { JpGraphError::RaiseL(25082,$aWidth,$aHeight);//("Illegal sizes specified for width or height when creating an image, (width=$aWidth, height=$aHeight)"); } $this->img = @imagecreatetruecolor($aWidth, $aHeight); if( $this->img < 1 ) { JpGraphError::RaiseL(25126); //die("Can't create truecolor image. Check that you really have GD2 library installed."); } $this->SetAlphaBlending(); if( $this->iInterlace ) { imageinterlace($this->img,1); } if( $this->rgb != null ) { $this->rgb->img = $this->img ; } else { $this->rgb = new RGB($this->img); } } function CloneCanvasH() { $oldimage = $this->img; $this->CreateRawCanvas($this->width,$this->height); imagecopy($this->img,$oldimage,0,0,0,0,$this->width,$this->height); return $oldimage; } function CreateImgCanvas($aWidth=0,$aHeight=0) { $old = array($this->img,$this->width,$this->height); $aWidth = round($aWidth); $aHeight = round($aHeight); $this->width=$aWidth; $this->height=$aHeight; if( $aWidth==0 || $aHeight==0 ) { // We will set the final size later. // Note: The size must be specified before any other // img routines that stroke anything are called. $this->img = null; $this->rgb = null; return $old; } $this->CreateRawCanvas($aWidth,$aHeight); // Set canvas color (will also be the background color for a // a pallett image $this->SetColor($this->canvascolor); $this->FilledRectangle(0,0,$aWidth-1,$aHeight-1); return $old ; } function CopyCanvasH($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY,$aWidth,$aHeight,$aw=-1,$ah=-1) { if( $aw === -1 ) { $aw = $aWidth; $ah = $aHeight; $f = 'imagecopyresized'; } else { $f = 'imagecopyresampled'; } $f($aToHdl,$aFromHdl,$aToX,$aToY,$aFromX,$aFromY, $aWidth,$aHeight,$aw,$ah); } function Copy($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1) { $this->CopyCanvasH($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight); } function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) { if( $aMix == 100 ) { $this->CopyCanvasH($this->img,$fromImg, $toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight); } else { if( ($fromWidth != -1 && ($fromWidth != $toWidth)) || ($fromHeight != -1 && ($fromHeight != $fromHeight)) ) { // Create a new canvas that will hold the re-scaled original from image if( $toWidth <= 1 || $toHeight <= 1 ) { JpGraphError::RaiseL(25083);//('Illegal image size when copying image. Size for copied to image is 1 pixel or less.'); } $tmpimg = @imagecreatetruecolor($toWidth, $toHeight); if( $tmpimg < 1 ) { JpGraphError::RaiseL(25084);//('Failed to create temporary GD canvas. Out of memory ?'); } $this->CopyCanvasH($tmpimg,$fromImg,0,0,0,0, $toWidth,$toHeight,$fromWidth,$fromHeight); $fromImg = $tmpimg; } imagecopymerge($this->img,$fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$aMix); } } static function GetWidth($aImg=null) { if( $aImg === null ) { $aImg = $this->img; } return imagesx($aImg); } static function GetHeight($aImg=null) { if( $aImg === null ) { $aImg = $this->img; } return imagesy($aImg); } static function CreateFromString($aStr) { $img = imagecreatefromstring($aStr); if( $img === false ) { JpGraphError::RaiseL(25085); //('An image can not be created from the supplied string. It is either in a format not supported or the string is representing an corrupt image.'); } return $img; } function SetCanvasH($aHdl) { $this->img = $aHdl; $this->rgb->img = $aHdl; } function SetCanvasColor($aColor) { $this->canvascolor = $aColor ; } function SetAlphaBlending($aFlg=true) { ImageAlphaBlending($this->img,$aFlg); } function SetAutoMargin() { $min_bm=5; $lm = min(40,$this->width/7); $rm = min(20,$this->width/10); $tm = max(5,$this->height/7); $bm = max($min_bm,$this->height/6); $this->SetMargin($lm,$rm,$tm,$bm); } //--------------- // PUBLIC METHODS function SetFont($family,$style=FS_NORMAL,$size=10) { $this->font_family=$family; $this->font_style=$style; $this->font_size=$size; $this->font_file=''; if( ($this->font_family==FF_FONT1 || $this->font_family==FF_FONT2) && $this->font_style==FS_BOLD ){ ++$this->font_family; } if( $this->font_family > FF_FONT2+1 ) { // A TTF font so get the font file // Check that this PHP has support for TTF fonts if( !function_exists('imagettfbbox') ) { JpGraphError::RaiseL(25087);//('This PHP build has not been configured with TTF support. You need to recompile your PHP installation with FreeType support.'); } $this->font_file = $this->ttf->File($this->font_family,$this->font_style); } } // Get the specific height for a text string function GetTextHeight($txt="",$angle=0) { $tmp = preg_split('/\n/',$txt); $n = count($tmp); $m=0; for($i=0; $i< $n; ++$i) { $m = max($m,strlen($tmp[$i])); } if( $this->font_family <= FF_FONT2+1 ) { if( $angle==0 ) { $h = imagefontheight($this->font_family); if( $h === false ) { JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); } return $n*$h; } else { $w = @imagefontwidth($this->font_family); if( $w === false ) { JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); } return $m*$w; } } else { $bbox = $this->GetTTFBBox($txt,$angle); return $bbox[1]-$bbox[5]+1; } } // Estimate font height function GetFontHeight($angle=0) { $txt = "XOMg"; return $this->GetTextHeight($txt,$angle); } // Approximate font width with width of letter "O" function GetFontWidth($angle=0) { $txt = 'O'; return $this->GetTextWidth($txt,$angle); } // Get actual width of text in absolute pixels. Note that the width is the // texts projected with onto the x-axis. Call with angle=0 to get the true // etxt width. function GetTextWidth($txt,$angle=0) { $tmp = preg_split('/\n/',$txt); $n = count($tmp); if( $this->font_family <= FF_FONT2+1 ) { $m=0; for($i=0; $i < $n; ++$i) { $l=strlen($tmp[$i]); if( $l > $m ) { $m = $l; } } if( $angle==0 ) { $w = @imagefontwidth($this->font_family); if( $w === false ) { JpGraphError::RaiseL(25088);//('You have a misconfigured GD font support. The call to imagefontwidth() fails.'); } return $m*$w; } else { // 90 degrees internal so height becomes width $h = @imagefontheight($this->font_family); if( $h === false ) { JpGraphError::RaiseL(25089);//('You have a misconfigured GD font support. The call to imagefontheight() fails.'); } return $n*$h; } } else { // For TTF fonts we must walk through a lines and find the // widest one which we use as the width of the multi-line // paragraph $m=0; for( $i=0; $i < $n; ++$i ) { $bbox = $this->GetTTFBBox($tmp[$i],$angle); $mm = $bbox[2] - $bbox[0]; if( $mm > $m ) $m = $mm; } return $m; } } // Draw text with a box around it function StrokeBoxedText($x,$y,$txt,$dir=0,$fcolor="white",$bcolor="black", $shadowcolor=false,$paragraph_align="left", $xmarg=6,$ymarg=4,$cornerradius=0,$dropwidth=3) { $oldx = $this->lastx; $oldy = $this->lasty; if( !is_numeric($dir) ) { if( $dir=="h" ) $dir=0; elseif( $dir=="v" ) $dir=90; else JpGraphError::RaiseL(25090,$dir);//(" Unknown direction specified in call to StrokeBoxedText() [$dir]"); } if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) { $width=$this->GetTextWidth($txt,$dir) ; $height=$this->GetTextHeight($txt,$dir) ; } else { $width=$this->GetBBoxWidth($txt,$dir) ; $height=$this->GetBBoxHeight($txt,$dir) ; } $height += 2*$ymarg; $width += 2*$xmarg; if( $this->text_halign=="right" ) $x -= $width; elseif( $this->text_halign=="center" ) $x -= $width/2; if( $this->text_valign=="bottom" ) $y -= $height; elseif( $this->text_valign=="center" ) $y -= $height/2; $olda = $this->SetAngle(0); if( $shadowcolor ) { $this->PushColor($shadowcolor); $this->FilledRoundedRectangle($x-$xmarg+$dropwidth,$y-$ymarg+$dropwidth, $x+$width+$dropwidth,$y+$height-$ymarg+$dropwidth, $cornerradius); $this->PopColor(); $this->PushColor($fcolor); $this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg, $x+$width,$y+$height-$ymarg, $cornerradius); $this->PopColor(); $this->PushColor($bcolor); $this->RoundedRectangle($x-$xmarg,$y-$ymarg, $x+$width,$y+$height-$ymarg,$cornerradius); $this->PopColor(); } else { if( $fcolor ) { $oc=$this->current_color; $this->SetColor($fcolor); $this->FilledRoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius); $this->current_color=$oc; } if( $bcolor ) { $oc=$this->current_color; $this->SetColor($bcolor); $this->RoundedRectangle($x-$xmarg,$y-$ymarg,$x+$width,$y+$height-$ymarg,$cornerradius); $this->current_color=$oc; } } $h=$this->text_halign; $v=$this->text_valign; $this->SetTextAlign("left","top"); $debug=false; $this->StrokeText($x, $y, $txt, $dir, $paragraph_align,$debug); $bb = array($x-$xmarg,$y+$height-$ymarg,$x+$width,$y+$height-$ymarg, $x+$width,$y-$ymarg,$x-$xmarg,$y-$ymarg); $this->SetTextAlign($h,$v); $this->SetAngle($olda); $this->lastx = $oldx; $this->lasty = $oldy; return $bb; } // Draw text with a box around it. This time the box will be rotated // with the text. The previous method will just make a larger enough non-rotated // box to hold the text inside. function StrokeBoxedText2($x,$y,$txt,$dir=0,$fcolor="white",$bcolor="black", $shadowcolor=false,$paragraph_align="left", $xmarg=6,$ymarg=4,$cornerradius=0,$dropwidth=3) { // This version of boxed text will stroke a rotated box round the text // thta will follow the angle of the text. // This has two implications: // 1) This methos will only support TTF fonts // 2) The only two alignment that makes sense are centered or baselined if( $this->font_family <= FF_FONT2+1 ) { JpGraphError::RaiseL(25131);//StrokeBoxedText2() Only support TTF fonts and not built in bitmap fonts } $oldx = $this->lastx; $oldy = $this->lasty; $dir = $this->NormAngle($dir); if( !is_numeric($dir) ) { if( $dir=="h" ) $dir=0; elseif( $dir=="v" ) $dir=90; else JpGraphError::RaiseL(25090,$dir);//(" Unknown direction specified in call to StrokeBoxedText() [$dir]"); } $width=$this->GetTextWidth($txt,0) + 2*$xmarg; $height=$this->GetTextHeight($txt,0) + 2*$ymarg ; $rect_width=$this->GetBBoxWidth($txt,$dir) ; $rect_height=$this->GetBBoxHeight($txt,$dir) ; $baseline_offset = $this->bbox_cache[1]-1; if( $this->text_halign=="center" ) { if( $dir >= 0 && $dir <= 90 ) { $x -= $rect_width/2; $x += sin($dir*M_PI/180)*$height; $y += $rect_height/2; } elseif( $dir >= 270 && $dir <= 360 ) { $x -= $rect_width/2; $y -= $rect_height/2; $y += cos($dir*M_PI/180)*$height; } elseif( $dir >= 90 && $dir <= 180 ) { $x += $rect_width/2; $y += $rect_height/2; $y += cos($dir*M_PI/180)*$height; } else { // $dir > 180 && $dir < 270 $x += $rect_width/2; $x += sin($dir*M_PI/180)*$height; $y -= $rect_height/2; } } // Rotate the box around this point $this->SetCenter($x,$y); $olda = $this->SetAngle(-$dir); // We need to use adjusted coordinats for the box to be able // to draw the box below the baseline. This cannot be done before since // the rotating point must be the original x,y since that is arounbf the // point where the text will rotate and we cannot change this since // that is where the GD/GreeType will rotate the text // For smaller <14pt font we need to do some additional // adjustments to make it look good if( $this->font_size < 14 ) { $x -= 2; $y += 2; } else { // $y += $baseline_offset; } if( $shadowcolor ) { $this->PushColor($shadowcolor); $this->FilledRectangle($x-$xmarg+$dropwidth,$y+$ymarg+$dropwidth-$height, $x+$width+$dropwidth,$y+$ymarg+$dropwidth); //$cornerradius); $this->PopColor(); $this->PushColor($fcolor); $this->FilledRectangle($x-$xmarg, $y+$ymarg-$height, $x+$width, $y+$ymarg); //$cornerradius); $this->PopColor(); $this->PushColor($bcolor); $this->Rectangle($x-$xmarg,$y+$ymarg-$height, $x+$width,$y+$ymarg); //$cornerradius); $this->PopColor(); } else { if( $fcolor ) { $oc=$this->current_color; $this->SetColor($fcolor); $this->FilledRectangle($x-$xmarg,$y+$ymarg-$height,$x+$width,$y+$ymarg);//,$cornerradius); $this->current_color=$oc; } if( $bcolor ) { $oc=$this->current_color; $this->SetColor($bcolor); $this->Rectangle($x-$xmarg,$y+$ymarg-$height,$x+$width,$y+$ymarg);//,$cornerradius); $this->current_color=$oc; } } if( $this->font_size < 14 ) { $x += 2; $y -= 2; } else { // Restore the original y before we stroke the text // $y -= $baseline_offset; } $this->SetCenter(0,0); $this->SetAngle($olda); $h=$this->text_halign; $v=$this->text_valign; if( $this->text_halign == 'center') { $this->SetTextAlign('center','basepoint'); } else { $this->SetTextAlign('basepoint','basepoint'); } $debug=false; $this->StrokeText($x, $y, $txt, $dir, $paragraph_align,$debug); $bb = array($x-$xmarg, $y+$height-$ymarg, $x+$width, $y+$height-$ymarg, $x+$width, $y-$ymarg, $x-$xmarg, $y-$ymarg); $this->SetTextAlign($h,$v); $this->SetAngle($olda); $this->lastx = $oldx; $this->lasty = $oldy; return $bb; } // Set text alignment function SetTextAlign($halign,$valign="bottom") { $this->text_halign=$halign; $this->text_valign=$valign; } function _StrokeBuiltinFont($x,$y,$txt,$dir,$paragraph_align,&$aBoundingBox,$aDebug=false) { if( is_numeric($dir) && $dir!=90 && $dir!=0) JpGraphError::RaiseL(25091);//(" Internal font does not support drawing text at arbitrary angle. Use TTF fonts instead."); $h=$this->GetTextHeight($txt); $fh=$this->GetFontHeight(); $w=$this->GetTextWidth($txt); if( $this->text_halign=="right") { $x -= $dir==0 ? $w : $h; } elseif( $this->text_halign=="center" ) { // For center we subtract 1 pixel since this makes the middle // be prefectly in the middle $x -= $dir==0 ? $w/2-1 : $h/2; } if( $this->text_valign=="top" ) { $y += $dir==0 ? $h : $w; } elseif( $this->text_valign=="center" ) { $y += $dir==0 ? $h/2 : $w/2; } if( $dir==90 ) { imagestringup($this->img,$this->font_family,$x,$y,$txt,$this->current_color); $aBoundingBox = array(round($x),round($y),round($x),round($y-$w),round($x+$h),round($y-$w),round($x+$h),round($y)); if( $aDebug ) { // Draw bounding box $this->PushColor('green'); $this->Polygon($aBoundingBox,true); $this->PopColor(); } } else { if( preg_match('/\n/',$txt) ) { $tmp = preg_split('/\n/',$txt); for($i=0; $i < count($tmp); ++$i) { $w1 = $this->GetTextWidth($tmp[$i]); if( $paragraph_align=="left" ) { imagestring($this->img,$this->font_family,$x,$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); } elseif( $paragraph_align=="right" ) { imagestring($this->img,$this->font_family,$x+($w-$w1),$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); } else { imagestring($this->img,$this->font_family,$x+$w/2-$w1/2,$y-$h+1+$i*$fh,$tmp[$i],$this->current_color); } } } else { //Put the text imagestring($this->img,$this->font_family,$x,$y-$h+1,$txt,$this->current_color); } if( $aDebug ) { // Draw the bounding rectangle and the bounding box $p1 = array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y)); // Draw bounding box $this->PushColor('green'); $this->Polygon($p1,true); $this->PopColor(); } $aBoundingBox=array(round($x),round($y),round($x),round($y-$h),round($x+$w),round($y-$h),round($x+$w),round($y)); } } function AddTxtCR($aTxt) { // If the user has just specified a '\n' // instead of '\n\t' we have to add '\r' since // the width will be too muchy otherwise since when // we print we stroke the individually lines by hand. $e = explode("\n",$aTxt); $n = count($e); for($i=0; $i<$n; ++$i) { $e[$i]=str_replace("\r","",$e[$i]); } return implode("\n\r",$e); } function NormAngle($a) { // Normalize angle in degrees // Normalize angle to be between 0-360 while( $a > 360 ) $a -= 360; while( $a < -360 ) $a += 360; if( $a < 0 ) $a = 360 + $a; return $a; } function imagettfbbox_fixed($size, $angle, $fontfile, $text) { if( ! USE_LIBRARY_IMAGETTFBBOX ) { $bbox = @imagettfbbox($size, $angle, $fontfile, $text); if( $bbox === false ) { JpGraphError::RaiseL(25092,$this->font_file); //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library."); } $this->bbox_cache = $bbox; return $bbox; } // The built in imagettfbbox is buggy for angles != 0 so // we calculate this manually by getting the bounding box at // angle = 0 and then rotate the bounding box manually $bbox = @imagettfbbox($size, 0, $fontfile, $text); if( $bbox === false ) { JpGraphError::RaiseL(25092,$this->font_file); //("There is either a configuration problem with TrueType or a problem reading font file (".$this->font_file."). Make sure file exists and is in a readable place for the HTTP process. (If 'basedir' restriction is enabled in PHP then the font file must be located in the document root.). It might also be a wrongly installed FreeType library. Try uppgrading to at least FreeType 2.1.13 and recompile GD with the correct setup so it can find the new FT library."); } $angle = $this->NormAngle($angle); $a = $angle*M_PI/180; $ca = cos($a); $sa = sin($a); $ret = array(); // We always add 1 pixel to the left since the left edge of the bounding // box is sometimes coinciding with the first pixel of the text //$bbox[0] -= 1; //$bbox[6] -= 1; // For roatated text we need to add extra width for rotated // text since the kerning and stroking of the TTF is not the same as for // text at a 0 degree angle if( $angle > 0.001 && abs($angle-360) > 0.001 ) { $h = abs($bbox[7]-$bbox[1]); $w = abs($bbox[2]-$bbox[0]); $bbox[0] -= 2; $bbox[6] -= 2; // The width is underestimated so compensate for that $bbox[2] += round($w*0.06); $bbox[4] += round($w*0.06); // and we also need to compensate with increased height $bbox[5] -= round($h*0.1); $bbox[7] -= round($h*0.1); if( $angle > 90 ) { // For angles > 90 we also need to extend the height further down // by the baseline since that is also one more problem $bbox[1] += round($h*0.15); $bbox[3] += round($h*0.15); // and also make it slighty less height $bbox[7] += round($h*0.05); $bbox[5] += round($h*0.05); // And we need to move the box slightly top the rright (from a tetx perspective) $bbox[0] += round($w*0.02); $bbox[6] += round($w*0.02); if( $angle > 180 ) { // And we need to move the box slightly to the left (from a text perspective) $bbox[0] -= round($w*0.02); $bbox[6] -= round($w*0.02); $bbox[2] -= round($w*0.02); $bbox[4] -= round($w*0.02); } } for($i = 0; $i < 7; $i += 2) { $ret[$i] = round($bbox[$i] * $ca + $bbox[$i+1] * $sa); $ret[$i+1] = round($bbox[$i+1] * $ca - $bbox[$i] * $sa); } $this->bbox_cache = $ret; return $ret; } else { $this->bbox_cache = $bbox; return $bbox; } } // Deprecated function GetTTFBBox($aTxt,$aAngle=0) { $bbox = $this->imagettfbbox_fixed($this->font_size,$aAngle,$this->font_file,$aTxt); return $bbox; } function GetBBoxTTF($aTxt,$aAngle=0) { // Normalize the bounding box to become a minimum // enscribing rectangle $aTxt = $this->AddTxtCR($aTxt); if( !is_readable($this->font_file) ) { JpGraphError::RaiseL(25093,$this->font_file); //('Can not read font file ('.$this->font_file.') in call to Image::GetBBoxTTF. Please make sure that you have set a font before calling this method and that the font is installed in the TTF directory.'); } $bbox = $this->imagettfbbox_fixed($this->font_size,$aAngle,$this->font_file,$aTxt); if( $aAngle==0 ) return $bbox; if( $aAngle >= 0 ) { if( $aAngle <= 90 ) { //<=0 $bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1], $bbox[2],$bbox[5],$bbox[6],$bbox[5]); } elseif( $aAngle <= 180 ) { //<= 2 $bbox = array($bbox[4],$bbox[7],$bbox[0],$bbox[7], $bbox[0],$bbox[3],$bbox[4],$bbox[3]); } elseif( $aAngle <= 270 ) { //<= 3 $bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5], $bbox[6],$bbox[1],$bbox[2],$bbox[1]); } else { $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], $bbox[4],$bbox[7],$bbox[0],$bbox[7]); } } elseif( $aAngle < 0 ) { if( $aAngle <= -270 ) { // <= -3 $bbox = array($bbox[6],$bbox[1],$bbox[2],$bbox[1], $bbox[2],$bbox[5],$bbox[6],$bbox[5]); } elseif( $aAngle <= -180 ) { // <= -2 $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], $bbox[4],$bbox[7],$bbox[0],$bbox[7]); } elseif( $aAngle <= -90 ) { // <= -1 $bbox = array($bbox[2],$bbox[5],$bbox[6],$bbox[5], $bbox[6],$bbox[1],$bbox[2],$bbox[1]); } else { $bbox = array($bbox[0],$bbox[3],$bbox[4],$bbox[3], $bbox[4],$bbox[7],$bbox[0],$bbox[7]); } } return $bbox; } function GetBBoxHeight($aTxt,$aAngle=0) { $box = $this->GetBBoxTTF($aTxt,$aAngle); return abs($box[7]-$box[1]); } function GetBBoxWidth($aTxt,$aAngle=0) { $box = $this->GetBBoxTTF($aTxt,$aAngle); return $box[2]-$box[0]+1; } function _StrokeTTF($x,$y,$txt,$dir,$paragraph_align,&$aBoundingBox,$debug=false) { // Setup default inter line margin for paragraphs to be // 3% of the font height. $ConstLineSpacing = 0.03 ; // Remember the anchor point before adjustment if( $debug ) { $ox=$x; $oy=$y; } if( !preg_match('/\n/',$txt) || ($dir>0 && preg_match('/\n/',$txt)) ) { // Format a single line $txt = $this->AddTxtCR($txt); $bbox=$this->GetBBoxTTF($txt,$dir); $width = $this->GetBBoxWidth($txt,$dir); $height = $this->GetBBoxHeight($txt,$dir); // The special alignment "basepoint" is mostly used internally // in the library. This will put the anchor position at the left // basepoint of the tetx. This is the default anchor point for // TTF text. if( $this->text_valign != 'basepoint' ) { // Align x,y ot lower left corner of bbox if( $this->text_halign=='right' ) { $x -= $width; $x -= $bbox[0]; } elseif( $this->text_halign=='center' ) { $x -= $width/2; $x -= $bbox[0]; } elseif( $this->text_halign=='baseline' ) { // This is only support for text at 90 degree !! // Do nothing the text is drawn at baseline by default } if( $this->text_valign=='top' ) { $y -= $bbox[1]; // Adjust to bottom of text $y += $height; } elseif( $this->text_valign=='center' ) { $y -= $bbox[1]; // Adjust to bottom of text $y += $height/2; } elseif( $this->text_valign=='baseline' ) { // This is only support for text at 0 degree !! // Do nothing the text is drawn at baseline by default } } ImageTTFText ($this->img, $this->font_size, $dir, $x, $y, $this->current_color,$this->font_file,$txt); // Calculate and return the co-ordinates for the bounding box $box = $this->imagettfbbox_fixed($this->font_size,$dir,$this->font_file,$txt); $p1 = array(); for($i=0; $i < 4; ++$i) { $p1[] = round($box[$i*2]+$x); $p1[] = round($box[$i*2+1]+$y); } $aBoundingBox = $p1; // Debugging code to highlight the bonding box and bounding rectangle // For text at 0 degrees the bounding box and bounding rectangle are the // same if( $debug ) { // Draw the bounding rectangle and the bounding box $p = array(); $p1 = array(); for($i=0; $i < 4; ++$i) { $p[] = $bbox[$i*2]+$x ; $p[] = $bbox[$i*2+1]+$y; $p1[] = $box[$i*2]+$x ; $p1[] = $box[$i*2+1]+$y ; } // Draw bounding box $this->PushColor('green'); $this->Polygon($p1,true); $this->PopColor(); // Draw bounding rectangle $this->PushColor('darkgreen'); $this->Polygon($p,true); $this->PopColor(); // Draw a cross at the anchor point $this->PushColor('red'); $this->Line($ox-15,$oy,$ox+15,$oy); $this->Line($ox,$oy-15,$ox,$oy+15); $this->PopColor(); } } else { // Format a text paragraph $fh=$this->GetFontHeight(); // Line margin is 25% of font height $linemargin=round($fh*$ConstLineSpacing); $fh += $linemargin; $w=$this->GetTextWidth($txt); $y -= $linemargin/2; $tmp = preg_split('/\n/',$txt); $nl = count($tmp); $h = $nl * $fh; if( $this->text_halign=='right') { $x -= $dir==0 ? $w : $h; } elseif( $this->text_halign=='center' ) { $x -= $dir==0 ? $w/2 : $h/2; } if( $this->text_valign=='top' ) { $y += $dir==0 ? $h : $w; } elseif( $this->text_valign=='center' ) { $y += $dir==0 ? $h/2 : $w/2; } // Here comes a tricky bit. // Since we have to give the position for the string at the // baseline this means thaht text will move slightly up // and down depending on any of it's character descend below // the baseline, for example a 'g'. To adjust the Y-position // we therefore adjust the text with the baseline Y-offset // as used for the current font and size. This will keep the // baseline at a fixed positoned disregarding the actual // characters in the string. $standardbox = $this->GetTTFBBox('Gg',$dir); $yadj = $standardbox[1]; $xadj = $standardbox[0]; $aBoundingBox = array(); for($i=0; $i < $nl; ++$i) { $wl = $this->GetTextWidth($tmp[$i]); $bbox = $this->GetTTFBBox($tmp[$i],$dir); if( $paragraph_align=='left' ) { $xl = $x; } elseif( $paragraph_align=='right' ) { $xl = $x + ($w-$wl); } else { // Center $xl = $x + $w/2 - $wl/2 ; } // In theory we should adjust with full pre-lead to get the lines // lined up but this doesn't look good so therfore we only adjust with // half th pre-lead $xl -= $bbox[0]/2; $yl = $y - $yadj; //$xl = $xl- $xadj; ImageTTFText($this->img, $this->font_size, $dir, $xl, $yl-($h-$fh)+$fh*$i, $this->current_color,$this->font_file,$tmp[$i]); // echo "xl=$xl,".$tmp[$i]."
    "; if( $debug ) { // Draw the bounding rectangle around each line $box=@ImageTTFBBox($this->font_size,$dir,$this->font_file,$tmp[$i]); $p = array(); for($j=0; $j < 4; ++$j) { $p[] = $bbox[$j*2]+$xl; $p[] = $bbox[$j*2+1]+$yl-($h-$fh)+$fh*$i; } // Draw bounding rectangle $this->PushColor('darkgreen'); $this->Polygon($p,true); $this->PopColor(); } } // Get the bounding box $bbox = $this->GetBBoxTTF($txt,$dir); for($j=0; $j < 4; ++$j) { $bbox[$j*2]+= round($x); $bbox[$j*2+1]+= round($y - ($h-$fh) - $yadj); } $aBoundingBox = $bbox; if( $debug ) { // Draw a cross at the anchor point $this->PushColor('red'); $this->Line($ox-25,$oy,$ox+25,$oy); $this->Line($ox,$oy-25,$ox,$oy+25); $this->PopColor(); } } } function StrokeText($x,$y,$txt,$dir=0,$paragraph_align="left",$debug=false) { $x = round($x); $y = round($y); // Do special language encoding $txt = $this->langconv->Convert($txt,$this->font_family); if( !is_numeric($dir) ) { JpGraphError::RaiseL(25094);//(" Direction for text most be given as an angle between 0 and 90."); } if( $this->font_family >= FF_FONT0 && $this->font_family <= FF_FONT2+1) { $this->_StrokeBuiltinFont($x,$y,$txt,$dir,$paragraph_align,$boundingbox,$debug); } elseif( $this->font_family >= _FIRST_FONT && $this->font_family <= _LAST_FONT) { $this->_StrokeTTF($x,$y,$txt,$dir,$paragraph_align,$boundingbox,$debug); } else { JpGraphError::RaiseL(25095);//(" Unknown font font family specification. "); } return $boundingbox; } function SetMargin($lm,$rm,$tm,$bm) { $this->left_margin=$lm; $this->right_margin=$rm; $this->top_margin=$tm; $this->bottom_margin=$bm; $this->plotwidth=$this->width - $this->left_margin-$this->right_margin ; $this->plotheight=$this->height - $this->top_margin-$this->bottom_margin ; if( $this->width > 0 && $this->height > 0 ) { if( $this->plotwidth < 0 || $this->plotheight < 0 ) { JpGraphError::RaiseL(25130, $this->plotwidth, $this->plotheight); //JpGraphError::raise("To small plot area. ($lm,$rm,$tm,$bm : $this->plotwidth x $this->plotheight). With the given image size and margins there is to little space left for the plot. Increase the plot size or reduce the margins."); } } } function SetTransparent($color) { imagecolortransparent ($this->img,$this->rgb->allocate($color)); } function SetColor($color,$aAlpha=0) { $this->current_color_name = $color; $this->current_color=$this->rgb->allocate($color,$aAlpha); if( $this->current_color == -1 ) { $tc=imagecolorstotal($this->img); JpGraphError::RaiseL(25096); //("Can't allocate any more colors. Image has already allocated maximum of $tc colors. This might happen if you have anti-aliasing turned on together with a background image or perhaps gradient fill since this requires many, many colors. Try to turn off anti-aliasing. If there is still a problem try downgrading the quality of the background image to use a smaller pallete to leave some entries for your graphs. You should try to limit the number of colors in your background image to 64. If there is still problem set the constant DEFINE(\"USE_APPROX_COLORS\",true); in jpgraph.php This will use approximative colors when the palette is full. Unfortunately there is not much JpGraph can do about this since the palette size is a limitation of current graphic format and what the underlying GD library suppports."); } return $this->current_color; } function PushColor($color) { if( $color != "" ) { $this->colorstack[$this->colorstackidx]=$this->current_color_name; $this->colorstack[$this->colorstackidx+1]=$this->current_color; $this->colorstackidx+=2; $this->SetColor($color); } else { JpGraphError::RaiseL(25097);//("Color specified as empty string in PushColor()."); } } function PopColor() { if( $this->colorstackidx < 1 ) { JpGraphError::RaiseL(25098);//(" Negative Color stack index. Unmatched call to PopColor()"); } $this->current_color=$this->colorstack[--$this->colorstackidx]; $this->current_color_name=$this->colorstack[--$this->colorstackidx]; } function SetLineWeight($weight) { $old = $this->line_weight; imagesetthickness($this->img,$weight); $this->line_weight = $weight; return $old; } function SetStartPoint($x,$y) { $this->lastx=round($x); $this->lasty=round($y); } function Arc($cx,$cy,$w,$h,$s,$e) { // GD Arc doesn't like negative angles while( $s < 0) $s += 360; while( $e < 0) $e += 360; imagearc($this->img,round($cx),round($cy),round($w),round($h),$s,$e,$this->current_color); } function FilledArc($xc,$yc,$w,$h,$s,$e,$style='') { $s = round($s); $e = round($e); while( $s < 0 ) $s += 360; while( $e < 0 ) $e += 360; if( $style=='' ) $style=IMG_ARC_PIE; if( abs($s-$e) > 0 ) { imagefilledarc($this->img,round($xc),round($yc),round($w),round($h),$s,$e,$this->current_color,$style); } } function FilledCakeSlice($cx,$cy,$w,$h,$s,$e) { $this->CakeSlice($cx,$cy,$w,$h,$s,$e,$this->current_color_name); } function CakeSlice($xc,$yc,$w,$h,$s,$e,$fillcolor="",$arccolor="") { $s = round($s); $e = round($e); $w = round($w); $h = round($h); $xc = round($xc); $yc = round($yc); if( $s == $e ) { // A full circle. We draw this a plain circle $this->PushColor($fillcolor); imagefilledellipse($this->img,$xc,$yc,2*$w,2*$h,$this->current_color); // If antialiasing is used then we often don't have any color no the surrounding // arc. So, we need to check for this special case so we don't send an empty // color to the push function. In this case we use the fill color for the arc as well if( $arccolor != '' ) { $this->PopColor(); $this->PushColor($arccolor); } imageellipse($this->img,$xc,$yc,2*$w,2*$h,$this->current_color); $this->Line($xc,$yc,cos($s*M_PI/180)*$w+$xc,$yc+sin($s*M_PI/180)*$h); $this->PopColor(); } else { $this->PushColor($fillcolor); $this->FilledArc($xc,$yc,2*$w,2*$h,$s,$e); $this->PopColor(); if( $arccolor != "" ) { $this->PushColor($arccolor); // We add 2 pixels to make the Arc() better aligned with // the filled arc. imagefilledarc($this->img,$xc,$yc,2*$w,2*$h,$s,$e,$this->current_color,IMG_ARC_NOFILL | IMG_ARC_EDGED ) ; $this->PopColor(); } } } function Ellipse($xc,$yc,$w,$h) { $this->Arc($xc,$yc,$w,$h,0,360); } function Circle($xc,$yc,$r) { imageellipse($this->img,round($xc),round($yc),$r*2,$r*2,$this->current_color); } function FilledCircle($xc,$yc,$r) { imagefilledellipse($this->img,round($xc),round($yc),2*$r,2*$r,$this->current_color); } // Linear Color InterPolation function lip($f,$t,$p) { $p = round($p,1); $r = $f[0] + ($t[0]-$f[0])*$p; $g = $f[1] + ($t[1]-$f[1])*$p; $b = $f[2] + ($t[2]-$f[2])*$p; return array($r,$g,$b); } // Set line style dashed, dotted etc function SetLineStyle($s) { if( is_numeric($s) ) { if( $s<1 || $s>4 ) { JpGraphError::RaiseL(25101,$s);//(" Illegal numeric argument to SetLineStyle(): ($s)"); } } elseif( is_string($s) ) { if( $s == "solid" ) $s=1; elseif( $s == "dotted" ) $s=2; elseif( $s == "dashed" ) $s=3; elseif( $s == "longdashed" ) $s=4; else { JpGraphError::RaiseL(25102,$s);//(" Illegal string argument to SetLineStyle(): $s"); } } else { JpGraphError::RaiseL(25103,$s);//(" Illegal argument to SetLineStyle $s"); } $old = $this->line_style; $this->line_style=$s; return $old; } // Same as Line but take the line_style into account function StyleLine($x1,$y1,$x2,$y2,$aStyle='') { if( $this->line_weight <= 0 ) return; if( $aStyle === '' ) { $aStyle = $this->line_style; } // Add error check since dashed line will only work if anti-alias is disabled // this is a limitation in GD if( $aStyle == 1 ) { // Solid style. We can handle anti-aliasing for this $this->Line($x1,$y1,$x2,$y2); } else { // Since the GD routines doesn't handle AA for styled line // we have no option than to turn it off to get any lines at // all if the weight > 1 $oldaa = $this->GetAntiAliasing(); if( $oldaa && $this->line_weight > 1 ) { $this->SetAntiAliasing(false); } switch( $aStyle ) { case 2: // Dotted $this->DashedLine($x1,$y1,$x2,$y2,2,6); break; case 3: // Dashed $this->DashedLine($x1,$y1,$x2,$y2,5,9); break; case 4: // Longdashes $this->DashedLine($x1,$y1,$x2,$y2,9,13); break; default: JpGraphError::RaiseL(25104,$this->line_style);//(" Unknown line style: $this->line_style "); break; } if( $oldaa ) { $this->SetAntiAliasing(true); } } } function DashedLine($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) { if( $this->line_weight <= 0 ) return; // Add error check to make sure anti-alias is not enabled. // Dashed line does not work with anti-alias enabled. This // is a limitation in GD. if( $this->use_anti_aliasing ) { JpGraphError::RaiseL(25129); // Anti-alias can not be used with dashed lines. Please disable anti-alias or use solid lines. } $x1 = round($x1); $x2 = round($x2); $y1 = round($y1); $y2 = round($y2); $style = array_fill(0,$dash_length,$this->current_color); $style = array_pad($style,$dash_space,IMG_COLOR_TRANSPARENT); imagesetstyle($this->img, $style); imageline($this->img, $x1, $y1, $x2, $y2, IMG_COLOR_STYLED); $this->lastx = $x2; $this->lasty = $y2; } function Line($x1,$y1,$x2,$y2) { if( $this->line_weight <= 0 ) return; $x1 = round($x1); $x2 = round($x2); $y1 = round($y1); $y2 = round($y2); imageline($this->img,$x1,$y1,$x2,$y2,$this->current_color); $this->lastx=$x2; $this->lasty=$y2; } function Polygon($p,$closed=FALSE,$fast=FALSE) { if( $this->line_weight <= 0 ) return; $n=count($p); $oldx = $p[0]; $oldy = $p[1]; if( $fast ) { for( $i=2; $i < $n; $i+=2 ) { imageline($this->img,$oldx,$oldy,$p[$i],$p[$i+1],$this->current_color); $oldx = $p[$i]; $oldy = $p[$i+1]; } if( $closed ) { imageline($this->img,$p[$n*2-2],$p[$n*2-1],$p[0],$p[1],$this->current_color); } } else { for( $i=2; $i < $n; $i+=2 ) { $this->StyleLine($oldx,$oldy,$p[$i],$p[$i+1]); $oldx = $p[$i]; $oldy = $p[$i+1]; } if( $closed ) { $this->StyleLine($oldx,$oldy,$p[0],$p[1]); } } } function FilledPolygon($pts) { $n=count($pts); if( $n == 0 ) { JpGraphError::RaiseL(25105);//('NULL data specified for a filled polygon. Check that your data is not NULL.'); } for($i=0; $i < $n; ++$i) { $pts[$i] = round($pts[$i]); } $old = $this->line_weight; imagesetthickness($this->img,1); imagefilledpolygon($this->img,$pts,count($pts)/2,$this->current_color); $this->line_weight = $old; imagesetthickness($this->img,$old); } function Rectangle($xl,$yu,$xr,$yl) { $this->Polygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl,$xl,$yu)); } function FilledRectangle($xl,$yu,$xr,$yl) { $this->FilledPolygon(array($xl,$yu,$xr,$yu,$xr,$yl,$xl,$yl)); } function FilledRectangle2($xl,$yu,$xr,$yl,$color1,$color2,$style=1) { // Fill a rectangle with lines of two colors if( $style===1 ) { // Horizontal stripe if( $yl < $yu ) { $t = $yl; $yl=$yu; $yu=$t; } for( $y=$yu; $y <= $yl; ++$y) { $this->SetColor($color1); $this->Line($xl,$y,$xr,$y); ++$y; $this->SetColor($color2); $this->Line($xl,$y,$xr,$y); } } else { if( $xl < $xl ) { $t = $xl; $xl=$xr; $xr=$t; } for( $x=$xl; $x <= $xr; ++$x) { $this->SetColor($color1); $this->Line($x,$yu,$x,$yl); ++$x; $this->SetColor($color2); $this->Line($x,$yu,$x,$yl); } } } function ShadowRectangle($xl,$yu,$xr,$yl,$fcolor=false,$shadow_width=4,$shadow_color='darkgray',$useAlpha=true) { // This is complicated by the fact that we must also handle the case where // the reactangle has no fill color $xl = floor($xl); $yu = floor($yu); $xr = floor($xr); $yl = floor($yl); $this->PushColor($shadow_color); $shadowAlpha=0; $this->SetLineWeight(1); $this->SetLineStyle('solid'); $basecolor = $this->rgb->Color($shadow_color); $shadow_color = array($basecolor[0],$basecolor[1],$basecolor[2],); for( $i=0; $i < $shadow_width; ++$i ) { $this->SetColor($shadow_color,$shadowAlpha); $this->Line($xr-$shadow_width+$i, $yu+$shadow_width, $xr-$shadow_width+$i, $yl-$shadow_width-1+$i); $this->Line($xl+$shadow_width, $yl-$shadow_width+$i, $xr-$shadow_width+$i, $yl-$shadow_width+$i); if( $useAlpha ) $shadowAlpha += 1.0/$shadow_width; } $this->PopColor(); if( $fcolor==false ) { $this->Rectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); } else { $this->PushColor($fcolor); $this->FilledRectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); $this->PopColor(); $this->Rectangle($xl,$yu,$xr-$shadow_width-1,$yl-$shadow_width-1); } } function FilledRoundedRectangle($xt,$yt,$xr,$yl,$r=5) { if( $r==0 ) { $this->FilledRectangle($xt,$yt,$xr,$yl); return; } // To avoid overlapping fillings (which will look strange // when alphablending is enabled) we have no choice but // to fill the five distinct areas one by one. // Center square $this->FilledRectangle($xt+$r,$yt+$r,$xr-$r,$yl-$r); // Top band $this->FilledRectangle($xt+$r,$yt,$xr-$r,$yt+$r); // Bottom band $this->FilledRectangle($xt+$r,$yl-$r,$xr-$r,$yl); // Left band $this->FilledRectangle($xt,$yt+$r,$xt+$r,$yl-$r); // Right band $this->FilledRectangle($xr-$r,$yt+$r,$xr,$yl-$r); // Topleft & Topright arc $this->FilledArc($xt+$r,$yt+$r,$r*2,$r*2,180,270); $this->FilledArc($xr-$r,$yt+$r,$r*2,$r*2,270,360); // Bottomleft & Bottom right arc $this->FilledArc($xt+$r,$yl-$r,$r*2,$r*2,90,180); $this->FilledArc($xr-$r,$yl-$r,$r*2,$r*2,0,90); } function RoundedRectangle($xt,$yt,$xr,$yl,$r=5) { if( $r==0 ) { $this->Rectangle($xt,$yt,$xr,$yl); return; } // Top & Bottom line $this->Line($xt+$r,$yt,$xr-$r,$yt); $this->Line($xt+$r,$yl,$xr-$r,$yl); // Left & Right line $this->Line($xt,$yt+$r,$xt,$yl-$r); $this->Line($xr,$yt+$r,$xr,$yl-$r); // Topleft & Topright arc $this->Arc($xt+$r,$yt+$r,$r*2,$r*2,180,270); $this->Arc($xr-$r,$yt+$r,$r*2,$r*2,270,360); // Bottomleft & Bottomright arc $this->Arc($xt+$r,$yl-$r,$r*2,$r*2,90,180); $this->Arc($xr-$r,$yl-$r,$r*2,$r*2,0,90); } function FilledBevel($x1,$y1,$x2,$y2,$depth=2,$color1='white@0.4',$color2='darkgray@0.4') { $this->FilledRectangle($x1,$y1,$x2,$y2); $this->Bevel($x1,$y1,$x2,$y2,$depth,$color1,$color2); } function Bevel($x1,$y1,$x2,$y2,$depth=2,$color1='white@0.4',$color2='black@0.5') { $this->PushColor($color1); for( $i=0; $i < $depth; ++$i ) { $this->Line($x1+$i,$y1+$i,$x1+$i,$y2-$i); $this->Line($x1+$i,$y1+$i,$x2-$i,$y1+$i); } $this->PopColor(); $this->PushColor($color2); for( $i=0; $i < $depth; ++$i ) { $this->Line($x1+$i,$y2-$i,$x2-$i,$y2-$i); $this->Line($x2-$i,$y1+$i,$x2-$i,$y2-$i-1); } $this->PopColor(); } function StyleLineTo($x,$y) { $this->StyleLine($this->lastx,$this->lasty,$x,$y); $this->lastx=$x; $this->lasty=$y; } function LineTo($x,$y) { $this->Line($this->lastx,$this->lasty,$x,$y); $this->lastx=$x; $this->lasty=$y; } function Point($x,$y) { imagesetpixel($this->img,round($x),round($y),$this->current_color); } function Fill($x,$y) { imagefill($this->img,round($x),round($y),$this->current_color); } function FillToBorder($x,$y,$aBordColor) { $bc = $this->rgb->allocate($aBordColor); if( $bc == -1 ) { JpGraphError::RaiseL(25106);//('Image::FillToBorder : Can not allocate more colors'); } imagefilltoborder($this->img,round($x),round($y),$bc,$this->current_color); } function SetExpired($aFlg=true) { $this->expired = $aFlg; } // Generate image header function Headers() { // In case we are running from the command line with the client version of // PHP we can't send any headers. $sapi = php_sapi_name(); if( $sapi == 'cli' ) return; // These parameters are set by headers_sent() but they might cause // an undefined variable error unless they are initilized $file=''; $lineno=''; if( headers_sent($file,$lineno) ) { $file=basename($file); $t = new ErrMsgText(); $msg = $t->Get(10,$file,$lineno); die($msg); } if ($this->expired) { header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); } header("Content-type: image/$this->img_format"); } // Adjust image quality for formats that allow this function SetQuality($q) { $this->quality = $q; } // Stream image to browser or to file function Stream($aFile="") { $func="image".$this->img_format; if( $this->img_format=="jpeg" && $this->quality != null ) { $res = @$func($this->img,$aFile,$this->quality); } else { if( $aFile != "" ) { $res = @$func($this->img,$aFile); if( !$res ) { JpGraphError::RaiseL(25107,$aFile);//("Can't write to file '$aFile'. Check that the process running PHP has enough permission."); } } else { $res = @$func($this->img); if( !$res ) { JpGraphError::RaiseL(25108);//("Can't stream image. This is most likely due to a faulty PHP/GD setup. Try to recompile PHP and use the built-in GD library that comes with PHP."); } } } } // Clear resources used by image (this is normally not used since all resources are/should be // returned when the script terminates function Destroy() { imagedestroy($this->img); } // Specify image format. Note depending on your installation // of PHP not all formats may be supported. function SetImgFormat($aFormat,$aQuality=75) { $this->quality = $aQuality; $aFormat = strtolower($aFormat); $tst = true; $supported = imagetypes(); if( $aFormat=="auto" ) { if( $supported & IMG_PNG ) $this->img_format="png"; elseif( $supported & IMG_JPG ) $this->img_format="jpeg"; elseif( $supported & IMG_GIF ) $this->img_format="gif"; elseif( $supported & IMG_WBMP ) $this->img_format="wbmp"; elseif( $supported & IMG_XPM ) $this->img_format="xpm"; else { JpGraphError::RaiseL(25109);//("Your PHP (and GD-lib) installation does not appear to support any known graphic formats. You need to first make sure GD is compiled as a module to PHP. If you also want to use JPEG images you must get the JPEG library. Please see the PHP docs for details."); } return true; } else { if( $aFormat=="jpeg" || $aFormat=="png" || $aFormat=="gif" ) { if( $aFormat=="jpeg" && !($supported & IMG_JPG) ) $tst=false; elseif( $aFormat=="png" && !($supported & IMG_PNG) ) $tst=false; elseif( $aFormat=="gif" && !($supported & IMG_GIF) ) $tst=false; elseif( $aFormat=="wbmp" && !($supported & IMG_WBMP) ) $tst=false; elseif( $aFormat=="xpm" && !($supported & IMG_XPM) ) $tst=false; else { $this->img_format=$aFormat; return true; } } else { $tst=false; } if( !$tst ) { JpGraphError::RaiseL(25110,$aFormat);//(" Your PHP installation does not support the chosen graphic format: $aFormat"); } } } } // CLASS //=================================================== // CLASS RotImage // Description: Exactly as Image but draws the image at // a specified angle around a specified rotation point. //=================================================== class RotImage extends Image { public $a=0; public $dx=0,$dy=0,$transx=0,$transy=0; private $m=array(); function __construct($aWidth,$aHeight,$a=0,$aFormat=DEFAULT_GFORMAT,$aSetAutoMargin=true) { parent::__construct($aWidth,$aHeight,$aFormat,$aSetAutoMargin); $this->dx=$this->left_margin+$this->plotwidth/2; $this->dy=$this->top_margin+$this->plotheight/2; $this->SetAngle($a); } function SetCenter($dx,$dy) { $old_dx = $this->dx; $old_dy = $this->dy; $this->dx=$dx; $this->dy=$dy; $this->SetAngle($this->a); return array($old_dx,$old_dy); } function SetTranslation($dx,$dy) { $old = array($this->transx,$this->transy); $this->transx = $dx; $this->transy = $dy; return $old; } function UpdateRotMatrice() { $a = $this->a; $a *= M_PI/180; $sa=sin($a); $ca=cos($a); // Create the rotation matrix $this->m[0][0] = $ca; $this->m[0][1] = -$sa; $this->m[0][2] = $this->dx*(1-$ca) + $sa*$this->dy ; $this->m[1][0] = $sa; $this->m[1][1] = $ca; $this->m[1][2] = $this->dy*(1-$ca) - $sa*$this->dx ; } function SetAngle($a) { $tmp = $this->a; $this->a = $a; $this->UpdateRotMatrice(); return $tmp; } function Circle($xc,$yc,$r) { list($xc,$yc) = $this->Rotate($xc,$yc); parent::Circle($xc,$yc,$r); } function FilledCircle($xc,$yc,$r) { list($xc,$yc) = $this->Rotate($xc,$yc); parent::FilledCircle($xc,$yc,$r); } function Arc($xc,$yc,$w,$h,$s,$e) { list($xc,$yc) = $this->Rotate($xc,$yc); $s += $this->a; $e += $this->a; parent::Arc($xc,$yc,$w,$h,$s,$e); } function FilledArc($xc,$yc,$w,$h,$s,$e,$style='') { list($xc,$yc) = $this->Rotate($xc,$yc); $s += $this->a; $e += $this->a; parent::FilledArc($xc,$yc,$w,$h,$s,$e); } function SetMargin($lm,$rm,$tm,$bm) { parent::SetMargin($lm,$rm,$tm,$bm); $this->dx=$this->left_margin+$this->plotwidth/2; $this->dy=$this->top_margin+$this->plotheight/2; $this->UpdateRotMatrice(); } function Rotate($x,$y) { // Optimization. Ignore rotation if Angle==0 || Angle==360 if( $this->a == 0 || $this->a == 360 ) { return array($x + $this->transx, $y + $this->transy ); } else { $x1=round($this->m[0][0]*$x + $this->m[0][1]*$y,1) + $this->m[0][2] + $this->transx; $y1=round($this->m[1][0]*$x + $this->m[1][1]*$y,1) + $this->m[1][2] + $this->transy; return array($x1,$y1); } } function CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth=-1,$fromHeight=-1,$aMix=100) { list($toX,$toY) = $this->Rotate($toX,$toY); parent::CopyMerge($fromImg,$toX,$toY,$fromX,$fromY,$toWidth,$toHeight,$fromWidth,$fromHeight,$aMix); } function ArrRotate($pnts) { $n = count($pnts)-1; for($i=0; $i < $n; $i+=2) { list ($x,$y) = $this->Rotate($pnts[$i],$pnts[$i+1]); $pnts[$i] = $x; $pnts[$i+1] = $y; } return $pnts; } function DashedLine($x1,$y1,$x2,$y2,$dash_length=1,$dash_space=4) { list($x1,$y1) = $this->Rotate($x1,$y1); list($x2,$y2) = $this->Rotate($x2,$y2); parent::DashedLine($x1,$y1,$x2,$y2,$dash_length,$dash_space); } function Line($x1,$y1,$x2,$y2) { list($x1,$y1) = $this->Rotate($x1,$y1); list($x2,$y2) = $this->Rotate($x2,$y2); parent::Line($x1,$y1,$x2,$y2); } function Rectangle($x1,$y1,$x2,$y2) { // Rectangle uses Line() so it will be rotated through that call parent::Rectangle($x1,$y1,$x2,$y2); } function FilledRectangle($x1,$y1,$x2,$y2) { if( $y1==$y2 || $x1==$x2 ) $this->Line($x1,$y1,$x2,$y2); else $this->FilledPolygon(array($x1,$y1,$x2,$y1,$x2,$y2,$x1,$y2)); } function Polygon($pnts,$closed=FALSE,$fast=FALSE) { // Polygon uses Line() so it will be rotated through that call unless // fast drawing routines are used in which case a rotate is needed if( $fast ) { parent::Polygon($this->ArrRotate($pnts)); } else { parent::Polygon($pnts,$closed,$fast); } } function FilledPolygon($pnts) { parent::FilledPolygon($this->ArrRotate($pnts)); } function Point($x,$y) { list($xp,$yp) = $this->Rotate($x,$y); parent::Point($xp,$yp); } function StrokeText($x,$y,$txt,$dir=0,$paragraph_align="left",$debug=false) { list($xp,$yp) = $this->Rotate($x,$y); return parent::StrokeText($xp,$yp,$txt,$dir,$paragraph_align,$debug); } } //======================================================================= // CLASS ImgStreamCache // Description: Handle caching of graphs to files. All image output goes // through this class //======================================================================= class ImgStreamCache { private $cache_dir, $timeout=0; // Infinite timeout //--------------- // CONSTRUCTOR function __construct($aCacheDir=CACHE_DIR) { $this->cache_dir = $aCacheDir; } //--------------- // PUBLIC METHODS // Specify a timeout (in minutes) for the file. If the file is older then the // timeout value it will be overwritten with a newer version. // If timeout is set to 0 this is the same as infinite large timeout and if // timeout is set to -1 this is the same as infinite small timeout function SetTimeout($aTimeout) { $this->timeout=$aTimeout; } // Output image to browser and also write it to the cache function PutAndStream($aImage,$aCacheFileName,$aInline,$aStrokeFileName) { // Check if we should always stroke the image to a file if( _FORCE_IMGTOFILE ) { $aStrokeFileName = _FORCE_IMGDIR.GenImgName(); } if( $aStrokeFileName != '' ) { if( $aStrokeFileName == 'auto' ) { $aStrokeFileName = GenImgName(); } if( file_exists($aStrokeFileName) ) { // Wait for lock (to make sure no readers are trying to access the image) $fd = fopen($aStrokeFileName,'w'); $lock = flock($fd, LOCK_EX); // Since the image write routines only accepts a filename which must not // exist we need to delete the old file first if( !@unlink($aStrokeFileName) ) { $lock = flock($fd, LOCK_UN); JpGraphError::RaiseL(25111,$aStrokeFileName); //(" Can't delete cached image $aStrokeFileName. Permission problem?"); } $aImage->Stream($aStrokeFileName); $lock = flock($fd, LOCK_UN); fclose($fd); } else { $aImage->Stream($aStrokeFileName); } return; } if( $aCacheFileName != '' && USE_CACHE) { $aCacheFileName = $this->cache_dir . $aCacheFileName; if( file_exists($aCacheFileName) ) { if( !$aInline ) { // If we are generating image off-line (just writing to the cache) // and the file exists and is still valid (no timeout) // then do nothing, just return. $diff=time()-filemtime($aCacheFileName); if( $diff < 0 ) { JpGraphError::RaiseL(25112,$aCacheFileName); //(" Cached imagefile ($aCacheFileName) has file date in the future!!"); } if( $this->timeout>0 && ($diff <= $this->timeout*60) ) return; } // Wait for lock (to make sure no readers are trying to access the image) $fd = fopen($aCacheFileName,'w'); $lock = flock($fd, LOCK_EX); if( !@unlink($aCacheFileName) ) { $lock = flock($fd, LOCK_UN); JpGraphError::RaiseL(25113,$aStrokeFileName); //(" Can't delete cached image $aStrokeFileName. Permission problem?"); } $aImage->Stream($aCacheFileName); $lock = flock($fd, LOCK_UN); fclose($fd); } else { $this->MakeDirs(dirname($aCacheFileName)); if( !is_writeable(dirname($aCacheFileName)) ) { JpGraphError::RaiseL(25114,$aCacheFileName); //('PHP has not enough permissions to write to the cache file '.$aCacheFileName.'. Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.'); } $aImage->Stream($aCacheFileName); } $res=true; // Set group to specified if( CACHE_FILE_GROUP != '' ) { $res = @chgrp($aCacheFileName,CACHE_FILE_GROUP); } if( CACHE_FILE_MOD != '' ) { $res = @chmod($aCacheFileName,CACHE_FILE_MOD); } if( !$res ) { JpGraphError::RaiseL(25115,$aStrokeFileName); //(" Can't set permission for cached image $aStrokeFileName. Permission problem?"); } $aImage->Destroy(); if( $aInline ) { if ($fh = @fopen($aCacheFileName, "rb") ) { $aImage->Headers(); fpassthru($fh); return; } else { JpGraphError::RaiseL(25116,$aFile);//(" Cant open file from cache [$aFile]"); } } } elseif( $aInline ) { $aImage->Headers(); $aImage->Stream(); return; } } function IsValid($aCacheFileName) { $aCacheFileName = $this->cache_dir.$aCacheFileName; if ( USE_CACHE && file_exists($aCacheFileName) ) { $diff=time()-filemtime($aCacheFileName); if( $this->timeout>0 && ($diff > $this->timeout*60) ) { return false; } else { return true; } } else { return false; } } function StreamImgFile($aImage,$aCacheFileName) { $aCacheFileName = $this->cache_dir.$aCacheFileName; if ( $fh = @fopen($aCacheFileName, 'rb') ) { $lock = flock($fh, LOCK_SH); $aImage->Headers(); fpassthru($fh); $lock = flock($fh, LOCK_UN); fclose($fh); return true; } else { JpGraphError::RaiseL(25117,$aCacheFileName);//(" Can't open cached image \"$aCacheFileName\" for reading."); } } // Check if a given image is in cache and in that case // pass it directly on to web browser. Return false if the // image file doesn't exist or exists but is to old function GetAndStream($aImage,$aCacheFileName) { if( $this->Isvalid($aCacheFileName) ) { $this->StreamImgFile($aImage,$aCacheFileName); } else { return false; } } //--------------- // PRIVATE METHODS // Create all necessary directories in a path function MakeDirs($aFile) { $dirs = array(); // In order to better work when open_basedir is enabled // we do not create directories in the root path while ( $aFile != '/' && !(file_exists($aFile)) ) { $dirs[] = $aFile.'/'; $aFile = dirname($aFile); } for ($i = sizeof($dirs)-1; $i>=0; $i--) { if(! @mkdir($dirs[$i],0777) ) { JpGraphError::RaiseL(25118,$aFile);//(" Can't create directory $aFile. Make sure PHP has write permission to this directory."); } // We also specify mode here after we have changed group. // This is necessary if Apache user doesn't belong the // default group and hence can't specify group permission // in the previous mkdir() call if( CACHE_FILE_GROUP != "" ) { $res=true; $res =@chgrp($dirs[$i],CACHE_FILE_GROUP); $res = @chmod($dirs[$i],0777); if( !$res ) { JpGraphError::RaiseL(25119,$aFile);//(" Can't set permissions for $aFile. Permission problems?"); } } } return true; } } // CLASS Cache ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_text.inc.php0000644000175000017500000002411412225176641023175 0ustar danieldanielt = $aTxt; $this->x = round($aXAbsPos); $this->y = round($aYAbsPos); $this->margin = 0; } //--------------- // PUBLIC METHODS // Set the string in the text object function Set($aTxt) { $this->t = $aTxt; } // Alias for Pos() function SetPos($aXAbsPos=0,$aYAbsPos=0,$aHAlign="left",$aVAlign="top") { //$this->Pos($aXAbsPos,$aYAbsPos,$aHAlign,$aVAlign); $this->x = $aXAbsPos; $this->y = $aYAbsPos; $this->halign = $aHAlign; $this->valign = $aVAlign; } function SetScalePos($aX,$aY) { $this->iScalePosX = $aX; $this->iScalePosY = $aY; } // Specify alignment for the text function Align($aHAlign,$aVAlign="top",$aParagraphAlign="") { $this->halign = $aHAlign; $this->valign = $aVAlign; if( $aParagraphAlign != "" ) $this->paragraph_align = $aParagraphAlign; } // Alias function SetAlign($aHAlign,$aVAlign="top",$aParagraphAlign="") { $this->Align($aHAlign,$aVAlign,$aParagraphAlign); } // Specifies the alignment for a multi line text function ParagraphAlign($aAlign) { $this->paragraph_align = $aAlign; } // Specifies the alignment for a multi line text function SetParagraphAlign($aAlign) { $this->paragraph_align = $aAlign; } function SetShadow($aShadowColor='gray',$aShadowWidth=3) { $this->ishadowwidth=$aShadowWidth; $this->shadow=$aShadowColor; $this->boxed=true; } function SetWordWrap($aCol) { $this->iWordwrap = $aCol ; } // Specify that the text should be boxed. fcolor=frame color, bcolor=border color, // $shadow=drop shadow should be added around the text. function SetBox($aFrameColor=array(255,255,255),$aBorderColor=array(0,0,0),$aShadowColor=false,$aCornerRadius=4,$aShadowWidth=3) { if( $aFrameColor === false ) { $this->boxed=false; } else { $this->boxed=true; } $this->fcolor=$aFrameColor; $this->bcolor=$aBorderColor; // For backwards compatibility when shadow was just true or false if( $aShadowColor === true ) { $aShadowColor = 'gray'; } $this->shadow=$aShadowColor; $this->icornerradius=$aCornerRadius; $this->ishadowwidth=$aShadowWidth; } function SetBox2($aFrameColor=array(255,255,255),$aBorderColor=array(0,0,0),$aShadowColor=false,$aCornerRadius=4,$aShadowWidth=3) { $this->iBoxType=2; $this->SetBox($aFrameColor,$aBorderColor,$aShadowColor,$aCornerRadius,$aShadowWidth); } // Hide the text function Hide($aHide=true) { $this->hide=$aHide; } // This looks ugly since it's not a very orthogonal design // but I added this "inverse" of Hide() to harmonize // with some classes which I designed more recently (especially) // jpgraph_gantt function Show($aShow=true) { $this->hide=!$aShow; } // Specify font function SetFont($aFamily,$aStyle=FS_NORMAL,$aSize=10) { $this->font_family=$aFamily; $this->font_style=$aStyle; $this->font_size=$aSize; } // Center the text between $left and $right coordinates function Center($aLeft,$aRight,$aYAbsPos=false) { $this->x = $aLeft + ($aRight-$aLeft )/2; $this->halign = "center"; if( is_numeric($aYAbsPos) ) $this->y = $aYAbsPos; } // Set text color function SetColor($aColor) { $this->color = $aColor; } function SetAngle($aAngle) { $this->SetOrientation($aAngle); } // Orientation of text. Note only TTF fonts can have an arbitrary angle function SetOrientation($aDirection=0) { if( is_numeric($aDirection) ) $this->dir=$aDirection; elseif( $aDirection=="h" ) $this->dir = 0; elseif( $aDirection=="v" ) $this->dir = 90; else JpGraphError::RaiseL(25051);//(" Invalid direction specified for text."); } // Total width of text function GetWidth($aImg) { $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $w = $aImg->GetTextWidth($this->t,$this->dir); return $w; } // Hight of font function GetFontHeight($aImg) { $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $h = $aImg->GetFontHeight(); return $h; } function GetTextHeight($aImg) { $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $h = $aImg->GetTextHeight($this->t,$this->dir); return $h; } function GetHeight($aImg) { // Synonym for GetTextHeight() $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $h = $aImg->GetTextHeight($this->t,$this->dir); return $h; } // Set the margin which will be interpretated differently depending // on the context. function SetMargin($aMarg) { $this->margin = $aMarg; } function StrokeWithScale($aImg,$axscale,$ayscale) { if( $this->iScalePosX === null || $this->iScalePosY === null ) { $this->Stroke($aImg); } else { $this->Stroke($aImg, round($axscale->Translate($this->iScalePosX)), round($ayscale->Translate($this->iScalePosY))); } } function SetCSIMTarget($aURITarget,$aAlt='',$aWinTarget='') { $this->iCSIMtarget = $aURITarget; $this->iCSIMalt = $aAlt; $this->iCSIMWinTarget = $aWinTarget; } function GetCSIMareas() { if( $this->iCSIMtarget !== '' ) { return $this->iCSIMarea; } else { return ''; } } // Display text in image function Stroke($aImg,$x=null,$y=null) { if( $x !== null ) $this->x = round($x); if( $y !== null ) $this->y = round($y); // Insert newlines if( $this->iWordwrap > 0 ) { $this->t = wordwrap($this->t,$this->iWordwrap,"\n"); } // If position been given as a fraction of the image size // calculate the absolute position if( $this->x < 1 && $this->x > 0 ) $this->x *= $aImg->width; if( $this->y < 1 && $this->y > 0 ) $this->y *= $aImg->height; $aImg->PushColor($this->color); $aImg->SetFont($this->font_family,$this->font_style,$this->font_size); $aImg->SetTextAlign($this->halign,$this->valign); if( $this->boxed ) { if( $this->fcolor=="nofill" ) { $this->fcolor=false; } $oldweight=$aImg->SetLineWeight(1); if( $this->iBoxType == 2 && $this->font_family > FF_FONT2+2 ) { $bbox = $aImg->StrokeBoxedText2($this->x, $this->y, $this->t, $this->dir, $this->fcolor, $this->bcolor, $this->shadow, $this->paragraph_align, 2,4, $this->icornerradius, $this->ishadowwidth); } else { $bbox = $aImg->StrokeBoxedText($this->x,$this->y,$this->t, $this->dir,$this->fcolor,$this->bcolor,$this->shadow, $this->paragraph_align,3,3,$this->icornerradius, $this->ishadowwidth); } $aImg->SetLineWeight($oldweight); } else { $debug=false; $bbox = $aImg->StrokeText($this->x,$this->y,$this->t,$this->dir,$this->paragraph_align,$debug); } // Create CSIM targets $coords = $bbox[0].','.$bbox[1].','.$bbox[2].','.$bbox[3].','.$bbox[4].','.$bbox[5].','.$bbox[6].','.$bbox[7]; $this->iCSIMarea = "iCSIMtarget)."\" "; if( trim($this->iCSIMalt) != '' ) { $this->iCSIMarea .= " alt=\"".$this->iCSIMalt."\" "; $this->iCSIMarea .= " title=\"".$this->iCSIMalt."\" "; } if( trim($this->iCSIMWinTarget) != '' ) { $this->iCSIMarea .= " target=\"".$this->iCSIMWinTarget."\" "; } $this->iCSIMarea .= " />\n"; $aImg->PopColor($this->color); } } // Class ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_plotband.php0000644000175000017500000005110512225176641023244 0ustar danieldanielx=$aX; $this->y=$aY; $this->w=$aWidth; $this->h=$aHeight; $this->xe=$aX+$aWidth-1; $this->ye=$aY+$aHeight-1; } } //===================================================================== // Class RectPattern // Base class for pattern hierarchi that is used to display patterned // bands on the graph. Any subclass that doesn't override Stroke() // must at least implement method DoPattern($aImg) which is responsible // for drawing the pattern onto the graph. //===================================================================== class RectPattern { protected $color; protected $weight; protected $rect=null; protected $doframe=true; protected $linespacing; // Line spacing in pixels protected $iBackgroundColor=-1; // Default is no background fill function __construct($aColor,$aWeight=1) { $this->color = $aColor; $this->weight = $aWeight; } function SetBackground($aBackgroundColor) { $this->iBackgroundColor=$aBackgroundColor; } function SetPos($aRect) { $this->rect = $aRect; } function ShowFrame($aShow=true) { $this->doframe=$aShow; } function SetDensity($aDens) { if( $aDens < 1 || $aDens > 100 ) JpGraphError::RaiseL(16001,$aDens); //(" Desity for pattern must be between 1 and 100. (You tried $aDens)"); // 1% corresponds to linespacing=50 // 100 % corresponds to linespacing 1 $this->linespacing = floor(((100-$aDens)/100.0)*50)+1; } function Stroke($aImg) { if( $this->rect == null ) JpGraphError::RaiseL(16002); //(" No positions specified for pattern."); if( !(is_numeric($this->iBackgroundColor) && $this->iBackgroundColor==-1) ) { $aImg->SetColor($this->iBackgroundColor); $aImg->FilledRectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye); } $aImg->SetColor($this->color); $aImg->SetLineWeight($this->weight); // Virtual function implemented by subclass $this->DoPattern($aImg); // Frame around the pattern area if( $this->doframe ) $aImg->Rectangle($this->rect->x,$this->rect->y,$this->rect->xe,$this->rect->ye); } } //===================================================================== // Class RectPatternSolid // Implements a solid band //===================================================================== class RectPatternSolid extends RectPattern { function __construct($aColor="black",$aWeight=1) { parent::__construct($aColor,$aWeight); } function DoPattern($aImg) { $aImg->SetColor($this->color); $aImg->FilledRectangle($this->rect->x,$this->rect->y, $this->rect->xe,$this->rect->ye); } } //===================================================================== // Class RectPatternHor // Implements horizontal line pattern //===================================================================== class RectPatternHor extends RectPattern { function __construct($aColor="black",$aWeight=1,$aLineSpacing=7) { parent::__construct($aColor,$aWeight); $this->linespacing = $aLineSpacing; } function DoPattern($aImg) { $x0 = $this->rect->x; $x1 = $this->rect->xe; $y = $this->rect->y; while( $y < $this->rect->ye ) { $aImg->Line($x0,$y,$x1,$y); $y += $this->linespacing; } } } //===================================================================== // Class RectPatternVert // Implements vertical line pattern //===================================================================== class RectPatternVert extends RectPattern { function __construct($aColor="black",$aWeight=1,$aLineSpacing=7) { parent::__construct($aColor,$aWeight); $this->linespacing = $aLineSpacing; } //-------------------- // Private methods // function DoPattern($aImg) { $x = $this->rect->x; $y0 = $this->rect->y; $y1 = $this->rect->ye; while( $x < $this->rect->xe ) { $aImg->Line($x,$y0,$x,$y1); $x += $this->linespacing; } } } //===================================================================== // Class RectPatternRDiag // Implements right diagonal pattern //===================================================================== class RectPatternRDiag extends RectPattern { function __construct($aColor="black",$aWeight=1,$aLineSpacing=12) { parent::__construct($aColor,$aWeight); $this->linespacing = $aLineSpacing; } function DoPattern($aImg) { // -------------------- // | / / / / /| // |/ / / / / | // | / / / / | // -------------------- $xe = $this->rect->xe; $ye = $this->rect->ye; $x0 = $this->rect->x + round($this->linespacing/2); $y0 = $this->rect->y; $x1 = $this->rect->x; $y1 = $this->rect->y + round($this->linespacing/2); while($x0<=$xe && $y1<=$ye) { $aImg->Line($x0,$y0,$x1,$y1); $x0 += $this->linespacing; $y1 += $this->linespacing; } if( $xe-$x1 > $ye-$y0 ) { // Width larger than height $x1 = $this->rect->x + ($y1-$ye); $y1 = $ye; $y0 = $this->rect->y; while( $x0 <= $xe ) { $aImg->Line($x0,$y0,$x1,$y1); $x0 += $this->linespacing; $x1 += $this->linespacing; } $y0=$this->rect->y + ($x0-$xe); $x0=$xe; } else { // Height larger than width $diff = $x0-$xe; $y0 = $diff+$this->rect->y; $x0 = $xe; $x1 = $this->rect->x; while( $y1 <= $ye ) { $aImg->Line($x0,$y0,$x1,$y1); $y1 += $this->linespacing; $y0 += $this->linespacing; } $diff = $y1-$ye; $y1 = $ye; $x1 = $diff + $this->rect->x; } while( $y0 <= $ye ) { $aImg->Line($x0,$y0,$x1,$y1); $y0 += $this->linespacing; $x1 += $this->linespacing; } } } //===================================================================== // Class RectPatternLDiag // Implements left diagonal pattern //===================================================================== class RectPatternLDiag extends RectPattern { function __construct($aColor="black",$aWeight=1,$aLineSpacing=12) { $this->linespacing = $aLineSpacing; parent::__construct($aColor,$aWeight); } function DoPattern($aImg) { // -------------------- // |\ \ \ \ \ | // | \ \ \ \ \| // | \ \ \ \ | // |------------------| $xe = $this->rect->xe; $ye = $this->rect->ye; $x0 = $this->rect->x + round($this->linespacing/2); $y0 = $this->rect->ye; $x1 = $this->rect->x; $y1 = $this->rect->ye - round($this->linespacing/2); while($x0<=$xe && $y1>=$this->rect->y) { $aImg->Line($x0,$y0,$x1,$y1); $x0 += $this->linespacing; $y1 -= $this->linespacing; } if( $xe-$x1 > $ye-$this->rect->y ) { // Width larger than height $x1 = $this->rect->x + ($this->rect->y-$y1); $y0=$ye; $y1=$this->rect->y; while( $x0 <= $xe ) { $aImg->Line($x0,$y0,$x1,$y1); $x0 += $this->linespacing; $x1 += $this->linespacing; } $y0=$this->rect->ye - ($x0-$xe); $x0=$xe; } else { // Height larger than width $diff = $x0-$xe; $y0 = $ye-$diff; $x0 = $xe; while( $y1 >= $this->rect->y ) { $aImg->Line($x0,$y0,$x1,$y1); $y0 -= $this->linespacing; $y1 -= $this->linespacing; } $diff = $this->rect->y - $y1; $x1 = $this->rect->x + $diff; $y1 = $this->rect->y; } while( $y0 >= $this->rect->y ) { $aImg->Line($x0,$y0,$x1,$y1); $y0 -= $this->linespacing; $x1 += $this->linespacing; } } } //===================================================================== // Class RectPattern3DPlane // Implements "3D" plane pattern //===================================================================== class RectPattern3DPlane extends RectPattern { private $alpha=50; // Parameter that specifies the distance // to "simulated" horizon in pixel from the // top of the band. Specifies how fast the lines // converge. function __construct($aColor="black",$aWeight=1) { parent::__construct($aColor,$aWeight); $this->SetDensity(10); // Slightly larger default } function SetHorizon($aHorizon) { $this->alpha=$aHorizon; } function DoPattern($aImg) { // "Fake" a nice 3D grid-effect. $x0 = $this->rect->x + $this->rect->w/2; $y0 = $this->rect->y; $x1 = $x0; $y1 = $this->rect->ye; $x0_right = $x0; $x1_right = $x1; // BTW "apa" means monkey in Swedish but is really a shortform for // "alpha+a" which was the labels I used on paper when I derived the // geometric to get the 3D perspective right. // $apa is the height of the bounding rectangle plus the distance to the // artifical horizon (alpha) $apa = $this->rect->h + $this->alpha; // Three cases and three loops // 1) The endpoint of the line ends on the bottom line // 2) The endpoint ends on the side // 3) Horizontal lines // Endpoint falls on bottom line $middle=$this->rect->x + $this->rect->w/2; $dist=$this->linespacing; $factor=$this->alpha /($apa); while($x1>$this->rect->x) { $aImg->Line($x0,$y0,$x1,$y1); $aImg->Line($x0_right,$y0,$x1_right,$y1); $x1 = $middle - $dist; $x0 = $middle - $dist * $factor; $x1_right = $middle + $dist; $x0_right = $middle + $dist * $factor; $dist += $this->linespacing; } // Endpoint falls on sides $dist -= $this->linespacing; $d=$this->rect->w/2; $c = $apa - $d*$apa/$dist; while( $x0>$this->rect->x ) { $aImg->Line($x0,$y0,$this->rect->x,$this->rect->ye-$c); $aImg->Line($x0_right,$y0,$this->rect->xe,$this->rect->ye-$c); $dist += $this->linespacing; $x0 = $middle - $dist * $factor; $x1 = $middle - $dist; $x0_right = $middle + $dist * $factor; $c = $apa - $d*$apa/$dist; } // Horizontal lines // They need some serious consideration since they are a function // of perspective depth (alpha) and density (linespacing) $x0=$this->rect->x; $x1=$this->rect->xe; $y=$this->rect->ye; // The first line is drawn directly. Makes the loop below slightly // more readable. $aImg->Line($x0,$y,$x1,$y); $hls = $this->linespacing; // A correction factor for vertical "brick" line spacing to account for // a) the difference in number of pixels hor vs vert // b) visual apperance to make the first layer of "bricks" look more // square. $vls = $this->linespacing*0.6; $ds = $hls*($apa-$vls)/$apa; // Get the slope for the "perspective line" going from bottom right // corner to top left corner of the "first" brick. // Uncomment the following lines if you want to get a visual understanding // of what this helpline does. BTW this mimics the way you would get the // perspective right when drawing on paper. /* $x0 = $middle; $y0 = $this->rect->ye; $len=floor(($this->rect->ye-$this->rect->y)/$vls); $x1 = $middle+round($len*$ds); $y1 = $this->rect->ye-$len*$vls; $aImg->PushColor("red"); $aImg->Line($x0,$y0,$x1,$y1); $aImg->PopColor(); */ $y -= $vls; $k=($this->rect->ye-($this->rect->ye-$vls))/($middle-($middle-$ds)); $dist = $hls; while( $y>$this->rect->y ) { $aImg->Line($this->rect->x,$y,$this->rect->xe,$y); $adj = $k*$dist/(1+$dist*$k/$apa); if( $adj < 2 ) $adj=1; $y = $this->rect->ye - round($adj); $dist += $hls; } } } //===================================================================== // Class RectPatternCross // Vert/Hor crosses //===================================================================== class RectPatternCross extends RectPattern { private $vert=null; private $hor=null; function __construct($aColor="black",$aWeight=1) { parent::__construct($aColor,$aWeight); $this->vert = new RectPatternVert($aColor,$aWeight); $this->hor = new RectPatternHor($aColor,$aWeight); } function SetOrder($aDepth) { $this->vert->SetOrder($aDepth); $this->hor->SetOrder($aDepth); } function SetPos($aRect) { parent::SetPos($aRect); $this->vert->SetPos($aRect); $this->hor->SetPos($aRect); } function SetDensity($aDens) { $this->vert->SetDensity($aDens); $this->hor->SetDensity($aDens); } function DoPattern($aImg) { $this->vert->DoPattern($aImg); $this->hor->DoPattern($aImg); } } //===================================================================== // Class RectPatternDiagCross // Vert/Hor crosses //===================================================================== class RectPatternDiagCross extends RectPattern { private $left=null; private $right=null; function __construct($aColor="black",$aWeight=1) { parent::__construct($aColor,$aWeight); $this->right = new RectPatternRDiag($aColor,$aWeight); $this->left = new RectPatternLDiag($aColor,$aWeight); } function SetOrder($aDepth) { $this->left->SetOrder($aDepth); $this->right->SetOrder($aDepth); } function SetPos($aRect) { parent::SetPos($aRect); $this->left->SetPos($aRect); $this->right->SetPos($aRect); } function SetDensity($aDens) { $this->left->SetDensity($aDens); $this->right->SetDensity($aDens); } function DoPattern($aImg) { $this->left->DoPattern($aImg); $this->right->DoPattern($aImg); } } //===================================================================== // Class RectPatternFactory // Factory class for rectangular pattern //===================================================================== class RectPatternFactory { function __construct() { // Empty } function Create($aPattern,$aColor,$aWeight=1) { switch($aPattern) { case BAND_RDIAG: $obj = new RectPatternRDiag($aColor,$aWeight); break; case BAND_LDIAG: $obj = new RectPatternLDiag($aColor,$aWeight); break; case BAND_SOLID: $obj = new RectPatternSolid($aColor,$aWeight); break; case BAND_VLINE: $obj = new RectPatternVert($aColor,$aWeight); break; case BAND_HLINE: $obj = new RectPatternHor($aColor,$aWeight); break; case BAND_3DPLANE: $obj = new RectPattern3DPlane($aColor,$aWeight); break; case BAND_HVCROSS: $obj = new RectPatternCross($aColor,$aWeight); break; case BAND_DIAGCROSS: $obj = new RectPatternDiagCross($aColor,$aWeight); break; default: JpGraphError::RaiseL(16003,$aPattern); //(" Unknown pattern specification ($aPattern)"); } return $obj; } } //===================================================================== // Class PlotBand // Factory class which is used by the client. // It is responsible for factoring the corresponding pattern // concrete class. //===================================================================== class PlotBand { public $depth; // Determine if band should be over or under the plots private $prect=null; private $dir, $min, $max; function __construct($aDir,$aPattern,$aMin,$aMax,$aColor="black",$aWeight=1,$aDepth=DEPTH_BACK) { $f = new RectPatternFactory(); $this->prect = $f->Create($aPattern,$aColor,$aWeight); if( is_numeric($aMin) && is_numeric($aMax) && ($aMin > $aMax) ) JpGraphError::RaiseL(16004); //('Min value for plotband is larger than specified max value. Please correct.'); $this->dir = $aDir; $this->min = $aMin; $this->max = $aMax; $this->depth=$aDepth; } // Set position. aRect contains absolute image coordinates function SetPos($aRect) { assert( $this->prect != null ) ; $this->prect->SetPos($aRect); } function ShowFrame($aFlag=true) { $this->prect->ShowFrame($aFlag); } // Set z-order. In front of pplot or in the back function SetOrder($aDepth) { $this->depth=$aDepth; } function SetDensity($aDens) { $this->prect->SetDensity($aDens); } function GetDir() { return $this->dir; } function GetMin() { return $this->min; } function GetMax() { return $this->max; } function PreStrokeAdjust($aGraph) { // Nothing to do } // Display band function Stroke($aImg,$aXScale,$aYScale) { assert( $this->prect != null ) ; if( $this->dir == HORIZONTAL ) { if( $this->min === 'min' ) $this->min = $aYScale->GetMinVal(); if( $this->max === 'max' ) $this->max = $aYScale->GetMaxVal(); // Only draw the bar if it actually appears in the range if ($this->min < $aYScale->GetMaxVal() && $this->max > $aYScale->GetMinVal()) { // Trucate to limit of axis $this->min = max($this->min, $aYScale->GetMinVal()); $this->max = min($this->max, $aYScale->GetMaxVal()); $x=$aXScale->scale_abs[0]; $y=$aYScale->Translate($this->max); $width=$aXScale->scale_abs[1]-$aXScale->scale_abs[0]+1; $height=abs($y-$aYScale->Translate($this->min))+1; $this->prect->SetPos(new Rectangle($x,$y,$width,$height)); $this->prect->Stroke($aImg); } } else { // VERTICAL if( $this->min === 'min' ) $this->min = $aXScale->GetMinVal(); if( $this->max === 'max' ) $this->max = $aXScale->GetMaxVal(); // Only draw the bar if it actually appears in the range if ($this->min < $aXScale->GetMaxVal() && $this->max > $aXScale->GetMinVal()) { // Trucate to limit of axis $this->min = max($this->min, $aXScale->GetMinVal()); $this->max = min($this->max, $aXScale->GetMaxVal()); $y=$aYScale->scale_abs[1]; $x=$aXScale->Translate($this->min); $height=abs($aYScale->scale_abs[1]-$aYScale->scale_abs[0]); $width=abs($x-$aXScale->Translate($this->max)); $this->prect->SetPos(new Rectangle($x,$y,$width,$height)); $this->prect->Stroke($aImg); } } } } ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_pie3d.php0000644000175000017500000007625212225176641022457 0ustar danieldanielradius = 0.5; $this->data = $data; $this->title = new Text(""); $this->title->SetFont(FF_FONT1,FS_BOLD); $this->value = new DisplayValue(); $this->value->Show(); $this->value->SetFormat('%.0f%%'); } //--------------- // PUBLIC METHODS // Set label arrays function SetLegends($aLegend) { $this->legends = array_reverse(array_slice($aLegend,0,count($this->data))); } function SetSliceColors($aColors) { $this->setslicecolors = $aColors; } function Legend($aGraph) { parent::Legend($aGraph); $aGraph->legend->txtcol = array_reverse($aGraph->legend->txtcol); } function SetCSIMTargets($aTargets,$aAlts='',$aWinTargets='') { $this->csimtargets = $aTargets; $this->csimwintargets = $aWinTargets; $this->csimalts = $aAlts; } // Should the slices be separated by a line? If color is specified as "" no line // will be used to separate pie slices. function SetEdge($aColor='black',$aWeight=1) { $this->edgecolor = $aColor; $this->edgeweight = $aWeight; } // Specify projection angle for 3D in degrees // Must be between 20 and 70 degrees function SetAngle($a) { if( $a<5 || $a>90 ) { JpGraphError::RaiseL(14002); //("PiePlot3D::SetAngle() 3D Pie projection angle must be between 5 and 85 degrees."); } else { $this->angle = $a; } } function Add3DSliceToCSIM($i,$xc,$yc,$height,$width,$thick,$sa,$ea) { //Slice number, ellipse centre (x,y), height, width, start angle, end angle $sa *= M_PI/180; $ea *= M_PI/180; //add coordinates of the centre to the map $coords = "$xc, $yc"; //add coordinates of the first point on the arc to the map $xp = floor($width*cos($sa)/2+$xc); $yp = floor($yc-$height*sin($sa)/2); $coords.= ", $xp, $yp"; //If on the front half, add the thickness offset if ($sa >= M_PI && $sa <= 2*M_PI*1.01) { $yp = floor($yp+$thick); $coords.= ", $xp, $yp"; } //add coordinates every 0.2 radians $a=$sa+0.2; while ($a<$ea) { $xp = floor($width*cos($a)/2+$xc); if ($a >= M_PI && $a <= 2*M_PI*1.01) { $yp = floor($yc-($height*sin($a)/2)+$thick); } else { $yp = floor($yc-$height*sin($a)/2); } $coords.= ", $xp, $yp"; $a += 0.2; } //Add the last point on the arc $xp = floor($width*cos($ea)/2+$xc); $yp = floor($yc-$height*sin($ea)/2); if ($ea >= M_PI && $ea <= 2*M_PI*1.01) { $coords.= ", $xp, ".floor($yp+$thick); } $coords.= ", $xp, $yp"; $alt=''; if( !empty($this->csimtargets[$i]) ) { $this->csimareas .= "csimtargets[$i]."\""; if( !empty($this->csimwintargets[$i]) ) { $this->csimareas .= " target=\"".$this->csimwintargets[$i]."\" "; } if( !empty($this->csimalts[$i]) ) { $tmp=sprintf($this->csimalts[$i],$this->data[$i]); $this->csimareas .= "alt=\"$tmp\" title=\"$tmp\" "; } $this->csimareas .= " />\n"; } } function SetLabels($aLabels,$aLblPosAdj="auto") { $this->labels = $aLabels; $this->ilabelposadj=$aLblPosAdj; } // Distance from the pie to the labels function SetLabelMargin($m) { $this->value->SetMargin($m); } // Show a thin line from the pie to the label for a specific slice function ShowLabelHint($f=true) { $this->showlabelhint=$f; } // Set color of hint line to label for each slice function SetLabelHintColor($c) { $this->labelhintcolor=$c; } function SetHeight($aHeight) { $this->iThickness = $aHeight; } // Normalize Angle between 0-360 function NormAngle($a) { // Normalize anle to 0 to 2M_PI // if( $a > 0 ) { while($a > 360) $a -= 360; } else { while($a < 0) $a += 360; } if( $a < 0 ) $a = 360 + $a; if( $a == 360 ) $a=0; return $a; } // Draw one 3D pie slice at position ($xc,$yc) with height $z function Pie3DSlice($img,$xc,$yc,$w,$h,$sa,$ea,$z,$fillcolor,$shadow=0.65) { // Due to the way the 3D Pie algorithm works we are // guaranteed that any slice we get into this method // belongs to either the left or right side of the // pie ellipse. Hence, no slice will cross 90 or 270 // point. if( ($sa < 90 && $ea > 90) || ( ($sa > 90 && $sa < 270) && $ea > 270) ) { JpGraphError::RaiseL(14003);//('Internal assertion failed. Pie3D::Pie3DSlice'); exit(1); } $p[] = array(); // Setup pre-calculated values $rsa = $sa/180*M_PI; // to Rad $rea = $ea/180*M_PI; // to Rad $sinsa = sin($rsa); $cossa = cos($rsa); $sinea = sin($rea); $cosea = cos($rea); // p[] is the points for the overall slice and // pt[] is the points for the top pie // Angular step when approximating the arc with a polygon train. $step = 0.05; if( $sa >= 270 ) { if( $ea > 360 || ($ea > 0 && $ea <= 90) ) { if( $ea > 0 && $ea <= 90 ) { // Adjust angle to simplify conditions in loops $rea += 2*M_PI; } $p = array($xc,$yc,$xc,$yc+$z, $xc+$w*$cossa,$z+$yc-$h*$sinsa); $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); for( $a=$rsa; $a < 2*M_PI; $a += $step ) { $tca = cos($a); $tsa = sin($a); $p[] = $xc+$w*$tca; $p[] = $z+$yc-$h*$tsa; $pt[] = $xc+$w*$tca; $pt[] = $yc-$h*$tsa; } $pt[] = $xc+$w; $pt[] = $yc; $p[] = $xc+$w; $p[] = $z+$yc; $p[] = $xc+$w; $p[] = $yc; $p[] = $xc; $p[] = $yc; for( $a=2*M_PI+$step; $a < $rea; $a += $step ) { $pt[] = $xc + $w*cos($a); $pt[] = $yc - $h*sin($a); } $pt[] = $xc+$w*$cosea; $pt[] = $yc-$h*$sinea; $pt[] = $xc; $pt[] = $yc; } else { $p = array($xc,$yc,$xc,$yc+$z, $xc+$w*$cossa,$z+$yc-$h*$sinsa); $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); $rea = $rea == 0.0 ? 2*M_PI : $rea; for( $a=$rsa; $a < $rea; $a += $step ) { $tca = cos($a); $tsa = sin($a); $p[] = $xc+$w*$tca; $p[] = $z+$yc-$h*$tsa; $pt[] = $xc+$w*$tca; $pt[] = $yc-$h*$tsa; } $pt[] = $xc+$w*$cosea; $pt[] = $yc-$h*$sinea; $pt[] = $xc; $pt[] = $yc; $p[] = $xc+$w*$cosea; $p[] = $z+$yc-$h*$sinea; $p[] = $xc+$w*$cosea; $p[] = $yc-$h*$sinea; $p[] = $xc; $p[] = $yc; } } elseif( $sa >= 180 ) { $p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea); $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); for( $a=$rea; $a>$rsa; $a -= $step ) { $tca = cos($a); $tsa = sin($a); $p[] = $xc+$w*$tca; $p[] = $z+$yc-$h*$tsa; $pt[] = $xc+$w*$tca; $pt[] = $yc-$h*$tsa; } $pt[] = $xc+$w*$cossa; $pt[] = $yc-$h*$sinsa; $pt[] = $xc; $pt[] = $yc; $p[] = $xc+$w*$cossa; $p[] = $z+$yc-$h*$sinsa; $p[] = $xc+$w*$cossa; $p[] = $yc-$h*$sinsa; $p[] = $xc; $p[] = $yc; } elseif( $sa >= 90 ) { if( $ea > 180 ) { $p = array($xc,$yc,$xc,$yc+$z,$xc+$w*$cosea,$z+$yc-$h*$sinea); $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); for( $a=$rea; $a > M_PI; $a -= $step ) { $tca = cos($a); $tsa = sin($a); $p[] = $xc+$w*$tca; $p[] = $z + $yc - $h*$tsa; $pt[] = $xc+$w*$tca; $pt[] = $yc-$h*$tsa; } $p[] = $xc-$w; $p[] = $z+$yc; $p[] = $xc-$w; $p[] = $yc; $p[] = $xc; $p[] = $yc; $pt[] = $xc-$w; $pt[] = $z+$yc; $pt[] = $xc-$w; $pt[] = $yc; for( $a=M_PI-$step; $a > $rsa; $a -= $step ) { $pt[] = $xc + $w*cos($a); $pt[] = $yc - $h*sin($a); } $pt[] = $xc+$w*$cossa; $pt[] = $yc-$h*$sinsa; $pt[] = $xc; $pt[] = $yc; } else { // $sa >= 90 && $ea <= 180 $p = array($xc,$yc,$xc,$yc+$z, $xc+$w*$cosea,$z+$yc-$h*$sinea, $xc+$w*$cosea,$yc-$h*$sinea, $xc,$yc); $pt = array($xc,$yc,$xc+$w*$cosea,$yc-$h*$sinea); for( $a=$rea; $a>$rsa; $a -= $step ) { $pt[] = $xc + $w*cos($a); $pt[] = $yc - $h*sin($a); } $pt[] = $xc+$w*$cossa; $pt[] = $yc-$h*$sinsa; $pt[] = $xc; $pt[] = $yc; } } else { // sa > 0 && ea < 90 $p = array($xc,$yc,$xc,$yc+$z, $xc+$w*$cossa,$z+$yc-$h*$sinsa, $xc+$w*$cossa,$yc-$h*$sinsa, $xc,$yc); $pt = array($xc,$yc,$xc+$w*$cossa,$yc-$h*$sinsa); for( $a=$rsa; $a < $rea; $a += $step ) { $pt[] = $xc + $w*cos($a); $pt[] = $yc - $h*sin($a); } $pt[] = $xc+$w*$cosea; $pt[] = $yc-$h*$sinea; $pt[] = $xc; $pt[] = $yc; } $img->PushColor($fillcolor.":".$shadow); $img->FilledPolygon($p); $img->PopColor(); $img->PushColor($fillcolor); $img->FilledPolygon($pt); $img->PopColor(); } function SetStartAngle($aStart) { if( $aStart < 0 || $aStart > 360 ) { JpGraphError::RaiseL(14004);//('Slice start angle must be between 0 and 360 degrees.'); } $this->startangle = $aStart; } // Draw a 3D Pie function Pie3D($aaoption,$img,$data,$colors,$xc,$yc,$d,$angle,$z, $shadow=0.65,$startangle=0,$edgecolor="",$edgeweight=1) { //--------------------------------------------------------------------------- // As usual the algorithm get more complicated than I originally // envisioned. I believe that this is as simple as it is possible // to do it with the features I want. It's a good exercise to start // thinking on how to do this to convince your self that all this // is really needed for the general case. // // The algorithm two draw 3D pies without "real 3D" is done in // two steps. // First imagine the pie cut in half through a thought line between // 12'a clock and 6'a clock. It now easy to imagine that we can plot // the individual slices for each half by starting with the topmost // pie slice and continue down to 6'a clock. // // In the algortithm this is done in three principal steps // Step 1. Do the knife cut to ensure by splitting slices that extends // over the cut line. This is done by splitting the original slices into // upto 3 subslices. // Step 2. Find the top slice for each half // Step 3. Draw the slices from top to bottom // // The thing that slightly complicates this scheme with all the // angle comparisons below is that we can have an arbitrary start // angle so we must take into account the different equivalence classes. // For the same reason we must walk through the angle array in a // modulo fashion. // // Limitations of algorithm: // * A small exploded slice which crosses the 270 degree point // will get slightly nagged close to the center due to the fact that // we print the slices in Z-order and that the slice left part // get printed first and might get slightly nagged by a larger // slice on the right side just before the right part of the small // slice. Not a major problem though. //--------------------------------------------------------------------------- // Determine the height of the ellippse which gives an // indication of the inclination angle $h = ($angle/90.0)*$d; $sum = 0; for($i=0; $ilabeltype == 2 ) { $this->adjusted_data = $this->AdjPercentage($data); } // Setup the start $accsum = 0; $a = $startangle; $a = $this->NormAngle($a); // // Step 1 . Split all slices that crosses 90 or 270 // $idx=0; $adjexplode=array(); $numcolors = count($colors); for($i=0; $iexplode_radius[$i]) ) { $this->explode_radius[$i]=0; } $expscale=1; if( $aaoption == 1 ) { $expscale=2; } $la = $a + $da/2; $explode = array( $xc + $this->explode_radius[$i]*cos($la*M_PI/180)*$expscale, $yc - $this->explode_radius[$i]*sin($la*M_PI/180) * ($h/$d) *$expscale ); $adjexplode[$idx] = $explode; $labeldata[$i] = array($la,$explode[0],$explode[1]); $originalangles[$i] = array($a,$a+$da); $ne = $this->NormAngle($a+$da); if( $da <= 180 ) { // If the slice size is <= 90 it can at maximum cut across // one boundary (either 90 or 270) where it needs to be split $split=-1; // no split if( ($da<=90 && ($a <= 90 && $ne > 90)) || (($da <= 180 && $da >90) && (($a < 90 || $a >= 270) && $ne > 90)) ) { $split = 90; } elseif( ($da<=90 && ($a <= 270 && $ne > 270)) || (($da<=180 && $da>90) && ($a >= 90 && $a < 270 && ($a+$da) > 270 )) ) { $split = 270; } if( $split > 0 ) { // split in two $angles[$idx] = array($a,$split); $adjcolors[$idx] = $colors[$i % $numcolors]; $adjexplode[$idx] = $explode; $angles[++$idx] = array($split,$ne); $adjcolors[$idx] = $colors[$i % $numcolors]; $adjexplode[$idx] = $explode; } else { // no split $angles[$idx] = array($a,$ne); $adjcolors[$idx] = $colors[$i % $numcolors]; $adjexplode[$idx] = $explode; } } else { // da>180 // Slice may, depending on position, cross one or two // bonudaries if( $a < 90 ) $split = 90; elseif( $a <= 270 ) $split = 270; else $split = 90; $angles[$idx] = array($a,$split); $adjcolors[$idx] = $colors[$i % $numcolors]; $adjexplode[$idx] = $explode; //if( $a+$da > 360-$split ) { // For slices larger than 270 degrees we might cross // another boundary as well. This means that we must // split the slice further. The comparison gets a little // bit complicated since we must take into accound that // a pie might have a startangle >0 and hence a slice might // wrap around the 0 angle. // Three cases: // a) Slice starts before 90 and hence gets a split=90, but // we must also check if we need to split at 270 // b) Slice starts after 90 but before 270 and slices // crosses 90 (after a wrap around of 0) // c) If start is > 270 (hence the firstr split is at 90) // and the slice is so large that it goes all the way // around 270. if( ($a < 90 && ($a+$da > 270)) || ($a > 90 && $a<=270 && ($a+$da>360+90) ) || ($a > 270 && $this->NormAngle($a+$da)>270) ) { $angles[++$idx] = array($split,360-$split); $adjcolors[$idx] = $colors[$i % $numcolors]; $adjexplode[$idx] = $explode; $angles[++$idx] = array(360-$split,$ne); $adjcolors[$idx] = $colors[$i % $numcolors]; $adjexplode[$idx] = $explode; } else { // Just a simple split to the previous decided // angle. $angles[++$idx] = array($split,$ne); $adjcolors[$idx] = $colors[$i % $numcolors]; $adjexplode[$idx] = $explode; } } $a += $da; $a = $this->NormAngle($a); } // Total number of slices $n = count($angles); for($i=0; $i<$n; ++$i) { list($dbgs,$dbge) = $angles[$i]; } // // Step 2. Find start index (first pie that starts in upper left quadrant) // $minval = $angles[0][0]; $min = 0; for( $i=0; $i<$n; ++$i ) { if( $angles[$i][0] < $minval ) { $minval = $angles[$i][0]; $min = $i; } } $j = $min; $cnt = 0; while( $angles[$j][1] <= 90 ) { $j++; if( $j>=$n) { $j=0; } if( $cnt > $n ) { JpGraphError::RaiseL(14005); //("Pie3D Internal error (#1). Trying to wrap twice when looking for start index"); } ++$cnt; } $start = $j; // // Step 3. Print slices in z-order // $cnt = 0; // First stroke all the slices between 90 and 270 (left half circle) // counterclockwise while( $angles[$j][0] < 270 && $aaoption !== 2 ) { list($x,$y) = $adjexplode[$j]; $this->Pie3DSlice($img,$x,$y,$d,$h,$angles[$j][0],$angles[$j][1], $z,$adjcolors[$j],$shadow); $last = array($x,$y,$j); $j++; if( $j >= $n ) $j=0; if( $cnt > $n ) { JpGraphError::RaiseL(14006); //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); } ++$cnt; } $slice_left = $n-$cnt; $j=$start-1; if($j<0) $j=$n-1; $cnt = 0; // The stroke all slices from 90 to -90 (right half circle) // clockwise while( $cnt < $slice_left && $aaoption !== 2 ) { list($x,$y) = $adjexplode[$j]; $this->Pie3DSlice($img,$x,$y,$d,$h,$angles[$j][0],$angles[$j][1], $z,$adjcolors[$j],$shadow); $j--; if( $cnt > $n ) { JpGraphError::RaiseL(14006); //("Pie3D Internal Error: Z-Sorting algorithm for 3D Pies is not working properly (2). Trying to wrap twice while stroking."); } if($j<0) $j=$n-1; $cnt++; } // Now do a special thing. Stroke the last slice on the left // halfcircle one more time. This is needed in the case where // the slice close to 270 have been exploded. In that case the // part of the slice close to the center of the pie might be // slightly nagged. if( $aaoption !== 2 ) $this->Pie3DSlice($img,$last[0],$last[1],$d,$h,$angles[$last[2]][0], $angles[$last[2]][1],$z,$adjcolors[$last[2]],$shadow); if( $aaoption !== 1 ) { // Now print possible labels and add csim $this->value->ApplyFont($img); $margin = $img->GetFontHeight()/2 + $this->value->margin ; for($i=0; $i < count($data); ++$i ) { $la = $labeldata[$i][0]; $x = $labeldata[$i][1] + cos($la*M_PI/180)*($d+$margin)*$this->ilabelposadj; $y = $labeldata[$i][2] - sin($la*M_PI/180)*($h+$margin)*$this->ilabelposadj; if( $this->ilabelposadj >= 1.0 ) { if( $la > 180 && $la < 360 ) $y += $z; } if( $this->labeltype == 0 ) { if( $sum > 0 ) $l = 100*$data[$i]/$sum; else $l = 0; } elseif( $this->labeltype == 1 ) { $l = $data[$i]; } else { $l = $this->adjusted_data[$i]; } if( isset($this->labels[$i]) && is_string($this->labels[$i]) ) { $l=sprintf($this->labels[$i],$l); } $this->StrokeLabels($l,$img,$labeldata[$i][0]*M_PI/180,$x,$y,$z); $this->Add3DSliceToCSIM($i,$labeldata[$i][1],$labeldata[$i][2],$h*2,$d*2,$z, $originalangles[$i][0],$originalangles[$i][1]); } } // // Finally add potential lines in pie // if( $edgecolor=="" || $aaoption !== 0 ) return; $accsum = 0; $a = $startangle; $a = $this->NormAngle($a); $a *= M_PI/180.0; $idx=0; $img->PushColor($edgecolor); $img->SetLineWeight($edgeweight); $fulledge = true; for($i=0; $i < count($data) && $fulledge; ++$i ) { if( empty($this->explode_radius[$i]) ) { $this->explode_radius[$i]=0; } if( $this->explode_radius[$i] > 0 ) { $fulledge = false; } } for($i=0; $i < count($data); ++$i, ++$idx ) { $da = $data[$i]/$sum * 2*M_PI; $this->StrokeFullSliceFrame($img,$xc,$yc,$a,$a+$da,$d,$h,$z,$edgecolor, $this->explode_radius[$i],$fulledge); $a += $da; } $img->PopColor(); } function StrokeFullSliceFrame($img,$xc,$yc,$sa,$ea,$w,$h,$z,$edgecolor,$exploderadius,$fulledge) { $step = 0.02; if( $exploderadius > 0 ) { $la = ($sa+$ea)/2; $xc += $exploderadius*cos($la); $yc -= $exploderadius*sin($la) * ($h/$w) ; } $p = array($xc,$yc,$xc+$w*cos($sa),$yc-$h*sin($sa)); for($a=$sa; $a < $ea; $a += $step ) { $p[] = $xc + $w*cos($a); $p[] = $yc - $h*sin($a); } $p[] = $xc+$w*cos($ea); $p[] = $yc-$h*sin($ea); $p[] = $xc; $p[] = $yc; $img->SetColor($edgecolor); $img->Polygon($p); // Unfortunately we can't really draw the full edge around the whole of // of the slice if any of the slices are exploded. The reason is that // this algorithm is to simply. There are cases where the edges will // "overwrite" other slices when they have been exploded. // Doing the full, proper 3D hidden lines stiff is actually quite // tricky. So for exploded pies we only draw the top edge. Not perfect // but the "real" solution is much more complicated. if( $fulledge && !( $sa > 0 && $sa < M_PI && $ea < M_PI) ) { if($sa < M_PI && $ea > M_PI) { $sa = M_PI; } if($sa < 2*M_PI && (($ea >= 2*M_PI) || ($ea > 0 && $ea < $sa ) ) ) { $ea = 2*M_PI; } if( $sa >= M_PI && $ea <= 2*M_PI ) { $p = array($xc + $w*cos($sa),$yc - $h*sin($sa), $xc + $w*cos($sa),$z + $yc - $h*sin($sa)); for($a=$sa+$step; $a < $ea; $a += $step ) { $p[] = $xc + $w*cos($a); $p[] = $z + $yc - $h*sin($a); } $p[] = $xc + $w*cos($ea); $p[] = $z + $yc - $h*sin($ea); $p[] = $xc + $w*cos($ea); $p[] = $yc - $h*sin($ea); $img->SetColor($edgecolor); $img->Polygon($p); } } } function Stroke($img,$aaoption=0) { $n = count($this->data); // If user hasn't set the colors use the theme array if( $this->setslicecolors==null ) { $colors = array_keys($img->rgb->rgb_table); sort($colors); $idx_a=$this->themearr[$this->theme]; $ca = array(); $m = count($idx_a); for($i=0; $i < $m; ++$i) { $ca[$i] = $colors[$idx_a[$i]]; } $ca = array_reverse(array_slice($ca,0,$n)); } else { $ca = $this->setslicecolors; } if( $this->posx <= 1 && $this->posx > 0 ) { $xc = round($this->posx*$img->width); } else { $xc = $this->posx ; } if( $this->posy <= 1 && $this->posy > 0 ) { $yc = round($this->posy*$img->height); } else { $yc = $this->posy ; } if( $this->radius <= 1 ) { $width = floor($this->radius*min($img->width,$img->height)); // Make sure that the pie doesn't overflow the image border // The 0.9 factor is simply an extra margin to leave some space // between the pie an the border of the image. $width = min($width,min($xc*0.9,($yc*90/$this->angle-$width/4)*0.9)); } else { $width = $this->radius * ($aaoption === 1 ? 2 : 1 ) ; } // Add a sanity check for width if( $width < 1 ) { JpGraphError::RaiseL(14007);//("Width for 3D Pie is 0. Specify a size > 0"); } // Establish a thickness. By default the thickness is a fifth of the // pie slice width (=pie radius) but since the perspective depends // on the inclination angle we use some heuristics to make the edge // slightly thicker the less the angle. // Has user specified an absolute thickness? In that case use // that instead if( $this->iThickness ) { $thick = $this->iThickness; $thick *= ($aaoption === 1 ? 2 : 1 ); } else { $thick = $width/12; } $a = $this->angle; if( $a <= 30 ) $thick *= 1.6; elseif( $a <= 40 ) $thick *= 1.4; elseif( $a <= 50 ) $thick *= 1.2; elseif( $a <= 60 ) $thick *= 1.0; elseif( $a <= 70 ) $thick *= 0.8; elseif( $a <= 80 ) $thick *= 0.7; else $thick *= 0.6; $thick = floor($thick); if( $this->explode_all ) { for($i=0; $i < $n; ++$i) $this->explode_radius[$i]=$this->explode_r; } $this->Pie3D($aaoption,$img,$this->data, $ca, $xc, $yc, $width, $this->angle, $thick, 0.65, $this->startangle, $this->edgecolor, $this->edgeweight); // Adjust title position if( $aaoption != 1 ) { $this->title->SetPos($xc,$yc-$this->title->GetFontHeight($img)-$width/2-$this->title->margin, "center","bottom"); $this->title->Stroke($img); } } //--------------- // PRIVATE METHODS // Position the labels of each slice function StrokeLabels($label,$img,$a,$xp,$yp,$z) { $this->value->halign="left"; $this->value->valign="top"; // Position the axis title. // dx, dy is the offset from the top left corner of the bounding box that sorrounds the text // that intersects with the extension of the corresponding axis. The code looks a little // bit messy but this is really the only way of having a reasonable position of the // axis titles. $this->value->ApplyFont($img); $h=$img->GetTextHeight($label); // For numeric values the format of the display value // must be taken into account if( is_numeric($label) ) { if( $label >= 0 ) { $w=$img->GetTextWidth(sprintf($this->value->format,$label)); } else { $w=$img->GetTextWidth(sprintf($this->value->negformat,$label)); } } else { $w=$img->GetTextWidth($label); } while( $a > 2*M_PI ) { $a -= 2*M_PI; } if( $a>=7*M_PI/4 || $a <= M_PI/4 ) $dx=0; if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dx=($a-M_PI/4)*2/M_PI; if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dx=1; if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dx=(1-($a-M_PI*5/4)*2/M_PI); if( $a>=7*M_PI/4 ) $dy=(($a-M_PI)-3*M_PI/4)*2/M_PI; if( $a<=M_PI/4 ) $dy=(1-$a*2/M_PI); if( $a>=M_PI/4 && $a <= 3*M_PI/4 ) $dy=1; if( $a>=3*M_PI/4 && $a <= 5*M_PI/4 ) $dy=(1-($a-3*M_PI/4)*2/M_PI); if( $a>=5*M_PI/4 && $a <= 7*M_PI/4 ) $dy=0; $x = round($xp-$dx*$w); $y = round($yp-$dy*$h); // Mark anchor point for debugging /* $img->SetColor('red'); $img->Line($xp-10,$yp,$xp+10,$yp); $img->Line($xp,$yp-10,$xp,$yp+10); */ $oldmargin = $this->value->margin; $this->value->margin=0; $this->value->Stroke($img,$label,$x,$y); $this->value->margin=$oldmargin; } } // Class /* EOF */ ?> loganalyzer-3.6.5/src/classes/jpgraph/jpgraph_rgb.inc.php0000644000175000017500000006447112225176641022775 0ustar danieldanielimg = $aImg; // Conversion array between color names and RGB $this->rgb_table = array( 'aqua'=> array(0,255,255), 'lime'=> array(0,255,0), 'teal'=> array(0,128,128), 'whitesmoke'=>array(245,245,245), 'gainsboro'=>array(220,220,220), 'oldlace'=>array(253,245,230), 'linen'=>array(250,240,230), 'antiquewhite'=>array(250,235,215), 'papayawhip'=>array(255,239,213), 'blanchedalmond'=>array(255,235,205), 'bisque'=>array(255,228,196), 'peachpuff'=>array(255,218,185), 'navajowhite'=>array(255,222,173), 'moccasin'=>array(255,228,181), 'cornsilk'=>array(255,248,220), 'ivory'=>array(255,255,240), 'lemonchiffon'=>array(255,250,205), 'seashell'=>array(255,245,238), 'mintcream'=>array(245,255,250), 'azure'=>array(240,255,255), 'aliceblue'=>array(240,248,255), 'lavender'=>array(230,230,250), 'lavenderblush'=>array(255,240,245), 'mistyrose'=>array(255,228,225), 'white'=>array(255,255,255), 'black'=>array(0,0,0), 'darkslategray'=>array(47,79,79), 'dimgray'=>array(105,105,105), 'slategray'=>array(112,128,144), 'lightslategray'=>array(119,136,153), 'gray'=>array(190,190,190), 'lightgray'=>array(211,211,211), 'midnightblue'=>array(25,25,112), 'navy'=>array(0,0,128), 'indigo'=>array(75,0,130), 'electricindigo'=>array(102,0,255), 'deepindigo'=>array(138,43,226), 'pigmentindigo'=>array(75,0,130), 'indigodye'=>array(0,65,106), 'cornflowerblue'=>array(100,149,237), 'darkslateblue'=>array(72,61,139), 'slateblue'=>array(106,90,205), 'mediumslateblue'=>array(123,104,238), 'lightslateblue'=>array(132,112,255), 'mediumblue'=>array(0,0,205), 'royalblue'=>array(65,105,225), 'blue'=>array(0,0,255), 'dodgerblue'=>array(30,144,255), 'deepskyblue'=>array(0,191,255), 'skyblue'=>array(135,206,235), 'lightskyblue'=>array(135,206,250), 'steelblue'=>array(70,130,180), 'lightred'=>array(211,167,168), 'lightsteelblue'=>array(176,196,222), 'lightblue'=>array(173,216,230), 'powderblue'=>array(176,224,230), 'paleturquoise'=>array(175,238,238), 'darkturquoise'=>array(0,206,209), 'mediumturquoise'=>array(72,209,204), 'turquoise'=>array(64,224,208), 'cyan'=>array(0,255,255), 'lightcyan'=>array(224,255,255), 'cadetblue'=>array(95,158,160), 'mediumaquamarine'=>array(102,205,170), 'aquamarine'=>array(127,255,212), 'darkgreen'=>array(0,100,0), 'darkolivegreen'=>array(85,107,47), 'darkseagreen'=>array(143,188,143), 'seagreen'=>array(46,139,87), 'mediumseagreen'=>array(60,179,113), 'lightseagreen'=>array(32,178,170), 'palegreen'=>array(152,251,152), 'springgreen'=>array(0,255,127), 'lawngreen'=>array(124,252,0), 'green'=>array(0,255,0), 'chartreuse'=>array(127,255,0), 'mediumspringgreen'=>array(0,250,154), 'greenyellow'=>array(173,255,47), 'limegreen'=>array(50,205,50), 'yellowgreen'=>array(154,205,50), 'forestgreen'=>array(34,139,34), 'olivedrab'=>array(107,142,35), 'darkkhaki'=>array(189,183,107), 'khaki'=>array(240,230,140), 'palegoldenrod'=>array(238,232,170), 'lightgoldenrodyellow'=>array(250,250,210), 'lightyellow'=>array(255,255,200), 'yellow'=>array(255,255,0), 'gold'=>array(255,215,0), 'lightgoldenrod'=>array(238,221,130), 'goldenrod'=>array(218,165,32), 'darkgoldenrod'=>array(184,134,11), 'rosybrown'=>array(188,143,143), 'indianred'=>array(205,92,92), 'saddlebrown'=>array(139,69,19), 'sienna'=>array(160,82,45), 'peru'=>array(205,133,63), 'burlywood'=>array(222,184,135), 'beige'=>array(245,245,220), 'wheat'=>array(245,222,179), 'sandybrown'=>array(244,164,96), 'tan'=>array(210,180,140), 'chocolate'=>array(210,105,30), 'firebrick'=>array(178,34,34), 'brown'=>array(165,42,42), 'darksalmon'=>array(233,150,122), 'salmon'=>array(250,128,114), 'lightsalmon'=>array(255,160,122), 'orange'=>array(255,165,0), 'darkorange'=>array(255,140,0), 'coral'=>array(255,127,80), 'lightcoral'=>array(240,128,128), 'tomato'=>array(255,99,71), 'orangered'=>array(255,69,0), 'red'=>array(255,0,0), 'hotpink'=>array(255,105,180), 'deeppink'=>array(255,20,147), 'pink'=>array(255,192,203), 'lightpink'=>array(255,182,193), 'palevioletred'=>array(219,112,147), 'maroon'=>array(176,48,96), 'mediumvioletred'=>array(199,21,133), 'violetred'=>array(208,32,144), 'magenta'=>array(255,0,255), 'violet'=>array(238,130,238), 'plum'=>array(221,160,221), 'orchid'=>array(218,112,214), 'mediumorchid'=>array(186,85,211), 'darkorchid'=>array(153,50,204), 'darkviolet'=>array(148,0,211), 'blueviolet'=>array(138,43,226), 'purple'=>array(160,32,240), 'mediumpurple'=>array(147,112,219), 'thistle'=>array(216,191,216), 'snow1'=>array(255,250,250), 'snow2'=>array(238,233,233), 'snow3'=>array(205,201,201), 'snow4'=>array(139,137,137), 'seashell1'=>array(255,245,238), 'seashell2'=>array(238,229,222), 'seashell3'=>array(205,197,191), 'seashell4'=>array(139,134,130), 'AntiqueWhite1'=>array(255,239,219), 'AntiqueWhite2'=>array(238,223,204), 'AntiqueWhite3'=>array(205,192,176), 'AntiqueWhite4'=>array(139,131,120), 'bisque1'=>array(255,228,196), 'bisque2'=>array(238,213,183), 'bisque3'=>array(205,183,158), 'bisque4'=>array(139,125,107), 'peachPuff1'=>array(255,218,185), 'peachpuff2'=>array(238,203,173), 'peachpuff3'=>array(205,175,149), 'peachpuff4'=>array(139,119,101), 'navajowhite1'=>array(255,222,173), 'navajowhite2'=>array(238,207,161), 'navajowhite3'=>array(205,179,139), 'navajowhite4'=>array(139,121,94), 'lemonchiffon1'=>array(255,250,205), 'lemonchiffon2'=>array(238,233,191), 'lemonchiffon3'=>array(205,201,165), 'lemonchiffon4'=>array(139,137,112), 'ivory1'=>array(255,255,240), 'ivory2'=>array(238,238,224), 'ivory3'=>array(205,205,193), 'ivory4'=>array(139,139,131), 'honeydew'=>array(193,205,193), 'lavenderblush1'=>array(255,240,245), 'lavenderblush2'=>array(238,224,229), 'lavenderblush3'=>array(205,193,197), 'lavenderblush4'=>array(139,131,134), 'mistyrose1'=>array(255,228,225), 'mistyrose2'=>array(238,213,210), 'mistyrose3'=>array(205,183,181), 'mistyrose4'=>array(139,125,123), 'azure1'=>array(240,255,255), 'azure2'=>array(224,238,238), 'azure3'=>array(193,205,205), 'azure4'=>array(131,139,139), 'slateblue1'=>array(131,111,255), 'slateblue2'=>array(122,103,238), 'slateblue3'=>array(105,89,205), 'slateblue4'=>array(71,60,139), 'royalblue1'=>array(72,118,255), 'royalblue2'=>array(67,110,238), 'royalblue3'=>array(58,95,205), 'royalblue4'=>array(39,64,139), 'dodgerblue1'=>array(30,144,255), 'dodgerblue2'=>array(28,134,238), 'dodgerblue3'=>array(24,116,205), 'dodgerblue4'=>array(16,78,139), 'steelblue1'=>array(99,184,255), 'steelblue2'=>array(92,172,238), 'steelblue3'=>array(79,148,205), 'steelblue4'=>array(54,100,139), 'deepskyblue1'=>array(0,191,255), 'deepskyblue2'=>array(0,178,238), 'deepskyblue3'=>array(0,154,205), 'deepskyblue4'=>array(0,104,139), 'skyblue1'=>array(135,206,255), 'skyblue2'=>array(126,192,238), 'skyblue3'=>array(108,166,205), 'skyblue4'=>array(74,112,139), 'lightskyblue1'=>array(176,226,255), 'lightskyblue2'=>array(164,211,238), 'lightskyblue3'=>array(141,182,205), 'lightskyblue4'=>array(96,123,139), 'slategray1'=>array(198,226,255), 'slategray2'=>array(185,211,238), 'slategray3'=>array(159,182,205), 'slategray4'=>array(108,123,139), 'lightsteelblue1'=>array(202,225,255), 'lightsteelblue2'=>array(188,210,238), 'lightsteelblue3'=>array(162,181,205), 'lightsteelblue4'=>array(110,123,139), 'lightblue1'=>array(191,239,255), 'lightblue2'=>array(178,223,238), 'lightblue3'=>array(154,192,205), 'lightblue4'=>array(104,131,139), 'lightcyan1'=>array(224,255,255), 'lightcyan2'=>array(209,238,238), 'lightcyan3'=>array(180,205,205), 'lightcyan4'=>array(122,139,139), 'paleturquoise1'=>array(187,255,255), 'paleturquoise2'=>array(174,238,238), 'paleturquoise3'=>array(150,205,205), 'paleturquoise4'=>array(102,139,139), 'cadetblue1'=>array(152,245,255), 'cadetblue2'=>array(142,229,238), 'cadetblue3'=>array(122,197,205), 'cadetblue4'=>array(83,134,139), 'turquoise1'=>array(0,245,255), 'turquoise2'=>array(0,229,238), 'turquoise3'=>array(0,197,205), 'turquoise4'=>array(0,134,139), 'cyan1'=>array(0,255,255), 'cyan2'=>array(0,238,238), 'cyan3'=>array(0,205,205), 'cyan4'=>array(0,139,139), 'darkslategray1'=>array(151,255,255), 'darkslategray2'=>array(141,238,238), 'darkslategray3'=>array(121,205,205), 'darkslategray4'=>array(82,139,139), 'aquamarine1'=>array(127,255,212), 'aquamarine2'=>array(118,238,198), 'aquamarine3'=>array(102,205,170), 'aquamarine4'=>array(69,139,116), 'darkseagreen1'=>array(193,255,193), 'darkseagreen2'=>array(180,238,180), 'darkseagreen3'=>array(155,205,155), 'darkseagreen4'=>array(105,139,105), 'seagreen1'=>array(84,255,159), 'seagreen2'=>array(78,238,148), 'seagreen3'=>array(67,205,128), 'seagreen4'=>array(46,139,87), 'palegreen1'=>array(154,255,154), 'palegreen2'=>array(144,238,144), 'palegreen3'=>array(124,205,124), 'palegreen4'=>array(84,139,84), 'springgreen1'=>array(0,255,127), 'springgreen2'=>array(0,238,118), 'springgreen3'=>array(0,205,102), 'springgreen4'=>array(0,139,69), 'chartreuse1'=>array(127,255,0), 'chartreuse2'=>array(118,238,0), 'chartreuse3'=>array(102,205,0), 'chartreuse4'=>array(69,139,0), 'olivedrab1'=>array(192,255,62), 'olivedrab2'=>array(179,238,58), 'olivedrab3'=>array(154,205,50), 'olivedrab4'=>array(105,139,34), 'darkolivegreen1'=>array(202,255,112), 'darkolivegreen2'=>array(188,238,104), 'darkolivegreen3'=>array(162,205,90), 'darkolivegreen4'=>array(110,139,61), 'khaki1'=>array(255,246,143), 'khaki2'=>array(238,230,133), 'khaki3'=>array(205,198,115), 'khaki4'=>array(139,134,78), 'lightgoldenrod1'=>array(255,236,139), 'lightgoldenrod2'=>array(238,220,130), 'lightgoldenrod3'=>array(205,190,112), 'lightgoldenrod4'=>array(139,129,76), 'yellow1'=>array(255,255,0), 'yellow2'=>array(238,238,0), 'yellow3'=>array(205,205,0), 'yellow4'=>array(139,139,0), 'gold1'=>array(255,215,0), 'gold2'=>array(238,201,0), 'gold3'=>array(205,173,0), 'gold4'=>array(139,117,0), 'goldenrod1'=>array(255,193,37), 'goldenrod2'=>array(238,180,34), 'goldenrod3'=>array(205,155,29), 'goldenrod4'=>array(139,105,20), 'darkgoldenrod1'=>array(255,185,15), 'darkgoldenrod2'=>array(238,173,14), 'darkgoldenrod3'=>array(205,149,12), 'darkgoldenrod4'=>array(139,101,8), 'rosybrown1'=>array(255,193,193), 'rosybrown2'=>array(238,180,180), 'rosybrown3'=>array(205,155,155), 'rosybrown4'=>array(139,105,105), 'indianred1'=>array(255,106,106), 'indianred2'=>array(238,99,99), 'indianred3'=>array(205,85,85), 'indianred4'=>array(139,58,58), 'sienna1'=>array(255,130,71), 'sienna2'=>array(238,121,66), 'sienna3'=>array(205,104,57), 'sienna4'=>array(139,71,38), 'burlywood1'=>array(255,211,155), 'burlywood2'=>array(238,197,145), 'burlywood3'=>array(205,170,125), 'burlywood4'=>array(139,115,85), 'wheat1'=>array(255,231,186), 'wheat2'=>array(238,216,174), 'wheat3'=>array(205,186,150), 'wheat4'=>array(139,126,102), 'tan1'=>array(255,165,79), 'tan2'=>array(238,154,73), 'tan3'=>array(205,133,63), 'tan4'=>array(139,90,43), 'chocolate1'=>array(255,127,36), 'chocolate2'=>array(238,118,33), 'chocolate3'=>array(205,102,29), 'chocolate4'=>array(139,69,19), 'firebrick1'=>array(255,48,48), 'firebrick2'=>array(238,44,44), 'firebrick3'=>array(205,38,38), 'firebrick4'=>array(139,26,26), 'brown1'=>array(255,64,64), 'brown2'=>array(238,59,59), 'brown3'=>array(205,51,51), 'brown4'=>array(139,35,35), 'salmon1'=>array(255,140,105), 'salmon2'=>array(238,130,98), 'salmon3'=>array(205,112,84), 'salmon4'=>array(139,76,57), 'lightsalmon1'=>array(255,160,122), 'lightsalmon2'=>array(238,149,114), 'lightsalmon3'=>array(205,129,98), 'lightsalmon4'=>array(139,87,66), 'orange1'=>array(255,165,0), 'orange2'=>array(238,154,0), 'orange3'=>array(205,133,0), 'orange4'=>array(139,90,0), 'darkorange1'=>array(255,127,0), 'darkorange2'=>array(238,118,0), 'darkorange3'=>array(205,102,0), 'darkorange4'=>array(139,69,0), 'coral1'=>array(255,114,86), 'coral2'=>array(238,106,80), 'coral3'=>array(205,91,69), 'coral4'=>array(139,62,47), 'tomato1'=>array(255,99,71), 'tomato2'=>array(238,92,66), 'tomato3'=>array(205,79,57), 'tomato4'=>array(139,54,38), 'orangered1'=>array(255,69,0), 'orangered2'=>array(238,64,0), 'orangered3'=>array(205,55,0), 'orangered4'=>array(139,37,0), 'deeppink1'=>array(255,20,147), 'deeppink2'=>array(238,18,137), 'deeppink3'=>array(205,16,118), 'deeppink4'=>array(139,10,80), 'hotpink1'=>array(255,110,180), 'hotpink2'=>array(238,106,167), 'hotpink3'=>array(205,96,144), 'hotpink4'=>array(139,58,98), 'pink1'=>array(255,181,197), 'pink2'=>array(238,169,184), 'pink3'=>array(205,145,158), 'pink4'=>array(139,99,108), 'lightpink1'=>array(255,174,185), 'lightpink2'=>array(238,162,173), 'lightpink3'=>array(205,140,149), 'lightpink4'=>array(139,95,101), 'palevioletred1'=>array(255,130,171), 'palevioletred2'=>array(238,121,159), 'palevioletred3'=>array(205,104,137), 'palevioletred4'=>array(139,71,93), 'maroon1'=>array(255,52,179), 'maroon2'=>array(238,48,167), 'maroon3'=>array(205,41,144), 'maroon4'=>array(139,28,98), 'violetred1'=>array(255,62,150), 'violetred2'=>array(238,58,140), 'violetred3'=>array(205,50,120), 'violetred4'=>array(139,34,82), 'magenta1'=>array(255,0,255), 'magenta2'=>array(238,0,238), 'magenta3'=>array(205,0,205), 'magenta4'=>array(139,0,139), 'mediumred'=>array(140,34,34), 'orchid1'=>array(255,131,250), 'orchid2'=>array(238,122,233), 'orchid3'=>array(205,105,201), 'orchid4'=>array(139,71,137), 'plum1'=>array(255,187,255), 'plum2'=>array(238,174,238), 'plum3'=>array(205,150,205), 'plum4'=>array(139,102,139), 'mediumorchid1'=>array(224,102,255), 'mediumorchid2'=>array(209,95,238), 'mediumorchid3'=>array(180,82,205), 'mediumorchid4'=>array(122,55,139), 'darkorchid1'=>array(191,62,255), 'darkorchid2'=>array(178,58,238), 'darkorchid3'=>array(154,50,205), 'darkorchid4'=>array(104,34,139), 'purple1'=>array(155,48,255), 'purple2'=>array(145,44,238), 'purple3'=>array(125,38,205), 'purple4'=>array(85,26,139), 'mediumpurple1'=>array(171,130,255), 'mediumpurple2'=>array(159,121,238), 'mediumpurple3'=>array(137,104,205), 'mediumpurple4'=>array(93,71,139), 'thistle1'=>array(255,225,255), 'thistle2'=>array(238,210,238), 'thistle3'=>array(205,181,205), 'thistle4'=>array(139,123,139), 'gray1'=>array(10,10,10), 'gray2'=>array(40,40,30), 'gray3'=>array(70,70,70), 'gray4'=>array(100,100,100), 'gray5'=>array(130,130,130), 'gray6'=>array(160,160,160), 'gray7'=>array(190,190,190), 'gray8'=>array(210,210,210), 'gray9'=>array(240,240,240), 'darkgray'=>array(100,100,100), 'darkblue'=>array(0,0,139), 'darkcyan'=>array(0,139,139), 'darkmagenta'=>array(139,0,139), 'darkred'=>array(139,0,0), 'silver'=>array(192, 192, 192), 'eggplant'=>array(144,176,168), 'lightgreen'=>array(144,238,144)); } //---------------- // PUBLIC METHODS // Colors can be specified as either // 1. #xxxxxx HTML style // 2. "colorname" as a named color // 3. array(r,g,b) RGB triple // This function translates this to a native RGB format and returns an // RGB triple. function Color($aColor) { if (is_string($aColor)) { $matches = array(); // this regex will parse a color string and fill the $matches array as such: // 0: the full match if any // 1: a hex string preceded by a hash, can be 3 characters (#fff) or 6 (#ffffff) (4 or 5 also accepted but...) // 2,3,4: r,g,b values in hex if the first character of the string is # // 5: all alpha-numeric characters at the beginning of the string if string does not start with # // 6: alpha value prefixed by @ if supplied // 7: alpha value with @ stripped // 8: adjust value prefixed with : if supplied // 9: adjust value with : stripped $regex = '/(#([0-9a-fA-F]{1,2})([0-9a-fA-F]{1,2})([0-9a-fA-F]{1,2}))?([\w]+)?(@([\d\.,]+))?(:([\d\.,]+))?/'; if(!preg_match($regex, $aColor, $matches)) { JpGraphError::RaiseL(25078,$aColor);//(" Unknown color: $aColor"); } if(empty($matches[5])) { $r = strlen($matches[2]) == 1 ? $matches[2].$matches[2] : $matches[2]; $g = strlen($matches[3]) == 1 ? $matches[3].$matches[3] : $matches[3]; $b = strlen($matches[4]) == 1 ? $matches[4].$matches[4] : $matches[4]; $r = hexdec($r); $g = hexdec($g); $b = hexdec($b); }else { if(!isset($this->rgb_table[$matches[5]]) ) { JpGraphError::RaiseL(25078,$aColor);//(" Unknown color: $aColor"); } $r = $this->rgb_table[$matches[5]][0]; $g = $this->rgb_table[$matches[5]][1]; $b = $this->rgb_table[$matches[5]][2]; } $alpha = isset($matches[7]) ? str_replace(',','.',$matches[7]) : 0; $adj = isset($matches[9]) ? str_replace(',','.',$matches[9]) : 1.0; if( $adj < 0 ) { JpGraphError::RaiseL(25077);//('Adjustment factor for color must be > 0'); } // Scale adj so that an adj=2 always // makes the color 100% white (i.e. 255,255,255. // and adj=1 neutral and adj=0 black. if( $adj == 1) { return array($r,$g,$b,$alpha); } elseif( $adj > 1 ) { $m = ($adj-1.0)*(255-min(255,min($r,min($g,$b)))); return array(min(255,$r+$m), min(255,$g+$m), min(255,$b+$m),$alpha); } elseif( $adj < 1 ) { $m = ($adj-1.0)*max(255,max($r,max($g,$b))); return array(max(0,$r+$m), max(0,$g+$m), max(0,$b+$m),$alpha); } } elseif( is_array($aColor) ) { if(!isset($aColor[3])) $aColor[3] = 0; return $aColor; } else { JpGraphError::RaiseL(25079,$aColor,count($aColor));//(" Unknown color specification: $aColor , size=".count($aColor)); } } // Compare two colors // return true if equal function Equal($aCol1,$aCol2) { $c1 = $this->Color($aCol1); $c2 = $this->Color($aCol2); return $c1[0]==$c2[0] && $c1[1]==$c2[1] && $c1[2]==$c2[2] ; } // Allocate a new color in the current image // Return new color index, -1 if no more colors could be allocated function Allocate($aColor,$aAlpha=0.0) { list ($r, $g, $b, $a) = $this->color($aColor); // If alpha is specified in the color string then this // takes precedence over the second argument if( $a > 0 ) { $aAlpha = $a; } if( $aAlpha < 0 || $aAlpha > 1 ) { JpGraphError::RaiseL(25080);//('Alpha parameter for color must be between 0.0 and 1.0'); } return imagecolorresolvealpha($this->img, $r, $g, $b, round($aAlpha * 127)); } // Try to convert an array with three valid numbers to the corresponding hex array // This is currenly only used in processing the colors for barplots in order to be able // to handle the case where the color might be specified as an array of colros as well. // In that case we must be able to find out if an array of values should be interpretated as // a single color (specifeid as an RGB triple) static function tryHexConversion($aColor) { if( is_array( $aColor ) ) { if( count( $aColor ) == 3 ) { if( is_numeric($aColor[0]) && is_numeric($aColor[1]) && is_numeric($aColor[2]) ) { if( ($aColor[0] >= 0 && $aColor[0] <= 255) && ($aColor[1] >= 0 && $aColor[1] <= 255) && ($aColor[2] >= 0 && $aColor[2] <= 255) ) { return sprintf('#%02x%02x%02x',$aColor[0],$aColor[1],$aColor[2]); } } } } return $aColor; } // Return a RGB tripple corresponding to a position in the normal light spectrum // The argumen values is in the range [0, 1] where a value of 0 correponds to blue and // a value of 1 corresponds to red. Values in betwen is mapped to a linear interpolation // of the constituting colors in the visible color spectra. // The $aDynamicRange specified how much of the dynamic range we shold use // a value of 1.0 give the full dyanmic range and a lower value give more dark // colors. In the extreme of 0.0 then all colors will be black. static function GetSpectrum($aVal,$aDynamicRange=1.0) { if( $aVal < 0 || $aVal > 1.0001 ) { return array(0,0,0); // Invalid case - just return black } $sat = round(255*$aDynamicRange); $a = 0.25; if( $aVal <= 0.25 ) { return array(0, round($sat*$aVal/$a), $sat); } elseif( $aVal <= 0.5 ) { return array(0, $sat, round($sat-$sat*($aVal-0.25)/$a)); } elseif( $aVal <= 0.75 ) { return array(round($sat*($aVal-0.5)/$a), $sat, 0); } else { return array($sat, round($sat-$sat*($aVal-0.75)/$a), 0); } } } // Class ?> loganalyzer-3.6.5/src/classes/logstreamlineparsermisc.class.php0000644000175000017500000000446112225176641024340 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- class LogStreamLineParsermisc extends LogStreamLineParser { // protected $_arrProperties = null; // Constructor public function LogStreamLineParsermisc() { return; // Nothing } /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public function ParseLine($szLine, &$arrArguments) { // Set MSG Property $arrArguments[SYSLOG_MESSAGE] = $szLine; // Set IUT Property $arrArguments[SYSLOG_MESSAGETYPE] = IUT_Unknown; // Return success! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/logstreamlineparsersyslogng.class.php0000644000175000017500000001574112225176641025255 0ustar danieldaniel severity * +--------> facility * * destination messages { file("/var/log/messages" * template("$FACILITY_NUM $LEVEL_NUM $DATE $FULLHOST $MESSAGE\n") * ); * }; * * Referensi macro: * http://www.balabit.com/sites/default/files/documents/syslog-ng-ose-3.3 * -guides/en/syslog-ng-ose-v3.3-guide-admin-en/html/reference_macros.html * * * All directives are explained within this file * * * Copyright (C) 2008-2010 Adiscon GmbH. * * This file is part of LogAnalyzer. * * LogAnalyzer 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 3 of the License, or * (at your option) any later version. * * LogAnalyzer 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 LogAnalyzer. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- class LogStreamLineParsersyslog extends LogStreamLineParser { // protected $_arrProperties = null; // Constructor public function LogStreamLineParsersyslog() { return; // Nothing } /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public function ParseLine($szLine, &$arrArguments) { // Set IUT Property first! $arrArguments[SYSLOG_MESSAGETYPE] = IUT_Syslog; // MULYADI: add code to parse facility and level number (each 1 digit decimal) // Sample (Syslog): 2 2 Mar 10 14:45:44 debandre anacron[3226]: Job `cron.daily' terminated (mailing output) if ( preg_match("/([0-9]) ([0-9]) (...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32})\[(.*?)\]:(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_FACILITY] = $out[1]; $arrArguments[SYSLOG_SEVERITY] = $out[2]; $arrArguments[SYSLOG_DATE] = GetEventTime($out[3] . " " . $out[4]); $arrArguments[SYSLOG_HOST] = $out[5]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[6]; $arrArguments[SYSLOG_PROCESSID] = $out[7]; $arrArguments[SYSLOG_MESSAGE] = $out[8]; } // Sample (Syslog): 2 2 Mar 10 14:45:39 debandre syslogd 1.4.1#18: restart else if ( preg_match("/([0-9]) ([0-9]) (...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32}):(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_FACILITY] = $out[1]; $arrArguments[SYSLOG_SEVERITY] = $out[2]; $arrArguments[SYSLOG_DATE] = GetEventTime($out[3] . " " . $out[4]); $arrArguments[SYSLOG_HOST] = $out[5]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[6]; $arrArguments[SYSLOG_MESSAGE] = $out[7]; } // Sample (Syslog): 2 2 Mar 10 14:45:39 debandre syslogd restart else if ( preg_match("/([0-9]) ([0-9]) (...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32}) (.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_FACILITY] = $out[1]; $arrArguments[SYSLOG_SEVERITY] = $out[2]; $arrArguments[SYSLOG_DATE] = GetEventTime($out[3] . " " . $out[4]); $arrArguments[SYSLOG_HOST] = $out[5]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[6]; $arrArguments[SYSLOG_MESSAGE] = $out[7]; } // Sample (Syslog): 2 2 Mar 7 17:18:35 debandre exiting on signal 15 else if ( preg_match("/([0-9]) ([0-9]) (...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_FACILITY] = $out[1]; $arrArguments[SYSLOG_SEVERITY] = $out[2]; $arrArguments[SYSLOG_DATE] = GetEventTime($out[3] . " " . $out[4]); $arrArguments[SYSLOG_HOST] = $out[5]; $arrArguments[SYSLOG_MESSAGE] = $out[6]; } // Sample (RSyslog): 2008-03-28T11:07:40+01:00 localhost rger: test 1 else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?):(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_HOST] = $out[2]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[3]; $arrArguments[SYSLOG_MESSAGE] = $out[4]; } // Sample (RSyslog): 2008-03-28T11:07:40.591633+01:00 localhost rger: test 1 else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}\.[0-9]{1,6}.[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?):(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_HOST] = $out[2]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[3]; $arrArguments[SYSLOG_MESSAGE] = $out[4]; } // Sample: 2008-03-28T15:17:05.480876+01:00,**NO MATCH** else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}\.[0-9]{1,6}.[0-9]{1,2}:[0-9]{1,2}),(.*?)$/", $szLine, $out ) ) { // Some kind of debug message or something ... $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_MESSAGE] = $out[2]; } else { if ( isset($arrArguments[SYSLOG_MESSAGE]) && strlen($arrArguments[SYSLOG_MESSAGE]) > 0 ) OutputDebugMessage("Unparseable syslog msg - '" . $arrArguments[SYSLOG_MESSAGE] . "'", DEBUG_ERROR); } // If SyslogTag is set, we check for MessageType! if ( isset($arrArguments[SYSLOG_SYSLOGTAG]) ) { if ( strpos($arrArguments[SYSLOG_SYSLOGTAG], "EvntSLog" ) !== false ) $arrArguments[SYSLOG_MESSAGETYPE] = IUT_NT_EventReport; } // Return success! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/logstreamconfigpdo.class.php0000644000175000017500000001162212225176641023265 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- class LogStreamConfigPDO extends LogStreamConfig { public $DBServer = 'localhost'; public $DBPort = 0; public $DBName = ''; public $DBUser = ''; public $DBPassword = ''; public $DBType = DB_MYSQL; // Default = MYSQL! public $DBTableType = 'winsyslog'; // Default = WINSYSLOG DB Layout! public $DBTableName = 'systemevents'; // Default Tabelname from WINSYSLOG public $DBEnableRowCounting = true; // Default RowCounting is enabled! // Runtime configuration variables public $RecordsPerQuery = 100; // This will determine how to limit sql statements public $IDsPerQuery = 5000; // When we query ID's, we read a lot more the datarecords at once! public $SortColumn = SYSLOG_UID; // Default sorting column public function LogStreamFactory($o) { // An instance is created, then include the logstreamdisk class as well! global $gl_root_path; require_once($gl_root_path . 'classes/logstreampdo.class.php'); // return LogStreamDisk instance return new LogStreamPDO($o); } public function GetPDOTriggersSupported() { // TRIGGERS are not supported for all db engines! switch ($this->DBType) { case DB_MYSQL: return true; case DB_MSSQL: return true; case DB_ODBC: return false; case DB_PGSQL: return true; case DB_OCI: return false; case DB_DB2: return false; case DB_FIREBIRD: return false; case DB_INFORMIX: return false; case DB_SQLITE: return false; default: return false; } } public function GetPDODatabaseType() { switch ($this->DBType) { case DB_MYSQL: return "mysql"; case DB_MSSQL: return "odbc"; case DB_ODBC: return "odbc"; case DB_PGSQL: return "pgsql"; case DB_OCI: return "oci"; case DB_DB2: return "ibm"; case DB_FIREBIRD: return "firebird"; case DB_INFORMIX: return "informix"; case DB_SQLITE: return "sqlite"; default: return ""; } } public function CreateConnectDSN() { switch ($this->DBType) { case DB_MYSQL: $myDsn = 'mysql:host=' . $this->DBServer /*. ',' . $this->DBPort*/ . ';dbname=' . $this->DBName; break; case DB_MSSQL: $myDsn = 'odbc:Driver={SQL Server}; Server=' . $this->DBServer . '; Uid=' . $this->DBUser . '; Pwd=' . $this->DBPassword . '; Database=' . $this->DBName . ';'; break; case DB_ODBC: $myDsn = 'odbc:dsn=' . $this->DBServer. ';uid=' . $this->DBUser . ';pwd=' . $this->DBPassword . ';Database=' . $this->DBName; break; case DB_PGSQL: $myDsn = 'pgsql:host=' . $this->DBServer . ' dbname=' . $this->DBName . ' user=' . $this->DBUser . ' password=' . $this->DBPassword; // port=5432 break; case DB_OCI: $myDsn = 'oci:dbname=' . $this->DBServer . '/' . $this->DBName; break; case DB_DB2: $myDsn = 'ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=' . $this->DBName . '; HOSTNAME=' . $this->DBServer . '; PROTOCOL=TCPIP; UID=' . $this->DBUser . '; PWD=' . $this->DBPassword; // PORT=port ; break; case DB_FIREBIRD: $myDsn = 'firebird:User=' . $this->DBUser . ';Password=' . $this->DBPassword . ';Database=' . $this->DBName . ';DataSource=' . $this->DBServer; //;Port=3050'; break; case DB_INFORMIX: $myDsn = 'informix:host=' . $this->DBServer . '; database=' . $this->DBName . '; server=' . $this->DBServer . '; protocol=onsoctcp; EnableScrollableCursors=1'; break; case DB_SQLITE: $myDsn = 'sqlite:' . $this->DBName; // DBName is the full Path to the sqlite db file break; default: $myDsn = ''; } // return my DSN now! return $myDsn; } } ?>loganalyzer-3.6.5/src/classes/logstreamlineparserwinsyslog.class.php0000644000175000017500000000763412225176641025450 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. * * Adiscon LogAnalyzer is also available under a commercial license. * For details, contact info@adiscon.com or visit * http://loganalyzer.adiscon.com/commercial ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- // --- Basic Includes require_once($gl_root_path . 'classes/enums.class.php'); require_once($gl_root_path . 'include/constants_errors.php'); require_once($gl_root_path . 'include/constants_logstream.php'); // --- class LogStreamLineParserwinsyslog extends LogStreamLineParser { // protected $_arrProperties = null; // Constructor public function LogStreamLineParserwinsyslog() { return; // Nothing } /** * ParseLine * * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them. * @return integer Error stat */ public function ParseLine($szLine, &$arrArguments) { global $content; // Set IUT Property first! $arrArguments[SYSLOG_MESSAGETYPE] = IUT_Syslog; // Sample (WinSyslog/EventReporter): 2008-04-02,15:19:06,2008-04-02,15:19:06,127.0.0.1,16,5,EvntSLog: Performance counters for the RSVP (QoS RSVP) service were loaded successfully. if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}.[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}),([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}.[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}),(.*?),([0-9]{1,2}),([0-9]{1,2}),(.*?):(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_HOST] = $out[3]; $arrArguments[SYSLOG_FACILITY] = $out[4]; $arrArguments[SYSLOG_SEVERITY] = $out[5]; $arrArguments[SYSLOG_SYSLOGTAG] = $out[6]; $arrArguments[SYSLOG_MESSAGE] = $out[7]; } else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}.[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}),([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}.[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}),(.*?),([0-9]{1,2}),([0-9]{1,2}),(.*?)$/", $szLine, $out ) ) { // Copy parsed properties! $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]); $arrArguments[SYSLOG_HOST] = $out[3]; $arrArguments[SYSLOG_FACILITY] = $out[4]; $arrArguments[SYSLOG_SEVERITY] = $out[5]; $arrArguments[SYSLOG_MESSAGE] = $out[6]; } else { if ( isset($arrArguments[SYSLOG_MESSAGE]) && strlen($arrArguments[SYSLOG_MESSAGE]) > 0 ) OutputDebugMessage("Unparseable Winsyslog message - '" . $arrArguments[SYSLOG_MESSAGE] . "'", DEBUG_ERROR); } // If SyslogTag is set, we check for MessageType! if ( isset($arrArguments[SYSLOG_SYSLOGTAG]) ) { if ( strpos($arrArguments[SYSLOG_SYSLOGTAG], "EvntSLog" ) !== false ) $arrArguments[SYSLOG_MESSAGETYPE] = IUT_NT_EventReport; } // Return success! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/logstreamconfig.class.php0000644000175000017500000001247712225176641022573 0ustar danieldaniel. * * A copy of the GPL can be found in the file "COPYING" in this * distribution. ********************************************************************* */ // --- Avoid directly accessing this file! if ( !defined('IN_PHPLOGCON') ) { die('Hacking attempt'); exit; } // --- abstract class LogStreamConfig { // Public needed properties public $_pageCount = 50; // Paging Count number! // protected properties protected $_logStreamConfigObj = null; protected $_logStreamId = -1; protected $_logStreamName = ''; protected $_defaultFacility = ''; protected $_defaultSeverity = ''; // helpers properties for message parser list! protected $_msgParserList = null; // Contains a string list of configure msg parsers protected $_msgParserObjList = null; // Contains an object reference list to the msg parsers protected $_MsgNormalize = 0; // If set to one, the msg will be reconstructed if successfully parsed before public $_defaultfilter = ""; // Default filter for this source, will be added to all further filters. public $_SkipUnparseable = 0; // If set to one, all unparseable message will be ignored! This of course only applies if a msg parser is used // Constructor prototype public abstract function LogStreamFactory($o); /* * Initialize Msg Parsers! */ public function InitMsgParsers() { // Init parsers if available and not initialized already! if ( $this->_msgParserList != null && $this->_msgParserObjList == null ) { // Loop through parsers foreach( $this->_msgParserList as $szParser ) { // Set Classname $szClassName = "MsgParser_" . $szParser; // Create OBjectRef! $NewParser = new $szClassName(); // Create new instance $NewParser->_MsgNormalize = $this->_MsgNormalize; // Copy property! $this->_msgParserObjList[] = $NewParser; // Append NewParser to Parser array } } } /* * Helper function to init Parserlist */ public function SetSkipUnparseable( $nNewVal ) { if ( $nNewVal == 0 ) $this->_SkipUnparseable = 0; else $this->_SkipUnparseable = 1; } /* * Helper function to init Parserlist */ public function SetMsgNormalize( $nNewVal ) { if ( $nNewVal == 0 ) $this->_MsgNormalize = 0; else $this->_MsgNormalize = 1; } /* * Helper function to set defautl filters */ public function SetDefaultfilter( $szNewVal ) { $this->_defaultfilter = $szNewVal; } /* * Helper function to init Parserlist */ public function SetMsgParserList( $szParsers ) { global $gl_root_path; // Check if we have at least something to check if ( $szParsers == null || strlen($szParsers) <= 0 ) return; // Set list of Parsers! if ( strpos($szParsers, ",") ) $aParsers = explode( ",", $szParsers ); else $aParsers[0] = $szParsers; // Loop through parsers foreach( $aParsers as $szParser ) { // Remove whitespaces $szParser = trim($szParser); // Check if parser file include exists $szIncludeFile = $gl_root_path . 'classes/msgparsers/msgparser.' . $szParser . '.class.php'; if ( file_exists($szIncludeFile) ) { // Try to include if ( @include_once($szIncludeFile) ) $this->_msgParserList[] = $szParser; else OutputDebugMessage("Error, MsgParser '" . $szParser . "' could not be included. ", DEBUG_ERROR); } } // print_r ( $this->_msgParserList ); } public function ProcessMsgParsers($szMsg, &$arrArguments) { // Abort msgparsers if we have less then 5 seconds of processing time! global $content, $gl_starttime; $scriptruntime = intval(microtime_float() - $gl_starttime); if ( $scriptruntime > ($content['MaxExecutionTime']-5) ) return ERROR_MSG_SCANABORTED; // Process if set! if ( $this->_msgParserObjList != null ) { foreach( $this->_msgParserObjList as $myMsgParser ) { // Perform Parsing, and return if was successfull or the message needs to be skipped! // Otherwise the next Parser will be called. $ret = $myMsgParser->ParseMsg($szMsg, $arrArguments); if ( $ret == SUCCESS || $ret == ERROR_MSG_SKIPMESSAGE ) return $ret; // Extra check, if user wants to, we SKIP the message! if ( $this->_SkipUnparseable == 1 && $ret == ERROR_MSG_NOMATCH ) return ERROR_MSG_SKIPMESSAGE; } } // reached this means all work is done! return SUCCESS; } } ?>loganalyzer-3.6.5/src/classes/html2fpdf/0000755000175000017500000000000012225176641017446 5ustar danieldanielloganalyzer-3.6.5/src/classes/html2fpdf/gif.php0000644000175000017500000006436212225176641020737 0ustar danieldaniel = gif_loadFile(filename, [index]) // = gif_getSize( or filename, &width, &height) // = gif_outputAsPng(, filename, [bgColor]) // = gif_outputAsBmp(, filename, [bgcolor]) // = gif_outputAsJpeg(, filename, [bgcolor]) - Requires cjpeg /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_loadFile($lpszFileName, $iIndex = 0) { $gif = new CGIF(); if(!$gif->loadFile($lpszFileName, $iIndex)) { return false; } return $gif; } /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_outputAsBmp($gif, $lpszFileName, $bgColor = -1) { if(!isSet($gif) || (@get_class($gif) <> "cgif") || !$gif->loaded() || ($lpszFileName == "")) { return false; } $fd = $gif->getBmp($bgColor); if(strlen($fd) <= 0) { return false; } if(!($fh = @fOpen($lpszFileName, "wb"))) { return false; } @fWrite($fh, $fd, strlen($fd)); @fFlush($fh); @fClose($fh); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_outputAsPng($gif, $lpszFileName, $bgColor = -1) { if(!isSet($gif) || (@get_class($gif) <> "cgif") || !$gif->loaded() || ($lpszFileName == "")) { return false; } $fd = $gif->getPng($bgColor); if(strlen($fd) <= 0) { return false; } if(!($fh = @fOpen($lpszFileName, "wb"))) { return false; } @fWrite($fh, $fd, strlen($fd)); @fFlush($fh); @fClose($fh); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_outputAsJpeg($gif, $lpszFileName, $bgColor = -1) { if(gif_outputAsBmp($gif, "$lpszFileName.bmp", $gbColor)) { exec("cjpeg $lpszFileName.bmp >$lpszFileName 2>/dev/null"); @unLink("$lpszFileName.bmp"); if(@file_exists($lpszFileName)) { if(@fileSize($lpszFileName) > 0) { return true; } @unLink($lpszFileName); } } return false; } /////////////////////////////////////////////////////////////////////////////////////////////////// function gif_getSize($gif, &$width, &$height) { if(isSet($gif) && (@get_class($gif) == "cgif") && $gif->loaded()) { $width = $gif->width(); $height = $gif->height(); } else if(@file_exists($gif)) { $myGIF = new CGIF(); if(!$myGIF->getSize($gif, $width, $height)) { return false; } } else { return false; } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFLZW { var $MAX_LZW_BITS; var $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode; var $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIFLZW() { $this->MAX_LZW_BITS = 12; unSet($this->Next); unSet($this->Vals); unSet($this->Stack); unSet($this->Buf); $this->Next = range(0, (1 << $this->MAX_LZW_BITS) - 1); $this->Vals = range(0, (1 << $this->MAX_LZW_BITS) - 1); $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1); $this->Buf = range(0, 279); } /////////////////////////////////////////////////////////////////////////// function deCompress($data, &$datLen) { $stLen = strlen($data); $datLen = 0; $ret = ""; // INITIALIZATION $this->LZWCommand($data, true); while(($iIndex = $this->LZWCommand($data, false)) >= 0) { $ret .= chr($iIndex); } $datLen = $stLen - strlen($data); if($iIndex != -2) { return false; } return $ret; } /////////////////////////////////////////////////////////////////////////// function LZWCommand(&$data, $bInit) { if($bInit) { $this->SetCodeSize = ord($data{0}); $data = substr($data, 1); $this->CodeSize = $this->SetCodeSize + 1; $this->ClearCode = 1 << $this->SetCodeSize; $this->EndCode = $this->ClearCode + 1; $this->MaxCode = $this->ClearCode + 2; $this->MaxCodeSize = $this->ClearCode << 1; $this->GetCode($data, $bInit); $this->Fresh = 1; for($i = 0; $i < $this->ClearCode; $i++) { $this->Next[$i] = 0; $this->Vals[$i] = $i; } for(; $i < (1 << $this->MAX_LZW_BITS); $i++) { $this->Next[$i] = 0; $this->Vals[$i] = 0; } $this->sp = 0; return 1; } if($this->Fresh) { $this->Fresh = 0; do { $this->FirstCode = $this->GetCode($data, $bInit); $this->OldCode = $this->FirstCode; } while($this->FirstCode == $this->ClearCode); return $this->FirstCode; } if($this->sp > 0) { $this->sp--; return $this->Stack[$this->sp]; } while(($Code = $this->GetCode($data, $bInit)) >= 0) { if($Code == $this->ClearCode) { for($i = 0; $i < $this->ClearCode; $i++) { $this->Next[$i] = 0; $this->Vals[$i] = $i; } for(; $i < (1 << $this->MAX_LZW_BITS); $i++) { $this->Next[$i] = 0; $this->Vals[$i] = 0; } $this->CodeSize = $this->SetCodeSize + 1; $this->MaxCodeSize = $this->ClearCode << 1; $this->MaxCode = $this->ClearCode + 2; $this->sp = 0; $this->FirstCode = $this->GetCode($data, $bInit); $this->OldCode = $this->FirstCode; return $this->FirstCode; } if($Code == $this->EndCode) { return -2; } $InCode = $Code; if($Code >= $this->MaxCode) { $this->Stack[$this->sp] = $this->FirstCode; $this->sp++; $Code = $this->OldCode; } while($Code >= $this->ClearCode) { $this->Stack[$this->sp] = $this->Vals[$Code]; $this->sp++; if($Code == $this->Next[$Code]) // Circular table entry, big GIF Error! return -1; $Code = $this->Next[$Code]; } $this->FirstCode = $this->Vals[$Code]; $this->Stack[$this->sp] = $this->FirstCode; $this->sp++; if(($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) { $this->Next[$Code] = $this->OldCode; $this->Vals[$Code] = $this->FirstCode; $this->MaxCode++; if(($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) { $this->MaxCodeSize *= 2; $this->CodeSize++; } } $this->OldCode = $InCode; if($this->sp > 0) { $this->sp--; return $this->Stack[$this->sp]; } } return $Code; } /////////////////////////////////////////////////////////////////////////// function GetCode(&$data, $bInit) { if($bInit) { $this->CurBit = 0; $this->LastBit = 0; $this->Done = 0; $this->LastByte = 2; return 1; } if(($this->CurBit + $this->CodeSize) >= $this->LastBit) { if($this->Done) { if($this->CurBit >= $this->LastBit) { // Ran off the end of my bits return 0; } return -1; } $this->Buf[0] = $this->Buf[$this->LastByte - 2]; $this->Buf[1] = $this->Buf[$this->LastByte - 1]; $Count = ord($data{0}); $data = substr($data, 1); if($Count) { for($i = 0; $i < $Count; $i++) { $this->Buf[2 + $i] = ord($data{$i}); } $data = substr($data, $Count); } else { $this->Done = 1; } $this->LastByte = 2 + $Count; $this->CurBit = ($this->CurBit - $this->LastBit) + 16; $this->LastBit = (2 + $Count) << 3; } $iRet = 0; for($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) { $iRet |= (($this->Buf[intval($i / 8)] & (1 << ($i % 8))) != 0) << $j; } $this->CurBit += $this->CodeSize; return $iRet; } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFCOLORTABLE { var $m_nColors; var $m_arColors; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIFCOLORTABLE() { unSet($this->m_nColors); unSet($this->m_arColors); } /////////////////////////////////////////////////////////////////////////// function load($lpData, $num) { $this->m_nColors = 0; $this->m_arColors = array(); for($i = 0; $i < $num; $i++) { $rgb = substr($lpData, $i * 3, 3); if(strlen($rgb) < 3) { return false; } $this->m_arColors[] = (ord($rgb{2}) << 16) + (ord($rgb{1}) << 8) + ord($rgb{0}); $this->m_nColors++; } return true; } /////////////////////////////////////////////////////////////////////////// function toString() { $ret = ""; for($i = 0; $i < $this->m_nColors; $i++) { $ret .= chr(($this->m_arColors[$i] & 0x000000FF)) . // R chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G chr(($this->m_arColors[$i] & 0x00FF0000) >> 16); // B } return $ret; } /////////////////////////////////////////////////////////////////////////// function toRGBQuad() { $ret = ""; for($i = 0; $i < $this->m_nColors; $i++) { $ret .= chr(($this->m_arColors[$i] & 0x00FF0000) >> 16) . // B chr(($this->m_arColors[$i] & 0x0000FF00) >> 8) . // G chr(($this->m_arColors[$i] & 0x000000FF)) . // R "\x00"; } return $ret; } /////////////////////////////////////////////////////////////////////////// function colorIndex($rgb) { $rgb = intval($rgb) & 0xFFFFFF; $r1 = ($rgb & 0x0000FF); $g1 = ($rgb & 0x00FF00) >> 8; $b1 = ($rgb & 0xFF0000) >> 16; $idx = -1; for($i = 0; $i < $this->m_nColors; $i++) { $r2 = ($this->m_arColors[$i] & 0x000000FF); $g2 = ($this->m_arColors[$i] & 0x0000FF00) >> 8; $b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16; $d = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1); if(($idx == -1) || ($d < $dif)) { $idx = $i; $dif = $d; } } return $idx; } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFFILEHEADER { var $m_lpVer; var $m_nWidth; var $m_nHeight; var $m_bGlobalClr; var $m_nColorRes; var $m_bSorted; var $m_nTableSize; var $m_nBgColor; var $m_nPixelRatio; var $m_colorTable; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIFFILEHEADER() { unSet($this->m_lpVer); unSet($this->m_nWidth); unSet($this->m_nHeight); unSet($this->m_bGlobalClr); unSet($this->m_nColorRes); unSet($this->m_bSorted); unSet($this->m_nTableSize); unSet($this->m_nBgColor); unSet($this->m_nPixelRatio); unSet($this->m_colorTable); } /////////////////////////////////////////////////////////////////////////// function load($lpData, &$hdrLen) { $hdrLen = 0; $this->m_lpVer = substr($lpData, 0, 6); if(($this->m_lpVer <> "GIF87a") && ($this->m_lpVer <> "GIF89a")) { return false; } $this->m_nWidth = $this->w2i(substr($lpData, 6, 2)); $this->m_nHeight = $this->w2i(substr($lpData, 8, 2)); if(!$this->m_nWidth || !$this->m_nHeight) { return false; } $b = ord(substr($lpData, 10, 1)); $this->m_bGlobalClr = ($b & 0x80) ? true : false; $this->m_nColorRes = ($b & 0x70) >> 4; $this->m_bSorted = ($b & 0x08) ? true : false; $this->m_nTableSize = 2 << ($b & 0x07); $this->m_nBgColor = ord(substr($lpData, 11, 1)); $this->m_nPixelRatio = ord(substr($lpData, 12, 1)); $hdrLen = 13; if($this->m_bGlobalClr) { $this->m_colorTable = new CGIFCOLORTABLE(); if(!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) { return false; } $hdrLen += 3 * $this->m_nTableSize; } return true; } /////////////////////////////////////////////////////////////////////////// function w2i($str) { return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8); } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFIMAGEHEADER { var $m_nLeft; var $m_nTop; var $m_nWidth; var $m_nHeight; var $m_bLocalClr; var $m_bInterlace; var $m_bSorted; var $m_nTableSize; var $m_colorTable; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIFIMAGEHEADER() { unSet($this->m_nLeft); unSet($this->m_nTop); unSet($this->m_nWidth); unSet($this->m_nHeight); unSet($this->m_bLocalClr); unSet($this->m_bInterlace); unSet($this->m_bSorted); unSet($this->m_nTableSize); unSet($this->m_colorTable); } /////////////////////////////////////////////////////////////////////////// function load($lpData, &$hdrLen) { $hdrLen = 0; $this->m_nLeft = $this->w2i(substr($lpData, 0, 2)); $this->m_nTop = $this->w2i(substr($lpData, 2, 2)); $this->m_nWidth = $this->w2i(substr($lpData, 4, 2)); $this->m_nHeight = $this->w2i(substr($lpData, 6, 2)); if(!$this->m_nWidth || !$this->m_nHeight) { return false; } $b = ord($lpData{8}); $this->m_bLocalClr = ($b & 0x80) ? true : false; $this->m_bInterlace = ($b & 0x40) ? true : false; $this->m_bSorted = ($b & 0x20) ? true : false; $this->m_nTableSize = 2 << ($b & 0x07); $hdrLen = 9; if($this->m_bLocalClr) { $this->m_colorTable = new CGIFCOLORTABLE(); if(!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) { return false; } $hdrLen += 3 * $this->m_nTableSize; } return true; } /////////////////////////////////////////////////////////////////////////// function w2i($str) { return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8); } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIFIMAGE { var $m_disp; var $m_bUser; var $m_bTrans; var $m_nDelay; var $m_nTrans; var $m_lpComm; var $m_gih; var $m_data; var $m_lzw; /////////////////////////////////////////////////////////////////////////// function CGIFIMAGE() { unSet($this->m_disp); unSet($this->m_bUser); unSet($this->m_bTrans); unSet($this->m_nDelay); unSet($this->m_nTrans); unSet($this->m_lpComm); unSet($this->m_data); $this->m_gih = new CGIFIMAGEHEADER(); $this->m_lzw = new CGIFLZW(); } /////////////////////////////////////////////////////////////////////////// function load($data, &$datLen) { $datLen = 0; while(true) { $b = ord($data{0}); $data = substr($data, 1); $datLen++; switch($b) { case 0x21: // Extension if(!$this->skipExt($data, $len = 0)) { return false; } $datLen += $len; break; case 0x2C: // Image // LOAD HEADER & COLOR TABLE if(!$this->m_gih->load($data, $len = 0)) { return false; } $data = substr($data, $len); $datLen += $len; // ALLOC BUFFER if(!($this->m_data = $this->m_lzw->deCompress($data, $len = 0))) { return false; } $data = substr($data, $len); $datLen += $len; if($this->m_gih->m_bInterlace) { $this->deInterlace(); } return true; case 0x3B: // EOF default: return false; } } return false; } /////////////////////////////////////////////////////////////////////////// function skipExt(&$data, &$extLen) { $extLen = 0; $b = ord($data{0}); $data = substr($data, 1); $extLen++; switch($b) { case 0xF9: // Graphic Control $b = ord($data{1}); $this->m_disp = ($b & 0x1C) >> 2; $this->m_bUser = ($b & 0x02) ? true : false; $this->m_bTrans = ($b & 0x01) ? true : false; $this->m_nDelay = $this->w2i(substr($data, 2, 2)); $this->m_nTrans = ord($data{4}); break; case 0xFE: // Comment $this->m_lpComm = substr($data, 1, ord($data{0})); break; case 0x01: // Plain text break; case 0xFF: // Application break; } // SKIP DEFAULT AS DEFS MAY CHANGE $b = ord($data{0}); $data = substr($data, 1); $extLen++; while($b > 0) { $data = substr($data, $b); $extLen += $b; $b = ord($data{0}); $data = substr($data, 1); $extLen++; } return true; } /////////////////////////////////////////////////////////////////////////// function w2i($str) { return ord(substr($str, 0, 1)) + (ord(substr($str, 1, 1)) << 8); } /////////////////////////////////////////////////////////////////////////// function deInterlace() { $data = $this->m_data; for($i = 0; $i < 4; $i++) { switch($i) { case 0: $s = 8; $y = 0; break; case 1: $s = 8; $y = 4; break; case 2: $s = 4; $y = 2; break; case 3: $s = 2; $y = 1; break; } for(; $y < $this->m_gih->m_nHeight; $y += $s) { $lne = substr($this->m_data, 0, $this->m_gih->m_nWidth); $this->m_data = substr($this->m_data, $this->m_gih->m_nWidth); $data = substr($data, 0, $y * $this->m_gih->m_nWidth) . $lne . substr($data, ($y + 1) * $this->m_gih->m_nWidth); } } $this->m_data = $data; } } /////////////////////////////////////////////////////////////////////////////////////////////////// class CGIF { var $m_gfh; var $m_lpData; var $m_img; var $m_bLoaded; /////////////////////////////////////////////////////////////////////////// // CONSTRUCTOR function CGIF() { $this->m_gfh = new CGIFFILEHEADER(); $this->m_img = new CGIFIMAGE(); $this->m_lpData = ""; $this->m_bLoaded = false; } /////////////////////////////////////////////////////////////////////////// function loadFile($lpszFileName, $iIndex) { if($iIndex < 0) { return false; } // READ FILE if(!($fh = @fOpen($lpszFileName, "rb"))) { return false; } //EDITEI - in order to read remote files (HTTP(s) and FTP protocols) if ( strpos($lpszFileName,"http") !== false or strpos($lpszFileName,"ftp") !== false ) { $contents = ''; while (!feof($fh)) $contents .= @fread($fh, 8192); } else { $contents = @fread($fh,@filesize($lpszFileName) ); } $this->m_lpData = $contents; // $this->m_lpData = @fRead($fh, @fileSize($lpszFileName)); fClose($fh); // GET FILE HEADER if(!$this->m_gfh->load($this->m_lpData, $len = 0)) { return false; } $this->m_lpData = substr($this->m_lpData, $len); do { if(!$this->m_img->load($this->m_lpData, $imgLen = 0)) { return false; } $this->m_lpData = substr($this->m_lpData, $imgLen); } while($iIndex-- > 0); $this->m_bLoaded = true; return true; } /////////////////////////////////////////////////////////////////////////// function getSize($lpszFileName, &$width, &$height) { if(!($fh = @fOpen($lpszFileName, "rb"))) { return false; } $data = @fRead($fh, @fileSize($lpszFileName)); @fClose($fh); $gfh = new CGIFFILEHEADER(); if(!$gfh->load($data, $len = 0)) { return false; } $width = $gfh->m_nWidth; $height = $gfh->m_nHeight; return true; } /////////////////////////////////////////////////////////////////////////// function getBmp($bgColor) { $out = ""; if(!$this->m_bLoaded) { return false; } // PREPARE COLOR TABLE (RGBQUADs) if($this->m_img->m_gih->m_bLocalClr) { $nColors = $this->m_img->m_gih->m_nTableSize; $rgbq = $this->m_img->m_gih->m_colorTable->toRGBQuad(); if($bgColor != -1) { $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor); } } else if($this->m_gfh->m_bGlobalClr) { $nColors = $this->m_gfh->m_nTableSize; $rgbq = $this->m_gfh->m_colorTable->toRGBQuad(); if($bgColor != -1) { $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor); } } else { $nColors = 0; $bgColor = -1; } // PREPARE BITMAP BITS $data = $this->m_img->m_data; $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth; $bmp = ""; $nPad = ($this->m_gfh->m_nWidth % 4) ? 4 - ($this->m_gfh->m_nWidth % 4) : 0; for($y = 0; $y < $this->m_gfh->m_nHeight; $y++) { for($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) { if( ($x >= $this->m_img->m_gih->m_nLeft) && ($y >= $this->m_img->m_gih->m_nTop) && ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) && ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) { // PART OF IMAGE if($this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) { // TRANSPARENT -> BACKGROUND if($bgColor == -1) { $bmp .= chr($this->m_gfh->m_nBgColor); } else { $bmp .= chr($bgColor); } } else { $bmp .= $data{$nPxl}; } } else { // BACKGROUND if($bgColor == -1) { $bmp .= chr($this->m_gfh->m_nBgColor); } else { $bmp .= chr($bgColor); } } } $nPxl -= $this->m_gfh->m_nWidth << 1; // ADD PADDING for($x = 0; $x < $nPad; $x++) { $bmp .= "\x00"; } } // BITMAPFILEHEADER $out .= "BM"; $out .= $this->dword(14 + 40 + ($nColors << 2) + strlen($bmp)); $out .= "\x00\x00"; $out .= "\x00\x00"; $out .= $this->dword(14 + 40 + ($nColors << 2)); // BITMAPINFOHEADER $out .= $this->dword(40); $out .= $this->dword($this->m_gfh->m_nWidth); $out .= $this->dword($this->m_gfh->m_nHeight); $out .= "\x01\x00"; $out .= "\x08\x00"; $out .= "\x00\x00\x00\x00"; $out .= "\x00\x00\x00\x00"; $out .= "\x12\x0B\x00\x00"; $out .= "\x12\x0B\x00\x00"; $out .= $this->dword($nColors % 256); $out .= "\x00\x00\x00\x00"; // COLOR TABLE if($nColors > 0) { $out .= $rgbq; } // DATA $out .= $bmp; return $out; } /////////////////////////////////////////////////////////////////////////// function getPng($bgColor) { $out = ""; if(!$this->m_bLoaded) { return false; } // PREPARE COLOR TABLE (RGBQUADs) if($this->m_img->m_gih->m_bLocalClr) { $nColors = $this->m_img->m_gih->m_nTableSize; $pal = $this->m_img->m_gih->m_colorTable->toString(); if($bgColor != -1) { $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor); } } else if($this->m_gfh->m_bGlobalClr) { $nColors = $this->m_gfh->m_nTableSize; $pal = $this->m_gfh->m_colorTable->toString(); if($bgColor != -1) { $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor); } } else { $nColors = 0; $bgColor = -1; } // PREPARE BITMAP BITS $data = $this->m_img->m_data; $nPxl = 0; $bmp = ""; for($y = 0; $y < $this->m_gfh->m_nHeight; $y++) { $bmp .= "\x00"; for($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) { if( ($x >= $this->m_img->m_gih->m_nLeft) && ($y >= $this->m_img->m_gih->m_nTop) && ($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) && ($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) { // PART OF IMAGE $bmp .= $data{$nPxl}; } else { // BACKGROUND if($bgColor == -1) { $bmp .= chr($this->m_gfh->m_nBgColor); } else { $bmp .= chr($bgColor); } } } } $bmp = gzcompress($bmp, 9); /////////////////////////////////////////////////////////////////////// // SIGNATURE $out .= "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"; /////////////////////////////////////////////////////////////////////// // HEADER $out .= "\x00\x00\x00\x0D"; $tmp = "IHDR"; $tmp .= $this->ndword($this->m_gfh->m_nWidth); $tmp .= $this->ndword($this->m_gfh->m_nHeight); $tmp .= "\x08\x03\x00\x00\x00"; $out .= $tmp; $out .= $this->ndword(crc32($tmp)); /////////////////////////////////////////////////////////////////////// // PALETTE if($nColors > 0) { $out .= $this->ndword($nColors * 3); $tmp = "PLTE"; $tmp .= $pal; $out .= $tmp; $out .= $this->ndword(crc32($tmp)); } /////////////////////////////////////////////////////////////////////// // TRANSPARENCY if($this->m_img->m_bTrans && ($nColors > 0)) { $out .= $this->ndword($nColors); $tmp = "tRNS"; for($i = 0; $i < $nColors; $i++) { $tmp .= ($i == $this->m_img->m_nTrans) ? "\x00" : "\xFF"; } $out .= $tmp; $out .= $this->ndword(crc32($tmp)); } /////////////////////////////////////////////////////////////////////// // DATA BITS $out .= $this->ndword(strlen($bmp)); $tmp = "IDAT"; $tmp .= $bmp; $out .= $tmp; $out .= $this->ndword(crc32($tmp)); /////////////////////////////////////////////////////////////////////// // END OF FILE $out .= "\x00\x00\x00\x00IEND\xAE\x42\x60\x82"; return $out; } /////////////////////////////////////////////////////////////////////////// function dword($val) { $val = intval($val); return chr($val & 0xFF).chr(($val & 0xFF00) >> 8).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF000000) >> 24); } /////////////////////////////////////////////////////////////////////////// function ndword($val) { $val = intval($val); return chr(($val & 0xFF000000) >> 24).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF00) >> 8).chr($val & 0xFF); } /////////////////////////////////////////////////////////////////////////// function width() { return $this->m_gfh->m_nWidth; } /////////////////////////////////////////////////////////////////////////// function height() { return $this->m_gfh->m_nHeight; } /////////////////////////////////////////////////////////////////////////// function comment() { return $this->m_img->m_lpComm; } /////////////////////////////////////////////////////////////////////////// function loaded() { return $this->m_bLoaded; } } /////////////////////////////////////////////////////////////////////////////////////////////////// ?> loganalyzer-3.6.5/src/classes/html2fpdf/license.txt0000644000175000017500000000275112225176641021636 0ustar danieldaniel More info can be found on the site: [http://html2fpdf.sourceforge.net] ############################################################################## ############## DO NOT MODIFY THE CONTENTS OF THIS BOX ######################## ############################################################################## ## ## ## HTML2FPDF is a php script to read a HTML text and generate a PDF file. ## ## Copyright (C) 2004-2005 Renato Coelho ## ## This script may be distributed as long as the following files are kept ## ## together: ## ## ## ## fpdf.php, html2fpdf.php, gif.php,htmltoolkit.php,license.txt,credits.txt ## ## ## ############################################################################## 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; 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. [http://www.opensource.org/licenses/lgpl-license.php]loganalyzer-3.6.5/src/classes/html2fpdf/html2fpdf.php0000644000175000017500000034567012225176641022064 0ustar danieldanielcurrentfont - mine . $this->CurrentFont - fpdf's TODO (in the future...): - Make font-family, font-size, lineheight customizable - Increase number of HTML/CSS tags/properties, Image/Font Types, recognized/supported - allow BMP support? (tried with http://phpthumb.sourceforge.net/ but failed) - Improve CSS support - support image side-by-side or one-below-another or both? - Improve code clarity even more (modularize and get better var names like on textbuffer array's indexes for example) ////////////////////////////////////////////////////////////////////////////// //////////////DO NOT MODIFY THE CONTENTS OF THIS BOX////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // // HTML2FPDF is a php script to read a HTML text and generate a PDF file. // // Copyright (C) 2004-2005 Renato Coelho // // This script may be distributed as long as the following files are kept // // together: // // // // fpdf.php, html2fpdf.php, gif.php,htmltoolkit.php,license.txt,credits.txt // // // ////////////////////////////////////////////////////////////////////////////// Misc. Observations: - CSS + align = bug! (?) OBS1: para textos de mais de 1 página, talvez tenha que juntar varios $texto_artigo antes de mandar gerar o PDF, para que o PDF gerado seja completo. OBS2: there are 2 types of spaces 32 and 160 (ascii values) OBS3: //! is a special comment to be used with source2doc.php, a script I created in order to generate the doc on the site html2fpdf.sf.net OBS4: var $LineWidth; // line width in user unit - use this to make css thin/medium/thick work OBS5: Images and Textareas: when they are inserted you can only type below them (==display:block) OBS6: Optimized to 'A4' paper (default font: Arial , normal , size 11 ) OBS7: Regexp + Perl ([preg]accepts non-greedy quantifiers while PHP[ereg] does not) Perl: '/regexp/x' where x == option ( x = i:ignore case , x = s: DOT gets \n as well) ========================END OF INITIAL COMMENTS================================= */ define('HTML2FPDF_VERSION','3.0(beta)'); if (!defined('RELATIVE_PATH')) define('RELATIVE_PATH',''); if (!defined('FPDF_FONTPATH')) define('FPDF_FONTPATH','font/'); require_once(RELATIVE_PATH.'fpdf.php'); require_once(RELATIVE_PATH.'htmltoolkit.php'); class HTML2FPDF extends FPDF { //internal attributes var $HREF; //! string var $pgwidth; //! float var $fontlist; //! array var $issetfont; //! bool var $issetcolor; //! bool var $titulo; //! string var $oldx; //! float var $oldy; //! float var $B; //! int var $U; //! int var $I; //! int var $tablestart; //! bool var $tdbegin; //! bool var $table; //! array var $cell; //! array var $col; //! int var $row; //! int var $divbegin; //! bool var $divalign; //! char var $divwidth; //! float var $divheight; //! float var $divbgcolor; //! bool var $divcolor; //! bool var $divborder; //! int var $divrevert; //! bool var $listlvl; //! int var $listnum; //! int var $listtype; //! string //array(lvl,# of occurrences) var $listoccur; //! array //array(lvl,occurrence,type,maxnum) var $listlist; //! array //array(lvl,num,content,type) var $listitem; //! array var $buffer_on; //! bool var $pbegin; //! bool var $pjustfinished; //! bool var $blockjustfinished; //! bool var $SUP; //! bool var $SUB; //! bool var $toupper; //! bool var $tolower; //! bool var $dash_on; //! bool var $dotted_on; //! bool var $strike; //! bool var $CSS; //! array var $cssbegin; //! bool var $backupcss; //! array var $textbuffer; //! array var $currentstyle; //! string var $currentfont; //! string var $colorarray; //! array var $bgcolorarray; //! array var $internallink; //! array var $enabledtags; //! string var $lineheight; //! int var $basepath; //! string // array('COLOR','WIDTH','OLDWIDTH') var $outlineparam; //! array var $outline_on; //! bool var $specialcontent; //! string var $selectoption; //! array //options attributes var $usecss; //! bool var $usepre; //! bool var $usetableheader; //! bool var $shownoimg; //! bool function HTML2FPDF($orientation='P',$unit='mm',$format='A4') { //! @desc Constructor //! @return An object (a class instance) //Call parent constructor $this->FPDF($orientation,$unit,$format); //To make the function Footer() work properly $this->AliasNbPages(); //Enable all tags as default $this->DisableTags(); //Set default display preferences $this->DisplayPreferences(''); //Initialization of the attributes $this->SetFont('Arial','',10); // Changeable?(not yet...) $this->lineheight = 4; // Related to FontSizePt == 11 $this->pgwidth = $this->fw - $this->lMargin - $this->rMargin ; $this->SetFillColor(255); $this->HREF=''; $this->titulo=''; $this->oldx=-1; $this->oldy=-1; $this->B=0; $this->U=0; $this->I=0; $this->listlvl=0; $this->listnum=0; $this->listtype=''; $this->listoccur=array(); $this->listlist=array(); $this->listitem=array(); $this->tablestart=false; $this->tdbegin=false; $this->table=array(); $this->cell=array(); $this->col=-1; $this->row=-1; $this->divbegin=false; $this->divalign="L"; $this->divwidth=0; $this->divheight=0; $this->divbgcolor=false; $this->divcolor=false; $this->divborder=0; $this->divrevert=false; $this->fontlist=array("arial","times","courier","helvetica","symbol","monospace","serif","sans"); $this->issetfont=false; $this->issetcolor=false; $this->pbegin=false; $this->pjustfinished=false; $this->blockjustfinished = true; //in order to eliminate exceeding left-side spaces $this->toupper=false; $this->tolower=false; $this->dash_on=false; $this->dotted_on=false; $this->SUP=false; $this->SUB=false; $this->buffer_on=false; $this->strike=false; $this->currentfont=''; $this->currentstyle=''; $this->colorarray=array(); $this->bgcolorarray=array(); $this->cssbegin=false; $this->textbuffer=array(); $this->CSS=array(); $this->backupcss=array(); $this->internallink=array(); $this->basepath = ""; $this->outlineparam = array(); $this->outline_on = false; $this->specialcontent = ''; $this->selectoption = array(); $this->shownoimg=false; $this->usetableheader=false; $this->usecss=true; $this->usepre=true; } function setBasePath($str) { //! @desc Inform the script where the html file is (full path - e.g. http://www.google.com/dir1/dir2/dir3/file.html ) in order to adjust HREF and SRC links. No-Parameter: The directory where this script is. //! @return void $this->basepath = dirname($str) . "/"; $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows } function ShowNOIMG_GIF($opt=true) { //! @desc Enable/Disable Displaying the no_img.gif when an image is not found. No-Parameter: Enable //! @return void $this->shownoimg=$opt; } function UseCSS($opt=true) { //! @desc Enable/Disable CSS recognition. No-Parameter: Enable //! @return void $this->usecss=$opt; } function UseTableHeader($opt=true) { //! @desc Enable/Disable Table Header to appear every new page. No-Parameter: Enable //! @return void $this->usetableheader=$opt; } function UsePRE($opt=true) { //! @desc Enable/Disable pre tag recognition. No-Parameter: Enable //! @return void $this->usepre=$opt; } //Page header function Header($content='') { //! @return void //! @desc The header is printed in every page. if($this->usetableheader and $content != '') { $y = $this->y; foreach($content as $tableheader) { $this->y = $y; //Set some cell values $x = $tableheader['x']; $w = $tableheader['w']; $h = $tableheader['h']; $va = $tableheader['va']; $mih = $tableheader['mih']; $fill = $tableheader['bgcolor']; $border = $tableheader['border']; $align = $tableheader['a']; //Align $this->divalign=$align; $this->x = $x; //Vertical align if (!isset($va) || $va=='M') $this->y += ($h-$mih)/2; elseif (isset($va) && $va=='B') $this->y += $h-$mih; if ($fill) { $color = ConvertColor($fill); $this->SetFillColor($color['R'],$color['G'],$color['B']); $this->Rect($x, $y, $w, $h, 'F'); } //Border if (isset($border) and $border != 'all') $this->_tableRect($x, $y, $w, $h, $border); elseif (isset($border) && $border == 'all') $this->Rect($x, $y, $w, $h); //Print cell content $this->divwidth = $w-2; $this->divheight = 1.1*$this->lineheight; $textbuffer = $tableheader['textbuffer']; if (!empty($textbuffer)) $this->printbuffer($textbuffer,false,true/*inside a table*/); $textbuffer = array(); } $this->y = $y + $h; //Update y coordinate }//end of 'if usetableheader ...' } //Page footer function Footer() { //! @return void //! @desc The footer is printed in every page! //Position at 1.0 cm from bottom $this->SetY(-10); //Copyright //especial para esta versão $this->SetFont('Arial','B',9); $this->SetTextColor(0); //Arial italic 9 $this->SetFont('Arial','I',9); //Page number $this->Cell(0,10,$this->PageNo().'/{nb}',0,0,'C'); //Return Font to normal $this->SetFont('Arial','',11); } /////////////////// /// HTML parser /// /////////////////// function WriteHTML($html) { //! @desc HTML parser //! @return void /* $e == content */ $this->ReadMetaTags($html); $html = AdjustHTML($html,$this->usepre); //Try to make HTML look more like XHTML if ($this->usecss) $html = $this->ReadCSS($html); //Add new supported tags in the DisableTags function $html=str_replace('enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string //Explode the string in order to parse the HTML code $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE); foreach($a as $i => $e) { if($i%2==0) { //TEXT //Adjust lineheight // $this->lineheight = (5*$this->FontSizePt)/11; //should be inside printbuffer? //Adjust text, if needed if (strpos($e,"&") !== false) //HTML-ENTITIES decoding { if (strpos($e,"#") !== false) $e = value_entity_decode($e); // Decode value entities //Avoid crashing the script on PHP 4.0 $version = phpversion(); $version = str_replace('.','',$version); if ($version >= 430) $e = html_entity_decode($e,ENT_QUOTES,'cp1252'); // changes   and the like by their respective char else $e = lesser_entity_decode($e); } $e = str_replace(chr(160),chr(32),$e); //unify ascii code of spaces (in order to recognize all of them correctly) if (strlen($e) == 0) continue; if ($this->divrevert) $e = strrev($e); if ($this->toupper) $e = strtoupper($e); if ($this->tolower) $e = strtolower($e); //Start of 'if/elseif's if($this->titulo) $this->SetTitle($e); elseif($this->specialcontent) { if ($this->specialcontent == "type=select" and $this->selectoption['ACTIVE'] == true) //SELECT tag (form element) { $stringwidth = $this->GetStringWidth($e); if (!isset($this->selectoption['MAXWIDTH']) or $stringwidth > $this->selectoption['MAXWIDTH']) $this->selectoption['MAXWIDTH'] = $stringwidth; if (!isset($this->selectoption['SELECTED']) or $this->selectoption['SELECTED'] == '') $this->selectoption['SELECTED'] = $e; } else $this->textbuffer[] = array("»¤¬"/*identifier*/.$this->specialcontent."»¤¬".$e); } elseif($this->tablestart) { if($this->tdbegin) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); $this->cell[$this->row][$this->col]['text'][] = $e; // BEGIN FIX BY ANDRE if (!isset($this->cell[$this->row][$this->col]['s']) ) $this->cell[$this->row][$this->col]['s'] = 0; // END FIX BY ANDRE $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e); } //Ignore content between , and a
    tag (this content is usually only a bunch of spaces) } elseif($this->pbegin or $this->HREF or $this->divbegin or $this->SUP or $this->SUB or $this->strike or $this->buffer_on) $this->textbuffer[] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); //Accumulate text on buffer else { if ($this->blockjustfinished) $e = ltrim($e); if ($e != '') { $this->Write($this->lineheight,$e); //Write text directly in the PDF if ($this->pjustfinished) $this->pjustfinished = false; } } } else { //Tag if($e{0}=='/') $this->CloseTag(strtoupper(substr($e,1))); else { $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any $e = preg_replace($regexp,"=\"\$1\"",$e); $regexp = '| (\\w+?)=([^\\s>"]+)|si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags) $e = preg_replace($regexp," \$1=\"\$2\"",$e); //Fix path values, if needed if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) ) { $regexp = '/ (href|src)="(.*?)"/i'; preg_match($regexp,$e,$auxiliararray); $path = $auxiliararray[2]; $path = str_replace("\\","/",$path); //If on Windows //Get link info and obtain its absolute path $regexp = '|^./|'; $path = preg_replace($regexp,'',$path); if($path{0} != '#') //It is not an Internal Link { if (strpos($path,"../") !== false ) //It is a Relative Link { $backtrackamount = substr_count($path,"../"); $maxbacktrack = substr_count($this->basepath,"/") - 1; $filepath = str_replace("../",'',$path); $path = $this->basepath; //If it is an invalid relative link, then make it go to directory root if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack; //Backtrack some directories for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") ); $path = $path . "/" . $filepath; //Make it an absolute path } elseif( strpos($path,":/") === false) //It is a Local Link { $path = $this->basepath . $path; } //Do nothing if it is an Absolute Link } $regexp = '/ (href|src)="(.*?)"/i'; $e = preg_replace($regexp,' \\1="'.$path.'"',$e); }//END of Fix path values //Extract attributes $contents=array(); preg_match_all('/\\S*=["\'][^"\']*["\']/',$e,$contents); preg_match('/\\S+/',$e,$a2); $tag=strtoupper($a2[0]); $attr=array(); if (!empty($contents)) { foreach($contents[0] as $v) { if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3)) { $attr[strtoupper($a3[1])]=$a3[2]; } } } $this->OpenTag($tag,$attr); } } }//end of foreach($a as $i=>$e) //Create Internal Links, if needed if (!empty($this->internallink) ) { foreach($this->internallink as $k=>$v) { if (strpos($k,"#") !== false ) continue; //ignore $ypos = $v['Y']; $pagenum = $v['PAGE']; $sharp = "#"; while (array_key_exists($sharp.$k,$this->internallink)) { $internallink = $this->internallink[$sharp.$k]; $this->SetLink($internallink,$ypos,$pagenum); $sharp .= "#"; } } } } function OpenTag($tag,$attr) { //! @return void // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','middle'=>'M','bottom'=>'B','justify'=>'J'); $this->blockjustfinished=false; //Opening tag switch($tag){ case 'PAGE_BREAK': //custom-tag case 'NEWPAGE': //custom-tag $this->blockjustfinished = true; $this->AddPage(); break; case 'OUTLINE': //custom-tag (CSS2 property - browsers don't support it yet - Jan2005) //Usage: (default: width=normal color=white) //Text //Mix this tag with the tag to get mixed colors on outlined text! $this->buffer_on = true; if (isset($attr['COLOR'])) $this->outlineparam['COLOR'] = ConvertColor($attr['COLOR']); else $this->outlineparam['COLOR'] = array('R'=>255,'G'=>255,'B'=>255); //white $this->outlineparam['OLDWIDTH'] = $this->LineWidth; if (isset($attr['WIDTH'])) { switch(strtoupper($attr['WIDTH'])) { case 'THIN': $this->outlineparam['WIDTH'] = 0.75*$this->LineWidth; break; case 'MEDIUM': $this->outlineparam['WIDTH'] = $this->LineWidth; break; case 'THICK': $this->outlineparam['WIDTH'] = 1.75*$this->LineWidth; break; } } else $this->outlineparam['WIDTH'] = $this->LineWidth; //width == oldwidth break; case 'BDO': if (isset($attr['DIR']) and (strtoupper($attr['DIR']) == 'RTL' )) $this->divrevert = true; break; case 'S': case 'STRIKE': case 'DEL': $this->strike=true; break; case 'SUB': $this->SUB=true; break; case 'SUP': $this->SUP=true; break; case 'CENTER': $this->buffer_on = true; if ($this->tdbegin) $this->cell[$this->row][$this->col]['a'] = $align['center']; else { $this->divalign = $align['center']; if ($this->x != $this->lMargin) $this->Ln($this->lineheight); } break; case 'ADDRESS': $this->buffer_on = true; $this->SetStyle('I',true); if (!$this->tdbegin and $this->x != $this->lMargin) $this->Ln($this->lineheight); break; case 'TABLE': // TABLE-BEGIN if ($this->x != $this->lMargin) $this->Ln($this->lineheight); $this->tablestart = true; $this->table['nc'] = $this->table['nr'] = 0; if (isset($attr['REPEAT_HEADER']) and $attr['REPEAT_HEADER'] == true) $this->UseTableHeader(true); if (isset($attr['WIDTH'])) $this->table['w'] = ConvertSize($attr['WIDTH'],$this->pgwidth); if (isset($attr['HEIGHT'])) $this->table['h'] = ConvertSize($attr['HEIGHT'],$this->pgwidth); if (isset($attr['ALIGN'])) $this->table['a'] = $align[strtolower($attr['ALIGN'])]; if (isset($attr['BORDER'])) $this->table['border'] = $attr['BORDER']; if (isset($attr['BGCOLOR'])) $this->table['bgcolor'][-1] = $attr['BGCOLOR']; break; case 'TR': $this->row++; $this->table['nr']++; $this->col = -1; if (isset($attr['BGCOLOR']))$this->table['bgcolor'][$this->row] = $attr['BGCOLOR']; break; case 'TH': $this->SetStyle('B',true); if (!isset($attr['ALIGN'])) $attr['ALIGN'] = "center"; case 'TD': $this->tdbegin = true; $this->col++; while (isset($this->cell[$this->row][$this->col])) $this->col++; //Update number column if ($this->table['nc'] < $this->col+1) $this->table['nc'] = $this->col+1; $this->cell[$this->row][$this->col] = array(); $this->cell[$this->row][$this->col]['text'] = array(); $this->cell[$this->row][$this->col]['s'] = 3; if (isset($attr['WIDTH'])) $this->cell[$this->row][$this->col]['w'] = ConvertSize($attr['WIDTH'],$this->pgwidth); if (isset($attr['HEIGHT'])) $this->cell[$this->row][$this->col]['h'] = ConvertSize($attr['HEIGHT'],$this->pgwidth); if (isset($attr['ALIGN'])) $this->cell[$this->row][$this->col]['a'] = $align[strtolower($attr['ALIGN'])]; if (isset($attr['VALIGN'])) $this->cell[$this->row][$this->col]['va'] = $align[strtolower($attr['VALIGN'])]; if (isset($attr['BORDER'])) $this->cell[$this->row][$this->col]['border'] = $attr['BORDER']; if (isset($attr['BGCOLOR'])) $this->cell[$this->row][$this->col]['bgcolor'] = $attr['BGCOLOR']; $cs = $rs = 1; if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN']; if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN']; //Chiem dung vi tri de danh cho cell span (¿mais hein?) for ($k=$this->row ; $k < $this->row+$rs ;$k++) for($l=$this->col; $l < $this->col+$cs ;$l++) { if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0; } if (isset($attr['NOWRAP'])) $this->cell[$this->row][$this->col]['nowrap']= 1; break; case 'OL': if ( !isset($attr['TYPE']) or $attr['TYPE'] == '' ) $this->listtype = '1'; //OL default == '1' else $this->listtype = $attr['TYPE']; // ol and ul types are mixed here case 'UL': if ( (!isset($attr['TYPE']) or $attr['TYPE'] == '') and $tag=='UL') { //Insert UL defaults if ($this->listlvl == 0) $this->listtype = 'disc'; elseif ($this->listlvl == 1) $this->listtype = 'circle'; else $this->listtype = 'square'; } elseif (isset($attr['TYPE']) and $tag=='UL') $this->listtype = $attr['TYPE']; $this->buffer_on = false; if ($this->listlvl == 0) { //First of all, skip a line if (!$this->pjustfinished) { if ($this->x != $this->lMargin) $this->Ln($this->lineheight); $this->Ln($this->lineheight); } $this->oldx = $this->x; $this->listlvl++; // first depth level $this->listnum = 0; // reset $this->listoccur[$this->listlvl] = 1; $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum); } else { if (!empty($this->textbuffer)) { $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]); $this->listnum++; } $this->textbuffer = array(); $occur = $this->listoccur[$this->listlvl]; $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum $this->listlvl++; $this->listnum = 0; // reset if ($this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1; else $this->listoccur[$this->listlvl]++; $occur = $this->listoccur[$this->listlvl]; $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum); } break; case 'LI': //Observation: is ignored if ($this->listlvl == 0) //in case of malformed HTML code. Example:(...)

  • Content
  • Paragraph1

    (...) { //First of all, skip a line if (!$this->pjustfinished and $this->x != $this->lMargin) $this->Ln(2*$this->lineheight); $this->oldx = $this->x; $this->listlvl++; // first depth level $this->listnum = 0; // reset $this->listoccur[$this->listlvl] = 1; $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum); } if ($this->listnum == 0) { $this->buffer_on = true; //activate list 'bufferization' $this->listnum++; $this->textbuffer = array(); } else { $this->buffer_on = true; //activate list 'bufferization' if (!empty($this->textbuffer)) { $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]); $this->listnum++; } $this->textbuffer = array(); } break; case 'H1': // 2 * fontsize case 'H2': // 1.5 * fontsize case 'H3': // 1.17 * fontsize case 'H4': // 1 * fontsize case 'H5': // 0.83 * fontsize case 'H6': // 0.67 * fontsize //Values obtained from: http://www.w3.org/TR/REC-CSS2/sample.html if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])]; $this->buffer_on = true; if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight); elseif (!$this->pjustfinished) $this->Ln($this->lineheight); $this->SetStyle('B',true); switch($tag) { case 'H1': $this->SetFontSize(2*$this->FontSizePt); $this->lineheight *= 2; break; case 'H2': $this->SetFontSize(1.5*$this->FontSizePt); $this->lineheight *= 1.5; break; case 'H3': $this->SetFontSize(1.17*$this->FontSizePt); $this->lineheight *= 1.17; break; case 'H4': $this->SetFontSize($this->FontSizePt); break; case 'H5': $this->SetFontSize(0.83*$this->FontSizePt); $this->lineheight *= 0.83; break; case 'H6': $this->SetFontSize(0.67*$this->FontSizePt); $this->lineheight *= 0.67; break; } break; case 'HR': //Default values: width=100% align=center color=gray //Skip a line, if needed if ($this->x != $this->lMargin) $this->Ln($this->lineheight); $this->Ln(0.2*$this->lineheight); $hrwidth = $this->pgwidth; $hralign = 'C'; $hrcolor = array('R'=>200,'G'=>200,'B'=>200); if($attr['WIDTH'] != '') $hrwidth = ConvertSize($attr['WIDTH'],$this->pgwidth); if($attr['ALIGN'] != '') $hralign = $align[strtolower($attr['ALIGN'])]; if($attr['COLOR'] != '') $hrcolor = ConvertColor($attr['COLOR']); $this->SetDrawColor($hrcolor['R'],$hrcolor['G'],$hrcolor['B']); $x = $this->x; $y = $this->y; switch($hralign) { case 'L': case 'J': break; case 'C': $empty = $this->pgwidth - $hrwidth; $empty /= 2; $x += $empty; break; case 'R': $empty = $this->pgwidth - $hrwidth; $x += $empty; break; } $oldlinewidth = $this->LineWidth; $this->SetLineWidth(0.3); $this->Line($x,$y,$x+$hrwidth,$y); $this->SetLineWidth($oldlinewidth); $this->Ln(0.2*$this->lineheight); $this->SetDrawColor(0); $this->blockjustfinished = true; //Eliminate exceeding left-side spaces break; case 'INS': $this->SetStyle('U',true); break; case 'SMALL': $newsize = $this->FontSizePt - 1; $this->SetFontSize($newsize); break; case 'BIG': $newsize = $this->FontSizePt + 1; $this->SetFontSize($newsize); case 'STRONG': $this->SetStyle('B',true); break; case 'CITE': case 'EM': $this->SetStyle('I',true); break; case 'TITLE': $this->titulo = true; break; case 'B': case 'I': case 'U': if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) ) { $this->cssbegin=true; if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']]; elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']]; //Read Inline CSS if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']); //Look for name in the $this->CSS array $this->backupcss = $properties; if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array! } $this->SetStyle($tag,true); break; case 'A': if (isset($attr['NAME']) and $attr['NAME'] != '') $this->textbuffer[] = array('','','',array(),'',false,false,$attr['NAME']); //an internal link (adds a space for recognition) if (isset($attr['HREF'])) $this->HREF=$attr['HREF']; break; case 'DIV': //in case of malformed HTML code. Example:(...)
  • Content
  • DIV1
    (...) if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s) { $this->buffer_on = false; if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]); $this->textbuffer = array(); $this->listlvl--; $this->printlistbuffer(); $this->pjustfinished = true; //act as if a paragraph just ended } $this->divbegin=true; if ($this->x != $this->lMargin) $this->Ln($this->lineheight); if( isset($attr['ALIGN']) and $attr['ALIGN'] != '' ) $this->divalign = $align[strtolower($attr['ALIGN'])]; if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) ) { $this->cssbegin=true; if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']]; elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']]; //Read Inline CSS if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']); //Look for name in the $this->CSS array if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array! } break; case 'IMG': if(!empty($this->textbuffer) and !$this->tablestart) { //Output previously buffered content and output image below //Set some default values $olddivwidth = $this->divwidth; $olddivheight = $this->divheight; if ( $this->divwidth == 0) $this->divwidth = $this->pgwidth - $x + $this->lMargin; if ( $this->divheight == 0) $this->divheight = $this->lineheight; //Print content $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/); $this->textbuffer=array(); //Reset values $this->divwidth = $olddivwidth; $this->divheight = $olddivheight; $this->textbuffer=array(); $this->Ln($this->lineheight); } if(isset($attr['SRC'])) { $srcpath = $attr['SRC']; if(!isset($attr['WIDTH'])) $attr['WIDTH'] = 0; else $attr['WIDTH'] = ConvertSize($attr['WIDTH'],$this->pgwidth);//$attr['WIDTH'] /= 4; if(!isset($attr['HEIGHT'])) $attr['HEIGHT'] = 0; else $attr['HEIGHT'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);//$attr['HEIGHT'] /= 4; if ($this->tdbegin) { $bak_x = $this->x; $bak_y = $this->y; //Check whether image exists locally or on the URL $f_exists = @fopen($srcpath,"rb"); if (!$f_exists) //Show 'image not found' icon instead { if(!$this->shownoimg) break; $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/"; $srcpath .= 'no_img.gif'; } $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false); $this->y = $bak_y; $this->x = $bak_x; } elseif($this->pbegin or $this->divbegin) { //In order to support
    $ypos = 0; $bak_x = $this->x; $bak_y = $this->y; //Check whether image exists locally or on the URL $f_exists = @fopen($srcpath,"rb"); if (!$f_exists) //Show 'image not found' icon instead { if(!$this->shownoimg) break; $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/"; $srcpath .= 'no_img.gif'; } $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false); $this->y = $bak_y; $this->x = $bak_x; $xpos = ''; switch($this->divalign) { case "C": $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 ); $empty = ($this->pgwidth - $sizesarray['WIDTH'])/2; $xpos = 'xpos='.$empty.','; break; case "R": $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 ); $empty = ($this->pgwidth - $sizesarray['WIDTH']); $xpos = 'xpos='.$empty.','; break; default: break; } $numberoflines = (integer)ceil($sizesarray['HEIGHT']/$this->lineheight) ; $ypos = $numberoflines * $this->lineheight; $this->textbuffer[] = array("»¤¬"/*identifier*/."type=image,ypos=$ypos,{$xpos}width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."»¤¬".$sizesarray['OUTPUT']); while($numberoflines) {$this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);$numberoflines--;} } else { $imgborder = 0; if (isset($attr['BORDER'])) $imgborder = ConvertSize($attr['BORDER'],$this->pgwidth); //Check whether image exists locally or on the URL $f_exists = @fopen($srcpath,"rb"); if (!$f_exists) //Show 'image not found' icon instead { $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/"; $srcpath .= 'no_img.gif'; } $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'',$this->HREF); //Output Image $ini_x = $sizesarray['X']; $ini_y = $sizesarray['Y']; if ($imgborder) { $oldlinewidth = $this->LineWidth; $this->SetLineWidth($imgborder); $this->Rect($ini_x,$ini_y,$sizesarray['WIDTH'],$sizesarray['HEIGHT']); $this->SetLineWidth($oldlinewidth); } } if ($sizesarray['X'] < $this->x) $this->x = $this->lMargin; if ($this->tablestart) { $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=image,width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."»¤¬".$sizesarray['OUTPUT']); $this->cell[$this->row][$this->col]['s'] += $sizesarray['WIDTH'] + 1;// +1 == margin $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later if (!isset($this->cell[$this->row][$this->col]['w'])) $this->cell[$this->row][$this->col]['w'] = $sizesarray['WIDTH'] + 3; if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $sizesarray['HEIGHT'] + 3; } } break; case 'BLOCKQUOTE': case 'BR': if($this->tablestart) { $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); $this->cell[$this->row][$this->col]['text'][] = "\n"; if (!isset($this->cell[$this->row][$this->col]['maxs'])) $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'] +2; //+2 == margin elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s']+2;//+2 == margin $this->cell[$this->row][$this->col]['s'] = 0;// reset } elseif($this->divbegin or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); else {$this->Ln($this->lineheight);$this->blockjustfinished = true;} break; case 'P': //in case of malformed HTML code. Example:(...)

  • Content
  • Paragraph1

    (...) if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s) { $this->buffer_on = false; if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]); $this->textbuffer = array(); $this->listlvl--; $this->printlistbuffer(); $this->pjustfinished = true; //act as if a paragraph just ended } if ($this->tablestart) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); $this->cell[$this->row][$this->col]['text'][] = "\n"; break; } $this->pbegin=true; if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight); elseif (!$this->pjustfinished) $this->Ln($this->lineheight); //Save x,y coords in case we need to print borders... $this->oldx = $this->x; $this->oldy = $this->y; if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])]; if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) ) { $this->cssbegin=true; if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']]; elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']]; //Read Inline CSS if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']); //Look for name in the $this->CSS array $this->backupcss = $properties; if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array! } break; case 'SPAN': $this->buffer_on = true; //Save x,y coords in case we need to print borders... $this->oldx = $this->x; $this->oldy = $this->y; if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) ) { $this->cssbegin=true; if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']]; elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']]; //Read Inline CSS if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']); //Look for name in the $this->CSS array $this->backupcss = $properties; if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array! } break; case 'PRE': if($this->tablestart) { $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); $this->cell[$this->row][$this->col]['text'][] = "\n"; } elseif($this->divbegin or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); else { if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight); elseif (!$this->pjustfinished) $this->Ln($this->lineheight); $this->buffer_on = true; //Save x,y coords in case we need to print borders... $this->oldx = $this->x; $this->oldy = $this->y; if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])]; if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) ) { $this->cssbegin=true; if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']]; elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']]; //Read Inline CSS if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']); //Look for name in the $this->CSS array $this->backupcss = $properties; if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array! } } case 'TT': case 'KBD': case 'SAMP': case 'CODE': $this->SetFont('courier'); $this->currentfont='courier'; break; case 'TEXTAREA': $this->buffer_on = true; $colsize = 20; //HTML default value $rowsize = 2; //HTML default value if (isset($attr['COLS'])) $colsize = $attr['COLS']; if (isset($attr['ROWS'])) $rowsize = $attr['ROWS']; if (!$this->tablestart) { if ($this->x != $this->lMargin) $this->Ln($this->lineheight); $this->col = $colsize; $this->row = $rowsize; } else //it is inside a table { $this->specialcontent = "type=textarea,lines=$rowsize,width=".((2.2*$colsize) + 3); //Activate form info in order to paint FORM elements within table $this->cell[$this->row][$this->col]['s'] += (2.2*$colsize) + 6;// +6 == margin if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = 1.1*$this->lineheight*$rowsize + 2.5; } break; case 'SELECT': $this->specialcontent = "type=select"; //Activate form info in order to paint FORM elements within table break; case 'OPTION': $this->selectoption['ACTIVE'] = true; if (empty($this->selectoption)) { $this->selectoption['MAXWIDTH'] = ''; $this->selectoption['SELECTED'] = ''; } if (isset($attr['SELECTED'])) $this->selectoption['SELECTED'] = ''; break; case 'FORM': if($this->tablestart) { $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); $this->cell[$this->row][$this->col]['text'][] = "\n"; } elseif ($this->x != $this->lMargin) $this->Ln($this->lineheight); //Skip a line, if needed break; case 'INPUT': if (!isset($attr['TYPE'])) $attr['TYPE'] == ''; //in order to allow default 'TEXT' form (in case of malformed HTML code) if (!$this->tablestart) { switch(strtoupper($attr['TYPE'])){ case 'CHECKBOX': //Draw Checkbox $checked = false; if (isset($attr['CHECKED'])) $checked = true; $this->SetFillColor(235,235,235); $this->x += 3; $this->Rect($this->x,$this->y+1,3,3,'DF'); if ($checked) { $this->Line($this->x,$this->y+1,$this->x+3,$this->y+1+3); $this->Line($this->x,$this->y+1+3,$this->x+3,$this->y+1); } $this->SetFillColor(255); $this->x += 3.5; break; case 'RADIO': //Draw Radio button $checked = false; if (isset($attr['CHECKED'])) $checked = true; $this->x += 4; $this->Circle($this->x,$this->y+2.2,1,'D'); $this->_out('0.000 g'); if ($checked) $this->Circle($this->x,$this->y+2.2,0.4,'DF'); $this->Write(5,$texto,$this->x); $this->x += 2; break; case 'BUTTON': // Draw a button case 'SUBMIT': case 'RESET': $texto=''; if (isset($attr['VALUE'])) $texto = $attr['VALUE']; $nihil = 2.5; $this->x += 2; $this->SetFillColor(190,190,190); $this->Rect($this->x,$this->y,$this->GetStringWidth($texto)+2*$nihil,4.5,'DF'); // 4.5 in order to avoid overlapping $this->x += $nihil; $this->Write(5,$texto,$this->x); $this->x += $nihil; $this->SetFillColor(255); break; case 'PASSWORD': if (isset($attr['VALUE'])) { $num_stars = strlen($attr['VALUE']); $attr['VALUE'] = str_repeat('*',$num_stars); } case 'TEXT': //Draw TextField default: //default == TEXT $texto=''; if (isset($attr['VALUE'])) $texto = $attr['VALUE']; $tamanho = 20; if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE']; $this->SetFillColor(235,235,235); $this->x += 2; $this->Rect($this->x,$this->y,2*$tamanho,4.5,'DF');// 4.5 in order to avoid overlapping if ($texto != '') { $this->x += 1; $this->Write(5,$texto,$this->x); $this->x -= $this->GetStringWidth($texto); } $this->SetFillColor(255); $this->x += 2*$tamanho; break; } } else //we are inside a table { $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later $type = ''; $text = ''; $height = 0; $width = 0; switch(strtoupper($attr['TYPE'])){ case 'CHECKBOX': //Draw Checkbox $checked = false; if (isset($attr['CHECKED'])) $checked = true; $text = $checked; $type = 'CHECKBOX'; $width = 4; $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."»¤¬".$text); $this->cell[$this->row][$this->col]['s'] += $width; if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight; break; case 'RADIO': //Draw Radio button $checked = false; if (isset($attr['CHECKED'])) $checked = true; $text = $checked; $type = 'RADIO'; $width = 3; $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."»¤¬".$text); $this->cell[$this->row][$this->col]['s'] += $width; if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight; break; case 'BUTTON': $type = 'BUTTON'; // Draw a button case 'SUBMIT': if ($type == '') $type = 'SUBMIT'; case 'RESET': if ($type == '') $type = 'RESET'; $texto=''; if (isset($attr['VALUE'])) $texto = " " . $attr['VALUE'] . " "; $text = $texto; $width = $this->GetStringWidth($texto)+3; $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."»¤¬".$text); $this->cell[$this->row][$this->col]['s'] += $width; if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2; break; case 'PASSWORD': if (isset($attr['VALUE'])) { $num_stars = strlen($attr['VALUE']); $attr['VALUE'] = str_repeat('*',$num_stars); } $type = 'PASSWORD'; case 'TEXT': //Draw TextField default: //default == TEXT $texto=''; if (isset($attr['VALUE'])) $texto = $attr['VALUE']; $tamanho = 20; if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE']; $text = $texto; $width = 2*$tamanho; if ($type == '') $type = 'TEXT'; $this->cell[$this->row][$this->col]['textbuffer'][] = array("»¤¬"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."»¤¬".$text); $this->cell[$this->row][$this->col]['s'] += $width; if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2; break; } } break; case 'FONT': //Font size is ignored for now if (isset($attr['COLOR']) and $attr['COLOR']!='') { $cor = ConvertColor($attr['COLOR']); //If something goes wrong switch color to black $cor['R'] = (isset($cor['R'])?$cor['R']:0); $cor['G'] = (isset($cor['G'])?$cor['G']:0); $cor['B'] = (isset($cor['B'])?$cor['B']:0); $this->colorarray = $cor; $this->SetTextColor($cor['R'],$cor['G'],$cor['B']); $this->issetcolor = true; } if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist)) { $this->SetFont(strtolower($attr['FACE'])); $this->issetfont=true; } //'If' disabled in this version due lack of testing (you may enable it if you want) // if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist) and isset($attr['SIZE']) and $attr['SIZE']!='') { // $this->SetFont(strtolower($attr['FACE']),'',$attr['SIZE']); // $this->issetfont=true; // } break; }//end of switch $this->pjustfinished=false; } function CloseTag($tag) { //! @return void //Closing tag if($tag=='OPTION') $this->selectoption['ACTIVE'] = false; if($tag=='BDO') $this->divrevert = false; if($tag=='INS') $tag='U'; if($tag=='STRONG') $tag='B'; if($tag=='EM' or $tag=='CITE') $tag='I'; if($tag=='OUTLINE') { if(!$this->pbegin and !$this->divbegin and !$this->tablestart) { //Deactivate $this->outlineparam for its info is already stored inside $this->textbuffer //if (isset($this->outlineparam['OLDWIDTH'])) $this->SetTextOutline($this->outlineparam['OLDWIDTH']); $this->SetTextOutline(false); $this->outlineparam=array(); //Save x,y coords ??? $x = $this->x; $y = $this->y; //Set some default values $this->divwidth = $this->pgwidth - $x + $this->lMargin; //Print content $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/); $this->textbuffer=array(); //Reset values $this->Reset(); $this->buffer_on=false; } $this->SetTextOutline(false); $this->outlineparam=array(); } if($tag=='A') { if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on) { //Deactivate $this->HREF for its info is already stored inside $this->textbuffer $this->HREF=''; //Save x,y coords ??? $x = $this->x; $y = $this->y; //Set some default values $this->divwidth = $this->pgwidth - $x + $this->lMargin; //Print content $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/); $this->textbuffer=array(); //Reset values $this->Reset(); } $this->HREF=''; } if($tag=='TH') $this->SetStyle('B',false); if($tag=='TH' or $tag=='TD') $this->tdbegin = false; if($tag=='SPAN') { if(!$this->pbegin and !$this->divbegin and !$this->tablestart) { if($this->cssbegin) { //Check if we have borders to print if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor)) { $texto=''; foreach($this->textbuffer as $vetor) $texto.=$vetor[0]; $tempx = $this->x; if($this->divbgcolor) $this->Cell($this->GetStringWidth($texto),$this->lineheight,'',$this->divborder,'','L',$this->divbgcolor); if ($this->dash_on) $this->Rect($this->oldx,$this->oldy,$this->GetStringWidth($texto),$this->lineheight); if ($this->dotted_on) $this->DottedRect($this->x - $this->GetStringWidth($texto),$this->y,$this->GetStringWidth($texto),$this->lineheight); $this->x = $tempx; $this->x -= 1; //adjust alignment } $this->cssbegin=false; $this->backupcss=array(); } //Save x,y coords ??? $x = $this->x; $y = $this->y; //Set some default values $this->divwidth = $this->pgwidth - $x + $this->lMargin; //Print content $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/); $this->textbuffer=array(); //Reset values $this->Reset(); } $this->buffer_on=false; } if($tag=='P' or $tag=='DIV') //CSS in BLOCK mode { $this->blockjustfinished = true; //Eliminate exceeding left-side spaces if(!$this->tablestart) { if ($this->divwidth == 0) $this->divwidth = $this->pgwidth; if ($tag=='P') { $this->pbegin=false; $this->pjustfinished=true; } else $this->divbegin=false; $content=''; foreach($this->textbuffer as $aux) $content .= $aux[0]; $numlines = $this->WordWrap($content,$this->divwidth); if ($this->divheight == 0) $this->divheight = $numlines * 5; //Print content $this->printbuffer($this->textbuffer); $this->textbuffer=array(); if ($tag=='P') $this->Ln($this->lineheight); }//end of 'if (!this->tablestart)' //Reset values $this->Reset(); $this->cssbegin=false; $this->backupcss=array(); } if($tag=='TABLE') { // TABLE-END // BEGIN FIX BY ANDRE if ( isset($this->table['nc']) && $this->table['nr'] ) { // END FIX BY ANDRE $this->blockjustfinished = true; //Eliminate exceeding left-side spaces $this->table['cells'] = $this->cell; $this->table['wc'] = array_pad(array(),$this->table['nc'],array('miw'=>0,'maw'=>0)); $this->table['hr'] = array_pad(array(),$this->table['nr'],0); $this->_tableColumnWidth($this->table); $this->_tableWidth($this->table); $this->_tableHeight($this->table); //Output table on PDF $this->_tableWrite($this->table); // BEGIN FIX BY ANDRE } // END FIX BY ANDRE //Reset values $this->tablestart=false; //bool $this->table=array(); //array $this->cell=array(); //array $this->col=-1; //int $this->row=-1; //int $this->Reset(); $this->Ln(0.5*$this->lineheight); } if(($tag=='UL') or ($tag=='OL')) { if ($this->buffer_on == false) $this->listnum--;//Adjust minor BUG (this happens when there are two together) if ($this->listlvl == 1) // We are closing the last OL/UL tag { $this->blockjustfinished = true; //Eliminate exceeding left-side spaces $this->buffer_on = false; if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]); $this->textbuffer = array(); $this->listlvl--; $this->printlistbuffer(); } else // returning one level { if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]); $this->textbuffer = array(); $occur = $this->listoccur[$this->listlvl]; $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum $this->listlvl--; $occur = $this->listoccur[$this->listlvl]; $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type $this->buffer_on = false; } } if($tag=='H1' or $tag=='H2' or $tag=='H3' or $tag=='H4' or $tag=='H5' or $tag=='H6') { $this->blockjustfinished = true; //Eliminate exceeding left-side spaces if(!$this->pbegin and !$this->divbegin and !$this->tablestart) { //These 2 codelines are useless? $texto=''; foreach($this->textbuffer as $vetor) $texto.=$vetor[0]; //Save x,y coords ??? $x = $this->x; $y = $this->y; //Set some default values $this->divwidth = $this->pgwidth; //Print content $this->printbuffer($this->textbuffer); $this->textbuffer=array(); if ($this->x != $this->lMargin) $this->Ln($this->lineheight); //Reset values $this->Reset(); } $this->buffer_on=false; $this->lineheight = 5; $this->Ln($this->lineheight); $this->SetFontSize(11); $this->SetStyle('B',false); } if($tag=='TITLE') {$this->titulo=false; $this->blockjustfinished = true;} if($tag=='FORM') $this->Ln($this->lineheight); if($tag=='PRE') { if(!$this->pbegin and !$this->divbegin and !$this->tablestart) { if ($this->divwidth == 0) $this->divwidth = $this->pgwidth; $content=''; foreach($this->textbuffer as $aux) $content .= $aux[0]; $numlines = $this->WordWrap($content,$this->divwidth); if ($this->divheight == 0) $this->divheight = $numlines * 5; //Print content $this->textbuffer[0][0] = ltrim($this->textbuffer[0][0]); //Remove exceeding left-side space $this->printbuffer($this->textbuffer); $this->textbuffer=array(); if ($this->x != $this->lMargin) $this->Ln($this->lineheight); //Reset values $this->Reset(); $this->Ln(1.1*$this->lineheight); } if($this->tablestart) { $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); $this->cell[$this->row][$this->col]['text'][] = "\n"; } if($this->divbegin or $this->pbegin or $this->buffer_on) $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); $this->cssbegin=false; $this->backupcss=array(); $this->buffer_on = false; $this->blockjustfinished = true; //Eliminate exceeding left-side spaces $this->pjustfinished = true; //behaves the same way } if($tag=='CODE' or $tag=='PRE' or $tag=='TT' or $tag=='KBD' or $tag=='SAMP') { $this->currentfont=''; $this->SetFont('arial'); } if($tag=='B' or $tag=='I' or $tag=='U') { $this->SetStyle($tag,false); if ($this->cssbegin and !$this->divbegin and !$this->pbegin and !$this->buffer_on) { //Reset values $this->Reset(); $this->cssbegin=false; $this->backupcss=array(); } } if($tag=='TEXTAREA') { if (!$this->tablestart) //not inside a table { //Draw arrows too? $texto = ''; foreach($this->textbuffer as $v) $texto .= $v[0]; $this->SetFillColor(235,235,235); $this->SetFont('courier'); $this->x +=3; $linesneeded = $this->WordWrap($texto,($this->col*2.2)+3); if ( $linesneeded > $this->row ) //Too many words inside textarea { $textoaux = explode("\n",$texto); $texto = ''; for($i=0;$i < $this->row;$i++) { if ($i == $this->row-1) $texto .= $textoaux[$i]; else $texto .= $textoaux[$i] . "\n"; } //Inform the user that some text has been truncated $texto{strlen($texto)-1} = "."; $texto{strlen($texto)-2} = "."; $texto{strlen($texto)-3} = "."; } $backup_y = $this->y; $this->Rect($this->x,$this->y,(2.2*$this->col)+6,5*$this->row,'DF'); if ($texto != '') $this->MultiCell((2.2*$this->col)+6,$this->lineheight,$texto); $this->y = $backup_y + $this->row*$this->lineheight; $this->SetFont('arial'); } else //inside a table { $this->cell[$this->row][$this->col]['textbuffer'][] = $this->textbuffer[0]; $this->cell[$this->row][$this->col]['text'][] = $this->textbuffer[0]; $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later $this->specialcontent = ''; } $this->SetFillColor(255); $this->textbuffer=array(); $this->buffer_on = false; } if($tag=='SELECT') { $texto = ''; $tamanho = 0; if (isset($this->selectoption['MAXWIDTH'])) $tamanho = $this->selectoption['MAXWIDTH']; if ($this->tablestart) { $texto = "»¤¬".$this->specialcontent."»¤¬".$this->selectoption['SELECTED']; $aux = explode("»¤¬",$texto); $texto = $aux[2]; $texto = "»¤¬".$aux[1].",width=$tamanho,height=".($this->lineheight + 2)."»¤¬".$texto; $this->cell[$this->row][$this->col]['s'] += $tamanho + 7; // margin + arrow box $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2; $this->cell[$this->row][$this->col]['textbuffer'][] = array($texto); $this->cell[$this->row][$this->col]['text'][] = ''; } else //not inside a table { $texto = $this->selectoption['SELECTED']; $this->SetFillColor(235,235,235); $this->x += 2; $this->Rect($this->x,$this->y,$tamanho+2,5,'DF');//+2 margin $this->x += 1; if ($texto != '') $this->Write(5,$texto,$this->x); $this->x += $tamanho - $this->GetStringWidth($texto) + 2; $this->SetFillColor(190,190,190); $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box $this->SetFont('zapfdingbats'); $this->Write(5,chr(116),$this->x); //Down arrow $this->SetFont('arial'); $this->SetFillColor(255); $this->x += 1; } $this->selectoption = array(); $this->specialcontent = ''; $this->textbuffer = array(); } if($tag=='SUB' or $tag=='SUP') //subscript or superscript { if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on and !$this->strike) { //Deactivate $this->SUB/SUP for its info is already stored inside $this->textbuffer $this->SUB=false; $this->SUP=false; //Save x,y coords ??? $x = $this->x; $y = $this->y; //Set some default values $this->divwidth = $this->pgwidth - $x + $this->lMargin; //Print content $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/); $this->textbuffer=array(); //Reset values $this->Reset(); } $this->SUB=false; $this->SUP=false; } if($tag=='S' or $tag=='STRIKE' or $tag=='DEL') { if(!$this->pbegin and !$this->divbegin and !$this->tablestart) { //Deactivate $this->strike for its info is already stored inside $this->textbuffer $this->strike=false; //Save x,y coords ??? $x = $this->x; $y = $this->y; //Set some default values $this->divwidth = $this->pgwidth - $x + $this->lMargin; //Print content $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/); $this->textbuffer=array(); //Reset values $this->Reset(); } $this->strike=false; } if($tag=='ADDRESS' or $tag=='CENTER') //
    or
    tag { $this->blockjustfinished = true; //Eliminate exceeding left-side spaces if(!$this->pbegin and !$this->divbegin and !$this->tablestart) { //Save x,y coords ??? $x = $this->x; $y = $this->y; //Set some default values $this->divwidth = $this->pgwidth - $x + $this->lMargin; //Print content $this->printbuffer($this->textbuffer); $this->textbuffer=array(); //Reset values $this->Reset(); } $this->buffer_on=false; if ($tag == 'ADDRESS') $this->SetStyle('I',false); } if($tag=='BIG') { $newsize = $this->FontSizePt - 1; $this->SetFontSize($newsize); $this->SetStyle('B',false); } if($tag=='SMALL') { $newsize = $this->FontSizePt + 1; $this->SetFontSize($newsize); } if($tag=='FONT') { if ($this->issetcolor == true) { $this->colorarray = array(); $this->SetTextColor(0); $this->issetcolor = false; } if ($this->issetfont) { $this->SetFont('arial'); $this->issetfont=false; } if ($this->cssbegin) { //Get some attributes back! $this->setCSS($this->backupcss); } } } function printlistbuffer() { //! @return void //! @desc Prints all list-related buffered info //Save x coordinate $x = $this->oldx; foreach($this->listitem as $item) { //Set default width & height values $this->divwidth = $this->pgwidth; $this->divheight = $this->lineheight; //Get list's buffered data $lvl = $item[0]; $num = $item[1]; $this->textbuffer = $item[2]; $occur = $item[3]; $type = $this->listlist[$lvl][$occur]['TYPE']; $maxnum = $this->listlist[$lvl][$occur]['MAXNUM']; switch($type) //Format type { case 'A': $num = dec2alpha($num,true); $maxnum = dec2alpha($maxnum,true); $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . "."; break; case 'a': $num = dec2alpha($num,false); $maxnum = dec2alpha($maxnum,false); $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . "."; break; case 'I': $num = dec2roman($num,true); $maxnum = dec2roman($maxnum,true); $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . "."; break; case 'i': $num = dec2roman($num,false); $maxnum = dec2roman($maxnum,false); $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . "."; break; case '1': $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . "."; break; case 'disc': $type = chr(149); break; case 'square': $type = chr(110); //black square on Zapfdingbats font break; case 'circle': $type = chr(186); break; default: break; } $this->x = (5*$lvl) + $x; //Indent list //Get bullet width including margins $oldsize = $this->FontSize * $this->k; if ($type == chr(110)) $this->SetFont('zapfdingbats','',5); $type .= ' '; $blt_width = $this->GetStringWidth($type)+$this->cMargin*2; //Output bullet $this->Cell($blt_width,5,$type,'','','L'); $this->SetFont('arial','',$oldsize); $this->divwidth = $this->divwidth + $this->lMargin - $this->x; //Print content $this->printbuffer($this->textbuffer); $this->textbuffer=array(); } //Reset all used values $this->listoccur = array(); $this->listitem = array(); $this->listlist = array(); $this->listlvl = 0; $this->listnum = 0; $this->listtype = ''; $this->textbuffer = array(); $this->divwidth = 0; $this->divheight = 0; $this->oldx = -1; //At last, but not least, skip a line $this->Ln($this->lineheight); } function printbuffer($arrayaux,$outofblock=false,$is_table=false) { //! @return headache //! @desc Prepares buffered text to be printed with FlowingBlock() //Save some previous parameters $save = array(); $save['strike'] = $this->strike; $save['SUP'] = $this->SUP; $save['SUB'] = $this->SUB; $save['DOTTED'] = $this->dotted_on; $save['DASHED'] = $this->dash_on; $this->SetDash(); //restore to no dash $this->dash_on = false; $this->dotted_on = false; $bak_y = $this->y; $bak_x = $this->x; $align = $this->divalign; $oldpage = $this->page; //Overall object size == $old_height //Line height == $this->divheight $old_height = $this->divheight; if ($is_table) { $this->divheight = 1.1*$this->lineheight; $fill = 0; } else { $this->divheight = $this->lineheight; if ($this->FillColor == '1.000 g') $fill = 0; //avoid useless background painting (1.000 g == white background color) else $fill = 1; } $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table); $array_size = count($arrayaux); for($i=0;$i < $array_size; $i++) { $vetor = $arrayaux[$i]; if ($i == 0 and $vetor[0] != "\n") $vetor[0] = ltrim($vetor[0]); if (empty($vetor[0]) and empty($vetor[7])) continue; //Ignore empty text and not carrying an internal link //Activating buffer properties if(isset($vetor[10]) and !empty($vetor[10])) //Background color { $cor = $vetor[10]; $this->SetFillColor($cor['R'],$cor['G'],$cor['B']); $this->divbgcolor = true; } if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters { $cor = $vetor[9]['COLOR']; $outlinewidth = $vetor[9]['WIDTH']; $this->SetTextOutline($outlinewidth,$cor['R'],$cor['G'],$cor['B']); $this->outline_on = true; } if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text { $this->strike = true; } if(isset($vetor[7]) and $vetor[7] != '') // internal link: { $this->internallink[$vetor[7]] = array("Y"=>$this->y,"PAGE"=>$this->page ); $this->Bookmark($vetor[7]." (pg. $this->page)",0,$this->y); if (empty($vetor[0])) continue; //Ignore empty text } if(isset($vetor[6]) and $vetor[6] === true) // Subscript { $this->SUB = true; $this->SetFontSize(6); } if(isset($vetor[5]) and $vetor[5] === true) // Superscript { $this->SUP = true; $this->SetFontSize(6); } if(isset($vetor[4]) and $vetor[4] != '') $this->SetFont($vetor[4]); // Font Family if (!empty($vetor[3])) //Font Color { $cor = $vetor[3]; $this->SetTextColor($cor['R'],$cor['G'],$cor['B']); } if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles { if (strpos($vetor[2],"B") !== false) $this->SetStyle('B',true); if (strpos($vetor[2],"I") !== false) $this->SetStyle('I',true); if (strpos($vetor[2],"U") !== false) $this->SetStyle('U',true); } if(isset($vetor[1]) and $vetor[1] != '') //LINK { if (strpos($vetor[1],".") === false) //assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.) { //Repeated reference to same anchor? while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1]; $this->internallink[$vetor[1]] = $this->AddLink(); $vetor[1] = $this->internallink[$vetor[1]]; } $this->HREF = $vetor[1]; $this->SetTextColor(0,0,255); $this->SetStyle('U',true); } //Print-out special content if (isset($vetor[0]) and $vetor[0]{0} == '»' and $vetor[0]{1} == '¤' and $vetor[0]{2} == '¬') //identifier has been identified! { $content = explode("»¤¬",$vetor[0]); $texto = $content[2]; $content = explode(",",$content[1]); foreach($content as $value) { $value = explode("=",$value); $specialcontent[$value[0]] = $value[1]; } if ($this->flowingBlockAttr[ 'contentWidth' ] > 0) // Print out previously accumulated content { $width_used = $this->flowingBlockAttr[ 'contentWidth' ] / $this->k; //Restart Flowing Block $this->finishFlowingBlock($outofblock); $this->x = $bak_x + ($width_used % $this->divwidth) + 0.5;// 0.5 == margin $this->y -= ($this->lineheight + 0.5); $extrawidth = 0; //only to be used in case $specialcontent['width'] does not contain all used width (e.g. Select Box) if ($specialcontent['type'] == 'select') $extrawidth = 7; //arrow box + margin if(($this->x - $bak_x) + $specialcontent['width'] + $extrawidth > $this->divwidth ) { $this->x = $bak_x; $this->y += $this->lineheight - 1; } $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table ); } switch(strtoupper($specialcontent['type'])) { case 'IMAGE': //xpos and ypos used in order to support:
    $xpos = 0; $ypos = 0; if (isset($specialcontent['ypos']) and $specialcontent['ypos'] != '') $ypos = (float)$specialcontent['ypos']; if (isset($specialcontent['xpos']) and $specialcontent['xpos'] != '') $xpos = (float)$specialcontent['xpos']; $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later //Is this the best way of fixing x,y coordinates? $fix_x = ($this->x+2) * $this->k + ($xpos*$this->k); //+2 margin $fix_y = ($this->h - (($this->y+2) + $specialcontent['height'])) * $this->k;//+2 margin $imgtemp = explode(" ",$texto); $imgtemp[5]=$fix_x; // x $imgtemp[6]=$fix_y; // y $texto = implode(" ",$imgtemp); $this->_out($texto); //Readjust x coordinate in order to allow text to be placed after this form element $this->x = $bak_x; $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 ); $spacenum = (integer)ceil(($width_used / $spacesize)); //Consider the space used so far in this line as a bunch of spaces if ($ypos != 0) $this->Ln($ypos); else $this->WriteFlowingBlock(str_repeat(' ',$spacenum)); break; case 'INPUT': switch($specialcontent['subtype']) { case 'PASSWORD': case 'TEXT': //Draw TextField $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later $this->SetFillColor(235,235,235); $this->x += 1; $this->y += 1; $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF');// 4.5 in order to avoid overlapping if ($texto != '') { $this->x += 1; $this->Write(5,$texto,$this->x); $this->x -= $this->GetStringWidth($texto); } $this->SetFillColor(255); $this->y -= 1; //Readjust x coordinate in order to allow text to be placed after this form element $this->x = $bak_x; $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 ); $spacenum = (integer)ceil(($width_used / $spacesize)); //Consider the space used so far in this line as a bunch of spaces $this->WriteFlowingBlock(str_repeat(' ',$spacenum)); break; case 'CHECKBOX': //Draw Checkbox $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later $checked = $texto; $this->SetFillColor(235,235,235); $this->y += 1; $this->x += 1; $this->Rect($this->x,$this->y,3,3,'DF'); if ($checked) { $this->Line($this->x,$this->y,$this->x+3,$this->y+3); $this->Line($this->x,$this->y+3,$this->x+3,$this->y); } $this->SetFillColor(255); $this->y -= 1; //Readjust x coordinate in order to allow text to be placed after this form element $this->x = $bak_x; $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 ); $spacenum = (integer)ceil(($width_used / $spacesize)); //Consider the space used so far in this line as a bunch of spaces $this->WriteFlowingBlock(str_repeat(' ',$spacenum)); break; case 'RADIO': //Draw Radio button $width_used = (($this->x - $bak_x) + $specialcontent['width']+0.5)*$this->k; //in order to adjust x coordinate later $checked = $texto; $this->x += 2; $this->y += 1.5; $this->Circle($this->x,$this->y+1.2,1,'D'); $this->_out('0.000 g'); if ($checked) $this->Circle($this->x,$this->y+1.2,0.4,'DF'); $this->y -= 1.5; //Readjust x coordinate in order to allow text to be placed after this form element $this->x = $bak_x; $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 ); $spacenum = (integer)ceil(($width_used / $spacesize)); //Consider the space used so far in this line as a bunch of spaces $this->WriteFlowingBlock(str_repeat(' ',$spacenum)); break; case 'BUTTON': // Draw a button case 'SUBMIT': case 'RESET': $nihil = ($specialcontent['width']-$this->GetStringWidth($texto))/2; $this->x += 1.5; $this->y += 1; $this->SetFillColor(190,190,190); $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF'); // 4.5 in order to avoid overlapping $this->x += $nihil; $this->Write(5,$texto,$this->x); $this->x += $nihil; $this->SetFillColor(255); $this->y -= 1; break; default: break; } break; case 'SELECT': $width_used = (($this->x - $bak_x) + $specialcontent['width'] + 8)*$this->k; //in order to adjust x coordinate later $this->SetFillColor(235,235,235); //light gray $this->x += 1.5; $this->y += 1; $this->Rect($this->x,$this->y,$specialcontent['width']+2,$this->lineheight,'DF'); // +2 == margin $this->x += 1; if ($texto != '') $this->Write($this->lineheight,$texto,$this->x); //the combobox content $this->x += $specialcontent['width'] - $this->GetStringWidth($texto) + 2; $this->SetFillColor(190,190,190); //dark gray $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box $this->SetFont('zapfdingbats'); $this->Write($this->lineheight,chr(116),$this->x); //Down arrow $this->SetFont('arial'); $this->SetFillColor(255); //Readjust x coordinate in order to allow text to be placed after this form element $this->x = $bak_x; $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 ); $spacenum = (integer)ceil(($width_used / $spacesize)); //Consider the space used so far in this line as a bunch of spaces $this->WriteFlowingBlock(str_repeat(' ',$spacenum)); break; case 'TEXTAREA': //Setup TextArea properties $this->SetFillColor(235,235,235); $this->SetFont('courier'); $this->currentfont='courier'; $ta_lines = $specialcontent['lines']; $ta_height = 1.1*$this->lineheight*$ta_lines; $ta_width = $specialcontent['width']; //Adjust x,y coordinates $this->x += 1.5; $this->y += 1.5; $linesneeded = $this->WordWrap($texto,$ta_width); if ( $linesneeded > $ta_lines ) //Too many words inside textarea { $textoaux = explode("\n",$texto); $texto = ''; for($i=0;$i<$ta_lines;$i++) { if ($i == $ta_lines-1) $texto .= $textoaux[$i]; else $texto .= $textoaux[$i] . "\n"; } //Inform the user that some text has been truncated $texto{strlen($texto)-1} = "."; $texto{strlen($texto)-2} = "."; $texto{strlen($texto)-3} = "."; } $backup_y = $this->y; $backup_x = $this->x; $this->Rect($this->x,$this->y,$ta_width+3,$ta_height,'DF'); if ($texto != '') $this->MultiCell($ta_width+3,$this->lineheight,$texto); $this->y = $backup_y - 1.5; $this->x = $backup_x + $ta_width + 2.5; $this->SetFillColor(255); $this->SetFont('arial'); $this->currentfont=''; break; default: break; } } else //THE text { if ($vetor[0] == "\n") //We are reading a
    now turned into newline ("\n") { //Restart Flowing Block $this->finishFlowingBlock($outofblock); if($outofblock) $this->Ln($this->lineheight); $this->x = $bak_x; $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table ); } else $this->WriteFlowingBlock( $vetor[0] , $outofblock ); } //Check if it is the last element. If so then finish printing the block if ($i == ($array_size-1)) $this->finishFlowingBlock($outofblock); //Now we must deactivate what we have used if( (isset($vetor[1]) and $vetor[1] != '') or $this->HREF != '') { $this->SetTextColor(0); $this->SetStyle('U',false); $this->HREF = ''; } if(isset($vetor[2]) and $vetor[2] != '') { $this->SetStyle('B',false); $this->SetStyle('I',false); $this->SetStyle('U',false); } if(isset($vetor[3]) and $vetor[3] != '') { unset($cor); $this->SetTextColor(0); } if(isset($vetor[4]) and $vetor[4] != '') $this->SetFont('arial'); if(isset($vetor[5]) and $vetor[5] === true) { $this->SUP = false; $this->SetFontSize(11); } if(isset($vetor[6]) and $vetor[6] === true) { $this->SUB = false; $this->SetFontSize(11); } //vetor7-internal links if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text { $this->strike = false; } if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters { $this->SetTextOutline(false); $this->outline_on = false; } if(isset($vetor[10]) and !empty($vetor[10])) //Background color { $this->SetFillColor(255); $this->divbgcolor = false; } }//end of for(i=0;istrike = $save['strike']; $this->SUP = $save['SUP']; $this->SUB = $save['SUB']; $this->dotted_on = $save['DOTTED']; $this->dash_on = $save['DASHED']; if ($this->dash_on) $this->SetDash(2,2); //Check whether we have borders to paint or not //(only works 100% if whole content spans only 1 page) if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor)) { if ($oldpage != $this->page) { //Only border on last page is painted (known bug) $x = $this->lMargin; $y = $this->tMargin; $old_height = $this->y - $y; } else { if ($this->oldx < 0) $x = $this->x; else $x = $this->oldx; if ($this->oldy < 0) $y = $this->y - $old_height; else $y = $this->oldy; } if ($this->divborder) $this->Rect($x,$y,$this->divwidth,$old_height); if ($this->dash_on) $this->Rect($x,$y,$this->divwidth,$old_height); if ($this->dotted_on) $this->DottedRect($x,$y,$this->divwidth,$old_height); $this->x = $bak_x; } } function Reset() { //! @return void //! @desc Resets several class attributes // if ( $this->issetcolor !== true ) // { $this->SetTextColor(0); $this->SetDrawColor(0); $this->SetFillColor(255); $this->colorarray = array(); $this->bgcolorarray = array(); $this->issetcolor = false; // } $this->HREF = ''; $this->SetTextOutline(false); //$this->strike = false; $this->SetFontSize(11); $this->SetStyle('B',false); $this->SetStyle('I',false); $this->SetStyle('U',false); $this->SetFont('arial'); $this->divwidth = 0; $this->divheight = 0; $this->divalign = "L"; $this->divrevert = false; $this->divborder = 0; $this->divbgcolor = false; $this->toupper = false; $this->tolower = false; $this->SetDash(); //restore to no dash $this->dash_on = false; $this->dotted_on = false; $this->oldx = -1; $this->oldy = -1; } function ReadMetaTags($html) { //! @return void //! @desc Pass meta tag info to PDF file properties $regexp = '/ (\\w+?)=([^\\s>"]+)/si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags) $html = preg_replace($regexp," \$1=\"\$2\"",$html); $regexp = '//si'; preg_match_all($regexp,$html,$aux); $firstattr = $aux[1]; $secondattr = $aux[3]; for( $i = 0 ; $i < count($aux[0]) ; $i++) { $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]); $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i]; switch($name) { case "KEYWORDS": $this->SetKeywords($content); break; case "AUTHOR": $this->SetAuthor($content); break; case "DESCRIPTION": $this->SetSubject($content); break; } } //Comercial do Aplicativo usado (no caso um script): $this->SetCreator("HTML2FPDF >> http://html2fpdf.sf.net"); } ////////////////// /// CSS parser /// ////////////////// function ReadCSS($html) { //! @desc CSS parser //! @return string /* * This version ONLY supports: .class {...} / #id { .... } * It does NOT support: body{...} / a#hover { ... } / p.right { ... } / other mixed names * This function must read the CSS code (internal or external) and order its value inside $this->CSS. */ $match = 0; // no match for instance $regexp = ''; // This helps debugging: showing what is the REAL string being processed //CSS inside external files $regexp = '//si'; $match = preg_match_all($regexp,$html,$CSSext); $ind = 0; while($match){ //Fix path value $path = $CSSext[1][$ind]; $path = str_replace("\\","/",$path); //If on Windows //Get link info and obtain its absolute path $regexp = '|^./|'; $path = preg_replace($regexp,'',$path); if (strpos($path,"../") !== false ) //It is a Relative Link { $backtrackamount = substr_count($path,"../"); $maxbacktrack = substr_count($this->basepath,"/") - 1; $filepath = str_replace("../",'',$path); $path = $this->basepath; //If it is an invalid relative link, then make it go to directory root if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack; //Backtrack some directories for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") ); $path = $path . "/" . $filepath; //Make it an absolute path } elseif( strpos($path,":/") === false) //It is a Local Link { $path = $this->basepath . $path; } //Do nothing if it is an Absolute Link //END of fix path value $CSSextblock = file_get_contents($path); //Get class/id name and its characteristics from $CSSblock[1] $regexp = '/[.# ]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n preg_match_all( $regexp, $CSSextblock, $extstyle); //Make CSS[Name-of-the-class] = array(key => value) $regexp = '/\\s*?(\\S+?):(.+?);/si'; for($i=0; $i < count($extstyle[1]) ; $i++) { preg_match_all( $regexp, $extstyle[2][$i], $extstyleinfo); $extproperties = $extstyleinfo[1]; $extvalues = $extstyleinfo[2]; for($j = 0; $j < count($extproperties) ; $j++) { //Array-properties and Array-values must have the SAME SIZE! $extclassproperties[strtoupper($extproperties[$j])] = trim($extvalues[$j]); } $this->CSS[$extstyle[1][$i]] = $extclassproperties; $extproperties = array(); $extvalues = array(); $extclassproperties = array(); } $match--; $ind++; } //end of match $match = 0; // reset value, if needed //CSS internal //Get content between tags and order it, using regexp $regexp = '/(.*?)<\/style>/si'; // it can be